All of lore.kernel.org
 help / color / mirror / Atom feed
From: Oleg Drokin <green@linuxhacker.ru>
To: linux-fsdevel@vger.kernel.org
Subject: [PATCH 1/3] VFS "stat light" out of fstatat, and fine grained flags
Date: Wed, 8 Apr 2009 03:15:24 +0400	[thread overview]
Message-ID: <20090407231524.GA1569655@fiona.linuxhacker.ru> (raw)

[-- Attachment #1: Type: text/plain, Size: 746 bytes --]

Hello!

   This is reworked Mark Fasheh's patch + my earlier patch.
   It allows one to specify which specific struct stat fields are needed
   out of the fstatat call, and also a request to obtain most uptodate
   information for inode (for NFS mostly).

   Also it adds AT_STAT_SELF flag to mean that the stat should be executed not
   on a path, but on the passed filedecriptor itself.

   A first real kernel user for this added in loop block driver that does
   not care about size or anything else besides rdev and inode number.

   I see various architectures replicate bits of vfs_*stat* in some compat
   code, I am not sure if we need to update those as well or not.

   This patch does away with all the extra syscalls.

Bye,
    Oleg

[-- Attachment #2: stat_light_vfs.diff --]
[-- Type: text/plain, Size: 21422 bytes --]

 arch/arm/kernel/sys_oabi-compat.c |    6 +--
 arch/ia64/ia32/sys_ia32.c         |    2 -
 arch/s390/kernel/compat_linux.c   |    6 +--
 arch/sparc/kernel/sys_sparc32.c   |    6 +--
 arch/x86/ia32/sys_ia32.c          |    6 +--
 drivers/block/loop.c              |    3 +
 fs/compat.c                       |   10 ++---
 fs/libfs.c                        |    2 -
 fs/nfsd/nfs3proc.c                |    2 -
 fs/nfsd/nfs3xdr.c                 |    5 +-
 fs/nfsd/nfs4xdr.c                 |    5 +-
 fs/nfsd/nfsproc.c                 |    6 +--
 fs/nfsd/nfsxdr.c                  |    3 +
 fs/stat.c                         |   64 +++++++++++++++++++++++---------------
 include/linux/fcntl.h             |   31 ++++++++++++++++++
 include/linux/fs.h                |   14 ++++----
 16 files changed, 112 insertions(+), 59 deletions(-)

Index: linux-2.6.29/arch/arm/kernel/sys_oabi-compat.c
===================================================================
--- linux-2.6.29.orig/arch/arm/kernel/sys_oabi-compat.c	2009-04-07 17:39:39.000000000 -0400
+++ linux-2.6.29/arch/arm/kernel/sys_oabi-compat.c	2009-04-07 18:21:49.000000000 -0400
@@ -164,7 +164,7 @@
 				 struct oldabi_stat64 __user * statbuf)
 {
 	struct kstat stat;
-	int error = vfs_fstat(fd, &stat);
+	int error = vfs_fstat(fd, &stat, STAT_EVERYTHING);
 	if (!error)
 		error = cp_oldabi_stat64(&stat, statbuf);
 	return error;
@@ -182,9 +182,9 @@
 		goto out;
 
 	if (flag & AT_SYMLINK_NOFOLLOW)
-		error = vfs_lstat_fd(dfd, filename, &stat);
+		error = vfs_lstat_fd(dfd, filename, &stat, flag);
 	else
-		error = vfs_stat_fd(dfd, filename, &stat);
+		error = vfs_stat_fd(dfd, filename, &stat, flag);
 
 	if (!error)
 	error = cp_oldabi_stat64(&stat, statbuf);
Index: linux-2.6.29/arch/s390/kernel/compat_linux.c
===================================================================
--- linux-2.6.29.orig/arch/s390/kernel/compat_linux.c	2009-04-07 17:39:39.000000000 -0400
+++ linux-2.6.29/arch/s390/kernel/compat_linux.c	2009-04-07 18:48:11.000000000 -0400
@@ -692,7 +692,7 @@
 asmlinkage long sys32_fstat64(unsigned long fd, struct stat64_emu31 __user * statbuf)
 {
 	struct kstat stat;
-	int ret = vfs_fstat(fd, &stat);
+	int ret = vfs_fstat(fd, &stat, STAT_EVERYTHING);
 	if (!ret)
 		ret = cp_stat64(statbuf, &stat);
 	return ret;
@@ -708,9 +708,9 @@
 		goto out;
 
 	if (flag & AT_SYMLINK_NOFOLLOW)
-		error = vfs_lstat_fd(dfd, filename, &stat);
+		error = vfs_lstat_fd(dfd, filename, &stat, flag);
 	else
-		error = vfs_stat_fd(dfd, filename, &stat);
+		error = vfs_stat_fd(dfd, filename, &stat, flag);
 
 	if (!error)
 		error = cp_stat64(statbuf, &stat);
Index: linux-2.6.29/arch/sparc/kernel/sys_sparc32.c
===================================================================
--- linux-2.6.29.orig/arch/sparc/kernel/sys_sparc32.c	2009-04-07 17:39:39.000000000 -0400
+++ linux-2.6.29/arch/sparc/kernel/sys_sparc32.c	2009-04-07 18:48:39.000000000 -0400
@@ -195,7 +195,7 @@
 		struct compat_stat64 __user * statbuf)
 {
 	struct kstat stat;
-	int error = vfs_fstat(fd, &stat);
+	int error = vfs_fstat(fd, &stat, STAT_EVERYTHING);
 
 	if (!error)
 		error = cp_compat_stat64(&stat, statbuf);
@@ -212,9 +212,9 @@
 		goto out;
 
 	if (flag & AT_SYMLINK_NOFOLLOW)
-		error = vfs_lstat_fd(dfd, filename, &stat);
+		error = vfs_lstat_fd(dfd, filename, &stat, flag);
 	else
-		error = vfs_stat_fd(dfd, filename, &stat);
+		error = vfs_stat_fd(dfd, filename, &stat, flag);
 
 	if (!error)
 		error = cp_compat_stat64(&stat, statbuf);
Index: linux-2.6.29/arch/x86/ia32/sys_ia32.c
===================================================================
--- linux-2.6.29.orig/arch/x86/ia32/sys_ia32.c	2009-04-07 17:39:39.000000000 -0400
+++ linux-2.6.29/arch/x86/ia32/sys_ia32.c	2009-04-07 18:48:59.000000000 -0400
@@ -119,7 +119,7 @@
 asmlinkage long sys32_fstat64(unsigned int fd, struct stat64 __user *statbuf)
 {
 	struct kstat stat;
-	int ret = vfs_fstat(fd, &stat);
+	int ret = vfs_fstat(fd, &stat, STAT_EVERYTHING);
 	if (!ret)
 		ret = cp_stat64(statbuf, &stat);
 	return ret;
@@ -135,9 +135,9 @@
 		goto out;
 
 	if (flag & AT_SYMLINK_NOFOLLOW)
-		error = vfs_lstat_fd(dfd, filename, &stat);
+		error = vfs_lstat_fd(dfd, filename, &stat, flag);
 	else
-		error = vfs_stat_fd(dfd, filename, &stat);
+		error = vfs_stat_fd(dfd, filename, &stat, flag);
 
 	if (!error)
 		error = cp_stat64(statbuf, &stat);
Index: linux-2.6.29/drivers/block/loop.c
===================================================================
--- linux-2.6.29.orig/drivers/block/loop.c	2009-04-07 17:39:39.000000000 -0400
+++ linux-2.6.29/drivers/block/loop.c	2009-04-07 17:49:36.000000000 -0400
@@ -1027,7 +1027,8 @@
 
 	if (lo->lo_state != Lo_bound)
 		return -ENXIO;
-	error = vfs_getattr(file->f_path.mnt, file->f_path.dentry, &stat);
+	error = vfs_getattr(file->f_path.mnt, file->f_path.dentry, &stat,
+			    STAT_INO|STAT_RDEV);
 	if (error)
 		return error;
 	memset(info, 0, sizeof(*info));
Index: linux-2.6.29/fs/compat.c
===================================================================
--- linux-2.6.29.orig/fs/compat.c	2009-04-07 17:39:39.000000000 -0400
+++ linux-2.6.29/fs/compat.c	2009-04-07 18:49:18.000000000 -0400
@@ -180,7 +180,7 @@
 		struct compat_stat __user *statbuf)
 {
 	struct kstat stat;
-	int error = vfs_stat_fd(AT_FDCWD, filename, &stat);
+	int error = vfs_stat_fd(AT_FDCWD, filename, &stat, STAT_EVERYTHING);
 
 	if (!error)
 		error = cp_compat_stat(&stat, statbuf);
@@ -191,7 +191,7 @@
 		struct compat_stat __user *statbuf)
 {
 	struct kstat stat;
-	int error = vfs_lstat_fd(AT_FDCWD, filename, &stat);
+	int error = vfs_lstat_fd(AT_FDCWD, filename, &stat, STAT_EVERYTHING);
 
 	if (!error)
 		error = cp_compat_stat(&stat, statbuf);
@@ -209,9 +209,9 @@
 		goto out;
 
 	if (flag & AT_SYMLINK_NOFOLLOW)
-		error = vfs_lstat_fd(dfd, filename, &stat);
+		error = vfs_lstat_fd(dfd, filename, &stat, flag);
 	else
-		error = vfs_stat_fd(dfd, filename, &stat);
+		error = vfs_stat_fd(dfd, filename, &stat, flag);
 
 	if (!error)
 		error = cp_compat_stat(&stat, statbuf);
@@ -225,7 +225,7 @@
 		struct compat_stat __user * statbuf)
 {
 	struct kstat stat;
-	int error = vfs_fstat(fd, &stat);
+	int error = vfs_fstat(fd, &stat, STAT_EVERYTHING);
 
 	if (!error)
 		error = cp_compat_stat(&stat, statbuf);
Index: linux-2.6.29/fs/libfs.c
===================================================================
--- linux-2.6.29.orig/fs/libfs.c	2009-04-07 17:39:39.000000000 -0400
+++ linux-2.6.29/fs/libfs.c	2009-04-07 17:44:22.000000000 -0400
@@ -13,7 +13,7 @@
 #include <asm/uaccess.h>
 
 int simple_getattr(struct vfsmount *mnt, struct dentry *dentry,
-		   struct kstat *stat)
+		   struct kstat *stat, int flags)
 {
 	struct inode *inode = dentry->d_inode;
 	generic_fillattr(inode, stat);
Index: linux-2.6.29/fs/nfsd/nfs3proc.c
===================================================================
--- linux-2.6.29.orig/fs/nfsd/nfs3proc.c	2009-04-07 17:39:39.000000000 -0400
+++ linux-2.6.29/fs/nfsd/nfs3proc.c	2009-04-07 17:44:22.000000000 -0400
@@ -69,7 +69,7 @@
 		RETURN_STATUS(nfserr);
 
 	err = vfs_getattr(resp->fh.fh_export->ex_path.mnt,
-			  resp->fh.fh_dentry, &resp->stat);
+			  resp->fh.fh_dentry, &resp->stat, STAT_EVERYTHING);
 	nfserr = nfserrno(err);
 
 	RETURN_STATUS(nfserr);
Index: linux-2.6.29/fs/nfsd/nfs3xdr.c
===================================================================
--- linux-2.6.29.orig/fs/nfsd/nfs3xdr.c	2009-04-07 17:39:39.000000000 -0400
+++ linux-2.6.29/fs/nfsd/nfs3xdr.c	2009-04-07 17:44:51.000000000 -0400
@@ -218,7 +218,8 @@
 	        int err;
 		struct kstat stat;
 
-		err = vfs_getattr(fhp->fh_export->ex_path.mnt, dentry, &stat);
+		err = vfs_getattr(fhp->fh_export->ex_path.mnt, dentry, &stat,
+				  STAT_EVERYTHING);
 		if (!err) {
 			*p++ = xdr_one;		/* attributes follow */
 			lease_get_mtime(dentry->d_inode, &stat.mtime);
@@ -271,7 +272,7 @@
 		printk("nfsd: inode locked twice during operation.\n");
 
 	err = vfs_getattr(fhp->fh_export->ex_path.mnt, fhp->fh_dentry,
-			&fhp->fh_post_attr);
+			  &fhp->fh_post_attr, STAT_EVERYTHING);
 	if (err)
 		fhp->fh_post_saved = 0;
 	else
Index: linux-2.6.29/fs/nfsd/nfs4xdr.c
===================================================================
--- linux-2.6.29.orig/fs/nfsd/nfs4xdr.c	2009-04-07 17:39:39.000000000 -0400
+++ linux-2.6.29/fs/nfsd/nfs4xdr.c	2009-04-07 17:44:22.000000000 -0400
@@ -1436,7 +1436,7 @@
 			goto out;
 	}
 
-	err = vfs_getattr(exp->ex_path.mnt, dentry, &stat);
+	err = vfs_getattr(exp->ex_path.mnt, dentry, &stat, STAT_EVERYTHING);
 	if (err)
 		goto out_nfserr;
 	if ((bmval0 & (FATTR4_WORD0_FILES_FREE | FATTR4_WORD0_FILES_TOTAL |
@@ -1795,7 +1795,8 @@
 		if (ignore_crossmnt == 0 &&
 		    exp->ex_path.mnt->mnt_root->d_inode == dentry->d_inode) {
 			err = vfs_getattr(exp->ex_path.mnt->mnt_parent,
-				exp->ex_path.mnt->mnt_mountpoint, &stat);
+					  exp->ex_path.mnt->mnt_mountpoint,
+					  &stat, STAT_EVERYTHING);
 			if (err)
 				goto out_nfserr;
 		}
Index: linux-2.6.29/fs/nfsd/nfsproc.c
===================================================================
--- linux-2.6.29.orig/fs/nfsd/nfsproc.c	2009-04-07 17:39:39.000000000 -0400
+++ linux-2.6.29/fs/nfsd/nfsproc.c	2009-04-07 17:44:22.000000000 -0400
@@ -43,7 +43,7 @@
 	if (err) return err;
 	return nfserrno(vfs_getattr(resp->fh.fh_export->ex_path.mnt,
 				    resp->fh.fh_dentry,
-				    &resp->stat));
+				    &resp->stat, STAT_EVERYTHING));
 }
 static __be32
 nfsd_return_dirop(__be32 err, struct nfsd_diropres *resp)
@@ -51,7 +51,7 @@
 	if (err) return err;
 	return nfserrno(vfs_getattr(resp->fh.fh_export->ex_path.mnt,
 				    resp->fh.fh_dentry,
-				    &resp->stat));
+				    &resp->stat, STAT_EVERYTHING));
 }
 /*
  * Get a file's attributes
@@ -167,7 +167,7 @@
 	if (nfserr) return nfserr;
 	return nfserrno(vfs_getattr(resp->fh.fh_export->ex_path.mnt,
 				    resp->fh.fh_dentry,
-				    &resp->stat));
+				    &resp->stat, STAT_EVERYTHING));
 }
 
 /*
Index: linux-2.6.29/fs/nfsd/nfsxdr.c
===================================================================
--- linux-2.6.29.orig/fs/nfsd/nfsxdr.c	2009-04-07 17:39:39.000000000 -0400
+++ linux-2.6.29/fs/nfsd/nfsxdr.c	2009-04-07 17:45:16.000000000 -0400
@@ -207,7 +207,8 @@
 __be32 *nfs2svc_encode_fattr(struct svc_rqst *rqstp, __be32 *p, struct svc_fh *fhp)
 {
 	struct kstat stat;
-	vfs_getattr(fhp->fh_export->ex_path.mnt, fhp->fh_dentry, &stat);
+	vfs_getattr(fhp->fh_export->ex_path.mnt, fhp->fh_dentry, &stat,
+		    STAT_EVERYTHING);
 	return encode_fattr(rqstp, p, fhp, &stat);
 }
 
Index: linux-2.6.29/fs/stat.c
===================================================================
--- linux-2.6.29.orig/fs/stat.c	2009-04-07 17:39:39.000000000 -0400
+++ linux-2.6.29/fs/stat.c	2009-04-07 18:55:01.000000000 -0400
@@ -37,7 +37,8 @@
 
 EXPORT_SYMBOL(generic_fillattr);
 
-int vfs_getattr(struct vfsmount *mnt, struct dentry *dentry, struct kstat *stat)
+int vfs_getattr(struct vfsmount *mnt, struct dentry *dentry, struct kstat *stat,
+		int flags)
 {
 	struct inode *inode = dentry->d_inode;
 	int retval;
@@ -47,7 +48,7 @@
 		return retval;
 
 	if (inode->i_op->getattr)
-		return inode->i_op->getattr(mnt, dentry, stat);
+		return inode->i_op->getattr(mnt, dentry, stat, flags);
 
 	generic_fillattr(inode, stat);
 	return 0;
@@ -55,14 +56,14 @@
 
 EXPORT_SYMBOL(vfs_getattr);
 
-int vfs_stat_fd(int dfd, char __user *name, struct kstat *stat)
+int vfs_stat_fd(int dfd, char __user *name, struct kstat *stat, int flags)
 {
 	struct path path;
 	int error;
 
 	error = user_path_at(dfd, name, LOOKUP_FOLLOW, &path);
 	if (!error) {
-		error = vfs_getattr(path.mnt, path.dentry, stat);
+		error = vfs_getattr(path.mnt, path.dentry, stat, flags);
 		path_put(&path);
 	}
 	return error;
@@ -70,19 +71,19 @@
 
 int vfs_stat(char __user *name, struct kstat *stat)
 {
-	return vfs_stat_fd(AT_FDCWD, name, stat);
+	return vfs_stat_fd(AT_FDCWD, name, stat, STAT_EVERYTHING);
 }
 
 EXPORT_SYMBOL(vfs_stat);
 
-int vfs_lstat_fd(int dfd, char __user *name, struct kstat *stat)
+int vfs_lstat_fd(int dfd, char __user *name, struct kstat *stat, int flags)
 {
 	struct path path;
 	int error;
 
 	error = user_path_at(dfd, name, 0, &path);
 	if (!error) {
-		error = vfs_getattr(path.mnt, path.dentry, stat);
+		error = vfs_getattr(path.mnt, path.dentry, stat, flags);
 		path_put(&path);
 	}
 	return error;
@@ -90,18 +91,19 @@
 
 int vfs_lstat(char __user *name, struct kstat *stat)
 {
-	return vfs_lstat_fd(AT_FDCWD, name, stat);
+	return vfs_lstat_fd(AT_FDCWD, name, stat, STAT_EVERYTHING);
 }
 
 EXPORT_SYMBOL(vfs_lstat);
 
-int vfs_fstat(unsigned int fd, struct kstat *stat)
+int vfs_fstat(unsigned int fd, struct kstat *stat, int flags)
 {
 	struct file *f = fget(fd);
 	int error = -EBADF;
 
 	if (f) {
-		error = vfs_getattr(f->f_path.mnt, f->f_path.dentry, stat);
+		error = vfs_getattr(f->f_path.mnt, f->f_path.dentry, stat,
+				    flags);
 		fput(f);
 	}
 	return error;
@@ -155,7 +157,7 @@
 SYSCALL_DEFINE2(stat, char __user *, filename, struct __old_kernel_stat __user *, statbuf)
 {
 	struct kstat stat;
-	int error = vfs_stat_fd(AT_FDCWD, filename, &stat);
+	int error = vfs_stat_fd(AT_FDCWD, filename, &stat, STAT_EVERYTHING);
 
 	if (!error)
 		error = cp_old_stat(&stat, statbuf);
@@ -166,7 +168,7 @@
 SYSCALL_DEFINE2(lstat, char __user *, filename, struct __old_kernel_stat __user *, statbuf)
 {
 	struct kstat stat;
-	int error = vfs_lstat_fd(AT_FDCWD, filename, &stat);
+	int error = vfs_lstat_fd(AT_FDCWD, filename, &stat, STAT_EVERYTHING);
 
 	if (!error)
 		error = cp_old_stat(&stat, statbuf);
@@ -177,7 +179,7 @@
 SYSCALL_DEFINE2(fstat, unsigned int, fd, struct __old_kernel_stat __user *, statbuf)
 {
 	struct kstat stat;
-	int error = vfs_fstat(fd, &stat);
+	int error = vfs_fstat(fd, &stat, STAT_EVERYTHING);
 
 	if (!error)
 		error = cp_old_stat(&stat, statbuf);
@@ -240,7 +242,7 @@
 SYSCALL_DEFINE2(newstat, char __user *, filename, struct stat __user *, statbuf)
 {
 	struct kstat stat;
-	int error = vfs_stat_fd(AT_FDCWD, filename, &stat);
+	int error = vfs_stat_fd(AT_FDCWD, filename, &stat, STAT_EVERYTHING);
 
 	if (!error)
 		error = cp_new_stat(&stat, statbuf);
@@ -251,7 +253,7 @@
 SYSCALL_DEFINE2(newlstat, char __user *, filename, struct stat __user *, statbuf)
 {
 	struct kstat stat;
-	int error = vfs_lstat_fd(AT_FDCWD, filename, &stat);
+	int error = vfs_lstat_fd(AT_FDCWD, filename, &stat, STAT_EVERYTHING);
 
 	if (!error)
 		error = cp_new_stat(&stat, statbuf);
@@ -266,13 +268,20 @@
 	struct kstat stat;
 	int error = -EINVAL;
 
-	if ((flag & ~AT_SYMLINK_NOFOLLOW) != 0)
+	if (((flag & AT_FLAGS_SET) & ~AT_SYMLINK_NOFOLLOW) != 0)
 		goto out;
 
-	if (flag & AT_SYMLINK_NOFOLLOW)
-		error = vfs_lstat_fd(dfd, filename, &stat);
+	if ((flag & ~AT_FLAGS_SET) == 0)
+		flag |= STAT_EVERYTHING;
+	else
+		memset(&stat, 0, sizeof(stat));
+
+	if (flag & AT_STAT_SELF)
+		error = vfs_fstat(dfd, &stat, flag);
+	else if (flag & AT_SYMLINK_NOFOLLOW)
+		error = vfs_lstat_fd(dfd, filename, &stat, flag);
 	else
-		error = vfs_stat_fd(dfd, filename, &stat);
+		error = vfs_stat_fd(dfd, filename, &stat, flag);
 
 	if (!error)
 		error = cp_new_stat(&stat, statbuf);
@@ -285,7 +294,7 @@
 SYSCALL_DEFINE2(newfstat, unsigned int, fd, struct stat __user *, statbuf)
 {
 	struct kstat stat;
-	int error = vfs_fstat(fd, &stat);
+	int error = vfs_fstat(fd, &stat, STAT_EVERYTHING);
 
 	if (!error)
 		error = cp_new_stat(&stat, statbuf);
@@ -406,13 +415,20 @@
 	struct kstat stat;
 	int error = -EINVAL;
 
-	if ((flag & ~AT_SYMLINK_NOFOLLOW) != 0)
+	if (((flag & AT_FLAGS_SET) & ~AT_SYMLINK_NOFOLLOW) != 0)
 		goto out;
 
-	if (flag & AT_SYMLINK_NOFOLLOW)
-		error = vfs_lstat_fd(dfd, filename, &stat);
+	if ((flag & ~AT_FLAGS_SET) == 0)
+		flag |= STAT_EVERYTHING;
+	else
+		memset(&stat, 0, sizeof(stat));
+
+	if (flag & AT_STAT_SELF)
+		error = vfs_fstat(dfd, &stat, flag);
+	else if (flag & AT_SYMLINK_NOFOLLOW)
+		error = vfs_lstat_fd(dfd, filename, &stat, flag);
 	else
-		error = vfs_stat_fd(dfd, filename, &stat);
+		error = vfs_stat_fd(dfd, filename, &stat, flag);
 
 	if (!error)
 		error = cp_new_stat64(&stat, statbuf);
Index: linux-2.6.29/include/linux/fcntl.h
===================================================================
--- linux-2.6.29.orig/include/linux/fcntl.h	2009-04-07 17:39:39.000000000 -0400
+++ linux-2.6.29/include/linux/fcntl.h	2009-04-07 18:17:52.000000000 -0400
@@ -40,6 +40,37 @@
                                            unlinking file.  */
 #define AT_SYMLINK_FOLLOW	0x400   /* Follow symbolic links.  */
 
+#define AT_FLAGS_SET		0x700   /* All of the above flags for masking */
+
+#define	AT_STAT_SELF		0x800   /* Stat the actual fd passed to fstatat */
+
+/* Bits to define what fields the fstatat shoult fill in struct stat,
+ * should not intersect with above AT_* bits. No flags means get everthing
+ * for compatibility reasons */
+#define STAT_REVALIDATE	     0x000001	/* For NFS and other non local
+					   filesystems, do get the latest
+					   possible info */
+#define	STAT_INO	     0x001000   /* inode number */
+#define STAT_TYPE	     0x002000	/* file type */
+#define STAT_MODE	     0x004000	/* access mode */
+#define STAT_NLINK	     0x008000	/* nlink count */
+#define STAT_UID	     0x010000	/* owner uid */
+#define STAT_GID	     0x020000   /* owner gid */
+#define STAT_ATIME	     0x040000	/* atime */
+#define STAT_MTIME	     0x080000	/* mtime */
+#define STAT_CTIME	     0x100000	/* ctime */
+#define STAT_SIZE	     0x200000	/* file size */
+#define STAT_BLOCK	     0x400000	/* number of blocks allocated */
+#define STAT_RDEV	     0x800000	/* rdev */
+/* ->dev is assumed to be too lightweight to have its own bit, so you
+ * always get it. ->blksize is consideret to be unimportant in this case, so
+ * you always get it too. */
+
+/* Now some useful aggregators */
+#define STAT_EVERYTHING	     0xfff000   /* Avoid the temptation to use ~0 here*/
+#define STAT_TIMES	     (STAT_ATIME|STAT_MTIME|STAT_CTIME)
+#define STAT_ACCESS	     (STAT_MODE|STAT_UID|STAT_GID)
+
 #ifdef __KERNEL__
 
 #ifndef force_o_largefile
Index: linux-2.6.29/include/linux/fs.h
===================================================================
--- linux-2.6.29.orig/include/linux/fs.h	2009-04-07 17:39:39.000000000 -0400
+++ linux-2.6.29/include/linux/fs.h	2009-04-07 18:19:28.000000000 -0400
@@ -366,6 +366,8 @@
 #define ATTR_OPEN	(1 << 15) /* Truncating from open(O_TRUNC) */
 #define ATTR_TIMES_SET	(1 << 16)
 
+#define ATTR_STAT_ALL	(ATTR_MODE|ATTR_UID|ATTR_GID|ATTR_SIZE|ATTR_ATIME|ATTR_MTIME|ATTR_CTIME)
+
 /*
  * This is the Inode Attributes structure, used for notify_change().  It
  * uses the above definitions as flags, to know which values have changed.
@@ -1353,7 +1355,7 @@
 	void (*truncate) (struct inode *);
 	int (*permission) (struct inode *, int);
 	int (*setattr) (struct dentry *, struct iattr *);
-	int (*getattr) (struct vfsmount *mnt, struct dentry *, struct kstat *);
+	int (*getattr) (struct vfsmount *mnt, struct dentry *, struct kstat *, int);
 	int (*setxattr) (struct dentry *, const char *,const void *,size_t,int);
 	ssize_t (*getxattr) (struct dentry *, const char *, void *, size_t);
 	ssize_t (*listxattr) (struct dentry *, char *, size_t);
@@ -2062,7 +2064,7 @@
 extern const struct inode_operations page_symlink_inode_operations;
 extern int generic_readlink(struct dentry *, char __user *, int);
 extern void generic_fillattr(struct inode *, struct kstat *);
-extern int vfs_getattr(struct vfsmount *, struct dentry *, struct kstat *);
+extern int vfs_getattr(struct vfsmount *, struct dentry *, struct kstat *, int);
 void inode_add_bytes(struct inode *inode, loff_t bytes);
 void inode_sub_bytes(struct inode *inode, loff_t bytes);
 loff_t inode_get_bytes(struct inode *inode);
@@ -2072,9 +2074,9 @@
 
 extern int vfs_stat(char __user *, struct kstat *);
 extern int vfs_lstat(char __user *, struct kstat *);
-extern int vfs_stat_fd(int dfd, char __user *, struct kstat *);
-extern int vfs_lstat_fd(int dfd, char __user *, struct kstat *);
-extern int vfs_fstat(unsigned int, struct kstat *);
+extern int vfs_stat_fd(int dfd, char __user *, struct kstat *, int);
+extern int vfs_lstat_fd(int dfd, char __user *, struct kstat *, int);
+extern int vfs_fstat(unsigned int, struct kstat *, int);
 
 extern int do_vfs_ioctl(struct file *filp, unsigned int fd, unsigned int cmd,
 		    unsigned long arg);
@@ -2096,7 +2098,7 @@
 extern int dcache_dir_close(struct inode *, struct file *);
 extern loff_t dcache_dir_lseek(struct file *, loff_t, int);
 extern int dcache_readdir(struct file *, void *, filldir_t);
-extern int simple_getattr(struct vfsmount *, struct dentry *, struct kstat *);
+extern int simple_getattr(struct vfsmount *, struct dentry *, struct kstat *, int);
 extern int simple_statfs(struct dentry *, struct kstatfs *);
 extern int simple_link(struct dentry *, struct inode *, struct dentry *);
 extern int simple_unlink(struct inode *, struct dentry *);
Index: linux-2.6.29/arch/ia64/ia32/sys_ia32.c
===================================================================
--- linux-2.6.29.orig/arch/ia64/ia32/sys_ia32.c	2009-03-23 19:12:14.000000000 -0400
+++ linux-2.6.29/arch/ia64/ia32/sys_ia32.c	2009-04-07 18:22:50.000000000 -0400
@@ -1885,7 +1885,7 @@
 sys32_fstat64 (unsigned int fd, struct stat64 __user *statbuf)
 {
 	struct kstat s;
-	long ret = vfs_fstat(fd, &s);
+	long ret = vfs_fstat(fd, &s, STAT_EVERYTHING);
 	if (!ret)
 		ret = putstat64(statbuf, &s);
 	return ret;

             reply	other threads:[~2009-04-07 23:15 UTC|newest]

Thread overview: 7+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2009-04-07 23:15 Oleg Drokin [this message]
2009-04-07 23:25 ` [PATCH 1/3] VFS "stat light" out of fstatat, and fine grained flags Jeff Garzik
2009-04-08  6:56   ` forwarding -fsdevel to -kernel (was Re: [PATCH 1/3] VFS "stat ...) flags Miklos Szeredi
2009-04-08  7:35     ` David Miller
2009-04-12 20:50 ` [PATCH 1/3] VFS "stat light" out of fstatat, and fine grained flags Jamie Lokier
2009-04-12 21:46   ` Oleg Drokin
2009-04-21 10:20     ` VFS "stat light" fstatat, inconsistent *at() function interfaces Jamie Lokier

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=20090407231524.GA1569655@fiona.linuxhacker.ru \
    --to=green@linuxhacker.ru \
    --cc=linux-fsdevel@vger.kernel.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.