From b43a5f125519c83d045a4693ea95eb53d332604c Mon Sep 17 00:00:00 2001 From: Norman Feske Date: Wed, 16 Apr 2014 17:13:25 +0200 Subject: [PATCH] tar_fs: Return correct size of stat'ed dirs Genode's file system interface returns the number of directories multiplied by sizeof(Directory_entry) as size of a directory. The tar_fs server used to return zero. The fix counts the sub nodes of the given directory. --- os/src/server/tar_fs/main.cc | 34 +++++++++++++++++++++++++--------- os/src/server/tar_fs/record.h | 2 +- 2 files changed, 26 insertions(+), 10 deletions(-) diff --git a/os/src/server/tar_fs/main.cc b/os/src/server/tar_fs/main.cc index 900b67685..550876fcf 100644 --- a/os/src/server/tar_fs/main.cc +++ b/os/src/server/tar_fs/main.cc @@ -235,7 +235,7 @@ namespace File_system { Symlink_handle symlink(Dir_handle dir_handle, Name const &name, bool create) { PDBGV("_root = %s, dir_name = %s, name = %s, create = %d", - _root.record()->name(), + _root.record()->name(), _handle_registry.lookup(dir_handle)->record()->name(), name.string(), create); @@ -276,7 +276,7 @@ namespace File_system { Dir_handle dir(Path const &path, bool create) { PDBGV("_root = %s, path = %s, create = %d", - _root.record()->name(), path.string(), create); + _root.record()->name(), path.string(), create); _assert_valid_path(path.string()); @@ -379,20 +379,36 @@ namespace File_system { Node *node = _handle_registry.lookup(node_handle); - status.size = node->record()->size(); - /* convert TAR record modes to stat modes */ switch (node->record()->type()) { - case Record::TYPE_DIR: status.mode |= Status::MODE_DIRECTORY; break; - case Record::TYPE_FILE: status.mode |= Status::MODE_FILE; break; - case Record::TYPE_SYMLINK: status.mode |= Status::MODE_SYMLINK; break; + case Record::TYPE_DIR: + { + status.size = node->record()->size(); + + /* count directory entries */ + Lookup_member_of_path lookup_criterion(node->record()->name(), ~0); + _lookup(&lookup_criterion); + + status.size = lookup_criterion.cnt*sizeof(Directory_entry); + status.mode |= Status::MODE_DIRECTORY; + break; + } + + case Record::TYPE_FILE: + status.size = node->record()->size(); + status.mode |= Status::MODE_FILE; + break; + + case Record::TYPE_SYMLINK: + status.size = node->record()->size(); + status.mode |= Status::MODE_SYMLINK; + break; + default: if (verbose) PWRN("unhandled record type %d", node->record()->type()); } - PDBGV("name = %s", node->record()->name()); - return status; } diff --git a/os/src/server/tar_fs/record.h b/os/src/server/tar_fs/record.h index 219eb9ed1..b2b1556dc 100644 --- a/os/src/server/tar_fs/record.h +++ b/os/src/server/tar_fs/record.h @@ -58,7 +58,7 @@ namespace File_system { /* record type values */ enum { TYPE_FILE = 0, TYPE_HARDLINK = 1, - TYPE_SYMLINK = 2, TYPE_DIR = 5 }; + TYPE_SYMLINK = 2, TYPE_DIR = 5 }; size_t size() const { return _read(_size); } unsigned uid() const { return _read(_uid); }