Please (help) improve support for linux-vserver

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



Hi,

I'm a user of xfs and linux-vserver (http://linux-vserver.org/).

I'd like vserver to work better with xfs (or vice versa) and am trying to
proxy between the two development communities (which in the case of vserver
is not very large).

vservers are basically chroots on steroids: the host runs a single kernel,
but it isolates processes running in the guests from each other. There is a
"copy on write hardlink breaking" feature that allows you to hardlink files
(such as libc6) of different guests together (so that they only get mapped
into memory once), and have the kernel break the link if the inode is opened
for writing (by creating a copy and returning a FD to the copy).

This feature relies on inode flags (like the 'immutable' bit). vserver adds
two fields to the inode (the other is used to tag inodes with a context ID).

The kernel parts work, but xfs_repair breaks such filesystems because it
thinks the flags are invalid.

I approached David Chinner and Eric Sandeen about this on IRC, and they said
that the first step towards any improvement would be to share with this list
the parts of the vserver patch that affect xfs, so that's what I'm doing
now.

Please find attached the output of

filterdiff -i '*xfs*' patch-3.7-vs2.3.5.1.diff

(the latter was obtained from http://vserver.13thfloor.at/Experimental/ but
the xfs specific parts apparently haven't changed in a while).

Andras

-- 
                     Andras Korn <korn at elan.rulez.org>
                                 I ? Unicode.
--- linux-3.7/fs/xfs/xfs_dinode.h	2012-10-04 13:27:44.000000000 +0000
+++ linux-3.7-vs2.3.5.1/fs/xfs/xfs_dinode.h	2012-12-11 15:56:32.000000000 +0000
@@ -51,7 +51,9 @@ typedef struct xfs_dinode {
 	__be32		di_nlink;	/* number of links to file */
 	__be16		di_projid_lo;	/* lower part of owner's project id */
 	__be16		di_projid_hi;	/* higher part owner's project id */
-	__u8		di_pad[6];	/* unused, zeroed space */
+	__u8		di_pad[2];	/* unused, zeroed space */
+	__be16		di_tag;		/* context tagging */
+	__be16		di_vflags;	/* vserver specific flags */
 	__be16		di_flushiter;	/* incremented on flush */
 	xfs_timestamp_t	di_atime;	/* time last accessed */
 	xfs_timestamp_t	di_mtime;	/* time last modified */
@@ -184,6 +186,8 @@ static inline void xfs_dinode_put_rdev(s
 #define XFS_DIFLAG_EXTSZINHERIT_BIT 12	/* inherit inode extent size */
 #define XFS_DIFLAG_NODEFRAG_BIT     13	/* do not reorganize/defragment */
 #define XFS_DIFLAG_FILESTREAM_BIT   14  /* use filestream allocator */
+#define XFS_DIFLAG_IXUNLINK_BIT     15	/* Immutable inver on unlink */
+
 #define XFS_DIFLAG_REALTIME      (1 << XFS_DIFLAG_REALTIME_BIT)
 #define XFS_DIFLAG_PREALLOC      (1 << XFS_DIFLAG_PREALLOC_BIT)
 #define XFS_DIFLAG_NEWRTBM       (1 << XFS_DIFLAG_NEWRTBM_BIT)
@@ -199,6 +203,7 @@ static inline void xfs_dinode_put_rdev(s
 #define XFS_DIFLAG_EXTSZINHERIT  (1 << XFS_DIFLAG_EXTSZINHERIT_BIT)
 #define XFS_DIFLAG_NODEFRAG      (1 << XFS_DIFLAG_NODEFRAG_BIT)
 #define XFS_DIFLAG_FILESTREAM    (1 << XFS_DIFLAG_FILESTREAM_BIT)
+#define XFS_DIFLAG_IXUNLINK      (1 << XFS_DIFLAG_IXUNLINK_BIT)
 
 #ifdef CONFIG_XFS_RT
 #define XFS_IS_REALTIME_INODE(ip) ((ip)->i_d.di_flags & XFS_DIFLAG_REALTIME)
@@ -211,6 +216,10 @@ static inline void xfs_dinode_put_rdev(s
 	 XFS_DIFLAG_IMMUTABLE | XFS_DIFLAG_APPEND | XFS_DIFLAG_SYNC | \
 	 XFS_DIFLAG_NOATIME | XFS_DIFLAG_NODUMP | XFS_DIFLAG_RTINHERIT | \
 	 XFS_DIFLAG_PROJINHERIT | XFS_DIFLAG_NOSYMLINKS | XFS_DIFLAG_EXTSIZE | \
-	 XFS_DIFLAG_EXTSZINHERIT | XFS_DIFLAG_NODEFRAG | XFS_DIFLAG_FILESTREAM)
+	 XFS_DIFLAG_EXTSZINHERIT | XFS_DIFLAG_NODEFRAG | XFS_DIFLAG_FILESTREAM | \
+	 XFS_DIFLAG_IXUNLINK)
+
+#define XFS_DIVFLAG_BARRIER	0x01
+#define XFS_DIVFLAG_COW		0x02
 
 #endif	/* __XFS_DINODE_H__ */
--- linux-3.7/fs/xfs/xfs_fs.h	2011-10-24 16:45:31.000000000 +0000
+++ linux-3.7-vs2.3.5.1/fs/xfs/xfs_fs.h	2012-12-11 15:56:32.000000000 +0000
@@ -67,6 +67,9 @@ struct fsxattr {
 #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_IXUNLINK	0x00008000	/* immutable invert on unlink */
+#define XFS_XFLAG_BARRIER	0x10000000	/* chroot() barrier */
+#define XFS_XFLAG_COW		0x20000000	/* copy on write mark */
 #define XFS_XFLAG_HASATTR	0x80000000	/* no DIFLAG for this	*/
 
 /*
@@ -302,7 +305,8 @@ typedef struct xfs_bstat {
 #define	bs_projid	bs_projid_lo	/* (previously just bs_projid)	*/
 	__u16		bs_forkoff;	/* inode fork offset in bytes	*/
 	__u16		bs_projid_hi;	/* higher part of project id	*/
-	unsigned char	bs_pad[10];	/* pad space, unused		*/
+	unsigned char	bs_pad[8];	/* pad space, unused		*/
+	__u16		bs_tag;		/* context tagging		*/
 	__u32		bs_dmevmask;	/* DMIG event mask		*/
 	__u16		bs_dmstate;	/* DMIG state info		*/
 	__u16		bs_aextents;	/* attribute number of extents	*/
--- linux-3.7/fs/xfs/xfs_ialloc.c	2012-12-11 15:47:37.000000000 +0000
+++ linux-3.7-vs2.3.5.1/fs/xfs/xfs_ialloc.c	2012-12-11 15:56:32.000000000 +0000
@@ -37,7 +37,6 @@
 #include "xfs_error.h"
 #include "xfs_bmap.h"
 
-
 /*
  * Allocation group level functions.
  */
--- linux-3.7/fs/xfs/xfs_inode.c	2012-12-11 15:47:37.000000000 +0000
+++ linux-3.7-vs2.3.5.1/fs/xfs/xfs_inode.c	2012-12-11 22:20:23.000000000 +0000
@@ -16,6 +16,7 @@
  * Inc.,  51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
  */
 #include <linux/log2.h>
+#include <linux/vs_tag.h>
 
 #include "xfs.h"
 #include "xfs_fs.h"
@@ -563,15 +564,25 @@ xfs_iformat_btree(
 STATIC void
 xfs_dinode_from_disk(
 	xfs_icdinode_t		*to,
-	xfs_dinode_t		*from)
+	xfs_dinode_t		*from,
+	int			tagged)
 {
+	uint32_t uid, gid, tag;
+
 	to->di_magic = be16_to_cpu(from->di_magic);
 	to->di_mode = be16_to_cpu(from->di_mode);
 	to->di_version = from ->di_version;
 	to->di_format = from->di_format;
 	to->di_onlink = be16_to_cpu(from->di_onlink);
-	to->di_uid = be32_to_cpu(from->di_uid);
-	to->di_gid = be32_to_cpu(from->di_gid);
+
+	uid = be32_to_cpu(from->di_uid);
+	gid = be32_to_cpu(from->di_gid);
+	tag = be16_to_cpu(from->di_tag);
+
+	to->di_uid = INOTAG_UID(tagged, uid, gid);
+	to->di_gid = INOTAG_GID(tagged, uid, gid);
+	to->di_tag = INOTAG_TAG(tagged, uid, gid, tag);
+
 	to->di_nlink = be32_to_cpu(from->di_nlink);
 	to->di_projid_lo = be16_to_cpu(from->di_projid_lo);
 	to->di_projid_hi = be16_to_cpu(from->di_projid_hi);
@@ -593,21 +604,26 @@ xfs_dinode_from_disk(
 	to->di_dmevmask	= be32_to_cpu(from->di_dmevmask);
 	to->di_dmstate	= be16_to_cpu(from->di_dmstate);
 	to->di_flags	= be16_to_cpu(from->di_flags);
+	to->di_vflags	= be16_to_cpu(from->di_vflags);
 	to->di_gen	= be32_to_cpu(from->di_gen);
 }
 
 void
 xfs_dinode_to_disk(
 	xfs_dinode_t		*to,
-	xfs_icdinode_t		*from)
+	xfs_icdinode_t		*from,
+	int			tagged)
 {
 	to->di_magic = cpu_to_be16(from->di_magic);
 	to->di_mode = cpu_to_be16(from->di_mode);
 	to->di_version = from ->di_version;
 	to->di_format = from->di_format;
 	to->di_onlink = cpu_to_be16(from->di_onlink);
-	to->di_uid = cpu_to_be32(from->di_uid);
-	to->di_gid = cpu_to_be32(from->di_gid);
+
+	to->di_uid = cpu_to_be32(TAGINO_UID(tagged, from->di_uid, from->di_tag));
+	to->di_gid = cpu_to_be32(TAGINO_GID(tagged, from->di_gid, from->di_tag));
+	to->di_tag = cpu_to_be16(TAGINO_TAG(tagged, from->di_tag));
+
 	to->di_nlink = cpu_to_be32(from->di_nlink);
 	to->di_projid_lo = cpu_to_be16(from->di_projid_lo);
 	to->di_projid_hi = cpu_to_be16(from->di_projid_hi);
@@ -629,12 +645,14 @@ xfs_dinode_to_disk(
 	to->di_dmevmask = cpu_to_be32(from->di_dmevmask);
 	to->di_dmstate = cpu_to_be16(from->di_dmstate);
 	to->di_flags = cpu_to_be16(from->di_flags);
+	to->di_vflags = cpu_to_be16(from->di_vflags);
 	to->di_gen = cpu_to_be32(from->di_gen);
 }
 
 STATIC uint
 _xfs_dic2xflags(
-	__uint16_t		di_flags)
+	__uint16_t		di_flags,
+	__uint16_t		di_vflags)
 {
 	uint			flags = 0;
 
@@ -645,6 +663,8 @@ _xfs_dic2xflags(
 			flags |= XFS_XFLAG_PREALLOC;
 		if (di_flags & XFS_DIFLAG_IMMUTABLE)
 			flags |= XFS_XFLAG_IMMUTABLE;
+		if (di_flags & XFS_DIFLAG_IXUNLINK)
+			flags |= XFS_XFLAG_IXUNLINK;
 		if (di_flags & XFS_DIFLAG_APPEND)
 			flags |= XFS_XFLAG_APPEND;
 		if (di_flags & XFS_DIFLAG_SYNC)
@@ -669,6 +689,10 @@ _xfs_dic2xflags(
 			flags |= XFS_XFLAG_FILESTREAM;
 	}
 
+	if (di_vflags & XFS_DIVFLAG_BARRIER)
+		flags |= FS_BARRIER_FL;
+	if (di_vflags & XFS_DIVFLAG_COW)
+		flags |= FS_COW_FL;
 	return flags;
 }
 
@@ -678,7 +702,7 @@ xfs_ip2xflags(
 {
 	xfs_icdinode_t		*dic = &ip->i_d;
 
-	return _xfs_dic2xflags(dic->di_flags) |
+	return _xfs_dic2xflags(dic->di_flags, dic->di_vflags) |
 				(XFS_IFORK_Q(ip) ? XFS_XFLAG_HASATTR : 0);
 }
 
@@ -686,7 +710,8 @@ uint
 xfs_dic2xflags(
 	xfs_dinode_t		*dip)
 {
-	return _xfs_dic2xflags(be16_to_cpu(dip->di_flags)) |
+	return _xfs_dic2xflags(be16_to_cpu(dip->di_flags),
+				be16_to_cpu(dip->di_vflags)) |
 				(XFS_DFORK_Q(dip) ? XFS_XFLAG_HASATTR : 0);
 }
 
@@ -740,7 +765,8 @@ xfs_iread(
 	 * Otherwise, just get the truly permanent information.
 	 */
 	if (dip->di_mode) {
-		xfs_dinode_from_disk(&ip->i_d, dip);
+		xfs_dinode_from_disk(&ip->i_d, dip,
+			mp->m_flags & XFS_MOUNT_TAGGED);
 		error = xfs_iformat(ip, dip);
 		if (error)  {
 #ifdef DEBUG
@@ -927,6 +953,7 @@ xfs_ialloc(
 	ASSERT(ip->i_d.di_nlink == nlink);
 	ip->i_d.di_uid = current_fsuid();
 	ip->i_d.di_gid = current_fsgid();
+	ip->i_d.di_tag = current_fstag(&ip->i_vnode);
 	xfs_set_projid(ip, prid);
 	memset(&(ip->i_d.di_pad[0]), 0, sizeof(ip->i_d.di_pad));
 
@@ -986,6 +1013,7 @@ xfs_ialloc(
 	ip->i_d.di_dmevmask = 0;
 	ip->i_d.di_dmstate = 0;
 	ip->i_d.di_flags = 0;
+	ip->i_d.di_vflags = 0;
 	flags = XFS_ILOG_CORE;
 	switch (mode & S_IFMT) {
 	case S_IFIFO:
@@ -1668,6 +1696,7 @@ xfs_ifree(
 	}
 	ip->i_d.di_mode = 0;		/* mark incore inode as free */
 	ip->i_d.di_flags = 0;
+	ip->i_d.di_vflags = 0;
 	ip->i_d.di_dmevmask = 0;
 	ip->i_d.di_forkoff = 0;		/* mark the attr fork not in use */
 	ip->i_d.di_format = XFS_DINODE_FMT_EXTENTS;
@@ -1834,7 +1863,6 @@ xfs_iroot_realloc(
 	return;
 }
 
-
 /*
  * This is called when the amount of space needed for if_data
  * is increased or decreased.  The change in size is indicated by
@@ -2522,7 +2550,8 @@ xfs_iflush_int(
 	 * because if the inode is dirty at all the core must
 	 * be.
 	 */
-	xfs_dinode_to_disk(dip, &ip->i_d);
+	xfs_dinode_to_disk(dip, &ip->i_d,
+		mp->m_flags & XFS_MOUNT_TAGGED);
 
 	/* Wrap, we never let the log put out DI_MAX_FLUSH */
 	if (ip->i_d.di_flushiter == DI_MAX_FLUSH)
--- linux-3.7/fs/xfs/xfs_inode.h	2012-10-04 13:27:44.000000000 +0000
+++ linux-3.7-vs2.3.5.1/fs/xfs/xfs_inode.h	2012-12-11 15:56:32.000000000 +0000
@@ -134,7 +134,9 @@ typedef struct xfs_icdinode {
 	__uint32_t	di_nlink;	/* number of links to file */
 	__uint16_t	di_projid_lo;	/* lower part of owner's project id */
 	__uint16_t	di_projid_hi;	/* higher part of owner's project id */
-	__uint8_t	di_pad[6];	/* unused, zeroed space */
+	__uint8_t	di_pad[2];	/* unused, zeroed space */
+	__uint16_t	di_tag;		/* context tagging */
+	__uint16_t	di_vflags;	/* vserver specific flags */
 	__uint16_t	di_flushiter;	/* incremented on flush */
 	xfs_ictimestamp_t di_atime;	/* time last accessed */
 	xfs_ictimestamp_t di_mtime;	/* time last modified */
@@ -561,7 +563,7 @@ int		xfs_imap_to_bp(struct xfs_mount *,
 int		xfs_iread(struct xfs_mount *, struct xfs_trans *,
 			  struct xfs_inode *, uint);
 void		xfs_dinode_to_disk(struct xfs_dinode *,
-				   struct xfs_icdinode *);
+				   struct xfs_icdinode *, int);
 void		xfs_idestroy_fork(struct xfs_inode *, int);
 void		xfs_idata_realloc(struct xfs_inode *, int, int);
 void		xfs_iroot_realloc(struct xfs_inode *, int, int);
--- linux-3.7/fs/xfs/xfs_ioctl.c	2012-12-11 15:47:37.000000000 +0000
+++ linux-3.7-vs2.3.5.1/fs/xfs/xfs_ioctl.c	2012-12-11 15:56:32.000000000 +0000
@@ -26,7 +26,7 @@
 #include "xfs_bmap_btree.h"
 #include "xfs_dinode.h"
 #include "xfs_inode.h"
-#include "xfs_ioctl.h"
+// #include "xfs_ioctl.h"
 #include "xfs_rtalloc.h"
 #include "xfs_itable.h"
 #include "xfs_error.h"
@@ -762,6 +762,10 @@ xfs_merge_ioc_xflags(
 		xflags |= XFS_XFLAG_IMMUTABLE;
 	else
 		xflags &= ~XFS_XFLAG_IMMUTABLE;
+	if (flags & FS_IXUNLINK_FL)
+		xflags |= XFS_XFLAG_IXUNLINK;
+	else
+		xflags &= ~XFS_XFLAG_IXUNLINK;
 	if (flags & FS_APPEND_FL)
 		xflags |= XFS_XFLAG_APPEND;
 	else
@@ -790,6 +794,8 @@ xfs_di2lxflags(
 
 	if (di_flags & XFS_DIFLAG_IMMUTABLE)
 		flags |= FS_IMMUTABLE_FL;
+	if (di_flags & XFS_DIFLAG_IXUNLINK)
+		flags |= FS_IXUNLINK_FL;
 	if (di_flags & XFS_DIFLAG_APPEND)
 		flags |= FS_APPEND_FL;
 	if (di_flags & XFS_DIFLAG_SYNC)
@@ -850,6 +856,8 @@ xfs_set_diflags(
 	di_flags = (ip->i_d.di_flags & XFS_DIFLAG_PREALLOC);
 	if (xflags & XFS_XFLAG_IMMUTABLE)
 		di_flags |= XFS_DIFLAG_IMMUTABLE;
+	if (xflags & XFS_XFLAG_IXUNLINK)
+		di_flags |= XFS_DIFLAG_IXUNLINK;
 	if (xflags & XFS_XFLAG_APPEND)
 		di_flags |= XFS_DIFLAG_APPEND;
 	if (xflags & XFS_XFLAG_SYNC)
@@ -892,6 +900,10 @@ xfs_diflags_to_linux(
 		inode->i_flags |= S_IMMUTABLE;
 	else
 		inode->i_flags &= ~S_IMMUTABLE;
+	if (xflags & XFS_XFLAG_IXUNLINK)
+		inode->i_flags |= S_IXUNLINK;
+	else
+		inode->i_flags &= ~S_IXUNLINK;
 	if (xflags & XFS_XFLAG_APPEND)
 		inode->i_flags |= S_APPEND;
 	else
@@ -1396,10 +1408,18 @@ xfs_file_ioctl(
 	case XFS_IOC_FSGETXATTRA:
 		return xfs_ioc_fsgetxattr(ip, 1, arg);
 	case XFS_IOC_FSSETXATTR:
+		if (IS_BARRIER(inode)) {
+			vxwprintk_task(1, "messing with the barrier.");
+			return -XFS_ERROR(EACCES);
+		}
 		return xfs_ioc_fssetxattr(ip, filp, arg);
 	case XFS_IOC_GETXFLAGS:
 		return xfs_ioc_getxflags(ip, arg);
 	case XFS_IOC_SETXFLAGS:
+		if (IS_BARRIER(inode)) {
+			vxwprintk_task(1, "messing with the barrier.");
+			return -XFS_ERROR(EACCES);
+		}
 		return xfs_ioc_setxflags(ip, filp, arg);
 
 	case XFS_IOC_FSSETDM: {
--- linux-3.7/fs/xfs/xfs_ioctl.h	2011-10-24 16:45:31.000000000 +0000
+++ linux-3.7-vs2.3.5.1/fs/xfs/xfs_ioctl.h	2012-12-11 15:56:32.000000000 +0000
@@ -70,6 +70,12 @@ xfs_handle_to_dentry(
 	void __user		*uhandle,
 	u32			hlen);
 
+extern int
+xfs_sync_flags(
+	struct inode		*inode,
+	int			flags,
+	int			vflags);
+
 extern long
 xfs_file_ioctl(
 	struct file		*filp,
--- linux-3.7/fs/xfs/xfs_iops.c	2012-10-04 13:27:44.000000000 +0000
+++ linux-3.7-vs2.3.5.1/fs/xfs/xfs_iops.c	2012-12-11 15:56:32.000000000 +0000
@@ -28,6 +28,7 @@
 #include "xfs_bmap_btree.h"
 #include "xfs_dinode.h"
 #include "xfs_inode.h"
+#include "xfs_ioctl.h"
 #include "xfs_bmap.h"
 #include "xfs_rtalloc.h"
 #include "xfs_error.h"
@@ -46,6 +47,7 @@
 #include <linux/security.h>
 #include <linux/fiemap.h>
 #include <linux/slab.h>
+#include <linux/vs_tag.h>
 
 static int
 xfs_initxattrs(
@@ -421,6 +423,7 @@ xfs_vn_getattr(
 	stat->nlink = ip->i_d.di_nlink;
 	stat->uid = ip->i_d.di_uid;
 	stat->gid = ip->i_d.di_gid;
+	stat->tag = ip->i_d.di_tag;
 	stat->ino = ip->i_ino;
 	stat->atime = inode->i_atime;
 	stat->mtime = inode->i_mtime;
@@ -1033,6 +1036,7 @@ static const struct inode_operations xfs
 	.listxattr		= xfs_vn_listxattr,
 	.fiemap			= xfs_vn_fiemap,
 	.update_time		= xfs_vn_update_time,
+	.sync_flags		= xfs_sync_flags,
 };
 
 static const struct inode_operations xfs_dir_inode_operations = {
@@ -1059,6 +1063,7 @@ static const struct inode_operations xfs
 	.removexattr		= generic_removexattr,
 	.listxattr		= xfs_vn_listxattr,
 	.update_time		= xfs_vn_update_time,
+	.sync_flags		= xfs_sync_flags,
 };
 
 static const struct inode_operations xfs_dir_ci_inode_operations = {
@@ -1110,6 +1115,10 @@ xfs_diflags_to_iflags(
 		inode->i_flags |= S_IMMUTABLE;
 	else
 		inode->i_flags &= ~S_IMMUTABLE;
+	if (ip->i_d.di_flags & XFS_DIFLAG_IXUNLINK)
+		inode->i_flags |= S_IXUNLINK;
+	else
+		inode->i_flags &= ~S_IXUNLINK;
 	if (ip->i_d.di_flags & XFS_DIFLAG_APPEND)
 		inode->i_flags |= S_APPEND;
 	else
@@ -1122,6 +1131,15 @@ xfs_diflags_to_iflags(
 		inode->i_flags |= S_NOATIME;
 	else
 		inode->i_flags &= ~S_NOATIME;
+
+	if (ip->i_d.di_vflags & XFS_DIVFLAG_BARRIER)
+		inode->i_vflags |= V_BARRIER;
+	else
+		inode->i_vflags &= ~V_BARRIER;
+	if (ip->i_d.di_vflags & XFS_DIVFLAG_COW)
+		inode->i_vflags |= V_COW;
+	else
+		inode->i_vflags &= ~V_COW;
 }
 
 /*
@@ -1153,6 +1171,7 @@ xfs_setup_inode(
 	set_nlink(inode, ip->i_d.di_nlink);
 	inode->i_uid	= ip->i_d.di_uid;
 	inode->i_gid	= ip->i_d.di_gid;
+	inode->i_tag    = ip->i_d.di_tag;
 
 	switch (inode->i_mode & S_IFMT) {
 	case S_IFBLK:
--- linux-3.7/fs/xfs/xfs_itable.c	2012-10-04 13:27:44.000000000 +0000
+++ linux-3.7-vs2.3.5.1/fs/xfs/xfs_itable.c	2012-12-11 15:56:32.000000000 +0000
@@ -96,6 +96,7 @@ xfs_bulkstat_one_int(
 	buf->bs_mode = dic->di_mode;
 	buf->bs_uid = dic->di_uid;
 	buf->bs_gid = dic->di_gid;
+	buf->bs_tag = dic->di_tag;
 	buf->bs_size = dic->di_size;
 	buf->bs_atime.tv_sec = dic->di_atime.t_sec;
 	buf->bs_atime.tv_nsec = dic->di_atime.t_nsec;
--- linux-3.7/fs/xfs/xfs_linux.h	2011-10-24 16:45:31.000000000 +0000
+++ linux-3.7-vs2.3.5.1/fs/xfs/xfs_linux.h	2012-12-11 15:56:32.000000000 +0000
@@ -121,6 +121,7 @@
 
 #define current_cpu()		(raw_smp_processor_id())
 #define current_pid()		(current->pid)
+#define current_fstag(vp)	(dx_current_fstag((vp)->i_sb))
 #define current_test_flags(f)	(current->flags & (f))
 #define current_set_flags_nested(sp, f)		\
 		(*(sp) = current->flags, current->flags |= (f))
--- linux-3.7/fs/xfs/xfs_log_recover.c	2012-12-11 15:47:37.000000000 +0000
+++ linux-3.7-vs2.3.5.1/fs/xfs/xfs_log_recover.c	2012-12-11 15:56:32.000000000 +0000
@@ -2359,7 +2359,8 @@ xlog_recover_inode_pass2(
 	}
 
 	/* The core is in in-core format */
-	xfs_dinode_to_disk(dip, item->ri_buf[1].i_addr);
+	xfs_dinode_to_disk(dip, item->ri_buf[1].i_addr,
+		mp->m_flags & XFS_MOUNT_TAGGED);
 
 	/* the rest is in on-disk format */
 	if (item->ri_buf[1].i_len > sizeof(struct xfs_icdinode)) {
--- linux-3.7/fs/xfs/xfs_mount.h	2012-12-11 15:47:37.000000000 +0000
+++ linux-3.7-vs2.3.5.1/fs/xfs/xfs_mount.h	2012-12-11 15:56:32.000000000 +0000
@@ -246,6 +246,7 @@ typedef struct xfs_mount {
 						   allocator */
 #define XFS_MOUNT_NOATTR2	(1ULL << 25)	/* disable use of attr2 format */
 
+#define XFS_MOUNT_TAGGED	(1ULL << 31)	/* context tagging */
 
 /*
  * Default minimum read and write sizes.
--- linux-3.7/fs/xfs/xfs_super.c	2012-12-11 15:47:37.000000000 +0000
+++ linux-3.7-vs2.3.5.1/fs/xfs/xfs_super.c	2012-12-11 17:36:47.000000000 +0000
@@ -114,6 +114,9 @@ mempool_t *xfs_ioend_pool;
 #define MNTOPT_NODELAYLOG  "nodelaylog"	/* Delayed logging disabled */
 #define MNTOPT_DISCARD	   "discard"	/* Discard unused blocks */
 #define MNTOPT_NODISCARD   "nodiscard"	/* Do not discard unused blocks */
+#define MNTOPT_TAGXID	"tagxid"	/* context tagging for inodes */
+#define MNTOPT_TAGGED	"tag"		/* context tagging for inodes */
+#define MNTOPT_NOTAGTAG	"notag"		/* do not use context tagging */
 
 /*
  * Table driven mount option parser.
@@ -126,6 +129,8 @@ enum {
 	Opt_nobarrier,
 	Opt_inode64,
 	Opt_inode32,
+	Opt_tag,
+	Opt_notag,
 	Opt_err
 };
 
@@ -134,6 +139,9 @@ static const match_table_t tokens = {
 	{Opt_nobarrier, "nobarrier"},
 	{Opt_inode64, "inode64"},
 	{Opt_inode32, "inode32"},
+	{Opt_tag, "tagxid"},
+	{Opt_tag, "tag"},
+	{Opt_notag, "notag"},
 	{Opt_err, NULL}
 };
 
@@ -383,6 +391,19 @@ xfs_parseargs(
 		} else if (!strcmp(this_char, "irixsgid")) {
 			xfs_warn(mp,
 	"irixsgid is now a sysctl(2) variable, option is deprecated.");
+#ifndef CONFIG_TAGGING_NONE
+		} else if (!strcmp(this_char, MNTOPT_TAGGED)) {
+			mp->m_flags |= XFS_MOUNT_TAGGED;
+		} else if (!strcmp(this_char, MNTOPT_NOTAGTAG)) {
+			mp->m_flags &= ~XFS_MOUNT_TAGGED;
+		} else if (!strcmp(this_char, MNTOPT_TAGXID)) {
+			mp->m_flags |= XFS_MOUNT_TAGGED;
+#endif
+#ifdef CONFIG_PROPAGATE
+		} else if (!strcmp(this_char, MNTOPT_TAGGED)) {
+			/* use value */
+			mp->m_flags |= XFS_MOUNT_TAGGED;
+#endif
 		} else {
 			xfs_warn(mp, "unknown mount option [%s].", this_char);
 			return EINVAL;
@@ -1149,6 +1170,16 @@ xfs_fs_remount(
 		case Opt_inode32:
 			mp->m_maxagi = xfs_set_inode32(mp);
 			break;
+		case Opt_tag:
+			if (!(sb->s_flags & MS_TAGGED)) {
+				printk(KERN_INFO
+					"XFS: %s: tagging not permitted on remount.\n",
+					sb->s_id);
+				return -EINVAL;
+			}
+			break;
+		case Opt_notag:
+			break;
 		default:
 			/*
 			 * Logically we would return an error here to prevent
@@ -1368,6 +1399,9 @@ xfs_fs_fill_super(
 	if (error)
 		goto out_free_sb;
 
+	if (mp->m_flags & XFS_MOUNT_TAGGED)
+		sb->s_flags |= MS_TAGGED;
+
 	/*
 	 * we must configure the block size in the superblock before we run the
 	 * full mount process as the mount process can lookup and cache inodes.
--- linux-3.7/fs/xfs/xfs_vnodeops.c	2012-10-04 13:27:44.000000000 +0000
+++ linux-3.7-vs2.3.5.1/fs/xfs/xfs_vnodeops.c	2012-12-11 15:56:32.000000000 +0000
@@ -103,6 +103,77 @@ xfs_readlink_bmap(
 	return error;
 }
 
+
+STATIC void
+xfs_get_inode_flags(
+	xfs_inode_t	*ip)
+{
+	struct inode 	*inode = VFS_I(ip);
+	unsigned int 	flags = inode->i_flags;
+	unsigned int 	vflags = inode->i_vflags;
+
+	if (flags & S_IMMUTABLE)
+		ip->i_d.di_flags |= XFS_DIFLAG_IMMUTABLE;
+	else
+		ip->i_d.di_flags &= ~XFS_DIFLAG_IMMUTABLE;
+	if (flags & S_IXUNLINK)
+		ip->i_d.di_flags |= XFS_DIFLAG_IXUNLINK;
+	else
+		ip->i_d.di_flags &= ~XFS_DIFLAG_IXUNLINK;
+
+	if (vflags & V_BARRIER)
+		ip->i_d.di_vflags |= XFS_DIVFLAG_BARRIER;
+	else
+		ip->i_d.di_vflags &= ~XFS_DIVFLAG_BARRIER;
+	if (vflags & V_COW)
+		ip->i_d.di_vflags |= XFS_DIVFLAG_COW;
+	else
+		ip->i_d.di_vflags &= ~XFS_DIVFLAG_COW;
+}
+
+int
+xfs_sync_flags(
+	struct inode		*inode,
+	int			flags,
+	int			vflags)
+{
+	struct xfs_inode	*ip = XFS_I(inode);
+	struct xfs_mount	*mp = ip->i_mount;
+	struct xfs_trans        *tp;
+	unsigned int		lock_flags = 0;
+	int			code;
+
+	tp = xfs_trans_alloc(mp, XFS_TRANS_SETATTR_NOT_SIZE);
+	code = xfs_trans_reserve(tp, 0, XFS_ICHANGE_LOG_RES(mp), 0, 0, 0);
+	if (code)
+		goto error_out;
+
+	xfs_ilock(ip, XFS_ILOCK_EXCL);
+	xfs_trans_ijoin(tp, ip, 0);
+
+	inode->i_flags = flags;
+	inode->i_vflags = vflags;
+	xfs_get_inode_flags(ip);
+
+	xfs_trans_log_inode(tp, ip, XFS_ILOG_CORE);
+	xfs_trans_ichgtime(tp, ip, XFS_ICHGTIME_CHG);
+
+	XFS_STATS_INC(xs_ig_attrchg);
+
+	if (mp->m_flags & XFS_MOUNT_WSYNC)
+		xfs_trans_set_sync(tp);
+	code = xfs_trans_commit(tp, 0);
+	xfs_iunlock(ip, XFS_ILOCK_EXCL);
+	return code;
+
+error_out:
+	xfs_trans_cancel(tp, 0);
+	if (lock_flags)
+		xfs_iunlock(ip, XFS_ILOCK_EXCL);
+	return code;
+}
+
+
 int
 xfs_readlink(
 	xfs_inode_t     *ip,
_______________________________________________
xfs mailing list
xfs@xxxxxxxxxxx
http://oss.sgi.com/mailman/listinfo/xfs

[Index of Archives]     [Linux XFS Devel]     [Linux Filesystem Development]     [Filesystem Testing]     [Linux USB Devel]     [Linux Audio Users]     [Yosemite News]     [Linux Kernel]     [Linux SCSI]

  Powered by Linux