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: Christoph Hellwig <hch@lst.de> Signed-off-by: Al Viro <viro@zeniv.linux.org.uk>
This commit is contained in:
committed by
Al Viro
parent
336fb3b97b
commit
ebabe9a900
@@ -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,
|
|||||||
|
|
||||||
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,
|
|||||||
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)
|
|||||||
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 {
|
|||||||
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,
|
|||||||
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)
|
|||||||
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)
|
|||||||
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,
|
|||||||
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,
|
|||||||
/* 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");
|
||||||
|
10
fs/compat.c
10
fs/compat.c
@@ -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
|
|||||||
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
|
|||||||
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
|
|||||||
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)
|
|||||||
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)
|
|||||||
*/
|
*/
|
||||||
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,
|
|||||||
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,
|
|||||||
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 @@ out:
|
|||||||
__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;
|
||||||
}
|
}
|
||||||
|
34
fs/statfs.c
34
fs/statfs.c
@@ -7,13 +7,13 @@
|
|||||||
#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->d_sb->s_op->statfs)
|
||||||
|
return -ENOSYS;
|
||||||
|
|
||||||
if (dentry) {
|
|
||||||
retval = -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)
|
||||||
@@ -21,19 +21,21 @@ int vfs_statfs(struct dentry *dentry, struct kstatfs *buf)
|
|||||||
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)
|
|||||||
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
|
|||||||
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
|
|||||||
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)
|
|||||||
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
|
|||||||
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)
|
|||||||
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 *);
|
|||||||
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)
|
|||||||
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;
|
||||||
|
Reference in New Issue
Block a user