[PATCH 1/2] [RFC] vfs: 'stat light' fstatat flags

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

 



This very, very rough patch set adds three flags to fstatat - AT_NO_SIZE,
AT_NO_TIMES, and AT_STRICT.

The first two flags (AT_NO_SIZE, AT_NO_TIMES) allow userspace to notify the
file system layer that certain stat fields are not required to be accurate.
Some file systems want this information in order to optimize away expensive
operations associated with stat. In particular, NFS can avoid some syncing
to the server (if userspace doesn't want atime, ctime or mtime) and Lustre
can avoid some expensive locking by avoiding an update of various size
fields (st_size, st_blocks).

AT_STRICT allows userspace to indicate that it wants the most up to date
version of a files status, regardless of performance impact. A distributed
file system which has a non-coherent inode cache would know then to send a
direct query to it's server.

As noted previously, these patches are really rough. Mostly I'd like to get
some feedback on the interface and general direction of implementation. Some
glaring issues which we want to resolve:

- This patch set doesn't actually wire up any client file systems yet :)

- There's the question of whether we wire up [fl]stat(2) variants instead of
  using fstatat. I went with the former as the implementation was more
  straight forward.

- I'm not sure whether we want to force zeroing of the optional fields, or
  return whatever's in the inode (which may be stale, or just junk).

- Testing has been very light (compiles and boots on x86_64). There really
  isn't a whole lot to test yet anyway.

- There's probably other issues I'm missing :)

Finally, credit should be given to Sage Weil, Ted Tso, Andreas Dilger,
Russell Cattelan, Trond Myklebust and others at LSF who participated in a
lively discussion on this topic :)

Signed-off-by: Mark Fasheh <mfasheh@xxxxxxxx>
---
 arch/arm/kernel/sys_oabi-compat.c |    4 +-
 arch/s390/kernel/compat_linux.c   |    4 +-
 arch/sparc/kernel/sys_sparc32.c   |    4 +-
 arch/x86/ia32/sys_ia32.c          |    4 +-
 drivers/block/loop.c              |    2 +-
 fs/compat.c                       |    8 +++---
 fs/libfs.c                        |    2 +-
 fs/nfsd/nfs3proc.c                |    2 +-
 fs/nfsd/nfs3xdr.c                 |    4 +-
 fs/nfsd/nfs4xdr.c                 |    5 ++-
 fs/nfsd/nfsproc.c                 |    6 ++--
 fs/nfsd/nfsxdr.c                  |    2 +-
 fs/stat.c                         |   44 +++++++++++++++++++++---------------
 include/linux/fcntl.h             |    6 +++++
 include/linux/fs.h                |   12 ++++++----
 15 files changed, 63 insertions(+), 46 deletions(-)

diff --git a/arch/arm/kernel/sys_oabi-compat.c b/arch/arm/kernel/sys_oabi-compat.c
index 42623db..b48a9ac 100644
--- a/arch/arm/kernel/sys_oabi-compat.c
+++ b/arch/arm/kernel/sys_oabi-compat.c
@@ -182,9 +182,9 @@ asmlinkage long sys_oabi_fstatat64(int dfd,
 		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);
diff --git a/arch/s390/kernel/compat_linux.c b/arch/s390/kernel/compat_linux.c
index 6cc87d8..de65f40 100644
--- a/arch/s390/kernel/compat_linux.c
+++ b/arch/s390/kernel/compat_linux.c
@@ -708,9 +708,9 @@ asmlinkage long sys32_fstatat64(unsigned int dfd, char __user *filename,
 		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);
diff --git a/arch/sparc/kernel/sys_sparc32.c b/arch/sparc/kernel/sys_sparc32.c
index e800503..387823e 100644
--- a/arch/sparc/kernel/sys_sparc32.c
+++ b/arch/sparc/kernel/sys_sparc32.c
@@ -212,9 +212,9 @@ asmlinkage long compat_sys_fstatat64(unsigned int dfd, char __user *filename,
 		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);
diff --git a/arch/x86/ia32/sys_ia32.c b/arch/x86/ia32/sys_ia32.c
index 6c0d7f6..79eb683 100644
--- a/arch/x86/ia32/sys_ia32.c
+++ b/arch/x86/ia32/sys_ia32.c
@@ -135,9 +135,9 @@ asmlinkage long sys32_fstatat(unsigned int dfd, char __user *filename,
 		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);
diff --git a/drivers/block/loop.c b/drivers/block/loop.c
index bf03455..02d3b47 100644
--- a/drivers/block/loop.c
+++ b/drivers/block/loop.c
@@ -1027,7 +1027,7 @@ loop_get_status(struct loop_device *lo, struct loop_info64 *info)
 
 	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, 0);
 	if (error)
 		return error;
 	memset(info, 0, sizeof(*info));
diff --git a/fs/compat.c b/fs/compat.c
index d0145ca..7549b3f 100644
--- a/fs/compat.c
+++ b/fs/compat.c
@@ -180,7 +180,7 @@ asmlinkage long compat_sys_newstat(char __user * filename,
 		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, 0);
 
 	if (!error)
 		error = cp_compat_stat(&stat, statbuf);
@@ -191,7 +191,7 @@ asmlinkage long compat_sys_newlstat(char __user * filename,
 		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, 0);
 
 	if (!error)
 		error = cp_compat_stat(&stat, statbuf);
@@ -209,9 +209,9 @@ asmlinkage long compat_sys_newfstatat(unsigned int dfd, char __user *filename,
 		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);
diff --git a/fs/libfs.c b/fs/libfs.c
index 49b4409..cbde1fb 100644
--- a/fs/libfs.c
+++ b/fs/libfs.c
@@ -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);
diff --git a/fs/nfsd/nfs3proc.c b/fs/nfsd/nfs3proc.c
index 9dbd2eb..9d56561 100644
--- a/fs/nfsd/nfs3proc.c
+++ b/fs/nfsd/nfs3proc.c
@@ -69,7 +69,7 @@ nfsd3_proc_getattr(struct svc_rqst *rqstp, struct nfsd_fhandle  *argp,
 		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, 0);
 	nfserr = nfserrno(err);
 
 	RETURN_STATUS(nfserr);
diff --git a/fs/nfsd/nfs3xdr.c b/fs/nfsd/nfs3xdr.c
index 17d0dd9..b19d320 100644
--- a/fs/nfsd/nfs3xdr.c
+++ b/fs/nfsd/nfs3xdr.c
@@ -218,7 +218,7 @@ encode_post_op_attr(struct svc_rqst *rqstp, __be32 *p, struct svc_fh *fhp)
 	        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, 0);
 		if (!err) {
 			*p++ = xdr_one;		/* attributes follow */
 			lease_get_mtime(dentry->d_inode, &stat.mtime);
@@ -271,7 +271,7 @@ void fill_post_wcc(struct svc_fh *fhp)
 		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, 0);
 	if (err)
 		fhp->fh_post_saved = 0;
 	else
diff --git a/fs/nfsd/nfs4xdr.c b/fs/nfsd/nfs4xdr.c
index 9250067..0a29e85 100644
--- a/fs/nfsd/nfs4xdr.c
+++ b/fs/nfsd/nfs4xdr.c
@@ -1436,7 +1436,7 @@ nfsd4_encode_fattr(struct svc_fh *fhp, struct svc_export *exp,
 			goto out;
 	}
 
-	err = vfs_getattr(exp->ex_path.mnt, dentry, &stat);
+	err = vfs_getattr(exp->ex_path.mnt, dentry, &stat, 0);
 	if (err)
 		goto out_nfserr;
 	if ((bmval0 & (FATTR4_WORD0_FILES_FREE | FATTR4_WORD0_FILES_TOTAL |
@@ -1795,7 +1795,8 @@ out_acl:
 		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, 0);
 			if (err)
 				goto out_nfserr;
 		}
diff --git a/fs/nfsd/nfsproc.c b/fs/nfsd/nfsproc.c
index 6f7f263..2f7c86d 100644
--- a/fs/nfsd/nfsproc.c
+++ b/fs/nfsd/nfsproc.c
@@ -43,7 +43,7 @@ nfsd_return_attrs(__be32 err, struct nfsd_attrstat *resp)
 	if (err) return err;
 	return nfserrno(vfs_getattr(resp->fh.fh_export->ex_path.mnt,
 				    resp->fh.fh_dentry,
-				    &resp->stat));
+				    &resp->stat, 0));
 }
 static __be32
 nfsd_return_dirop(__be32 err, struct nfsd_diropres *resp)
@@ -51,7 +51,7 @@ nfsd_return_dirop(__be32 err, struct nfsd_diropres *resp)
 	if (err) return err;
 	return nfserrno(vfs_getattr(resp->fh.fh_export->ex_path.mnt,
 				    resp->fh.fh_dentry,
-				    &resp->stat));
+				    &resp->stat, 0));
 }
 /*
  * Get a file's attributes
@@ -167,7 +167,7 @@ nfsd_proc_read(struct svc_rqst *rqstp, struct nfsd_readargs *argp,
 	if (nfserr) return nfserr;
 	return nfserrno(vfs_getattr(resp->fh.fh_export->ex_path.mnt,
 				    resp->fh.fh_dentry,
-				    &resp->stat));
+				    &resp->stat, 0));
 }
 
 /*
diff --git a/fs/nfsd/nfsxdr.c b/fs/nfsd/nfsxdr.c
index afd08e2..25dc0d0 100644
--- a/fs/nfsd/nfsxdr.c
+++ b/fs/nfsd/nfsxdr.c
@@ -207,7 +207,7 @@ encode_fattr(struct svc_rqst *rqstp, __be32 *p, struct svc_fh *fhp,
 __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, 0);
 	return encode_fattr(rqstp, p, fhp, &stat);
 }
 
diff --git a/fs/stat.c b/fs/stat.c
index 2db740a..624af05 100644
--- a/fs/stat.c
+++ b/fs/stat.c
@@ -37,17 +37,25 @@ void generic_fillattr(struct inode *inode, struct kstat *stat)
 
 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;
+	int attr_flags = ATTR_STAT_ALL;
 
 	retval = security_inode_getattr(mnt, dentry);
 	if (retval)
 		return retval;
 
+	if (flags & AT_NO_SIZE)
+		attr_flags &= ~ATTR_SIZE;
+
+	if (flags & AT_NO_TIMES)
+		attr_flags &= ~(ATTR_MTIME|ATTR_CTIME|ATTR_ATIME);
+
 	if (inode->i_op->getattr)
-		return inode->i_op->getattr(mnt, dentry, stat);
+		return inode->i_op->getattr(mnt, dentry, stat, attr_flags);
 
 	generic_fillattr(inode, stat);
 	return 0;
@@ -55,14 +63,14 @@ int vfs_getattr(struct vfsmount *mnt, struct dentry *dentry, struct kstat *stat)
 
 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 +78,19 @@ int vfs_stat_fd(int dfd, char __user *name, struct kstat *stat)
 
 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, 0);
 }
 
 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,7 +98,7 @@ int vfs_lstat_fd(int dfd, char __user *name, struct kstat *stat)
 
 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, 0);
 }
 
 EXPORT_SYMBOL(vfs_lstat);
@@ -101,7 +109,7 @@ int vfs_fstat(unsigned int fd, struct kstat *stat)
 	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, 0);
 		fput(f);
 	}
 	return error;
@@ -155,7 +163,7 @@ static int cp_old_stat(struct kstat *stat, struct __old_kernel_stat __user * sta
 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, 0);
 
 	if (!error)
 		error = cp_old_stat(&stat, statbuf);
@@ -166,7 +174,7 @@ SYSCALL_DEFINE2(stat, char __user *, filename, struct __old_kernel_stat __user *
 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, 0);
 
 	if (!error)
 		error = cp_old_stat(&stat, statbuf);
@@ -240,7 +248,7 @@ static int cp_new_stat(struct kstat *stat, struct stat __user *statbuf)
 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, 0);
 
 	if (!error)
 		error = cp_new_stat(&stat, statbuf);
@@ -251,7 +259,7 @@ SYSCALL_DEFINE2(newstat, char __user *, filename, struct stat __user *, statbuf)
 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, 0);
 
 	if (!error)
 		error = cp_new_stat(&stat, statbuf);
@@ -266,13 +274,13 @@ SYSCALL_DEFINE4(newfstatat, int, dfd, char __user *, filename,
 	struct kstat stat;
 	int error = -EINVAL;
 
-	if ((flag & ~AT_SYMLINK_NOFOLLOW) != 0)
+	if ((flag & ~AT_MASK) != 0)
 		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_new_stat(&stat, statbuf);
@@ -410,9 +418,9 @@ SYSCALL_DEFINE4(fstatat64, int, dfd, char __user *, filename,
 		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_new_stat64(&stat, statbuf);
diff --git a/include/linux/fcntl.h b/include/linux/fcntl.h
index 8603740..b02127a 100644
--- a/include/linux/fcntl.h
+++ b/include/linux/fcntl.h
@@ -39,6 +39,12 @@
 #define AT_REMOVEDIR		0x200   /* Remove directory instead of
                                            unlinking file.  */
 #define AT_SYMLINK_FOLLOW	0x400   /* Follow symbolic links.  */
+#define AT_NO_SIZE		0x800	/* Do not return size or block count */
+#define	AT_NO_TIMES		0x1000	/* Do not return [amc]time */
+#define AT_STRICT		0x2000	/* Guarantee correctness of field
+					 * values */
+
+#define AT_MASK			(AT_SYMLINK_NOFOLLOW|AT_NO_SIZE|AT_NO_TIMES)
 
 #ifdef __KERNEL__
 
diff --git a/include/linux/fs.h b/include/linux/fs.h
index 92734c0..2e099dd 100644
--- a/include/linux/fs.h
+++ b/include/linux/fs.h
@@ -366,6 +366,8 @@ typedef void (dio_iodone_t)(struct kiocb *iocb, loff_t offset,
 #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 @@ struct inode_operations {
 	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 int page_symlink(struct inode *inode, const char *symname, int len);
 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,8 +2074,8 @@ extern int vfs_readdir(struct file *, filldir_t, void *);
 
 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_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 *);
 
 extern int do_vfs_ioctl(struct file *filp, unsigned int fd, unsigned int cmd,
@@ -2096,7 +2098,7 @@ extern int dcache_dir_open(struct inode *, struct file *);
 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 *);
-- 
1.5.6

--
To unsubscribe from this list: send the line "unsubscribe linux-fsdevel" in
the body of a message to majordomo@xxxxxxxxxxxxxxx
More majordomo info at  http://vger.kernel.org/majordomo-info.html

[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