* 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:
@@ -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
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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!
|
||||
}
|
||||
|
||||
|
||||
|
||||
Reference in New Issue
Block a user