diff options
Diffstat (limited to 'fs/statfs.c')
-rw-r--r-- | fs/statfs.c | 47 |
1 files changed, 46 insertions, 1 deletions
diff --git a/fs/statfs.c b/fs/statfs.c index 6a305709a4da..30ea8c8a996b 100644 --- a/fs/statfs.c +++ b/fs/statfs.c | |||
@@ -2,11 +2,49 @@ | |||
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 | ||
11 | static int flags_by_mnt(int mnt_flags) | ||
12 | { | ||
13 | int flags = 0; | ||
14 | |||
15 | if (mnt_flags & MNT_READONLY) | ||
16 | flags |= ST_RDONLY; | ||
17 | if (mnt_flags & MNT_NOSUID) | ||
18 | flags |= ST_NOSUID; | ||
19 | if (mnt_flags & MNT_NODEV) | ||
20 | flags |= ST_NODEV; | ||
21 | if (mnt_flags & MNT_NOEXEC) | ||
22 | flags |= ST_NOEXEC; | ||
23 | if (mnt_flags & MNT_NOATIME) | ||
24 | flags |= ST_NOATIME; | ||
25 | if (mnt_flags & MNT_NODIRATIME) | ||
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 | |||
10 | int statfs_by_dentry(struct dentry *dentry, struct kstatfs *buf) | 48 | int statfs_by_dentry(struct dentry *dentry, struct kstatfs *buf) |
11 | { | 49 | { |
12 | int retval; | 50 | int retval; |
@@ -26,7 +64,12 @@ int statfs_by_dentry(struct dentry *dentry, struct kstatfs *buf) | |||
26 | 64 | ||
27 | int vfs_statfs(struct path *path, struct kstatfs *buf) | 65 | int vfs_statfs(struct path *path, struct kstatfs *buf) |
28 | { | 66 | { |
29 | return statfs_by_dentry(path->dentry, buf); | 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; | ||
30 | } | 73 | } |
31 | EXPORT_SYMBOL(vfs_statfs); | 74 | EXPORT_SYMBOL(vfs_statfs); |
32 | 75 | ||
@@ -69,6 +112,7 @@ static int do_statfs_native(struct path *path, struct statfs *buf) | |||
69 | buf->f_fsid = st.f_fsid; | 112 | buf->f_fsid = st.f_fsid; |
70 | buf->f_namelen = st.f_namelen; | 113 | buf->f_namelen = st.f_namelen; |
71 | buf->f_frsize = st.f_frsize; | 114 | buf->f_frsize = st.f_frsize; |
115 | buf->f_flags = st.f_flags; | ||
72 | memset(buf->f_spare, 0, sizeof(buf->f_spare)); | 116 | memset(buf->f_spare, 0, sizeof(buf->f_spare)); |
73 | } | 117 | } |
74 | return 0; | 118 | return 0; |
@@ -96,6 +140,7 @@ static int do_statfs64(struct path *path, struct statfs64 *buf) | |||
96 | buf->f_fsid = st.f_fsid; | 140 | buf->f_fsid = st.f_fsid; |
97 | buf->f_namelen = st.f_namelen; | 141 | buf->f_namelen = st.f_namelen; |
98 | buf->f_frsize = st.f_frsize; | 142 | buf->f_frsize = st.f_frsize; |
143 | buf->f_flags = st.f_flags; | ||
99 | memset(buf->f_spare, 0, sizeof(buf->f_spare)); | 144 | memset(buf->f_spare, 0, sizeof(buf->f_spare)); |
100 | } | 145 | } |
101 | return 0; | 146 | return 0; |