From: Miklos Szeredi <[EMAIL PROTECTED]>

Pass the open file into the filesystem's ->getattr() method for
fstat().

This is needed to be able to correctly implement open-unlink-fstat
semantics in some filesystem such as sshfs, without having to resort
to "silly-renaming".

Do this by adding a 'struct file *' parameter to i_op->getattr().  For
fstat() pass the open file pointer, in other cases pass NULL.

This is safe from a compatibility standpoint, out-of-tree old stuff
will continue to work, but will get a warning at compile time.

Signed-off-by: Miklos Szeredi <[EMAIL PROTECTED]>
---

Index: linux/fs/9p/vfs_inode.c
===================================================================
--- linux.orig/fs/9p/vfs_inode.c        2007-08-09 16:47:30.000000000 +0200
+++ linux/fs/9p/vfs_inode.c     2007-08-09 16:48:45.000000000 +0200
@@ -706,7 +706,7 @@ done:
 
 static int
 v9fs_vfs_getattr(struct vfsmount *mnt, struct dentry *dentry,
-                struct kstat *stat)
+                struct kstat *stat, struct file *file)
 {
        int err;
        struct v9fs_session_info *v9ses;
Index: linux/fs/afs/inode.c
===================================================================
--- linux.orig/fs/afs/inode.c   2007-08-09 16:47:30.000000000 +0200
+++ linux/fs/afs/inode.c        2007-08-09 16:48:45.000000000 +0200
@@ -295,7 +295,7 @@ error_unlock:
  * read the attributes of an inode
  */
 int afs_getattr(struct vfsmount *mnt, struct dentry *dentry,
-                     struct kstat *stat)
+                     struct kstat *stat, struct file *file)
 {
        struct inode *inode;
 
Index: linux/fs/afs/internal.h
===================================================================
--- linux.orig/fs/afs/internal.h        2007-08-09 16:47:30.000000000 +0200
+++ linux/fs/afs/internal.h     2007-08-09 16:48:45.000000000 +0200
@@ -548,7 +548,8 @@ extern struct inode *afs_iget(struct sup
                              struct afs_callback *);
 extern void afs_zap_data(struct afs_vnode *);
 extern int afs_validate(struct afs_vnode *, struct key *);
-extern int afs_getattr(struct vfsmount *, struct dentry *, struct kstat *);
+extern int afs_getattr(struct vfsmount *, struct dentry *, struct kstat *,
+                      struct file *);
 extern int afs_setattr(struct dentry *, struct iattr *);
 extern void afs_clear_inode(struct inode *);
 
Index: linux/fs/bad_inode.c
===================================================================
--- linux.orig/fs/bad_inode.c   2007-08-09 16:47:30.000000000 +0200
+++ linux/fs/bad_inode.c        2007-08-09 16:48:45.000000000 +0200
@@ -250,7 +250,7 @@ static int bad_inode_permission(struct i
 }
 
 static int bad_inode_getattr(struct vfsmount *mnt, struct dentry *dentry,
-                       struct kstat *stat)
+                       struct kstat *stat, struct file *file)
 {
        return -EIO;
 }
Index: linux/fs/cifs/cifsfs.h
===================================================================
--- linux.orig/fs/cifs/cifsfs.h 2007-08-09 16:47:30.000000000 +0200
+++ linux/fs/cifs/cifsfs.h      2007-08-09 16:48:45.000000000 +0200
@@ -55,7 +55,8 @@ extern int cifs_rmdir(struct inode *, st
 extern int cifs_rename(struct inode *, struct dentry *, struct inode *,
                       struct dentry *);
 extern int cifs_revalidate(struct dentry *);
-extern int cifs_getattr(struct vfsmount *, struct dentry *, struct kstat *);
+extern int cifs_getattr(struct vfsmount *, struct dentry *, struct kstat *,
+                       struct file *);
 extern int cifs_setattr(struct dentry *, struct iattr *);
 
 extern const struct inode_operations cifs_file_inode_ops;
Index: linux/fs/cifs/inode.c
===================================================================
--- linux.orig/fs/cifs/inode.c  2007-08-09 16:47:30.000000000 +0200
+++ linux/fs/cifs/inode.c       2007-08-09 16:48:45.000000000 +0200
@@ -1332,7 +1332,7 @@ int cifs_revalidate(struct dentry *diren
 }
 
 int cifs_getattr(struct vfsmount *mnt, struct dentry *dentry,
-       struct kstat *stat)
+       struct kstat *stat, struct file *file)
 {
        int err = cifs_revalidate(dentry);
        if (!err) {
Index: linux/fs/coda/inode.c
===================================================================
--- linux.orig/fs/coda/inode.c  2007-08-09 16:47:30.000000000 +0200
+++ linux/fs/coda/inode.c       2007-08-09 16:48:45.000000000 +0200
@@ -220,7 +220,8 @@ static void coda_clear_inode(struct inod
        coda_cache_clear_inode(inode);
 }
 
-int coda_getattr(struct vfsmount *mnt, struct dentry *dentry, struct kstat 
*stat)
+int coda_getattr(struct vfsmount *mnt, struct dentry *dentry,
+                struct kstat *stat, struct file *file)
 {
        int err = coda_revalidate_inode(dentry);
        if (!err)
Index: linux/fs/fat/file.c
===================================================================
--- linux.orig/fs/fat/file.c    2007-08-09 16:47:30.000000000 +0200
+++ linux/fs/fat/file.c 2007-08-09 16:48:45.000000000 +0200
@@ -303,7 +303,8 @@ void fat_truncate(struct inode *inode)
        fat_flush_inodes(inode->i_sb, inode, NULL);
 }
 
-int fat_getattr(struct vfsmount *mnt, struct dentry *dentry, struct kstat 
*stat)
+int fat_getattr(struct vfsmount *mnt, struct dentry *dentry,
+               struct kstat *stat, struct file *file)
 {
        struct inode *inode = dentry->d_inode;
        generic_fillattr(inode, stat);
Index: linux/fs/fuse/dir.c
===================================================================
--- linux.orig/fs/fuse/dir.c    2007-08-09 16:47:30.000000000 +0200
+++ linux/fs/fuse/dir.c 2007-08-09 16:48:45.000000000 +0200
@@ -1056,7 +1056,7 @@ static int fuse_setattr(struct dentry *e
 }
 
 static int fuse_getattr(struct vfsmount *mnt, struct dentry *entry,
-                       struct kstat *stat)
+                       struct kstat *stat, struct file *file)
 {
        struct inode *inode = entry->d_inode;
        struct fuse_inode *fi = get_fuse_inode(inode);
Index: linux/fs/gfs2/ops_inode.c
===================================================================
--- linux.orig/fs/gfs2/ops_inode.c      2007-08-09 16:47:30.000000000 +0200
+++ linux/fs/gfs2/ops_inode.c   2007-08-09 16:48:45.000000000 +0200
@@ -1030,7 +1030,7 @@ out:
  */
 
 static int gfs2_getattr(struct vfsmount *mnt, struct dentry *dentry,
-                       struct kstat *stat)
+                       struct kstat *stat, struct file *file)
 {
        struct inode *inode = dentry->d_inode;
        struct gfs2_inode *ip = GFS2_I(inode);
Index: linux/fs/libfs.c
===================================================================
--- linux.orig/fs/libfs.c       2007-08-09 16:47:30.000000000 +0200
+++ linux/fs/libfs.c    2007-08-09 16:48:45.000000000 +0200
@@ -12,7 +12,7 @@
 #include <asm/uaccess.h>
 
 int simple_getattr(struct vfsmount *mnt, struct dentry *dentry,
-                  struct kstat *stat)
+                  struct kstat *stat, struct file *file)
 {
        struct inode *inode = dentry->d_inode;
        generic_fillattr(inode, stat);
Index: linux/fs/nfs/inode.c
===================================================================
--- linux.orig/fs/nfs/inode.c   2007-08-09 16:47:30.000000000 +0200
+++ linux/fs/nfs/inode.c        2007-08-09 16:48:45.000000000 +0200
@@ -423,7 +423,8 @@ static void nfs_wake_up_inode(struct ino
        wake_up_bit(&nfsi->flags, NFS_INO_REVALIDATING);
 }
 
-int nfs_getattr(struct vfsmount *mnt, struct dentry *dentry, struct kstat 
*stat)
+int nfs_getattr(struct vfsmount *mnt, struct dentry *dentry,
+               struct kstat *stat, struct file *file)
 {
        struct inode *inode = dentry->d_inode;
        int need_atime = NFS_I(inode)->cache_validity & NFS_INO_INVALID_ATIME;
Index: linux/fs/ocfs2/file.c
===================================================================
--- linux.orig/fs/ocfs2/file.c  2007-08-09 16:47:30.000000000 +0200
+++ linux/fs/ocfs2/file.c       2007-08-09 16:48:45.000000000 +0200
@@ -1086,7 +1086,8 @@ bail:
 
 int ocfs2_getattr(struct vfsmount *mnt,
                  struct dentry *dentry,
-                 struct kstat *stat)
+                 struct kstat *stat,
+                 struct file *file)
 {
        struct inode *inode = dentry->d_inode;
        struct super_block *sb = dentry->d_inode->i_sb;
Index: linux/fs/ocfs2/file.h
===================================================================
--- linux.orig/fs/ocfs2/file.h  2007-08-09 16:47:30.000000000 +0200
+++ linux/fs/ocfs2/file.h       2007-08-09 16:48:45.000000000 +0200
@@ -53,7 +53,7 @@ int ocfs2_lock_allocators(struct inode *
                          struct ocfs2_alloc_context **meta_ac);
 int ocfs2_setattr(struct dentry *dentry, struct iattr *attr);
 int ocfs2_getattr(struct vfsmount *mnt, struct dentry *dentry,
-                 struct kstat *stat);
+                 struct kstat *stat, struct file *file);
 int ocfs2_permission(struct inode *inode, int mask,
                     struct nameidata *nd);
 
Index: linux/fs/proc/base.c
===================================================================
--- linux.orig/fs/proc/base.c   2007-08-09 16:47:30.000000000 +0200
+++ linux/fs/proc/base.c        2007-08-09 16:48:45.000000000 +0200
@@ -1028,7 +1028,8 @@ out_unlock:
        return NULL;
 }
 
-static int pid_getattr(struct vfsmount *mnt, struct dentry *dentry, struct 
kstat *stat)
+static int pid_getattr(struct vfsmount *mnt, struct dentry *dentry,
+                      struct kstat *stat, struct file *file)
 {
        struct inode *inode = dentry->d_inode;
        struct task_struct *task;
@@ -2584,7 +2585,8 @@ out_no_task:
        return retval;
 }
 
-static int proc_task_getattr(struct vfsmount *mnt, struct dentry *dentry, 
struct kstat *stat)
+static int proc_task_getattr(struct vfsmount *mnt, struct dentry *dentry,
+                            struct kstat *stat, struct file *file)
 {
        struct inode *inode = dentry->d_inode;
        struct task_struct *p = get_proc_task(inode);
Index: linux/fs/proc/generic.c
===================================================================
--- linux.orig/fs/proc/generic.c        2007-08-09 16:47:30.000000000 +0200
+++ linux/fs/proc/generic.c     2007-08-09 16:48:45.000000000 +0200
@@ -255,7 +255,7 @@ out:
 }
 
 static int proc_getattr(struct vfsmount *mnt, struct dentry *dentry,
-                       struct kstat *stat)
+                       struct kstat *stat, struct file *file)
 {
        struct inode *inode = dentry->d_inode;
        struct proc_dir_entry *de = PROC_I(inode)->pde;
Index: linux/fs/proc/root.c
===================================================================
--- linux.orig/fs/proc/root.c   2007-08-09 16:47:30.000000000 +0200
+++ linux/fs/proc/root.c        2007-08-09 16:48:45.000000000 +0200
@@ -82,8 +82,8 @@ void __init proc_root_init(void)
        proc_sys_init();
 }
 
-static int proc_root_getattr(struct vfsmount *mnt, struct dentry *dentry, 
struct kstat *stat
-)
+static int proc_root_getattr(struct vfsmount *mnt, struct dentry *dentry,
+                            struct kstat *stat, struct file *file)
 {
        generic_fillattr(dentry->d_inode, stat);
        stat->nlink = proc_root.nlink + nr_processes();
Index: linux/fs/smbfs/inode.c
===================================================================
--- linux.orig/fs/smbfs/inode.c 2007-08-09 16:47:30.000000000 +0200
+++ linux/fs/smbfs/inode.c      2007-08-09 16:48:45.000000000 +0200
@@ -659,7 +659,8 @@ smb_statfs(struct dentry *dentry, struct
        return result;
 }
 
-int smb_getattr(struct vfsmount *mnt, struct dentry *dentry, struct kstat 
*stat)
+int smb_getattr(struct vfsmount *mnt, struct dentry *dentry,
+               struct kstat *stat, struct file *file)
 {
        int err = smb_revalidate_inode(dentry);
        if (!err)
Index: linux/fs/smbfs/proto.h
===================================================================
--- linux.orig/fs/smbfs/proto.h 2007-08-09 16:47:30.000000000 +0200
+++ linux/fs/smbfs/proto.h      2007-08-09 16:48:45.000000000 +0200
@@ -60,7 +60,8 @@ extern void smb_get_inode_attr(struct in
 extern void smb_set_inode_attr(struct inode *inode, struct smb_fattr *fattr);
 extern void smb_invalidate_inodes(struct smb_sb_info *server);
 extern int smb_revalidate_inode(struct dentry *dentry);
-extern int smb_getattr(struct vfsmount *mnt, struct dentry *dentry, struct 
kstat *stat);
+extern int smb_getattr(struct vfsmount *mnt, struct dentry *dentry,
+                      struct kstat *stat, struct file *file);
 extern int smb_notify_change(struct dentry *dentry, struct iattr *attr);
 /* file.c */
 extern const struct address_space_operations smb_file_aops;
Index: linux/fs/stat.c
===================================================================
--- linux.orig/fs/stat.c        2007-08-09 16:47:30.000000000 +0200
+++ linux/fs/stat.c     2007-08-09 16:48:45.000000000 +0200
@@ -37,7 +37,8 @@ void generic_fillattr(struct inode *inod
 
 EXPORT_SYMBOL(generic_fillattr);
 
-int vfs_getattr(struct vfsmount *mnt, struct dentry *dentry, struct kstat 
*stat)
+static int vfs_fgetattr(struct vfsmount *mnt, struct dentry *dentry,
+                       struct kstat *stat, struct file *file)
 {
        struct inode *inode = dentry->d_inode;
        int retval;
@@ -47,12 +48,17 @@ int vfs_getattr(struct vfsmount *mnt, st
                return retval;
 
        if (inode->i_op->getattr)
-               return inode->i_op->getattr(mnt, dentry, stat);
+               return inode->i_op->getattr(mnt, dentry, stat, file);
 
        generic_fillattr(inode, stat);
        return 0;
 }
 
+int vfs_getattr(struct vfsmount *mnt, struct dentry *dentry, struct kstat 
*stat)
+{
+       return vfs_fgetattr(mnt, dentry, stat, NULL);
+}
+
 EXPORT_SYMBOL(vfs_getattr);
 
 int vfs_stat_fd(int dfd, char __user *name, struct kstat *stat)
@@ -62,7 +68,7 @@ int vfs_stat_fd(int dfd, char __user *na
 
        error = __user_walk_fd(dfd, name, LOOKUP_FOLLOW, &nd);
        if (!error) {
-               error = vfs_getattr(nd.mnt, nd.dentry, stat);
+               error = vfs_fgetattr(nd.mnt, nd.dentry, stat, NULL);
                path_release(&nd);
        }
        return error;
@@ -82,7 +88,7 @@ int vfs_lstat_fd(int dfd, char __user *n
 
        error = __user_walk_fd(dfd, name, 0, &nd);
        if (!error) {
-               error = vfs_getattr(nd.mnt, nd.dentry, stat);
+               error = vfs_fgetattr(nd.mnt, nd.dentry, stat, NULL);
                path_release(&nd);
        }
        return error;
@@ -101,7 +107,7 @@ int vfs_fstat(unsigned int fd, struct ks
        int error = -EBADF;
 
        if (f) {
-               error = vfs_getattr(f->f_path.mnt, f->f_path.dentry, stat);
+               error = vfs_fgetattr(f->f_path.mnt, f->f_path.dentry, stat, f);
                fput(f);
        }
        return error;
Index: linux/fs/sysv/itree.c
===================================================================
--- linux.orig/fs/sysv/itree.c  2007-08-09 16:47:30.000000000 +0200
+++ linux/fs/sysv/itree.c       2007-08-09 16:48:45.000000000 +0200
@@ -440,7 +440,8 @@ static unsigned sysv_nblocks(struct supe
        return blocks;
 }
 
-int sysv_getattr(struct vfsmount *mnt, struct dentry *dentry, struct kstat 
*stat)
+int sysv_getattr(struct vfsmount *mnt, struct dentry *dentry,
+                struct kstat *stat, struct file *file)
 {
        struct super_block *s = mnt->mnt_sb;
        generic_fillattr(dentry->d_inode, stat);
Index: linux/fs/sysv/sysv.h
===================================================================
--- linux.orig/fs/sysv/sysv.h   2007-08-09 16:47:30.000000000 +0200
+++ linux/fs/sysv/sysv.h        2007-08-09 16:48:45.000000000 +0200
@@ -145,7 +145,8 @@ extern int sysv_write_inode(struct inode
 extern int sysv_sync_inode(struct inode *);
 extern int sysv_sync_file(struct file *, struct dentry *, int);
 extern void sysv_set_inode(struct inode *, dev_t);
-extern int sysv_getattr(struct vfsmount *, struct dentry *, struct kstat *);
+extern int sysv_getattr(struct vfsmount *, struct dentry *, struct kstat *,
+                       struct file *);
 extern int sysv_init_icache(void);
 extern void sysv_destroy_icache(void);
 
Index: linux/fs/xfs/linux-2.6/xfs_iops.c
===================================================================
--- linux.orig/fs/xfs/linux-2.6/xfs_iops.c      2007-08-09 16:47:30.000000000 
+0200
+++ linux/fs/xfs/linux-2.6/xfs_iops.c   2007-08-09 16:48:45.000000000 +0200
@@ -617,7 +617,8 @@ STATIC int
 xfs_vn_getattr(
        struct vfsmount *mnt,
        struct dentry   *dentry,
-       struct kstat    *stat)
+       struct kstat    *stat,
+       struct file     *file)
 {
        struct inode    *inode = dentry->d_inode;
        bhv_vnode_t     *vp = vn_from_inode(inode);
Index: linux/include/linux/coda_linux.h
===================================================================
--- linux.orig/include/linux/coda_linux.h       2007-08-09 16:47:30.000000000 
+0200
+++ linux/include/linux/coda_linux.h    2007-08-09 16:48:45.000000000 +0200
@@ -39,7 +39,8 @@ int coda_open(struct inode *i, struct fi
 int coda_release(struct inode *i, struct file *f);
 int coda_permission(struct inode *inode, int mask, struct nameidata *nd);
 int coda_revalidate_inode(struct dentry *);
-int coda_getattr(struct vfsmount *, struct dentry *, struct kstat *);
+int coda_getattr(struct vfsmount *, struct dentry *, struct kstat *,
+                struct file *);
 int coda_setattr(struct dentry *, struct iattr *);
 
 /* this file:  heloers */
Index: linux/include/linux/fs.h
===================================================================
--- linux.orig/include/linux/fs.h       2007-08-09 16:47:30.000000000 +0200
+++ linux/include/linux/fs.h    2007-08-09 16:48:45.000000000 +0200
@@ -1210,7 +1210,8 @@ struct inode_operations {
        void (*truncate) (struct inode *);
        int (*permission) (struct inode *, int, struct nameidata *);
        int (*setattr) (struct dentry *, struct iattr *);
-       int (*getattr) (struct vfsmount *mnt, struct dentry *, struct kstat *);
+       int (*getattr) (struct vfsmount *mnt, struct dentry *, struct kstat *,
+                       struct file *file);
        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);
@@ -1929,7 +1930,8 @@ extern int dcache_dir_open(struct inode 
 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 *,
+                         struct file *);
 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/include/linux/msdos_fs.h
===================================================================
--- linux.orig/include/linux/msdos_fs.h 2007-08-09 16:47:30.000000000 +0200
+++ linux/include/linux/msdos_fs.h      2007-08-09 16:48:45.000000000 +0200
@@ -404,7 +404,7 @@ extern const struct inode_operations fat
 extern int fat_notify_change(struct dentry * dentry, struct iattr * attr);
 extern void fat_truncate(struct inode *inode);
 extern int fat_getattr(struct vfsmount *mnt, struct dentry *dentry,
-                      struct kstat *stat);
+                      struct kstat *stat, struct file *file);
 
 /* fat/inode.c */
 extern void fat_attach(struct inode *inode, loff_t i_pos);
Index: linux/include/linux/nfs_fs.h
===================================================================
--- linux.orig/include/linux/nfs_fs.h   2007-08-09 16:47:30.000000000 +0200
+++ linux/include/linux/nfs_fs.h        2007-08-09 16:48:45.000000000 +0200
@@ -285,7 +285,8 @@ extern struct inode *nfs_fhget(struct su
                                struct nfs_fattr *);
 extern int nfs_refresh_inode(struct inode *, struct nfs_fattr *);
 extern int nfs_post_op_update_inode(struct inode *inode, struct nfs_fattr 
*fattr);
-extern int nfs_getattr(struct vfsmount *, struct dentry *, struct kstat *);
+extern int nfs_getattr(struct vfsmount *, struct dentry *, struct kstat *,
+                      struct file *);
 extern int nfs_permission(struct inode *, int, struct nameidata *);
 extern int nfs_access_get_cached(struct inode *, struct rpc_cred *, struct 
nfs_access_entry *);
 extern void nfs_access_add_cache(struct inode *, struct nfs_access_entry *);
Index: linux/fs/reiser4/plugin/inode_ops.c
===================================================================
--- linux.orig/fs/reiser4/plugin/inode_ops.c    2007-08-09 16:47:30.000000000 
+0200
+++ linux/fs/reiser4/plugin/inode_ops.c 2007-08-09 16:48:53.000000000 +0200
@@ -475,7 +475,8 @@ int reiser4_setattr_common(struct dentry
    inode_operations
 */
 int reiser4_getattr_common(struct vfsmount *mnt UNUSED_ARG,
-                          struct dentry *dentry, struct kstat *stat)
+                          struct dentry *dentry, struct kstat *stat,
+                          struct file *file UNUSED_ARG)
 {
        struct inode *obj;
 
Index: linux/fs/reiser4/plugin/object.h
===================================================================
--- linux.orig/fs/reiser4/plugin/object.h       2007-08-09 16:47:30.000000000 
+0200
+++ linux/fs/reiser4/plugin/object.h    2007-08-09 16:48:53.000000000 +0200
@@ -29,7 +29,7 @@ int reiser4_permission_common(struct ino
                              struct nameidata *nameidata);
 int reiser4_setattr_common(struct dentry *, struct iattr *);
 int reiser4_getattr_common(struct vfsmount *mnt, struct dentry *,
-                          struct kstat *);
+                          struct kstat *, struct file *);
 
 /* common implementations of file operations */
 loff_t reiser4_llseek_dir_common(struct file *, loff_t off, int origin);
Index: linux/fs/revoked_inode.c
===================================================================
--- linux.orig/fs/revoked_inode.c       2007-08-09 16:47:30.000000000 +0200
+++ linux/fs/revoked_inode.c    2007-08-09 16:48:53.000000000 +0200
@@ -295,7 +295,7 @@ static int revoked_inode_permission(stru
 }
 
 static int revoked_inode_getattr(struct vfsmount *mnt, struct dentry *dentry,
-                                struct kstat *stat)
+                                struct kstat *stat, struct file *file)
 {
        return -EBADF;
 }

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

Reply via email to