This is the mail archive of the libc-alpha@sourceware.org mailing list for the glibc project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

Re: Extended file stat: Splitting file- and fs-specific info?


On 2012-05-08, at 18:24, Dave Chinner <david@fromorbit.com> wrote:
> On Tue, May 08, 2012 at 09:19:42PM +0100, David Howells wrote:
>> 
>> Should I split the file-specific info and the fs-specific info and make the
>> second optional?  What I'm thinking of is something like this:
>> 
>> Have a file information structure:
>> 
>> struct statx {
>>    /* 0x00 */
>>    uint32_t    st_mask;    /* What results were written */
>>    uint32_t    st_information;    /* Information about the file */
>>    uint16_t    st_mode;    /* File mode */
>>    uint16_t    __spare0[3];
>>    /* 0x10 */
>>    uint32_t    st_uid;        /* User ID of owner */
>>    uint32_t    st_gid;        /* Group ID of owner */
>>    uint32_t    st_nlink;    /* Number of hard links */
>>    uint32_t    st_blksize;    /* Optimal size for filesystem I/O */
>>    /* 0x20 */
>>    struct statx_dev st_rdev;    /* Device ID of special file */
>>    struct statx_dev st_dev;    /* ID of device containing file */
>>    /* 0x30 */
>>    int32_t        st_atime_ns;    /* Last access time (ns part) */
>>    int32_t        st_btime_ns;    /* File creation time (ns part) */
>>    int32_t        st_ctime_ns;    /* Last attribute change time (ns part) */
>>    int32_t        st_mtime_ns;    /* Last data modification time (ns part) */
>>    /* 0x40 */
>>    int64_t        st_atime;    /* Last access time */
>>    int64_t        st_btime;    /* File creation time */
>>    int64_t        st_ctime;    /* Last attribute change time */
>>    int64_t        st_mtime;    /* Last data modification time */
>>    /* 0x60 */
>>    uint64_t    st_ino;        /* Inode number */
>>    uint64_t    st_size;    /* File size */
>>    uint64_t    st_blocks;    /* Number of 512-byte blocks allocated */
>>    uint64_t    st_gen;        /* Inode generation number */
> 
> I don't think we want to expose the inode generation numbers. It is
> trivial to construct NFS file handles (usually just fsid, inode
> number and generation) with that information and hence bypass
> security checks to access files.

At the same time, if the user can stay the file and get this information, that isn't making the sole any less secure than if they can access the file via NFS. They have already passed all of the pathname security checks by the time they can do a statxat() on the file. 

>>    uint64_t    st_version;    /* Data version number */
>>    uint64_t    st_ioc_flags;    /* As FS_IOC_GETFLAGS */
>>    /* 0x90 */
>>    uint64_t    __spare1[13];    /* Spare space for future expansion */
>>    /* 0x100 */
>> };
>> 
>> And an fs information structure for less commonly needed data:

One comment on this struct is that it would probably be better to use sx_ or sf_ as the prefix for these fields. 

>> struct statx_fsinfo {
>>    /* 0x00 - General info */
>>    uint32_t    st_mask;    /* What optional fields are filled in */
>>    uint32_t    st_type;    /* Filesystem type from linux/magic.h */
>> 
>>    /* 0x08 - file timestamp granularity info */
>>    uint16_t    st_atime_gran_mantissa;    /* gran(secs) = mant * 10^exp */
>>    uint16_t    st_btime_gran_mantissa;
>>    uint16_t    st_ctime_gran_mantissa;
>>    uint16_t    st_mtime_gran_mantissa;
>>    /* 0x10 */
>>    int8_t        st_atime_gran_exponent;
>>    int8_t        st_btime_gran_exponent;
>>    int8_t        st_ctime_gran_exponent;
>>    int8_t        st_mtime_gran_exponent;
>> 
>>    /* 0x14 - I/O parameters */
>>    uint32_t    st_blksize;      /* File block size */
>>    uint32_t    st_alloc_blksize; /* Allocation block size/alignment */
>>    uint32_t    st_small_io_size; /* IO size/alignment that avoids fs/page cache RMW */
>>    uint32_t    st_pref_io_size;  /* Preferred IO size for general usage */
>>    uint32_t    st_large_io_size; /* IO size/alignment for high bandwidth sequential IO */
> 
> That's per file information, not per filesystem. XFS definitely
> needs this IO information per-file....

Definitely. Lustre can have wildly different layouts for each file. This will also avoid duplication of st_blksize in both the statx and statx_fsinfo structs. 

The main question I have about these fields is what the difference is between st_blksize and st_alloc_blksize?


>>    /* 0x28 - Restrictions on struct statx contents */
>>    uint64_t    st_supported_ioc_flags; /* FS_IOC_GETFLAGS flags supported  */
>> 
>>    /* 0x30 - Volume/filesystem information */
>>    uint64_t    st_fsid;    /* Short 64-bit Filesystem ID (as statfs) */
>>    uint64_t    __spare0[3];
>>    /* 0x50 */
>>    uint8_t        st_volume_id[16]; /* Volume/fs identifier */
>>    uint8_t        st_volume_uuid[16]; /* Volume/fs UUID */
> 
> And there's all the remaining information needed to construct file
> NFS handles without root priviledges...
> 
>>    /* 0x80 */
>>    uint64_t    __spare1[8];
>>    /* 0xc0 */
>>    uint8_t        st_volume_name[64]; /* Volume name (up to 64 chars) */
>>    /* 0x100 */
>>    uint8_t        st_domain_name[256]; /* Domain/cell/workgroup name (up to 256 chars) */
>>    /* 0x200 */
>> };
>> 
>> One could argue a bit over what goes in which, should we go for this.  This
>> may be better split between multiple syscalls though (with the race that that
>> implies) and potentially merging with statfs.
>> 
>> 
>> The statxat() syscall [nÃe xstat] could then use the 6th parameter thusly:
>> 
>> asmlinkage long sys_statxat(int dfd, const char __user *path, unsigned flags,
>>                unsigned mask, struct statx __user *buffer,
>>                struct statx_fsinfo __user *fsinfo);
>> 
>> 
>> letting fsinfo be NULL to indicate a lack of interest.  I'm not sure we want
>> to do that, though.
>> 
>> 
>> Also, do Dave Chinner's ideas for indicating five I/O parameters want to be
>> 32-bit numbers?  Larger?  Smaller?  Can they be log2?
> 
> Definitely 32 bit, IMO, as it's not uncommon to see optimal IO sizes
> in the tens of megabytes on large, high bandwidth storage systems.
> As for being log2 - that's just making it more complex to use and
> making code ugly - we'd have to convert to log2 in kernel, then
> convert back in every single application....
> 
>> Note also, that I've suggested that we represent the timestamp granularity
>> information as a decimal float (which requires 3 bytes per timestamp) and that
>> we provide separate granularities for each timestamp.
>> 
>> David
>> 
> 
> -- 
> Dave Chinner
> david@fromorbit.com
> --
> To unsubscribe from this list: send the line "unsubscribe linux-ext4" in
> the body of a message to majordomo@vger.kernel.org
> More majordomo info at  http://vger.kernel.org/majordomo-info.html


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]