diff -NurpP --minimal linux-2.6.27.4-vs2.3.0.35.7/fs/xfs/linux-2.6/xfs_ioctl.c linux-2.6.27.4-vs2.3.0.35.7.x/fs/xfs/linux-2.6/xfs_ioctl.c
--- linux-2.6.27.4-vs2.3.0.35.7/fs/xfs/linux-2.6/xfs_ioctl.c	2008-10-24 03:58:56.000000000 +0200
+++ linux-2.6.27.4-vs2.3.0.35.7.x/fs/xfs/linux-2.6/xfs_ioctl.c	2008-11-01 16:05:41.000000000 +0100
@@ -806,6 +806,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
@@ -834,6 +838,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)
@@ -892,6 +898,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)
@@ -934,6 +942,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
@@ -1392,10 +1404,18 @@ xfs_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: {
diff -NurpP --minimal linux-2.6.27.4-vs2.3.0.35.7/fs/xfs/linux-2.6/xfs_iops.c linux-2.6.27.4-vs2.3.0.35.7.x/fs/xfs/linux-2.6/xfs_iops.c
--- linux-2.6.27.4-vs2.3.0.35.7/fs/xfs/linux-2.6/xfs_iops.c	2008-10-24 03:59:17.000000000 +0200
+++ linux-2.6.27.4-vs2.3.0.35.7.x/fs/xfs/linux-2.6/xfs_iops.c	2008-11-01 07:43:34.000000000 +0100
@@ -53,6 +53,7 @@
 #include <linux/namei.h>
 #include <linux/security.h>
 #include <linux/falloc.h>
+#include <linux/vs_tag.h>
 
 /*
  * Bring the atime in the XFS inode uptodate.
@@ -558,6 +559,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;
 #if XFS_BIG_INUMS
 	stat->ino += mp->m_inoadd;
@@ -597,6 +599,12 @@ xfs_vn_getattr(
 }
 
 STATIC int
+xfs_vn_sync_xflags(struct inode *inode)
+{
+	return -xfs_sync_xflags(XFS_I(inode));
+}
+
+STATIC int
 xfs_vn_setattr(
 	struct dentry	*dentry,
 	struct iattr	*iattr)
@@ -671,6 +679,7 @@ static const struct inode_operations xfs
 	.removexattr		= generic_removexattr,
 	.listxattr		= xfs_vn_listxattr,
 	.fallocate		= xfs_vn_fallocate,
+	.sync_flags		= xfs_vn_sync_xflags,
 };
 
 static const struct inode_operations xfs_dir_inode_operations = {
@@ -696,6 +705,7 @@ static const struct inode_operations xfs
 	.getxattr		= generic_getxattr,
 	.removexattr		= generic_removexattr,
 	.listxattr		= xfs_vn_listxattr,
+	.sync_flags		= xfs_vn_sync_xflags,
 };
 
 static const struct inode_operations xfs_dir_ci_inode_operations = {
@@ -745,6 +755,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
@@ -757,6 +771,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;
 }
 
 /*
@@ -777,6 +800,7 @@ xfs_setup_inode(
 	inode->i_nlink	= 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:
diff -NurpP --minimal linux-2.6.27.4-vs2.3.0.35.7/fs/xfs/linux-2.6/xfs_super.c linux-2.6.27.4-vs2.3.0.35.7.x/fs/xfs/linux-2.6/xfs_super.c
--- linux-2.6.27.4-vs2.3.0.35.7/fs/xfs/linux-2.6/xfs_super.c	2008-10-24 03:59:37.000000000 +0200
+++ linux-2.6.27.4-vs2.3.0.35.7.x/fs/xfs/linux-2.6/xfs_super.c	2008-11-01 04:41:10.000000000 +0100
@@ -147,6 +147,9 @@ xfs_args_allocate(
 #define MNTOPT_DMAPI	"dmapi"		/* DMI enabled (DMAPI / XDSM) */
 #define MNTOPT_XDSM	"xdsm"		/* DMI enabled (DMAPI / XDSM) */
 #define MNTOPT_DMI	"dmi"		/* DMI enabled (DMAPI / XDSM) */
+#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.
@@ -155,10 +158,14 @@ xfs_args_allocate(
  * in the future, too.
  */
 enum {
+	Opt_tag, Opt_notag,
 	Opt_barrier, Opt_nobarrier, Opt_err
 };
 
 static match_table_t tokens = {
+	{Opt_tag, "tagxid"},
+	{Opt_tag, "tag"},
+	{Opt_notag, "notag"},
 	{Opt_barrier, "barrier"},
 	{Opt_nobarrier, "nobarrier"},
 	{Opt_err, NULL}
@@ -383,6 +390,19 @@ xfs_parseargs(
 		} else if (!strcmp(this_char, "irixsgid")) {
 			cmn_err(CE_WARN,
 	"XFS: irixsgid is now a sysctl(2) variable, option is deprecated.");
+#ifndef CONFIG_TAGGING_NONE
+		} else if (!strcmp(this_char, MNTOPT_TAGGED)) {
+			args->flags2 |= XFSMNT2_TAGGED;
+		} else if (!strcmp(this_char, MNTOPT_NOTAGTAG)) {
+			args->flags2 &= ~XFSMNT2_TAGGED;
+		} else if (!strcmp(this_char, MNTOPT_TAGXID)) {
+			args->flags2 |= XFSMNT2_TAGGED;
+#endif
+#ifdef CONFIG_PROPAGATE
+		} else if (!strcmp(this_char, MNTOPT_TAGGED)) {
+			/* use value */
+			args->flags2 |= XFSMNT2_TAGGED;
+#endif
 		} else {
 			cmn_err(CE_WARN,
 				"XFS: unknown mount option [%s].", this_char);
@@ -1301,6 +1321,16 @@ xfs_fs_remount(
 		case Opt_nobarrier:
 			mp->m_flags &= ~XFS_MOUNT_BARRIER;
 			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
@@ -1555,6 +1585,9 @@ xfs_start_flags(
 
 	if (ap->flags & XFSMNT_DMAPI)
 		mp->m_flags |= XFS_MOUNT_DMAPI;
+
+	if (ap->flags2 & XFSMNT2_TAGGED)
+		mp->m_flags |= XFS_MOUNT_TAGGED;
 	return 0;
 
 
@@ -1749,6 +1782,9 @@ xfs_fs_fill_super(
 
 	XFS_SEND_MOUNT(mp, DM_RIGHT_NULL, args->mtpt, args->fsname);
 
+	if (mp->m_flags & XFS_MOUNT_TAGGED)
+		sb->s_flags |= MS_TAGGED;
+
 	sb->s_dirt = 1;
 	sb->s_magic = XFS_SB_MAGIC;
 	sb->s_blocksize = mp->m_sb.sb_blocksize;
diff -NurpP --minimal linux-2.6.27.4-vs2.3.0.35.7/fs/xfs/xfs_dinode.h linux-2.6.27.4-vs2.3.0.35.7.x/fs/xfs/xfs_dinode.h
--- linux-2.6.27.4-vs2.3.0.35.7/fs/xfs/xfs_dinode.h	2008-10-24 03:47:08.000000000 +0200
+++ linux-2.6.27.4-vs2.3.0.35.7.x/fs/xfs/xfs_dinode.h	2008-11-01 03:45:54.000000000 +0100
@@ -53,7 +53,9 @@ typedef struct xfs_dinode_core {
 	__be32		di_gid;		/* owner's group id */
 	__be32		di_nlink;	/* number of links to file */
 	__be16		di_projid;	/* owner's project id */
-	__u8		di_pad[8];	/* unused, zeroed space */
+	__be16		di_tag;		/* context tagging */
+	__be16		di_vflags;	/* vserver specific flags */
+	__u8		di_pad[4];	/* unused, zeroed space */
 	__be16		di_flushiter;	/* incremented on flush */
 	xfs_timestamp_t	di_atime;	/* time last accessed */
 	xfs_timestamp_t	di_mtime;	/* time last modified */
diff -NurpP --minimal linux-2.6.27.4-vs2.3.0.35.7/fs/xfs/xfs_ialloc.c linux-2.6.27.4-vs2.3.0.35.7.x/fs/xfs/xfs_ialloc.c
--- linux-2.6.27.4-vs2.3.0.35.7/fs/xfs/xfs_ialloc.c	2008-10-24 03:47:08.000000000 +0200
+++ linux-2.6.27.4-vs2.3.0.35.7.x/fs/xfs/xfs_ialloc.c	2008-11-01 03:27:16.000000000 +0100
@@ -84,6 +84,8 @@ xfs_ialloc_log_di(
 		offsetof(xfs_dinode_t, di_next_unlinked),
 		offsetof(xfs_dinode_t, di_u),
 		offsetof(xfs_dinode_t, di_a),
+		offsetof(xfs_dinode_core_t, di_tag),
+		offsetof(xfs_dinode_core_t, di_vflags),
 		sizeof(xfs_dinode_t)
 	};
 
diff -NurpP --minimal linux-2.6.27.4-vs2.3.0.35.7/fs/xfs/xfs_inode.c linux-2.6.27.4-vs2.3.0.35.7.x/fs/xfs/xfs_inode.c
--- linux-2.6.27.4-vs2.3.0.35.7/fs/xfs/xfs_inode.c	2008-10-24 03:56:31.000000000 +0200
+++ linux-2.6.27.4-vs2.3.0.35.7.x/fs/xfs/xfs_inode.c	2008-11-01 08:00:29.000000000 +0100
@@ -249,6 +249,7 @@ xfs_inotobp(
 	return 0;
 }
 
+#include <linux/vs_tag.h>
 
 /*
  * This routine is called to map an inode to the buffer containing
@@ -660,15 +661,25 @@ xfs_iformat_btree(
 void
 xfs_dinode_from_disk(
 	xfs_icdinode_t		*to,
-	xfs_dinode_core_t	*from)
+	xfs_dinode_core_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 = be16_to_cpu(from->di_projid);
 	memcpy(to->di_pad, from->di_pad, sizeof(to->di_pad));
@@ -689,21 +700,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_core_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 = cpu_to_be16(from->di_projid);
 	memcpy(to->di_pad, from->di_pad, sizeof(to->di_pad));
@@ -724,12 +740,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;
 
@@ -740,6 +758,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)
@@ -764,6 +784,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;
 }
 
@@ -773,7 +797,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);
 }
 
@@ -783,7 +807,8 @@ xfs_dic2xflags(
 {
 	xfs_dinode_core_t	*dic = &dip->di_core;
 
-	return _xfs_dic2xflags(be16_to_cpu(dic->di_flags)) |
+	return _xfs_dic2xflags(be16_to_cpu(dic->di_flags),
+				be16_to_cpu(dic->di_vflags)) |
 				(XFS_DFORK_Q(dip) ? XFS_XFLAG_HASATTR : 0);
 }
 
@@ -878,7 +903,8 @@ xfs_iread(
 	 * Otherwise, just get the truly permanent information.
 	 */
 	if (dip->di_core.di_mode) {
-		xfs_dinode_from_disk(&ip->i_d, &dip->di_core);
+		xfs_dinode_from_disk(&ip->i_d, &dip->di_core,
+			mp->m_flags & XFS_MOUNT_TAGGED);
 		error = xfs_iformat(ip, dip);
 		if (error)  {
 			kmem_zone_free(xfs_inode_zone, ip);
@@ -1083,6 +1109,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(cr, ip->i_vnode);
 	ip->i_d.di_projid = prid;
 	memset(&(ip->i_d.di_pad[0]), 0, sizeof(ip->i_d.di_pad));
 
@@ -1143,6 +1170,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:
@@ -2249,6 +2277,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_df.if_ext_max =
@@ -3342,7 +3371,8 @@ xfs_iflush_int(
 	 * because if the inode is dirty at all the core must
 	 * be.
 	 */
-	xfs_dinode_to_disk(&dip->di_core, &ip->i_d);
+	xfs_dinode_to_disk(&dip->di_core, &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)
diff -NurpP --minimal linux-2.6.27.4-vs2.3.0.35.7/fs/xfs/xfs_inode.h linux-2.6.27.4-vs2.3.0.35.7.x/fs/xfs/xfs_inode.h
--- linux-2.6.27.4-vs2.3.0.35.7/fs/xfs/xfs_inode.h	2008-10-24 03:47:08.000000000 +0200
+++ linux-2.6.27.4-vs2.3.0.35.7.x/fs/xfs/xfs_inode.h	2008-11-01 04:51:52.000000000 +0100
@@ -173,7 +173,9 @@ typedef struct xfs_icdinode {
 	__uint32_t	di_gid;		/* owner's group id */
 	__uint32_t	di_nlink;	/* number of links to file */
 	__uint16_t	di_projid;	/* owner's project id */
-	__uint8_t	di_pad[8];	/* unused, zeroed space */
+	__uint16_t	di_tag;		/* context tagging */
+	__uint16_t	di_vflags;	/* vserver specific flags */
+	__uint8_t	di_pad[4];	/* unused, zeroed space */
 	__uint16_t	di_flushiter;	/* incremented on flush */
 	xfs_ictimestamp_t di_atime;	/* time last accessed */
 	xfs_ictimestamp_t di_mtime;	/* time last modified */
@@ -500,9 +502,9 @@ int		xfs_ialloc(struct xfs_trans *, xfs_
 			   xfs_nlink_t, xfs_dev_t, struct cred *, xfs_prid_t,
 			   int, struct xfs_buf **, boolean_t *, xfs_inode_t **);
 void		xfs_dinode_from_disk(struct xfs_icdinode *,
-				     struct xfs_dinode_core *);
+				     struct xfs_dinode_core *, int tagged);
 void		xfs_dinode_to_disk(struct xfs_dinode_core *,
-				   struct xfs_icdinode *);
+				   struct xfs_icdinode *, int tagged);
 
 uint		xfs_ip2xflags(struct xfs_inode *);
 uint		xfs_dic2xflags(struct xfs_dinode *);
diff -NurpP --minimal linux-2.6.27.4-vs2.3.0.35.7/fs/xfs/xfs_itable.c linux-2.6.27.4-vs2.3.0.35.7.x/fs/xfs/xfs_itable.c
--- linux-2.6.27.4-vs2.3.0.35.7/fs/xfs/xfs_itable.c	2008-10-24 03:57:28.000000000 +0200
+++ linux-2.6.27.4-vs2.3.0.35.7.x/fs/xfs/xfs_itable.c	2008-11-01 03:27:16.000000000 +0100
@@ -82,6 +82,7 @@ xfs_bulkstat_one_iget(
 	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;
 	vn_atime_to_bstime(VFS_I(ip), &buf->bs_atime);
 	buf->bs_mtime.tv_sec = dic->di_mtime.t_sec;
diff -NurpP --minimal linux-2.6.27.4-vs2.3.0.35.7/fs/xfs/xfs_log_recover.c linux-2.6.27.4-vs2.3.0.35.7.x/fs/xfs/xfs_log_recover.c
--- linux-2.6.27.4-vs2.3.0.35.7/fs/xfs/xfs_log_recover.c	2008-10-24 03:47:08.000000000 +0200
+++ linux-2.6.27.4-vs2.3.0.35.7.x/fs/xfs/xfs_log_recover.c	2008-11-01 04:51:52.000000000 +0100
@@ -2417,7 +2417,8 @@ xlog_recover_do_inode_trans(
 
 	/* The core is in in-core format */
 	xfs_dinode_to_disk(&dip->di_core,
-		(xfs_icdinode_t *)item->ri_buf[1].i_addr);
+		(xfs_icdinode_t *)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(xfs_dinode_core_t)) {
diff -NurpP --minimal linux-2.6.27.4-vs2.3.0.35.7/fs/xfs/xfs_vnodeops.c linux-2.6.27.4-vs2.3.0.35.7.x/fs/xfs/xfs_vnodeops.c
--- linux-2.6.27.4-vs2.3.0.35.7/fs/xfs/xfs_vnodeops.c	2008-10-24 03:58:20.000000000 +0200
+++ linux-2.6.27.4-vs2.3.0.35.7.x/fs/xfs/xfs_vnodeops.c	2008-11-01 07:40:48.000000000 +0100
@@ -75,6 +75,89 @@ xfs_open(
 	return 0;
 }
 
+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_xflags(
+	xfs_inode_t		*ip)
+{
+	struct xfs_mount	*mp = ip->i_mount;
+	struct xfs_trans	*tp;	
+	unsigned int		lock_flags = 0;
+	int			code;
+
+	xfs_itrace_entry(ip);
+
+	if (mp->m_flags & XFS_MOUNT_RDONLY)
+		return XFS_ERROR(EROFS);
+
+	/*
+	 * we acquire the inode lock and do an error checking pass.
+	 */
+	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_return;
+
+	lock_flags = XFS_ILOCK_EXCL;
+	xfs_ilock(ip, lock_flags);
+
+	xfs_trans_ijoin(tp, ip, lock_flags);
+	xfs_trans_ihold(tp, ip);
+
+	xfs_get_inode_flags(ip);
+	// xfs_diflags_to_linux(ip);
+
+	xfs_trans_log_inode(tp, ip, XFS_ILOG_CORE);
+	xfs_ichgtime(ip, XFS_ICHGTIME_CHG);
+
+	XFS_STATS_INC(xs_ig_attrchg);
+
+	/*
+	 * If this is a synchronous mount, make sure that the
+	 * transaction goes to disk before returning to the user.
+	 */
+	if (mp->m_flags & XFS_MOUNT_WSYNC)
+		xfs_trans_set_sync(tp);
+	code = xfs_trans_commit(tp, 0);
+	xfs_iunlock(ip, lock_flags);
+ 
+	if (code)
+		return code;
+	return 0;
+
+ error_return:
+	xfs_trans_cancel(tp, 0);
+	if (lock_flags)
+		xfs_iunlock(ip, lock_flags);
+	return code;
+}
+
 int
 xfs_setattr(
 	struct xfs_inode	*ip,
@@ -91,6 +174,7 @@ xfs_setattr(
 	uint			commit_flags=0;
 	uid_t			uid=0, iuid=0;
 	gid_t			gid=0, igid=0;
+	tag_t			tag=0, itag=0;
 	int			timeflags = 0;
 	struct xfs_dquot	*udqp, *gdqp, *olddquot1, *olddquot2;
 	int			file_owner;
@@ -238,7 +322,7 @@ xfs_setattr(
 	 * and can change the group id only to a group of which he
 	 * or she is a member.
 	 */
-	if (mask & (ATTR_UID|ATTR_GID)) {
+	if (mask & (ATTR_UID|ATTR_GID|ATTR_TAG)) {
 		/*
 		 * These IDs could have changed since we last looked at them.
 		 * But, we're assured that if the ownership did change
@@ -247,8 +331,10 @@ xfs_setattr(
 		 */
 		iuid = ip->i_d.di_uid;
 		igid = ip->i_d.di_gid;
+		itag = ip->i_d.di_tag;
 		gid = (mask & ATTR_GID) ? iattr->ia_gid : igid;
 		uid = (mask & ATTR_UID) ? iattr->ia_uid : iuid;
+		tag = (mask & ATTR_TAG) ? iattr->ia_tag : itag;
 
 		/*
 		 * CAP_CHOWN overrides the following restrictions:
@@ -272,7 +358,9 @@ xfs_setattr(
 		 * going to change.
 		 */
 		if ((XFS_IS_UQUOTA_ON(mp) && iuid != uid) ||
-		    (XFS_IS_GQUOTA_ON(mp) && igid != gid)) {
+		    (XFS_IS_GQUOTA_ON(mp) && igid != gid) ||
+		    (XFS_IS_GQUOTA_ON(mp) && itag != tag)) {
+			/* TODO: handle tagging? */
 			ASSERT(tp);
 			code = XFS_QM_DQVOPCHOWNRESV(mp, tp, ip, udqp, gdqp,
 						capable(CAP_FOWNER) ?
@@ -461,7 +549,7 @@ xfs_setattr(
 	 * and can change the group id only to a group of which he
 	 * or she is a member.
 	 */
-	if (mask & (ATTR_UID|ATTR_GID)) {
+	if (mask & (ATTR_UID|ATTR_GID|ATTR_TAG)) {
 		/*
 		 * CAP_FSETID overrides the following restrictions:
 		 *
@@ -477,6 +565,10 @@ xfs_setattr(
 		 * Change the ownerships and register quota modifications
 		 * in the transaction.
 		 */
+		if (itag != tag) {
+			ip->i_d.di_tag = tag;
+			inode->i_tag = tag;
+		}
 		if (iuid != uid) {
 			if (XFS_IS_UQUOTA_ON(mp)) {
 				ASSERT(mask & ATTR_UID);
diff -NurpP --minimal linux-2.6.27.4-vs2.3.0.35.7/fs/xfs/xfs_vnodeops.h linux-2.6.27.4-vs2.3.0.35.7.x/fs/xfs/xfs_vnodeops.h
--- linux-2.6.27.4-vs2.3.0.35.7/fs/xfs/xfs_vnodeops.h	2008-10-13 14:52:06.000000000 +0200
+++ linux-2.6.27.4-vs2.3.0.35.7.x/fs/xfs/xfs_vnodeops.h	2008-11-01 07:18:06.000000000 +0100
@@ -15,6 +15,7 @@ struct xfs_iomap;
 
 
 int xfs_open(struct xfs_inode *ip);
+int xfs_sync_xflags(struct xfs_inode *ip);
 int xfs_setattr(struct xfs_inode *ip, struct iattr *vap, int flags,
 		struct cred *credp);
 #define	XFS_ATTR_DMI		0x01	/* invocation from a DMI function */
