Commit 726c3342 authored by David Howells's avatar David Howells Committed by Linus Torvalds
Browse files

[PATCH] VFS: Permit filesystem to perform statfs with a known root dentry



Give the statfs superblock operation a dentry 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.

linux/mount.h has been added where necessary to make allyesconfig build
successfully.

Interest has also been expressed for use with the FUSE and XFS filesystems.

Signed-off-by: default avatarDavid Howells <dhowells@redhat.com>
Acked-by: default avatarAl Viro <viro@zeniv.linux.org.uk>
Cc: Nathan Scott <nathans@sgi.com>
Signed-off-by: default avatarAndrew Morton <akpm@osdl.org>
Signed-off-by: default avatarLinus Torvalds <torvalds@osdl.org>
parent 454e2398
Loading
Loading
Loading
Loading
+1 −1
Original line number Diff line number Diff line
@@ -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 dentry *, struct kstatfs *);
	int (*remount_fs) (struct super_block *, int *, char *);
	void (*clear_inode) (struct inode *);
	void (*umount_begin) (struct super_block *);
+1 −1
Original line number Diff line number Diff line
@@ -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 dentry *, struct kstatfs *);
        int (*remount_fs) (struct super_block *, int *, char *);
        void (*clear_inode) (struct inode *);
        void (*umount_begin) (struct super_block *);
+1 −1
Original line number Diff line number Diff line
@@ -244,7 +244,7 @@ do_osf_statfs(struct dentry * dentry, 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(dentry, &linux_stat);
	if (!error)
		error = linux_to_osf_statfs(&linux_stat, buffer, bufsiz);
	return error;	
+6 −6
Original line number Diff line number Diff line
@@ -694,7 +694,7 @@ asmlinkage int irix_statfs(const char __user *path,
	if (error)
		goto out;

	error = vfs_statfs(nd.dentry->d_inode->i_sb, &kbuf);
	error = vfs_statfs(nd.dentry, &kbuf);
	if (error)
		goto dput_and_out;

@@ -732,7 +732,7 @@ asmlinkage int irix_fstatfs(unsigned int fd, struct irix_statfs __user *buf)
		goto out;
	}

	error = vfs_statfs(file->f_dentry->d_inode->i_sb, &kbuf);
	error = vfs_statfs(file->f_dentry, &kbuf);
	if (error)
		goto out_f;

@@ -1360,7 +1360,7 @@ asmlinkage int irix_statvfs(char __user *fname, struct irix_statvfs __user *buf)
	error = user_path_walk(fname, &nd);
	if (error)
		goto out;
	error = vfs_statfs(nd.dentry->d_inode->i_sb, &kbuf);
	error = vfs_statfs(nd.dentry, &kbuf);
	if (error)
		goto dput_and_out;

@@ -1406,7 +1406,7 @@ asmlinkage int irix_fstatvfs(int fd, struct irix_statvfs __user *buf)
		error = -EBADF;
		goto out;
	}
	error = vfs_statfs(file->f_dentry->d_inode->i_sb, &kbuf);
	error = vfs_statfs(file->f_dentry, &kbuf);
	if (error)
		goto out_f;

@@ -1611,7 +1611,7 @@ asmlinkage int irix_statvfs64(char __user *fname, struct irix_statvfs64 __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.dentry, &kbuf);
	if (error)
		goto dput_and_out;

@@ -1658,7 +1658,7 @@ asmlinkage int irix_fstatvfs64(int fd, struct irix_statvfs __user *buf)
		error = -EBADF;
		goto out;
	}
	error = vfs_statfs(file->f_dentry->d_inode->i_sb, &kbuf);
	error = vfs_statfs(file->f_dentry, &kbuf);
	if (error)
		goto out_f;

+5 −5
Original line number Diff line number Diff line
@@ -145,7 +145,7 @@ static int hpux_ustat(dev_t dev, struct hpux_ustat __user *ubuf)
	s = user_get_super(dev);
	if (s == NULL)
		goto out;
	err = vfs_statfs(s, &sbuf);
	err = vfs_statfs(s->s_root, &sbuf);
	drop_super(s);
	if (err)
		goto out;
@@ -186,12 +186,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 dentry *dentry, struct hpux_statfs *buf)
{
	struct kstatfs st;
	int retval;
	
	retval = vfs_statfs(sb, &st);
	retval = vfs_statfs(dentry, &st);
	if (retval)
		return retval;

@@ -219,7 +219,7 @@ asmlinkage long hpux_statfs(const char __user *path,
	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.dentry, &tmp);
		if (!error && copy_to_user(buf, &tmp, sizeof(tmp)))
			error = -EFAULT;
		path_release(&nd);
@@ -237,7 +237,7 @@ asmlinkage long hpux_fstatfs(unsigned int fd, struct hpux_statfs __user * buf)
	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_dentry, &tmp);
	if (!error && copy_to_user(buf, &tmp, sizeof(tmp)))
		error = -EFAULT;
	fput(file);
Loading