* Added stat::st_blocks field as required by POSIX. This also closes ticket

#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
This commit is contained in:
Axel Dörfler
2008-09-30 14:16:39 +00:00
parent 3ddf6441ea
commit b2ec044cb8
6 changed files with 57 additions and 8 deletions
+7 -6
View File
@@ -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 */
@@ -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
+1
View File
@@ -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;
@@ -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
+2 -1
View File
@@ -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; }
@@ -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!
}