diff --git a/swift/obj/diskfile.py b/swift/obj/diskfile.py index 9697d9d8f8..a8d14dfa2f 100644 --- a/swift/obj/diskfile.py +++ b/swift/obj/diskfile.py @@ -1605,14 +1605,22 @@ class DiskFile(object): """ if not exists(self._tmpdir): mkdirs(self._tmpdir) - fd, tmppath = mkstemp(dir=self._tmpdir) + try: + fd, tmppath = mkstemp(dir=self._tmpdir) + except OSError as err: + if err.errno in (errno.ENOSPC, errno.EDQUOT): + # No more inodes in filesystem + raise DiskFileNoSpace() + raise dfw = None try: if size is not None and size > 0: try: fallocate(fd, size) - except OSError: - raise DiskFileNoSpace() + except OSError as err: + if err.errno in (errno.ENOSPC, errno.EDQUOT): + raise DiskFileNoSpace() + raise dfw = DiskFileWriter(self._name, self._datadir, fd, tmppath, self._bytes_per_sync, self._threadpool) yield dfw diff --git a/test/unit/obj/test_diskfile.py b/test/unit/obj/test_diskfile.py index 22fd17aa1b..cc6747555c 100644 --- a/test/unit/obj/test_diskfile.py +++ b/test/unit/obj/test_diskfile.py @@ -1595,16 +1595,56 @@ class TestDiskFile(unittest.TestCase): def test_create_prealloc_oserror(self): df = self.df_mgr.get_diskfile(self.existing_device, '0', 'abc', '123', 'xyz') + for e in (errno.ENOSPC, errno.EDQUOT): + with mock.patch("swift.obj.diskfile.fallocate", + mock.MagicMock(side_effect=OSError( + e, os.strerror(e)))): + try: + with df.create(size=200): + pass + except DiskFileNoSpace: + pass + else: + self.fail("Expected exception DiskFileNoSpace") + + # Other OSErrors must not be raised as DiskFileNoSpace with mock.patch("swift.obj.diskfile.fallocate", mock.MagicMock(side_effect=OSError( errno.EACCES, os.strerror(errno.EACCES)))): try: with df.create(size=200): pass - except DiskFileNoSpace: + except OSError: pass else: - self.fail("Expected exception DiskFileNoSpace") + self.fail("Expected exception OSError") + + def test_create_mkstemp_no_space(self): + df = self.df_mgr.get_diskfile(self.existing_device, '0', 'abc', '123', + 'xyz') + for e in (errno.ENOSPC, errno.EDQUOT): + with mock.patch("swift.obj.diskfile.mkstemp", + mock.MagicMock(side_effect=OSError( + e, os.strerror(e)))): + try: + with df.create(size=200): + pass + except DiskFileNoSpace: + pass + else: + self.fail("Expected exception DiskFileNoSpace") + + # Other OSErrors must not be raised as DiskFileNoSpace + with mock.patch("swift.obj.diskfile.mkstemp", + mock.MagicMock(side_effect=OSError( + errno.EACCES, os.strerror(errno.EACCES)))): + try: + with df.create(size=200): + pass + except OSError: + pass + else: + self.fail("Expected exception OSError") def test_create_close_oserror(self): df = self.df_mgr.get_diskfile(self.existing_device, '0', 'abc', '123', diff --git a/test/unit/obj/test_server.py b/test/unit/obj/test_server.py index c8974deb42..1823a90140 100755 --- a/test/unit/obj/test_server.py +++ b/test/unit/obj/test_server.py @@ -4041,7 +4041,7 @@ class TestObjectController(unittest.TestCase): return '' def fake_fallocate(fd, size): - raise OSError(42, 'Unable to fallocate(%d)' % size) + raise OSError(errno.ENOSPC, os.strerror(errno.ENOSPC)) orig_fallocate = diskfile.fallocate try: