From: David Howells Give the statfs superblock operation a vfsmount pointer rather than a superblock pointer. This complements the get_sb() patch. That reduced the significance of sb->s_root, allowing NFS to place a fake root there. However, NFS does require a dentry to use as a target for the statfs operation. This permits the root in the vfsmount to be used instead. Signed-off-by: David Howells Cc: Trond Myklebust Signed-off-by: Andrew Morton --- Documentation/filesystems/Locking | 2 +- Documentation/filesystems/vfs.txt | 2 +- arch/alpha/kernel/osf_sys.c | 8 ++++---- arch/mips/kernel/sysirix.c | 12 ++++++------ arch/parisc/hpux/sys_hpux.c | 15 ++++++++++----- arch/sparc64/solaris/fs.c | 4 ++-- fs/adfs/super.c | 9 +++++---- fs/affs/super.c | 6 ++++-- fs/befs/linuxvfs.c | 6 ++++-- fs/bfs/inode.c | 4 +++- fs/cifs/cifsfs.c | 3 ++- fs/coda/inode.c | 6 +++--- fs/coda/upcall.c | 5 +++-- fs/compat.c | 8 ++++---- fs/cramfs/inode.c | 5 ++++- fs/efs/super.c | 7 ++++--- fs/ext2/super.c | 5 +++-- fs/ext3/super.c | 5 +++-- fs/fat/inode.c | 8 ++++---- fs/freevxfs/vxfs_super.c | 13 +++++++------ fs/fuse/inode.c | 3 ++- fs/hfs/super.c | 4 +++- fs/hfsplus/super.c | 5 ++++- fs/hostfs/hostfs_kern.c | 4 ++-- fs/hpfs/super.c | 4 +++- fs/hppfs/hppfs_kern.c | 2 +- fs/hugetlbfs/inode.c | 4 ++-- fs/isofs/inode.c | 7 +++++-- fs/jffs/inode-v23.c | 5 +++-- fs/jffs2/fs.c | 5 +++-- fs/jffs2/os-linux.h | 2 +- fs/jfs/super.c | 4 ++-- fs/libfs.c | 4 ++-- fs/minix/inode.c | 11 ++++++----- fs/ncpfs/inode.c | 6 ++++-- fs/nfs/inode.c | 5 +++-- fs/nfsd/nfs4xdr.c | 2 +- fs/nfsd/vfs.c | 14 ++++++++++++-- fs/ntfs/super.c | 8 +++++--- fs/ocfs2/super.c | 11 ++++++----- fs/open.c | 26 +++++++++++++------------- fs/qnx4/inode.c | 7 +++++-- fs/reiserfs/super.c | 8 ++++---- fs/romfs/inode.c | 5 +++-- fs/smbfs/inode.c | 6 +++--- fs/smbfs/proc.c | 5 +++-- fs/smbfs/proto.h | 2 +- fs/super.c | 7 ++++++- fs/sysv/inode.c | 4 +++- fs/udf/super.c | 7 +++++-- fs/ufs/super.c | 4 +++- fs/xfs/linux-2.6/xfs_super.c | 4 ++-- include/linux/coda_psdev.h | 2 +- include/linux/fs.h | 6 +++--- include/linux/mount.h | 5 +++++ include/linux/security.h | 14 +++++++------- kernel/acct.c | 2 +- mm/shmem.c | 4 ++-- security/dummy.c | 2 +- security/selinux/hooks.c | 6 +++--- 60 files changed, 221 insertions(+), 148 deletions(-) diff -puN arch/alpha/kernel/osf_sys.c~nfs-permit-filesystem-to-perform-statfs-with-a-known-root-dentry arch/alpha/kernel/osf_sys.c --- devel/arch/alpha/kernel/osf_sys.c~nfs-permit-filesystem-to-perform-statfs-with-a-known-root-dentry 2006-05-12 03:55:53.000000000 -0700 +++ devel-akpm/arch/alpha/kernel/osf_sys.c 2006-05-12 03:55:53.000000000 -0700 @@ -240,11 +240,11 @@ linux_to_osf_statfs(struct kstatfs *linu } static int -do_osf_statfs(struct dentry * dentry, struct osf_statfs __user *buffer, +do_osf_statfs(struct vfsmount *mnt, struct osf_statfs __user *buffer, unsigned long bufsiz) { struct kstatfs linux_stat; - int error = vfs_statfs(dentry->d_inode->i_sb, &linux_stat); + int error = vfs_statfs(mnt, &linux_stat); if (!error) error = linux_to_osf_statfs(&linux_stat, buffer, bufsiz); return error; @@ -258,7 +258,7 @@ osf_statfs(char __user *path, struct osf retval = user_path_walk(path, &nd); if (!retval) { - retval = do_osf_statfs(nd.dentry, buffer, bufsiz); + retval = do_osf_statfs(nd.mnt, buffer, bufsiz); path_release(&nd); } return retval; @@ -273,7 +273,7 @@ osf_fstatfs(unsigned long fd, struct osf retval = -EBADF; file = fget(fd); if (file) { - retval = do_osf_statfs(file->f_dentry, buffer, bufsiz); + retval = do_osf_statfs(file->f_vfsmnt, buffer, bufsiz); fput(file); } return retval; diff -puN arch/mips/kernel/sysirix.c~nfs-permit-filesystem-to-perform-statfs-with-a-known-root-dentry arch/mips/kernel/sysirix.c --- devel/arch/mips/kernel/sysirix.c~nfs-permit-filesystem-to-perform-statfs-with-a-known-root-dentry 2006-05-12 03:55:53.000000000 -0700 +++ devel-akpm/arch/mips/kernel/sysirix.c 2006-05-12 03:55:53.000000000 -0700 @@ -694,7 +694,7 @@ asmlinkage int irix_statfs(const char __ if (error) goto out; - error = vfs_statfs(nd.dentry->d_inode->i_sb, &kbuf); + error = vfs_statfs(nd.mnt, &kbuf); if (error) goto dput_and_out; @@ -732,7 +732,7 @@ asmlinkage int irix_fstatfs(unsigned int goto out; } - error = vfs_statfs(file->f_dentry->d_inode->i_sb, &kbuf); + error = vfs_statfs(file->f_vfsmnt, &kbuf); if (error) goto out_f; @@ -1360,7 +1360,7 @@ asmlinkage int irix_statvfs(char __user error = user_path_walk(fname, &nd); if (error) goto out; - error = vfs_statfs(nd.dentry->d_inode->i_sb, &kbuf); + error = vfs_statfs(nd.mnt, &kbuf); if (error) goto dput_and_out; @@ -1406,7 +1406,7 @@ asmlinkage int irix_fstatvfs(int fd, str error = -EBADF; goto out; } - error = vfs_statfs(file->f_dentry->d_inode->i_sb, &kbuf); + error = vfs_statfs(file->f_vfsmnt, &kbuf); if (error) goto out_f; @@ -1611,7 +1611,7 @@ asmlinkage int irix_statvfs64(char __use error = user_path_walk(fname, &nd); if (error) goto out; - error = vfs_statfs(nd.dentry->d_inode->i_sb, &kbuf); + error = vfs_statfs(nd.mnt, &kbuf); if (error) goto dput_and_out; @@ -1658,7 +1658,7 @@ asmlinkage int irix_fstatvfs64(int fd, s error = -EBADF; goto out; } - error = vfs_statfs(file->f_dentry->d_inode->i_sb, &kbuf); + error = vfs_statfs(file->f_vfsmnt, &kbuf); if (error) goto out_f; diff -puN arch/parisc/hpux/sys_hpux.c~nfs-permit-filesystem-to-perform-statfs-with-a-known-root-dentry arch/parisc/hpux/sys_hpux.c --- devel/arch/parisc/hpux/sys_hpux.c~nfs-permit-filesystem-to-perform-statfs-with-a-known-root-dentry 2006-05-12 03:55:53.000000000 -0700 +++ devel-akpm/arch/parisc/hpux/sys_hpux.c 2006-05-12 03:55:53.000000000 -0700 @@ -139,13 +139,18 @@ static int hpux_ustat(dev_t dev, struct { struct super_block *s; struct hpux_ustat tmp; /* Changed to hpux_ustat */ + struct vfsmount mnt; struct kstatfs sbuf; int err = -EINVAL; s = user_get_super(dev); if (s == NULL) goto out; - err = vfs_statfs(s, &sbuf); + memset(&mnt, 0, sizeof(mnt)); + mnt.mnt_sb = s; + mnt.mnt_root = s->s_root; + mnt.mnt_mountpoint = s->s_root; + err = vfs_statfs(&mnt, &sbuf); drop_super(s); if (err) goto out; @@ -186,12 +191,12 @@ struct hpux_statfs { int16_t f_pad; }; -static int vfs_statfs_hpux(struct super_block *sb, struct hpux_statfs *buf) +static int vfs_statfs_hpux(struct vfsmount *mnt, struct hpux_statfs *buf) { struct kstatfs st; int retval; - retval = vfs_statfs(sb, &st); + retval = vfs_statfs(mnt, &st); if (retval) return retval; @@ -219,7 +224,7 @@ asmlinkage long hpux_statfs(const char _ error = user_path_walk(path, &nd); if (!error) { struct hpux_statfs tmp; - error = vfs_statfs_hpux(nd.dentry->d_inode->i_sb, &tmp); + error = vfs_statfs_hpux(nd.mnt, &tmp); if (!error && copy_to_user(buf, &tmp, sizeof(tmp))) error = -EFAULT; path_release(&nd); @@ -237,7 +242,7 @@ asmlinkage long hpux_fstatfs(unsigned in file = fget(fd); if (!file) goto out; - error = vfs_statfs_hpux(file->f_dentry->d_inode->i_sb, &tmp); + error = vfs_statfs_hpux(file->f_vfsmnt, &tmp); if (!error && copy_to_user(buf, &tmp, sizeof(tmp))) error = -EFAULT; fput(file); diff -puN arch/sparc64/solaris/fs.c~nfs-permit-filesystem-to-perform-statfs-with-a-known-root-dentry arch/sparc64/solaris/fs.c --- devel/arch/sparc64/solaris/fs.c~nfs-permit-filesystem-to-perform-statfs-with-a-known-root-dentry 2006-05-12 03:55:53.000000000 -0700 +++ devel-akpm/arch/sparc64/solaris/fs.c 2006-05-12 03:55:53.000000000 -0700 @@ -356,7 +356,7 @@ static int report_statvfs(struct vfsmoun int error; struct sol_statvfs __user *ss = A(buf); - error = vfs_statfs(mnt->mnt_sb, &s); + error = vfs_statfs(mnt, &s); if (!error) { const char *p = mnt->mnt_sb->s_type->name; int i = 0; @@ -392,7 +392,7 @@ static int report_statvfs64(struct vfsmo int error; struct sol_statvfs64 __user *ss = A(buf); - error = vfs_statfs(mnt->mnt_sb, &s); + error = vfs_statfs(mnt, &s); if (!error) { const char *p = mnt->mnt_sb->s_type->name; int i = 0; diff -puN Documentation/filesystems/Locking~nfs-permit-filesystem-to-perform-statfs-with-a-known-root-dentry Documentation/filesystems/Locking --- devel/Documentation/filesystems/Locking~nfs-permit-filesystem-to-perform-statfs-with-a-known-root-dentry 2006-05-12 03:55:53.000000000 -0700 +++ devel-akpm/Documentation/filesystems/Locking 2006-05-12 03:55:53.000000000 -0700 @@ -99,7 +99,7 @@ prototypes: int (*sync_fs)(struct super_block *sb, int wait); void (*write_super_lockfs) (struct super_block *); void (*unlockfs) (struct super_block *); - int (*statfs) (struct super_block *, struct kstatfs *); + int (*statfs) (struct vfsmount *, struct kstatfs *); int (*remount_fs) (struct super_block *, int *, char *); void (*clear_inode) (struct inode *); void (*umount_begin) (struct super_block *); diff -puN Documentation/filesystems/vfs.txt~nfs-permit-filesystem-to-perform-statfs-with-a-known-root-dentry Documentation/filesystems/vfs.txt --- devel/Documentation/filesystems/vfs.txt~nfs-permit-filesystem-to-perform-statfs-with-a-known-root-dentry 2006-05-12 03:55:53.000000000 -0700 +++ devel-akpm/Documentation/filesystems/vfs.txt 2006-05-12 03:55:53.000000000 -0700 @@ -211,7 +211,7 @@ struct super_operations { int (*sync_fs)(struct super_block *sb, int wait); void (*write_super_lockfs) (struct super_block *); void (*unlockfs) (struct super_block *); - int (*statfs) (struct super_block *, struct kstatfs *); + int (*statfs) (struct vfsmount *, struct kstatfs *); int (*remount_fs) (struct super_block *, int *, char *); void (*clear_inode) (struct inode *); void (*umount_begin) (struct super_block *); diff -puN fs/adfs/super.c~nfs-permit-filesystem-to-perform-statfs-with-a-known-root-dentry fs/adfs/super.c --- devel/fs/adfs/super.c~nfs-permit-filesystem-to-perform-statfs-with-a-known-root-dentry 2006-05-12 03:55:53.000000000 -0700 +++ devel-akpm/fs/adfs/super.c 2006-05-12 03:55:53.000000000 -0700 @@ -20,6 +20,7 @@ #include #include #include +#include #include #include @@ -196,17 +197,17 @@ static int adfs_remount(struct super_blo return parse_options(sb, data); } -static int adfs_statfs(struct super_block *sb, struct kstatfs *buf) +static int adfs_statfs(struct vfsmount *mnt, struct kstatfs *buf) { - struct adfs_sb_info *asb = ADFS_SB(sb); + struct adfs_sb_info *asb = ADFS_SB(mnt->mnt_sb); buf->f_type = ADFS_SUPER_MAGIC; buf->f_namelen = asb->s_namelen; - buf->f_bsize = sb->s_blocksize; + buf->f_bsize = mnt->mnt_sb->s_blocksize; buf->f_blocks = asb->s_size; buf->f_files = asb->s_ids_per_zone * asb->s_map_size; buf->f_bavail = - buf->f_bfree = adfs_map_free(sb); + buf->f_bfree = adfs_map_free(mnt->mnt_sb); buf->f_ffree = (long)(buf->f_bfree * buf->f_files) / (long)buf->f_blocks; return 0; diff -puN fs/affs/super.c~nfs-permit-filesystem-to-perform-statfs-with-a-known-root-dentry fs/affs/super.c --- devel/fs/affs/super.c~nfs-permit-filesystem-to-perform-statfs-with-a-known-root-dentry 2006-05-12 03:55:53.000000000 -0700 +++ devel-akpm/fs/affs/super.c 2006-05-12 03:55:53.000000000 -0700 @@ -14,11 +14,12 @@ #include #include #include +#include #include "affs.h" extern struct timezone sys_tz; -static int affs_statfs(struct super_block *sb, struct kstatfs *buf); +static int affs_statfs(struct vfsmount *mnt, struct kstatfs *buf); static int affs_remount (struct super_block *sb, int *flags, char *data); static void @@ -508,8 +509,9 @@ affs_remount(struct super_block *sb, int } static int -affs_statfs(struct super_block *sb, struct kstatfs *buf) +affs_statfs(struct vfsmount *mnt, struct kstatfs *buf) { + struct super_block *sb = mnt->mnt_sb; int free; pr_debug("AFFS: statfs() partsize=%d, reserved=%d\n",AFFS_SB(sb)->s_partition_size, diff -puN fs/befs/linuxvfs.c~nfs-permit-filesystem-to-perform-statfs-with-a-known-root-dentry fs/befs/linuxvfs.c --- devel/fs/befs/linuxvfs.c~nfs-permit-filesystem-to-perform-statfs-with-a-known-root-dentry 2006-05-12 03:55:53.000000000 -0700 +++ devel-akpm/fs/befs/linuxvfs.c 2006-05-12 03:55:53.000000000 -0700 @@ -15,6 +15,7 @@ #include #include #include +#include #include "befs.h" #include "btree.h" @@ -49,7 +50,7 @@ static int befs_nls2utf(struct super_blo char **out, int *out_len); static void befs_put_super(struct super_block *); static int befs_remount(struct super_block *, int *, char *); -static int befs_statfs(struct super_block *, struct kstatfs *); +static int befs_statfs(struct vfsmount *, struct kstatfs *); static int parse_options(char *, befs_mount_options *); static const struct super_operations befs_sops = { @@ -880,8 +881,9 @@ befs_remount(struct super_block *sb, int } static int -befs_statfs(struct super_block *sb, struct kstatfs *buf) +befs_statfs(struct vfsmount *mnt, struct kstatfs *buf) { + struct super_block *sb = mnt->mnt_sb; befs_debug(sb, "---> befs_statfs()"); diff -puN fs/bfs/inode.c~nfs-permit-filesystem-to-perform-statfs-with-a-known-root-dentry fs/bfs/inode.c --- devel/fs/bfs/inode.c~nfs-permit-filesystem-to-perform-statfs-with-a-known-root-dentry 2006-05-12 03:55:53.000000000 -0700 +++ devel-akpm/fs/bfs/inode.c 2006-05-12 03:55:53.000000000 -0700 @@ -15,6 +15,7 @@ #include #include #include +#include #include #include "bfs.h" @@ -203,8 +204,9 @@ static void bfs_put_super(struct super_b s->s_fs_info = NULL; } -static int bfs_statfs(struct super_block *s, struct kstatfs *buf) +static int bfs_statfs(struct vfsmount *mnt, struct kstatfs *buf) { + struct super_block *s = mnt->mnt_sb; struct bfs_sb_info *info = BFS_SB(s); u64 id = huge_encode_dev(s->s_bdev->bd_dev); buf->f_type = BFS_MAGIC; diff -puN fs/cifs/cifsfs.c~nfs-permit-filesystem-to-perform-statfs-with-a-known-root-dentry fs/cifs/cifsfs.c --- devel/fs/cifs/cifsfs.c~nfs-permit-filesystem-to-perform-statfs-with-a-known-root-dentry 2006-05-12 03:55:53.000000000 -0700 +++ devel-akpm/fs/cifs/cifsfs.c 2006-05-12 03:55:53.000000000 -0700 @@ -166,8 +166,9 @@ cifs_put_super(struct super_block *sb) } static int -cifs_statfs(struct super_block *sb, struct kstatfs *buf) +cifs_statfs(struct vfsmount *mnt, struct kstatfs *buf) { + struct super_block *sb = mnt->mnt_sb; int xid; int rc = -EOPNOTSUPP; struct cifs_sb_info *cifs_sb; diff -puN fs/coda/inode.c~nfs-permit-filesystem-to-perform-statfs-with-a-known-root-dentry fs/coda/inode.c --- devel/fs/coda/inode.c~nfs-permit-filesystem-to-perform-statfs-with-a-known-root-dentry 2006-05-12 03:55:53.000000000 -0700 +++ devel-akpm/fs/coda/inode.c 2006-05-12 03:55:53.000000000 -0700 @@ -36,7 +36,7 @@ /* VFS super_block ops */ static void coda_clear_inode(struct inode *); static void coda_put_super(struct super_block *); -static int coda_statfs(struct super_block *sb, struct kstatfs *buf); +static int coda_statfs(struct vfsmount *mnt, struct kstatfs *buf); static kmem_cache_t * coda_inode_cachep; @@ -278,13 +278,13 @@ struct inode_operations coda_file_inode_ .setattr = coda_setattr, }; -static int coda_statfs(struct super_block *sb, struct kstatfs *buf) +static int coda_statfs(struct vfsmount *mnt, struct kstatfs *buf) { int error; lock_kernel(); - error = venus_statfs(sb, buf); + error = venus_statfs(mnt, buf); unlock_kernel(); diff -puN fs/coda/upcall.c~nfs-permit-filesystem-to-perform-statfs-with-a-known-root-dentry fs/coda/upcall.c --- devel/fs/coda/upcall.c~nfs-permit-filesystem-to-perform-statfs-with-a-known-root-dentry 2006-05-12 03:55:53.000000000 -0700 +++ devel-akpm/fs/coda/upcall.c 2006-05-12 03:55:53.000000000 -0700 @@ -29,6 +29,7 @@ #include #include #include +#include #include #include @@ -611,7 +612,7 @@ int venus_pioctl(struct super_block *sb, return error; } -int venus_statfs(struct super_block *sb, struct kstatfs *sfs) +int venus_statfs(struct vfsmount *mnt, struct kstatfs *sfs) { union inputArgs *inp; union outputArgs *outp; @@ -620,7 +621,7 @@ int venus_statfs(struct super_block *sb, insize = max_t(unsigned int, INSIZE(statfs), OUTSIZE(statfs)); UPARG(CODA_STATFS); - error = coda_upcall(coda_sbp(sb), insize, &outsize, inp); + error = coda_upcall(coda_sbp(mnt->mnt_sb), insize, &outsize, inp); if (!error) { sfs->f_blocks = outp->coda_statfs.stat.f_blocks; diff -puN fs/compat.c~nfs-permit-filesystem-to-perform-statfs-with-a-known-root-dentry fs/compat.c --- devel/fs/compat.c~nfs-permit-filesystem-to-perform-statfs-with-a-known-root-dentry 2006-05-12 03:55:53.000000000 -0700 +++ devel-akpm/fs/compat.c 2006-05-12 03:55:53.000000000 -0700 @@ -197,7 +197,7 @@ asmlinkage long compat_sys_statfs(const error = user_path_walk(path, &nd); if (!error) { struct kstatfs tmp; - error = vfs_statfs(nd.dentry->d_inode->i_sb, &tmp); + error = vfs_statfs(nd.mnt, &tmp); if (!error) error = put_compat_statfs(buf, &tmp); path_release(&nd); @@ -215,7 +215,7 @@ asmlinkage long compat_sys_fstatfs(unsig file = fget(fd); if (!file) goto out; - error = vfs_statfs(file->f_dentry->d_inode->i_sb, &tmp); + error = vfs_statfs(file->f_vfsmnt, &tmp); if (!error) error = put_compat_statfs(buf, &tmp); fput(file); @@ -265,7 +265,7 @@ asmlinkage long compat_sys_statfs64(cons error = user_path_walk(path, &nd); if (!error) { struct kstatfs tmp; - error = vfs_statfs(nd.dentry->d_inode->i_sb, &tmp); + error = vfs_statfs(nd.mnt, &tmp); if (!error) error = put_compat_statfs64(buf, &tmp); path_release(&nd); @@ -286,7 +286,7 @@ asmlinkage long compat_sys_fstatfs64(uns file = fget(fd); if (!file) goto out; - error = vfs_statfs(file->f_dentry->d_inode->i_sb, &tmp); + error = vfs_statfs(file->f_vfsmnt, &tmp); if (!error) error = put_compat_statfs64(buf, &tmp); fput(file); diff -puN fs/cramfs/inode.c~nfs-permit-filesystem-to-perform-statfs-with-a-known-root-dentry fs/cramfs/inode.c --- devel/fs/cramfs/inode.c~nfs-permit-filesystem-to-perform-statfs-with-a-known-root-dentry 2006-05-12 03:55:53.000000000 -0700 +++ devel-akpm/fs/cramfs/inode.c 2006-05-12 03:55:53.000000000 -0700 @@ -22,6 +22,7 @@ #include #include #include +#include #include #include @@ -322,8 +323,10 @@ out: return -EINVAL; } -static int cramfs_statfs(struct super_block *sb, struct kstatfs *buf) +static int cramfs_statfs(struct vfsmount *mnt, struct kstatfs *buf) { + struct super_block *sb = mnt->mnt_sb; + buf->f_type = CRAMFS_MAGIC; buf->f_bsize = PAGE_CACHE_SIZE; buf->f_blocks = CRAMFS_SB(sb)->blocks; diff -puN fs/efs/super.c~nfs-permit-filesystem-to-perform-statfs-with-a-known-root-dentry fs/efs/super.c --- devel/fs/efs/super.c~nfs-permit-filesystem-to-perform-statfs-with-a-known-root-dentry 2006-05-12 03:55:53.000000000 -0700 +++ devel-akpm/fs/efs/super.c 2006-05-12 03:55:53.000000000 -0700 @@ -14,8 +14,9 @@ #include #include #include +#include -static int efs_statfs(struct super_block *s, struct kstatfs *buf); +static int efs_statfs(struct vfsmount *mnt, struct kstatfs *buf); static int efs_fill_super(struct super_block *s, void *d, int silent); static int efs_get_sb(struct file_system_type *fs_type, @@ -322,8 +323,8 @@ out_no_fs: return -EINVAL; } -static int efs_statfs(struct super_block *s, struct kstatfs *buf) { - struct efs_sb_info *sb = SUPER_INFO(s); +static int efs_statfs(struct vfsmount *mnt, struct kstatfs *buf) { + struct efs_sb_info *sb = SUPER_INFO(mnt->mnt_sb); buf->f_type = EFS_SUPER_MAGIC; /* efs magic number */ buf->f_bsize = EFS_BLOCKSIZE; /* blocksize */ diff -puN fs/ext2/super.c~nfs-permit-filesystem-to-perform-statfs-with-a-known-root-dentry fs/ext2/super.c --- devel/fs/ext2/super.c~nfs-permit-filesystem-to-perform-statfs-with-a-known-root-dentry 2006-05-12 03:55:53.000000000 -0700 +++ devel-akpm/fs/ext2/super.c 2006-05-12 03:55:53.000000000 -0700 @@ -39,7 +39,7 @@ static void ext2_sync_super(struct super_block *sb, struct ext2_super_block *es); static int ext2_remount (struct super_block * sb, int * flags, char * data); -static int ext2_statfs (struct super_block * sb, struct kstatfs * buf); +static int ext2_statfs (struct vfsmount * mnt, struct kstatfs * buf); void ext2_error (struct super_block * sb, const char * function, const char * fmt, ...) @@ -1038,8 +1038,9 @@ restore_opts: return err; } -static int ext2_statfs (struct super_block * sb, struct kstatfs * buf) +static int ext2_statfs (struct vfsmount * mnt, struct kstatfs * buf) { + struct super_block *sb = mnt->mnt_sb; struct ext2_sb_info *sbi = EXT2_SB(sb); unsigned long overhead; int i; diff -puN fs/ext3/super.c~nfs-permit-filesystem-to-perform-statfs-with-a-known-root-dentry fs/ext3/super.c --- devel/fs/ext3/super.c~nfs-permit-filesystem-to-perform-statfs-with-a-known-root-dentry 2006-05-12 03:55:53.000000000 -0700 +++ devel-akpm/fs/ext3/super.c 2006-05-12 03:55:53.000000000 -0700 @@ -58,7 +58,7 @@ static int ext3_sync_fs(struct super_blo static const char *ext3_decode_error(struct super_block * sb, int errno, char nbuf[16]); static int ext3_remount (struct super_block * sb, int * flags, char * data); -static int ext3_statfs (struct super_block * sb, struct kstatfs * buf); +static int ext3_statfs (struct vfsmount * mnt, struct kstatfs * buf); static void ext3_unlockfs(struct super_block *sb); static void ext3_write_super (struct super_block * sb); static void ext3_write_super_lockfs(struct super_block *sb); @@ -2318,8 +2318,9 @@ restore_opts: return err; } -static int ext3_statfs (struct super_block * sb, struct kstatfs * buf) +static int ext3_statfs (struct vfsmount * mnt, struct kstatfs * buf) { + struct super_block *sb = mnt->mnt_sb; struct ext3_sb_info *sbi = EXT3_SB(sb); struct ext3_super_block *es = sbi->s_es; unsigned long overhead; diff -puN fs/fat/inode.c~nfs-permit-filesystem-to-perform-statfs-with-a-known-root-dentry fs/fat/inode.c --- devel/fs/fat/inode.c~nfs-permit-filesystem-to-perform-statfs-with-a-known-root-dentry 2006-05-12 03:55:53.000000000 -0700 +++ devel-akpm/fs/fat/inode.c 2006-05-12 03:55:53.000000000 -0700 @@ -539,18 +539,18 @@ static int fat_remount(struct super_bloc return 0; } -static int fat_statfs(struct super_block *sb, struct kstatfs *buf) +static int fat_statfs(struct vfsmount *mnt, struct kstatfs *buf) { - struct msdos_sb_info *sbi = MSDOS_SB(sb); + struct msdos_sb_info *sbi = MSDOS_SB(mnt->mnt_sb); /* If the count of free cluster is still unknown, counts it here. */ if (sbi->free_clusters == -1) { - int err = fat_count_free_clusters(sb); + int err = fat_count_free_clusters(mnt->mnt_sb); if (err) return err; } - buf->f_type = sb->s_magic; + buf->f_type = mnt->mnt_sb->s_magic; buf->f_bsize = sbi->cluster_size; buf->f_blocks = sbi->max_cluster - FAT_START_ENT; buf->f_bfree = sbi->free_clusters; diff -puN fs/freevxfs/vxfs_super.c~nfs-permit-filesystem-to-perform-statfs-with-a-known-root-dentry fs/freevxfs/vxfs_super.c --- devel/fs/freevxfs/vxfs_super.c~nfs-permit-filesystem-to-perform-statfs-with-a-known-root-dentry 2006-05-12 03:55:53.000000000 -0700 +++ devel-akpm/fs/freevxfs/vxfs_super.c 2006-05-12 03:55:53.000000000 -0700 @@ -40,6 +40,7 @@ #include #include #include +#include #include "vxfs.h" #include "vxfs_extern.h" @@ -55,7 +56,7 @@ MODULE_ALIAS("vxfs"); /* makes mount -t static void vxfs_put_super(struct super_block *); -static int vxfs_statfs(struct super_block *, struct kstatfs *); +static int vxfs_statfs(struct vfsmount *, struct kstatfs *); static int vxfs_remount(struct super_block *, int *, char *); static struct super_operations vxfs_super_ops = { @@ -90,12 +91,12 @@ vxfs_put_super(struct super_block *sbp) /** * vxfs_statfs - get filesystem information - * @sbp: VFS superblock + * @mnt: VFS mountpoint * @bufp: output buffer * * Description: * vxfs_statfs fills the statfs buffer @bufp with information - * about the filesystem described by @sbp. + * about the filesystem described by @mnt. * * Returns: * Zero. @@ -107,12 +108,12 @@ vxfs_put_super(struct super_block *sbp) * This is everything but complete... */ static int -vxfs_statfs(struct super_block *sbp, struct kstatfs *bufp) +vxfs_statfs(struct vfsmount *mnt, struct kstatfs *bufp) { - struct vxfs_sb_info *infp = VXFS_SBI(sbp); + struct vxfs_sb_info *infp = VXFS_SBI(mnt->mnt_sb); bufp->f_type = VXFS_SUPER_MAGIC; - bufp->f_bsize = sbp->s_blocksize; + bufp->f_bsize = mnt->mnt_sb->s_blocksize; bufp->f_blocks = infp->vsi_raw->vs_dsize; bufp->f_bfree = infp->vsi_raw->vs_free; bufp->f_bavail = 0; diff -puN fs/fuse/inode.c~nfs-permit-filesystem-to-perform-statfs-with-a-known-root-dentry fs/fuse/inode.c --- devel/fs/fuse/inode.c~nfs-permit-filesystem-to-perform-statfs-with-a-known-root-dentry 2006-05-12 03:55:53.000000000 -0700 +++ devel-akpm/fs/fuse/inode.c 2006-05-12 03:55:53.000000000 -0700 @@ -237,8 +237,9 @@ static void convert_fuse_statfs(struct k /* fsid is left zero */ } -static int fuse_statfs(struct super_block *sb, struct kstatfs *buf) +static int fuse_statfs(struct vfsmount *mnt, struct kstatfs *buf) { + struct super_block *sb = mnt->mnt_sb; struct fuse_conn *fc = get_fuse_conn_super(sb); struct fuse_req *req; struct fuse_statfs_out outarg; diff -puN fs/hfsplus/super.c~nfs-permit-filesystem-to-perform-statfs-with-a-known-root-dentry fs/hfsplus/super.c --- devel/fs/hfsplus/super.c~nfs-permit-filesystem-to-perform-statfs-with-a-known-root-dentry 2006-05-12 03:55:53.000000000 -0700 +++ devel-akpm/fs/hfsplus/super.c 2006-05-12 03:55:53.000000000 -0700 @@ -15,6 +15,7 @@ #include #include #include +#include #include static struct inode *hfsplus_alloc_inode(struct super_block *sb); @@ -212,8 +213,10 @@ static void hfsplus_put_super(struct sup sb->s_fs_info = NULL; } -static int hfsplus_statfs(struct super_block *sb, struct kstatfs *buf) +static int hfsplus_statfs(struct vfsmount *mnt, struct kstatfs *buf) { + struct super_block *sb = mnt->mnt_sb; + buf->f_type = HFSPLUS_SUPER_MAGIC; buf->f_bsize = sb->s_blocksize; buf->f_blocks = HFSPLUS_SB(sb).total_blocks << HFSPLUS_SB(sb).fs_shift; diff -puN fs/hfs/super.c~nfs-permit-filesystem-to-perform-statfs-with-a-known-root-dentry fs/hfs/super.c --- devel/fs/hfs/super.c~nfs-permit-filesystem-to-perform-statfs-with-a-known-root-dentry 2006-05-12 03:55:53.000000000 -0700 +++ devel-akpm/fs/hfs/super.c 2006-05-12 03:55:53.000000000 -0700 @@ -80,8 +80,10 @@ static void hfs_put_super(struct super_b * * changed f_files/f_ffree to reflect the fs_ablock/free_ablocks. */ -static int hfs_statfs(struct super_block *sb, struct kstatfs *buf) +static int hfs_statfs(struct vfsmount *mnt, struct kstatfs *buf) { + struct super_block *sb = mnt->mnt_sb; + buf->f_type = HFS_SUPER_MAGIC; buf->f_bsize = sb->s_blocksize; buf->f_blocks = (u32)HFS_SB(sb)->fs_ablocks * HFS_SB(sb)->fs_div; diff -puN fs/hostfs/hostfs_kern.c~nfs-permit-filesystem-to-perform-statfs-with-a-known-root-dentry fs/hostfs/hostfs_kern.c --- devel/fs/hostfs/hostfs_kern.c~nfs-permit-filesystem-to-perform-statfs-with-a-known-root-dentry 2006-05-12 03:55:53.000000000 -0700 +++ devel-akpm/fs/hostfs/hostfs_kern.c 2006-05-12 03:55:53.000000000 -0700 @@ -239,7 +239,7 @@ static int read_inode(struct inode *ino) return(err); } -int hostfs_statfs(struct super_block *sb, struct kstatfs *sf) +int hostfs_statfs(struct vfsmount *mnt, struct kstatfs *sf) { /* do_statfs uses struct statfs64 internally, but the linux kernel * struct statfs still has 32-bit versions for most of these fields, @@ -252,7 +252,7 @@ int hostfs_statfs(struct super_block *sb long long f_files; long long f_ffree; - err = do_statfs(HOSTFS_I(sb->s_root->d_inode)->host_filename, + err = do_statfs(HOSTFS_I(mnt->mnt_sb->s_root->d_inode)->host_filename, &sf->f_bsize, &f_blocks, &f_bfree, &f_bavail, &f_files, &f_ffree, &sf->f_fsid, sizeof(sf->f_fsid), &sf->f_namelen, sf->f_spare); diff -puN fs/hpfs/super.c~nfs-permit-filesystem-to-perform-statfs-with-a-known-root-dentry fs/hpfs/super.c --- devel/fs/hpfs/super.c~nfs-permit-filesystem-to-perform-statfs-with-a-known-root-dentry 2006-05-12 03:55:53.000000000 -0700 +++ devel-akpm/fs/hpfs/super.c 2006-05-12 03:55:53.000000000 -0700 @@ -11,6 +11,7 @@ #include #include #include +#include /* Mark the filesystem dirty, so that chkdsk checks it when os/2 booted */ @@ -135,8 +136,9 @@ static unsigned count_bitmaps(struct sup return count; } -static int hpfs_statfs(struct super_block *s, struct kstatfs *buf) +static int hpfs_statfs(struct vfsmount *mnt, struct kstatfs *buf) { + struct super_block *s = mnt->mnt_sb; struct hpfs_sb_info *sbi = hpfs_sb(s); lock_kernel(); diff -puN fs/hppfs/hppfs_kern.c~nfs-permit-filesystem-to-perform-statfs-with-a-known-root-dentry fs/hppfs/hppfs_kern.c --- devel/fs/hppfs/hppfs_kern.c~nfs-permit-filesystem-to-perform-statfs-with-a-known-root-dentry 2006-05-12 03:55:53.000000000 -0700 +++ devel-akpm/fs/hppfs/hppfs_kern.c 2006-05-12 03:55:53.000000000 -0700 @@ -616,7 +616,7 @@ static const struct file_operations hppf .fsync = hppfs_fsync, }; -static int hppfs_statfs(struct super_block *sb, struct kstatfs *sf) +static int hppfs_statfs(struct vfsmount *mnt, struct kstatfs *sf) { sf->f_blocks = 0; sf->f_bfree = 0; diff -puN fs/hugetlbfs/inode.c~nfs-permit-filesystem-to-perform-statfs-with-a-known-root-dentry fs/hugetlbfs/inode.c --- devel/fs/hugetlbfs/inode.c~nfs-permit-filesystem-to-perform-statfs-with-a-known-root-dentry 2006-05-12 03:55:53.000000000 -0700 +++ devel-akpm/fs/hugetlbfs/inode.c 2006-05-12 03:55:53.000000000 -0700 @@ -467,9 +467,9 @@ static int hugetlbfs_set_page_dirty(stru return 0; } -static int hugetlbfs_statfs(struct super_block *sb, struct kstatfs *buf) +static int hugetlbfs_statfs(struct vfsmount *mnt, struct kstatfs *buf) { - struct hugetlbfs_sb_info *sbinfo = HUGETLBFS_SB(sb); + struct hugetlbfs_sb_info *sbinfo = HUGETLBFS_SB(mnt->mnt_sb); buf->f_type = HUGETLBFS_MAGIC; buf->f_bsize = HPAGE_SIZE; diff -puN fs/isofs/inode.c~nfs-permit-filesystem-to-perform-statfs-with-a-known-root-dentry fs/isofs/inode.c --- devel/fs/isofs/inode.c~nfs-permit-filesystem-to-perform-statfs-with-a-known-root-dentry 2006-05-12 03:55:53.000000000 -0700 +++ devel-akpm/fs/isofs/inode.c 2006-05-12 03:55:53.000000000 -0700 @@ -22,6 +22,7 @@ #include #include #include +#include #include "isofs.h" #include "zisofs.h" @@ -56,7 +57,7 @@ static void isofs_put_super(struct super } static void isofs_read_inode(struct inode *); -static int isofs_statfs (struct super_block *, struct kstatfs *); +static int isofs_statfs (struct vfsmount *, struct kstatfs *); static kmem_cache_t *isofs_inode_cachep; @@ -901,8 +902,10 @@ out_freesbi: return -EINVAL; } -static int isofs_statfs (struct super_block *sb, struct kstatfs *buf) +static int isofs_statfs (struct vfsmount *mnt, struct kstatfs *buf) { + struct super_block *sb = mnt->mnt_sb; + buf->f_type = ISOFS_SUPER_MAGIC; buf->f_bsize = sb->s_blocksize; buf->f_blocks = (ISOFS_SB(sb)->s_nzones diff -puN fs/jffs2/fs.c~nfs-permit-filesystem-to-perform-statfs-with-a-known-root-dentry fs/jffs2/fs.c --- devel/fs/jffs2/fs.c~nfs-permit-filesystem-to-perform-statfs-with-a-known-root-dentry 2006-05-12 03:55:53.000000000 -0700 +++ devel-akpm/fs/jffs2/fs.c 2006-05-12 03:55:53.000000000 -0700 @@ -22,6 +22,7 @@ #include #include #include +#include #include #include "nodelist.h" @@ -188,9 +189,9 @@ int jffs2_setattr(struct dentry *dentry, return jffs2_do_setattr(dentry->d_inode, iattr); } -int jffs2_statfs(struct super_block *sb, struct kstatfs *buf) +int jffs2_statfs(struct vfsmount *mnt, struct kstatfs *buf) { - struct jffs2_sb_info *c = JFFS2_SB_INFO(sb); + struct jffs2_sb_info *c = JFFS2_SB_INFO(mnt->mnt_sb); unsigned long avail; buf->f_type = JFFS2_SUPER_MAGIC; diff -puN fs/jffs2/os-linux.h~nfs-permit-filesystem-to-perform-statfs-with-a-known-root-dentry fs/jffs2/os-linux.h --- devel/fs/jffs2/os-linux.h~nfs-permit-filesystem-to-perform-statfs-with-a-known-root-dentry 2006-05-12 03:55:53.000000000 -0700 +++ devel-akpm/fs/jffs2/os-linux.h 2006-05-12 03:55:53.000000000 -0700 @@ -182,7 +182,7 @@ void jffs2_clear_inode (struct inode *); void jffs2_dirty_inode(struct inode *inode); struct inode *jffs2_new_inode (struct inode *dir_i, int mode, struct jffs2_raw_inode *ri); -int jffs2_statfs (struct super_block *, struct kstatfs *); +int jffs2_statfs (struct vfsmount *, struct kstatfs *); void jffs2_write_super (struct super_block *); int jffs2_remount_fs (struct super_block *, int *, char *); int jffs2_do_fill_super(struct super_block *sb, void *data, int silent); diff -puN fs/jffs/inode-v23.c~nfs-permit-filesystem-to-perform-statfs-with-a-known-root-dentry fs/jffs/inode-v23.c --- devel/fs/jffs/inode-v23.c~nfs-permit-filesystem-to-perform-statfs-with-a-known-root-dentry 2006-05-12 03:55:53.000000000 -0700 +++ devel-akpm/fs/jffs/inode-v23.c 2006-05-12 03:55:53.000000000 -0700 @@ -42,6 +42,7 @@ #include #include #include +#include #include #include #include @@ -377,9 +378,9 @@ jffs_new_inode(const struct inode * dir, /* Get statistics of the file system. */ static int -jffs_statfs(struct super_block *sb, struct kstatfs *buf) +jffs_statfs(struct vfsmount *mnt, struct kstatfs *buf) { - struct jffs_control *c = (struct jffs_control *) sb->s_fs_info; + struct jffs_control *c = (struct jffs_control *) mnt->mnt_sb->s_fs_info; struct jffs_fmcontrol *fmc; lock_kernel(); diff -puN fs/jfs/super.c~nfs-permit-filesystem-to-perform-statfs-with-a-known-root-dentry fs/jfs/super.c --- devel/fs/jfs/super.c~nfs-permit-filesystem-to-perform-statfs-with-a-known-root-dentry 2006-05-12 03:55:53.000000000 -0700 +++ devel-akpm/fs/jfs/super.c 2006-05-12 03:55:53.000000000 -0700 @@ -139,9 +139,9 @@ static void jfs_destroy_inode(struct ino kmem_cache_free(jfs_inode_cachep, ji); } -static int jfs_statfs(struct super_block *sb, struct kstatfs *buf) +static int jfs_statfs(struct vfsmount *mnt, struct kstatfs *buf) { - struct jfs_sb_info *sbi = JFS_SBI(sb); + struct jfs_sb_info *sbi = JFS_SBI(mnt->mnt_sb); s64 maxinodes; struct inomap *imap = JFS_IP(sbi->ipimap)->i_imap; diff -puN fs/libfs.c~nfs-permit-filesystem-to-perform-statfs-with-a-known-root-dentry fs/libfs.c --- devel/fs/libfs.c~nfs-permit-filesystem-to-perform-statfs-with-a-known-root-dentry 2006-05-12 03:55:53.000000000 -0700 +++ devel-akpm/fs/libfs.c 2006-05-12 03:55:53.000000000 -0700 @@ -20,9 +20,9 @@ int simple_getattr(struct vfsmount *mnt, return 0; } -int simple_statfs(struct super_block *sb, struct kstatfs *buf) +int simple_statfs(struct vfsmount *mnt, struct kstatfs *buf) { - buf->f_type = sb->s_magic; + buf->f_type = mnt->mnt_sb->s_magic; buf->f_bsize = PAGE_CACHE_SIZE; buf->f_namelen = NAME_MAX; return 0; diff -puN fs/minix/inode.c~nfs-permit-filesystem-to-perform-statfs-with-a-known-root-dentry fs/minix/inode.c --- devel/fs/minix/inode.c~nfs-permit-filesystem-to-perform-statfs-with-a-known-root-dentry 2006-05-12 03:55:53.000000000 -0700 +++ devel-akpm/fs/minix/inode.c 2006-05-12 03:55:53.000000000 -0700 @@ -16,10 +16,11 @@ #include #include #include +#include static void minix_read_inode(struct inode * inode); static int minix_write_inode(struct inode * inode, int wait); -static int minix_statfs(struct super_block *sb, struct kstatfs *buf); +static int minix_statfs(struct vfsmount *mnt, struct kstatfs *buf); static int minix_remount (struct super_block * sb, int * flags, char * data); static void minix_delete_inode(struct inode *inode) @@ -296,11 +297,11 @@ out_bad_sb: return -EINVAL; } -static int minix_statfs(struct super_block *sb, struct kstatfs *buf) +static int minix_statfs(struct vfsmount *mnt, struct kstatfs *buf) { - struct minix_sb_info *sbi = minix_sb(sb); - buf->f_type = sb->s_magic; - buf->f_bsize = sb->s_blocksize; + struct minix_sb_info *sbi = minix_sb(mnt->mnt_sb); + buf->f_type = mnt->mnt_sb->s_magic; + buf->f_bsize = mnt->mnt_sb->s_blocksize; buf->f_blocks = (sbi->s_nzones - sbi->s_firstdatazone) << sbi->s_log_zone_size; buf->f_bfree = minix_count_free_blocks(sbi); buf->f_bavail = buf->f_bfree; diff -puN fs/ncpfs/inode.c~nfs-permit-filesystem-to-perform-statfs-with-a-known-root-dentry fs/ncpfs/inode.c --- devel/fs/ncpfs/inode.c~nfs-permit-filesystem-to-perform-statfs-with-a-known-root-dentry 2006-05-12 03:55:53.000000000 -0700 +++ devel-akpm/fs/ncpfs/inode.c 2006-05-12 03:55:53.000000000 -0700 @@ -29,6 +29,7 @@ #include #include #include +#include #include @@ -39,7 +40,7 @@ static void ncp_delete_inode(struct inode *); static void ncp_put_super(struct super_block *); -static int ncp_statfs(struct super_block *, struct kstatfs *); +static int ncp_statfs(struct vfsmount *, struct kstatfs *); static kmem_cache_t * ncp_inode_cachep; @@ -724,13 +725,14 @@ static void ncp_put_super(struct super_b kfree(server); } -static int ncp_statfs(struct super_block *sb, struct kstatfs *buf) +static int ncp_statfs(struct vfsmount *mnt, struct kstatfs *buf) { struct dentry* d; struct inode* i; struct ncp_inode_info* ni; struct ncp_server* s; struct ncp_volume_info vi; + struct super_block *sb = mnt->mnt_sb; int err; __u8 dh; diff -puN fs/nfsd/nfs4xdr.c~nfs-permit-filesystem-to-perform-statfs-with-a-known-root-dentry fs/nfsd/nfs4xdr.c --- devel/fs/nfsd/nfs4xdr.c~nfs-permit-filesystem-to-perform-statfs-with-a-known-root-dentry 2006-05-12 03:55:53.000000000 -0700 +++ devel-akpm/fs/nfsd/nfs4xdr.c 2006-05-12 03:55:53.000000000 -0700 @@ -1310,7 +1310,7 @@ nfsd4_encode_fattr(struct svc_fh *fhp, s if ((bmval0 & (FATTR4_WORD0_FILES_FREE | FATTR4_WORD0_FILES_TOTAL)) || (bmval1 & (FATTR4_WORD1_SPACE_AVAIL | FATTR4_WORD1_SPACE_FREE | FATTR4_WORD1_SPACE_TOTAL))) { - status = vfs_statfs(dentry->d_inode->i_sb, &statfs); + status = vfs_statfs(exp->ex_mnt, &statfs); if (status) goto out_nfserr; } diff -puN fs/nfsd/vfs.c~nfs-permit-filesystem-to-perform-statfs-with-a-known-root-dentry fs/nfsd/vfs.c --- devel/fs/nfsd/vfs.c~nfs-permit-filesystem-to-perform-statfs-with-a-known-root-dentry 2006-05-12 03:55:53.000000000 -0700 +++ devel-akpm/fs/nfsd/vfs.c 2006-05-12 03:55:53.000000000 -0700 @@ -1736,9 +1736,19 @@ out: int nfsd_statfs(struct svc_rqst *rqstp, struct svc_fh *fhp, struct kstatfs *stat) { + struct vfsmount mnt; + int err = fh_verify(rqstp, fhp, 0, MAY_NOP); - if (!err && vfs_statfs(fhp->fh_dentry->d_inode->i_sb,stat)) - err = nfserr_io; + if (!err) { + memset(&mnt, 0, sizeof(mnt)); + + mnt.mnt_sb = fhp->fh_dentry->d_inode->i_sb; + mnt.mnt_root = mnt.mnt_sb->s_root; + mnt.mnt_mountpoint = mnt.mnt_root; + + if (vfs_statfs(&mnt, stat)) + err = nfserr_io; + } return err; } diff -puN fs/nfs/inode.c~nfs-permit-filesystem-to-perform-statfs-with-a-known-root-dentry fs/nfs/inode.c --- devel/fs/nfs/inode.c~nfs-permit-filesystem-to-perform-statfs-with-a-known-root-dentry 2006-05-12 03:55:53.000000000 -0700 +++ devel-akpm/fs/nfs/inode.c 2006-05-12 03:55:53.000000000 -0700 @@ -67,7 +67,7 @@ static int nfs_write_inode(struct inode static void nfs_delete_inode(struct inode *); static void nfs_clear_inode(struct inode *); static void nfs_umount_begin(struct vfsmount *, int); -static int nfs_statfs(struct super_block *, struct kstatfs *); +static int nfs_statfs(struct vfsmount *, struct kstatfs *); static int nfs_show_options(struct seq_file *, struct vfsmount *); static int nfs_show_stats(struct seq_file *, struct vfsmount *); static void nfs_zap_acl_cache(struct inode *); @@ -548,8 +548,9 @@ nfs_fill_super(struct super_block *sb, s } static int -nfs_statfs(struct super_block *sb, struct kstatfs *buf) +nfs_statfs(struct vfsmount *mnt, struct kstatfs *buf) { + struct super_block *sb = mnt->mnt_sb; struct nfs_server *server = NFS_SB(sb); unsigned char blockbits; unsigned long blockres; diff -puN fs/ntfs/super.c~nfs-permit-filesystem-to-perform-statfs-with-a-known-root-dentry fs/ntfs/super.c --- devel/fs/ntfs/super.c~nfs-permit-filesystem-to-perform-statfs-with-a-known-root-dentry 2006-05-12 03:55:53.000000000 -0700 +++ devel-akpm/fs/ntfs/super.c 2006-05-12 03:55:53.000000000 -0700 @@ -28,6 +28,7 @@ #include /* For bdev_hardsect_size(). */ #include #include +#include #include #include #include @@ -2601,10 +2602,10 @@ static unsigned long __get_nr_free_mft_r /** * ntfs_statfs - return information about mounted NTFS volume - * @sb: super block of mounted volume + * @mnt: mountpoint of mounted volume * @sfs: statfs structure in which to return the information * - * Return information about the mounted NTFS volume @sb in the statfs structure + * Return information about the mounted NTFS volume @mnt in the statfs structure * pointed to by @sfs (this is initialized with zeros before ntfs_statfs is * called). We interpret the values to be correct of the moment in time at * which we are called. Most values are variable otherwise and this isn't just @@ -2617,8 +2618,9 @@ static unsigned long __get_nr_free_mft_r * * Return 0 on success or -errno on error. */ -static int ntfs_statfs(struct super_block *sb, struct kstatfs *sfs) +static int ntfs_statfs(struct vfsmount *mnt, struct kstatfs *sfs) { + struct super_block *sb = mnt->mnt_sb; s64 size; ntfs_volume *vol = NTFS_SB(sb); ntfs_inode *mft_ni = NTFS_I(vol->mft_ino); diff -puN fs/ocfs2/super.c~nfs-permit-filesystem-to-perform-statfs-with-a-known-root-dentry fs/ocfs2/super.c --- devel/fs/ocfs2/super.c~nfs-permit-filesystem-to-perform-statfs-with-a-known-root-dentry 2006-05-12 03:55:53.000000000 -0700 +++ devel-akpm/fs/ocfs2/super.c 2006-05-12 03:55:53.000000000 -0700 @@ -39,6 +39,7 @@ #include #include #include +#include #include @@ -100,7 +101,7 @@ static int ocfs2_initialize_mem_caches(v static void ocfs2_free_mem_caches(void); static void ocfs2_delete_osb(struct ocfs2_super *osb); -static int ocfs2_statfs(struct super_block *sb, struct kstatfs *buf); +static int ocfs2_statfs(struct vfsmount *mnt, struct kstatfs *buf); static int ocfs2_sync_fs(struct super_block *sb, int wait); @@ -857,7 +858,7 @@ static void ocfs2_put_super(struct super mlog_exit_void(); } -static int ocfs2_statfs(struct super_block *sb, struct kstatfs *buf) +static int ocfs2_statfs(struct vfsmount *mnt, struct kstatfs *buf) { struct ocfs2_super *osb; u32 numbits, freebits; @@ -866,9 +867,9 @@ static int ocfs2_statfs(struct super_blo struct buffer_head *bh = NULL; struct inode *inode = NULL; - mlog_entry("(%p, %p)\n", sb, buf); + mlog_entry("(%p, %p)\n", mnt->mnt_sb, buf); - osb = OCFS2_SB(sb); + osb = OCFS2_SB(mnt->mnt_sb); inode = ocfs2_get_system_file_inode(osb, GLOBAL_BITMAP_SYSTEM_INODE, @@ -891,7 +892,7 @@ static int ocfs2_statfs(struct super_blo freebits = numbits - le32_to_cpu(bm_lock->id1.bitmap1.i_used); buf->f_type = OCFS2_SUPER_MAGIC; - buf->f_bsize = sb->s_blocksize; + buf->f_bsize = mnt->mnt_sb->s_blocksize; buf->f_namelen = OCFS2_MAX_FILENAME_LEN; buf->f_blocks = ((sector_t) numbits) * (osb->s_clustersize >> osb->sb->s_blocksize_bits); diff -puN fs/open.c~nfs-permit-filesystem-to-perform-statfs-with-a-known-root-dentry fs/open.c --- devel/fs/open.c~nfs-permit-filesystem-to-perform-statfs-with-a-known-root-dentry 2006-05-12 03:55:53.000000000 -0700 +++ devel-akpm/fs/open.c 2006-05-12 03:55:53.000000000 -0700 @@ -31,18 +31,18 @@ #include -int vfs_statfs(struct super_block *sb, struct kstatfs *buf) +int vfs_statfs(struct vfsmount *mnt, struct kstatfs *buf) { int retval = -ENODEV; - if (sb) { + if (mnt) { retval = -ENOSYS; - if (sb->s_op->statfs) { + if (mnt->mnt_sb->s_op->statfs) { memset(buf, 0, sizeof(*buf)); - retval = security_sb_statfs(sb); + retval = security_sb_statfs(mnt); if (retval) return retval; - retval = sb->s_op->statfs(sb, buf); + retval = mnt->mnt_sb->s_op->statfs(mnt, buf); if (retval == 0 && buf->f_frsize == 0) buf->f_frsize = buf->f_bsize; } @@ -52,12 +52,12 @@ int vfs_statfs(struct super_block *sb, s EXPORT_SYMBOL(vfs_statfs); -static int vfs_statfs_native(struct super_block *sb, struct statfs *buf) +static int vfs_statfs_native(struct vfsmount *mnt, struct statfs *buf) { struct kstatfs st; int retval; - retval = vfs_statfs(sb, &st); + retval = vfs_statfs(mnt, &st); if (retval) return retval; @@ -95,12 +95,12 @@ static int vfs_statfs_native(struct supe return 0; } -static int vfs_statfs64(struct super_block *sb, struct statfs64 *buf) +static int vfs_statfs64(struct vfsmount *mnt, struct statfs64 *buf) { struct kstatfs st; int retval; - retval = vfs_statfs(sb, &st); + retval = vfs_statfs(mnt, &st); if (retval) return retval; @@ -130,7 +130,7 @@ asmlinkage long sys_statfs(const char __ error = user_path_walk(path, &nd); if (!error) { struct statfs tmp; - error = vfs_statfs_native(nd.dentry->d_inode->i_sb, &tmp); + error = vfs_statfs_native(nd.mnt, &tmp); if (!error && copy_to_user(buf, &tmp, sizeof(tmp))) error = -EFAULT; path_release(&nd); @@ -149,7 +149,7 @@ asmlinkage long sys_statfs64(const char error = user_path_walk(path, &nd); if (!error) { struct statfs64 tmp; - error = vfs_statfs64(nd.dentry->d_inode->i_sb, &tmp); + error = vfs_statfs64(nd.mnt, &tmp); if (!error && copy_to_user(buf, &tmp, sizeof(tmp))) error = -EFAULT; path_release(&nd); @@ -168,7 +168,7 @@ asmlinkage long sys_fstatfs(unsigned int file = fget(fd); if (!file) goto out; - error = vfs_statfs_native(file->f_dentry->d_inode->i_sb, &tmp); + error = vfs_statfs_native(file->f_vfsmnt, &tmp); if (!error && copy_to_user(buf, &tmp, sizeof(tmp))) error = -EFAULT; fput(file); @@ -189,7 +189,7 @@ asmlinkage long sys_fstatfs64(unsigned i file = fget(fd); if (!file) goto out; - error = vfs_statfs64(file->f_dentry->d_inode->i_sb, &tmp); + error = vfs_statfs64(file->f_vfsmnt, &tmp); if (!error && copy_to_user(buf, &tmp, sizeof(tmp))) error = -EFAULT; fput(file); diff -puN fs/qnx4/inode.c~nfs-permit-filesystem-to-perform-statfs-with-a-known-root-dentry fs/qnx4/inode.c --- devel/fs/qnx4/inode.c~nfs-permit-filesystem-to-perform-statfs-with-a-known-root-dentry 2006-05-12 03:55:53.000000000 -0700 +++ devel-akpm/fs/qnx4/inode.c 2006-05-12 03:55:53.000000000 -0700 @@ -26,6 +26,7 @@ #include #include #include +#include #include #define QNX4_VERSION 4 @@ -128,7 +129,7 @@ static struct inode *qnx4_alloc_inode(st static void qnx4_destroy_inode(struct inode *inode); static void qnx4_read_inode(struct inode *); static int qnx4_remount(struct super_block *sb, int *flags, char *data); -static int qnx4_statfs(struct super_block *, struct kstatfs *); +static int qnx4_statfs(struct vfsmount *, struct kstatfs *); static struct super_operations qnx4_sops = { @@ -282,8 +283,10 @@ unsigned long qnx4_block_map( struct ino return block; } -static int qnx4_statfs(struct super_block *sb, struct kstatfs *buf) +static int qnx4_statfs(struct vfsmount *mnt, struct kstatfs *buf) { + struct super_block *sb = mnt->mnt_sb; + lock_kernel(); buf->f_type = sb->s_magic; diff -puN fs/reiserfs/super.c~nfs-permit-filesystem-to-perform-statfs-with-a-known-root-dentry fs/reiserfs/super.c --- devel/fs/reiserfs/super.c~nfs-permit-filesystem-to-perform-statfs-with-a-known-root-dentry 2006-05-12 03:55:53.000000000 -0700 +++ devel-akpm/fs/reiserfs/super.c 2006-05-12 03:55:53.000000000 -0700 @@ -60,7 +60,7 @@ static int is_any_reiserfs_magic_string( } static int reiserfs_remount(struct super_block *s, int *flags, char *data); -static int reiserfs_statfs(struct super_block *s, struct kstatfs *buf); +static int reiserfs_statfs(struct vfsmount *mnt, struct kstatfs *buf); static int reiserfs_sync_fs(struct super_block *s, int wait) { @@ -1938,15 +1938,15 @@ static int reiserfs_fill_super(struct su return errval; } -static int reiserfs_statfs(struct super_block *s, struct kstatfs *buf) +static int reiserfs_statfs(struct vfsmount *mnt, struct kstatfs *buf) { - struct reiserfs_super_block *rs = SB_DISK_SUPER_BLOCK(s); + struct reiserfs_super_block *rs = SB_DISK_SUPER_BLOCK(mnt->mnt_sb); buf->f_namelen = (REISERFS_MAX_NAME(s->s_blocksize)); buf->f_bfree = sb_free_blocks(rs); buf->f_bavail = buf->f_bfree; buf->f_blocks = sb_block_count(rs) - sb_bmap_nr(rs) - 1; - buf->f_bsize = s->s_blocksize; + buf->f_bsize = mnt->mnt_sb->s_blocksize; /* changed to accommodate gcc folks. */ buf->f_type = REISERFS_SUPER_MAGIC; return 0; diff -puN fs/romfs/inode.c~nfs-permit-filesystem-to-perform-statfs-with-a-known-root-dentry fs/romfs/inode.c --- devel/fs/romfs/inode.c~nfs-permit-filesystem-to-perform-statfs-with-a-known-root-dentry 2006-05-12 03:55:53.000000000 -0700 +++ devel-akpm/fs/romfs/inode.c 2006-05-12 03:55:53.000000000 -0700 @@ -75,6 +75,7 @@ #include #include #include +#include #include @@ -179,12 +180,12 @@ outnobh: /* That's simple too. */ static int -romfs_statfs(struct super_block *sb, struct kstatfs *buf) +romfs_statfs(struct vfsmount *mnt, struct kstatfs *buf) { buf->f_type = ROMFS_MAGIC; buf->f_bsize = ROMBSIZE; buf->f_bfree = buf->f_bavail = buf->f_ffree; - buf->f_blocks = (romfs_maxsize(sb)+ROMBSIZE-1)>>ROMBSBITS; + buf->f_blocks = (romfs_maxsize(mnt->mnt_sb)+ROMBSIZE-1)>>ROMBSBITS; buf->f_namelen = ROMFS_MAXFN; return 0; } diff -puN fs/smbfs/inode.c~nfs-permit-filesystem-to-perform-statfs-with-a-known-root-dentry fs/smbfs/inode.c --- devel/fs/smbfs/inode.c~nfs-permit-filesystem-to-perform-statfs-with-a-known-root-dentry 2006-05-12 03:55:53.000000000 -0700 +++ devel-akpm/fs/smbfs/inode.c 2006-05-12 03:55:53.000000000 -0700 @@ -48,7 +48,7 @@ static void smb_delete_inode(struct inode *); static void smb_put_super(struct super_block *); -static int smb_statfs(struct super_block *, struct kstatfs *); +static int smb_statfs(struct vfsmount *, struct kstatfs *); static int smb_show_options(struct seq_file *, struct vfsmount *); static kmem_cache_t *smb_inode_cachep; @@ -641,13 +641,13 @@ out_no_server: } static int -smb_statfs(struct super_block *sb, struct kstatfs *buf) +smb_statfs(struct vfsmount *mnt, struct kstatfs *buf) { int result; lock_kernel(); - result = smb_proc_dskattr(sb, buf); + result = smb_proc_dskattr(mnt, buf); unlock_kernel(); diff -puN fs/smbfs/proc.c~nfs-permit-filesystem-to-perform-statfs-with-a-known-root-dentry fs/smbfs/proc.c --- devel/fs/smbfs/proc.c~nfs-permit-filesystem-to-perform-statfs-with-a-known-root-dentry 2006-05-12 03:55:53.000000000 -0700 +++ devel-akpm/fs/smbfs/proc.c 2006-05-12 03:55:53.000000000 -0700 @@ -21,6 +21,7 @@ #include #include #include +#include #include #include #include @@ -3226,9 +3227,9 @@ smb_proc_settime(struct dentry *dentry, } int -smb_proc_dskattr(struct super_block *sb, struct kstatfs *attr) +smb_proc_dskattr(struct vfsmount *mnt, struct kstatfs *attr) { - struct smb_sb_info *server = SMB_SB(sb); + struct smb_sb_info *server = SMB_SB(mnt->mnt_sb); int result; char *p; long unit; diff -puN fs/smbfs/proto.h~nfs-permit-filesystem-to-perform-statfs-with-a-known-root-dentry fs/smbfs/proto.h --- devel/fs/smbfs/proto.h~nfs-permit-filesystem-to-perform-statfs-with-a-known-root-dentry 2006-05-12 03:55:53.000000000 -0700 +++ devel-akpm/fs/smbfs/proto.h 2006-05-12 03:55:53.000000000 -0700 @@ -29,7 +29,7 @@ extern int smb_proc_getattr(struct dentr extern int smb_proc_setattr(struct dentry *dir, struct smb_fattr *fattr); extern int smb_proc_setattr_unix(struct dentry *d, struct iattr *attr, unsigned int major, unsigned int minor); extern int smb_proc_settime(struct dentry *dentry, struct smb_fattr *fattr); -extern int smb_proc_dskattr(struct super_block *sb, struct kstatfs *attr); +extern int smb_proc_dskattr(struct vfsmount *mnt, struct kstatfs *attr); extern int smb_proc_read_link(struct smb_sb_info *server, struct dentry *d, char *buffer, int len); extern int smb_proc_symlink(struct smb_sb_info *server, struct dentry *d, const char *oldpath); extern int smb_proc_link(struct smb_sb_info *server, struct dentry *dentry, struct dentry *new_dentry); diff -puN fs/super.c~nfs-permit-filesystem-to-perform-statfs-with-a-known-root-dentry fs/super.c --- devel/fs/super.c~nfs-permit-filesystem-to-perform-statfs-with-a-known-root-dentry 2006-05-12 03:55:53.000000000 -0700 +++ devel-akpm/fs/super.c 2006-05-12 03:55:53.000000000 -0700 @@ -481,12 +481,17 @@ asmlinkage long sys_ustat(unsigned dev, struct super_block *s; struct ustat tmp; struct kstatfs sbuf; + struct vfsmount mnt; int err = -EINVAL; s = user_get_super(new_decode_dev(dev)); if (s == NULL) goto out; - err = vfs_statfs(s, &sbuf); + memset(&mnt, 0, sizeof(mnt)); + mnt.mnt_sb = s; + mnt.mnt_root = s->s_root; + mnt.mnt_mountpoint = mnt.mnt_root; + err = vfs_statfs(&mnt, &sbuf); drop_super(s); if (err) goto out; diff -puN fs/sysv/inode.c~nfs-permit-filesystem-to-perform-statfs-with-a-known-root-dentry fs/sysv/inode.c --- devel/fs/sysv/inode.c~nfs-permit-filesystem-to-perform-statfs-with-a-known-root-dentry 2006-05-12 03:55:53.000000000 -0700 +++ devel-akpm/fs/sysv/inode.c 2006-05-12 03:55:53.000000000 -0700 @@ -27,6 +27,7 @@ #include #include #include +#include #include #include "sysv.h" @@ -85,8 +86,9 @@ static void sysv_put_super(struct super_ kfree(sbi); } -static int sysv_statfs(struct super_block *sb, struct kstatfs *buf) +static int sysv_statfs(struct vfsmount *mnt, struct kstatfs *buf) { + struct super_block *sb = mnt->mnt_sb; struct sysv_sb_info *sbi = SYSV_SB(sb); buf->f_type = sb->s_magic; diff -puN fs/udf/super.c~nfs-permit-filesystem-to-perform-statfs-with-a-known-root-dentry fs/udf/super.c --- devel/fs/udf/super.c~nfs-permit-filesystem-to-perform-statfs-with-a-known-root-dentry 2006-05-12 03:55:53.000000000 -0700 +++ devel-akpm/fs/udf/super.c 2006-05-12 03:55:53.000000000 -0700 @@ -53,6 +53,7 @@ #include #include #include +#include #include #include @@ -91,7 +92,7 @@ static void udf_load_partdesc(struct sup static void udf_open_lvid(struct super_block *); static void udf_close_lvid(struct super_block *); static unsigned int udf_count_free(struct super_block *); -static int udf_statfs(struct super_block *, struct kstatfs *); +static int udf_statfs(struct vfsmount *, struct kstatfs *); /* UDF filesystem type */ static int udf_get_sb(struct file_system_type *fs_type, @@ -1779,8 +1780,10 @@ udf_put_super(struct super_block *sb) * Written, tested, and released. */ static int -udf_statfs(struct super_block *sb, struct kstatfs *buf) +udf_statfs(struct vfsmount *mnt, struct kstatfs *buf) { + struct super_block *sb = mnt->mnt_sb; + buf->f_type = UDF_SUPER_MAGIC; buf->f_bsize = sb->s_blocksize; buf->f_blocks = UDF_SB_PARTLEN(sb, UDF_SB_PARTITION(sb)); diff -puN fs/ufs/super.c~nfs-permit-filesystem-to-perform-statfs-with-a-known-root-dentry fs/ufs/super.c --- devel/fs/ufs/super.c~nfs-permit-filesystem-to-perform-statfs-with-a-known-root-dentry 2006-05-12 03:55:53.000000000 -0700 +++ devel-akpm/fs/ufs/super.c 2006-05-12 03:55:53.000000000 -0700 @@ -86,6 +86,7 @@ #include #include #include +#include #include "swab.h" #include "util.h" @@ -1113,8 +1114,9 @@ static int ufs_remount (struct super_blo return 0; } -static int ufs_statfs (struct super_block *sb, struct kstatfs *buf) +static int ufs_statfs (struct vfsmount *mnt, struct kstatfs *buf) { + struct super_block *sb = mnt->mnt_sb; struct ufs_sb_private_info * uspi; struct ufs_super_block_first * usb1; struct ufs_super_block * usb; diff -puN fs/xfs/linux-2.6/xfs_super.c~nfs-permit-filesystem-to-perform-statfs-with-a-known-root-dentry fs/xfs/linux-2.6/xfs_super.c --- devel/fs/xfs/linux-2.6/xfs_super.c~nfs-permit-filesystem-to-perform-statfs-with-a-known-root-dentry 2006-05-12 03:55:53.000000000 -0700 +++ devel-akpm/fs/xfs/linux-2.6/xfs_super.c 2006-05-12 03:55:53.000000000 -0700 @@ -703,10 +703,10 @@ xfs_fs_sync_super( STATIC int xfs_fs_statfs( - struct super_block *sb, + struct vfsmount *mnt, struct kstatfs *statp) { - vfs_t *vfsp = vfs_from_sb(sb); + vfs_t *vfsp = vfs_from_sb(mnt->mnt_sb); int error; VFS_STATVFS(vfsp, statp, NULL, error); diff -puN include/linux/coda_psdev.h~nfs-permit-filesystem-to-perform-statfs-with-a-known-root-dentry include/linux/coda_psdev.h --- devel/include/linux/coda_psdev.h~nfs-permit-filesystem-to-perform-statfs-with-a-known-root-dentry 2006-05-12 03:55:53.000000000 -0700 +++ devel-akpm/include/linux/coda_psdev.h 2006-05-12 03:55:53.000000000 -0700 @@ -70,7 +70,7 @@ int venus_pioctl(struct super_block *sb, unsigned int cmd, struct PioctlData *data); int coda_downcall(int opcode, union outputArgs *out, struct super_block *sb); int venus_fsync(struct super_block *sb, struct CodaFid *fid); -int venus_statfs(struct super_block *sb, struct kstatfs *sfs); +int venus_statfs(struct vfsmount *mnt, struct kstatfs *sfs); /* messages between coda filesystem in kernel and Venus */ diff -puN include/linux/fs.h~nfs-permit-filesystem-to-perform-statfs-with-a-known-root-dentry include/linux/fs.h --- devel/include/linux/fs.h~nfs-permit-filesystem-to-perform-statfs-with-a-known-root-dentry 2006-05-12 03:55:53.000000000 -0700 +++ devel-akpm/include/linux/fs.h 2006-05-12 03:55:53.000000000 -0700 @@ -1096,7 +1096,7 @@ struct super_operations { int (*sync_fs)(struct super_block *sb, int wait); void (*write_super_lockfs) (struct super_block *); void (*unlockfs) (struct super_block *); - int (*statfs) (struct super_block *, struct kstatfs *); + int (*statfs) (struct vfsmount *, struct kstatfs *); int (*remount_fs) (struct super_block *, int *, char *); void (*clear_inode) (struct inode *); void (*umount_begin) (struct vfsmount *, int); @@ -1325,7 +1325,7 @@ extern struct vfsmount *copy_tree(struct extern void mnt_set_mountpoint(struct vfsmount *, struct dentry *, struct vfsmount *); -extern int vfs_statfs(struct super_block *, struct kstatfs *); +extern int vfs_statfs(struct vfsmount *, struct kstatfs *); /* /sys/fs */ extern struct subsystem fs_subsys; @@ -1749,7 +1749,7 @@ extern int dcache_dir_close(struct inode 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_statfs(struct super_block *, struct kstatfs *); +extern int simple_statfs(struct vfsmount *, struct kstatfs *); extern int simple_link(struct dentry *, struct inode *, struct dentry *); extern int simple_unlink(struct inode *, struct dentry *); extern int simple_rmdir(struct inode *, struct dentry *); diff -puN include/linux/mount.h~nfs-permit-filesystem-to-perform-statfs-with-a-known-root-dentry include/linux/mount.h --- devel/include/linux/mount.h~nfs-permit-filesystem-to-perform-statfs-with-a-known-root-dentry 2006-05-12 03:55:53.000000000 -0700 +++ devel-akpm/include/linux/mount.h 2006-05-12 03:55:53.000000000 -0700 @@ -17,6 +17,11 @@ #include #include +struct super_block; +struct vfsmount; +struct dentry; +struct namespace; + #define MNT_NOSUID 0x01 #define MNT_NODEV 0x02 #define MNT_NOEXEC 0x04 diff -puN include/linux/security.h~nfs-permit-filesystem-to-perform-statfs-with-a-known-root-dentry include/linux/security.h --- devel/include/linux/security.h~nfs-permit-filesystem-to-perform-statfs-with-a-known-root-dentry 2006-05-12 03:55:53.000000000 -0700 +++ devel-akpm/include/linux/security.h 2006-05-12 03:55:53.000000000 -0700 @@ -171,9 +171,9 @@ struct swap_info_struct; * Deallocate and clear the sb->s_security field. * @sb contains the super_block structure to be modified. * @sb_statfs: - * Check permission before obtaining filesystem statistics for the @sb - * filesystem. - * @sb contains the super_block structure for the filesystem. + * Check permission before obtaining filesystem statistics for the @mnt + * mountpoint. + * @mnt contains the mountpoint structure for the filesystem. * Return 0 if permission is granted. * @sb_mount: * Check permission before an object specified by @dev_name is mounted on @@ -1121,7 +1121,7 @@ struct security_operations { int (*sb_copy_data)(struct file_system_type *type, void *orig, void *copy); int (*sb_kern_mount) (struct super_block *sb, void *data); - int (*sb_statfs) (struct super_block * sb); + int (*sb_statfs) (struct vfsmount *mnt); int (*sb_mount) (char *dev_name, struct nameidata * nd, char *type, unsigned long flags, void *data); int (*sb_check_sb) (struct vfsmount * mnt, struct nameidata * nd); @@ -1442,9 +1442,9 @@ static inline int security_sb_kern_mount return security_ops->sb_kern_mount (sb, data); } -static inline int security_sb_statfs (struct super_block *sb) +static inline int security_sb_statfs (struct vfsmount *mnt) { - return security_ops->sb_statfs (sb); + return security_ops->sb_statfs (mnt); } static inline int security_sb_mount (char *dev_name, struct nameidata *nd, @@ -2154,7 +2154,7 @@ static inline int security_sb_kern_mount return 0; } -static inline int security_sb_statfs (struct super_block *sb) +static inline int security_sb_statfs (struct vfsmount *mnt) { return 0; } diff -puN kernel/acct.c~nfs-permit-filesystem-to-perform-statfs-with-a-known-root-dentry kernel/acct.c --- devel/kernel/acct.c~nfs-permit-filesystem-to-perform-statfs-with-a-known-root-dentry 2006-05-12 03:55:53.000000000 -0700 +++ devel-akpm/kernel/acct.c 2006-05-12 03:55:53.000000000 -0700 @@ -118,7 +118,7 @@ static int check_free_space(struct file spin_unlock(&acct_globals.lock); /* May block */ - if (vfs_statfs(file->f_dentry->d_inode->i_sb, &sbuf)) + if (vfs_statfs(file->f_vfsmnt, &sbuf)) return res; suspend = sbuf.f_blocks * SUSPEND; resume = sbuf.f_blocks * RESUME; diff -puN mm/shmem.c~nfs-permit-filesystem-to-perform-statfs-with-a-known-root-dentry mm/shmem.c --- devel/mm/shmem.c~nfs-permit-filesystem-to-perform-statfs-with-a-known-root-dentry 2006-05-12 03:55:53.000000000 -0700 +++ devel-akpm/mm/shmem.c 2006-05-12 03:55:53.000000000 -0700 @@ -1654,9 +1654,9 @@ static ssize_t shmem_file_sendfile(struc return desc.error; } -static int shmem_statfs(struct super_block *sb, struct kstatfs *buf) +static int shmem_statfs(struct vfsmount *mnt, struct kstatfs *buf) { - struct shmem_sb_info *sbinfo = SHMEM_SB(sb); + struct shmem_sb_info *sbinfo = SHMEM_SB(mnt->mnt_sb); buf->f_type = TMPFS_MAGIC; buf->f_bsize = PAGE_CACHE_SIZE; diff -puN security/dummy.c~nfs-permit-filesystem-to-perform-statfs-with-a-known-root-dentry security/dummy.c --- devel/security/dummy.c~nfs-permit-filesystem-to-perform-statfs-with-a-known-root-dentry 2006-05-12 03:55:53.000000000 -0700 +++ devel-akpm/security/dummy.c 2006-05-12 03:55:53.000000000 -0700 @@ -191,7 +191,7 @@ static int dummy_sb_kern_mount (struct s return 0; } -static int dummy_sb_statfs (struct super_block *sb) +static int dummy_sb_statfs (struct vfsmount *mnt) { return 0; } diff -puN security/selinux/hooks.c~nfs-permit-filesystem-to-perform-statfs-with-a-known-root-dentry security/selinux/hooks.c --- devel/security/selinux/hooks.c~nfs-permit-filesystem-to-perform-statfs-with-a-known-root-dentry 2006-05-12 03:55:53.000000000 -0700 +++ devel-akpm/security/selinux/hooks.c 2006-05-12 03:55:53.000000000 -0700 @@ -1902,13 +1902,13 @@ static int selinux_sb_kern_mount(struct return superblock_has_perm(current, sb, FILESYSTEM__MOUNT, &ad); } -static int selinux_sb_statfs(struct super_block *sb) +static int selinux_sb_statfs(struct vfsmount *mnt) { struct avc_audit_data ad; AVC_AUDIT_DATA_INIT(&ad,FS); - ad.u.fs.dentry = sb->s_root; - return superblock_has_perm(current, sb, FILESYSTEM__GETATTR, &ad); + ad.u.fs.dentry = mnt->mnt_root; + return superblock_has_perm(current, mnt->mnt_sb, FILESYSTEM__GETATTR, &ad); } static int selinux_mount(char * dev_name, _