diff options
| author | Axel Dörfler <axeld@pinc-software.de> | 2008-09-30 14:16:39 (GMT) |
|---|---|---|
| committer | Axel Dörfler <axeld@pinc-software.de> | 2008-09-30 14:16:39 (GMT) |
| commit | b2ec044cb8a930fe55b3a3d899f2e854d955f1d5 (patch) | |
| tree | 401d93643ab7a5aed74f78dd24b0f661ce286233 | |
| parent | 3ddf6441ea7dba1b04169b056a0a48c025df5d02 (diff) | |
* Added stat::st_blocks field as required by POSIX. This also closes tickethrev27791
#2261.
* Made at least BFS report it more or less correctly (the attributes are
ignored, though).
git-svn-id: file:///srv/svn/repos/haiku/haiku/trunk@27791 a95241bf-73f2-0310-859d-f6bbb57e9c96
| -rw-r--r-- | headers/posix/sys/stat.h | 13 | ||||
| -rw-r--r-- | headers/private/fs_shell/fssh_api_wrapper.h | 1 | ||||
| -rw-r--r-- | headers/private/fs_shell/fssh_stat.h | 1 | ||||
| -rw-r--r-- | src/add-ons/kernel/file_systems/bfs/Inode.cpp | 42 | ||||
| -rw-r--r-- | src/add-ons/kernel/file_systems/bfs/Inode.h | 3 | ||||
| -rw-r--r-- | src/add-ons/kernel/file_systems/bfs/kernel_interface.cpp | 5 |
6 files changed, 57 insertions, 8 deletions
diff --git a/headers/posix/sys/stat.h b/headers/posix/sys/stat.h index fea135f..194378a 100644 --- a/headers/posix/sys/stat.h +++ b/headers/posix/sys/stat.h @@ -10,15 +10,15 @@ struct stat { - dev_t st_dev; /* "device" that this file resides on */ - ino_t st_ino; /* this file's inode #, unique per device */ - mode_t st_mode; /* mode bits (rwx for user, group, etc) */ + dev_t st_dev; /* device ID that this file resides on */ + ino_t st_ino; /* this file's serial inode ID */ + mode_t st_mode; /* file mode (rwx for user, group, etc) */ nlink_t st_nlink; /* number of hard links to this file */ - uid_t st_uid; /* user id of the owner of this file */ - gid_t st_gid; /* group id of the owner of this file */ + uid_t st_uid; /* user ID of the owner of this file */ + gid_t st_gid; /* group ID of the owner of this file */ off_t st_size; /* size in bytes of this file */ dev_t st_rdev; /* device type (not used) */ - size_t st_blksize; /* preferred block size for i/o */ + blksize_t st_blksize; /* preferred block size for I/O */ time_t st_atime; /* last access time */ time_t st_mtime; /* last modification time */ time_t st_ctime; /* last change time, not creation time */ @@ -29,6 +29,7 @@ struct stat { * TODO: we should find another solution for this, as BStatable::GetStat() * can only retrieve the R5 stat structure */ unsigned int st_type; /* attribute/index type */ + blkcnt_t st_blocks; /* number of blocks allocated for object */ }; /* extended file types */ diff --git a/headers/private/fs_shell/fssh_api_wrapper.h b/headers/private/fs_shell/fssh_api_wrapper.h index 53f9312..176ea2a 100644 --- a/headers/private/fs_shell/fssh_api_wrapper.h +++ b/headers/private/fs_shell/fssh_api_wrapper.h @@ -1224,6 +1224,7 @@ #define st_ctime fssh_st_ctime #define st_crtime fssh_st_crtime #define st_type fssh_st_type +#define st_blocks fssh_st_blocks /* extended file types */ #define S_ATTR_DIR FSSH_S_ATTR_DIR diff --git a/headers/private/fs_shell/fssh_stat.h b/headers/private/fs_shell/fssh_stat.h index 492c707..94714fa 100644 --- a/headers/private/fs_shell/fssh_stat.h +++ b/headers/private/fs_shell/fssh_stat.h @@ -30,6 +30,7 @@ struct fssh_stat { // TODO: we should find another solution for this, as BStatable::GetStat() // can only retrieve the R5 stat structure unsigned int fssh_st_type; /* attribute/index type */ + fssh_off_t fssh_st_blocks; /* number of blocks allocated for object */ }; typedef struct fssh_stat fssh_struct_stat; diff --git a/src/add-ons/kernel/file_systems/bfs/Inode.cpp b/src/add-ons/kernel/file_systems/bfs/Inode.cpp index 3b2ab1c..89fc99e 100644 --- a/src/add-ons/kernel/file_systems/bfs/Inode.cpp +++ b/src/add-ons/kernel/file_systems/bfs/Inode.cpp @@ -1275,6 +1275,48 @@ Inode::IsEmpty() // #pragma mark - data stream +/*! Computes the number of bytes this inode occupies in the file system. + This includes the file meta blocks used for maintaining its data stream. + + TODO: However, the attributes in extra files are not really accounted for; + depending on the speed penalty, this should be changed, though (the value + could be cached in the inode structure or Inode object, though). +*/ +off_t +Inode::AllocatedSize() const +{ + if (IsSymLink() && (Flags() & INODE_LONG_SYMLINK) == 0) { + // This symlink does not have a data stream + return Node().InodeSize(); + } + + const data_stream& data = Node().data; + uint32 blockSize = fVolume->BlockSize(); + off_t size = blockSize; + + if (data.MaxDoubleIndirectRange() != 0) { + off_t doubleIndirectSize = data.MaxDoubleIndirectRange() + - data.MaxIndirectRange(); + int32 indirectSize = (1L << (INDIRECT_BLOCKS_SHIFT + + fVolume->BlockShift())) * (blockSize / sizeof(block_run)); + + size += (2 * NUM_ARRAY_BLOCKS + doubleIndirectSize / indirectSize) + * blockSize + data.MaxDoubleIndirectRange(); + } else if (data.MaxIndirectRange() != 0) + size += NUM_ARRAY_BLOCKS + data.MaxIndirectRange(); + else + size += data.MaxDirectRange(); + + if (!Node().attributes.IsZero()) { + // TODO: to make this exact, we'd had to count all attributes + size += 2 * blockSize; + // 2 blocks, one for the attributes inode, one for its B+tree + } + + return size; +} + + /*! Finds the block_run where "pos" is located in the data_stream of the inode. If successful, "offset" will then be set to the file offset diff --git a/src/add-ons/kernel/file_systems/bfs/Inode.h b/src/add-ons/kernel/file_systems/bfs/Inode.h index 1167b5a..3547011 100644 --- a/src/add-ons/kernel/file_systems/bfs/Inode.h +++ b/src/add-ons/kernel/file_systems/bfs/Inode.h @@ -76,8 +76,9 @@ public: int32 Flags() const { return fNode.Flags(); } off_t Size() const { return fNode.data.Size(); } + off_t AllocatedSize() const; off_t LastModified() const - { return fNode.last_modified_time; } + { return fNode.LastModifiedTime(); } const block_run& BlockRun() const { return fNode.inode_num; } diff --git a/src/add-ons/kernel/file_systems/bfs/kernel_interface.cpp b/src/add-ons/kernel/file_systems/bfs/kernel_interface.cpp index 7b6601e..5470fa6 100644 --- a/src/add-ons/kernel/file_systems/bfs/kernel_interface.cpp +++ b/src/add-ons/kernel/file_systems/bfs/kernel_interface.cpp @@ -50,11 +50,14 @@ fill_stat_buffer(Inode* inode, struct stat& stat) stat.st_mtime = stat.st_ctime = (time_t)(node.LastModifiedTime() >> INODE_TIME_SHIFT); stat.st_crtime = (time_t)(node.CreateTime() >> INODE_TIME_SHIFT); - if (inode->IsSymLink() && (node.Flags() & INODE_LONG_SYMLINK) == 0) { + if (inode->IsSymLink() && (inode->Flags() & INODE_LONG_SYMLINK) == 0) { // symlinks report the size of the link here stat.st_size = strlen(node.short_symlink); } else stat.st_size = inode->Size(); + + stat.st_blocks = inode->AllocatedSize() / node.InodeSize(); + // TODO: decide for a unit to use for st_blocks! } |
