[PATCH 1/3] VFS "stat light" out of fstatat, and fine grained flags

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



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
 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;

[Index of Archives]     [Linux Ext4 Filesystem]     [Union Filesystem]     [Filesystem Testing]     [Ceph Users]     [Ecryptfs]     [AutoFS]     [Kernel Newbies]     [Share Photos]     [Security]     [Netfilter]     [Bugtraq]     [Yosemite News]     [MIPS Linux]     [ARM Linux]     [Linux Security]     [Linux Cachefs]     [Reiser Filesystem]     [Linux RAID]     [Samba]     [Device Mapper]     [CEPH Development]
  Powered by Linux