summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorAxel Dörfler <axeld@pinc-software.de>2008-09-30 14:16:39 (GMT)
committerAxel Dörfler <axeld@pinc-software.de>2008-09-30 14:16:39 (GMT)
commitb2ec044cb8a930fe55b3a3d899f2e854d955f1d5 (patch)
tree401d93643ab7a5aed74f78dd24b0f661ce286233
parent3ddf6441ea7dba1b04169b056a0a48c025df5d02 (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.h13
-rw-r--r--headers/private/fs_shell/fssh_api_wrapper.h1
-rw-r--r--headers/private/fs_shell/fssh_stat.h1
-rw-r--r--src/add-ons/kernel/file_systems/bfs/Inode.cpp42
-rw-r--r--src/add-ons/kernel/file_systems/bfs/Inode.h3
-rw-r--r--src/add-ons/kernel/file_systems/bfs/kernel_interface.cpp5
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!
}