Commit ebabe9a9 authored by Christoph Hellwig's avatar Christoph Hellwig Committed by Al Viro

pass a struct path to vfs_statfs

We'll need the path to implement the flags field for statvfs support.
We do have it available in all callers except:

 - ecryptfs_statfs.  This one doesn't actually need vfs_statfs but just
   needs to do a caller to the lower filesystem statfs method.
 - sys_ustat.  Add a non-exported statfs_by_dentry helper for it which
   doesn't won't be able to fill out the flags field later on.

In addition rename the helpers for statfs vs fstatfs to do_*statfs instead
of the misleading vfs prefix.
Signed-off-by: default avatarChristoph Hellwig <hch@lst.de>
Signed-off-by: default avatarAl Viro <viro@zeniv.linux.org.uk>
parent 336fb3b9
...@@ -234,11 +234,11 @@ linux_to_osf_statfs(struct kstatfs *linux_stat, struct osf_statfs __user *osf_st ...@@ -234,11 +234,11 @@ linux_to_osf_statfs(struct kstatfs *linux_stat, struct osf_statfs __user *osf_st
} }
static int static int
do_osf_statfs(struct dentry * dentry, struct osf_statfs __user *buffer, do_osf_statfs(struct path *path, struct osf_statfs __user *buffer,
unsigned long bufsiz) unsigned long bufsiz)
{ {
struct kstatfs linux_stat; struct kstatfs linux_stat;
int error = vfs_statfs(dentry, &linux_stat); int error = vfs_statfs(path, &linux_stat);
if (!error) if (!error)
error = linux_to_osf_statfs(&linux_stat, buffer, bufsiz); error = linux_to_osf_statfs(&linux_stat, buffer, bufsiz);
return error; return error;
...@@ -252,7 +252,7 @@ SYSCALL_DEFINE3(osf_statfs, char __user *, pathname, ...@@ -252,7 +252,7 @@ SYSCALL_DEFINE3(osf_statfs, char __user *, pathname,
retval = user_path(pathname, &path); retval = user_path(pathname, &path);
if (!retval) { if (!retval) {
retval = do_osf_statfs(path.dentry, buffer, bufsiz); retval = do_osf_statfs(&path buffer, bufsiz);
path_put(&path); path_put(&path);
} }
return retval; return retval;
...@@ -267,7 +267,7 @@ SYSCALL_DEFINE3(osf_fstatfs, unsigned long, fd, ...@@ -267,7 +267,7 @@ SYSCALL_DEFINE3(osf_fstatfs, unsigned long, fd,
retval = -EBADF; retval = -EBADF;
file = fget(fd); file = fget(fd);
if (file) { if (file) {
retval = do_osf_statfs(file->f_path.dentry, buffer, bufsiz); retval = do_osf_statfs(&file->f_path, buffer, bufsiz);
fput(file); fput(file);
} }
return retval; return retval;
......
...@@ -145,7 +145,7 @@ static int hpux_ustat(dev_t dev, struct hpux_ustat __user *ubuf) ...@@ -145,7 +145,7 @@ static int hpux_ustat(dev_t dev, struct hpux_ustat __user *ubuf)
s = user_get_super(dev); s = user_get_super(dev);
if (s == NULL) if (s == NULL)
goto out; goto out;
err = vfs_statfs(s->s_root, &sbuf); err = statfs_by_dentry(s->s_root, &sbuf);
drop_super(s); drop_super(s);
if (err) if (err)
goto out; goto out;
...@@ -186,12 +186,12 @@ struct hpux_statfs { ...@@ -186,12 +186,12 @@ struct hpux_statfs {
int16_t f_pad; int16_t f_pad;
}; };
static int vfs_statfs_hpux(struct dentry *dentry, struct hpux_statfs *buf) static int do_statfs_hpux(struct path *path, struct hpux_statfs *buf)
{ {
struct kstatfs st; struct kstatfs st;
int retval; int retval;
retval = vfs_statfs(dentry, &st); retval = vfs_statfs(path, &st);
if (retval) if (retval)
return retval; return retval;
...@@ -219,7 +219,7 @@ asmlinkage long hpux_statfs(const char __user *pathname, ...@@ -219,7 +219,7 @@ asmlinkage long hpux_statfs(const char __user *pathname,
error = user_path(pathname, &path); error = user_path(pathname, &path);
if (!error) { if (!error) {
struct hpux_statfs tmp; struct hpux_statfs tmp;
error = vfs_statfs_hpux(path.dentry, &tmp); error = do_statfs_hpux(&path, &tmp);
if (!error && copy_to_user(buf, &tmp, sizeof(tmp))) if (!error && copy_to_user(buf, &tmp, sizeof(tmp)))
error = -EFAULT; error = -EFAULT;
path_put(&path); path_put(&path);
...@@ -237,7 +237,7 @@ asmlinkage long hpux_fstatfs(unsigned int fd, struct hpux_statfs __user * buf) ...@@ -237,7 +237,7 @@ asmlinkage long hpux_fstatfs(unsigned int fd, struct hpux_statfs __user * buf)
file = fget(fd); file = fget(fd);
if (!file) if (!file)
goto out; goto out;
error = vfs_statfs_hpux(file->f_path.dentry, &tmp); error = do_statfs_hpux(&file->f_path, &tmp);
if (!error && copy_to_user(buf, &tmp, sizeof(tmp))) if (!error && copy_to_user(buf, &tmp, sizeof(tmp)))
error = -EFAULT; error = -EFAULT;
fput(file); fput(file);
......
...@@ -146,7 +146,7 @@ static int cachefiles_daemon_add_cache(struct cachefiles_cache *cache) ...@@ -146,7 +146,7 @@ static int cachefiles_daemon_add_cache(struct cachefiles_cache *cache)
goto error_unsupported; goto error_unsupported;
/* get the cache size and blocksize */ /* get the cache size and blocksize */
ret = vfs_statfs(root, &stats); ret = vfs_statfs(&path, &stats);
if (ret < 0) if (ret < 0)
goto error_unsupported; goto error_unsupported;
......
...@@ -683,6 +683,10 @@ int cachefiles_has_space(struct cachefiles_cache *cache, ...@@ -683,6 +683,10 @@ int cachefiles_has_space(struct cachefiles_cache *cache,
unsigned fnr, unsigned bnr) unsigned fnr, unsigned bnr)
{ {
struct kstatfs stats; struct kstatfs stats;
struct path path = {
.mnt = cache->mnt,
.dentry = cache->mnt->mnt_root,
};
int ret; int ret;
//_enter("{%llu,%llu,%llu,%llu,%llu,%llu},%u,%u", //_enter("{%llu,%llu,%llu,%llu,%llu,%llu},%u,%u",
...@@ -697,7 +701,7 @@ int cachefiles_has_space(struct cachefiles_cache *cache, ...@@ -697,7 +701,7 @@ int cachefiles_has_space(struct cachefiles_cache *cache,
/* find out how many pages of blockdev are available */ /* find out how many pages of blockdev are available */
memset(&stats, 0, sizeof(stats)); memset(&stats, 0, sizeof(stats));
ret = vfs_statfs(cache->mnt->mnt_root, &stats); ret = vfs_statfs(&path, &stats);
if (ret < 0) { if (ret < 0) {
if (ret == -EIO) if (ret == -EIO)
cachefiles_io_error(cache, "statfs failed"); cachefiles_io_error(cache, "statfs failed");
......
...@@ -266,7 +266,7 @@ asmlinkage long compat_sys_statfs(const char __user *pathname, struct compat_sta ...@@ -266,7 +266,7 @@ asmlinkage long compat_sys_statfs(const char __user *pathname, struct compat_sta
error = user_path(pathname, &path); error = user_path(pathname, &path);
if (!error) { if (!error) {
struct kstatfs tmp; struct kstatfs tmp;
error = vfs_statfs(path.dentry, &tmp); error = vfs_statfs(&path, &tmp);
if (!error) if (!error)
error = put_compat_statfs(buf, &tmp); error = put_compat_statfs(buf, &tmp);
path_put(&path); path_put(&path);
...@@ -284,7 +284,7 @@ asmlinkage long compat_sys_fstatfs(unsigned int fd, struct compat_statfs __user ...@@ -284,7 +284,7 @@ asmlinkage long compat_sys_fstatfs(unsigned int fd, struct compat_statfs __user
file = fget(fd); file = fget(fd);
if (!file) if (!file)
goto out; goto out;
error = vfs_statfs(file->f_path.dentry, &tmp); error = vfs_statfs(&file->f_path, &tmp);
if (!error) if (!error)
error = put_compat_statfs(buf, &tmp); error = put_compat_statfs(buf, &tmp);
fput(file); fput(file);
...@@ -334,7 +334,7 @@ asmlinkage long compat_sys_statfs64(const char __user *pathname, compat_size_t s ...@@ -334,7 +334,7 @@ asmlinkage long compat_sys_statfs64(const char __user *pathname, compat_size_t s
error = user_path(pathname, &path); error = user_path(pathname, &path);
if (!error) { if (!error) {
struct kstatfs tmp; struct kstatfs tmp;
error = vfs_statfs(path.dentry, &tmp); error = vfs_statfs(&path, &tmp);
if (!error) if (!error)
error = put_compat_statfs64(buf, &tmp); error = put_compat_statfs64(buf, &tmp);
path_put(&path); path_put(&path);
...@@ -355,7 +355,7 @@ asmlinkage long compat_sys_fstatfs64(unsigned int fd, compat_size_t sz, struct c ...@@ -355,7 +355,7 @@ asmlinkage long compat_sys_fstatfs64(unsigned int fd, compat_size_t sz, struct c
file = fget(fd); file = fget(fd);
if (!file) if (!file)
goto out; goto out;
error = vfs_statfs(file->f_path.dentry, &tmp); error = vfs_statfs(&file->f_path, &tmp);
if (!error) if (!error)
error = put_compat_statfs64(buf, &tmp); error = put_compat_statfs64(buf, &tmp);
fput(file); fput(file);
...@@ -378,7 +378,7 @@ asmlinkage long compat_sys_ustat(unsigned dev, struct compat_ustat __user *u) ...@@ -378,7 +378,7 @@ asmlinkage long compat_sys_ustat(unsigned dev, struct compat_ustat __user *u)
sb = user_get_super(new_decode_dev(dev)); sb = user_get_super(new_decode_dev(dev));
if (!sb) if (!sb)
return -EINVAL; return -EINVAL;
err = vfs_statfs(sb->s_root, &sbuf); err = statfs_by_dentry(sb->s_root, &sbuf);
drop_super(sb); drop_super(sb);
if (err) if (err)
return err; return err;
......
...@@ -118,7 +118,11 @@ void ecryptfs_init_inode(struct inode *inode, struct inode *lower_inode) ...@@ -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) 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);
} }
/** /**
......
...@@ -1756,6 +1756,10 @@ nfsd4_encode_fattr(struct svc_fh *fhp, struct svc_export *exp, ...@@ -1756,6 +1756,10 @@ nfsd4_encode_fattr(struct svc_fh *fhp, struct svc_export *exp,
struct nfs4_acl *acl = NULL; struct nfs4_acl *acl = NULL;
struct nfsd4_compoundres *resp = rqstp->rq_resp; struct nfsd4_compoundres *resp = rqstp->rq_resp;
u32 minorversion = resp->cstate.minorversion; u32 minorversion = resp->cstate.minorversion;
struct path path = {
.mnt = exp->ex_path.mnt,
.dentry = dentry,
};
BUG_ON(bmval1 & NFSD_WRITEONLY_ATTRS_WORD1); BUG_ON(bmval1 & NFSD_WRITEONLY_ATTRS_WORD1);
BUG_ON(bmval0 & ~nfsd_suppattrs0(minorversion)); BUG_ON(bmval0 & ~nfsd_suppattrs0(minorversion));
...@@ -1776,7 +1780,7 @@ nfsd4_encode_fattr(struct svc_fh *fhp, struct svc_export *exp, ...@@ -1776,7 +1780,7 @@ nfsd4_encode_fattr(struct svc_fh *fhp, struct svc_export *exp,
FATTR4_WORD0_MAXNAME)) || FATTR4_WORD0_MAXNAME)) ||
(bmval1 & (FATTR4_WORD1_SPACE_AVAIL | FATTR4_WORD1_SPACE_FREE | (bmval1 & (FATTR4_WORD1_SPACE_AVAIL | FATTR4_WORD1_SPACE_FREE |
FATTR4_WORD1_SPACE_TOTAL))) { FATTR4_WORD1_SPACE_TOTAL))) {
err = vfs_statfs(dentry, &statfs); err = vfs_statfs(&path, &statfs);
if (err) if (err)
goto out_nfserr; goto out_nfserr;
} }
......
...@@ -2019,8 +2019,14 @@ nfsd_readdir(struct svc_rqst *rqstp, struct svc_fh *fhp, loff_t *offsetp, ...@@ -2019,8 +2019,14 @@ nfsd_readdir(struct svc_rqst *rqstp, struct svc_fh *fhp, loff_t *offsetp,
__be32 __be32
nfsd_statfs(struct svc_rqst *rqstp, struct svc_fh *fhp, struct kstatfs *stat, int access) 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); struct path path = {
if (!err && vfs_statfs(fhp->fh_dentry,stat)) .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; err = nfserr_io;
return err; return err;
} }
......
...@@ -7,33 +7,35 @@ ...@@ -7,33 +7,35 @@
#include <linux/security.h> #include <linux/security.h>
#include <linux/uaccess.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; int retval;
if (dentry) { if (!dentry->d_sb->s_op->statfs)
retval = -ENOSYS; return -ENOSYS;
if (dentry->d_sb->s_op->statfs) {
memset(buf, 0, sizeof(*buf)); memset(buf, 0, sizeof(*buf));
retval = security_sb_statfs(dentry); retval = security_sb_statfs(dentry);
if (retval) if (retval)
return retval; return retval;
retval = dentry->d_sb->s_op->statfs(dentry, buf); retval = dentry->d_sb->s_op->statfs(dentry, buf);
if (retval == 0 && buf->f_frsize == 0) if (retval == 0 && buf->f_frsize == 0)
buf->f_frsize = buf->f_bsize; buf->f_frsize = buf->f_bsize;
}
}
return retval; return retval;
} }
int vfs_statfs(struct path *path, struct kstatfs *buf)
{
return statfs_by_dentry(path->dentry, buf);
}
EXPORT_SYMBOL(vfs_statfs); 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; struct kstatfs st;
int retval; int retval;
retval = vfs_statfs(dentry, &st); retval = vfs_statfs(path, &st);
if (retval) if (retval)
return retval; return retval;
...@@ -72,12 +74,12 @@ static int vfs_statfs_native(struct dentry *dentry, struct statfs *buf) ...@@ -72,12 +74,12 @@ static int vfs_statfs_native(struct dentry *dentry, struct statfs *buf)
return 0; 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; struct kstatfs st;
int retval; int retval;
retval = vfs_statfs(dentry, &st); retval = vfs_statfs(path, &st);
if (retval) if (retval)
return retval; return retval;
...@@ -107,7 +109,7 @@ SYSCALL_DEFINE2(statfs, const char __user *, pathname, struct statfs __user *, b ...@@ -107,7 +109,7 @@ SYSCALL_DEFINE2(statfs, const char __user *, pathname, struct statfs __user *, b
error = user_path(pathname, &path); error = user_path(pathname, &path);
if (!error) { if (!error) {
struct statfs tmp; 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))) if (!error && copy_to_user(buf, &tmp, sizeof(tmp)))
error = -EFAULT; error = -EFAULT;
path_put(&path); path_put(&path);
...@@ -125,7 +127,7 @@ SYSCALL_DEFINE3(statfs64, const char __user *, pathname, size_t, sz, struct stat ...@@ -125,7 +127,7 @@ SYSCALL_DEFINE3(statfs64, const char __user *, pathname, size_t, sz, struct stat
error = user_path(pathname, &path); error = user_path(pathname, &path);
if (!error) { if (!error) {
struct statfs64 tmp; struct statfs64 tmp;
error = vfs_statfs64(path.dentry, &tmp); error = do_statfs64(&path, &tmp);
if (!error && copy_to_user(buf, &tmp, sizeof(tmp))) if (!error && copy_to_user(buf, &tmp, sizeof(tmp)))
error = -EFAULT; error = -EFAULT;
path_put(&path); path_put(&path);
...@@ -143,7 +145,7 @@ SYSCALL_DEFINE2(fstatfs, unsigned int, fd, struct statfs __user *, buf) ...@@ -143,7 +145,7 @@ SYSCALL_DEFINE2(fstatfs, unsigned int, fd, struct statfs __user *, buf)
file = fget(fd); file = fget(fd);
if (!file) if (!file)
goto out; 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))) if (!error && copy_to_user(buf, &tmp, sizeof(tmp)))
error = -EFAULT; error = -EFAULT;
fput(file); fput(file);
...@@ -164,7 +166,7 @@ SYSCALL_DEFINE3(fstatfs64, unsigned int, fd, size_t, sz, struct statfs64 __user ...@@ -164,7 +166,7 @@ SYSCALL_DEFINE3(fstatfs64, unsigned int, fd, size_t, sz, struct statfs64 __user
file = fget(fd); file = fget(fd);
if (!file) if (!file)
goto out; 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))) if (!error && copy_to_user(buf, &tmp, sizeof(tmp)))
error = -EFAULT; error = -EFAULT;
fput(file); fput(file);
...@@ -183,7 +185,7 @@ SYSCALL_DEFINE2(ustat, unsigned, dev, struct ustat __user *, ubuf) ...@@ -183,7 +185,7 @@ SYSCALL_DEFINE2(ustat, unsigned, dev, struct ustat __user *, ubuf)
if (!s) if (!s)
return -EINVAL; return -EINVAL;
err = vfs_statfs(s->s_root, &sbuf); err = statfs_by_dentry(s->s_root, &sbuf);
drop_super(s); drop_super(s);
if (err) if (err)
return err; return err;
......
...@@ -1813,7 +1813,8 @@ extern struct vfsmount *collect_mounts(struct path *); ...@@ -1813,7 +1813,8 @@ extern struct vfsmount *collect_mounts(struct path *);
extern void drop_collected_mounts(struct vfsmount *); extern void drop_collected_mounts(struct vfsmount *);
extern int iterate_mounts(int (*)(struct vfsmount *, void *), void *, extern int iterate_mounts(int (*)(struct vfsmount *, void *), void *,
struct vfsmount *); struct vfsmount *);
extern int vfs_statfs(struct dentry *, struct kstatfs *); extern int vfs_statfs(struct path *, struct kstatfs *);
extern int statfs_by_dentry(struct dentry *, struct kstatfs *);
extern int freeze_super(struct super_block *super); extern int freeze_super(struct super_block *super);
extern int thaw_super(struct super_block *super); extern int thaw_super(struct super_block *super);
......
...@@ -122,7 +122,7 @@ static int check_free_space(struct bsd_acct_struct *acct, struct file *file) ...@@ -122,7 +122,7 @@ static int check_free_space(struct bsd_acct_struct *acct, struct file *file)
spin_unlock(&acct_lock); spin_unlock(&acct_lock);
/* May block */ /* May block */
if (vfs_statfs(file->f_path.dentry, &sbuf)) if (vfs_statfs(&file->f_path, &sbuf))
return res; return res;
suspend = sbuf.f_blocks * SUSPEND; suspend = sbuf.f_blocks * SUSPEND;
resume = sbuf.f_blocks * RESUME; resume = sbuf.f_blocks * RESUME;
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment