diff options
| author | Ingo Molnar <mingo@elte.hu> | 2010-08-12 15:38:56 -0400 |
|---|---|---|
| committer | Ingo Molnar <mingo@elte.hu> | 2010-08-12 15:39:04 -0400 |
| commit | f46a6804135795f77d096ab0128f27531c7d051c (patch) | |
| tree | 7cd33f69e3661327739ae4c96e5a8389e7fc912e /fs/statfs.c | |
| parent | b3e84ffa21f916e3354a12a7f19169c9febe96d0 (diff) | |
| parent | ad41a1e0cab07c5125456e8d38e5b1ab148d04aa (diff) | |
Merge branch 'linus' into perf/urgent
Merge reason: Fix upstream breakage introduced by:
de5d9bf: Move list types from <linux/list.h> to <linux/types.h>.
Signed-off-by: Ingo Molnar <mingo@elte.hu>
Diffstat (limited to 'fs/statfs.c')
| -rw-r--r-- | fs/statfs.c | 95 |
1 files changed, 71 insertions, 24 deletions
diff --git a/fs/statfs.c b/fs/statfs.c index 4ef021f3b612..30ea8c8a996b 100644 --- a/fs/statfs.c +++ b/fs/statfs.c | |||
| @@ -2,38 +2,83 @@ | |||
| 2 | #include <linux/module.h> | 2 | #include <linux/module.h> |
| 3 | #include <linux/fs.h> | 3 | #include <linux/fs.h> |
| 4 | #include <linux/file.h> | 4 | #include <linux/file.h> |
| 5 | #include <linux/mount.h> | ||
| 5 | #include <linux/namei.h> | 6 | #include <linux/namei.h> |
| 6 | #include <linux/statfs.h> | 7 | #include <linux/statfs.h> |
| 7 | #include <linux/security.h> | 8 | #include <linux/security.h> |
| 8 | #include <linux/uaccess.h> | 9 | #include <linux/uaccess.h> |
| 9 | 10 | ||
| 10 | int vfs_statfs(struct dentry *dentry, struct kstatfs *buf) | 11 | static int flags_by_mnt(int mnt_flags) |
| 11 | { | 12 | { |
| 12 | int retval = -ENODEV; | 13 | int flags = 0; |
| 13 | 14 | ||
| 14 | if (dentry) { | 15 | if (mnt_flags & MNT_READONLY) |
| 15 | retval = -ENOSYS; | 16 | flags |= ST_RDONLY; |
| 16 | if (dentry->d_sb->s_op->statfs) { | 17 | if (mnt_flags & MNT_NOSUID) |
| 17 | memset(buf, 0, sizeof(*buf)); | 18 | flags |= ST_NOSUID; |
| 18 | retval = security_sb_statfs(dentry); | 19 | if (mnt_flags & MNT_NODEV) |
| 19 | if (retval) | 20 | flags |= ST_NODEV; |
| 20 | return retval; | 21 | if (mnt_flags & MNT_NOEXEC) |
| 21 | retval = dentry->d_sb->s_op->statfs(dentry, buf); | 22 | flags |= ST_NOEXEC; |
| 22 | if (retval == 0 && buf->f_frsize == 0) | 23 | if (mnt_flags & MNT_NOATIME) |
| 23 | buf->f_frsize = buf->f_bsize; | 24 | flags |= ST_NOATIME; |
| 24 | } | 25 | if (mnt_flags & MNT_NODIRATIME) |
| 25 | } | 26 | flags |= ST_NODIRATIME; |
| 27 | if (mnt_flags & MNT_RELATIME) | ||
| 28 | flags |= ST_RELATIME; | ||
| 29 | return flags; | ||
| 30 | } | ||
| 31 | |||
| 32 | static int flags_by_sb(int s_flags) | ||
| 33 | { | ||
| 34 | int flags = 0; | ||
| 35 | if (s_flags & MS_SYNCHRONOUS) | ||
| 36 | flags |= ST_SYNCHRONOUS; | ||
| 37 | if (s_flags & MS_MANDLOCK) | ||
| 38 | flags |= ST_MANDLOCK; | ||
| 39 | return flags; | ||
| 40 | } | ||
| 41 | |||
| 42 | static int calculate_f_flags(struct vfsmount *mnt) | ||
| 43 | { | ||
| 44 | return ST_VALID | flags_by_mnt(mnt->mnt_flags) | | ||
| 45 | flags_by_sb(mnt->mnt_sb->s_flags); | ||
| 46 | } | ||
| 47 | |||
| 48 | int statfs_by_dentry(struct dentry *dentry, struct kstatfs *buf) | ||
| 49 | { | ||
| 50 | int retval; | ||
| 51 | |||
| 52 | if (!dentry->d_sb->s_op->statfs) | ||
| 53 | return -ENOSYS; | ||
| 54 | |||
| 55 | memset(buf, 0, sizeof(*buf)); | ||
| 56 | retval = security_sb_statfs(dentry); | ||
| 57 | if (retval) | ||
| 58 | return retval; | ||
| 59 | retval = dentry->d_sb->s_op->statfs(dentry, buf); | ||
| 60 | if (retval == 0 && buf->f_frsize == 0) | ||
| 61 | buf->f_frsize = buf->f_bsize; | ||
| 26 | return retval; | 62 | return retval; |
| 27 | } | 63 | } |
| 28 | 64 | ||
| 65 | int vfs_statfs(struct path *path, struct kstatfs *buf) | ||
| 66 | { | ||
| 67 | int error; | ||
| 68 | |||
| 69 | error = statfs_by_dentry(path->dentry, buf); | ||
| 70 | if (!error) | ||
| 71 | buf->f_flags = calculate_f_flags(path->mnt); | ||
| 72 | return error; | ||
| 73 | } | ||
| 29 | EXPORT_SYMBOL(vfs_statfs); | 74 | EXPORT_SYMBOL(vfs_statfs); |
| 30 | 75 | ||
| 31 | static int vfs_statfs_native(struct dentry *dentry, struct statfs *buf) | 76 | static int do_statfs_native(struct path *path, struct statfs *buf) |
| 32 | { | 77 | { |
| 33 | struct kstatfs st; | 78 | struct kstatfs st; |
| 34 | int retval; | 79 | int retval; |
| 35 | 80 | ||
| 36 | retval = vfs_statfs(dentry, &st); | 81 | retval = vfs_statfs(path, &st); |
| 37 | if (retval) | 82 | if (retval) |
| 38 | return retval; | 83 | return retval; |
| 39 | 84 | ||
| @@ -67,17 +112,18 @@ static int vfs_statfs_native(struct dentry *dentry, struct statfs *buf) | |||
| 67 | buf->f_fsid = st.f_fsid; | 112 | buf->f_fsid = st.f_fsid; |
| 68 | buf->f_namelen = st.f_namelen; | 113 | buf->f_namelen = st.f_namelen; |
| 69 | buf->f_frsize = st.f_frsize; | 114 | buf->f_frsize = st.f_frsize; |
| 115 | buf->f_flags = st.f_flags; | ||
| 70 | memset(buf->f_spare, 0, sizeof(buf->f_spare)); | 116 | memset(buf->f_spare, 0, sizeof(buf->f_spare)); |
| 71 | } | 117 | } |
| 72 | return 0; | 118 | return 0; |
| 73 | } | 119 | } |
| 74 | 120 | ||
| 75 | static int vfs_statfs64(struct dentry *dentry, struct statfs64 *buf) | 121 | static int do_statfs64(struct path *path, struct statfs64 *buf) |
| 76 | { | 122 | { |
| 77 | struct kstatfs st; | 123 | struct kstatfs st; |
| 78 | int retval; | 124 | int retval; |
| 79 | 125 | ||
| 80 | retval = vfs_statfs(dentry, &st); | 126 | retval = vfs_statfs(path, &st); |
| 81 | if (retval) | 127 | if (retval) |
| 82 | return retval; | 128 | return retval; |
| 83 | 129 | ||
| @@ -94,6 +140,7 @@ static int vfs_statfs64(struct dentry *dentry, struct statfs64 *buf) | |||
| 94 | buf->f_fsid = st.f_fsid; | 140 | buf->f_fsid = st.f_fsid; |
| 95 | buf->f_namelen = st.f_namelen; | 141 | buf->f_namelen = st.f_namelen; |
| 96 | buf->f_frsize = st.f_frsize; | 142 | buf->f_frsize = st.f_frsize; |
| 143 | buf->f_flags = st.f_flags; | ||
| 97 | memset(buf->f_spare, 0, sizeof(buf->f_spare)); | 144 | memset(buf->f_spare, 0, sizeof(buf->f_spare)); |
| 98 | } | 145 | } |
| 99 | return 0; | 146 | return 0; |
| @@ -107,7 +154,7 @@ SYSCALL_DEFINE2(statfs, const char __user *, pathname, struct statfs __user *, b | |||
| 107 | error = user_path(pathname, &path); | 154 | error = user_path(pathname, &path); |
| 108 | if (!error) { | 155 | if (!error) { |
| 109 | struct statfs tmp; | 156 | struct statfs tmp; |
| 110 | error = vfs_statfs_native(path.dentry, &tmp); | 157 | error = do_statfs_native(&path, &tmp); |
| 111 | if (!error && copy_to_user(buf, &tmp, sizeof(tmp))) | 158 | if (!error && copy_to_user(buf, &tmp, sizeof(tmp))) |
| 112 | error = -EFAULT; | 159 | error = -EFAULT; |
| 113 | path_put(&path); | 160 | path_put(&path); |
| @@ -125,7 +172,7 @@ SYSCALL_DEFINE3(statfs64, const char __user *, pathname, size_t, sz, struct stat | |||
| 125 | error = user_path(pathname, &path); | 172 | error = user_path(pathname, &path); |
| 126 | if (!error) { | 173 | if (!error) { |
| 127 | struct statfs64 tmp; | 174 | struct statfs64 tmp; |
| 128 | error = vfs_statfs64(path.dentry, &tmp); | 175 | error = do_statfs64(&path, &tmp); |
| 129 | if (!error && copy_to_user(buf, &tmp, sizeof(tmp))) | 176 | if (!error && copy_to_user(buf, &tmp, sizeof(tmp))) |
| 130 | error = -EFAULT; | 177 | error = -EFAULT; |
| 131 | path_put(&path); | 178 | path_put(&path); |
| @@ -143,7 +190,7 @@ SYSCALL_DEFINE2(fstatfs, unsigned int, fd, struct statfs __user *, buf) | |||
| 143 | file = fget(fd); | 190 | file = fget(fd); |
| 144 | if (!file) | 191 | if (!file) |
| 145 | goto out; | 192 | goto out; |
| 146 | error = vfs_statfs_native(file->f_path.dentry, &tmp); | 193 | error = do_statfs_native(&file->f_path, &tmp); |
| 147 | if (!error && copy_to_user(buf, &tmp, sizeof(tmp))) | 194 | if (!error && copy_to_user(buf, &tmp, sizeof(tmp))) |
| 148 | error = -EFAULT; | 195 | error = -EFAULT; |
| 149 | fput(file); | 196 | fput(file); |
| @@ -164,7 +211,7 @@ SYSCALL_DEFINE3(fstatfs64, unsigned int, fd, size_t, sz, struct statfs64 __user | |||
| 164 | file = fget(fd); | 211 | file = fget(fd); |
| 165 | if (!file) | 212 | if (!file) |
| 166 | goto out; | 213 | goto out; |
| 167 | error = vfs_statfs64(file->f_path.dentry, &tmp); | 214 | error = do_statfs64(&file->f_path, &tmp); |
| 168 | if (!error && copy_to_user(buf, &tmp, sizeof(tmp))) | 215 | if (!error && copy_to_user(buf, &tmp, sizeof(tmp))) |
| 169 | error = -EFAULT; | 216 | error = -EFAULT; |
| 170 | fput(file); | 217 | fput(file); |
| @@ -183,7 +230,7 @@ SYSCALL_DEFINE2(ustat, unsigned, dev, struct ustat __user *, ubuf) | |||
| 183 | if (!s) | 230 | if (!s) |
| 184 | return -EINVAL; | 231 | return -EINVAL; |
| 185 | 232 | ||
| 186 | err = vfs_statfs(s->s_root, &sbuf); | 233 | err = statfs_by_dentry(s->s_root, &sbuf); |
| 187 | drop_super(s); | 234 | drop_super(s); |
| 188 | if (err) | 235 | if (err) |
| 189 | return err; | 236 | return err; |
