path: root/gluster
diff options
authorPrashanth Pai <>2016-03-11 17:56:46 +0530
committerThiago da Silva <>2016-05-03 12:47:05 -0700
commitfddb5d4a918affe7837d523b56e53e33f3ae5408 (patch)
tree919445423bd690ff74a64bf7e96dce0e8ad06eb9 /gluster
parent933bc5ade145413b0c7307a12b9d0b4084e7d767 (diff)
Open object only if it's going to be read
Open()ing an object is necessarry only in two cases: * Serving a GET request * Recalculating etag when metadata is stale (can be triggered by any type of request) This change ensures that for requests other than GET, a file is not opened if the metadata is valid (size and etag accurate). Note that if metadata is stale, the file is still opened and read to compute etag. This patch does not change the behaviour of triggering metadata validation and regeneration for non-GET requests. Change-Id: Icefa4dec7d715ec9e6dd68ae7fe89a0d90fe71b3 Signed-off-by: Prashanth Pai <> Reviewed-on: Reviewed-by: Thiago da Silva <> Tested-by: Thiago da Silva <>
Diffstat (limited to 'gluster')
1 files changed, 38 insertions, 6 deletions
diff --git a/gluster/swift/obj/ b/gluster/swift/obj/
index 14625d9..2e0837e 100644
--- a/gluster/swift/obj/
+++ b/gluster/swift/obj/
@@ -613,11 +613,13 @@ class DiskFile(object):
raise DiskFileNotExist
- self._stat = do_fstat(self._fd)
+ if not self._stat:
+ self._stat = do_fstat(self._fd)
self._is_dir = stat.S_ISDIR(self._stat.st_mode)
obj_size = self._stat.st_size
- self._metadata = read_metadata(self._fd)
+ if not self._metadata:
+ self._metadata = read_metadata(self._fd)
if not validate_object(self._metadata, self._stat):
self._metadata = create_object_metadata(self._fd, self._stat,
@@ -731,12 +733,42 @@ class DiskFile(object):
This method is invoked by Swift code in POST, PUT, HEAD and DELETE path
metadata = disk_file.read_metadata()
+ The operations performed here is very similar to those made in open().
+ This is to avoid opening and closing of file (two syscalls over
+ network). IOW, this optimization addresses the case where the fd
+ returned by open() isn't going to be used i.e the file is not read (GET
+ or metadata recalculation)
:returns: metadata dictionary for an object
:raises DiskFileError: this implementation will raise the same
errors as the `open()` method.
- with
- return self.get_metadata()
+ try:
+ self._metadata = read_metadata(self._data_file)
+ except (OSError, IOError) as err:
+ if err.errno in (errno.ENOENT, errno.ESTALE):
+ raise DiskFileNotExist
+ raise err
+ if self._metadata and self._is_object_expired(self._metadata):
+ raise DiskFileExpired(metadata=self._metadata)
+ try:
+ self._stat = do_stat(self._data_file)
+ except (OSError, IOError) as err:
+ if err.errno in (errno.ENOENT, errno.ESTALE):
+ raise DiskFileNotExist
+ raise err
+ if not validate_object(self._metadata, self._stat):
+ # Metadata is stale/invalid. So open the object for reading
+ # to update Etag and other metadata.
+ with
+ return self._metadata
+ else:
+ # Metadata is valid. Don't have to open the file.
+ self._filter_metadata()
+ return self._metadata
def reader(self, iter_hook=None, keep_cache=False):
@@ -1046,9 +1078,9 @@ class DiskFile(object):
errors as the `create()` method.
- metadata = read_metadata(self._data_file)
+ metadata = self._metadata or read_metadata(self._data_file)
except (IOError, OSError) as err:
- if err.errno != errno.ENOENT:
+ if err.errno not in (errno.ESTALE, errno.ENOENT):
if metadata[X_TIMESTAMP] >= timestamp: