From patchwork Thu Jul 1 23:57:38 2010 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: David Howells X-Patchwork-Id: 109785 Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by demeter.kernel.org (8.14.4/8.14.3) with ESMTP id o61NwhOm013977 for ; Thu, 1 Jul 2010 23:58:43 GMT Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1755910Ab0GAX54 (ORCPT ); Thu, 1 Jul 2010 19:57:56 -0400 Received: from mx1.redhat.com ([209.132.183.28]:24879 "EHLO mx1.redhat.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1755589Ab0GAX5n (ORCPT ); Thu, 1 Jul 2010 19:57:43 -0400 Received: from int-mx04.intmail.prod.int.phx2.redhat.com (int-mx04.intmail.prod.int.phx2.redhat.com [10.5.11.17]) by mx1.redhat.com (8.13.8/8.13.8) with ESMTP id o61Nvg2t019601 (version=TLSv1/SSLv3 cipher=DHE-RSA-AES256-SHA bits=256 verify=OK); Thu, 1 Jul 2010 19:57:42 -0400 Received: from warthog.cambridge.redhat.com (kibblesnbits.boston.devel.redhat.com [10.16.60.12]) by int-mx04.intmail.prod.int.phx2.redhat.com (8.13.8/8.13.8) with ESMTP id o61NvdfC012940 (version=TLSv1/SSLv3 cipher=DHE-RSA-AES256-SHA bits=256 verify=NO); Thu, 1 Jul 2010 19:57:41 -0400 Received: from [127.0.0.1] (helo=warthog.procyon.org.uk) by warthog.cambridge.redhat.com with esmtp (Exim 4.69 #1 (Red Hat Linux)) id 1OUTdS-0004y0-P7; Fri, 02 Jul 2010 00:57:38 +0100 Organization: Red Hat UK Ltd. Registered Address: Red Hat UK Ltd, Amberley Place, 107-111 Peascod Street, Windsor, Berkshire, SI4 1TE, United Kingdom. Registered in England and Wales under Company Registration No. 3798903 From: David Howells Subject: [PATCH 3/3] xstat: Implement a requestable extra result to procure some inode flags [ver #4] To: linux-fsdevel@vger.kernel.org Cc: dhowells@redhat.com, linux-cifs@vger.kernel.org, linux-kernel@vger.kernel.org, samba-technical@lists.samba.org, linux-ext4@vger.kernel.org Date: Fri, 02 Jul 2010 00:57:38 +0100 Message-ID: <20100701235738.19035.21536.stgit@warthog.procyon.org.uk> In-Reply-To: <20100701235727.19035.84584.stgit@warthog.procyon.org.uk> References: <20100701235727.19035.84584.stgit@warthog.procyon.org.uk> User-Agent: StGIT/0.14.3 MIME-Version: 1.0 X-Scanned-By: MIMEDefang 2.67 on 10.5.11.17 Sender: linux-cifs-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-cifs@vger.kernel.org X-Greylist: IP, sender and recipient auto-whitelisted, not delayed by milter-greylist-4.2.3 (demeter.kernel.org [140.211.167.41]); Thu, 01 Jul 2010 23:58:43 +0000 (UTC) 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)