Linux userland API discussions
 help / color / mirror / Atom feed
* [v13 4/5] ext4: adds FS_IOC_FSSETXATTR/FS_IOC_FSGETXATTR interface support
From: Li Xi @ 2015-04-20  1:39 UTC (permalink / raw)
  To: linux-fsdevel, linux-ext4, linux-api, tytso, adilger, jack, viro,
	hch, dmonakhov
In-Reply-To: <1429493988-16819-1-git-send-email-lixi@ddn.com>

This patch adds FS_IOC_FSSETXATTR/FS_IOC_FSGETXATTR ioctl interface
support for ext4. The interface is kept consistent with
XFS_IOC_FSGETXATTR/XFS_IOC_FSGETXATTR.

Signed-off-by: Li Xi <lixi@ddn.com>
---
 fs/ext4/ext4.h          |    9 ++
 fs/ext4/ioctl.c         |  364 +++++++++++++++++++++++++++++++++++-----------
 fs/xfs/xfs_fs.h         |   47 +++----
 include/uapi/linux/fs.h |   32 ++++
 4 files changed, 335 insertions(+), 117 deletions(-)

diff --git a/fs/ext4/ext4.h b/fs/ext4/ext4.h
index a7acf10..2d5a097 100644
--- a/fs/ext4/ext4.h
+++ b/fs/ext4/ext4.h
@@ -384,6 +384,13 @@ struct flex_groups {
 #define EXT4_FL_USER_VISIBLE		0x304BDFFF /* User visible flags */
 #define EXT4_FL_USER_MODIFIABLE		0x204380FF /* User modifiable flags */
 
+#define EXT4_FL_XFLAG_VISIBLE		(EXT4_SYNC_FL | \
+					 EXT4_IMMUTABLE_FL | \
+					 EXT4_APPEND_FL | \
+					 EXT4_NODUMP_FL | \
+					 EXT4_NOATIME_FL | \
+					 EXT4_PROJINHERIT_FL)
+
 /* Flags that should be inherited by new inodes from their parent. */
 #define EXT4_FL_INHERITED (EXT4_SECRM_FL | EXT4_UNRM_FL | EXT4_COMPR_FL |\
 			   EXT4_SYNC_FL | EXT4_NODUMP_FL | EXT4_NOATIME_FL |\
@@ -606,6 +613,8 @@ enum {
 #define EXT4_IOC_RESIZE_FS		_IOW('f', 16, __u64)
 #define EXT4_IOC_SWAP_BOOT		_IO('f', 17)
 #define EXT4_IOC_PRECACHE_EXTENTS	_IO('f', 18)
+#define EXT4_IOC_FSGETXATTR		FS_IOC_FSGETXATTR
+#define EXT4_IOC_FSSETXATTR		FS_IOC_FSSETXATTR
 
 #if defined(__KERNEL__) && defined(CONFIG_COMPAT)
 /*
diff --git a/fs/ext4/ioctl.c b/fs/ext4/ioctl.c
index f58a0d1..27e50a8 100644
--- a/fs/ext4/ioctl.c
+++ b/fs/ext4/ioctl.c
@@ -14,6 +14,8 @@
 #include <linux/compat.h>
 #include <linux/mount.h>
 #include <linux/file.h>
+#include <linux/quotaops.h>
+#include <linux/quota.h>
 #include <asm/uaccess.h>
 #include "ext4_jbd2.h"
 #include "ext4.h"
@@ -196,6 +198,225 @@ journal_err_out:
 	return err;
 }
 
+static int ext4_ioctl_setflags(struct inode *inode,
+			       unsigned int flags)
+{
+	struct ext4_inode_info *ei = EXT4_I(inode);
+	handle_t *handle = NULL;
+	int err = EPERM, migrate = 0;
+	struct ext4_iloc iloc;
+	unsigned int oldflags, mask, i;
+	unsigned int jflag;
+
+	/* Is it quota file? Do not allow user to mess with it */
+	if (IS_NOQUOTA(inode))
+		goto flags_out;
+
+	oldflags = ei->i_flags;
+
+	/* The JOURNAL_DATA flag is modifiable only by root */
+	jflag = flags & EXT4_JOURNAL_DATA_FL;
+
+	/*
+	 * The IMMUTABLE and APPEND_ONLY flags can only be changed by
+	 * the relevant capability.
+	 *
+	 * This test looks nicer. Thanks to Pauline Middelink
+	 */
+	if ((flags ^ oldflags) & (EXT4_APPEND_FL | EXT4_IMMUTABLE_FL)) {
+		if (!capable(CAP_LINUX_IMMUTABLE))
+			goto flags_out;
+	}
+
+	/*
+	 * The JOURNAL_DATA flag can only be changed by
+	 * the relevant capability.
+	 */
+	if ((jflag ^ oldflags) & (EXT4_JOURNAL_DATA_FL)) {
+		if (!capable(CAP_SYS_RESOURCE))
+			goto flags_out;
+	}
+	if ((flags ^ oldflags) & EXT4_EXTENTS_FL)
+		migrate = 1;
+
+	if (flags & EXT4_EOFBLOCKS_FL) {
+		/* we don't support adding EOFBLOCKS flag */
+		if (!(oldflags & EXT4_EOFBLOCKS_FL)) {
+			err = -EOPNOTSUPP;
+			goto flags_out;
+		}
+	} else if (oldflags & EXT4_EOFBLOCKS_FL)
+		ext4_truncate(inode);
+
+	handle = ext4_journal_start(inode, EXT4_HT_INODE, 1);
+	if (IS_ERR(handle)) {
+		err = PTR_ERR(handle);
+		goto flags_out;
+	}
+	if (IS_SYNC(inode))
+		ext4_handle_sync(handle);
+	err = ext4_reserve_inode_write(handle, inode, &iloc);
+	if (err)
+		goto flags_err;
+
+	for (i = 0, mask = 1; i < 32; i++, mask <<= 1) {
+		if (!(mask & EXT4_FL_USER_MODIFIABLE))
+			continue;
+		if (mask & flags)
+			ext4_set_inode_flag(inode, i);
+		else
+			ext4_clear_inode_flag(inode, i);
+	}
+
+	ext4_set_inode_flags(inode);
+	inode->i_ctime = ext4_current_time(inode);
+
+	err = ext4_mark_iloc_dirty(handle, inode, &iloc);
+flags_err:
+	ext4_journal_stop(handle);
+	if (err)
+		goto flags_out;
+
+	if ((jflag ^ oldflags) & (EXT4_JOURNAL_DATA_FL))
+		err = ext4_change_inode_journal_flag(inode, jflag);
+	if (err)
+		goto flags_out;
+	if (migrate) {
+		if (flags & EXT4_EXTENTS_FL)
+			err = ext4_ext_migrate(inode);
+		else
+			err = ext4_ind_migrate(inode);
+	}
+
+flags_out:
+	return err;
+}
+
+static int ext4_ioctl_setproject(struct file *filp, __u32 projid)
+{
+	struct inode *inode = file_inode(filp);
+	struct super_block *sb = inode->i_sb;
+	struct ext4_inode_info *ei = EXT4_I(inode);
+	int err;
+	handle_t *handle;
+	kprojid_t kprojid;
+	struct ext4_iloc iloc;
+	struct ext4_inode *raw_inode;
+
+	struct dquot *transfer_to[EXT4_MAXQUOTAS] = { };
+
+	if (!EXT4_HAS_RO_COMPAT_FEATURE(sb,
+			EXT4_FEATURE_RO_COMPAT_PROJECT)) {
+		BUG_ON(__kprojid_val(EXT4_I(inode)->i_projid)
+		       != EXT4_DEF_PROJID);
+		if (projid != EXT4_DEF_PROJID)
+			return -EOPNOTSUPP;
+		else
+			return 0;
+	}
+
+	kprojid = make_kprojid(&init_user_ns, (projid_t)projid);
+
+	if (projid_eq(kprojid, EXT4_I(inode)->i_projid))
+		return 0;
+
+	err = mnt_want_write_file(filp);
+	if (err)
+		return err;
+
+	err = -EPERM;
+	mutex_lock(&inode->i_mutex);
+	/* Is it quota file? Do not allow user to mess with it */
+	if (IS_NOQUOTA(inode))
+		goto project_out;
+
+	dquot_initialize(inode);
+
+	handle = ext4_journal_start(inode, EXT4_HT_QUOTA,
+		EXT4_QUOTA_INIT_BLOCKS(sb) +
+		EXT4_QUOTA_DEL_BLOCKS(sb) + 3);
+	if (IS_ERR(handle)) {
+		err = PTR_ERR(handle);
+		goto project_out;
+	}
+
+	err = ext4_reserve_inode_write(handle, inode, &iloc);
+	if (err)
+		goto project_stop;
+
+	raw_inode = ext4_raw_inode(&iloc);
+	if (EXT4_INODE_SIZE(sb) <= EXT4_GOOD_OLD_INODE_SIZE) {
+	    	err = -EOPNOTSUPP;
+	    	goto project_stop;
+	}
+
+	if (!EXT4_FITS_IN_INODE(raw_inode, ei, i_projid)) {
+	    	err = -EOVERFLOW;
+	    	goto project_stop;
+	}
+
+	transfer_to[PRJQUOTA] = dqget(sb, make_kqid_projid(kprojid));
+	if (!transfer_to[PRJQUOTA])
+		goto project_set;
+
+	err = __dquot_transfer(inode, transfer_to);
+	dqput(transfer_to[PRJQUOTA]);
+	if (err)
+		goto project_stop;
+
+project_set:
+	EXT4_I(inode)->i_projid = kprojid;
+	inode->i_ctime = ext4_current_time(inode);
+	err = ext4_mark_iloc_dirty(handle, inode, &iloc);
+project_stop:
+	ext4_journal_stop(handle);
+project_out:
+	mutex_unlock(&inode->i_mutex);
+	mnt_drop_write_file(filp);
+	return err;
+}
+
+/* Transfer internal flags to xflags */
+static inline __u32 ext4_iflags_to_xflags(unsigned long iflags)
+{
+	__u32 xflags = 0;
+
+	if (iflags & EXT4_SYNC_FL)
+		xflags |= FS_XFLAG_SYNC;
+	if (iflags & EXT4_IMMUTABLE_FL)
+		xflags |= FS_XFLAG_IMMUTABLE;
+	if (iflags & EXT4_APPEND_FL)
+		xflags |= FS_XFLAG_APPEND;
+	if (iflags & EXT4_NODUMP_FL)
+		xflags |= FS_XFLAG_NODUMP;
+	if (iflags & EXT4_NOATIME_FL)
+		xflags |= FS_XFLAG_NOATIME;
+	if (iflags & EXT4_PROJINHERIT_FL)
+		xflags |= FS_XFLAG_PROJINHERIT;
+	return xflags;
+}
+
+/* Transfer xflags flags to internal */
+static inline unsigned long ext4_xflags_to_iflags(__u32 xflags)
+{
+	unsigned long iflags = 0;
+
+	if (xflags & FS_XFLAG_SYNC)
+		iflags |= EXT4_SYNC_FL;
+	if (xflags & FS_XFLAG_IMMUTABLE)
+		iflags |= EXT4_IMMUTABLE_FL;
+	if (xflags & FS_XFLAG_APPEND)
+		iflags |= EXT4_APPEND_FL;
+	if (xflags & FS_XFLAG_NODUMP)
+		iflags |= EXT4_NODUMP_FL;
+	if (xflags & FS_XFLAG_NOATIME)
+		iflags |= EXT4_NOATIME_FL;
+	if (xflags & FS_XFLAG_PROJINHERIT)
+		iflags |= EXT4_PROJINHERIT_FL;
+
+	return iflags;
+}
+
 long ext4_ioctl(struct file *filp, unsigned int cmd, unsigned long arg)
 {
 	struct inode *inode = file_inode(filp);
@@ -211,11 +432,7 @@ long ext4_ioctl(struct file *filp, unsigned int cmd, unsigned long arg)
 		flags = ei->i_flags & EXT4_FL_USER_VISIBLE;
 		return put_user(flags, (int __user *) arg);
 	case EXT4_IOC_SETFLAGS: {
-		handle_t *handle = NULL;
-		int err, migrate = 0;
-		struct ext4_iloc iloc;
-		unsigned int oldflags, mask, i;
-		unsigned int jflag;
+		int err;
 
 		if (!inode_owner_or_capable(inode))
 			return -EACCES;
@@ -229,89 +446,8 @@ long ext4_ioctl(struct file *filp, unsigned int cmd, unsigned long arg)
 
 		flags = ext4_mask_flags(inode->i_mode, flags);
 
-		err = -EPERM;
 		mutex_lock(&inode->i_mutex);
-		/* Is it quota file? Do not allow user to mess with it */
-		if (IS_NOQUOTA(inode))
-			goto flags_out;
-
-		oldflags = ei->i_flags;
-
-		/* The JOURNAL_DATA flag is modifiable only by root */
-		jflag = flags & EXT4_JOURNAL_DATA_FL;
-
-		/*
-		 * The IMMUTABLE and APPEND_ONLY flags can only be changed by
-		 * the relevant capability.
-		 *
-		 * This test looks nicer. Thanks to Pauline Middelink
-		 */
-		if ((flags ^ oldflags) & (EXT4_APPEND_FL | EXT4_IMMUTABLE_FL)) {
-			if (!capable(CAP_LINUX_IMMUTABLE))
-				goto flags_out;
-		}
-
-		/*
-		 * The JOURNAL_DATA flag can only be changed by
-		 * the relevant capability.
-		 */
-		if ((jflag ^ oldflags) & (EXT4_JOURNAL_DATA_FL)) {
-			if (!capable(CAP_SYS_RESOURCE))
-				goto flags_out;
-		}
-		if ((flags ^ oldflags) & EXT4_EXTENTS_FL)
-			migrate = 1;
-
-		if (flags & EXT4_EOFBLOCKS_FL) {
-			/* we don't support adding EOFBLOCKS flag */
-			if (!(oldflags & EXT4_EOFBLOCKS_FL)) {
-				err = -EOPNOTSUPP;
-				goto flags_out;
-			}
-		} else if (oldflags & EXT4_EOFBLOCKS_FL)
-			ext4_truncate(inode);
-
-		handle = ext4_journal_start(inode, EXT4_HT_INODE, 1);
-		if (IS_ERR(handle)) {
-			err = PTR_ERR(handle);
-			goto flags_out;
-		}
-		if (IS_SYNC(inode))
-			ext4_handle_sync(handle);
-		err = ext4_reserve_inode_write(handle, inode, &iloc);
-		if (err)
-			goto flags_err;
-
-		for (i = 0, mask = 1; i < 32; i++, mask <<= 1) {
-			if (!(mask & EXT4_FL_USER_MODIFIABLE))
-				continue;
-			if (mask & flags)
-				ext4_set_inode_flag(inode, i);
-			else
-				ext4_clear_inode_flag(inode, i);
-		}
-
-		ext4_set_inode_flags(inode);
-		inode->i_ctime = ext4_current_time(inode);
-
-		err = ext4_mark_iloc_dirty(handle, inode, &iloc);
-flags_err:
-		ext4_journal_stop(handle);
-		if (err)
-			goto flags_out;
-
-		if ((jflag ^ oldflags) & (EXT4_JOURNAL_DATA_FL))
-			err = ext4_change_inode_journal_flag(inode, jflag);
-		if (err)
-			goto flags_out;
-		if (migrate) {
-			if (flags & EXT4_EXTENTS_FL)
-				err = ext4_ext_migrate(inode);
-			else
-				err = ext4_ind_migrate(inode);
-		}
-
-flags_out:
+		err = ext4_ioctl_setflags(inode, flags);
 		mutex_unlock(&inode->i_mutex);
 		mnt_drop_write_file(filp);
 		return err;
@@ -615,7 +751,61 @@ resizefs_out:
 	}
 	case EXT4_IOC_PRECACHE_EXTENTS:
 		return ext4_ext_precache(inode);
+	case EXT4_IOC_FSGETXATTR:
+	{
+		struct fsxattr fa;
+
+		memset(&fa, 0, sizeof(struct fsxattr));
 
+		ext4_get_inode_flags(ei);
+		fa.fsx_xflags = ext4_iflags_to_xflags(ei->i_flags & EXT4_FL_USER_VISIBLE);
+
+		if (EXT4_HAS_RO_COMPAT_FEATURE(inode->i_sb,
+				EXT4_FEATURE_RO_COMPAT_PROJECT)) {
+			fa.fsx_projid = (__u32)from_kprojid(&init_user_ns,
+				EXT4_I(inode)->i_projid);
+		}
+
+		if (copy_to_user((struct fsxattr __user *)arg,
+				 &fa, sizeof(fa)))
+			return -EFAULT;
+		return 0;
+	}
+	case EXT4_IOC_FSSETXATTR:
+	{
+		struct fsxattr fa;
+		int err;
+
+		if (copy_from_user(&fa, (struct fsxattr __user *)arg,
+				   sizeof(fa)))
+			return -EFAULT;
+
+		/* Make sure caller has proper permission */
+		if (!inode_owner_or_capable(inode))
+			return -EACCES;
+
+		err = mnt_want_write_file(filp);
+		if (err)
+			return err;
+
+		flags = ext4_xflags_to_iflags(fa.fsx_xflags);
+		flags = ext4_mask_flags(inode->i_mode, flags);
+
+		mutex_lock(&inode->i_mutex);
+		flags = (ei->i_flags & ~EXT4_FL_XFLAG_VISIBLE) |
+			 (flags & EXT4_FL_XFLAG_VISIBLE);
+		err = ext4_ioctl_setflags(inode, flags);
+		mutex_unlock(&inode->i_mutex);
+		mnt_drop_write_file(filp);
+		if (err)
+			return err;
+
+		err = ext4_ioctl_setproject(filp, fa.fsx_projid);
+		if (err)
+			return err;
+
+		return 0;
+	}
 	default:
 		return -ENOTTY;
 	}
diff --git a/fs/xfs/xfs_fs.h b/fs/xfs/xfs_fs.h
index 18dc721..64c7ae6 100644
--- a/fs/xfs/xfs_fs.h
+++ b/fs/xfs/xfs_fs.h
@@ -36,38 +36,25 @@ struct dioattr {
 #endif
 
 /*
- * Structure for XFS_IOC_FSGETXATTR[A] and XFS_IOC_FSSETXATTR.
- */
-#ifndef HAVE_FSXATTR
-struct fsxattr {
-	__u32		fsx_xflags;	/* xflags field value (get/set) */
-	__u32		fsx_extsize;	/* extsize field value (get/set)*/
-	__u32		fsx_nextents;	/* nextents field value (get)	*/
-	__u32		fsx_projid;	/* project identifier (get/set) */
-	unsigned char	fsx_pad[12];
-};
-#endif
-
-/*
  * Flags for the bs_xflags/fsx_xflags field
  * There should be a one-to-one correspondence between these flags and the
  * XFS_DIFLAG_s.
  */
-#define XFS_XFLAG_REALTIME	0x00000001	/* data in realtime volume */
-#define XFS_XFLAG_PREALLOC	0x00000002	/* preallocated file extents */
-#define XFS_XFLAG_IMMUTABLE	0x00000008	/* file cannot be modified */
-#define XFS_XFLAG_APPEND	0x00000010	/* all writes append */
-#define XFS_XFLAG_SYNC		0x00000020	/* all writes synchronous */
-#define XFS_XFLAG_NOATIME	0x00000040	/* do not update access time */
-#define XFS_XFLAG_NODUMP	0x00000080	/* do not include in backups */
-#define XFS_XFLAG_RTINHERIT	0x00000100	/* create with rt bit set */
-#define XFS_XFLAG_PROJINHERIT	0x00000200	/* create with parents projid */
-#define XFS_XFLAG_NOSYMLINKS	0x00000400	/* disallow symlink creation */
-#define XFS_XFLAG_EXTSIZE	0x00000800	/* extent size allocator hint */
-#define XFS_XFLAG_EXTSZINHERIT	0x00001000	/* inherit inode extent size */
-#define XFS_XFLAG_NODEFRAG	0x00002000  	/* do not defragment */
-#define XFS_XFLAG_FILESTREAM	0x00004000	/* use filestream allocator */
-#define XFS_XFLAG_HASATTR	0x80000000	/* no DIFLAG for this	*/
+#define XFS_XFLAG_REALTIME	FS_XFLAG_REALTIME	/* data in realtime volume */
+#define XFS_XFLAG_PREALLOC	FS_XFLAG_PREALLOC	/* preallocated file extents */
+#define XFS_XFLAG_IMMUTABLE	FS_XFLAG_IMMUTABLE	/* file cannot be modified */
+#define XFS_XFLAG_APPEND	FS_XFLAG_APPEND		/* all writes append */
+#define XFS_XFLAG_SYNC		FS_XFLAG_SYNC		/* all writes synchronous */
+#define XFS_XFLAG_NOATIME	FS_XFLAG_NOATIME	/* do not update access time */
+#define XFS_XFLAG_NODUMP	FS_XFLAG_NODUMP		/* do not include in backups */
+#define XFS_XFLAG_RTINHERIT	FS_XFLAG_RTINHERIT	/* create with rt bit set */
+#define XFS_XFLAG_PROJINHERIT	FS_XFLAG_PROJINHERIT	/* create with parents projid */
+#define XFS_XFLAG_NOSYMLINKS	FS_XFLAG_NOSYMLINKS	/* disallow symlink creation */
+#define XFS_XFLAG_EXTSIZE	FS_XFLAG_EXTSIZE	/* extent size allocator hint */
+#define XFS_XFLAG_EXTSZINHERIT	FS_XFLAG_EXTSZINHERIT	/* inherit inode extent size */
+#define XFS_XFLAG_NODEFRAG	FS_XFLAG_NODEFRAG  	/* do not defragment */
+#define XFS_XFLAG_FILESTREAM	FS_XFLAG_FILESTREAM	/* use filestream allocator */
+#define XFS_XFLAG_HASATTR	FS_XFLAG_HASATTR	/* no DIFLAG for this	*/
 
 /*
  * Structure for XFS_IOC_GETBMAP.
@@ -503,8 +490,8 @@ typedef struct xfs_swapext
 #define XFS_IOC_ALLOCSP		_IOW ('X', 10, struct xfs_flock64)
 #define XFS_IOC_FREESP		_IOW ('X', 11, struct xfs_flock64)
 #define XFS_IOC_DIOINFO		_IOR ('X', 30, struct dioattr)
-#define XFS_IOC_FSGETXATTR	_IOR ('X', 31, struct fsxattr)
-#define XFS_IOC_FSSETXATTR	_IOW ('X', 32, struct fsxattr)
+#define XFS_IOC_FSGETXATTR	FS_IOC_FSGETXATTR
+#define XFS_IOC_FSSETXATTR	FS_IOC_FSSETXATTR
 #define XFS_IOC_ALLOCSP64	_IOW ('X', 36, struct xfs_flock64)
 #define XFS_IOC_FREESP64	_IOW ('X', 37, struct xfs_flock64)
 #define XFS_IOC_GETBMAP		_IOWR('X', 38, struct getbmap)
diff --git a/include/uapi/linux/fs.h b/include/uapi/linux/fs.h
index fcbf647..69dda62 100644
--- a/include/uapi/linux/fs.h
+++ b/include/uapi/linux/fs.h
@@ -58,6 +58,36 @@ struct inodes_stat_t {
 	long dummy[5];		/* padding for sysctl ABI compatibility */
 };
 
+/*
+ * Structure for FS_IOC_FSGETXATTR and FS_IOC_FSSETXATTR.
+ */
+struct fsxattr {
+	__u32		fsx_xflags;	/* xflags field value (get/set) */
+	__u32		fsx_extsize;	/* extsize field value (get/set)*/
+	__u32		fsx_nextents;	/* nextents field value (get)	*/
+	__u32		fsx_projid;	/* project identifier (get/set) */
+	unsigned char	fsx_pad[12];
+};
+
+/*
+ * Flags for the fsx_xflags field
+ */
+#define FS_XFLAG_REALTIME	0x00000001	/* data in realtime volume */
+#define FS_XFLAG_PREALLOC	0x00000002	/* preallocated file extents */
+#define FS_XFLAG_IMMUTABLE	0x00000008	/* file cannot be modified */
+#define FS_XFLAG_APPEND		0x00000010	/* all writes append */
+#define FS_XFLAG_SYNC		0x00000020	/* all writes synchronous */
+#define FS_XFLAG_NOATIME	0x00000040	/* do not update access time */
+#define FS_XFLAG_NODUMP		0x00000080	/* do not include in backups */
+#define FS_XFLAG_RTINHERIT	0x00000100	/* create with rt bit set */
+#define FS_XFLAG_PROJINHERIT	0x00000200	/* create with parents projid */
+#define FS_XFLAG_NOSYMLINKS	0x00000400	/* disallow symlink creation */
+#define FS_XFLAG_EXTSIZE	0x00000800	/* extent size allocator hint */
+#define FS_XFLAG_EXTSZINHERIT	0x00001000	/* inherit inode extent size */
+#define FS_XFLAG_NODEFRAG	0x00002000  	/* do not defragment */
+#define FS_XFLAG_FILESTREAM	0x00004000	/* use filestream allocator */
+#define FS_XFLAG_HASATTR	0x80000000	/* no DIFLAG for this */
+
 
 #define NR_FILE  8192	/* this can well be larger on a larger system */
 
@@ -163,6 +193,8 @@ struct inodes_stat_t {
 #define	FS_IOC_GETVERSION		_IOR('v', 1, long)
 #define	FS_IOC_SETVERSION		_IOW('v', 2, long)
 #define FS_IOC_FIEMAP			_IOWR('f', 11, struct fiemap)
+#define FS_IOC_FSGETXATTR		_IOR('X', 31, struct fsxattr)
+#define FS_IOC_FSSETXATTR		_IOW('X', 32, struct fsxattr)
 #define FS_IOC32_GETFLAGS		_IOR('f', 1, int)
 #define FS_IOC32_SETFLAGS		_IOW('f', 2, int)
 #define FS_IOC32_GETVERSION		_IOR('v', 1, int)
-- 
1.7.1


^ permalink raw reply related

* [v13 3/5] ext4: adds project quota support
From: Li Xi @ 2015-04-20  1:39 UTC (permalink / raw)
  To: linux-fsdevel, linux-ext4, linux-api, tytso, adilger, jack, viro,
	hch, dmonakhov
In-Reply-To: <1429493988-16819-1-git-send-email-lixi@ddn.com>

This patch adds mount options for enabling/disabling project quota
accounting and enforcement. A new specific inode is also used for
project quota accounting.

Signed-off-by: Li Xi <lixi@ddn.com>
Signed-off-by: Dmitry Monakhov <dmonakhov@openvz.org>
Reviewed-by: Jan Kara <jack@suse.cz>
---
 fs/ext4/ext4.h  |    6 +++-
 fs/ext4/super.c |   56 ++++++++++++++++++++++++++++++++++++++++++++++++++----
 2 files changed, 55 insertions(+), 7 deletions(-)

diff --git a/fs/ext4/ext4.h b/fs/ext4/ext4.h
index 1446c4f..a7acf10 100644
--- a/fs/ext4/ext4.h
+++ b/fs/ext4/ext4.h
@@ -1169,7 +1169,8 @@ struct ext4_super_block {
 	__le32	s_overhead_clusters;	/* overhead blocks/clusters in fs */
 	__le32	s_backup_bgs[2];	/* groups with sparse_super2 SBs */
 	__u8	s_encrypt_algos[4];	/* Encryption algorithms in use  */
-	__le32	s_reserved[105];	/* Padding to the end of the block */
+	__le32  s_prj_quota_inum;       /* inode for tracking project quota */
+	__le32	s_reserved[104];	/* Padding to the end of the block */
 	__le32	s_checksum;		/* crc32c(superblock) */
 };
 
@@ -1184,7 +1185,7 @@ struct ext4_super_block {
 #define EXT4_MF_FS_ABORTED	0x0002	/* Fatal error detected */
 
 /* Number of quota types we support */
-#define EXT4_MAXQUOTAS 2
+#define EXT4_MAXQUOTAS 3
 
 /*
  * fourth extended-fs super-block data in memory
@@ -1376,6 +1377,7 @@ static inline int ext4_valid_inum(struct super_block *sb, unsigned long ino)
 		ino == EXT4_BOOT_LOADER_INO ||
 		ino == EXT4_JOURNAL_INO ||
 		ino == EXT4_RESIZE_INO ||
+		ino == le32_to_cpu(EXT4_SB(sb)->s_es->s_prj_quota_inum) ||
 		(ino >= EXT4_FIRST_INO(sb) &&
 		 ino <= le32_to_cpu(EXT4_SB(sb)->s_es->s_inodes_count));
 }
diff --git a/fs/ext4/super.c b/fs/ext4/super.c
index 04c6cc3..476e46f 100644
--- a/fs/ext4/super.c
+++ b/fs/ext4/super.c
@@ -1036,8 +1036,8 @@ static int bdev_try_to_free_page(struct super_block *sb, struct page *page,
 }
 
 #ifdef CONFIG_QUOTA
-#define QTYPE2NAME(t) ((t) == USRQUOTA ? "user" : "group")
-#define QTYPE2MOPT(on, t) ((t) == USRQUOTA?((on)##USRJQUOTA):((on)##GRPJQUOTA))
+static char *quotatypes[] = INITQFNAMES;
+#define QTYPE2NAME(t) (quotatypes[t])
 
 static int ext4_write_dquot(struct dquot *dquot);
 static int ext4_acquire_dquot(struct dquot *dquot);
@@ -3944,7 +3944,7 @@ static int ext4_fill_super(struct super_block *sb, void *data, int silent)
 		sb->s_qcop = &ext4_qctl_sysfile_operations;
 	else
 		sb->s_qcop = &ext4_qctl_operations;
-	sb->s_quota_types = QTYPE_MASK_USR | QTYPE_MASK_GRP;
+	sb->s_quota_types = QTYPE_MASK_USR | QTYPE_MASK_GRP | QTYPE_MASK_PRJ;
 #endif
 	memcpy(sb->s_uuid, es->s_uuid, sizeof(es->s_uuid));
 
@@ -5040,6 +5040,46 @@ restore_opts:
 	return err;
 }
 
+static int ext4_statfs_project(struct super_block *sb,
+			       kprojid_t projid, struct kstatfs *buf)
+{
+	struct kqid qid;
+	struct dquot *dquot;
+	u64 limit;
+	u64 curblock;
+
+	qid = make_kqid_projid(projid);
+	dquot = dqget(sb, qid);
+	if (!dquot)
+		return -ESRCH;
+	spin_lock(&dq_data_lock);
+
+	limit = dquot->dq_dqb.dqb_bsoftlimit ?
+		dquot->dq_dqb.dqb_bsoftlimit :
+		dquot->dq_dqb.dqb_bhardlimit;
+	if (limit && buf->f_blocks * buf->f_bsize > limit) {
+		curblock = dquot->dq_dqb.dqb_curspace / buf->f_bsize;
+		buf->f_blocks = limit / buf->f_bsize;
+		buf->f_bfree = buf->f_bavail =
+			(buf->f_blocks > curblock) ?
+			 (buf->f_blocks - curblock) : 0;
+	}
+
+	limit = dquot->dq_dqb.dqb_isoftlimit ?
+		dquot->dq_dqb.dqb_isoftlimit :
+		dquot->dq_dqb.dqb_ihardlimit;
+	if (limit && buf->f_files > limit) {
+		buf->f_files = limit;
+		buf->f_ffree =
+			(buf->f_files > dquot->dq_dqb.dqb_curinodes) ?
+			 (buf->f_files - dquot->dq_dqb.dqb_curinodes) : 0;
+	}
+
+	spin_unlock(&dq_data_lock);
+	dqput(dquot);
+	return 0;
+}
+
 static int ext4_statfs(struct dentry *dentry, struct kstatfs *buf)
 {
 	struct super_block *sb = dentry->d_sb;
@@ -5048,6 +5088,7 @@ static int ext4_statfs(struct dentry *dentry, struct kstatfs *buf)
 	ext4_fsblk_t overhead = 0, resv_blocks;
 	u64 fsid;
 	s64 bfree;
+	struct inode *inode = dentry->d_inode;
 	resv_blocks = EXT4_C2B(sbi, atomic64_read(&sbi->s_resv_clusters));
 
 	if (!test_opt(sb, MINIX_DF))
@@ -5072,6 +5113,9 @@ static int ext4_statfs(struct dentry *dentry, struct kstatfs *buf)
 	buf->f_fsid.val[0] = fsid & 0xFFFFFFFFUL;
 	buf->f_fsid.val[1] = (fsid >> 32) & 0xFFFFFFFFUL;
 
+	if (ext4_test_inode_flag(inode, EXT4_INODE_PROJINHERIT) &&
+	    sb_has_quota_limits_enabled(sb, PRJQUOTA))
+		ext4_statfs_project(sb, EXT4_I(inode)->i_projid, buf);
 	return 0;
 }
 
@@ -5236,7 +5280,8 @@ static int ext4_quota_enable(struct super_block *sb, int type, int format_id,
 	struct inode *qf_inode;
 	unsigned long qf_inums[EXT4_MAXQUOTAS] = {
 		le32_to_cpu(EXT4_SB(sb)->s_es->s_usr_quota_inum),
-		le32_to_cpu(EXT4_SB(sb)->s_es->s_grp_quota_inum)
+		le32_to_cpu(EXT4_SB(sb)->s_es->s_grp_quota_inum),
+		le32_to_cpu(EXT4_SB(sb)->s_es->s_prj_quota_inum)
 	};
 
 	BUG_ON(!EXT4_HAS_RO_COMPAT_FEATURE(sb, EXT4_FEATURE_RO_COMPAT_QUOTA));
@@ -5264,7 +5309,8 @@ static int ext4_enable_quotas(struct super_block *sb)
 	int type, err = 0;
 	unsigned long qf_inums[EXT4_MAXQUOTAS] = {
 		le32_to_cpu(EXT4_SB(sb)->s_es->s_usr_quota_inum),
-		le32_to_cpu(EXT4_SB(sb)->s_es->s_grp_quota_inum)
+		le32_to_cpu(EXT4_SB(sb)->s_es->s_grp_quota_inum),
+		le32_to_cpu(EXT4_SB(sb)->s_es->s_prj_quota_inum)
 	};
 
 	sb_dqopt(sb)->flags |= DQUOT_QUOTA_SYS_FILE;
-- 
1.7.1


^ permalink raw reply related

* [v13 2/5] ext4: adds project ID support
From: Li Xi @ 2015-04-20  1:39 UTC (permalink / raw)
  To: linux-fsdevel, linux-ext4, linux-api, tytso, adilger, jack, viro,
	hch, dmonakhov
In-Reply-To: <1429493988-16819-1-git-send-email-lixi@ddn.com>

This patch adds a new internal field of ext4 inode to save project
identifier. Also a new flag EXT4_INODE_PROJINHERIT is added for
inheriting project ID from parent directory.

Signed-off-by: Li Xi <lixi@ddn.com>
Reviewed-by: Jan Kara <jack@suse.cz>
---
 fs/ext4/ext4.h          |   21 +++++++++++++++++----
 fs/ext4/ialloc.c        |    5 +++++
 fs/ext4/inode.c         |   25 +++++++++++++++++++++++++
 fs/ext4/namei.c         |   18 ++++++++++++++++++
 fs/ext4/super.c         |    1 +
 include/uapi/linux/fs.h |    1 +
 6 files changed, 67 insertions(+), 4 deletions(-)

diff --git a/fs/ext4/ext4.h b/fs/ext4/ext4.h
index 7fec2ef..1446c4f 100644
--- a/fs/ext4/ext4.h
+++ b/fs/ext4/ext4.h
@@ -378,16 +378,18 @@ struct flex_groups {
 #define EXT4_EA_INODE_FL	        0x00200000 /* Inode used for large EA */
 #define EXT4_EOFBLOCKS_FL		0x00400000 /* Blocks allocated beyond EOF */
 #define EXT4_INLINE_DATA_FL		0x10000000 /* Inode has inline data. */
+#define EXT4_PROJINHERIT_FL		0x20000000 /* Create with parents projid */
 #define EXT4_RESERVED_FL		0x80000000 /* reserved for ext4 lib */
 
-#define EXT4_FL_USER_VISIBLE		0x004BDFFF /* User visible flags */
-#define EXT4_FL_USER_MODIFIABLE		0x004380FF /* User modifiable flags */
+#define EXT4_FL_USER_VISIBLE		0x304BDFFF /* User visible flags */
+#define EXT4_FL_USER_MODIFIABLE		0x204380FF /* User modifiable flags */
 
 /* Flags that should be inherited by new inodes from their parent. */
 #define EXT4_FL_INHERITED (EXT4_SECRM_FL | EXT4_UNRM_FL | EXT4_COMPR_FL |\
 			   EXT4_SYNC_FL | EXT4_NODUMP_FL | EXT4_NOATIME_FL |\
 			   EXT4_NOCOMPR_FL | EXT4_JOURNAL_DATA_FL |\
-			   EXT4_NOTAIL_FL | EXT4_DIRSYNC_FL)
+			   EXT4_NOTAIL_FL | EXT4_DIRSYNC_FL |\
+			   EXT4_PROJINHERIT_FL)
 
 /* Flags that are appropriate for regular files (all but dir-specific ones). */
 #define EXT4_REG_FLMASK (~(EXT4_DIRSYNC_FL | EXT4_TOPDIR_FL))
@@ -435,6 +437,7 @@ enum {
 	EXT4_INODE_EA_INODE	= 21,	/* Inode used for large EA */
 	EXT4_INODE_EOFBLOCKS	= 22,	/* Blocks allocated beyond EOF */
 	EXT4_INODE_INLINE_DATA	= 28,	/* Data in inode. */
+	EXT4_INODE_PROJINHERIT	= 29,	/* Create with parents projid */
 	EXT4_INODE_RESERVED	= 31,	/* reserved for ext4 lib */
 };
 
@@ -684,6 +687,7 @@ struct ext4_inode {
 	__le32  i_crtime;       /* File Creation time */
 	__le32  i_crtime_extra; /* extra FileCreationtime (nsec << 2 | epoch) */
 	__le32  i_version_hi;	/* high 32 bits for 64-bit version */
+	__le32  i_projid;	/* Project ID */
 };
 
 struct move_extent {
@@ -939,6 +943,7 @@ struct ext4_inode_info {
 
 	/* Precomputed uuid+inum+igen checksum for seeding inode checksums */
 	__u32 i_csum_seed;
+	kprojid_t i_projid;
 };
 
 /*
@@ -1531,6 +1536,7 @@ static inline void ext4_clear_state_flags(struct ext4_inode_info *ei)
  */
 #define EXT4_FEATURE_RO_COMPAT_METADATA_CSUM	0x0400
 #define EXT4_FEATURE_RO_COMPAT_READONLY		0x1000
+#define EXT4_FEATURE_RO_COMPAT_PROJECT		0x2000
 
 #define EXT4_FEATURE_INCOMPAT_COMPRESSION	0x0001
 #define EXT4_FEATURE_INCOMPAT_FILETYPE		0x0002
@@ -1581,7 +1587,8 @@ static inline void ext4_clear_state_flags(struct ext4_inode_info *ei)
 					 EXT4_FEATURE_RO_COMPAT_HUGE_FILE |\
 					 EXT4_FEATURE_RO_COMPAT_BIGALLOC |\
 					 EXT4_FEATURE_RO_COMPAT_METADATA_CSUM|\
-					 EXT4_FEATURE_RO_COMPAT_QUOTA)
+					 EXT4_FEATURE_RO_COMPAT_QUOTA |\
+					 EXT4_FEATURE_RO_COMPAT_PROJECT)
 
 /*
  * Default values for user and/or group using reserved blocks
@@ -1589,6 +1596,11 @@ static inline void ext4_clear_state_flags(struct ext4_inode_info *ei)
 #define	EXT4_DEF_RESUID		0
 #define	EXT4_DEF_RESGID		0
 
+/*
+ * Default project ID
+ */
+#define	EXT4_DEF_PROJID		0
+
 #define EXT4_DEF_INODE_READAHEAD_BLKS	32
 
 /*
@@ -2141,6 +2153,7 @@ extern int ext4_zero_partial_blocks(handle_t *handle, struct inode *inode,
 			     loff_t lstart, loff_t lend);
 extern int ext4_page_mkwrite(struct vm_area_struct *vma, struct vm_fault *vmf);
 extern qsize_t *ext4_get_reserved_space(struct inode *inode);
+extern int ext4_get_projid(struct inode *inode, kprojid_t *projid);
 extern void ext4_da_update_reserve_space(struct inode *inode,
 					int used, int quota_claim);
 
diff --git a/fs/ext4/ialloc.c b/fs/ext4/ialloc.c
index ac644c3..10ca9dd 100644
--- a/fs/ext4/ialloc.c
+++ b/fs/ext4/ialloc.c
@@ -756,6 +756,11 @@ struct inode *__ext4_new_inode(handle_t *handle, struct inode *dir,
 		inode->i_gid = dir->i_gid;
 	} else
 		inode_init_owner(inode, dir, mode);
+	if (EXT4_HAS_RO_COMPAT_FEATURE(sb, EXT4_FEATURE_RO_COMPAT_PROJECT) &&
+	    ext4_test_inode_flag(dir, EXT4_INODE_PROJINHERIT))
+		ei->i_projid = EXT4_I(dir)->i_projid;
+	else
+		ei->i_projid = make_kprojid(&init_user_ns, EXT4_DEF_PROJID);
 	dquot_initialize(inode);
 
 	if (!goal)
diff --git a/fs/ext4/inode.c b/fs/ext4/inode.c
index 4df6d01..cd482ac 100644
--- a/fs/ext4/inode.c
+++ b/fs/ext4/inode.c
@@ -3870,6 +3870,14 @@ static inline void ext4_iget_extra_inode(struct inode *inode,
 		EXT4_I(inode)->i_inline_off = 0;
 }
 
+int ext4_get_projid(struct inode *inode, kprojid_t *projid)
+{
+	if (!EXT4_HAS_RO_COMPAT_FEATURE(inode->i_sb, EXT4_FEATURE_RO_COMPAT_PROJECT))
+		return -EOPNOTSUPP;
+	*projid = EXT4_I(inode)->i_projid;
+	return 0;
+}
+
 struct inode *ext4_iget(struct super_block *sb, unsigned long ino)
 {
 	struct ext4_iloc iloc;
@@ -3881,6 +3889,7 @@ struct inode *ext4_iget(struct super_block *sb, unsigned long ino)
 	int block;
 	uid_t i_uid;
 	gid_t i_gid;
+	projid_t i_projid;
 
 	inode = iget_locked(sb, ino);
 	if (!inode)
@@ -3930,12 +3939,18 @@ struct inode *ext4_iget(struct super_block *sb, unsigned long ino)
 	inode->i_mode = le16_to_cpu(raw_inode->i_mode);
 	i_uid = (uid_t)le16_to_cpu(raw_inode->i_uid_low);
 	i_gid = (gid_t)le16_to_cpu(raw_inode->i_gid_low);
+	if (EXT4_HAS_RO_COMPAT_FEATURE(sb, EXT4_FEATURE_RO_COMPAT_PROJECT))
+		i_projid = (projid_t)le32_to_cpu(raw_inode->i_projid);
+	else
+		i_projid = EXT4_DEF_PROJID;
+
 	if (!(test_opt(inode->i_sb, NO_UID32))) {
 		i_uid |= le16_to_cpu(raw_inode->i_uid_high) << 16;
 		i_gid |= le16_to_cpu(raw_inode->i_gid_high) << 16;
 	}
 	i_uid_write(inode, i_uid);
 	i_gid_write(inode, i_gid);
+	ei->i_projid = make_kprojid(&init_user_ns, i_projid);;
 	set_nlink(inode, le16_to_cpu(raw_inode->i_links_count));
 
 	ext4_clear_state_flags(ei);	/* Only relevant on 32-bit archs */
@@ -4165,6 +4180,7 @@ static int ext4_do_update_inode(handle_t *handle,
 	int need_datasync = 0, set_large_file = 0;
 	uid_t i_uid;
 	gid_t i_gid;
+	projid_t i_projid;
 
 	spin_lock(&ei->i_raw_lock);
 
@@ -4177,6 +4193,7 @@ static int ext4_do_update_inode(handle_t *handle,
 	raw_inode->i_mode = cpu_to_le16(inode->i_mode);
 	i_uid = i_uid_read(inode);
 	i_gid = i_gid_read(inode);
+	i_projid = from_kprojid(&init_user_ns, ei->i_projid);
 	if (!(test_opt(inode->i_sb, NO_UID32))) {
 		raw_inode->i_uid_low = cpu_to_le16(low_16_bits(i_uid));
 		raw_inode->i_gid_low = cpu_to_le16(low_16_bits(i_gid));
@@ -4256,6 +4273,14 @@ static int ext4_do_update_inode(handle_t *handle,
 		}
 	}
 
+	BUG_ON(!EXT4_HAS_RO_COMPAT_FEATURE(inode->i_sb,
+			EXT4_FEATURE_RO_COMPAT_PROJECT) &&
+	       i_projid != EXT4_DEF_PROJID);
+
+	if (EXT4_INODE_SIZE(inode->i_sb) > EXT4_GOOD_OLD_INODE_SIZE &&
+	    EXT4_FITS_IN_INODE(raw_inode, ei, i_projid))
+		raw_inode->i_projid = cpu_to_le32(i_projid);
+
 	ext4_inode_csum_set(inode, raw_inode, ei);
 
 	spin_unlock(&ei->i_raw_lock);
diff --git a/fs/ext4/namei.c b/fs/ext4/namei.c
index 2291923..63a9623 100644
--- a/fs/ext4/namei.c
+++ b/fs/ext4/namei.c
@@ -2938,6 +2938,11 @@ static int ext4_link(struct dentry *old_dentry,
 	if (inode->i_nlink >= EXT4_LINK_MAX)
 		return -EMLINK;
 
+	if ((ext4_test_inode_flag(dir, EXT4_INODE_PROJINHERIT)) &&
+	    (!projid_eq(EXT4_I(dir)->i_projid,
+			EXT4_I(old_dentry->d_inode)->i_projid)))
+		return -EXDEV;
+
 	dquot_initialize(dir);
 
 retry:
@@ -3217,6 +3222,11 @@ static int ext4_rename(struct inode *old_dir, struct dentry *old_dentry,
 	int credits;
 	u8 old_file_type;
 
+	if ((ext4_test_inode_flag(new_dir, EXT4_INODE_PROJINHERIT)) &&
+	    (!projid_eq(EXT4_I(new_dir)->i_projid,
+			EXT4_I(old_dentry->d_inode)->i_projid)))
+		return -EXDEV;
+
 	dquot_initialize(old.dir);
 	dquot_initialize(new.dir);
 
@@ -3395,6 +3405,14 @@ static int ext4_cross_rename(struct inode *old_dir, struct dentry *old_dentry,
 	u8 new_file_type;
 	int retval;
 
+	if ((ext4_test_inode_flag(new_dir, EXT4_INODE_PROJINHERIT) &&
+	     !projid_eq(EXT4_I(new_dir)->i_projid,
+			EXT4_I(old_dentry->d_inode)->i_projid)) ||
+	    (ext4_test_inode_flag(old_dir, EXT4_INODE_PROJINHERIT) &&
+	     !projid_eq(EXT4_I(old_dir)->i_projid,
+			EXT4_I(new_dentry->d_inode)->i_projid)))
+		return -EXDEV;
+
 	dquot_initialize(old.dir);
 	dquot_initialize(new.dir);
 
diff --git a/fs/ext4/super.c b/fs/ext4/super.c
index bff3427..04c6cc3 100644
--- a/fs/ext4/super.c
+++ b/fs/ext4/super.c
@@ -1073,6 +1073,7 @@ static const struct dquot_operations ext4_quota_operations = {
 	.write_info	= ext4_write_info,
 	.alloc_dquot	= dquot_alloc,
 	.destroy_dquot	= dquot_destroy,
+	.get_projid	= ext4_get_projid,
 };
 
 static const struct quotactl_ops ext4_qctl_operations = {
diff --git a/include/uapi/linux/fs.h b/include/uapi/linux/fs.h
index 3735fa0..fcbf647 100644
--- a/include/uapi/linux/fs.h
+++ b/include/uapi/linux/fs.h
@@ -195,6 +195,7 @@ struct inodes_stat_t {
 #define FS_EXTENT_FL			0x00080000 /* Extents */
 #define FS_DIRECTIO_FL			0x00100000 /* Use direct i/o */
 #define FS_NOCOW_FL			0x00800000 /* Do not cow file */
+#define FS_PROJINHERIT_FL		0x20000000 /* Create with parents projid */
 #define FS_RESERVED_FL			0x80000000 /* reserved for ext2 lib */
 
 #define FS_FL_USER_VISIBLE		0x0003DFFF /* User visible flags */
-- 
1.7.1


^ permalink raw reply related

* [v13 1/5] vfs: adds general codes to enforces project quota limits
From: Li Xi @ 2015-04-20  1:39 UTC (permalink / raw)
  To: linux-fsdevel-u79uwXL29TY76Z2rM5mHXA,
	linux-ext4-u79uwXL29TY76Z2rM5mHXA,
	linux-api-u79uwXL29TY76Z2rM5mHXA, tytso-3s7WtUTddSA,
	adilger-m1MBpc4rdrD3fQ9qLvQP4Q, jack-AlSwsSmVLrQ,
	viro-RmSDqhL/yNMiFSDQTTA3OLVCufUGDwFn, hch-wEGCiKHe2LqWVfeAwA7xHQ,
	dmonakhov-GEFAQzZX7r8dnm+yROfE0A
In-Reply-To: <1429493988-16819-1-git-send-email-lixi-LfVdkaOWEx8@public.gmane.org>

This patch adds support for a new quota type PRJQUOTA for project quota
enforcement. Also a new method get_projid() is added into dquot_operations
structure.

Signed-off-by: Li Xi <lixi-LfVdkaOWEx8@public.gmane.org>
Signed-off-by: Dmitry Monakhov <dmonakhov-GEFAQzZX7r8dnm+yROfE0A@public.gmane.org>
Reviewed-by: Jan Kara <jack-AlSwsSmVLrQ@public.gmane.org>
---
 fs/quota/dquot.c           |   35 ++++++++++++++++++++++++++++++-----
 fs/quota/quota.c           |    5 ++++-
 fs/quota/quotaio_v2.h      |    6 ++++--
 include/linux/quota.h      |    2 ++
 include/uapi/linux/quota.h |    6 ++++--
 5 files changed, 44 insertions(+), 10 deletions(-)

diff --git a/fs/quota/dquot.c b/fs/quota/dquot.c
index 8f0acef..a02bb68 100644
--- a/fs/quota/dquot.c
+++ b/fs/quota/dquot.c
@@ -1159,8 +1159,8 @@ static int need_print_warning(struct dquot_warn *warn)
 			return uid_eq(current_fsuid(), warn->w_dq_id.uid);
 		case GRPQUOTA:
 			return in_group_p(warn->w_dq_id.gid);
-		case PRJQUOTA:	/* Never taken... Just make gcc happy */
-			return 0;
+		case PRJQUOTA:
+			return 1;
 	}
 	return 0;
 }
@@ -1399,6 +1399,9 @@ static void __dquot_initialize(struct inode *inode, int type)
 	/* First get references to structures we might need. */
 	for (cnt = 0; cnt < MAXQUOTAS; cnt++) {
 		struct kqid qid;
+		kprojid_t projid;
+		int rc;
+
 		got[cnt] = NULL;
 		if (type != -1 && cnt != type)
 			continue;
@@ -1409,6 +1412,10 @@ static void __dquot_initialize(struct inode *inode, int type)
 		 */
 		if (i_dquot(inode)[cnt])
 			continue;
+
+		if (!sb_has_quota_active(sb, cnt))
+			continue;
+
 		init_needed = 1;
 
 		switch (cnt) {
@@ -1418,6 +1425,12 @@ static void __dquot_initialize(struct inode *inode, int type)
 		case GRPQUOTA:
 			qid = make_kqid_gid(inode->i_gid);
 			break;
+		case PRJQUOTA:
+			rc = inode->i_sb->dq_op->get_projid(inode, &projid);
+			if (rc)
+				continue;
+			qid = make_kqid_projid(projid);
+			break;
 		}
 		got[cnt] = dqget(sb, qid);
 	}
@@ -2161,7 +2174,8 @@ static int vfs_load_quota_inode(struct inode *inode, int type, int format_id,
 		error = -EROFS;
 		goto out_fmt;
 	}
-	if (!sb->s_op->quota_write || !sb->s_op->quota_read) {
+	if (!sb->s_op->quota_write || !sb->s_op->quota_read ||
+	    (type == PRJQUOTA && sb->dq_op->get_projid == NULL)) {
 		error = -EINVAL;
 		goto out_fmt;
 	}
@@ -2402,8 +2416,19 @@ static void do_get_dqblk(struct dquot *dquot, struct fs_disk_quota *di)
 
 	memset(di, 0, sizeof(*di));
 	di->d_version = FS_DQUOT_VERSION;
-	di->d_flags = dquot->dq_id.type == USRQUOTA ?
-			FS_USER_QUOTA : FS_GROUP_QUOTA;
+	switch (dquot->dq_id.type) {
+	case USRQUOTA:
+		di->d_flags = FS_USER_QUOTA;
+		break;
+	case GRPQUOTA:
+		di->d_flags = FS_GROUP_QUOTA;
+		break;
+	case PRJQUOTA:
+		di->d_flags = FS_PROJ_QUOTA;
+		break;
+	default:
+		BUG();
+	}
 	di->d_id = from_kqid_munged(current_user_ns(), dquot->dq_id);
 
 	spin_lock(&dq_data_lock);
diff --git a/fs/quota/quota.c b/fs/quota/quota.c
index 2aa4151..33b30b1 100644
--- a/fs/quota/quota.c
+++ b/fs/quota/quota.c
@@ -30,7 +30,10 @@ static int check_quotactl_permission(struct super_block *sb, int type, int cmd,
 	case Q_XGETQSTATV:
 	case Q_XQUOTASYNC:
 		break;
-	/* allow to query information for dquots we "own" */
+	/*
+	 * allow to query information for dquots we "own"
+	 * always allow querying project quota
+	 */
 	case Q_GETQUOTA:
 	case Q_XGETQUOTA:
 		if ((type == USRQUOTA && uid_eq(current_euid(), make_kuid(current_user_ns(), id))) ||
diff --git a/fs/quota/quotaio_v2.h b/fs/quota/quotaio_v2.h
index f1966b4..4e95430 100644
--- a/fs/quota/quotaio_v2.h
+++ b/fs/quota/quotaio_v2.h
@@ -13,12 +13,14 @@
  */
 #define V2_INITQMAGICS {\
 	0xd9c01f11,	/* USRQUOTA */\
-	0xd9c01927	/* GRPQUOTA */\
+	0xd9c01927,	/* GRPQUOTA */\
+	0xd9c03f14,	/* PRJQUOTA */\
 }
 
 #define V2_INITQVERSIONS {\
 	1,		/* USRQUOTA */\
-	1		/* GRPQUOTA */\
+	1,		/* GRPQUOTA */\
+	1,		/* PRJQUOTA */\
 }
 
 /* First generic header */
diff --git a/include/linux/quota.h b/include/linux/quota.h
index 50978b7..ba51f7e 100644
--- a/include/linux/quota.h
+++ b/include/linux/quota.h
@@ -50,6 +50,7 @@
 
 #undef USRQUOTA
 #undef GRPQUOTA
+#undef PRJQUOTA
 enum quota_type {
 	USRQUOTA = 0,		/* element used for user quotas */
 	GRPQUOTA = 1,		/* element used for group quotas */
@@ -317,6 +318,7 @@ struct dquot_operations {
 	/* get reserved quota for delayed alloc, value returned is managed by
 	 * quota code only */
 	qsize_t *(*get_reserved_space) (struct inode *);
+	int (*get_projid) (struct inode *, kprojid_t *);/* Get project ID */
 };
 
 struct path;
diff --git a/include/uapi/linux/quota.h b/include/uapi/linux/quota.h
index 3b6cfbe..b2d9486 100644
--- a/include/uapi/linux/quota.h
+++ b/include/uapi/linux/quota.h
@@ -36,11 +36,12 @@
 #include <linux/errno.h>
 #include <linux/types.h>
 
-#define __DQUOT_VERSION__	"dquot_6.5.2"
+#define __DQUOT_VERSION__	"dquot_6.6.0"
 
-#define MAXQUOTAS 2
+#define MAXQUOTAS 3
 #define USRQUOTA  0		/* element used for user quotas */
 #define GRPQUOTA  1		/* element used for group quotas */
+#define PRJQUOTA  2		/* element used for project quotas */
 
 /*
  * Definitions for the default names of the quotas files.
@@ -48,6 +49,7 @@
 #define INITQFNAMES { \
 	"user",    /* USRQUOTA */ \
 	"group",   /* GRPQUOTA */ \
+	"project", /* PRJQUOTA */ \
 	"undefined", \
 };
 
-- 
1.7.1

^ permalink raw reply related

* [v13 0/5] ext4: add project quota support
From: Li Xi @ 2015-04-20  1:39 UTC (permalink / raw)
  To: linux-fsdevel-u79uwXL29TY76Z2rM5mHXA,
	linux-ext4-u79uwXL29TY76Z2rM5mHXA,
	linux-api-u79uwXL29TY76Z2rM5mHXA, tytso-3s7WtUTddSA,
	adilger-m1MBpc4rdrD3fQ9qLvQP4Q, jack-AlSwsSmVLrQ,
	viro-RmSDqhL/yNMiFSDQTTA3OLVCufUGDwFn, hch-wEGCiKHe2LqWVfeAwA7xHQ,
	dmonakhov-GEFAQzZX7r8dnm+yROfE0A

The following patches propose an implementation of project quota
support for ext4. A project is an aggregate of unrelated inodes
which might scatter in different directories. Inodes that belong
to the same project possess an identical identification i.e.
'project ID', just like every inode has its user/group
identification. The following patches add project quota as
supplement to the former uer/group quota types.

The semantics of ext4 project quota is consistent with XFS. Each
directory can have EXT4_INODE_PROJINHERIT flag set. When the
EXT4_INODE_PROJINHERIT flag of a parent directory is not set, a
newly created inode under that directory will have a default project
ID (i.e. 0). And its EXT4_INODE_PROJINHERIT flag is not set either.
When this flag is set on a directory, following rules will be kept:

1) The newly created inode under that directory will inherit both
the EXT4_INODE_PROJINHERIT flag and the project ID from its parent
directory.

2) Hard-linking a inode with different project ID into that directory
will fail with errno EXDEV.

3) Renaming a inode with different project ID into that directory
will fail with errno EXDEV. However, 'mv' command will detect this
failure and copy the renamed inode to a new inode in the directory.
Thus, this new inode will inherit both the project ID and
EXT4_INODE_PROJINHERIT flag.

4) If the project quota of that ID is being enforced, statfs() on
that directory will take the quotas as another upper limits along
with the capacity of the file system, i.e. the total block/inode
number will be the minimum of the quota limits and file system
capacity.

Changelog:
* v13 <- v12:
 - Update inode size check of project ID.
* v12 <- v11:
 - Relax the permission check when setting project ID.
* v11 <- v10:
 - Remove project quota mount option;
 - Fix permission check when setting project ID.
* v10 <- v9:
 - Remove non-journaled project quota interface;
 - Only allow admin to read project quota info;
 - Cleanup FS_IOC_FSSETXATTR/FS_IOC_FSGETXATTR interface.
* v9 <- v8:
 - Remove non-journaled project quota;
 - Rebase to newest dev branch of ext4 repository (3.19.0-rc3).
* v8 <- v7:
 - Rebase to newest dev branch of ext4 repository (3.18.0_rc3).
* v7 <- v6:
 - Map ext4 inode flags to xflags of struct fsxattr;
 - Add patch to cleanup ext4 inode flag definitions.
* v6 <- v5:
 - Add project ID check for cross rename;
 - Remove patch of EXT4_IOC_GETPROJECT/EXT4_IOC_SETPROJECT ioctl
* v5 <- v4:
 - Check project feature when set/get project ID;
 - Do not check project feature for project quota;
 - Add support of FS_IOC_FSSETXATTR/FS_IOC_FSGETXATTR.
* v4 <- v3:
 - Do not check project feature when set/get project ID;
 - Use EXT4_MAXQUOTAS instead of MAXQUOTAS in ext4 patches;
 - Remove unnecessary change of fs/quota/dquot.c;
 - Remove CONFIG_QUOTA_PROJECT.
* v3 <- v2:
 - Add EXT4_INODE_PROJINHERIT semantics.
* v2 <- v1:
 - Add ioctl interface for setting/getting project;
 - Add EXT4_FEATURE_RO_COMPAT_PROJECT;
 - Add get_projid() method in struct dquot_operations;
 - Add error check of ext4_inode_projid_set/get().

v12: http://www.spinics.net/lists/linux-fsdevel/msg84905.html
v11: http://www.spinics.net/lists/linux-ext4/msg47450.html
v10: http://www.spinics.net/lists/linux-ext4/msg47413.html
v9: http://www.spinics.net/lists/linux-ext4/msg47326.html
v8: http://www.spinics.net/lists/linux-ext4/msg46545.html
v7: http://www.spinics.net/lists/linux-fsdevel/msg80404.html
v6: http://www.spinics.net/lists/linux-fsdevel/msg80022.html
v5: http://www.spinics.net/lists/linux-api/msg04840.html
v4: http://lwn.net/Articles/612972/
v3: http://www.spinics.net/lists/linux-ext4/msg45184.html
v2: http://www.spinics.net/lists/linux-ext4/msg44695.html
v1: http://article.gmane.org/gmane.comp.file-systems.ext4/45153

Any comments or feedbacks are appreciated.

Regards,
                                         - Li Xi

Li Xi (5):
  vfs: adds general codes to enforces project quota limits
  ext4: adds project ID support
  ext4: adds project quota support
  ext4: adds FS_IOC_FSSETXATTR/FS_IOC_FSGETXATTR interface support
  ext4: cleanup inode flag definitions

 fs/ext4/ext4.h             |   86 +++++++----
 fs/ext4/ialloc.c           |    5 +
 fs/ext4/inode.c            |   25 +++
 fs/ext4/ioctl.c            |  364 +++++++++++++++++++++++++++++++++-----------
 fs/ext4/namei.c            |   18 +++
 fs/ext4/super.c            |   57 +++++++-
 fs/quota/dquot.c           |   35 ++++-
 fs/quota/quota.c           |    5 +-
 fs/quota/quotaio_v2.h      |    6 +-
 fs/xfs/xfs_fs.h            |   47 ++----
 include/linux/quota.h      |    2 +
 include/uapi/linux/fs.h    |   33 ++++
 include/uapi/linux/quota.h |    6 +-
 13 files changed, 526 insertions(+), 163 deletions(-)

^ permalink raw reply

* [PATCH] usb: core: add usb3 lpm sysfs
From: Zhuang Jin Can @ 2015-04-19  3:46 UTC (permalink / raw)
  To: gregkh, rafael.j.wysocki, stern, dan.j.williams, pmladek,
	peter.chen, jwerner, linux-api, linux-kernel, linux-usb

Some usb3 devices may not support usb3 lpm well.
The patch adds a sysfs to enable/disable u1 or u2 of the port.The
settings apply to both before and after device enumeration.
Supported values are "0" - u1 and u2 are disabled, "u1" - only u1 is
enabled, "u2" - only u2 is enabled, "u1_u2" - u1 and u2 are enabled.

The interface is useful for testing some USB3 devices during
development, and provides a way to disable usb3 lpm if the issues can
not be fixed in final products.

Signed-off-by: Zhuang Jin Can <jin.can.zhuang@intel.com>
---
 Documentation/ABI/testing/sysfs-bus-usb |   10 ++++
 drivers/usb/core/hub.c                  |   16 +++++-
 drivers/usb/core/hub.h                  |    4 ++
 drivers/usb/core/port.c                 |   89 ++++++++++++++++++++++++++++++-
 4 files changed, 116 insertions(+), 3 deletions(-)

diff --git a/Documentation/ABI/testing/sysfs-bus-usb b/Documentation/ABI/testing/sysfs-bus-usb
index e5cc763..32fc689 100644
--- a/Documentation/ABI/testing/sysfs-bus-usb
+++ b/Documentation/ABI/testing/sysfs-bus-usb
@@ -179,3 +179,13 @@ Description:
 		Supported values are 0 - 15.
 		More information on how besl values map to microseconds can be found in
 		USB 2.0 ECN Errata for Link Power Management, section 4.10)
+
+What:		/sys/bus/usb/devices/.../(hub interface)/portX/usb3_lpm
+Date:		March 2015
+Contact:	Zhuang Jin Can <jin.can.zhuang@intel.com>
+Description:
+		Some USB3.0 devices may not support usb3 lpm well.
+		usb3_lpm attribute allows enabling/disabling usb3 lpm of the port.
+		It takes effect both before and after a usb device is enumerated.
+		Supported values are "0" if u1 and u2 are disabled, "u1" if only u1 is
+		enabled, "u2" if only u2 is enabled, "u1_u2" if u1 and u2 are enabled.
diff --git a/drivers/usb/core/hub.c b/drivers/usb/core/hub.c
index d7c3d5a..7732a41 100644
--- a/drivers/usb/core/hub.c
+++ b/drivers/usb/core/hub.c
@@ -3996,6 +3996,8 @@ EXPORT_SYMBOL_GPL(usb_unlocked_disable_lpm);
 void usb_enable_lpm(struct usb_device *udev)
 {
 	struct usb_hcd *hcd;
+	struct usb_hub *hub;
+	struct usb_port *port_dev;
 
 	if (!udev || !udev->parent ||
 			udev->speed != USB_SPEED_SUPER ||
@@ -4015,8 +4017,18 @@ void usb_enable_lpm(struct usb_device *udev)
 	if (udev->lpm_disable_count > 0)
 		return;
 
-	usb_enable_link_state(hcd, udev, USB3_LPM_U1);
-	usb_enable_link_state(hcd, udev, USB3_LPM_U2);
+	hub = usb_hub_to_struct_hub(udev->parent);
+	if (!hub) {
+		dev_err(&udev->dev, "can't enable lpm, usb_hub is null.\n");
+		return;
+	}
+	port_dev = hub->ports[udev->portnum - 1];
+
+	if (port_dev->u1_is_enabled)
+		usb_enable_link_state(hcd, udev, USB3_LPM_U1);
+
+	if (port_dev->u2_is_enabled)
+		usb_enable_link_state(hcd, udev, USB3_LPM_U2);
 }
 EXPORT_SYMBOL_GPL(usb_enable_lpm);
 
diff --git a/drivers/usb/core/hub.h b/drivers/usb/core/hub.h
index 688817f..1ae060e 100644
--- a/drivers/usb/core/hub.h
+++ b/drivers/usb/core/hub.h
@@ -92,6 +92,8 @@ struct usb_hub {
  * @status_lock: synchronize port_event() vs usb_port_{suspend|resume}
  * @portnum: port index num based one
  * @is_superspeed cache super-speed status
+ * @u1_is_enabled: whether u1 should be enabled.
+ * @u2_is_enabled: whether u2 should be enabled.
  */
 struct usb_port {
 	struct usb_device *child;
@@ -104,6 +106,8 @@ struct usb_port {
 	struct mutex status_lock;
 	u8 portnum;
 	unsigned int is_superspeed:1;
+	unsigned int u1_is_enabled:1;
+	unsigned int u2_is_enabled:1;
 };
 
 #define to_usb_port(_dev) \
diff --git a/drivers/usb/core/port.c b/drivers/usb/core/port.c
index 2106183..7f4e6c7 100644
--- a/drivers/usb/core/port.c
+++ b/drivers/usb/core/port.c
@@ -50,6 +50,72 @@ static ssize_t connect_type_show(struct device *dev,
 }
 static DEVICE_ATTR_RO(connect_type);
 
+static ssize_t usb3_lpm_show(struct device *dev,
+			      struct device_attribute *attr, char *buf)
+{
+	struct usb_port *port_dev = to_usb_port(dev);
+	const char *p;
+
+	if (port_dev->u1_is_enabled) {
+		if (port_dev->u2_is_enabled)
+			p = "u1_u2";
+		else
+			p = "u1";
+	} else {
+		if (port_dev->u2_is_enabled)
+			p = "u2";
+		else
+			p = "0";
+	}
+
+	return sprintf(buf, "%s\n", p);
+}
+
+static ssize_t usb3_lpm_store(struct device *dev,
+			       struct device_attribute *attr,
+			       const char *buf, size_t count)
+{
+	struct usb_port *port_dev = to_usb_port(dev);
+	struct usb_device *udev = port_dev->child;
+	struct usb_hcd *hcd;
+
+	if (!strncmp(buf, "u1_u2", 5)) {
+		port_dev->u1_is_enabled = 1;
+		port_dev->u2_is_enabled = 1;
+
+	} else if (!strncmp(buf, "u1", 2)) {
+		port_dev->u1_is_enabled = 1;
+		port_dev->u2_is_enabled = 0;
+
+	} else if (!strncmp(buf, "u2", 2)) {
+		port_dev->u1_is_enabled = 0;
+		port_dev->u2_is_enabled = 1;
+
+	} else if (!strncmp(buf, "0", 1)) {
+		port_dev->u1_is_enabled = 0;
+		port_dev->u2_is_enabled = 0;
+	} else
+		return -EINVAL;
+
+	/* If device is connected to the port, disable & enable lpm
+	 * to make new u1 u2 setting take effect immediately
+	 */
+	if (udev) {
+		hcd = bus_to_hcd(udev->bus);
+		if (!hcd)
+			return -EINVAL;
+		usb_lock_device(udev);
+		mutex_lock(hcd->bandwidth_mutex);
+		if (!usb_disable_lpm(udev))
+			usb_enable_lpm(udev);
+		mutex_unlock(hcd->bandwidth_mutex);
+		usb_unlock_device(udev);
+	}
+
+	return count;
+}
+static DEVICE_ATTR_RW(usb3_lpm);
+
 static struct attribute *port_dev_attrs[] = {
 	&dev_attr_connect_type.attr,
 	NULL,
@@ -64,6 +130,21 @@ static const struct attribute_group *port_dev_group[] = {
 	NULL,
 };
 
+static struct attribute *port_dev_usb3_attrs[] = {
+	&dev_attr_usb3_lpm.attr,
+	NULL,
+};
+
+static struct attribute_group port_dev_usb3_attr_grp = {
+	.attrs = port_dev_usb3_attrs,
+};
+
+static const struct attribute_group *port_dev_usb3_group[] = {
+	&port_dev_attr_grp,
+	&port_dev_usb3_attr_grp,
+	NULL,
+};
+
 static void usb_port_device_release(struct device *dev)
 {
 	struct usb_port *port_dev = to_usb_port(dev);
@@ -401,6 +482,7 @@ static void find_and_link_peer(struct usb_hub *hub, int port1)
 int usb_hub_create_port_device(struct usb_hub *hub, int port1)
 {
 	struct usb_port *port_dev;
+	struct usb_device *hdev = hub->hdev;
 	int retval;
 
 	port_dev = kzalloc(sizeof(*port_dev), GFP_KERNEL);
@@ -417,7 +499,12 @@ int usb_hub_create_port_device(struct usb_hub *hub, int port1)
 	port_dev->portnum = port1;
 	set_bit(port1, hub->power_bits);
 	port_dev->dev.parent = hub->intfdev;
-	port_dev->dev.groups = port_dev_group;
+	if (hub_is_superspeed(hdev)) {
+		port_dev->u1_is_enabled = 1;
+		port_dev->u2_is_enabled = 1;
+		port_dev->dev.groups = port_dev_usb3_group;
+	} else
+		port_dev->dev.groups = port_dev_group;
 	port_dev->dev.type = &usb_port_device_type;
 	port_dev->dev.driver = &usb_port_driver;
 	if (hub_is_superspeed(hub->hdev))
-- 
1.7.9.5

^ permalink raw reply related

* Re: [PATCH/RFC 0/2] Repurpose the v4l2_plane data_offset field
From: Sakari Ailus @ 2015-04-18 13:04 UTC (permalink / raw)
  To: Hans Verkuil
  Cc: Laurent Pinchart, linux-media, linux-api, Sakari Ailus,
	Pawel Osciak, Marek Szyprowski, Mauro Carvalho Chehab
In-Reply-To: <5530E01D.3050105@xs4all.nl>

Hi Hans,

On Fri, Apr 17, 2015 at 12:27:41PM +0200, Hans Verkuil wrote:
> Hi Laurent,
> 
> On 04/14/2015 09:44 PM, Laurent Pinchart wrote:
> > Hello,
> > 
> > The v4l2_plane data_offset field has been introduced at the same time as the
> > the multiplane API to convey header size information between kernelspace and
> > userspace.
> > 
> > The API then became slightly controversial, both because different developers
> > understood the purpose of the field differently (resulting for instance in an
> > out-of-tree driver abusing the field for a different purpose), and because of
> > competing proposals (see for instance "[RFC] Multi format stream support" at
> > http://www.spinics.net/lists/linux-media/msg69130.html).
> > 
> > Furthermore, the data_offset field isn't used by any mainline driver except
> > vivid (for testing purpose).
> > 
> > I need a different data offset in planes to allow data capture to or data
> > output from a userspace-selected offset within a buffer (mainly for the
> > DMABUF and MMAP memory types). As the data_offset field already has the
> > right name, is unused, and ill-defined, I propose repurposing it. This is what
> > this RFC is about.
> > 
> > If the proposal is accepted I'll add another patch to update data_offset usage
> > in the vivid driver.
> 
> I am skeptical about all this for a variety of reasons:
> 
> 1) The data_offset field is well-defined in the spec. There really is no doubt
> about the meaning of the field.

I think that's debatable. :-) The specification doesn't say much what the
data_offset is really about. For instance, it does not specify what may be
in the buffer before data_offset.

The kerneldoc documentation next to struct v4l2_plane suggests there might
be a header, but that's primarily for driver developers rather than users.

I, for instance, understood data_offset to mean essentially how this set
"re-purposes" it. I wonder if there are others who have originally
understood it as such.

> 
> 2) We really don't know who else might be using it, or which applications might
> be using it (a lot of work was done in gstreamer recently, I wonder if data_offset
> support was implemented there).
> 
> 3) You offer no alternative to this feature. Basically this is my main objection.
> It is not at all unusual to have headers in front of the frame data. We (Cisco)
> use it in one of our product series for example. And I suspect it is something that
> happens especially in systems with an FPGA that does custom processing, and those
> systems are exactly the ones that are generally not upstreamed and so are not
> visible to us.

If you have a header before the image, the header probably has a format as
well. Some headers are device specific whereas some are more generic. The
SMIA standard, for example, does specify a metadata (header or footer!)
format.

It'd be useful to be able to tell the user what kind of header there is. For
that, the header could be located on a different plane, with a specific
format.

There's room for format information in struct v4l2_plane_pix_format but
hardly much else. It still would cover a number of potential use cases.

I might still consider making the planes independent of each other;
conveniently there's 8 bytes of free space in struct v4l2_pix_format_mplane
for alternative plane related information. It'd be nice to be able to do
this without an additional buffer type since that's visible in a large
number of other places: there's plenty of room in struct v4l2_plane for
any video buffer related information.

Frame descriptors are not needed for this --- you're quite right in that.
But the frame descriptors, when implemented, will very probably need plane
specific formats in the end as not many receivers are able to separate
different parts of the image to different buffers.

> 
> IMHO the functionality it provides is very much relevant, and I would like to see
> an alternative in place before it is repurposed.
> 
> But frankly, I really don't see why you would want to repurpose it. Adding a new
> field (buf_offset) would do exactly what you want it to do without causing an ABI
> change.

I said I ok with adding buf_offset field, but it might not be the best
choice we can make: it's a temporary solution for a very specific problem,
leaves the API with similar field names with different meanings (data_offset
vs. buf_offset, where the other is about the header and the other about the
data) and is not extensible. In addition, the size of the header is not
specified; it might be smaller than what's between buf_offset and
data_offset. Some devices produce footers as well; currently we have no way
to specify how they are dealt with.

I'd like to at least investigate if we could have something more
future-proof for this purpose.

-- 
Kind regards,

Sakari Ailus
e-mail: sakari.ailus@iki.fi	XMPP: sailus@retiisi.org.uk

^ permalink raw reply

* Re: [RFC 1/4] fs: Add generic file system event notifications
From: Andreas Dilger @ 2015-04-17 22:37 UTC (permalink / raw)
  To: John Spray
  Cc: Jan Kara, Austin S Hemmelgarn, Beata Michalska, LKML,
	Theodore Ts'o, Hugh Dickins, Lukáš Czerner,
	Christoph Hellwig, Ext4, linux-mm, kyungmin.park, kmpark,
	Linux Filesystem Mailing List, Linux API
In-Reply-To: <553144EB.9060701@redhat.com>

On Apr 17, 2015, at 11:37 AM, John Spray <john.spray@redhat.com> wrote:
> On 17/04/2015 17:22, Jan Kara wrote:
>> On Fri 17-04-15 17:08:10, John Spray wrote:
>>> On 17/04/2015 16:43, Jan Kara wrote:
>>> In that case I'm confused -- why would ENOSPC be an appropriate use
>>> of this interface if the mount being entirely blocked would be
>>> inappropriate?  Isn't being unable to service any I/O a more
>>> fundamental and severe thing than being up and healthy but full?
>>> 
>>> Were you intending the interface to be exclusively for data
>>> integrity issues like checksum failures, rather than more general
>>> events about a mount that userspace would probably like to know
>>> about?
>>   Well, I'm not saying we cannot have those events for fs availability /
>> inavailability. I'm just saying I'd like to see some use for that first.
>> I don't want events to be added just because it's possible...
>> 
>> For ENOSPC we have thin provisioned storage and the userspace deamon
>> shuffling real storage underneath. So there I know the usecase.
>> 
> 
> Ah, OK.  So I can think of a couple of use cases:
> * a cluster scheduling service (think MPI jobs or docker containers) might check for events like this.  If it can see the cluster filesystem is unavailable, then it can avoid scheduling the job, so that the (multi-node) application does not get hung on one node with a bad mount.  If it sees a mount go bad (unavailable, or client evicted) partway through a job, then it can kill -9 the process that was relying on the bad mount, and go run it somewhere else.
> * Boring but practical case: a nagios health check for checking if mounts are OK.

John,
thanks for chiming in, as I was just about to write the same.  Some users
were just asking yesterday at the Lustre User Group meeting about adding
an interface to notify job schedulers for your #1 point, and I'd much
rather use a generic interface than inventing our own for Lustre.

Cheers, Andreas

> We don't have to invent these event types now of course, but something to bear in mind.  Hopefully if/when any of the distributed filesystems (Lustre/Ceph/etc) choose to implement this, we can look at making the event types common at that time though.
> 
> BTW in any case an interface for filesystem events to userspace will be a useful addition, thank you!
> 
> Cheers,
> John


Cheers, Andreas





--
To unsubscribe, send a message with 'unsubscribe linux-mm' in
the body to majordomo@kvack.org.  For more info on Linux MM,
see: http://www.linux-mm.org/ .
Don't email: <a href=mailto:"dont@kvack.org"> email@kvack.org </a>

^ permalink raw reply

* Re: [PATCH V6 07/10] sched: add a macro to ref all CLONE_NEW* flags
From: Richard Guy Briggs @ 2015-04-17 22:00 UTC (permalink / raw)
  To: Peter Zijlstra
  Cc: linux-api-u79uwXL29TY76Z2rM5mHXA,
	containers-cunTk1MwBs9QetFLy7KEm3xJsTq8ys+cHZ5vskTnxNA,
	linux-kernel-u79uwXL29TY76Z2rM5mHXA,
	pmoore-H+wXaHxf7aLQT0dZR+AlfA, linux-audit-H+wXaHxf7aLQT0dZR+AlfA,
	eparis-FjpueFixGhCM4zKIHC2jIg, sgrubb-H+wXaHxf7aLQT0dZR+AlfA,
	zohar-23VcF4HTsmIX0ybBhKVfKdBPR1lH4CV8,
	mingo-H+wXaHxf7aLQT0dZR+AlfA, ebiederm-aS9lmoZGLiVWk0Htik3J/w
In-Reply-To: <20150417174131.GL23123-ndre7Fmf5hadTX5a5knrm8zTDFooKrT+cvkQGrU6aU0@public.gmane.org>

On 15/04/17, Peter Zijlstra wrote:
> On Fri, Apr 17, 2015 at 11:42:50AM -0400, Richard Guy Briggs wrote:
> > On 15/04/17, Peter Zijlstra wrote:
> > > On Fri, Apr 17, 2015 at 03:35:54AM -0400, Richard Guy Briggs wrote:
> > > > Added the macro CLONE_NEW_MASK_ALL to refer to all CLONE_NEW* flags.
> > > 
> > > A wee bit about why might be nice..
> > 
> > It makes the following patch much cleaner to read:
> > 	[PATCH V6 08/10] fork: audit on creation of new namespace(s)
> > 	https://lkml.org/lkml/2015/4/17/50
> > 
> > I was hoping it might also make a lot of other code cleaner, but most of
> > the other places where multiple CLONE_NEW* flags are used, not all six
> > are used together, but only 5 are used.  Ok, so it is helpful in 1 of 3:
> > 
> > It would actually be useful in check_unshare_flags():
> > 	https://github.com/torvalds/linux/blob/v3.17/kernel/fork.c#L1791
> > 
> > but not in copy_namespaces() or unshare_nsproxy_namespaces():
> > 	https://github.com/torvalds/linux/blob/v3.17/kernel/nsproxy.c#L130
> > 	https://github.com/torvalds/linux/blob/v3.17/kernel/nsproxy.c#L183
> 
> Right, so no objections from me on this, its just that I only saw this
> one patch in isolation without context and the changelog failed on
> rationale.

I realize you only saw a small window of this patchset, but this feels
like bike shedding about the main objective of the set...

I'll add a bit more justification and context if/when I respin for the
rest of the set.

> Does it perchance make sense to fold this patch into the next patch that
> actually makes use of it?

It would if it were the only potential user.  I don't want to bury a
surprise in something bigger.  Is there a preferred way to use such a
macro to make the other three examples cleaner, or is that just useless
churn and obfuscation?  Would there be a concise way to express all
CLONE_NEW* flags *except* user?

- RGB

--
Richard Guy Briggs <rbriggs-H+wXaHxf7aLQT0dZR+AlfA@public.gmane.org>
Senior Software Engineer, Kernel Security, AMER ENG Base Operating Systems, Red Hat
Remote, Ottawa, Canada
Voice: +1.647.777.2635, Internal: (81) 32635, Alt: +1.613.693.0684x3545

^ permalink raw reply

* Re: [PATCH V6 07/10] sched: add a macro to ref all CLONE_NEW* flags
From: Peter Zijlstra @ 2015-04-17 17:41 UTC (permalink / raw)
  To: Richard Guy Briggs
  Cc: linux-api-u79uwXL29TY76Z2rM5mHXA,
	containers-cunTk1MwBs9QetFLy7KEm3xJsTq8ys+cHZ5vskTnxNA,
	linux-kernel-u79uwXL29TY76Z2rM5mHXA,
	pmoore-H+wXaHxf7aLQT0dZR+AlfA, linux-audit-H+wXaHxf7aLQT0dZR+AlfA,
	eparis-FjpueFixGhCM4zKIHC2jIg, sgrubb-H+wXaHxf7aLQT0dZR+AlfA,
	zohar-23VcF4HTsmIX0ybBhKVfKdBPR1lH4CV8,
	mingo-H+wXaHxf7aLQT0dZR+AlfA, ebiederm-aS9lmoZGLiVWk0Htik3J/w
In-Reply-To: <20150417154250.GA26233-bcJWsdo4jJjeVoXN4CMphl7TgLCtbB0G@public.gmane.org>

On Fri, Apr 17, 2015 at 11:42:50AM -0400, Richard Guy Briggs wrote:
> On 15/04/17, Peter Zijlstra wrote:
> > On Fri, Apr 17, 2015 at 03:35:54AM -0400, Richard Guy Briggs wrote:
> > > Added the macro CLONE_NEW_MASK_ALL to refer to all CLONE_NEW* flags.
> > 
> > A wee bit about why might be nice..
> 
> It makes the following patch much cleaner to read:
> 	[PATCH V6 08/10] fork: audit on creation of new namespace(s)
> 	https://lkml.org/lkml/2015/4/17/50
> 
> I was hoping it might also make a lot of other code cleaner, but most of
> the other places where multiple CLONE_NEW* flags are used, not all six
> are used together, but only 5 are used.  Ok, so it is helpful in 1 of 3:
> 
> It would actually be useful in check_unshare_flags():
> 	https://github.com/torvalds/linux/blob/v3.17/kernel/fork.c#L1791
> 
> but not in copy_namespaces() or unshare_nsproxy_namespaces():
> 	https://github.com/torvalds/linux/blob/v3.17/kernel/nsproxy.c#L130
> 	https://github.com/torvalds/linux/blob/v3.17/kernel/nsproxy.c#L183
> 

Right, so no objections from me on this, its just that I only saw this
one patch in isolation without context and the changelog failed on
rationale.

Does it perchance make sense to fold this patch into the next patch that
actually makes use of it?

^ permalink raw reply

* Re: [RFC 1/4] fs: Add generic file system event notifications
From: John Spray @ 2015-04-17 17:37 UTC (permalink / raw)
  To: Jan Kara
  Cc: Austin S Hemmelgarn, Beata Michalska, linux-kernel, tytso,
	adilger.kernel, hughd, lczerner, hch, linux-ext4, linux-mm,
	kyungmin.park, kmpark, Linux Filesystem Mailing List, linux-api
In-Reply-To: <20150417162247.GB27500@quack.suse.cz>



On 17/04/2015 17:22, Jan Kara wrote:
> On Fri 17-04-15 17:08:10, John Spray wrote:
>> On 17/04/2015 16:43, Jan Kara wrote:
>> In that case I'm confused -- why would ENOSPC be an appropriate use
>> of this interface if the mount being entirely blocked would be
>> inappropriate?  Isn't being unable to service any I/O a more
>> fundamental and severe thing than being up and healthy but full?
>>
>> Were you intending the interface to be exclusively for data
>> integrity issues like checksum failures, rather than more general
>> events about a mount that userspace would probably like to know
>> about?
>    Well, I'm not saying we cannot have those events for fs availability /
> inavailability. I'm just saying I'd like to see some use for that first.
> I don't want events to be added just because it's possible...
>
> For ENOSPC we have thin provisioned storage and the userspace deamon
> shuffling real storage underneath. So there I know the usecase.
>

Ah, OK.  So I can think of a couple of use cases:
  * a cluster scheduling service (think MPI jobs or docker containers) 
might check for events like this.  If it can see the cluster filesystem 
is unavailable, then it can avoid scheduling the job, so that the 
(multi-node) application does not get hung on one node with a bad 
mount.  If it sees a mount go bad (unavailable, or client evicted) 
partway through a job, then it can kill -9 the process that was relying 
on the bad mount, and go run it somewhere else.
  * Boring but practical case: a nagios health check for checking if 
mounts are OK.

We don't have to invent these event types now of course, but something 
to bear in mind.  Hopefully if/when any of the distributed filesystems 
(Lustre/Ceph/etc) choose to implement this, we can look at making the 
event types common at that time though.

BTW in any case an interface for filesystem events to userspace will be 
a useful addition, thank you!

Cheers,
John

--
To unsubscribe, send a message with 'unsubscribe linux-mm' in
the body to majordomo@kvack.org.  For more info on Linux MM,
see: http://www.linux-mm.org/ .
Don't email: <a href=mailto:"dont@kvack.org"> email@kvack.org </a>

^ permalink raw reply

* Re: [RFC 1/4] fs: Add generic file system event notifications
From: Jan Kara @ 2015-04-17 16:39 UTC (permalink / raw)
  To: Austin S Hemmelgarn
  Cc: Jan Kara, John Spray, Beata Michalska,
	linux-kernel-u79uwXL29TY76Z2rM5mHXA, tytso-3s7WtUTddSA,
	adilger.kernel-m1MBpc4rdrD3fQ9qLvQP4Q,
	hughd-hpIqsD4AKlfQT0dZR+AlfA, lczerner-H+wXaHxf7aLQT0dZR+AlfA,
	hch-wEGCiKHe2LqWVfeAwA7xHQ, linux-ext4-u79uwXL29TY76Z2rM5mHXA,
	linux-mm-Bw31MaZKKs3YtjvyW6yDsg,
	kyungmin.park-Sze3O3UU22JBDgjK7y7TUQ,
	kmpark-wEGCiKHe2LqWVfeAwA7xHQ, Linux Filesystem Mailing List,
	linux-api-u79uwXL29TY76Z2rM5mHXA
In-Reply-To: <553134D3.9040001-Re5JQEeQqe8AvxtiuMwx3w@public.gmane.org>

On Fri 17-04-15 12:29:07, Austin S Hemmelgarn wrote:
> On 2015-04-17 12:22, Jan Kara wrote:
> >On Fri 17-04-15 17:08:10, John Spray wrote:
> >>
> >>On 17/04/2015 16:43, Jan Kara wrote:
> >>>On Fri 17-04-15 15:51:14, John Spray wrote:
> >>>>On 17/04/2015 14:23, Austin S Hemmelgarn wrote:
> >>>>
> >>>>>For some filesystems, it may make sense to differentiate between a
> >>>>>generic warning and an error.  For BTRFS and ZFS for example, if
> >>>>>there is a csum error on a block, this will get automatically
> >>>>>corrected in many configurations, and won't require anything like
> >>>>>fsck to be run, but monitoring applications will still probably
> >>>>>want to be notified.
> >>>>Another key differentiation IMHO is between transient errors (like
> >>>>server is unavailable in a distributed filesystem) that will block
> >>>>the filesystem but might clear on their own, vs. permanent errors
> >>>>like unreadable drives that definitely will not clear until the
> >>>>administrator takes some action.  It's usually a reasonable
> >>>>approximation to call transient issues warnings, and permanent
> >>>>issues errors.
> >>>   So you can have events like FS_UNAVAILABLE and FS_AVAILABLE but what use
> >>>would this have? I wouldn't like the interface to be dumping ground for
> >>>random crap - we have dmesg for that :).
> >>In that case I'm confused -- why would ENOSPC be an appropriate use
> >>of this interface if the mount being entirely blocked would be
> >>inappropriate?  Isn't being unable to service any I/O a more
> >>fundamental and severe thing than being up and healthy but full?
> >>
> >>Were you intending the interface to be exclusively for data
> >>integrity issues like checksum failures, rather than more general
> >>events about a mount that userspace would probably like to know
> >>about?
> >   Well, I'm not saying we cannot have those events for fs availability /
> >inavailability. I'm just saying I'd like to see some use for that first.
> >I don't want events to be added just because it's possible...
> >
> >For ENOSPC we have thin provisioned storage and the userspace deamon
> >shuffling real storage underneath. So there I know the usecase.
> >
> The use-case that immediately comes to mind for me would be diskless
> nodes with root-on-nfs needing to know if they can actually access
> the root filesystem.
  Well, most apps will access the root file system regardless of what we
send over netlink... So I don't see netlink events improving the situation
there too much. You could try to use it for something like failover but
even there I'm not too convinced - just doing some IO, waiting for timeout,
and failing over if IO doesn't complete works just fine for that these
days. That's why I was asking because I didn't see convincing usecase
myself...

								Honza
-- 
Jan Kara <jack-AlSwsSmVLrQ@public.gmane.org>
SUSE Labs, CR

^ permalink raw reply

* Re: [RFC 1/4] fs: Add generic file system event notifications
From: Austin S Hemmelgarn @ 2015-04-17 16:29 UTC (permalink / raw)
  To: Jan Kara, John Spray
  Cc: Beata Michalska, linux-kernel, tytso, adilger.kernel, hughd,
	lczerner, hch, linux-ext4, linux-mm, kyungmin.park, kmpark,
	Linux Filesystem Mailing List, linux-api
In-Reply-To: <20150417162247.GB27500@quack.suse.cz>

[-- Attachment #1: Type: text/plain, Size: 2311 bytes --]

On 2015-04-17 12:22, Jan Kara wrote:
> On Fri 17-04-15 17:08:10, John Spray wrote:
>>
>> On 17/04/2015 16:43, Jan Kara wrote:
>>> On Fri 17-04-15 15:51:14, John Spray wrote:
>>>> On 17/04/2015 14:23, Austin S Hemmelgarn wrote:
>>>>
>>>>> For some filesystems, it may make sense to differentiate between a
>>>>> generic warning and an error.  For BTRFS and ZFS for example, if
>>>>> there is a csum error on a block, this will get automatically
>>>>> corrected in many configurations, and won't require anything like
>>>>> fsck to be run, but monitoring applications will still probably
>>>>> want to be notified.
>>>> Another key differentiation IMHO is between transient errors (like
>>>> server is unavailable in a distributed filesystem) that will block
>>>> the filesystem but might clear on their own, vs. permanent errors
>>>> like unreadable drives that definitely will not clear until the
>>>> administrator takes some action.  It's usually a reasonable
>>>> approximation to call transient issues warnings, and permanent
>>>> issues errors.
>>>    So you can have events like FS_UNAVAILABLE and FS_AVAILABLE but what use
>>> would this have? I wouldn't like the interface to be dumping ground for
>>> random crap - we have dmesg for that :).
>> In that case I'm confused -- why would ENOSPC be an appropriate use
>> of this interface if the mount being entirely blocked would be
>> inappropriate?  Isn't being unable to service any I/O a more
>> fundamental and severe thing than being up and healthy but full?
>>
>> Were you intending the interface to be exclusively for data
>> integrity issues like checksum failures, rather than more general
>> events about a mount that userspace would probably like to know
>> about?
>    Well, I'm not saying we cannot have those events for fs availability /
> inavailability. I'm just saying I'd like to see some use for that first.
> I don't want events to be added just because it's possible...
>
> For ENOSPC we have thin provisioned storage and the userspace deamon
> shuffling real storage underneath. So there I know the usecase.
>
> 								Honza
>
The use-case that immediately comes to mind for me would be diskless 
nodes with root-on-nfs needing to know if they can actually access the 
root filesystem.


[-- Attachment #2: S/MIME Cryptographic Signature --]
[-- Type: application/pkcs7-signature, Size: 2967 bytes --]

^ permalink raw reply

* Re: [RFC 1/4] fs: Add generic file system event notifications
From: Beata Michalska @ 2015-04-17 16:25 UTC (permalink / raw)
  To: John Spray
  Cc: Jan Kara, Austin S Hemmelgarn,
	linux-kernel-u79uwXL29TY76Z2rM5mHXA, tytso-3s7WtUTddSA,
	adilger.kernel-m1MBpc4rdrD3fQ9qLvQP4Q,
	hughd-hpIqsD4AKlfQT0dZR+AlfA, lczerner-H+wXaHxf7aLQT0dZR+AlfA,
	hch-wEGCiKHe2LqWVfeAwA7xHQ, linux-ext4-u79uwXL29TY76Z2rM5mHXA,
	linux-mm-Bw31MaZKKs3YtjvyW6yDsg,
	kyungmin.park-Sze3O3UU22JBDgjK7y7TUQ,
	kmpark-wEGCiKHe2LqWVfeAwA7xHQ, Linux Filesystem Mailing List,
	linux-api-u79uwXL29TY76Z2rM5mHXA
In-Reply-To: <55312FEA.3030905-H+wXaHxf7aLQT0dZR+AlfA@public.gmane.org>

On 04/17/2015 06:08 PM, John Spray wrote:
> 
> On 17/04/2015 16:43, Jan Kara wrote:
>> On Fri 17-04-15 15:51:14, John Spray wrote:
>>> On 17/04/2015 14:23, Austin S Hemmelgarn wrote:
>>>
>>>> For some filesystems, it may make sense to differentiate between a
>>>> generic warning and an error.  For BTRFS and ZFS for example, if
>>>> there is a csum error on a block, this will get automatically
>>>> corrected in many configurations, and won't require anything like
>>>> fsck to be run, but monitoring applications will still probably
>>>> want to be notified.
>>> Another key differentiation IMHO is between transient errors (like
>>> server is unavailable in a distributed filesystem) that will block
>>> the filesystem but might clear on their own, vs. permanent errors
>>> like unreadable drives that definitely will not clear until the
>>> administrator takes some action.  It's usually a reasonable
>>> approximation to call transient issues warnings, and permanent
>>> issues errors.
>>    So you can have events like FS_UNAVAILABLE and FS_AVAILABLE but what use
>> would this have? I wouldn't like the interface to be dumping ground for
>> random crap - we have dmesg for that :).
> In that case I'm confused -- why would ENOSPC be an appropriate use of this interface if the mount being entirely blocked would be inappropriate?  Isn't being unable to service any I/O a more fundamental and severe thing than being up and healthy but full?
> 
> Were you intending the interface to be exclusively for data integrity issues like checksum failures, rather than more general events about a mount that userspace would probably like to know about?
> 
> John
> 

I think we should support both and leave the decision on what
is to be reported or not to particular file systems keeping it
to a reasonable extent, of course. The interface should hand it over
to user space - acting as a go-between. I would though avoid
any filesystem specific events (when it comes to specifying those),
keeping it as generic as possible.


BR
Beata

^ permalink raw reply

* Re: [RFC 1/4] fs: Add generic file system event notifications
From: Jan Kara @ 2015-04-17 16:22 UTC (permalink / raw)
  To: John Spray
  Cc: Jan Kara, Austin S Hemmelgarn, Beata Michalska,
	linux-kernel-u79uwXL29TY76Z2rM5mHXA, tytso-3s7WtUTddSA,
	adilger.kernel-m1MBpc4rdrD3fQ9qLvQP4Q,
	hughd-hpIqsD4AKlfQT0dZR+AlfA, lczerner-H+wXaHxf7aLQT0dZR+AlfA,
	hch-wEGCiKHe2LqWVfeAwA7xHQ, linux-ext4-u79uwXL29TY76Z2rM5mHXA,
	linux-mm-Bw31MaZKKs3YtjvyW6yDsg,
	kyungmin.park-Sze3O3UU22JBDgjK7y7TUQ,
	kmpark-wEGCiKHe2LqWVfeAwA7xHQ, Linux Filesystem Mailing List,
	linux-api-u79uwXL29TY76Z2rM5mHXA
In-Reply-To: <55312FEA.3030905-H+wXaHxf7aLQT0dZR+AlfA@public.gmane.org>

On Fri 17-04-15 17:08:10, John Spray wrote:
> 
> On 17/04/2015 16:43, Jan Kara wrote:
> >On Fri 17-04-15 15:51:14, John Spray wrote:
> >>On 17/04/2015 14:23, Austin S Hemmelgarn wrote:
> >>
> >>>For some filesystems, it may make sense to differentiate between a
> >>>generic warning and an error.  For BTRFS and ZFS for example, if
> >>>there is a csum error on a block, this will get automatically
> >>>corrected in many configurations, and won't require anything like
> >>>fsck to be run, but monitoring applications will still probably
> >>>want to be notified.
> >>Another key differentiation IMHO is between transient errors (like
> >>server is unavailable in a distributed filesystem) that will block
> >>the filesystem but might clear on their own, vs. permanent errors
> >>like unreadable drives that definitely will not clear until the
> >>administrator takes some action.  It's usually a reasonable
> >>approximation to call transient issues warnings, and permanent
> >>issues errors.
> >   So you can have events like FS_UNAVAILABLE and FS_AVAILABLE but what use
> >would this have? I wouldn't like the interface to be dumping ground for
> >random crap - we have dmesg for that :).
> In that case I'm confused -- why would ENOSPC be an appropriate use
> of this interface if the mount being entirely blocked would be
> inappropriate?  Isn't being unable to service any I/O a more
> fundamental and severe thing than being up and healthy but full?
> 
> Were you intending the interface to be exclusively for data
> integrity issues like checksum failures, rather than more general
> events about a mount that userspace would probably like to know
> about?
  Well, I'm not saying we cannot have those events for fs availability /
inavailability. I'm just saying I'd like to see some use for that first.
I don't want events to be added just because it's possible...

For ENOSPC we have thin provisioned storage and the userspace deamon
shuffling real storage underneath. So there I know the usecase.

								Honza
-- 
Jan Kara <jack-AlSwsSmVLrQ@public.gmane.org>
SUSE Labs, CR

^ permalink raw reply

* Re: [RFC 1/4] fs: Add generic file system event notifications
From: John Spray @ 2015-04-17 16:08 UTC (permalink / raw)
  To: Jan Kara
  Cc: Austin S Hemmelgarn, Beata Michalska,
	linux-kernel-u79uwXL29TY76Z2rM5mHXA, tytso-3s7WtUTddSA,
	adilger.kernel-m1MBpc4rdrD3fQ9qLvQP4Q,
	hughd-hpIqsD4AKlfQT0dZR+AlfA, lczerner-H+wXaHxf7aLQT0dZR+AlfA,
	hch-wEGCiKHe2LqWVfeAwA7xHQ, linux-ext4-u79uwXL29TY76Z2rM5mHXA,
	linux-mm-Bw31MaZKKs3YtjvyW6yDsg,
	kyungmin.park-Sze3O3UU22JBDgjK7y7TUQ,
	kmpark-wEGCiKHe2LqWVfeAwA7xHQ, Linux Filesystem Mailing List,
	linux-api-u79uwXL29TY76Z2rM5mHXA
In-Reply-To: <20150417154351.GA26736-+0h/O2h83AeN3ZZ/Hiejyg@public.gmane.org>


On 17/04/2015 16:43, Jan Kara wrote:
> On Fri 17-04-15 15:51:14, John Spray wrote:
>> On 17/04/2015 14:23, Austin S Hemmelgarn wrote:
>>
>>> For some filesystems, it may make sense to differentiate between a
>>> generic warning and an error.  For BTRFS and ZFS for example, if
>>> there is a csum error on a block, this will get automatically
>>> corrected in many configurations, and won't require anything like
>>> fsck to be run, but monitoring applications will still probably
>>> want to be notified.
>> Another key differentiation IMHO is between transient errors (like
>> server is unavailable in a distributed filesystem) that will block
>> the filesystem but might clear on their own, vs. permanent errors
>> like unreadable drives that definitely will not clear until the
>> administrator takes some action.  It's usually a reasonable
>> approximation to call transient issues warnings, and permanent
>> issues errors.
>    So you can have events like FS_UNAVAILABLE and FS_AVAILABLE but what use
> would this have? I wouldn't like the interface to be dumping ground for
> random crap - we have dmesg for that :).
In that case I'm confused -- why would ENOSPC be an appropriate use of 
this interface if the mount being entirely blocked would be 
inappropriate?  Isn't being unable to service any I/O a more fundamental 
and severe thing than being up and healthy but full?

Were you intending the interface to be exclusively for data integrity 
issues like checksum failures, rather than more general events about a 
mount that userspace would probably like to know about?

John

^ permalink raw reply

* Re: [RFC 1/4] fs: Add generic file system event notifications
From: Jan Kara @ 2015-04-17 15:43 UTC (permalink / raw)
  To: John Spray
  Cc: Austin S Hemmelgarn, Beata Michalska, Jan Kara, linux-kernel,
	tytso, adilger.kernel, hughd, lczerner, hch, linux-ext4, linux-mm,
	kyungmin.park, kmpark, Linux Filesystem Mailing List, linux-api
In-Reply-To: <55311DE2.9000901@redhat.com>

On Fri 17-04-15 15:51:14, John Spray wrote:
> On 17/04/2015 14:23, Austin S Hemmelgarn wrote:
> >On 2015-04-17 09:04, Beata Michalska wrote:
> >>On 04/17/2015 01:31 PM, Jan Kara wrote:
> >>>On Wed 15-04-15 09:15:44, Beata Michalska wrote:
> >>>...
> >>>>+static const match_table_t fs_etypes = {
> >>>>+    { FS_EVENT_INFO,    "info"  },
> >>>>+    { FS_EVENT_WARN,    "warn"  },
> >>>>+    { FS_EVENT_THRESH,  "thr"   },
> >>>>+    { FS_EVENT_ERR,     "err"   },
> >>>>+    { 0, NULL },
> >>>>+};
> >>>   Why are there these generic message types? Threshold
> >>>messages make good
> >>>sense to me. But not so much the rest. If they don't have a
> >>>clear meaning,
> >>>it will be a mess. So I also agree with a message like -
> >>>"filesystem has
> >>>trouble, you should probably unmount and run fsck" - that's fine. But
> >>>generic "info" or "warning" doesn't really carry any meaning
> >>>on its own and
> >>>thus seems pretty useless to me. To explain a bit more, AFAIU this
> >>>shouldn't be a generic logging interface where something like severity
> >>>makes sense but rather a relatively specific interface notifying about
> >>>events in filesystem userspace should know about so I expect
> >>>relatively low
> >>>number of types of events, not tens or even hundreds...
> >>>
> >>>                                Honza
> >>
> >>Getting rid of those would simplify the configuration part, indeed.
> >>So we would be left with 'generic' and threshold events.
> >>I guess I've overdone this part.
> >
> >For some filesystems, it may make sense to differentiate between a
> >generic warning and an error.  For BTRFS and ZFS for example, if
> >there is a csum error on a block, this will get automatically
> >corrected in many configurations, and won't require anything like
> >fsck to be run, but monitoring applications will still probably
> >want to be notified.
> 
> Another key differentiation IMHO is between transient errors (like
> server is unavailable in a distributed filesystem) that will block
> the filesystem but might clear on their own, vs. permanent errors
> like unreadable drives that definitely will not clear until the
> administrator takes some action.  It's usually a reasonable
> approximation to call transient issues warnings, and permanent
> issues errors.
  So you can have events like FS_UNAVAILABLE and FS_AVAILABLE but what use
would this have? I wouldn't like the interface to be dumping ground for
random crap - we have dmesg for that :).

								Honza
-- 
Jan Kara <jack@suse.cz>
SUSE Labs, CR

--
To unsubscribe, send a message with 'unsubscribe linux-mm' in
the body to majordomo@kvack.org.  For more info on Linux MM,
see: http://www.linux-mm.org/ .
Don't email: <a href=mailto:"dont@kvack.org"> email@kvack.org </a>

^ permalink raw reply

* Re: [PATCH V6 07/10] sched: add a macro to ref all CLONE_NEW* flags
From: Richard Guy Briggs @ 2015-04-17 15:42 UTC (permalink / raw)
  To: Peter Zijlstra
  Cc: containers, linux-kernel, linux-audit, sgrubb, eparis, pmoore,
	arozansk, ebiederm, serge, zohar, linux-api, mingo
In-Reply-To: <20150417081843.GE23123@twins.programming.kicks-ass.net>

On 15/04/17, Peter Zijlstra wrote:
> On Fri, Apr 17, 2015 at 03:35:54AM -0400, Richard Guy Briggs wrote:
> > Added the macro CLONE_NEW_MASK_ALL to refer to all CLONE_NEW* flags.
> 
> A wee bit about why might be nice..

It makes the following patch much cleaner to read:
	[PATCH V6 08/10] fork: audit on creation of new namespace(s)
	https://lkml.org/lkml/2015/4/17/50

I was hoping it might also make a lot of other code cleaner, but most of
the other places where multiple CLONE_NEW* flags are used, not all six
are used together, but only 5 are used.  Ok, so it is helpful in 1 of 3:

It would actually be useful in check_unshare_flags():
	https://github.com/torvalds/linux/blob/v3.17/kernel/fork.c#L1791

but not in copy_namespaces() or unshare_nsproxy_namespaces():
	https://github.com/torvalds/linux/blob/v3.17/kernel/nsproxy.c#L130
	https://github.com/torvalds/linux/blob/v3.17/kernel/nsproxy.c#L183

- RGB

--
Richard Guy Briggs <rbriggs@redhat.com>
Senior Software Engineer, Kernel Security, AMER ENG Base Operating Systems, Red Hat
Remote, Ottawa, Canada
Voice: +1.647.777.2635, Internal: (81) 32635, Alt: +1.613.693.0684x3545

^ permalink raw reply

* Re: [RFC 1/4] fs: Add generic file system event notifications
From: John Spray @ 2015-04-17 14:51 UTC (permalink / raw)
  To: Austin S Hemmelgarn, Beata Michalska, Jan Kara
  Cc: linux-kernel, tytso, adilger.kernel, hughd, lczerner, hch,
	linux-ext4, linux-mm, kyungmin.park, kmpark,
	Linux Filesystem Mailing List, linux-api
In-Reply-To: <55310957.3070101@gmail.com>

On 17/04/2015 14:23, Austin S Hemmelgarn wrote:
> On 2015-04-17 09:04, Beata Michalska wrote:
>> On 04/17/2015 01:31 PM, Jan Kara wrote:
>>> On Wed 15-04-15 09:15:44, Beata Michalska wrote:
>>> ...
>>>> +static const match_table_t fs_etypes = {
>>>> +    { FS_EVENT_INFO,    "info"  },
>>>> +    { FS_EVENT_WARN,    "warn"  },
>>>> +    { FS_EVENT_THRESH,  "thr"   },
>>>> +    { FS_EVENT_ERR,     "err"   },
>>>> +    { 0, NULL },
>>>> +};
>>>    Why are there these generic message types? Threshold messages 
>>> make good
>>> sense to me. But not so much the rest. If they don't have a clear 
>>> meaning,
>>> it will be a mess. So I also agree with a message like - "filesystem 
>>> has
>>> trouble, you should probably unmount and run fsck" - that's fine. But
>>> generic "info" or "warning" doesn't really carry any meaning on its 
>>> own and
>>> thus seems pretty useless to me. To explain a bit more, AFAIU this
>>> shouldn't be a generic logging interface where something like severity
>>> makes sense but rather a relatively specific interface notifying about
>>> events in filesystem userspace should know about so I expect 
>>> relatively low
>>> number of types of events, not tens or even hundreds...
>>>
>>>                                 Honza
>>
>> Getting rid of those would simplify the configuration part, indeed.
>> So we would be left with 'generic' and threshold events.
>> I guess I've overdone this part.
>
> For some filesystems, it may make sense to differentiate between a 
> generic warning and an error.  For BTRFS and ZFS for example, if there 
> is a csum error on a block, this will get automatically corrected in 
> many configurations, and won't require anything like fsck to be run, 
> but monitoring applications will still probably want to be notified.

Another key differentiation IMHO is between transient errors (like 
server is unavailable in a distributed filesystem) that will block the 
filesystem but might clear on their own, vs. permanent errors like 
unreadable drives that definitely will not clear until the administrator 
takes some action.  It's usually a reasonable approximation to call 
transient issues warnings, and permanent issues errors.

John




--
To unsubscribe, send a message with 'unsubscribe linux-mm' in
the body to majordomo@kvack.org.  For more info on Linux MM,
see: http://www.linux-mm.org/ .
Don't email: <a href=mailto:"dont@kvack.org"> email@kvack.org </a>

^ permalink raw reply

* Re: [dmidecode] [Patch 1/3] firmware: dmi_scan: rename dmi_table to dmi_decode_table
From: Jean Delvare @ 2015-04-17 14:12 UTC (permalink / raw)
  To: Matt Fleming
  Cc: dmidecode-devel, matt.fleming, ard.biesheuvel, linux-api,
	linux-doc, linux-kernel, leif.lindholm, mikew, roy.franz,
	Ivan Khoronzhuk, msalter, grant.likely
In-Reply-To: <20150417134036.GA3671@codeblueprint.co.uk>

Hi Matt,

Le Friday 17 April 2015 à 14:40 +0100, Matt Fleming a écrit :
> On Thu, 16 Apr, at 10:35:11AM, Jean Delvare wrote:
> > 
> > I don't really care who picks these patches up and sends them to Linus,
> > but I think they should all follow the same route so that Linus has as
> > little merge work to do as possible. So either you pick them all, or I
> > do. If I do, you'll have to drop the 2 patches you have in efi-next.
> > Again I'm fine either way, so please let me know what makes your life
> > easier and let's do that.
> 
> As was mentioned by Ivan, the following patches have already been merged
> by Linus,
> 
>   f617b0f32da2 ("firmware: dmi_scan: Use full dmi version for SMBIOS3")
>   e4b1dec448af ("firmware: dmi_scan: Use direct access to static vars")
> 
> so no patches need to be dropped from my tree and there are no pending
> DMI/SMBIOS patches in any of my branches.

Correct.

> How about you go ahead and collect all the patches and send them to
> Linus? I'm happy to pickup any patches in the future if I'm explicitly
> asked, but only if OK'd by you, Jean.
> 
> Sound OK to everyone?

Deal! :-)

-- 
Jean Delvare
SUSE L3 Support


_______________________________________________
https://lists.nongnu.org/mailman/listinfo/dmidecode-devel

^ permalink raw reply

* Re: [RFC 1/4] fs: Add generic file system event notifications
From: Jan Kara @ 2015-04-17 13:41 UTC (permalink / raw)
  To: Austin S Hemmelgarn
  Cc: Beata Michalska, Jan Kara, linux-kernel, tytso, adilger.kernel,
	hughd, lczerner, hch, linux-ext4, linux-mm, kyungmin.park, kmpark,
	Linux Filesystem Mailing List, linux-api
In-Reply-To: <55310957.3070101@gmail.com>

On Fri 17-04-15 09:23:35, Austin S Hemmelgarn wrote:
> On 2015-04-17 09:04, Beata Michalska wrote:
> >On 04/17/2015 01:31 PM, Jan Kara wrote:
> >>On Wed 15-04-15 09:15:44, Beata Michalska wrote:
> >>...
> >>>+static const match_table_t fs_etypes = {
> >>>+	{ FS_EVENT_INFO,    "info"  },
> >>>+	{ FS_EVENT_WARN,    "warn"  },
> >>>+	{ FS_EVENT_THRESH,  "thr"   },
> >>>+	{ FS_EVENT_ERR,     "err"   },
> >>>+	{ 0, NULL },
> >>>+};
> >>   Why are there these generic message types? Threshold messages make good
> >>sense to me. But not so much the rest. If they don't have a clear meaning,
> >>it will be a mess. So I also agree with a message like - "filesystem has
> >>trouble, you should probably unmount and run fsck" - that's fine. But
> >>generic "info" or "warning" doesn't really carry any meaning on its own and
> >>thus seems pretty useless to me. To explain a bit more, AFAIU this
> >>shouldn't be a generic logging interface where something like severity
> >>makes sense but rather a relatively specific interface notifying about
> >>events in filesystem userspace should know about so I expect relatively low
> >>number of types of events, not tens or even hundreds...
> >>
> >>								Honza
> >
> >Getting rid of those would simplify the configuration part, indeed.
> >So we would be left with 'generic' and threshold events.
> >I guess I've overdone this part.
> 
> For some filesystems, it may make sense to differentiate between a
> generic warning and an error.  For BTRFS and ZFS for example, if
> there is a csum error on a block, this will get automatically
> corrected in many configurations, and won't require anything like
> fsck to be run, but monitoring applications will still probably want
> to be notified.
   Sure, but in that case just create an event CORRECTED_CHECKSUM_ERROR and
use that. Then userspace knows what it should do with the event. No need to
hide it behind warning / error category.

								Honza
-- 
Jan Kara <jack@suse.cz>
SUSE Labs, CR

^ permalink raw reply

* Re: [Patch 1/3] firmware: dmi_scan: rename dmi_table to dmi_decode_table
From: Matt Fleming @ 2015-04-17 13:40 UTC (permalink / raw)
  To: Jean Delvare
  Cc: Ivan Khoronzhuk, linux-kernel, matt.fleming, ard.biesheuvel,
	grant.likely, linux-api, linux-doc, mikew, dmidecode-devel,
	leif.lindholm, msalter, roy.franz
In-Reply-To: <20150416103511.55927ccc@endymion.delvare>

On Thu, 16 Apr, at 10:35:11AM, Jean Delvare wrote:
> 
> I don't really care who picks these patches up and sends them to Linus,
> but I think they should all follow the same route so that Linus has as
> little merge work to do as possible. So either you pick them all, or I
> do. If I do, you'll have to drop the 2 patches you have in efi-next.
> Again I'm fine either way, so please let me know what makes your life
> easier and let's do that.

As was mentioned by Ivan, the following patches have already been merged
by Linus,

  f617b0f32da2 ("firmware: dmi_scan: Use full dmi version for SMBIOS3")
  e4b1dec448af ("firmware: dmi_scan: Use direct access to static vars")

so no patches need to be dropped from my tree and there are no pending
DMI/SMBIOS patches in any of my branches.

How about you go ahead and collect all the patches and send them to
Linus? I'm happy to pickup any patches in the future if I'm explicitly
asked, but only if OK'd by you, Jean.

Sound OK to everyone?

-- 
Matt Fleming, Intel Open Source Technology Center

^ permalink raw reply

* Re: [RFC 1/4] fs: Add generic file system event notifications
From: Austin S Hemmelgarn @ 2015-04-17 13:23 UTC (permalink / raw)
  To: Beata Michalska, Jan Kara
  Cc: linux-kernel, tytso, adilger.kernel, hughd, lczerner, hch,
	linux-ext4, linux-mm, kyungmin.park, kmpark,
	Linux Filesystem Mailing List, linux-api
In-Reply-To: <553104E5.2040704@samsung.com>

[-- Attachment #1: Type: text/plain, Size: 1677 bytes --]

On 2015-04-17 09:04, Beata Michalska wrote:
> On 04/17/2015 01:31 PM, Jan Kara wrote:
>> On Wed 15-04-15 09:15:44, Beata Michalska wrote:
>> ...
>>> +static const match_table_t fs_etypes = {
>>> +	{ FS_EVENT_INFO,    "info"  },
>>> +	{ FS_EVENT_WARN,    "warn"  },
>>> +	{ FS_EVENT_THRESH,  "thr"   },
>>> +	{ FS_EVENT_ERR,     "err"   },
>>> +	{ 0, NULL },
>>> +};
>>    Why are there these generic message types? Threshold messages make good
>> sense to me. But not so much the rest. If they don't have a clear meaning,
>> it will be a mess. So I also agree with a message like - "filesystem has
>> trouble, you should probably unmount and run fsck" - that's fine. But
>> generic "info" or "warning" doesn't really carry any meaning on its own and
>> thus seems pretty useless to me. To explain a bit more, AFAIU this
>> shouldn't be a generic logging interface where something like severity
>> makes sense but rather a relatively specific interface notifying about
>> events in filesystem userspace should know about so I expect relatively low
>> number of types of events, not tens or even hundreds...
>>
>> 								Honza
>
> Getting rid of those would simplify the configuration part, indeed.
> So we would be left with 'generic' and threshold events.
> I guess I've overdone this part.

For some filesystems, it may make sense to differentiate between a 
generic warning and an error.  For BTRFS and ZFS for example, if there 
is a csum error on a block, this will get automatically corrected in 
many configurations, and won't require anything like fsck to be run, but 
monitoring applications will still probably want to be notified.


[-- Attachment #2: S/MIME Cryptographic Signature --]
[-- Type: application/pkcs7-signature, Size: 2967 bytes --]

^ permalink raw reply

* Re: [RFC 1/4] fs: Add generic file system event notifications
From: Jan Kara @ 2015-04-17 13:16 UTC (permalink / raw)
  To: Beata Michalska
  Cc: Jan Kara, linux-kernel-u79uwXL29TY76Z2rM5mHXA, tytso-3s7WtUTddSA,
	adilger.kernel-m1MBpc4rdrD3fQ9qLvQP4Q,
	hughd-hpIqsD4AKlfQT0dZR+AlfA, lczerner-H+wXaHxf7aLQT0dZR+AlfA,
	hch-wEGCiKHe2LqWVfeAwA7xHQ, linux-ext4-u79uwXL29TY76Z2rM5mHXA,
	linux-mm-Bw31MaZKKs3YtjvyW6yDsg,
	kyungmin.park-Sze3O3UU22JBDgjK7y7TUQ,
	kmpark-wEGCiKHe2LqWVfeAwA7xHQ, Linux Filesystem Mailing List,
	linux-api-u79uwXL29TY76Z2rM5mHXA
In-Reply-To: <553104E5.2040704-Sze3O3UU22JBDgjK7y7TUQ@public.gmane.org>

On Fri 17-04-15 15:04:37, Beata Michalska wrote:
> On 04/17/2015 01:31 PM, Jan Kara wrote:
> > On Wed 15-04-15 09:15:44, Beata Michalska wrote:
> > Also I think that we should make it clear that each event type has
> > different set of arguments. For threshold events they'll be L1 & L2, for
> > other events there may be no arguments, for other events maybe something
> > else...
> > 
> 
> Currently only the threshold events use arguments -  not sure what arguments
> could be used for the remaining notifications. But any suggestions are welcomed.
  Me neither be someone will surely find something in future ;)

> > ...
> >> +static const match_table_t fs_etypes = {
> >> +	{ FS_EVENT_INFO,    "info"  },
> >> +	{ FS_EVENT_WARN,    "warn"  },
> >> +	{ FS_EVENT_THRESH,  "thr"   },
> >> +	{ FS_EVENT_ERR,     "err"   },
> >> +	{ 0, NULL },
> >> +};
> >   Why are there these generic message types? Threshold messages make good
> > sense to me. But not so much the rest. If they don't have a clear meaning,
> > it will be a mess. So I also agree with a message like - "filesystem has
> > trouble, you should probably unmount and run fsck" - that's fine. But
> > generic "info" or "warning" doesn't really carry any meaning on its own and
> > thus seems pretty useless to me. To explain a bit more, AFAIU this
> > shouldn't be a generic logging interface where something like severity
> > makes sense but rather a relatively specific interface notifying about
> > events in filesystem userspace should know about so I expect relatively low
> > number of types of events, not tens or even hundreds...
> > 
> 
> Getting rid of those would simplify the configuration part, indeed.
> So we would be left with 'generic' and threshold events.
> I guess I've overdone this part.
  Well, I would avoid defining anything that's not really used. So
currently you can define threshold events and we start with just those.
When someone hooks up filesystem error paths to send notification, we can
create event type for telling "filesystem corrupted". And so on... We just
have to be careful to document that new event types can be added and
userspace has to ignore events it does not understand.

								Honza
-- 
Jan Kara <jack-AlSwsSmVLrQ@public.gmane.org>
SUSE Labs, CR

^ permalink raw reply

* Re: [RFC 1/4] fs: Add generic file system event notifications
From: Beata Michalska @ 2015-04-17 13:15 UTC (permalink / raw)
  To: Jan Kara
  Cc: linux-kernel, tytso, adilger.kernel, hughd, lczerner, hch,
	linux-ext4, linux-mm, kyungmin.park, kmpark,
	Linux Filesystem Mailing List, linux-api
In-Reply-To: <553104E5.2040704@samsung.com>

On 04/17/2015 03:04 PM, Beata Michalska wrote:
> On 04/17/2015 01:31 PM, Jan Kara wrote:
>> On Wed 15-04-15 09:15:44, Beata Michalska wrote:
>>> Introduce configurable generic interface for file
>>> system-wide event notifications to provide file
>>> systems with a common way of reporting any potential
>>> issues as they emerge.
>>>
>>> The notifications are to be issued through generic
>>> netlink interface, by a dedicated, for file system
>>> events, multicast group. The file systems might as
>>> well use this group to send their own custom messages.
>>>
>>> The events have been split into four base categories:
>>> information, warnings, errors and threshold notifications,
>>> with some very basic event types like running out of space
>>> or file system being remounted as read-only.
>>>
>>> Threshold notifications have been included to allow
>>> triggering an event whenever the amount of free space
>>> drops below a certain level - or levels to be more precise
>>> as two of them are being supported: the lower and the upper
>>> range. The notifications work both ways: once the threshold
>>> level has been reached, an event shall be generated whenever
>>> the number of available blocks goes up again re-activating
>>> the threshold.
>>>
>>> The interface has been exposed through a vfs. Once mounted,
>>> it serves as an entry point for the set-up where one can
>>> register for particular file system events.
>>>
>>> Signed-off-by: Beata Michalska <b.michalska@samsung.com>
>>   Thanks for the patches! Some comments are below.
>>
>>> ---
>>>  Documentation/filesystems/events.txt |  254 +++++++++++
>>>  fs/Makefile                          |    1 +
>>>  fs/events/Makefile                   |    6 +
>>>  fs/events/fs_event.c                 |  775 ++++++++++++++++++++++++++++++++++
>>>  fs/events/fs_event.h                 |   27 ++
>>>  fs/events/fs_event_netlink.c         |   94 +++++
>>>  fs/namespace.c                       |    1 +
>>>  include/linux/fs.h                   |    6 +-
>>>  include/linux/fs_event.h             |   69 +++
>>>  include/uapi/linux/fs_event.h        |   62 +++
>>>  include/uapi/linux/genetlink.h       |    1 +
>>>  net/netlink/genetlink.c              |    7 +-
>>>  12 files changed, 1301 insertions(+), 2 deletions(-)
>>>  create mode 100644 Documentation/filesystems/events.txt
>>>  create mode 100644 fs/events/Makefile
>>>  create mode 100644 fs/events/fs_event.c
>>>  create mode 100644 fs/events/fs_event.h
>>>  create mode 100644 fs/events/fs_event_netlink.c
>>>  create mode 100644 include/linux/fs_event.h
>>>  create mode 100644 include/uapi/linux/fs_event.h
>>>
>>> diff --git a/Documentation/filesystems/events.txt b/Documentation/filesystems/events.txt
>>> new file mode 100644
>>> index 0000000..c85dd88
>>> --- /dev/null
>>> +++ b/Documentation/filesystems/events.txt
>>> @@ -0,0 +1,254 @@
>>> +
>>> +	Generic file system event notification interface
>>> +
>>> +Document created 09 April 2015 by Beata Michalska <b.michalska@samsung.com>
>>> +
>>> +1. The reason behind:
>>> +=====================
>>> +
>>> +There are many corner cases when things might get messy with the filesystems.
>>> +And it is not always obvious what and when went wrong. Sometimes you might
>>> +get some subtle hints that there is something going on - but by the time
>>> +you realise it, it might be too late as you are already out-of-space
>>> +or the filesystem has been remounted as read-only (i.e.). The generic
>>> +interface for the filesystem events fills the gap by providing a rather
>>> +easy way of real-time notifications triggered whenever something intreseting
>>> +happens, allowing filesystems to report events in a common way, as they occur.
>>> +
>>> +2. How does it work:
>>> +====================
>>> +
>>> +The interface itself has been exposed as fstrace-type Virtual File System,
>>> +primarily to ease the process of setting up the configuration for the file
>>> +system notifications. So for starters it needs to get mounted (obviously):
>>> +
>>> +	mount -t fstrace none /sys/fs/events
>>> +
>>> +This will unveil the single fstrace filesystem entry - the 'config' file,
>>> +through which the notification are being set-up.
>>> +
>>> +Activating notifications for particular filesystem is as straightforward
>>> +as writing into the 'config' file. Note that by default all events despite
>>> +the actual filesystem type are being disregarded.
>>   Is there a reason to have a special filesystem for this? Do you expect
>> extending it by (many) more files? Why not just creating a file in sysfs or
>> something like that?
> 
> No particular reason here - just for possible future extension if needed.
> I'm totally fine with having a single sysfs entry.
> 

On the other hand .... sysfs entries are mostly single-valued or are sets
of values of a single type, so not sure if we would fit in here -
with the current configuration for the interface.

>>
>>> +Synopsis of config:
>>> +------------------
>>> +
>>> +	MOUNT EVENT_TYPE [L1] [L2]
>>> +
>>> + MOUNT      : the filesystem's mount point
>>   I'm not quite decided but is mountpoint really the right thing to pass
>> via the interface? They aren't unique (filesystem can be mounted in
>> multiple places) and more importantly can change over time. So won't it be
>> better to pass major:minor over the interface? These are stable, unique to
>> the filesystem, and userspace can easily get them by calling stat(2) on the
>> desired path (or directly from /proc/self/mountinfo). That could be also
>> used as an fs identifier instead of assigned ID (and thus we won't need
>> those events about creation of new trace which look somewhat strange to
>> me).
>>
> Even if a given filesystem is being mounted in many places this will come
> down to single super_block - the interface will add trace for the first mount
> point. This is just to ease the usage: internally a particular trace is 
> associated with a super_block. 
> 
>> OTOH using major:minor may have issues in container world where processes
>> could watch events from filesystems inaccessible to the container if they
>> guess the device number. So maybe we could use 'path' when creating new
>> trace but I'd still like to use the device number internally and for all
>> outgoing communication because of above mentioned problems with
>> mountpoints.
> 
> Alright then, so dropping the idea of announcing new trace (with assigned id)
> and switching to using the major:minor numbers. Sounds OK to me.
> 
>>
>>> + EVENT_TYPE : type of events to be enabled: info,warn,err,thr;
>>> +              at least one type needs to be specified;
>>> +              note the comma delimiter and lack of spaces between
>>> +	      those options
>>> + L1         : the threshold limit - lower range
>>> + L2         : the threshold limit - upper range
>>> + 	      case enabling threshold notifications the lower level is
>>> +	      mandatory, whereas the upper one remains optional;
>>> +	      note though, that as those refer to the number of available
>>> +	      blocks, the lower level needs to be higher than the upper one
>>> +
>>> +Sample request could look like the follwoing:
>>> +
>>> + echo /sample/mount/point warn,err,thr 710000 500000 > /sys/fs/events/config
>>> +
>>> +Multiple request might be specified provided they are separated with semicolon.
>>   Is this necessary? It somewhat complicates syntax and parsing in kernel
>> and I don't see a need for that. I'd prefer to keep the interface as simple
>> as possible.
>>
> 
> This is not necessary but could ease the usage - i.e. through scripting: to specify
> multiple traces and register them in one go. 
> 
>> Also I think that we should make it clear that each event type has
>> different set of arguments. For threshold events they'll be L1 & L2, for
>> other events there may be no arguments, for other events maybe something
>> else...
>>
> 
> Currently only the threshold events use arguments -  not sure what arguments
> could be used for the remaining notifications. But any suggestions are welcomed.
> 
>> ...
>>> +static const match_table_t fs_etypes = {
>>> +	{ FS_EVENT_INFO,    "info"  },
>>> +	{ FS_EVENT_WARN,    "warn"  },
>>> +	{ FS_EVENT_THRESH,  "thr"   },
>>> +	{ FS_EVENT_ERR,     "err"   },
>>> +	{ 0, NULL },
>>> +};
>>   Why are there these generic message types? Threshold messages make good
>> sense to me. But not so much the rest. If they don't have a clear meaning,
>> it will be a mess. So I also agree with a message like - "filesystem has
>> trouble, you should probably unmount and run fsck" - that's fine. But
>> generic "info" or "warning" doesn't really carry any meaning on its own and
>> thus seems pretty useless to me. To explain a bit more, AFAIU this
>> shouldn't be a generic logging interface where something like severity
>> makes sense but rather a relatively specific interface notifying about
>> events in filesystem userspace should know about so I expect relatively low
>> number of types of events, not tens or even hundreds...
>>
>> 								Honza
> 
> Getting rid of those would simplify the configuration part, indeed.
> So we would be left with 'generic' and threshold events.
> I guess I've overdone this part.
> 
> Thanks for Your comments so far.
> 
> BR
> Beata
> 
> 
> 
> 
> 

--
To unsubscribe, send a message with 'unsubscribe linux-mm' in
the body to majordomo@kvack.org.  For more info on Linux MM,
see: http://www.linux-mm.org/ .
Don't email: <a href=mailto:"dont@kvack.org"> email@kvack.org </a>

^ permalink raw reply


This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox