From 88a1bd75a515e348c6cd5f08e98ec9e39b7f66e8 Mon Sep 17 00:00:00 2001 From: Prashanth Pai Date: Mon, 23 May 2016 14:47:38 +0530 Subject: Don't attempt unlink on a non-existing object Problem: getxattr() and unlink() were being called on an object path which was already determined to be non-existent. This resulted in both these syscalls always failing with ENOENT when client issues DELETE request on an object that does not exist. A request to DELETE an object will incur the following DiskFile API calls in sequence: disk_file.read_metadata() disk_file.delete() The above mentioned problem manifests because Swift code invokes disk_file.delete() even when disk_file.read_metadata() has raised DiskFileNotExist. Fix: During disk_file.read_metadata(), make a note that the file does not exist. When disk_file.delete() is called, do not proceed with object deletion. Change-Id: Iaf6915197a8fced7564db8fab80e696dea080c25 Signed-off-by: Prashanth Pai Reviewed-on: http://review.gluster.org/14501 Reviewed-by: Thiago da Silva Tested-by: Thiago da Silva --- gluster/swift/obj/diskfile.py | 14 +++++++++++++- 1 file changed, 13 insertions(+), 1 deletion(-) (limited to 'gluster') diff --git a/gluster/swift/obj/diskfile.py b/gluster/swift/obj/diskfile.py index f140a62..c7240ae 100644 --- a/gluster/swift/obj/diskfile.py +++ b/gluster/swift/obj/diskfile.py @@ -571,6 +571,8 @@ class DiskFile(object): self._stat = None # Don't store a value for data_file until we know it exists. self._data_file = None + # This is used to avoid unlink() on a file that does not exist. + self._disk_file_does_not_exist = False self._account = account # Unused, account = volume self._container = container @@ -752,6 +754,7 @@ class DiskFile(object): self._metadata = read_metadata(self._data_file) except (OSError, IOError) as err: if err.errno in (errno.ENOENT, errno.ESTALE): + self._disk_file_does_not_exist = True raise DiskFileNotExist raise err @@ -762,6 +765,7 @@ class DiskFile(object): self._stat = do_stat(self._data_file) except (OSError, IOError) as err: if err.errno in (errno.ENOENT, errno.ESTALE): + self._disk_file_does_not_exist = True raise DiskFileNotExist raise err @@ -1087,10 +1091,18 @@ class DiskFile(object): :raises DiskFileError: this implementation will raise the same errors as the `create()` method. """ + if self._disk_file_does_not_exist: + # It was determined during disk_file.read_metadata() call that + # the file does not exist. Don't proceed with deletion on a + # non-existing path. + return + try: metadata = self._metadata or read_metadata(self._data_file) except (IOError, OSError) as err: - if err.errno not in (errno.ESTALE, errno.ENOENT): + if err.errno in (errno.ESTALE, errno.ENOENT): + return + else: raise else: if metadata[X_TIMESTAMP] >= timestamp: -- cgit