Commit 365b18189789bfa1acd9939e6312b8a4b4577b28

Authored by Christoph Hellwig
Committed by Al Viro
1 parent ebabe9a900

add f_flags to struct statfs(64)

Add a flags field to help glibc implementing statvfs(3) efficiently.

We copy the flag values from glibc, and add a new ST_VALID flag to
denote that f_flags is implemented.

Signed-off-by: Christoph Hellwig <hch@lst.de>
Signed-off-by: Al Viro <viro@zeniv.linux.org.uk>

Showing 5 changed files with 89 additions and 13 deletions Side-by-side Diff

arch/mips/include/asm/statfs.h
... ... @@ -33,7 +33,8 @@
33 33 /* Linux specials */
34 34 __kernel_fsid_t f_fsid;
35 35 long f_namelen;
36   - long f_spare[6];
  36 + long f_flags;
  37 + long f_spare[5];
37 38 };
38 39  
39 40 #if (_MIPS_SIM == _MIPS_SIM_ABI32) || (_MIPS_SIM == _MIPS_SIM_NABI32)
... ... @@ -53,7 +54,8 @@
53 54 __u64 f_bavail;
54 55 __kernel_fsid_t f_fsid;
55 56 __u32 f_namelen;
56   - __u32 f_spare[6];
  57 + __u32 f_flags;
  58 + __u32 f_spare[5];
57 59 };
58 60  
59 61 #endif /* _MIPS_SIM == _MIPS_SIM_ABI32 */
... ... @@ -73,7 +75,8 @@
73 75 /* Linux specials */
74 76 __kernel_fsid_t f_fsid;
75 77 long f_namelen;
76   - long f_spare[6];
  78 + long f_flags;
  79 + long f_spare[5];
77 80 };
78 81  
79 82 struct compat_statfs64 {
... ... @@ -88,7 +91,8 @@
88 91 __u64 f_bavail;
89 92 __kernel_fsid_t f_fsid;
90 93 __u32 f_namelen;
91   - __u32 f_spare[6];
  94 + __u32 f_flags;
  95 + __u32 f_spare[5];
92 96 };
93 97  
94 98 #endif /* _MIPS_SIM == _MIPS_SIM_ABI64 */
arch/s390/include/asm/statfs.h
... ... @@ -33,7 +33,8 @@
33 33 __kernel_fsid_t f_fsid;
34 34 int f_namelen;
35 35 int f_frsize;
36   - int f_spare[5];
  36 + int f_flags;
  37 + int f_spare[4];
37 38 };
38 39  
39 40 struct statfs64 {
... ... @@ -47,7 +48,8 @@
47 48 __kernel_fsid_t f_fsid;
48 49 int f_namelen;
49 50 int f_frsize;
50   - int f_spare[5];
  51 + int f_flags;
  52 + int f_spare[4];
51 53 };
52 54  
53 55 struct compat_statfs64 {
... ... @@ -61,7 +63,8 @@
61 63 __kernel_fsid_t f_fsid;
62 64 __u32 f_namelen;
63 65 __u32 f_frsize;
64   - __u32 f_spare[5];
  66 + __u32 f_flags;
  67 + __u32 f_spare[4];
65 68 };
66 69  
67 70 #endif /* __s390x__ */
... ... @@ -2,11 +2,49 @@
2 2 #include <linux/module.h>
3 3 #include <linux/fs.h>
4 4 #include <linux/file.h>
  5 +#include <linux/mount.h>
5 6 #include <linux/namei.h>
6 7 #include <linux/statfs.h>
7 8 #include <linux/security.h>
8 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 48 int statfs_by_dentry(struct dentry *dentry, struct kstatfs *buf)
11 49 {
12 50 int retval;
... ... @@ -26,7 +64,12 @@
26 64  
27 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 74 EXPORT_SYMBOL(vfs_statfs);
32 75  
... ... @@ -69,6 +112,7 @@
69 112 buf->f_fsid = st.f_fsid;
70 113 buf->f_namelen = st.f_namelen;
71 114 buf->f_frsize = st.f_frsize;
  115 + buf->f_flags = st.f_flags;
72 116 memset(buf->f_spare, 0, sizeof(buf->f_spare));
73 117 }
74 118 return 0;
... ... @@ -96,6 +140,7 @@
96 140 buf->f_fsid = st.f_fsid;
97 141 buf->f_namelen = st.f_namelen;
98 142 buf->f_frsize = st.f_frsize;
  143 + buf->f_flags = st.f_flags;
99 144 memset(buf->f_spare, 0, sizeof(buf->f_spare));
100 145 }
101 146 return 0;
include/asm-generic/statfs.h
... ... @@ -33,7 +33,8 @@
33 33 __kernel_fsid_t f_fsid;
34 34 __statfs_word f_namelen;
35 35 __statfs_word f_frsize;
36   - __statfs_word f_spare[5];
  36 + __statfs_word f_flags;
  37 + __statfs_word f_spare[4];
37 38 };
38 39  
39 40 /*
... ... @@ -55,7 +56,8 @@
55 56 __kernel_fsid_t f_fsid;
56 57 __statfs_word f_namelen;
57 58 __statfs_word f_frsize;
58   - __statfs_word f_spare[5];
  59 + __statfs_word f_flags;
  60 + __statfs_word f_spare[4];
59 61 } ARCH_PACK_STATFS64;
60 62  
61 63 /*
... ... @@ -77,7 +79,8 @@
77 79 __kernel_fsid_t f_fsid;
78 80 __u32 f_namelen;
79 81 __u32 f_frsize;
80   - __u32 f_spare[5];
  82 + __u32 f_flags;
  83 + __u32 f_spare[4];
81 84 } ARCH_PACK_COMPAT_STATFS64;
82 85  
83 86 #endif
include/linux/statfs.h
... ... @@ -2,7 +2,6 @@
2 2 #define _LINUX_STATFS_H
3 3  
4 4 #include <linux/types.h>
5   -
6 5 #include <asm/statfs.h>
7 6  
8 7 struct kstatfs {
9 8  
... ... @@ -16,8 +15,30 @@
16 15 __kernel_fsid_t f_fsid;
17 16 long f_namelen;
18 17 long f_frsize;
19   - long f_spare[5];
  18 + long f_flags;
  19 + long f_spare[4];
20 20 };
  21 +
  22 +/*
  23 + * Definitions for the flag in f_flag.
  24 + *
  25 + * Generally these flags are equivalent to the MS_ flags used in the mount
  26 + * ABI. The exception is ST_VALID which has the same value as MS_REMOUNT
  27 + * which doesn't make any sense for statfs.
  28 + */
  29 +#define ST_RDONLY 0x0001 /* mount read-only */
  30 +#define ST_NOSUID 0x0002 /* ignore suid and sgid bits */
  31 +#define ST_NODEV 0x0004 /* disallow access to device special files */
  32 +#define ST_NOEXEC 0x0008 /* disallow program execution */
  33 +#define ST_SYNCHRONOUS 0x0010 /* writes are synced at once */
  34 +#define ST_VALID 0x0020 /* f_flags support is implemented */
  35 +#define ST_MANDLOCK 0x0040 /* allow mandatory locks on an FS */
  36 +/* 0x0080 used for ST_WRITE in glibc */
  37 +/* 0x0100 used for ST_APPEND in glibc */
  38 +/* 0x0200 used for ST_IMMUTABLE in glibc */
  39 +#define ST_NOATIME 0x0400 /* do not update access times */
  40 +#define ST_NODIRATIME 0x0800 /* do not update directory access times */
  41 +#define ST_RELATIME 0x1000 /* update atime relative to mtime/ctime */
21 42  
22 43 #endif