Skip to content

Commit

Permalink
Merge pull request #48 from ThomasWaldmann/fix-dirsize
Browse files Browse the repository at this point in the history
give up trying to do anything with a directory's "size"
  • Loading branch information
ThomasWaldmann authored Sep 21, 2024
2 parents df20590 + 9367918 commit aab79b6
Show file tree
Hide file tree
Showing 4 changed files with 13 additions and 19 deletions.
8 changes: 2 additions & 6 deletions src/borgstore/backends/posixfs.py
Original file line number Diff line number Diff line change
Expand Up @@ -92,8 +92,7 @@ def info(self, name):
return ItemInfo(name=path.name, exists=False, directory=False, size=0)
else:
is_dir = stat.S_ISDIR(st.st_mode)
size = 0 if is_dir else st.st_size
return ItemInfo(name=path.name, exists=True, directory=is_dir, size=size)
return ItemInfo(name=path.name, exists=True, directory=is_dir, size=st.st_size)

def load(self, name, *, size=None, offset=0):
if not self.opened:
Expand Down Expand Up @@ -165,7 +164,4 @@ def list(self, name):
pass
else:
is_dir = stat.S_ISDIR(st.st_mode)
# sadly, there is no reliable(!) st_nlink, thus we can't return size=0 for empty dirs.
# on macOS 13, it worked, on Linux (github CI), it didn't.
size = 1 if is_dir else st.st_size
yield ItemInfo(name=p.name, exists=True, size=size, directory=is_dir)
yield ItemInfo(name=p.name, exists=True, size=st.st_size, directory=is_dir)
7 changes: 2 additions & 5 deletions src/borgstore/backends/sftp.py
Original file line number Diff line number Diff line change
Expand Up @@ -176,8 +176,7 @@ def info(self, name):
return ItemInfo(name=name, exists=False, directory=False, size=0)
else:
is_dir = stat.S_ISDIR(st.st_mode)
size = 0 if is_dir else st.st_size
return ItemInfo(name=name, exists=True, directory=is_dir, size=size)
return ItemInfo(name=name, exists=True, directory=is_dir, size=st.st_size)

def load(self, name, *, size=None, offset=0):
if not self.opened:
Expand Down Expand Up @@ -247,6 +246,4 @@ def list(self, name):
for info in sorted(infos, key=lambda i: i.filename):
if not info.filename.endswith(TMP_SUFFIX):
is_dir = stat.S_ISDIR(info.st_mode)
# sadly, there is no st_nlink, thus we can't return size=0 for empty dirs.
size = 1 if is_dir else info.st_size
yield ItemInfo(name=info.filename, exists=True, size=size, directory=is_dir)
yield ItemInfo(name=info.filename, exists=True, size=info.st_size, directory=is_dir)
6 changes: 2 additions & 4 deletions src/borgstore/store.py
Original file line number Diff line number Diff line change
Expand Up @@ -247,10 +247,8 @@ def _list(self, name: str, deleted: bool = False) -> Iterator[ItemInfo]:
self._stats["list_time"] += end - start
if info.directory:
# note: we only expect subdirectories from key nesting, but not namespaces nested into each other.
if info.size > 0:
# if backend returns info.size == 0 for a directory, it indicates that there is nothing inside it.
subdir_name = (name + "/" + info.name) if name else info.name
yield from self._list(subdir_name, deleted=deleted)
subdir_name = (name + "/" + info.name) if name else info.name
yield from self._list(subdir_name, deleted=deleted)
else:
is_deleted = info.name.endswith(DEL_SUFFIX)
if deleted and is_deleted:
Expand Down
11 changes: 7 additions & 4 deletions tests/test_backends.py
Original file line number Diff line number Diff line change
Expand Up @@ -172,7 +172,6 @@ def test_namespaced(tested_backends, request):
ins0 = backend.info(ns0)
assert ins0.exists
assert ins0.directory
assert ins0.size == 0

backend.mkdir(ns1)
backend.store(ns1 + "/" + k1, v1)
Expand Down Expand Up @@ -240,9 +239,13 @@ def test_list(tested_backends, request):
assert len(items) == 3
assert ItemInfo(name=k0, exists=True, size=len(v0), directory=False) in items
assert ItemInfo(name=k1, exists=True, size=len(v1), directory=False) in items
# currently, all backends return size==1 for directories as they can't reliably signal
# an empty directory via size==0.
assert ItemInfo(name="dir", exists=True, size=1, directory=True) in items
# for "dir", we do not know what size the backend has returned.
# that is rather OS / fs / backend specific.
matching_items = [item for item in items if item.name == "dir"]
assert len(matching_items) == 1
dir_item = matching_items[0]
assert dir_item.exists
assert dir_item.directory

items = list(backend.list("dir"))
assert items == []
Expand Down

0 comments on commit aab79b6

Please sign in to comment.