diff options
Diffstat (limited to 'fs')
-rw-r--r-- | fs/cachefiles/bind.c | 2 | ||||
-rw-r--r-- | fs/cachefiles/daemon.c | 6 | ||||
-rw-r--r-- | fs/compat.c | 10 | ||||
-rw-r--r-- | fs/ecryptfs/super.c | 6 | ||||
-rw-r--r-- | fs/nfsd/nfs4xdr.c | 6 | ||||
-rw-r--r-- | fs/nfsd/vfs.c | 10 | ||||
-rw-r--r-- | fs/statfs.c | 50 |
7 files changed, 55 insertions, 35 deletions
diff --git a/fs/cachefiles/bind.c b/fs/cachefiles/bind.c index 2906077ac798..a2603e7c0bb5 100644 --- a/fs/cachefiles/bind.c +++ b/fs/cachefiles/bind.c @@ -146,7 +146,7 @@ static int cachefiles_daemon_add_cache(struct cachefiles_cache *cache) goto error_unsupported; /* get the cache size and blocksize */ - ret = vfs_statfs(root, &stats); + ret = vfs_statfs(&path, &stats); if (ret < 0) goto error_unsupported; diff --git a/fs/cachefiles/daemon.c b/fs/cachefiles/daemon.c index c2413561ea75..24eb0d37241a 100644 --- a/fs/cachefiles/daemon.c +++ b/fs/cachefiles/daemon.c @@ -683,6 +683,10 @@ int cachefiles_has_space(struct cachefiles_cache *cache, unsigned fnr, unsigned bnr) { struct kstatfs stats; + struct path path = { + .mnt = cache->mnt, + .dentry = cache->mnt->mnt_root, + }; int ret; //_enter("{%llu,%llu,%llu,%llu,%llu,%llu},%u,%u", @@ -697,7 +701,7 @@ int cachefiles_has_space(struct cachefiles_cache *cache, /* find out how many pages of blockdev are available */ memset(&stats, 0, sizeof(stats)); - ret = vfs_statfs(cache->mnt->mnt_root, &stats); + ret = vfs_statfs(&path, &stats); if (ret < 0) { if (ret == -EIO) cachefiles_io_error(cache, "statfs failed"); diff --git a/fs/compat.c b/fs/compat.c index 6490d2134ff3..fc6c2adf2f6b 100644 --- a/fs/compat.c +++ b/fs/compat.c @@ -266,7 +266,7 @@ asmlinkage long compat_sys_statfs(const char __user *pathname, struct compat_sta error = user_path(pathname, &path); if (!error) { struct kstatfs tmp; - error = vfs_statfs(path.dentry, &tmp); + error = vfs_statfs(&path, &tmp); if (!error) error = put_compat_statfs(buf, &tmp); path_put(&path); @@ -284,7 +284,7 @@ asmlinkage long compat_sys_fstatfs(unsigned int fd, struct compat_statfs __user file = fget(fd); if (!file) goto out; - error = vfs_statfs(file->f_path.dentry, &tmp); + error = vfs_statfs(&file->f_path, &tmp); if (!error) error = put_compat_statfs(buf, &tmp); fput(file); @@ -334,7 +334,7 @@ asmlinkage long compat_sys_statfs64(const char __user *pathname, compat_size_t s error = user_path(pathname, &path); if (!error) { struct kstatfs tmp; - error = vfs_statfs(path.dentry, &tmp); + error = vfs_statfs(&path, &tmp); if (!error) error = put_compat_statfs64(buf, &tmp); path_put(&path); @@ -355,7 +355,7 @@ asmlinkage long compat_sys_fstatfs64(unsigned int fd, compat_size_t sz, struct c file = fget(fd); if (!file) goto out; - error = vfs_statfs(file->f_path.dentry, &tmp); + error = vfs_statfs(&file->f_path, &tmp); if (!error) error = put_compat_statfs64(buf, &tmp); fput(file); @@ -378,7 +378,7 @@ asmlinkage long compat_sys_ustat(unsigned dev, struct compat_ustat __user *u) sb = user_get_super(new_decode_dev(dev)); if (!sb) return -EINVAL; - err = vfs_statfs(sb->s_root, &sbuf); + err = statfs_by_dentry(sb->s_root, &sbuf); drop_super(sb); if (err) return err; diff --git a/fs/ecryptfs/super.c b/fs/ecryptfs/super.c index 4b5de6c6e0fa..f7fc286a3aa9 100644 --- a/fs/ecryptfs/super.c +++ b/fs/ecryptfs/super.c @@ -118,7 +118,11 @@ void ecryptfs_init_inode(struct inode *inode, struct inode *lower_inode) */ static int ecryptfs_statfs(struct dentry *dentry, struct kstatfs *buf) { - return vfs_statfs(ecryptfs_dentry_to_lower(dentry), buf); + struct dentry *lower_dentry = ecryptfs_dentry_to_lower(dentry); + + if (!lower_dentry->d_sb->s_op->statfs) + return -ENOSYS; + return lower_dentry->d_sb->s_op->statfs(lower_dentry, buf); } /** diff --git a/fs/nfsd/nfs4xdr.c b/fs/nfsd/nfs4xdr.c index ac17a7080239..4d6154f66e04 100644 --- a/fs/nfsd/nfs4xdr.c +++ b/fs/nfsd/nfs4xdr.c @@ -1756,6 +1756,10 @@ nfsd4_encode_fattr(struct svc_fh *fhp, struct svc_export *exp, struct nfs4_acl *acl = NULL; struct nfsd4_compoundres *resp = rqstp->rq_resp; u32 minorversion = resp->cstate.minorversion; + struct path path = { + .mnt = exp->ex_path.mnt, + .dentry = dentry, + }; BUG_ON(bmval1 & NFSD_WRITEONLY_ATTRS_WORD1); BUG_ON(bmval0 & ~nfsd_suppattrs0(minorversion)); @@ -1776,7 +1780,7 @@ nfsd4_encode_fattr(struct svc_fh *fhp, struct svc_export *exp, FATTR4_WORD0_MAXNAME)) || (bmval1 & (FATTR4_WORD1_SPACE_AVAIL | FATTR4_WORD1_SPACE_FREE | FATTR4_WORD1_SPACE_TOTAL))) { - err = vfs_statfs(dentry, &statfs); + err = vfs_statfs(&path, &statfs); if (err) goto out_nfserr; } diff --git a/fs/nfsd/vfs.c b/fs/nfsd/vfs.c index 3c111120b619..f6f1a718642f 100644 --- a/fs/nfsd/vfs.c +++ b/fs/nfsd/vfs.c @@ -2019,8 +2019,14 @@ out: __be32 nfsd_statfs(struct svc_rqst *rqstp, struct svc_fh *fhp, struct kstatfs *stat, int access) { - __be32 err = fh_verify(rqstp, fhp, 0, NFSD_MAY_NOP | access); - if (!err && vfs_statfs(fhp->fh_dentry,stat)) + struct path path = { + .mnt = fhp->fh_export->ex_path.mnt, + .dentry = fhp->fh_dentry, + }; + __be32 err; + + err = fh_verify(rqstp, fhp, 0, NFSD_MAY_NOP | access); + if (!err && vfs_statfs(&path, stat)) err = nfserr_io; return err; } diff --git a/fs/statfs.c b/fs/statfs.c index 4ef021f3b612..6a305709a4da 100644 --- a/fs/statfs.c +++ b/fs/statfs.c @@ -7,33 +7,35 @@ #include <linux/security.h> #include <linux/uaccess.h> -int vfs_statfs(struct dentry *dentry, struct kstatfs *buf) +int statfs_by_dentry(struct dentry *dentry, struct kstatfs *buf) { - int retval = -ENODEV; - - if (dentry) { - retval = -ENOSYS; - if (dentry->d_sb->s_op->statfs) { - memset(buf, 0, sizeof(*buf)); - retval = security_sb_statfs(dentry); - if (retval) - return retval; - retval = dentry->d_sb->s_op->statfs(dentry, buf); - if (retval == 0 && buf->f_frsize == 0) - buf->f_frsize = buf->f_bsize; - } - } + int retval; + + if (!dentry->d_sb->s_op->statfs) + return -ENOSYS; + + memset(buf, 0, sizeof(*buf)); + retval = security_sb_statfs(dentry); + if (retval) + return retval; + retval = dentry->d_sb->s_op->statfs(dentry, buf); + if (retval == 0 && buf->f_frsize == 0) + buf->f_frsize = buf->f_bsize; return retval; } +int vfs_statfs(struct path *path, struct kstatfs *buf) +{ + return statfs_by_dentry(path->dentry, buf); +} EXPORT_SYMBOL(vfs_statfs); -static int vfs_statfs_native(struct dentry *dentry, struct statfs *buf) +static int do_statfs_native(struct path *path, struct statfs *buf) { struct kstatfs st; int retval; - retval = vfs_statfs(dentry, &st); + retval = vfs_statfs(path, &st); if (retval) return retval; @@ -72,12 +74,12 @@ static int vfs_statfs_native(struct dentry *dentry, struct statfs *buf) return 0; } -static int vfs_statfs64(struct dentry *dentry, struct statfs64 *buf) +static int do_statfs64(struct path *path, struct statfs64 *buf) { struct kstatfs st; int retval; - retval = vfs_statfs(dentry, &st); + retval = vfs_statfs(path, &st); if (retval) return retval; @@ -107,7 +109,7 @@ SYSCALL_DEFINE2(statfs, const char __user *, pathname, struct statfs __user *, b error = user_path(pathname, &path); if (!error) { struct statfs tmp; - error = vfs_statfs_native(path.dentry, &tmp); + error = do_statfs_native(&path, &tmp); if (!error && copy_to_user(buf, &tmp, sizeof(tmp))) error = -EFAULT; path_put(&path); @@ -125,7 +127,7 @@ SYSCALL_DEFINE3(statfs64, const char __user *, pathname, size_t, sz, struct stat error = user_path(pathname, &path); if (!error) { struct statfs64 tmp; - error = vfs_statfs64(path.dentry, &tmp); + error = do_statfs64(&path, &tmp); if (!error && copy_to_user(buf, &tmp, sizeof(tmp))) error = -EFAULT; path_put(&path); @@ -143,7 +145,7 @@ SYSCALL_DEFINE2(fstatfs, unsigned int, fd, struct statfs __user *, buf) file = fget(fd); if (!file) goto out; - error = vfs_statfs_native(file->f_path.dentry, &tmp); + error = do_statfs_native(&file->f_path, &tmp); if (!error && copy_to_user(buf, &tmp, sizeof(tmp))) error = -EFAULT; fput(file); @@ -164,7 +166,7 @@ SYSCALL_DEFINE3(fstatfs64, unsigned int, fd, size_t, sz, struct statfs64 __user file = fget(fd); if (!file) goto out; - error = vfs_statfs64(file->f_path.dentry, &tmp); + error = do_statfs64(&file->f_path, &tmp); if (!error && copy_to_user(buf, &tmp, sizeof(tmp))) error = -EFAULT; fput(file); @@ -183,7 +185,7 @@ SYSCALL_DEFINE2(ustat, unsigned, dev, struct ustat __user *, ubuf) if (!s) return -EINVAL; - err = vfs_statfs(s->s_root, &sbuf); + err = statfs_by_dentry(s->s_root, &sbuf); drop_super(s); if (err) return err; |