Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 365b1818 authored by Christoph Hellwig's avatar Christoph Hellwig Committed by Al Viro
Browse files

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: default avatarChristoph Hellwig <hch@lst.de>
Signed-off-by: default avatarAl Viro <viro@zeniv.linux.org.uk>
parent ebabe9a9
Loading
Loading
Loading
Loading
+8 −4
Original line number Diff line number Diff line
@@ -33,7 +33,8 @@ struct statfs {
	/* Linux specials */
	__kernel_fsid_t	f_fsid;
	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)
@@ -53,7 +54,8 @@ struct statfs64 {
	__u64	f_bavail;
	__kernel_fsid_t f_fsid;
	__u32	f_namelen;
	__u32	f_spare[6];
	__u32	f_flags;
	__u32	f_spare[5];
};

#endif /* _MIPS_SIM == _MIPS_SIM_ABI32 */
@@ -73,7 +75,8 @@ struct statfs64 { /* Same as struct statfs */
	/* Linux specials */
	__kernel_fsid_t	f_fsid;
	long		f_namelen;
	long		f_spare[6];
	long		f_flags;
	long		f_spare[5];
};

struct compat_statfs64 {
@@ -88,7 +91,8 @@ struct compat_statfs64 {
	__u64	f_bavail;
	__kernel_fsid_t f_fsid;
	__u32	f_namelen;
	__u32	f_spare[6];
	__u32	f_flags;
	__u32	f_spare[5];
};

#endif /* _MIPS_SIM == _MIPS_SIM_ABI64 */
+6 −3
Original line number Diff line number Diff line
@@ -33,7 +33,8 @@ struct statfs {
	__kernel_fsid_t f_fsid;
	int  f_namelen;
	int  f_frsize;
	int  f_spare[5];
	int  f_flags;
	int  f_spare[4];
};

struct statfs64 {
@@ -47,7 +48,8 @@ struct statfs64 {
	__kernel_fsid_t f_fsid;
	int  f_namelen;
	int  f_frsize;
	int  f_spare[5];
	int  f_flags;
	int  f_spare[4];
};

struct compat_statfs64 {
@@ -61,7 +63,8 @@ struct compat_statfs64 {
	__kernel_fsid_t f_fsid;
	__u32 f_namelen;
	__u32 f_frsize;
	__u32 f_spare[5];
	__u32 f_flags;
	__u32 f_spare[4];
};

#endif /* __s390x__ */
+46 −1
Original line number Diff line number Diff line
@@ -2,11 +2,49 @@
#include <linux/module.h>
#include <linux/fs.h>
#include <linux/file.h>
#include <linux/mount.h>
#include <linux/namei.h>
#include <linux/statfs.h>
#include <linux/security.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 retval;
@@ -26,7 +64,12 @@ int statfs_by_dentry(struct dentry *dentry, 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);

@@ -69,6 +112,7 @@ static int do_statfs_native(struct path *path, struct statfs *buf)
		buf->f_fsid = st.f_fsid;
		buf->f_namelen = st.f_namelen;
		buf->f_frsize = st.f_frsize;
		buf->f_flags = st.f_flags;
		memset(buf->f_spare, 0, sizeof(buf->f_spare));
	}
	return 0;
@@ -96,6 +140,7 @@ static int do_statfs64(struct path *path, struct statfs64 *buf)
		buf->f_fsid = st.f_fsid;
		buf->f_namelen = st.f_namelen;
		buf->f_frsize = st.f_frsize;
		buf->f_flags = st.f_flags;
		memset(buf->f_spare, 0, sizeof(buf->f_spare));
	}
	return 0;
+6 −3
Original line number Diff line number Diff line
@@ -33,7 +33,8 @@ struct statfs {
	__kernel_fsid_t f_fsid;
	__statfs_word f_namelen;
	__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;
	__statfs_word f_namelen;
	__statfs_word f_frsize;
	__statfs_word f_spare[5];
	__statfs_word f_flags;
	__statfs_word f_spare[4];
} ARCH_PACK_STATFS64;

/* 
@@ -77,7 +79,8 @@ struct compat_statfs64 {
	__kernel_fsid_t f_fsid;
	__u32 f_namelen;
	__u32 f_frsize;
	__u32 f_spare[5];
	__u32 f_flags;
	__u32 f_spare[4];
} ARCH_PACK_COMPAT_STATFS64;

#endif
+23 −2
Original line number Diff line number Diff line
@@ -2,7 +2,6 @@
#define _LINUX_STATFS_H

#include <linux/types.h>

#include <asm/statfs.h>

struct kstatfs {
@@ -16,7 +15,29 @@ struct kstatfs {
	__kernel_fsid_t f_fsid;
	long f_namelen;
	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