All of lore.kernel.org
 help / color / mirror / Atom feed
From: Michael Kerrisk <mtk.manpages@gmail.com>
To: David Howells <dhowells@redhat.com>
Cc: linux-cifs@vger.kernel.org, linux-api@vger.kernel.org,
	samba-technical@lists.samba.org, linux-kernel@vger.kernel.org,
	linux-fsdevel@vger.kernel.org, linux-ext4@vger.kernel.org
Subject: Re: [PATCH 3/3] xstat: Implement a requestable extra result to procure some inode flags [ver #4]
Date: Sun, 4 Jul 2010 06:27:30 +0200	[thread overview]
Message-ID: <AANLkTilJVYGllPB5I2lG_MPWgxYSJmHh4dproHx563kT@mail.gmail.com> (raw)
In-Reply-To: <20100701235738.19035.21536.stgit@warthog.procyon.org.uk>

[CC+=linux-api]

On Fri, Jul 2, 2010 at 1:57 AM, David Howells <dhowells@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@andromeda ~]# chattr +ia /var/cache/fscache/cull_atimes
>        [root@andromeda ~]# lsattr /var/cache/fscache/cull_atimes
>        ----ia-------e- /var/cache/fscache/cull_atimes
>        [root@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@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@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/

WARNING: multiple messages have this Message-ID (diff)
From: Michael Kerrisk <mtk.manpages@gmail.com>
To: David Howells <dhowells@redhat.com>
Cc: linux-fsdevel@vger.kernel.org, linux-cifs@vger.kernel.org,
	linux-kernel@vger.kernel.org, samba-technical@lists.samba.org,
	linux-ext4@vger.kernel.org, linux-api@vger.kernel.org
Subject: Re: [PATCH 3/3] xstat: Implement a requestable extra result to  procure some inode flags [ver #4]
Date: Sun, 4 Jul 2010 06:27:30 +0200	[thread overview]
Message-ID: <AANLkTilJVYGllPB5I2lG_MPWgxYSJmHh4dproHx563kT@mail.gmail.com> (raw)
In-Reply-To: <20100701235738.19035.21536.stgit@warthog.procyon.org.uk>

[CC+=linux-api]

On Fri, Jul 2, 2010 at 1:57 AM, David Howells <dhowells@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@andromeda ~]# chattr +ia /var/cache/fscache/cull_atimes
>        [root@andromeda ~]# lsattr /var/cache/fscache/cull_atimes
>        ----ia-------e- /var/cache/fscache/cull_atimes
>        [root@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@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@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/

  parent reply	other threads:[~2010-07-04  4:27 UTC|newest]

Thread overview: 15+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2010-07-01 23:57 [PATCH 1/3] xstat: Add a pair of system calls to make extended file stats available [ver #4] David Howells
2010-07-01 23:57 ` [PATCH 2/3] xstat: Provide a mechanism to gather extra results for [f]xstat() " David Howells
2010-07-01 23:57   ` David Howells
2010-07-01 23:57 ` [PATCH 3/3] xstat: Implement a requestable extra result to procure some inode flags " David Howells
2010-07-01 23:57   ` David Howells
     [not found]   ` <20100701235738.19035.21536.stgit-S6HVgzuS8uM4Awkfq6JHfwNdhmdF6hFW@public.gmane.org>
2010-07-02 17:45     ` Andreas Dilger
2010-07-02 17:45       ` Andreas Dilger
     [not found]       ` <C80B6032-0FB2-4D63-B940-3FE86B52992B-m1MBpc4rdrD3fQ9qLvQP4Q@public.gmane.org>
2010-07-04  4:29         ` Michael Kerrisk
2010-07-04  4:29           ` Michael Kerrisk
2010-07-04  4:27   ` Michael Kerrisk [this message]
2010-07-04  4:27     ` Michael Kerrisk
2010-07-05 15:05   ` David Howells
     [not found] ` <20100701235727.19035.84584.stgit-S6HVgzuS8uM4Awkfq6JHfwNdhmdF6hFW@public.gmane.org>
2010-07-02 11:03   ` [PATCH 1/3] xstat: Add a pair of system calls to make extended file stats available " Nick Piggin
2010-07-02 11:03     ` Nick Piggin
2010-07-02 14:35 ` David Howells

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=AANLkTilJVYGllPB5I2lG_MPWgxYSJmHh4dproHx563kT@mail.gmail.com \
    --to=mtk.manpages@gmail.com \
    --cc=dhowells@redhat.com \
    --cc=linux-api@vger.kernel.org \
    --cc=linux-cifs@vger.kernel.org \
    --cc=linux-ext4@vger.kernel.org \
    --cc=linux-fsdevel@vger.kernel.org \
    --cc=linux-kernel@vger.kernel.org \
    --cc=samba-technical@lists.samba.org \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.