diff options
| author | Stephen Rothwell <sfr@canb.auug.org.au> | 2003-01-12 05:31:48 -0800 |
|---|---|---|
| committer | Kai Germaschewski <kai@tp1.ruhr-uni-bochum.de> | 2003-01-12 05:31:48 -0800 |
| commit | 3929af2b29ff9edd154f47a502222fa0084b90cd (patch) | |
| tree | 80e03f130cf1a13734860263b4d408e1ba03c6bb | |
| parent | 45fce7ea4d84aac84da674cafb974ee54cc4b3a7 (diff) | |
[PATCH] compat_sys_[f]statfs - generic part
This patch creates compat_sys_statfs and compat_sys_fstatfs. This is just
the generic part of the patch. Specific archs will follow.
| -rw-r--r-- | fs/compat.c | 57 |
1 files changed, 57 insertions, 0 deletions
diff --git a/fs/compat.c b/fs/compat.c index 2a0bdefb362a..9e8906a35ccc 100644 --- a/fs/compat.c +++ b/fs/compat.c @@ -17,6 +17,8 @@ #include <linux/time.h> #include <linux/fs.h> #include <linux/fcntl.h> +#include <linux/namei.h> +#include <linux/file.h> #include <asm/uaccess.h> @@ -101,3 +103,58 @@ int put_compat_flock(struct flock *kfl, struct compat_flock *ufl) err |= __put_user(kfl->l_pid, &ufl->l_pid); return err; } + +static int put_compat_statfs(struct compat_statfs *ubuf, struct statfs *kbuf) +{ + if (verify_area(VERIFY_WRITE, ubuf, sizeof(*ubuf)) || + __put_user(kbuf->f_type, &ubuf->f_type) || + __put_user(kbuf->f_bsize, &ubuf->f_bsize) || + __put_user(kbuf->f_blocks, &ubuf->f_blocks) || + __put_user(kbuf->f_bfree, &ubuf->f_bfree) || + __put_user(kbuf->f_bavail, &ubuf->f_bavail) || + __put_user(kbuf->f_files, &ubuf->f_files) || + __put_user(kbuf->f_ffree, &ubuf->f_ffree) || + __put_user(kbuf->f_namelen, &ubuf->f_namelen) || + __put_user(kbuf->f_fsid.val[0], &ubuf->f_fsid.val[0]) || + __put_user(kbuf->f_fsid.val[1], &ubuf->f_fsid.val[1])) + return -EFAULT; + return 0; +} + +/* + * The following statfs calls are copies of code from fs/open.c and + * should be checked against those from time to time + */ +asmlinkage long compat_sys_statfs(const char *path, struct compat_statfs *buf) +{ + struct nameidata nd; + int error; + + error = user_path_walk(path, &nd); + if (!error) { + struct statfs tmp; + error = vfs_statfs(nd.dentry->d_inode->i_sb, &tmp); + if (!error && put_compat_statfs(buf, &tmp)) + error = -EFAULT; + path_release(&nd); + } + return error; +} + +asmlinkage long compat_sys_fstatfs(unsigned int fd, struct compat_statfs *buf) +{ + struct file * file; + struct statfs tmp; + int error; + + error = -EBADF; + file = fget(fd); + if (!file) + goto out; + error = vfs_statfs(file->f_dentry->d_inode->i_sb, &tmp); + if (!error && put_compat_statfs(buf, &tmp)) + error = -EFAULT; + fput(file); +out: + return error; +} |
