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>
This commit is contained in:
parent
ebabe9a900
commit
365b181897
5 changed files with 89 additions and 13 deletions
|
@ -33,7 +33,8 @@ struct statfs {
|
||||||
/* Linux specials */
|
/* Linux specials */
|
||||||
__kernel_fsid_t f_fsid;
|
__kernel_fsid_t f_fsid;
|
||||||
long f_namelen;
|
long f_namelen;
|
||||||
long f_spare[6];
|
long f_flags;
|
||||||
|
long f_spare[5];
|
||||||
};
|
};
|
||||||
|
|
||||||
#if (_MIPS_SIM == _MIPS_SIM_ABI32) || (_MIPS_SIM == _MIPS_SIM_NABI32)
|
#if (_MIPS_SIM == _MIPS_SIM_ABI32) || (_MIPS_SIM == _MIPS_SIM_NABI32)
|
||||||
|
@ -53,7 +54,8 @@ struct statfs64 {
|
||||||
__u64 f_bavail;
|
__u64 f_bavail;
|
||||||
__kernel_fsid_t f_fsid;
|
__kernel_fsid_t f_fsid;
|
||||||
__u32 f_namelen;
|
__u32 f_namelen;
|
||||||
__u32 f_spare[6];
|
__u32 f_flags;
|
||||||
|
__u32 f_spare[5];
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif /* _MIPS_SIM == _MIPS_SIM_ABI32 */
|
#endif /* _MIPS_SIM == _MIPS_SIM_ABI32 */
|
||||||
|
@ -73,7 +75,8 @@ struct statfs64 { /* Same as struct statfs */
|
||||||
/* Linux specials */
|
/* Linux specials */
|
||||||
__kernel_fsid_t f_fsid;
|
__kernel_fsid_t f_fsid;
|
||||||
long f_namelen;
|
long f_namelen;
|
||||||
long f_spare[6];
|
long f_flags;
|
||||||
|
long f_spare[5];
|
||||||
};
|
};
|
||||||
|
|
||||||
struct compat_statfs64 {
|
struct compat_statfs64 {
|
||||||
|
@ -88,7 +91,8 @@ struct compat_statfs64 {
|
||||||
__u64 f_bavail;
|
__u64 f_bavail;
|
||||||
__kernel_fsid_t f_fsid;
|
__kernel_fsid_t f_fsid;
|
||||||
__u32 f_namelen;
|
__u32 f_namelen;
|
||||||
__u32 f_spare[6];
|
__u32 f_flags;
|
||||||
|
__u32 f_spare[5];
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif /* _MIPS_SIM == _MIPS_SIM_ABI64 */
|
#endif /* _MIPS_SIM == _MIPS_SIM_ABI64 */
|
||||||
|
|
|
@ -33,7 +33,8 @@ struct statfs {
|
||||||
__kernel_fsid_t f_fsid;
|
__kernel_fsid_t f_fsid;
|
||||||
int f_namelen;
|
int f_namelen;
|
||||||
int f_frsize;
|
int f_frsize;
|
||||||
int f_spare[5];
|
int f_flags;
|
||||||
|
int f_spare[4];
|
||||||
};
|
};
|
||||||
|
|
||||||
struct statfs64 {
|
struct statfs64 {
|
||||||
|
@ -47,7 +48,8 @@ struct statfs64 {
|
||||||
__kernel_fsid_t f_fsid;
|
__kernel_fsid_t f_fsid;
|
||||||
int f_namelen;
|
int f_namelen;
|
||||||
int f_frsize;
|
int f_frsize;
|
||||||
int f_spare[5];
|
int f_flags;
|
||||||
|
int f_spare[4];
|
||||||
};
|
};
|
||||||
|
|
||||||
struct compat_statfs64 {
|
struct compat_statfs64 {
|
||||||
|
@ -61,7 +63,8 @@ struct compat_statfs64 {
|
||||||
__kernel_fsid_t f_fsid;
|
__kernel_fsid_t f_fsid;
|
||||||
__u32 f_namelen;
|
__u32 f_namelen;
|
||||||
__u32 f_frsize;
|
__u32 f_frsize;
|
||||||
__u32 f_spare[5];
|
__u32 f_flags;
|
||||||
|
__u32 f_spare[4];
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif /* __s390x__ */
|
#endif /* __s390x__ */
|
||||||
|
|
47
fs/statfs.c
47
fs/statfs.c
|
@ -2,11 +2,49 @@
|
||||||
#include <linux/module.h>
|
#include <linux/module.h>
|
||||||
#include <linux/fs.h>
|
#include <linux/fs.h>
|
||||||
#include <linux/file.h>
|
#include <linux/file.h>
|
||||||
|
#include <linux/mount.h>
|
||||||
#include <linux/namei.h>
|
#include <linux/namei.h>
|
||||||
#include <linux/statfs.h>
|
#include <linux/statfs.h>
|
||||||
#include <linux/security.h>
|
#include <linux/security.h>
|
||||||
#include <linux/uaccess.h>
|
#include <linux/uaccess.h>
|
||||||
|
|
||||||
|
static int flags_by_mnt(int mnt_flags)
|
||||||
|
{
|
||||||
|
int flags = 0;
|
||||||
|
|
||||||
|
if (mnt_flags & MNT_READONLY)
|
||||||
|
flags |= ST_RDONLY;
|
||||||
|
if (mnt_flags & MNT_NOSUID)
|
||||||
|
flags |= ST_NOSUID;
|
||||||
|
if (mnt_flags & MNT_NODEV)
|
||||||
|
flags |= ST_NODEV;
|
||||||
|
if (mnt_flags & MNT_NOEXEC)
|
||||||
|
flags |= ST_NOEXEC;
|
||||||
|
if (mnt_flags & MNT_NOATIME)
|
||||||
|
flags |= ST_NOATIME;
|
||||||
|
if (mnt_flags & MNT_NODIRATIME)
|
||||||
|
flags |= ST_NODIRATIME;
|
||||||
|
if (mnt_flags & MNT_RELATIME)
|
||||||
|
flags |= ST_RELATIME;
|
||||||
|
return flags;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int flags_by_sb(int s_flags)
|
||||||
|
{
|
||||||
|
int flags = 0;
|
||||||
|
if (s_flags & MS_SYNCHRONOUS)
|
||||||
|
flags |= ST_SYNCHRONOUS;
|
||||||
|
if (s_flags & MS_MANDLOCK)
|
||||||
|
flags |= ST_MANDLOCK;
|
||||||
|
return flags;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int calculate_f_flags(struct vfsmount *mnt)
|
||||||
|
{
|
||||||
|
return ST_VALID | flags_by_mnt(mnt->mnt_flags) |
|
||||||
|
flags_by_sb(mnt->mnt_sb->s_flags);
|
||||||
|
}
|
||||||
|
|
||||||
int statfs_by_dentry(struct dentry *dentry, struct kstatfs *buf)
|
int statfs_by_dentry(struct dentry *dentry, struct kstatfs *buf)
|
||||||
{
|
{
|
||||||
int retval;
|
int retval;
|
||||||
|
@ -26,7 +64,12 @@ int statfs_by_dentry(struct dentry *dentry, struct kstatfs *buf)
|
||||||
|
|
||||||
int vfs_statfs(struct path *path, struct kstatfs *buf)
|
int vfs_statfs(struct path *path, struct kstatfs *buf)
|
||||||
{
|
{
|
||||||
return statfs_by_dentry(path->dentry, buf);
|
int error;
|
||||||
|
|
||||||
|
error = statfs_by_dentry(path->dentry, buf);
|
||||||
|
if (!error)
|
||||||
|
buf->f_flags = calculate_f_flags(path->mnt);
|
||||||
|
return error;
|
||||||
}
|
}
|
||||||
EXPORT_SYMBOL(vfs_statfs);
|
EXPORT_SYMBOL(vfs_statfs);
|
||||||
|
|
||||||
|
@ -69,6 +112,7 @@ static int do_statfs_native(struct path *path, struct statfs *buf)
|
||||||
buf->f_fsid = st.f_fsid;
|
buf->f_fsid = st.f_fsid;
|
||||||
buf->f_namelen = st.f_namelen;
|
buf->f_namelen = st.f_namelen;
|
||||||
buf->f_frsize = st.f_frsize;
|
buf->f_frsize = st.f_frsize;
|
||||||
|
buf->f_flags = st.f_flags;
|
||||||
memset(buf->f_spare, 0, sizeof(buf->f_spare));
|
memset(buf->f_spare, 0, sizeof(buf->f_spare));
|
||||||
}
|
}
|
||||||
return 0;
|
return 0;
|
||||||
|
@ -96,6 +140,7 @@ static int do_statfs64(struct path *path, struct statfs64 *buf)
|
||||||
buf->f_fsid = st.f_fsid;
|
buf->f_fsid = st.f_fsid;
|
||||||
buf->f_namelen = st.f_namelen;
|
buf->f_namelen = st.f_namelen;
|
||||||
buf->f_frsize = st.f_frsize;
|
buf->f_frsize = st.f_frsize;
|
||||||
|
buf->f_flags = st.f_flags;
|
||||||
memset(buf->f_spare, 0, sizeof(buf->f_spare));
|
memset(buf->f_spare, 0, sizeof(buf->f_spare));
|
||||||
}
|
}
|
||||||
return 0;
|
return 0;
|
||||||
|
|
|
@ -33,7 +33,8 @@ struct statfs {
|
||||||
__kernel_fsid_t f_fsid;
|
__kernel_fsid_t f_fsid;
|
||||||
__statfs_word f_namelen;
|
__statfs_word f_namelen;
|
||||||
__statfs_word f_frsize;
|
__statfs_word f_frsize;
|
||||||
__statfs_word f_spare[5];
|
__statfs_word f_flags;
|
||||||
|
__statfs_word f_spare[4];
|
||||||
};
|
};
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
@ -55,7 +56,8 @@ struct statfs64 {
|
||||||
__kernel_fsid_t f_fsid;
|
__kernel_fsid_t f_fsid;
|
||||||
__statfs_word f_namelen;
|
__statfs_word f_namelen;
|
||||||
__statfs_word f_frsize;
|
__statfs_word f_frsize;
|
||||||
__statfs_word f_spare[5];
|
__statfs_word f_flags;
|
||||||
|
__statfs_word f_spare[4];
|
||||||
} ARCH_PACK_STATFS64;
|
} ARCH_PACK_STATFS64;
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
@ -77,7 +79,8 @@ struct compat_statfs64 {
|
||||||
__kernel_fsid_t f_fsid;
|
__kernel_fsid_t f_fsid;
|
||||||
__u32 f_namelen;
|
__u32 f_namelen;
|
||||||
__u32 f_frsize;
|
__u32 f_frsize;
|
||||||
__u32 f_spare[5];
|
__u32 f_flags;
|
||||||
|
__u32 f_spare[4];
|
||||||
} ARCH_PACK_COMPAT_STATFS64;
|
} ARCH_PACK_COMPAT_STATFS64;
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
|
@ -2,7 +2,6 @@
|
||||||
#define _LINUX_STATFS_H
|
#define _LINUX_STATFS_H
|
||||||
|
|
||||||
#include <linux/types.h>
|
#include <linux/types.h>
|
||||||
|
|
||||||
#include <asm/statfs.h>
|
#include <asm/statfs.h>
|
||||||
|
|
||||||
struct kstatfs {
|
struct kstatfs {
|
||||||
|
@ -16,7 +15,29 @@ struct kstatfs {
|
||||||
__kernel_fsid_t f_fsid;
|
__kernel_fsid_t f_fsid;
|
||||||
long f_namelen;
|
long f_namelen;
|
||||||
long f_frsize;
|
long f_frsize;
|
||||||
long f_spare[5];
|
long f_flags;
|
||||||
|
long f_spare[4];
|
||||||
};
|
};
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Definitions for the flag in f_flag.
|
||||||
|
*
|
||||||
|
* Generally these flags are equivalent to the MS_ flags used in the mount
|
||||||
|
* ABI. The exception is ST_VALID which has the same value as MS_REMOUNT
|
||||||
|
* which doesn't make any sense for statfs.
|
||||||
|
*/
|
||||||
|
#define ST_RDONLY 0x0001 /* mount read-only */
|
||||||
|
#define ST_NOSUID 0x0002 /* ignore suid and sgid bits */
|
||||||
|
#define ST_NODEV 0x0004 /* disallow access to device special files */
|
||||||
|
#define ST_NOEXEC 0x0008 /* disallow program execution */
|
||||||
|
#define ST_SYNCHRONOUS 0x0010 /* writes are synced at once */
|
||||||
|
#define ST_VALID 0x0020 /* f_flags support is implemented */
|
||||||
|
#define ST_MANDLOCK 0x0040 /* allow mandatory locks on an FS */
|
||||||
|
/* 0x0080 used for ST_WRITE in glibc */
|
||||||
|
/* 0x0100 used for ST_APPEND in glibc */
|
||||||
|
/* 0x0200 used for ST_IMMUTABLE in glibc */
|
||||||
|
#define ST_NOATIME 0x0400 /* do not update access times */
|
||||||
|
#define ST_NODIRATIME 0x0800 /* do not update directory access times */
|
||||||
|
#define ST_RELATIME 0x1000 /* update atime relative to mtime/ctime */
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
Loading…
Reference in a new issue