#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;
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);
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;
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;
#define _LINUX_STATFS_H
#include <linux/types.h>
-
#include <asm/statfs.h>
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