mirror of
				https://github.com/torvalds/linux.git
				synced 2025-11-04 10:40:15 +02:00 
			
		
		
		
	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 */
 | 
			
		||||
	__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 */
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -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__ */
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
							
								
								
									
										47
									
								
								fs/statfs.c
									
									
									
									
									
								
							
							
						
						
									
										47
									
								
								fs/statfs.c
									
									
									
									
									
								
							| 
						 | 
				
			
			@ -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;
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -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
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -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
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
		Loading…
	
		Reference in a new issue