From: Michael Kerrisk on 4 Jul 2010 00:30 [CC+=linux-api] On Fri, Jul 2, 2010 at 1:57 AM, David Howells <dhowells(a)redhat.com> wrote: > [This is, for the moment, to be considered an example. �Do we actually want to > �export these flags? �Should they be a full member of struct xstat?] Since I suggested the idea, obviously I'm inclined to think they should ;-). Cheers, Michael > Allow an extra result to be requested that makes available some inode flags, > along the lines of BSD's st_flags and Ext2/3/4's inode flags. �This is > requested by setting XSTAT_REQUEST_INODE_FLAGS in the request_mask. �If the > filesystem supports it for that file, then this will be set in result_mask and > 16 bytes of information will be appended to the xstat buffer, if sufficient > buffer space is available. > > The extra result is laid out according to the following structure: > > � � � �struct xstat_inode_flags { > � � � � � � � �unsigned long long � � �st_flags; > � � � � � � � �unsigned long long � � �st_supported_flags; > � � � �}; > > where the filesystem indicates the flags it supports for that file and the > flags that are set on that file. �The structure is of length: > > � � � �XSTAT_LENGTH_INODE_FLAGS > > The flags come in three sets: > > �(1) User settable flags (to be consistent with the BSD st_flags field): > > � � � �UF_NODUMP � � � Do not dump this file. > � � � �UF_IMMUTABLE � �This file is immutable. > � � � �UF_APPEND � � � This file is append-only. > � � � �UF_OPAQUE � � � This directory is opaque (unionfs). > � � � �UF_NOUNLINK � � This file can't be removed or renamed. > � � � �UF_COMPRESSED � This file is compressed. > � � � �UF_HIDDEN � � � This file shouldn't be displayed in a GUI. > > � � The UF_SETTABLE constant is the union of the above flags. > > �(2) Superuser settable flags (to be consistent with the BSD st_flags field): > > � � � �SF_ARCHIVED � � This file has been archived. > � � � �SF_IMMUTABLE � �This file is immutable. > � � � �SF_APPEND � � � This file is append-only. > � � � �SF_NOUNLINK � � This file can't be removed or renamed. > � � � �SF_HIDDEN � � � This file is a snapshot inode. > > � � The SF_SETTABLE constant is the union of the above flags. > > �(3) Linux-specific flags: > > � � � �XSTAT_LF_MAGIC_FILE � � Magic file, such as found in procfs and sysfs. > � � � �XSTAT_LF_SYNC � � � � � File is written synchronously. > � � � �XSTAT_LF_NOATIME � � � �Atime is not updated on this file. > � � � �XSTAT_LF_JOURNALLED_DATA Data modifications to this file are journalled. > � � � �XSTAT_LF_ENCRYPTED � � �This file is encrypted. > � � � �XSTAT_LF_SYSTEM � � � � This file is a system file (FAT/NTFS/CIFS). > � � � �XSTAT_LF_TEMPORARY � � �This file is a temporary file (NTFS/CIFS). > � � � �XSTAT_LF_OFFLINE � � � �file is currently unavailable (CIFS). > > > The Ext4 filesystem has been modified to map certain Ext4 inode flags to the > above: > > � � � �EXT4 FLAG � � � � � � � MAPPED TO > � � � �======================= ======================================= > � � � �EXT4_COMPR_FL � � � � � UF_COMPRESSED > � � � �EXT4_SYNC_FL � � � � � �XSTAT_LF_SYNC > � � � �EXT4_IMMUTABLE_FL � � � UF_IMMUTABLE and SF_IMMUTABLE > � � � �EXT4_APPEND_FL � � � � �UF_APPEND and SF_APPEND > � � � �EXT4_NODUMP_FL � � � � �UF_NODUMP > � � � �EXT4_NOATIME_FL � � � � XSTAT_LF_NOATIME > � � � �EXT4_JOURNAL_DATA_FL � �XSTAT_LF_JOURNALLED_DATA > � � � �EXT4_DIRSYNC_FL � � � � XSTAT_LF_SYNC (directories only) > > With this patch applied, the test program given in the patch that introduced > the xstat() syscalls now does this: > > � � � �[root(a)andromeda ~]# chattr +ia /var/cache/fscache/cull_atimes > � � � �[root(a)andromeda ~]# lsattr /var/cache/fscache/cull_atimes > � � � �----ia-------e- /var/cache/fscache/cull_atimes > � � � �[root(a)andromeda ~]# /tmp/xstat /var/cache/fscache/cull_atimes > � � � �xstat(/var/cache/fscache/cull_atimes) = 168 > � � � �results=5fef > � � � � �Size: 78088 � � � � � Blocks: 168 � � � �IO Block: 4096 � �regular file > � � � �Device: 08:06 � � � � � Inode: 13 � � � � �Links: 1 > � � � �Access: (0600/-rw-------) �Uid: 0 > � � � �Gid: 0 > � � � �Access: 2010-06-29 18:17:41.092290108+0100 > � � � �Modify: 2010-06-25 17:25:53.320261493+0100 > � � � �Change: 2010-07-02 00:46:51.278803967+0100 > � � � �Create: 2010-06-25 15:17:39.711172889+0100 > � � � �Inode version: f585ab73h > � � � �0098: 0000000000060006 0000000e00060027 > > The extra results are hex dumped at the end in 64-bit chunks. �As can be seen > above, st_flags=0x0000000000060006 and st_supported_flags=0000000e00060027. > That's showing that the file now has [SU]F_IMMUTABLE and [SU]F_APPEND enabled. > > Note also that XSTAT_REQUEST_INODE_FLAGS (0x4000) is present in the result_mask > value (0x5fef) returned to userspace, and the amount of data returned by > xstat() has increased from 152 to 168 as appropriate for 16 bytes of extra > data. > > Signed-off-by: David Howells <dhowells(a)redhat.com> > --- > > �fs/ext4/ext4.h � � � | � �2 ++ > �fs/ext4/file.c � � � | � �1 + > �fs/ext4/inode.c � � �| � 50 ++++++++++++++++++++++++++++++++++++++++++++++++++ > �fs/ext4/namei.c � � �| � �2 ++ > �fs/ext4/symlink.c � �| � �2 ++ > �include/linux/stat.h | � 47 ++++++++++++++++++++++++++++++++++++++++++++++- > �6 files changed, 103 insertions(+), 1 deletions(-) > > diff --git a/fs/ext4/ext4.h b/fs/ext4/ext4.h > index 96823f3..26b8dd6 100644 > --- a/fs/ext4/ext4.h > +++ b/fs/ext4/ext4.h > @@ -1573,6 +1573,8 @@ extern int �ext4_getattr(struct vfsmount *mnt, struct dentry *dentry, > � � � � � � � � � � � � � � � �struct kstat *stat); > �extern int �ext4_file_getattr(struct vfsmount *mnt, struct dentry *dentry, > � � � � � � � � � � � � � � � �struct kstat *stat); > +extern int �ext4_getattr_extra(struct vfsmount *, struct dentry *, > + � � � � � � � � � � � � � � �struct xstat_extra_result *); > �extern void ext4_delete_inode(struct inode *); > �extern int �ext4_sync_inode(handle_t *, struct inode *); > �extern void ext4_dirty_inode(struct inode *); > diff --git a/fs/ext4/file.c b/fs/ext4/file.c > index 18c29ab..657ffa0 100644 > --- a/fs/ext4/file.c > +++ b/fs/ext4/file.c > @@ -151,6 +151,7 @@ const struct inode_operations ext4_file_inode_operations = { > � � � �.truncate � � � = ext4_truncate, > � � � �.setattr � � � �= ext4_setattr, > � � � �.getattr � � � �= ext4_file_getattr, > + � � � .getattr_extra �= ext4_getattr_extra, > �#ifdef CONFIG_EXT4_FS_XATTR > � � � �.setxattr � � � = generic_setxattr, > � � � �.getxattr � � � = generic_getxattr, > diff --git a/fs/ext4/inode.c b/fs/ext4/inode.c > index f9a730a..efa17d6 100644 > --- a/fs/ext4/inode.c > +++ b/fs/ext4/inode.c > @@ -5595,6 +5595,56 @@ int ext4_file_getattr(struct vfsmount *mnt, struct dentry *dentry, > � � � �return 0; > �} > > +int ext4_getattr_inode_flags(struct inode *inode, > + � � � � � � � � � � � � � �struct xstat_extra_result *extra) > +{ > + � � � struct ext4_inode_info *ei = EXT4_I(inode); > + � � � struct xstat_inode_flags xif = { 0, 0 }; > + > +#define _(FL, ST) � � � � � � � � � �\ > + � � � xif.st_supported_flags |= ST; \ > + � � � if (ei->i_flags & FL) � � � � \ > + � � � � � � � xif.st_flags |= ST; > + > + � � � _(EXT4_COMPR_FL, � � � �UF_COMPRESSED); > + � � � _(EXT4_SYNC_FL, � � � � XSTAT_LF_SYNC); > + � � � _(EXT4_IMMUTABLE_FL, � �UF_IMMUTABLE | SF_IMMUTABLE); > + � � � _(EXT4_APPEND_FL, � � � UF_APPEND | SF_APPEND); > + � � � _(EXT4_NODUMP_FL, � � � UF_NODUMP); > + � � � _(EXT4_NOATIME_FL, � � �XSTAT_LF_NOATIME); > + � � � _(EXT4_JOURNAL_DATA_FL, XSTAT_LF_JOURNALLED_DATA); > + > + � � � if (S_ISDIR(ei->vfs_inode.i_mode)) > + � � � � � � � _(EXT4_DIRSYNC_FL, � � �XSTAT_LF_SYNC); > + > + � � � return extra->pass_result(extra, ilog2(XSTAT_REQUEST_INODE_FLAGS), > + � � � � � � � � � � � � � � � � &xif, sizeof(xif)); > +} > + > +int ext4_getattr_extra(struct vfsmount *mnt, struct dentry *dentry, > + � � � � � � � � � � �struct xstat_extra_result *extra) > +{ > + � � � struct inode *inode = dentry->d_inode; > + � � � u64 request_mask = extra->request_mask; > + � � � int request, ret; > + > + � � � do { > + � � � � � � � request = __ffs64(request_mask); > + � � � � � � � request_mask &= ~(1ULL << request); > + > + � � � � � � � switch (request) { > + � � � � � � � case ilog2(XSTAT_REQUEST_INODE_FLAGS): > + � � � � � � � � � � � ret = ext4_getattr_inode_flags(inode, extra); > + � � � � � � � � � � � break; > + � � � � � � � default: > + � � � � � � � � � � � ret = 0; > + � � � � � � � � � � � break; > + � � � � � � � } > + > + � � � } while (ret == 0 && request_mask); > + � � � return ret; > +} > + > �static int ext4_indirect_trans_blocks(struct inode *inode, int nrblocks, > � � � � � � � � � � � � � � � � � � �int chunk) > �{ > diff --git a/fs/ext4/namei.c b/fs/ext4/namei.c > index 0f776c7..3c37b3f 100644 > --- a/fs/ext4/namei.c > +++ b/fs/ext4/namei.c > @@ -2543,6 +2543,7 @@ const struct inode_operations ext4_dir_inode_operations = { > � � � �.rename � � � � = ext4_rename, > � � � �.setattr � � � �= ext4_setattr, > � � � �.getattr � � � �= ext4_getattr, > + � � � .getattr_extra �= ext4_getattr_extra, > �#ifdef CONFIG_EXT4_FS_XATTR > � � � �.setxattr � � � = generic_setxattr, > � � � �.getxattr � � � = generic_getxattr, > @@ -2556,6 +2557,7 @@ const struct inode_operations ext4_dir_inode_operations = { > �const struct inode_operations ext4_special_inode_operations = { > � � � �.setattr � � � �= ext4_setattr, > � � � �.getattr � � � �= ext4_getattr, > + � � � .getattr_extra �= ext4_getattr_extra, > �#ifdef CONFIG_EXT4_FS_XATTR > � � � �.setxattr � � � = generic_setxattr, > � � � �.getxattr � � � = generic_getxattr, > diff --git a/fs/ext4/symlink.c b/fs/ext4/symlink.c > index d8fe7fb..8c206b2 100644 > --- a/fs/ext4/symlink.c > +++ b/fs/ext4/symlink.c > @@ -36,6 +36,7 @@ const struct inode_operations ext4_symlink_inode_operations = { > � � � �.put_link � � � = page_put_link, > � � � �.setattr � � � �= ext4_setattr, > � � � �.getattr � � � �= ext4_getattr, > + � � � .getattr_extra �= ext4_getattr_extra, > �#ifdef CONFIG_EXT4_FS_XATTR > � � � �.setxattr � � � = generic_setxattr, > � � � �.getxattr � � � = generic_getxattr, > @@ -49,6 +50,7 @@ const struct inode_operations ext4_fast_symlink_inode_operations = { > � � � �.follow_link � �= ext4_follow_link, > � � � �.setattr � � � �= ext4_setattr, > � � � �.getattr � � � �= ext4_getattr, > + � � � .getattr_extra �= ext4_getattr_extra, > �#ifdef CONFIG_EXT4_FS_XATTR > � � � �.setxattr � � � = generic_setxattr, > � � � �.getxattr � � � = generic_getxattr, > diff --git a/include/linux/stat.h b/include/linux/stat.h > index 9e27f88..4c87878 100644 > --- a/include/linux/stat.h > +++ b/include/linux/stat.h > @@ -107,7 +107,8 @@ struct xstat_parameters { > �#define XSTAT_REQUEST_GEN � � � � � � �0x00001000ULL � /* want/got st_gen */ > �#define XSTAT_REQUEST_DATA_VERSION � � 0x00002000ULL � /* want/got st_data_version */ > �#define XSTAT_REQUEST__EXTENDED_STATS �0x00003fffULL � /* the stuff in the xstat struct */ > -#define XSTAT_REQUEST__ALL_STATS � � � 0x00003fffULL � /* the defined set of requestables */ > +#define XSTAT_REQUEST_INODE_FLAGS � � �0x00004000ULL � /* want/got xstat_inode_flags */ > +#define XSTAT_REQUEST__ALL_STATS � � � 0x00007fffULL � /* the defined set of requestables */ > �#define XSTAT_REQUEST__EXTRA_STATS � � (XSTAT_REQUEST__ALL_STATS & ~XSTAT_REQUEST__EXTENDED_STATS) > �}; > > @@ -140,6 +141,50 @@ struct xstat { > � � � �unsigned long long � � �st_extra_results[0]; /* extra requested results */ > �}; > > +/* > + * Extra result field for inode flags (XSTAT_REQUEST_INODE_FLAGS) > + */ > +struct xstat_inode_flags { > + � � � /* Flags set on the file > + � � � �* - the LSW matches the BSD st_flags > + � � � �* - the MSW are Linux-specific > + � � � �*/ > + � � � unsigned long long � � �st_flags; > + � � � /* st_flags that users can set */ > +#define UF_SETTABLE � �0x0000ffff > +#define UF_NODUMP � � �0x00000001 � � �/* do not dump */ > +#define UF_IMMUTABLE � 0x00000002 � � �/* immutable */ > +#define UF_APPEND � � �0x00000004 � � �/* append-only */ > +#define UF_OPAQUE � � �0x00000008 � � �/* directory is opaque (unionfs) */ > +#define UF_NOUNLINK � �0x00000010 � � �/* can't be removed or renamed */ > +#define UF_COMPRESSED �0x00000020 � � �/* file is compressed */ > +#define UF_HIDDEN � � �0x00008000 � � �/* file shouldn't be displayed in a GUI */ > + > + � � � /* st_flags that only root can set */ > +#define SF_SETTABLE � �0xffff0000 > +#define SF_ARCHIVED � �0x00010000 � � �/* archived */ > +#define SF_IMMUTABLE � 0x00020000 � � �/* immutable */ > +#define SF_APPEND � � �0x00040000 � � �/* append-only */ > +#define SF_NOUNLINK � �0x00100000 � � �/* can't be removed or renamed */ > +#define SF_SNAPSHOT � �0x00200000 � � �/* snapshot inode */ > + > + � � � /* Linux-specific st_flags */ > +#define XSTAT_LF_MAGIC_FILE � �(1ULL << 32) � �/* magic file, such as /proc/? and /sys/? */ > +#define XSTAT_LF_SYNC � � � � �(1ULL << 33) � �/* file is written synchronously */ > +#define XSTAT_LF_NOATIME � � � (1ULL << 34) � �/* atime is not updated on file */ > +#define XSTAT_LF_JOURNALLED_DATA (1ULL << 35) �/* data modifications to file are journalled */ > +#define XSTAT_LF_ENCRYPTED � � (1ULL << 36) � �/* file is encrypted */ > +#define XSTAT_LF_SYSTEM � � � � � � � �(1ULL << 37) � �/* system file */ > +#define XSTAT_LF_TEMPORARY � � (1ULL << 38) � �/* temporary file */ > +#define XSTAT_LF_OFFLINE � � � (1ULL << 39) � �/* file is currently unavailable */ > + > + � � � /* Which st_flags are actually supported by this filesystem for this > + � � � �* file */ > + � � � unsigned long long � � �st_supported_flags; > +}; > +#define XSTAT_LENGTH_INODE_FLAGS (sizeof(struct xstat_inode_flags)) > + > + > �#ifdef __KERNEL__ > �#define S_IRWXUGO � � �(S_IRWXU|S_IRWXG|S_IRWXO) > �#define S_IALLUGO � � �(S_ISUID|S_ISGID|S_ISVTX|S_IRWXUGO) > > -- > To unsubscribe from this list: send the line "unsubscribe linux-fsdevel" in > the body of a message to majordomo(a)vger.kernel.org > More majordomo info at �http://vger.kernel.org/majordomo-info.html > -- Michael Kerrisk Linux man-pages maintainer; http://www.kernel.org/doc/man-pages/ Author of "The Linux Programming Interface", http://blog.man7.org/ -- To unsubscribe from this list: send the line "unsubscribe linux-kernel" in the body of a message to majordomo(a)vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html Please read the FAQ at http://www.tux.org/lkml/
From: Michael Kerrisk on 4 Jul 2010 00:40 [CC+=linux-api] On Fri, Jul 2, 2010 at 7:45 PM, Andreas Dilger <adilger(a)dilger.ca> wrote: > On 2010-07-01, at 17:57, David Howells wrote: >> [This is, for the moment, to be considered an example. �Do we actually want to >> export these flags? �Should they be a full member of struct xstat?] > > I would say this should be a full-fledged member of struct xstat. > I think they are fairly standard (available on many filesystems > today), and requiring an ioctl to access them is unpleasant. > >> (1) User settable flags (to be consistent with the BSD st_flags field): >> >> � � � UF_NODUMP � � � Do not dump this file. >> � � � UF_IMMUTABLE � �This file is immutable. >> � � � UF_APPEND � � � This file is append-only. >> � � � UF_OPAQUE � � � This directory is opaque (unionfs). >> � � � UF_NOUNLINK � � This file can't be removed or renamed. >> � � � UF_COMPRESSED � This file is compressed. >> � � � UF_HIDDEN � � � This file shouldn't be displayed in a GUI. >> >> � �The UF_SETTABLE constant is the union of the above flags. >> >> (2) Superuser settable flags (to be consistent with the BSD st_flags field): >> >> � � � SF_ARCHIVED � � This file has been archived. >> � � � SF_IMMUTABLE � �This file is immutable. >> � � � SF_APPEND � � � This file is append-only. >> � � � SF_NOUNLINK � � This file can't be removed or renamed. >> � � � SF_HIDDEN � � � This file is a snapshot inode. >> >> � �The SF_SETTABLE constant is the union of the above flags. >> >> (3) Linux-specific flags: >> >> � � � XSTAT_LF_MAGIC_FILE � � Magic file, such as found in procfs and sysfs. >> � � � XSTAT_LF_SYNC � � � � � File is written synchronously. >> � � � XSTAT_LF_NOATIME � � � �Atime is not updated on this file. >> � � � XSTAT_LF_JOURNALLED_DATA Data modifications to this file are journalled. >> � � � XSTAT_LF_ENCRYPTED � � �This file is encrypted. >> � � � XSTAT_LF_SYSTEM � � � � This file is a system file (FAT/NTFS/CIFS). >> � � � XSTAT_LF_TEMPORARY � � �This file is a temporary file (NTFS/CIFS). >> � � � XSTAT_LF_OFFLINE � � � �file is currently unavailable (CIFS). > > Yuck on the names. �Why not stick with the "UF_" and "SF_" prefixes? > Since we don't need to keep _binary_ compatibility with these flag values > (only name portability) we can use the same flag values as the > FS_*_FL definitions in fs.h. �That is what all of the existing filesystems > already use (ext2/3/4, ocfs, btrfs, reiserfs, xfs, jfs). Agree on the naming. Andreas expresses what I intended when I proposed the idea. Cheers, Michael -- Michael Kerrisk Linux man-pages maintainer; http://www.kernel.org/doc/man-pages/ Author of "The Linux Programming Interface", http://blog.man7.org/ -- To unsubscribe from this list: send the line "unsubscribe linux-kernel" in the body of a message to majordomo(a)vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html Please read the FAQ at http://www.tux.org/lkml/
|
Pages: 1 Prev: VIDEO: ivtvfb, remove unneeded NULL test Next: [PATCH] nilfs2: remove BKL uses |