--- linux-2.6.12.2/fs/attr.c 2005-06-22 02:38:33 +0200 +++ linux-2.6.12.2-vs2.0-rc6.1/fs/attr.c 2005-07-02 22:38:30 +0200 @@ -87,6 +130,8 @@ int inode_setattr(struct inode * inode, inode->i_uid = attr->ia_uid; if (ia_valid & ATTR_GID) inode->i_gid = attr->ia_gid; + if (ia_valid & ATTR_XID) + inode->i_xid = attr->ia_xid; if (ia_valid & ATTR_ATIME) inode->i_atime = timespec_trunc(attr->ia_atime, inode->i_sb->s_time_gran); --- linux-2.6.12.2/fs/attr.c 2005-06-22 02:38:33 +0200 +++ linux-2.6.12.2-vs2.0-rc6.1/fs/attr.c 2005-07-02 22:38:30 +0200 @@ -118,6 +165,8 @@ int setattr_mask(unsigned int ia_valid) dn_mask |= DN_ATTRIB; if (ia_valid & ATTR_GID) dn_mask |= DN_ATTRIB; + if (ia_valid & ATTR_XID) + dn_mask |= DN_ATTRIB; if (ia_valid & ATTR_SIZE) dn_mask |= DN_MODIFY; /* both times implies a utime(s) call */ --- linux-2.6.12.2/fs/attr.c 2005-06-22 02:38:33 +0200 +++ linux-2.6.12.2-vs2.0-rc6.1/fs/attr.c 2005-07-02 22:38:30 +0200 @@ -187,7 +236,8 @@ int notify_change(struct dentry * dentry error = security_inode_setattr(dentry, attr); if (!error) { if ((ia_valid & ATTR_UID && attr->ia_uid != inode->i_uid) || - (ia_valid & ATTR_GID && attr->ia_gid != inode->i_gid)) + (ia_valid & ATTR_GID && attr->ia_gid != inode->i_gid) || + (ia_valid & ATTR_XID && attr->ia_xid != inode->i_xid)) error = DQUOT_TRANSFER(inode, attr) ? -EDQUOT : 0; if (!error) error = inode_setattr(inode, attr); --- linux-2.6.12.2/fs/ext2/inode.c 2005-06-22 02:38:35 +0200 +++ linux-2.6.12.2-vs2.0-rc6.1/fs/ext2/inode.c 2005-07-02 22:38:30 +0200 @@ -1047,6 +1059,8 @@ void ext2_read_inode (struct inode * ino ino_t ino = inode->i_ino; struct buffer_head * bh; struct ext2_inode * raw_inode = ext2_get_inode(inode->i_sb, ino, &bh); + uid_t uid; + gid_t gid; int n; #ifdef CONFIG_EXT2_FS_POSIX_ACL --- linux-2.6.12.2/fs/ext2/inode.c 2005-06-22 02:38:35 +0200 +++ linux-2.6.12.2-vs2.0-rc6.1/fs/ext2/inode.c 2005-07-02 22:38:30 +0200 @@ -1057,12 +1071,17 @@ void ext2_read_inode (struct inode * ino goto bad_inode; inode->i_mode = le16_to_cpu(raw_inode->i_mode); - inode->i_uid = (uid_t)le16_to_cpu(raw_inode->i_uid_low); - inode->i_gid = (gid_t)le16_to_cpu(raw_inode->i_gid_low); + uid = (uid_t)le16_to_cpu(raw_inode->i_uid_low); + gid = (gid_t)le16_to_cpu(raw_inode->i_gid_low); if (!(test_opt (inode->i_sb, NO_UID32))) { - inode->i_uid |= le16_to_cpu(raw_inode->i_uid_high) << 16; - inode->i_gid |= le16_to_cpu(raw_inode->i_gid_high) << 16; + uid |= le16_to_cpu(raw_inode->i_uid_high) << 16; + gid |= le16_to_cpu(raw_inode->i_gid_high) << 16; } + inode->i_uid = INOXID_UID(XID_TAG(inode), uid, gid); + inode->i_gid = INOXID_GID(XID_TAG(inode), uid, gid); + inode->i_xid = INOXID_XID(XID_TAG(inode), uid, gid, + le16_to_cpu(raw_inode->i_raw_xid)); + inode->i_nlink = le16_to_cpu(raw_inode->i_links_count); inode->i_size = le32_to_cpu(raw_inode->i_size); inode->i_atime.tv_sec = le32_to_cpu(raw_inode->i_atime); --- linux-2.6.12.2/fs/ext2/inode.c 2005-06-22 02:38:35 +0200 +++ linux-2.6.12.2-vs2.0-rc6.1/fs/ext2/inode.c 2005-07-02 22:38:30 +0200 @@ -1155,8 +1174,8 @@ static int ext2_update_inode(struct inod struct ext2_inode_info *ei = EXT2_I(inode); struct super_block *sb = inode->i_sb; ino_t ino = inode->i_ino; - uid_t uid = inode->i_uid; - gid_t gid = inode->i_gid; + uid_t uid = XIDINO_UID(XID_TAG(inode), inode->i_uid, inode->i_xid); + gid_t gid = XIDINO_GID(XID_TAG(inode), inode->i_gid, inode->i_xid); struct buffer_head * bh; struct ext2_inode * raw_inode = ext2_get_inode(sb, ino, &bh); int n; --- linux-2.6.12.2/fs/ext2/inode.c 2005-06-22 02:38:35 +0200 +++ linux-2.6.12.2-vs2.0-rc6.1/fs/ext2/inode.c 2005-07-02 22:38:30 +0200 @@ -1191,6 +1210,9 @@ static int ext2_update_inode(struct inod raw_inode->i_uid_high = 0; raw_inode->i_gid_high = 0; } +#ifdef CONFIG_INOXID_INTERN + raw_inode->i_raw_xid = cpu_to_le16(inode->i_xid); +#endif raw_inode->i_links_count = cpu_to_le16(inode->i_nlink); raw_inode->i_size = cpu_to_le32(inode->i_size); raw_inode->i_atime = cpu_to_le32(inode->i_atime.tv_sec); --- linux-2.6.12.2/fs/ext2/inode.c 2005-06-22 02:38:35 +0200 +++ linux-2.6.12.2-vs2.0-rc6.1/fs/ext2/inode.c 2005-07-02 22:38:30 +0200 @@ -1277,11 +1320,15 @@ int ext2_setattr(struct dentry *dentry, if (error) return error; if ((iattr->ia_valid & ATTR_UID && iattr->ia_uid != inode->i_uid) || - (iattr->ia_valid & ATTR_GID && iattr->ia_gid != inode->i_gid)) { + (iattr->ia_valid & ATTR_GID && iattr->ia_gid != inode->i_gid) || + (iattr->ia_valid & ATTR_XID && iattr->ia_xid != inode->i_xid)) { error = DQUOT_TRANSFER(inode, iattr) ? -EDQUOT : 0; if (error) return error; } + if (iattr->ia_valid & ATTR_ATTR_FLAG) + ext2_setattr_flags(inode, iattr->ia_attr_flags); + error = inode_setattr(inode, iattr); if (!error && (iattr->ia_valid & ATTR_MODE)) error = ext2_acl_chmod(inode); --- linux-2.6.12.2/fs/ext2/namei.c 2005-03-02 12:38:44 +0100 +++ linux-2.6.12.2-vs2.0-rc6.1/fs/ext2/namei.c 2005-07-02 22:38:30 +0200 @@ -81,6 +82,7 @@ static struct dentry *ext2_lookup(struct inode = iget(dir->i_sb, ino); if (!inode) return ERR_PTR(-EACCES); + vx_propagate_xid(nd, inode); } if (inode) return d_splice_alias(inode, dentry); --- linux-2.6.12.2/fs/ext2/super.c 2005-06-22 02:38:35 +0200 +++ linux-2.6.12.2-vs2.0-rc6.1/fs/ext2/super.c 2005-07-02 22:38:30 +0200 @@ -257,7 +257,7 @@ enum { Opt_bsd_df, Opt_minix_df, Opt_grpid, Opt_nogrpid, Opt_resgid, Opt_resuid, Opt_sb, Opt_err_cont, Opt_err_panic, Opt_err_ro, Opt_nouid32, Opt_check, Opt_nocheck, Opt_debug, Opt_oldalloc, Opt_orlov, Opt_nobh, - Opt_user_xattr, Opt_nouser_xattr, Opt_acl, Opt_noacl, + Opt_user_xattr, Opt_nouser_xattr, Opt_acl, Opt_noacl, Opt_tagxid, Opt_ignore, Opt_err, }; --- linux-2.6.12.2/fs/ext2/super.c 2005-06-22 02:38:35 +0200 +++ linux-2.6.12.2-vs2.0-rc6.1/fs/ext2/super.c 2005-07-02 22:38:30 +0200 @@ -286,6 +286,7 @@ static match_table_t tokens = { {Opt_nouser_xattr, "nouser_xattr"}, {Opt_acl, "acl"}, {Opt_noacl, "noacl"}, + {Opt_tagxid, "tagxid"}, {Opt_ignore, "grpquota"}, {Opt_ignore, "noquota"}, {Opt_ignore, "quota"}, --- linux-2.6.12.2/fs/ext2/super.c 2005-06-22 02:38:35 +0200 +++ linux-2.6.12.2-vs2.0-rc6.1/fs/ext2/super.c 2005-07-02 22:38:30 +0200 @@ -349,6 +350,11 @@ static int parse_options (char * options case Opt_nouid32: set_opt (sbi->s_mount_opt, NO_UID32); break; +#ifndef CONFIG_INOXID_NONE + case Opt_tagxid: + set_opt (sbi->s_mount_opt, TAG_XID); + break; +#endif case Opt_check: #ifdef CONFIG_EXT2_CHECK set_opt (sbi->s_mount_opt, CHECK); --- linux-2.6.12.2/fs/ext2/super.c 2005-06-22 02:38:35 +0200 +++ linux-2.6.12.2-vs2.0-rc6.1/fs/ext2/super.c 2005-07-02 22:38:30 +0200 @@ -636,6 +642,8 @@ static int ext2_fill_super(struct super_ if (!parse_options ((char *) data, sbi)) goto failed_mount; + if (EXT2_SB(sb)->s_mount_opt & EXT2_MOUNT_TAG_XID) + sb->s_flags |= MS_TAGXID; sb->s_flags = (sb->s_flags & ~MS_POSIXACL) | ((EXT2_SB(sb)->s_mount_opt & EXT2_MOUNT_POSIX_ACL) ? MS_POSIXACL : 0); --- linux-2.6.12.2/fs/ext3/inode.c 2005-06-22 02:38:36 +0200 +++ linux-2.6.12.2-vs2.0-rc6.1/fs/ext3/inode.c 2005-07-02 22:38:30 +0200 @@ -2430,6 +2442,8 @@ void ext3_read_inode(struct inode * inod struct ext3_inode_info *ei = EXT3_I(inode); struct buffer_head *bh; int block; + uid_t uid; + gid_t gid; #ifdef CONFIG_EXT3_FS_POSIX_ACL ei->i_acl = EXT3_ACL_NOT_CACHED; --- linux-2.6.12.2/fs/ext3/inode.c 2005-06-22 02:38:36 +0200 +++ linux-2.6.12.2-vs2.0-rc6.1/fs/ext3/inode.c 2005-07-02 22:38:30 +0200 @@ -2442,12 +2456,17 @@ void ext3_read_inode(struct inode * inod bh = iloc.bh; raw_inode = ext3_raw_inode(&iloc); inode->i_mode = le16_to_cpu(raw_inode->i_mode); - inode->i_uid = (uid_t)le16_to_cpu(raw_inode->i_uid_low); - inode->i_gid = (gid_t)le16_to_cpu(raw_inode->i_gid_low); + uid = (uid_t)le16_to_cpu(raw_inode->i_uid_low); + gid = (gid_t)le16_to_cpu(raw_inode->i_gid_low); if(!(test_opt (inode->i_sb, NO_UID32))) { - inode->i_uid |= le16_to_cpu(raw_inode->i_uid_high) << 16; - inode->i_gid |= le16_to_cpu(raw_inode->i_gid_high) << 16; + uid |= le16_to_cpu(raw_inode->i_uid_high) << 16; + gid |= le16_to_cpu(raw_inode->i_gid_high) << 16; } + inode->i_uid = INOXID_UID(XID_TAG(inode), uid, gid); + inode->i_gid = INOXID_GID(XID_TAG(inode), uid, gid); + inode->i_xid = INOXID_XID(XID_TAG(inode), uid, gid, + le16_to_cpu(raw_inode->i_raw_xid)); + inode->i_nlink = le16_to_cpu(raw_inode->i_links_count); inode->i_size = le32_to_cpu(raw_inode->i_size); inode->i_atime.tv_sec = le32_to_cpu(raw_inode->i_atime); --- linux-2.6.12.2/fs/ext3/inode.c 2005-06-22 02:38:36 +0200 +++ linux-2.6.12.2-vs2.0-rc6.1/fs/ext3/inode.c 2005-07-02 22:38:30 +0200 @@ -2574,6 +2593,8 @@ static int ext3_do_update_inode(handle_t struct ext3_inode *raw_inode = ext3_raw_inode(iloc); struct ext3_inode_info *ei = EXT3_I(inode); struct buffer_head *bh = iloc->bh; + uid_t uid = XIDINO_UID(XID_TAG(inode), inode->i_uid, inode->i_xid); + gid_t gid = XIDINO_GID(XID_TAG(inode), inode->i_gid, inode->i_xid); int err = 0, rc, block; /* For fields not not tracking in the in-memory inode, --- linux-2.6.12.2/fs/ext3/inode.c 2005-06-22 02:38:36 +0200 +++ linux-2.6.12.2-vs2.0-rc6.1/fs/ext3/inode.c 2005-07-02 22:38:30 +0200 @@ -2583,29 +2604,32 @@ static int ext3_do_update_inode(handle_t raw_inode->i_mode = cpu_to_le16(inode->i_mode); if(!(test_opt(inode->i_sb, NO_UID32))) { - raw_inode->i_uid_low = cpu_to_le16(low_16_bits(inode->i_uid)); - raw_inode->i_gid_low = cpu_to_le16(low_16_bits(inode->i_gid)); + raw_inode->i_uid_low = cpu_to_le16(low_16_bits(uid)); + raw_inode->i_gid_low = cpu_to_le16(low_16_bits(gid)); /* * Fix up interoperability with old kernels. Otherwise, old inodes get * re-used with the upper 16 bits of the uid/gid intact */ if(!ei->i_dtime) { raw_inode->i_uid_high = - cpu_to_le16(high_16_bits(inode->i_uid)); + cpu_to_le16(high_16_bits(uid)); raw_inode->i_gid_high = - cpu_to_le16(high_16_bits(inode->i_gid)); + cpu_to_le16(high_16_bits(gid)); } else { raw_inode->i_uid_high = 0; raw_inode->i_gid_high = 0; } } else { raw_inode->i_uid_low = - cpu_to_le16(fs_high2lowuid(inode->i_uid)); + cpu_to_le16(fs_high2lowuid(uid)); raw_inode->i_gid_low = - cpu_to_le16(fs_high2lowgid(inode->i_gid)); + cpu_to_le16(fs_high2lowgid(gid)); raw_inode->i_uid_high = 0; raw_inode->i_gid_high = 0; } +#ifdef CONFIG_INOXID_INTERN + raw_inode->i_raw_xid = cpu_to_le16(inode->i_xid); +#endif raw_inode->i_links_count = cpu_to_le16(inode->i_nlink); raw_inode->i_size = cpu_to_le32(ei->i_disksize); raw_inode->i_atime = cpu_to_le32(inode->i_atime.tv_sec); --- linux-2.6.12.2/fs/ext3/inode.c 2005-06-22 02:38:36 +0200 +++ linux-2.6.12.2-vs2.0-rc6.1/fs/ext3/inode.c 2005-07-02 22:38:30 +0200 @@ -2758,7 +2820,8 @@ int ext3_setattr(struct dentry *dentry, return error; if ((ia_valid & ATTR_UID && attr->ia_uid != inode->i_uid) || - (ia_valid & ATTR_GID && attr->ia_gid != inode->i_gid)) { + (ia_valid & ATTR_GID && attr->ia_gid != inode->i_gid) || + (ia_valid & ATTR_XID && attr->ia_xid != inode->i_xid)) { handle_t *handle; /* (user+group)*(old+new) structure, inode write (sb, --- linux-2.6.12.2/fs/ext3/inode.c 2005-06-22 02:38:36 +0200 +++ linux-2.6.12.2-vs2.0-rc6.1/fs/ext3/inode.c 2005-07-02 22:38:30 +0200 @@ -2779,6 +2842,10 @@ int ext3_setattr(struct dentry *dentry, inode->i_uid = attr->ia_uid; if (attr->ia_valid & ATTR_GID) inode->i_gid = attr->ia_gid; + if ((attr->ia_valid & ATTR_XID) + && inode->i_sb + && (inode->i_sb->s_flags & MS_TAGXID)) + inode->i_xid = attr->ia_xid; error = ext3_mark_inode_dirty(handle, inode); ext3_journal_stop(handle); } --- linux-2.6.12.2/fs/ext3/namei.c 2005-03-02 12:38:44 +0100 +++ linux-2.6.12.2-vs2.0-rc6.1/fs/ext3/namei.c 2005-07-02 22:38:30 +0200 @@ -994,6 +995,7 @@ static struct dentry *ext3_lookup(struct if (!inode) return ERR_PTR(-EACCES); + vx_propagate_xid(nd, inode); } if (inode) return d_splice_alias(inode, dentry); --- linux-2.6.12.2/fs/ext3/super.c 2005-06-22 02:38:36 +0200 +++ linux-2.6.12.2-vs2.0-rc6.1/fs/ext3/super.c 2005-07-02 22:38:30 +0200 @@ -590,7 +590,7 @@ enum { Opt_abort, Opt_data_journal, Opt_data_ordered, Opt_data_writeback, Opt_usrjquota, Opt_grpjquota, Opt_offusrjquota, Opt_offgrpjquota, Opt_jqfmt_vfsold, Opt_jqfmt_vfsv0, - Opt_ignore, Opt_barrier, Opt_err, Opt_resize, + Opt_tagxid, Opt_barrier, Opt_ignore, Opt_err, Opt_resize, }; static match_table_t tokens = { --- linux-2.6.12.2/fs/ext3/super.c 2005-06-22 02:38:36 +0200 +++ linux-2.6.12.2-vs2.0-rc6.1/fs/ext3/super.c 2005-07-02 22:38:30 +0200 @@ -634,6 +634,7 @@ static match_table_t tokens = { {Opt_grpjquota, "grpjquota=%s"}, {Opt_jqfmt_vfsold, "jqfmt=vfsold"}, {Opt_jqfmt_vfsv0, "jqfmt=vfsv0"}, + {Opt_tagxid, "tagxid"}, {Opt_ignore, "grpquota"}, {Opt_ignore, "noquota"}, {Opt_ignore, "quota"}, --- linux-2.6.12.2/fs/ext3/super.c 2005-06-22 02:38:36 +0200 +++ linux-2.6.12.2-vs2.0-rc6.1/fs/ext3/super.c 2005-07-02 22:38:30 +0200 @@ -730,6 +731,16 @@ static int parse_options (char * options case Opt_nouid32: set_opt (sbi->s_mount_opt, NO_UID32); break; +#ifndef CONFIG_INOXID_NONE + case Opt_tagxid: + if (is_remount) { + printk(KERN_ERR "EXT3-fs: cannot specify " + "tagxid on remount\n"); + return 0; + } + set_opt (sbi->s_mount_opt, TAG_XID); + break; +#endif case Opt_check: #ifdef CONFIG_EXT3_CHECK set_opt (sbi->s_mount_opt, CHECK); --- linux-2.6.12.2/fs/ext3/super.c 2005-06-22 02:38:36 +0200 +++ linux-2.6.12.2-vs2.0-rc6.1/fs/ext3/super.c 2005-07-02 22:38:30 +0200 @@ -1333,6 +1344,9 @@ static int ext3_fill_super (struct super if (!parse_options ((char *) data, sb, &journal_inum, NULL, 0)) goto failed_mount; + if (EXT3_SB(sb)->s_mount_opt & EXT3_MOUNT_TAG_XID) + sb->s_flags |= MS_TAGXID; + sb->s_flags = (sb->s_flags & ~MS_POSIXACL) | ((sbi->s_mount_opt & EXT3_MOUNT_POSIX_ACL) ? MS_POSIXACL : 0); --- linux-2.6.12.2/fs/inode.c 2005-06-22 02:38:36 +0200 +++ linux-2.6.12.2-vs2.0-rc6.1/fs/inode.c 2005-07-02 22:38:30 +0200 @@ -114,6 +114,9 @@ static struct inode *alloc_inode(struct struct address_space * const mapping = &inode->i_data; inode->i_sb = sb; + + /* essential because of inode slab reuse */ + inode->i_xid = 0; inode->i_blkbits = sb->s_blocksize_bits; inode->i_flags = 0; atomic_set(&inode->i_count, 1); --- linux-2.6.12.2/fs/inode.c 2005-06-22 02:38:36 +0200 +++ linux-2.6.12.2-vs2.0-rc6.1/fs/inode.c 2005-07-02 22:38:30 +0200 @@ -230,6 +233,8 @@ void __iget(struct inode * inode) inodes_stat.nr_unused--; } +EXPORT_SYMBOL_GPL(__iget); + /** * clear_inode - clear an inode * @inode: inode to clear --- linux-2.6.12.2/fs/jfs/acl.c 2004-12-25 01:55:20 +0100 +++ linux-2.6.12.2-vs2.0-rc6.1/fs/jfs/acl.c 2005-07-09 04:09:36 +0200 @@ -220,7 +220,8 @@ int jfs_setattr(struct dentry *dentry, s return rc; if ((iattr->ia_valid & ATTR_UID && iattr->ia_uid != inode->i_uid) || - (iattr->ia_valid & ATTR_GID && iattr->ia_gid != inode->i_gid)) { + (iattr->ia_valid & ATTR_GID && iattr->ia_gid != inode->i_gid) || + (iattr->ia_valid & ATTR_XID && iattr->ia_xid != inode->i_xid)) { if (DQUOT_TRANSFER(inode, iattr)) return -EDQUOT; } --- linux-2.6.12.2/fs/jfs/jfs_imap.c 2005-06-22 02:38:36 +0200 +++ linux-2.6.12.2-vs2.0-rc6.1/fs/jfs/jfs_imap.c 2005-07-02 22:38:30 +0200 @@ -3100,14 +3101,21 @@ static void duplicateIXtree(struct super static int copy_from_dinode(struct dinode * dip, struct inode *ip) { struct jfs_inode_info *jfs_ip = JFS_IP(ip); + uid_t uid; + gid_t gid; jfs_ip->fileset = le32_to_cpu(dip->di_fileset); jfs_ip->mode2 = le32_to_cpu(dip->di_mode); ip->i_mode = le32_to_cpu(dip->di_mode) & 0xffff; ip->i_nlink = le32_to_cpu(dip->di_nlink); - ip->i_uid = le32_to_cpu(dip->di_uid); - ip->i_gid = le32_to_cpu(dip->di_gid); + + uid = le32_to_cpu(dip->di_uid); + gid = le32_to_cpu(dip->di_gid); + ip->i_uid = INOXID_UID(XID_TAG(ip), uid, gid); + ip->i_gid = INOXID_GID(XID_TAG(ip), uid, gid); + ip->i_xid = INOXID_XID(XID_TAG(ip), uid, gid, 0); + ip->i_size = le64_to_cpu(dip->di_size); ip->i_atime.tv_sec = le32_to_cpu(dip->di_atime.tv_sec); ip->i_atime.tv_nsec = le32_to_cpu(dip->di_atime.tv_nsec); --- linux-2.6.12.2/fs/jfs/jfs_imap.c 2005-06-22 02:38:36 +0200 +++ linux-2.6.12.2-vs2.0-rc6.1/fs/jfs/jfs_imap.c 2005-07-02 22:38:30 +0200 @@ -3158,6 +3166,8 @@ static int copy_from_dinode(struct dinod static void copy_to_dinode(struct dinode * dip, struct inode *ip) { struct jfs_inode_info *jfs_ip = JFS_IP(ip); + uid_t uid; + gid_t gid; dip->di_fileset = cpu_to_le32(jfs_ip->fileset); dip->di_inostamp = cpu_to_le32(JFS_SBI(ip->i_sb)->inostamp); --- linux-2.6.12.2/fs/jfs/jfs_imap.c 2005-06-22 02:38:36 +0200 +++ linux-2.6.12.2-vs2.0-rc6.1/fs/jfs/jfs_imap.c 2005-07-02 22:38:30 +0200 @@ -3166,8 +3176,11 @@ static void copy_to_dinode(struct dinode dip->di_size = cpu_to_le64(ip->i_size); dip->di_nblocks = cpu_to_le64(PBLK2LBLK(ip->i_sb, ip->i_blocks)); dip->di_nlink = cpu_to_le32(ip->i_nlink); - dip->di_uid = cpu_to_le32(ip->i_uid); - dip->di_gid = cpu_to_le32(ip->i_gid); + + uid = XIDINO_UID(XID_TAG(ip), ip->i_uid, ip->i_xid); + gid = XIDINO_GID(XID_TAG(ip), ip->i_gid, ip->i_xid); + dip->di_uid = cpu_to_le32(uid); + dip->di_gid = cpu_to_le32(gid); /* * mode2 is only needed for storing the higher order bits. * Trust i_mode for the lower order ones --- linux-2.6.12.2/fs/jfs/super.c 2005-06-22 02:38:36 +0200 +++ linux-2.6.12.2-vs2.0-rc6.1/fs/jfs/super.c 2005-07-09 04:09:36 +0200 @@ -219,7 +219,7 @@ static void jfs_put_super(struct super_b enum { Opt_integrity, Opt_nointegrity, Opt_iocharset, Opt_resize, - Opt_resize_nosize, Opt_errors, Opt_ignore, Opt_err, + Opt_resize_nosize, Opt_errors, Opt_tagxid, Opt_ignore, Opt_err, }; static match_table_t tokens = { --- linux-2.6.12.2/fs/jfs/super.c 2005-06-22 02:38:36 +0200 +++ linux-2.6.12.2-vs2.0-rc6.1/fs/jfs/super.c 2005-07-09 04:09:36 +0200 @@ -229,6 +229,7 @@ static match_table_t tokens = { {Opt_resize, "resize=%u"}, {Opt_resize_nosize, "resize"}, {Opt_errors, "errors=%s"}, + {Opt_tagxid, "tagxid"}, {Opt_ignore, "noquota"}, {Opt_ignore, "quota"}, {Opt_ignore, "usrquota"}, --- linux-2.6.12.2/fs/jfs/super.c 2005-06-22 02:38:36 +0200 +++ linux-2.6.12.2-vs2.0-rc6.1/fs/jfs/super.c 2005-07-09 04:09:36 +0200 @@ -421,6 +425,9 @@ static int jfs_fill_super(struct super_b #ifdef CONFIG_JFS_POSIX_ACL sb->s_flags |= MS_POSIXACL; #endif + /* map mount option tagxid */ + if (sbi->flag & JFS_TAGXID) + sb->s_flags |= MS_TAGXID; if (newLVSize) { printk(KERN_ERR "resize option for remount only\n"); --- linux-2.6.12.2/fs/namei.c 2005-06-22 02:38:37 +0200 +++ linux-2.6.12.2-vs2.0-rc6.1/fs/namei.c 2005-07-09 04:35:26 +0200 @@ -221,6 +225,24 @@ int generic_permission(struct inode *ino return -EACCES; } +static inline int xid_permission(struct inode *inode, int mask, struct nameidata *nd) +{ + if (IS_BARRIER(inode) && !vx_check(0, VX_ADMIN)) { + vxwprintk(1, "xid=%d did hit the barrier.", + vx_current_xid()); + return -EACCES; + } + if (inode->i_xid == 0) + return 0; + if (vx_check(inode->i_xid, VX_ADMIN|VX_WATCH|VX_IDENT)) + return 0; + + vxwprintk(1, "xid=%d denied access to %p[#%d,%lu] »%s«.", + vx_current_xid(), inode, inode->i_xid, inode->i_ino, + vxd_path(nd->dentry, nd->mnt)); + return -EACCES; +} + int permission(struct inode *inode, int mask, struct nameidata *nd) { int retval, submask; --- linux-2.6.12.2/fs/namei.c 2005-06-22 02:38:37 +0200 +++ linux-2.6.12.2-vs2.0-rc6.1/fs/namei.c 2005-07-09 04:35:26 +0200 @@ -245,6 +267,8 @@ int permission(struct inode *inode, int /* Ordinary permission routines do not understand MAY_APPEND. */ submask = mask & ~MAY_APPEND; + if ((retval = xid_permission(inode, mask, nd))) + return retval; if (inode->i_op && inode->i_op->permission) retval = inode->i_op->permission(inode, submask, nd); else --- linux-2.6.12.2/fs/namei.c 2005-06-22 02:38:37 +0200 +++ linux-2.6.12.2-vs2.0-rc6.1/fs/namei.c 2005-07-09 04:35:26 +0200 @@ -637,7 +661,8 @@ static inline void follow_dotdot(struct if (nd->dentry == current->fs->root && nd->mnt == current->fs->rootmnt) { read_unlock(¤t->fs->lock); - break; + /* for sane '/' avoid follow_mount() */ + return; } read_unlock(¤t->fs->lock); spin_lock(&dcache_lock); --- linux-2.6.12.2/fs/namespace.c 2005-06-22 02:38:37 +0200 +++ linux-2.6.12.2-vs2.0-rc6.1/fs/namespace.c 2005-07-09 04:35:26 +0200 @@ -228,6 +258,7 @@ static int show_vfsmnt(struct seq_file * { MS_MANDLOCK, ",mand" }, { MS_NOATIME, ",noatime" }, { MS_NODIRATIME, ",nodiratime" }, + { MS_TAGXID, ",tagxid" }, { 0, NULL } }; static struct proc_fs_info mnt_info[] = { --- linux-2.6.12.2/fs/open.c 2005-03-02 12:38:45 +0100 +++ linux-2.6.12.2-vs2.0-rc6.1/fs/open.c 2005-07-02 22:38:30 +0200 @@ -678,11 +683,11 @@ static int chown_common(struct dentry * newattrs.ia_valid = ATTR_CTIME; if (user != (uid_t) -1) { newattrs.ia_valid |= ATTR_UID; - newattrs.ia_uid = user; + newattrs.ia_uid = vx_map_uid(user); } if (group != (gid_t) -1) { newattrs.ia_valid |= ATTR_GID; - newattrs.ia_gid = group; + newattrs.ia_gid = vx_map_gid(group); } if (!S_ISDIR(inode->i_mode)) newattrs.ia_valid |= ATTR_KILL_SUID|ATTR_KILL_SGID; --- linux-2.6.12.2/fs/reiserfs/inode.c 2005-06-22 02:38:37 +0200 +++ linux-2.6.12.2-vs2.0-rc6.1/fs/reiserfs/inode.c 2005-07-09 04:09:27 +0200 @@ -1047,6 +1048,8 @@ static void init_inode (struct inode * i struct buffer_head * bh; struct item_head * ih; __u32 rdev; + uid_t uid; + gid_t gid; //int version = ITEM_VERSION_1; bh = PATH_PLAST_BUFFER (path); --- linux-2.6.12.2/fs/reiserfs/inode.c 2005-06-22 02:38:37 +0200 +++ linux-2.6.12.2-vs2.0-rc6.1/fs/reiserfs/inode.c 2005-07-09 04:09:27 +0200 @@ -1070,12 +1073,13 @@ static void init_inode (struct inode * i struct stat_data_v1 * sd = (struct stat_data_v1 *)B_I_PITEM (bh, ih); unsigned long blocks; + uid = sd_v1_uid(sd); + gid = sd_v1_gid(sd); + set_inode_item_key_version (inode, KEY_FORMAT_3_5); set_inode_sd_version (inode, STAT_DATA_V1); inode->i_mode = sd_v1_mode(sd); inode->i_nlink = sd_v1_nlink(sd); - inode->i_uid = sd_v1_uid(sd); - inode->i_gid = sd_v1_gid(sd); inode->i_size = sd_v1_size(sd); inode->i_atime.tv_sec = sd_v1_atime(sd); inode->i_mtime.tv_sec = sd_v1_mtime(sd); --- linux-2.6.12.2/fs/reiserfs/inode.c 2005-06-22 02:38:37 +0200 +++ linux-2.6.12.2-vs2.0-rc6.1/fs/reiserfs/inode.c 2005-07-09 04:09:27 +0200 @@ -1115,11 +1119,12 @@ static void init_inode (struct inode * i // (directories and symlinks) struct stat_data * sd = (struct stat_data *)B_I_PITEM (bh, ih); + uid = sd_v2_uid(sd); + gid = sd_v2_gid(sd); + inode->i_mode = sd_v2_mode(sd); inode->i_nlink = sd_v2_nlink(sd); - inode->i_uid = sd_v2_uid(sd); inode->i_size = sd_v2_size(sd); - inode->i_gid = sd_v2_gid(sd); inode->i_mtime.tv_sec = sd_v2_mtime(sd); inode->i_atime.tv_sec = sd_v2_atime(sd); inode->i_ctime.tv_sec = sd_v2_ctime(sd); --- linux-2.6.12.2/fs/reiserfs/inode.c 2005-06-22 02:38:37 +0200 +++ linux-2.6.12.2-vs2.0-rc6.1/fs/reiserfs/inode.c 2005-07-09 04:09:27 +0200 @@ -1146,6 +1151,9 @@ static void init_inode (struct inode * i REISERFS_I(inode)->i_attrs = sd_v2_attrs( sd ); sd_attrs_to_i_attrs( sd_v2_attrs( sd ), inode ); } + inode->i_uid = INOXID_UID(XID_TAG(inode), uid, gid); + inode->i_gid = INOXID_GID(XID_TAG(inode), uid, gid); + inode->i_xid = INOXID_XID(XID_TAG(inode), uid, gid, 0); pathrelse (path); if (S_ISREG (inode->i_mode)) { --- linux-2.6.12.2/fs/reiserfs/inode.c 2005-06-22 02:38:37 +0200 +++ linux-2.6.12.2-vs2.0-rc6.1/fs/reiserfs/inode.c 2005-07-09 04:09:27 +0200 @@ -1170,13 +1178,15 @@ static void init_inode (struct inode * i static void inode2sd (void * sd, struct inode * inode, loff_t size) { struct stat_data * sd_v2 = (struct stat_data *)sd; + uid_t uid = XIDINO_UID(XID_TAG(inode), inode->i_uid, inode->i_xid); + gid_t gid = XIDINO_GID(XID_TAG(inode), inode->i_gid, inode->i_xid); __u16 flags; + set_sd_v2_uid(sd_v2, uid ); + set_sd_v2_gid(sd_v2, gid ); set_sd_v2_mode(sd_v2, inode->i_mode ); set_sd_v2_nlink(sd_v2, inode->i_nlink ); - set_sd_v2_uid(sd_v2, inode->i_uid ); set_sd_v2_size(sd_v2, size ); - set_sd_v2_gid(sd_v2, inode->i_gid ); set_sd_v2_mtime(sd_v2, inode->i_mtime.tv_sec ); set_sd_v2_atime(sd_v2, inode->i_atime.tv_sec ); set_sd_v2_ctime(sd_v2, inode->i_ctime.tv_sec ); --- linux-2.6.12.2/fs/reiserfs/namei.c 2005-06-22 02:38:37 +0200 +++ linux-2.6.12.2-vs2.0-rc6.1/fs/reiserfs/namei.c 2005-07-09 04:09:27 +0200 @@ -350,6 +351,7 @@ static struct dentry * reiserfs_lookup ( reiserfs_write_unlock(dir->i_sb); return ERR_PTR(-EACCES); } + vx_propagate_xid(nd, inode); /* Propogate the priv_object flag so we know we're in the priv tree */ if (is_reiserfs_priv_object (dir)) --- linux-2.6.12.2/fs/reiserfs/namei.c 2005-06-22 02:38:37 +0200 +++ linux-2.6.12.2-vs2.0-rc6.1/fs/reiserfs/namei.c 2005-07-09 04:09:27 +0200 @@ -576,6 +578,7 @@ static int new_inode_init(struct inode * } else { inode->i_gid = current->fsgid; } + inode->i_xid = vx_current_fsxid(inode->i_sb); DQUOT_INIT(inode); return 0 ; } --- linux-2.6.12.2/fs/reiserfs/super.c 2005-06-22 02:38:37 +0200 +++ linux-2.6.12.2-vs2.0-rc6.1/fs/reiserfs/super.c 2005-07-09 04:09:27 +0200 @@ -850,6 +850,7 @@ static int reiserfs_parse_options (struc {"user_xattr", .setmask = 1<s_mount_opt & (1 << REISERFS_TAGXID)) + s->s_flags |= MS_TAGXID ; + rs = SB_DISK_SUPER_BLOCK (s); /* Let's do basic sanity check to verify that underlying device is not smaller than the filesystem. If the check fails then abort and scream, --- linux-2.6.12.2/fs/stat.c 2004-12-25 01:55:21 +0100 +++ linux-2.6.12.2-vs2.0-rc6.1/fs/stat.c 2005-07-02 22:38:30 +0200 @@ -27,6 +27,7 @@ void generic_fillattr(struct inode *inod stat->nlink = inode->i_nlink; stat->uid = inode->i_uid; stat->gid = inode->i_gid; + stat->xid = inode->i_xid; stat->rdev = inode->i_rdev; stat->atime = inode->i_atime; stat->mtime = inode->i_mtime; --- linux-2.6.12.2/include/linux/ext2_fs.h 2004-10-23 05:06:22 +0200 +++ linux-2.6.12.2-vs2.0-rc6.1/include/linux/ext2_fs.h 2005-07-02 22:38:30 +0200 @@ -240,7 +247,7 @@ struct ext2_inode { struct { __u8 l_i_frag; /* Fragment number */ __u8 l_i_fsize; /* Fragment size */ - __u16 i_pad1; + __u16 l_i_xid; /* LRU Context */ __le16 l_i_uid_high; /* these 2 fields */ __le16 l_i_gid_high; /* were reserved2[0] */ __u32 l_i_reserved2; --- linux-2.6.12.2/include/linux/ext2_fs.h 2004-10-23 05:06:22 +0200 +++ linux-2.6.12.2-vs2.0-rc6.1/include/linux/ext2_fs.h 2005-07-02 22:38:30 +0200 @@ -272,6 +279,7 @@ struct ext2_inode { #define i_gid_low i_gid #define i_uid_high osd2.linux2.l_i_uid_high #define i_gid_high osd2.linux2.l_i_gid_high +#define i_raw_xid osd2.linux2.l_i_xid #define i_reserved2 osd2.linux2.l_i_reserved2 #endif --- linux-2.6.12.2/include/linux/ext2_fs.h 2004-10-23 05:06:22 +0200 +++ linux-2.6.12.2-vs2.0-rc6.1/include/linux/ext2_fs.h 2005-07-02 22:38:30 +0200 @@ -312,6 +320,7 @@ struct ext2_inode { #define EXT2_MOUNT_NO_UID32 0x0200 /* Disable 32-bit UIDs */ #define EXT2_MOUNT_XATTR_USER 0x4000 /* Extended user attributes */ #define EXT2_MOUNT_POSIX_ACL 0x8000 /* POSIX Access Control Lists */ +#define EXT2_MOUNT_TAG_XID (1<<24) /* Enable Context Tags */ #define clear_opt(o, opt) o &= ~EXT2_MOUNT_##opt #define set_opt(o, opt) o |= EXT2_MOUNT_##opt --- linux-2.6.12.2/include/linux/ext3_fs.h 2005-06-22 02:38:48 +0200 +++ linux-2.6.12.2-vs2.0-rc6.1/include/linux/ext3_fs.h 2005-07-02 22:38:30 +0200 @@ -273,7 +283,7 @@ struct ext3_inode { struct { __u8 l_i_frag; /* Fragment number */ __u8 l_i_fsize; /* Fragment size */ - __u16 i_pad1; + __u16 l_i_xid; /* LRU Context */ __le16 l_i_uid_high; /* these 2 fields */ __le16 l_i_gid_high; /* were reserved2[0] */ __u32 l_i_reserved2; --- linux-2.6.12.2/include/linux/ext3_fs.h 2005-06-22 02:38:48 +0200 +++ linux-2.6.12.2-vs2.0-rc6.1/include/linux/ext3_fs.h 2005-07-02 22:38:30 +0200 @@ -307,6 +317,7 @@ struct ext3_inode { #define i_gid_low i_gid #define i_uid_high osd2.linux2.l_i_uid_high #define i_gid_high osd2.linux2.l_i_gid_high +#define i_raw_xid osd2.linux2.l_i_xid #define i_reserved2 osd2.linux2.l_i_reserved2 #elif defined(__GNU__) --- linux-2.6.12.2/include/linux/ext3_fs.h 2005-06-22 02:38:48 +0200 +++ linux-2.6.12.2-vs2.0-rc6.1/include/linux/ext3_fs.h 2005-07-02 22:38:30 +0200 @@ -358,6 +369,7 @@ struct ext3_inode { #define EXT3_MOUNT_RESERVATION 0x10000 /* Preallocation */ #define EXT3_MOUNT_BARRIER 0x20000 /* Use block barriers */ #define EXT3_MOUNT_NOBH 0x40000 /* No bufferheads */ +#define EXT3_MOUNT_TAG_XID (1<<24) /* Enable Context Tags */ /* Compatibility, for having both ext2_fs.h and ext3_fs.h included at once */ #ifndef _LINUX_EXT2_FS_H --- linux-2.6.12.2/include/linux/fs.h 2005-06-22 02:38:48 +0200 +++ linux-2.6.12.2-vs2.0-rc6.1/include/linux/fs.h 2005-07-09 03:54:30 +0200 @@ -103,6 +103,8 @@ extern int dir_notify_enable; #define MS_REC 16384 #define MS_VERBOSE 32768 #define MS_POSIXACL (1<<16) /* VFS does not apply the umask */ +#define MS_TAGXID (1<<24) /* tag inodes with context information */ +#define MS_XID (1<<25) /* use specific xid for this mount */ #define MS_ACTIVE (1<<30) #define MS_NOUSER (1<<31) --- linux-2.6.12.2/include/linux/fs.h 2005-06-22 02:38:48 +0200 +++ linux-2.6.12.2-vs2.0-rc6.1/include/linux/fs.h 2005-07-09 03:54:30 +0200 @@ -260,6 +267,7 @@ typedef void (dio_iodone_t)(struct inode #define ATTR_ATTR_FLAG 1024 #define ATTR_KILL_SUID 2048 #define ATTR_KILL_SGID 4096 +#define ATTR_XID 8192 /* * This is the Inode Attributes structure, used for notify_change(). It --- linux-2.6.12.2/include/linux/fs.h 2005-06-22 02:38:48 +0200 +++ linux-2.6.12.2-vs2.0-rc6.1/include/linux/fs.h 2005-07-09 03:54:30 +0200 @@ -275,6 +283,7 @@ struct iattr { umode_t ia_mode; uid_t ia_uid; gid_t ia_gid; + xid_t ia_xid; loff_t ia_size; struct timespec ia_atime; struct timespec ia_mtime; --- linux-2.6.12.2/include/linux/fs.h 2005-06-22 02:38:48 +0200 +++ linux-2.6.12.2-vs2.0-rc6.1/include/linux/fs.h 2005-07-09 03:54:30 +0200 @@ -435,6 +447,7 @@ struct inode { unsigned int i_nlink; uid_t i_uid; gid_t i_gid; + xid_t i_xid; dev_t i_rdev; loff_t i_size; struct timespec i_atime; --- linux-2.6.12.2/include/linux/fs.h 2005-06-22 02:38:48 +0200 +++ linux-2.6.12.2-vs2.0-rc6.1/include/linux/fs.h 2005-07-09 03:54:30 +0200 @@ -586,6 +599,7 @@ struct file { struct fown_struct f_owner; unsigned int f_uid, f_gid; struct file_ra_state f_ra; + xid_t f_xid; size_t f_maxcount; unsigned long f_version; --- linux-2.6.12.2/include/linux/mount.h 2004-12-25 01:55:29 +0100 +++ linux-2.6.12.2-vs2.0-rc6.1/include/linux/mount.h 2005-07-02 22:38:30 +0200 @@ -19,6 +19,7 @@ #define MNT_NOSUID 1 #define MNT_NODEV 2 #define MNT_NOEXEC 4 +#define MNT_XID 256 struct vfsmount { --- linux-2.6.12.2/include/linux/mount.h 2004-12-25 01:55:29 +0100 +++ linux-2.6.12.2-vs2.0-rc6.1/include/linux/mount.h 2005-07-02 22:38:30 +0200 @@ -36,6 +37,7 @@ struct vfsmount struct list_head mnt_list; struct list_head mnt_fslink; /* link in fs-specific expiry list */ struct namespace *mnt_namespace; /* containing namespace */ + xid_t mnt_xid; /* xid tagging used for vfsmount */ }; static inline struct vfsmount *mntget(struct vfsmount *mnt) --- linux-2.6.12.2/include/linux/reiserfs_fs_sb.h 2005-03-02 12:38:53 +0100 +++ linux-2.6.12.2-vs2.0-rc6.1/include/linux/reiserfs_fs_sb.h 2005-07-02 22:38:30 +0200 @@ -461,6 +461,7 @@ enum reiserfs_mount_options { REISERFS_POSIXACL, REISERFS_BARRIER_NONE, REISERFS_BARRIER_FLUSH, + REISERFS_TAGXID, /* Actions on error */ REISERFS_ERROR_PANIC, --- linux-2.6.12.2/include/linux/stat.h 2004-08-14 12:55:10 +0200 +++ linux-2.6.12.2-vs2.0-rc6.1/include/linux/stat.h 2005-07-02 22:38:30 +0200 @@ -63,6 +63,7 @@ struct kstat { unsigned int nlink; uid_t uid; gid_t gid; + xid_t xid; dev_t rdev; loff_t size; struct timespec atime; --- linux-2.6.12.2/include/linux/vserver/xid.h 1970-01-01 01:00:00 +0100 +++ linux-2.6.12.2-vs2.0-rc6.1/include/linux/vserver/xid.h 2005-07-09 04:09:10 +0200 @@ -0,0 +1,145 @@ +#ifndef _VX_XID_H +#define _VX_XID_H + +#ifndef CONFIG_VSERVER +#warning config options missing +#endif + +#define XID_TAG_SB(sb) (sb->s_flags & MS_TAGXID) + +#define XID_TAG(in) (!(in) || \ + (((struct inode *)in)->i_sb && \ + XID_TAG_SB(((struct inode *)in)->i_sb))) + + +#ifdef CONFIG_XID_TAG_NFSD +#define XID_TAG_NFSD 1 +#else +#define XID_TAG_NFSD 0 +#endif + + +#ifdef CONFIG_INOXID_NONE + +#define MAX_UID 0xFFFFFFFF +#define MAX_GID 0xFFFFFFFF + +#define INOXID_XID(tag, uid, gid, xid) (0) + +#define XIDINO_UID(tag, uid, xid) (uid) +#define XIDINO_GID(tag, gid, xid) (gid) + +#endif + + +#ifdef CONFIG_INOXID_GID16 + +#define MAX_UID 0xFFFFFFFF +#define MAX_GID 0x0000FFFF + +#define INOXID_XID(tag, uid, gid, xid) \ + ((tag) ? (((gid) >> 16) & 0xFFFF) : 0) + +#define XIDINO_UID(tag, uid, xid) (uid) +#define XIDINO_GID(tag, gid, xid) \ + ((tag) ? (((gid) & 0xFFFF) | ((xid) << 16)) : (gid)) + +#endif + + +#ifdef CONFIG_INOXID_UGID24 + +#define MAX_UID 0x00FFFFFF +#define MAX_GID 0x00FFFFFF + +#define INOXID_XID(tag, uid, gid, xid) \ + ((tag) ? ((((uid) >> 16) & 0xFF00) | (((gid) >> 24) & 0xFF)) : 0) + +#define XIDINO_UID(tag, uid, xid) \ + ((tag) ? (((uid) & 0xFFFFFF) | (((xid) & 0xFF00) << 16)) : (uid)) +#define XIDINO_GID(tag, gid, xid) \ + ((tag) ? (((gid) & 0xFFFFFF) | (((xid) & 0x00FF) << 24)) : (gid)) + +#endif + + +#ifdef CONFIG_INOXID_UID16 + +#define MAX_UID 0x0000FFFF +#define MAX_GID 0xFFFFFFFF + +#define INOXID_XID(tag, uid, gid, xid) \ + ((tag) ? (((uid) >> 16) & 0xFFFF) : 0) + +#define XIDINO_UID(tag, uid, xid) \ + ((tag) ? (((uid) & 0xFFFF) | ((xid) << 16)) : (uid)) +#define XIDINO_GID(tag, gid, xid) (gid) + +#endif + + +#ifdef CONFIG_INOXID_INTERN + +#define MAX_UID 0xFFFFFFFF +#define MAX_GID 0xFFFFFFFF + +#define INOXID_XID(tag, uid, gid, xid) \ + ((tag) ? (xid) : 0) + +#define XIDINO_UID(tag, uid, xid) (uid) +#define XIDINO_GID(tag, gid, xid) (gid) + +#endif + + +#ifdef CONFIG_INOXID_RUNTIME + +#define MAX_UID 0xFFFFFFFF +#define MAX_GID 0xFFFFFFFF + +#define INOXID_XID(tag, uid, gid, xid) (0) + +#define XIDINO_UID(tag, uid, xid) (uid) +#define XIDINO_GID(tag, gid, xid) (gid) + +#endif + + +#ifdef CONFIG_INOXID_NONE +#define vx_current_fsxid(sb) (0) +#else +#define vx_current_fsxid(sb) \ + (XID_TAG_SB(sb) ? current->xid : 0) +#endif + +#define INOXID_UID(tag, uid, gid) \ + ((tag) ? ((uid) & MAX_UID) : (uid)) +#define INOXID_GID(tag, uid, gid) \ + ((tag) ? ((gid) & MAX_GID) : (gid)) + + +static inline uid_t vx_map_uid(uid_t uid) +{ + if ((uid > MAX_UID) && (uid != -1)) + uid = -2; + return (uid & MAX_UID); +} + +static inline gid_t vx_map_gid(gid_t gid) +{ + if ((gid > MAX_GID) && (gid != -1)) + gid = -2; + return (gid & MAX_GID); +} + + +#ifdef CONFIG_VSERVER_LEGACY +#define FIOC_GETXID _IOR('x', 1, long) +#define FIOC_SETXID _IOW('x', 2, long) +#define FIOC_SETXIDJ _IOW('x', 3, long) +#endif + +int vx_parse_xid(char *string, xid_t *xid, int remove); +void vx_propagate_xid(struct nameidata *nd, struct inode *inode); + +#endif /* _VX_XID_H */ --- linux-2.6.12.2/fs/xfs/linux-2.6/xfs_vnode.h 2005-06-22 02:38:40 +0200 +++ linux-2.6.12.2-vs2.0-rc6.1/fs/xfs/linux-2.6/xfs_vnode.h 2005-07-09 04:06:41 +0200 @@ -461,13 +462,15 @@ typedef struct vattr { #define XFS_AT_PROJID 0x04000000 #define XFS_AT_SIZE_NOPERM 0x08000000 #define XFS_AT_GENCOUNT 0x10000000 +#define XFS_AT_XID 0x20000000 #define XFS_AT_ALL (XFS_AT_TYPE|XFS_AT_MODE|XFS_AT_UID|XFS_AT_GID|\ XFS_AT_FSID|XFS_AT_NODEID|XFS_AT_NLINK|XFS_AT_SIZE|\ XFS_AT_ATIME|XFS_AT_MTIME|XFS_AT_CTIME|XFS_AT_RDEV|\ XFS_AT_BLKSIZE|XFS_AT_NBLOCKS|XFS_AT_VCODE|XFS_AT_MAC|\ XFS_AT_ACL|XFS_AT_CAP|XFS_AT_INF|XFS_AT_XFLAGS|XFS_AT_EXTSIZE|\ - XFS_AT_NEXTENTS|XFS_AT_ANEXTENTS|XFS_AT_PROJID|XFS_AT_GENCOUNT) + XFS_AT_NEXTENTS|XFS_AT_ANEXTENTS|XFS_AT_PROJID|XFS_AT_GENCOUNT\ + XFS_AT_XID) #define XFS_AT_STAT (XFS_AT_TYPE|XFS_AT_MODE|XFS_AT_UID|XFS_AT_GID|\ XFS_AT_FSID|XFS_AT_NODEID|XFS_AT_NLINK|XFS_AT_SIZE|\ --- linux-2.6.12.2/fs/xfs/xfs_vfsops.c 2005-06-22 02:38:41 +0200 +++ linux-2.6.12.2-vs2.0-rc6.1/fs/xfs/xfs_vfsops.c 2005-07-02 22:38:30 +0200 @@ -403,6 +405,8 @@ xfs_finish_flags( return XFS_ERROR(EINVAL); } + if (ap->flags & XFSMNT_TAGXID) + vfs->vfs_super->s_flags |= MS_TAGXID; return 0; } --- linux-2.6.12.2/fs/xfs/xfs_vfsops.c 2005-06-22 02:38:41 +0200 +++ linux-2.6.12.2-vs2.0-rc6.1/fs/xfs/xfs_vfsops.c 2005-07-02 22:38:30 +0200 @@ -1815,6 +1820,8 @@ xfs_parseargs( args->flags &= ~XFSMNT_IDELETE; } else if (!strcmp(this_char, MNTOPT_NOIKEEP)) { args->flags |= XFSMNT_IDELETE; + } else if (!strcmp(this_char, MNTOPT_TAGXID)) { + args->flags |= XFSMNT_TAGXID; } else if (!strcmp(this_char, "osyncisdsync")) { /* no-op, this is now the default */ printk("XFS: osyncisdsync is now the default, option is deprecated.\n"); --- linux-2.6.12.2/fs/xfs/linux-2.6/xfs_linux.h 2005-06-22 02:38:40 +0200 +++ linux-2.6.12.2-vs2.0-rc6.1/fs/xfs/linux-2.6/xfs_linux.h 2005-07-09 04:09:10 +0200 @@ -152,6 +152,7 @@ static inline void set_buffer_unwritten_ #define current_pid() (current->pid) #define current_fsuid(cred) (current->fsuid) #define current_fsgid(cred) (current->fsgid) +#define current_fsxid(cred,vp) (vx_current_fsxid(LINVFS_GET_IP(vp)->i_sb)) #define NBPP PAGE_SIZE #define DPPSHFT (PAGE_SHIFT - 9) --- linux-2.6.12.2/fs/jfs/jfs_inode.c 2004-10-23 05:06:16 +0200 +++ linux-2.6.12.2-vs2.0-rc6.1/fs/jfs/jfs_inode.c 2005-07-09 04:09:36 +0200 @@ -60,6 +62,7 @@ struct inode *ialloc(struct inode *paren mode |= S_ISGID; } else inode->i_gid = current->fsgid; + inode->i_xid = vx_current_fsxid(sb); /* * Allocate inode to quota. --- linux-2.6.12.2/fs/jfs/super.c 2005-06-22 02:38:36 +0200 +++ linux-2.6.12.2-vs2.0-rc6.1/fs/jfs/super.c 2005-07-09 04:09:36 +0200 @@ -320,6 +321,9 @@ static int parse_options(char *options, } break; } + case Opt_tagxid: + *flag |= JFS_TAGXID; + break; default: printk("jfs: Unrecognized mount option \"%s\" " " or missing value\n", p); --- linux-2.6.12.2/fs/jfs/jfs_filsys.h 2004-08-14 12:55:32 +0200 +++ linux-2.6.12.2-vs2.0-rc6.1/fs/jfs/jfs_filsys.h 2005-07-09 04:09:36 +0200 @@ -81,6 +81,7 @@ #define JFS_DIR_INDEX 0x00200000 /* Persistant index for */ /* directory entries */ +#define JFS_TAGXID 0x00800000 /* xid tagging */ /* * buffer cache configuration --- linux-2.6.12.2/fs/xfs/linux-2.6/xfs_iops.c 2005-03-02 12:38:46 +0100 +++ linux-2.6.12.2-vs2.0-rc6.1/fs/xfs/linux-2.6/xfs_iops.c 2005-07-09 04:09:20 +0200 @@ -488,6 +514,10 @@ linvfs_setattr( vattr.va_mask |= XFS_AT_GID; vattr.va_gid = attr->ia_gid; } + if (ia_valid & ATTR_XID) { + vattr.va_mask |= XFS_AT_XID; + vattr.va_xid = attr->ia_xid; + } if (ia_valid & ATTR_SIZE) { vattr.va_mask |= XFS_AT_SIZE; vattr.va_size = attr->ia_size; --- linux-2.6.12.2/fs/xfs/linux-2.6/xfs_super.c 2005-06-22 02:38:40 +0200 +++ linux-2.6.12.2-vs2.0-rc6.1/fs/xfs/linux-2.6/xfs_super.c 2005-07-09 04:06:41 +0200 @@ -171,6 +171,7 @@ xfs_revalidate_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_xid = ip->i_d.di_xid; if (((1 << vp->v_type) & ((1<i_rdev = 0; } else { --- linux-2.6.12.2/fs/xfs/linux-2.6/xfs_vnode.c 2005-06-22 02:38:40 +0200 +++ linux-2.6.12.2-vs2.0-rc6.1/fs/xfs/linux-2.6/xfs_vnode.c 2005-07-09 04:06:41 +0200 @@ -202,6 +202,7 @@ vn_revalidate_core( inode->i_nlink = vap->va_nlink; inode->i_uid = vap->va_uid; inode->i_gid = vap->va_gid; + inode->i_xid = vap->va_xid; inode->i_blocks = vap->va_nblocks; inode->i_mtime = vap->va_mtime; inode->i_ctime = vap->va_ctime; --- linux-2.6.12.2/fs/xfs/linux-2.6/xfs_vnode.h 2005-06-22 02:38:40 +0200 +++ linux-2.6.12.2-vs2.0-rc6.1/fs/xfs/linux-2.6/xfs_vnode.h 2005-07-09 04:06:41 +0200 @@ -413,6 +413,7 @@ typedef struct vattr { xfs_nlink_t va_nlink; /* number of references to file */ uid_t va_uid; /* owner user id */ gid_t va_gid; /* owner group id */ + xid_t va_xid; /* owner group id */ xfs_ino_t va_nodeid; /* file id */ xfs_off_t va_size; /* file size in bytes */ u_long va_blocksize; /* blocksize preferred for i/o */ --- linux-2.6.12.2/fs/xfs/xfs_dinode.h 2005-06-22 02:38:40 +0200 +++ linux-2.6.12.2-vs2.0-rc6.1/fs/xfs/xfs_dinode.h 2005-07-09 04:06:41 +0200 @@ -72,7 +72,8 @@ typedef struct xfs_dinode_core __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_xid; /* vserver context id */ + __uint8_t di_pad[6]; /* unused, zeroed space */ __uint16_t di_flushiter; /* incremented on flush */ xfs_timestamp_t di_atime; /* time last accessed */ xfs_timestamp_t di_mtime; /* time last modified */ --- linux-2.6.12.2/fs/xfs/xfs_fs.h 2004-10-23 05:06:18 +0200 +++ linux-2.6.12.2-vs2.0-rc6.1/fs/xfs/xfs_fs.h 2005-07-09 04:06:41 +0200 @@ -306,7 +308,8 @@ typedef struct xfs_bstat { __s32 bs_extents; /* number of extents */ __u32 bs_gen; /* generation count */ __u16 bs_projid; /* project id */ - unsigned char bs_pad[14]; /* pad space, unused */ + __u16 bs_xid; /* context id */ + unsigned char bs_pad[12]; /* pad space, unused */ __u32 bs_dmevmask; /* DMIG event mask */ __u16 bs_dmstate; /* DMIG state info */ __u16 bs_aextents; /* attribute number of extents */ --- linux-2.6.12.2/fs/xfs/xfs_inode.c 2005-06-22 02:38:40 +0200 +++ linux-2.6.12.2-vs2.0-rc6.1/fs/xfs/xfs_inode.c 2005-07-09 04:09:10 +0200 @@ -792,20 +793,34 @@ xfs_xlate_dinode_core( xfs_dinode_core_t *buf_core = (xfs_dinode_core_t *)buf; xfs_dinode_core_t *mem_core = (xfs_dinode_core_t *)dip; xfs_arch_t arch = ARCH_CONVERT; + uint32_t uid = 0, gid = 0; + uint16_t xid = 0; ASSERT(dir); + if (dir < 0) { + /* FIXME make that conditional on some flag */ + xid = mem_core->di_xid; + uid = XIDINO_UID(1, mem_core->di_uid, xid); + gid = XIDINO_GID(1, mem_core->di_gid, xid); + } + INT_XLATE(buf_core->di_magic, mem_core->di_magic, dir, arch); INT_XLATE(buf_core->di_mode, mem_core->di_mode, dir, arch); INT_XLATE(buf_core->di_version, mem_core->di_version, dir, arch); INT_XLATE(buf_core->di_format, mem_core->di_format, dir, arch); INT_XLATE(buf_core->di_onlink, mem_core->di_onlink, dir, arch); - INT_XLATE(buf_core->di_uid, mem_core->di_uid, dir, arch); - INT_XLATE(buf_core->di_gid, mem_core->di_gid, dir, arch); + INT_XLATE(buf_core->di_uid, uid, dir, arch); + INT_XLATE(buf_core->di_gid, gid, dir, arch); + INT_XLATE(buf_core->di_xid, xid, dir, arch); INT_XLATE(buf_core->di_nlink, mem_core->di_nlink, dir, arch); INT_XLATE(buf_core->di_projid, mem_core->di_projid, dir, arch); if (dir > 0) { + /* FIXME make that conditional on some flag */ + mem_core->di_uid = INOXID_UID(1, uid, gid); + mem_core->di_gid = INOXID_GID(1, uid, gid); + mem_core->di_xid = INOXID_XID(1, uid, gid, xid); memcpy(mem_core->di_pad, buf_core->di_pad, sizeof(buf_core->di_pad)); } else { --- linux-2.6.12.2/fs/xfs/xfs_inode.c 2005-06-22 02:38:40 +0200 +++ linux-2.6.12.2-vs2.0-rc6.1/fs/xfs/xfs_inode.c 2005-07-09 04:09:10 +0200 @@ -1180,6 +1199,7 @@ xfs_ialloc( ASSERT(ip->i_d.di_nlink == nlink); ip->i_d.di_uid = current_fsuid(cr); ip->i_d.di_gid = current_fsgid(cr); + ip->i_d.di_xid = current_fsxid(cr, vp); ip->i_d.di_projid = prid; memset(&(ip->i_d.di_pad[0]), 0, sizeof(ip->i_d.di_pad)); --- linux-2.6.12.2/fs/xfs/xfs_mount.h 2005-06-22 02:38:41 +0200 +++ linux-2.6.12.2-vs2.0-rc6.1/fs/xfs/xfs_mount.h 2005-07-02 22:38:30 +0200 @@ -421,6 +421,7 @@ typedef struct xfs_mount { * allocation */ #define XFS_MOUNT_IHASHSIZE 0x00100000 /* inode hash table size */ #define XFS_MOUNT_DIRSYNC 0x00200000 /* synchronous directory ops */ +#define XFS_MOUNT_TAGXID 0x80000000 /* context xid tagging */ /* * Default minimum read and write sizes. --- linux-2.6.12.2/fs/xfs/xfs_vfsops.c 2005-06-22 02:38:41 +0200 +++ linux-2.6.12.2-vs2.0-rc6.1/fs/xfs/xfs_vfsops.c 2005-07-02 22:38:30 +0200 @@ -321,6 +321,8 @@ xfs_start_flags( if (ap->flags & XFSMNT_NOUUID) mp->m_flags |= XFS_MOUNT_NOUUID; + if (ap->flags & XFSMNT_TAGXID) + mp->m_flags |= XFS_MOUNT_TAGXID; if (ap->flags & XFSMNT_NOLOGFLUSH) mp->m_flags |= XFS_MOUNT_NOLOGFLUSH; --- linux-2.6.12.2/fs/xfs/xfs_vfsops.c 2005-06-22 02:38:41 +0200 +++ linux-2.6.12.2-vs2.0-rc6.1/fs/xfs/xfs_vfsops.c 2005-07-02 22:38:30 +0200 @@ -1657,6 +1661,7 @@ xfs_vget( #define MNTOPT_64BITINODE "inode64" /* inodes can be allocated anywhere */ #define MNTOPT_IKEEP "ikeep" /* do not free empty inode clusters */ #define MNTOPT_NOIKEEP "noikeep" /* free empty inode clusters */ +#define MNTOPT_TAGXID "tagxid" /* context xid tagging for inodes */ STATIC unsigned long suffix_strtoul(const char *cp, char **endp, unsigned int base) --- linux-2.6.12.2/fs/xfs/xfs_vnodeops.c 2005-06-22 02:38:41 +0200 +++ linux-2.6.12.2-vs2.0-rc6.1/fs/xfs/xfs_vnodeops.c 2005-07-09 04:06:41 +0200 @@ -167,6 +167,7 @@ xfs_getattr( vap->va_mode = ip->i_d.di_mode & MODEMASK; vap->va_uid = ip->i_d.di_uid; vap->va_gid = ip->i_d.di_gid; + vap->va_xid = ip->i_d.di_xid; vap->va_projid = ip->i_d.di_projid; /* --- linux-2.6.12.2/fs/xfs/xfs_vnodeops.c 2005-06-22 02:38:41 +0200 +++ linux-2.6.12.2-vs2.0-rc6.1/fs/xfs/xfs_vnodeops.c 2005-07-09 04:06:41 +0200 @@ -299,6 +300,7 @@ xfs_setattr( uint commit_flags=0; uid_t uid=0, iuid=0; gid_t gid=0, igid=0; + xid_t xid=0, ixid=0; int timeflags = 0; vnode_t *vp; xfs_prid_t projid=0, iprojid=0; --- linux-2.6.12.2/fs/xfs/xfs_vnodeops.c 2005-06-22 02:38:41 +0200 +++ linux-2.6.12.2-vs2.0-rc6.1/fs/xfs/xfs_vnodeops.c 2005-07-09 04:06:41 +0200 @@ -354,6 +356,7 @@ xfs_setattr( if (XFS_IS_QUOTA_ON(mp) && (mask & (XFS_AT_UID|XFS_AT_GID))) { uint qflags = 0; + /* FIXME: handle xid? */ if (mask & XFS_AT_UID) { uid = vap->va_uid; qflags |= XFS_QMOPT_UQUOTA; --- linux-2.6.12.2/fs/xfs/xfs_vnodeops.c 2005-06-22 02:38:41 +0200 +++ linux-2.6.12.2-vs2.0-rc6.1/fs/xfs/xfs_vnodeops.c 2005-07-09 04:06:41 +0200 @@ -427,6 +430,8 @@ xfs_setattr( if (mask & (XFS_AT_MODE|XFS_AT_XFLAGS|XFS_AT_EXTSIZE|XFS_AT_UID| XFS_AT_GID|XFS_AT_PROJID)) { + /* FIXME: handle xid? */ + /* * CAP_FOWNER overrides the following restrictions: * --- linux-2.6.12.2/fs/xfs/xfs_vnodeops.c 2005-06-22 02:38:41 +0200 +++ linux-2.6.12.2-vs2.0-rc6.1/fs/xfs/xfs_vnodeops.c 2005-07-09 04:06:41 +0200 @@ -475,7 +480,7 @@ xfs_setattr( * and can change the group id only to a group of which he * or she is a member. */ - if (mask & (XFS_AT_UID|XFS_AT_GID|XFS_AT_PROJID)) { + if (mask & (XFS_AT_UID|XFS_AT_GID|XFS_AT_XID|XFS_AT_PROJID)) { /* * These IDs could have changed since we last looked at them. * But, we're assured that if the ownership did change --- linux-2.6.12.2/fs/xfs/xfs_vnodeops.c 2005-06-22 02:38:41 +0200 +++ linux-2.6.12.2-vs2.0-rc6.1/fs/xfs/xfs_vnodeops.c 2005-07-09 04:06:41 +0200 @@ -483,10 +488,12 @@ xfs_setattr( * would have changed also. */ iuid = ip->i_d.di_uid; - iprojid = ip->i_d.di_projid; igid = ip->i_d.di_gid; - gid = (mask & XFS_AT_GID) ? vap->va_gid : igid; + ixid = ip->i_d.di_xid; + iprojid = ip->i_d.di_projid; uid = (mask & XFS_AT_UID) ? vap->va_uid : iuid; + gid = (mask & XFS_AT_GID) ? vap->va_gid : igid; + xid = (mask & XFS_AT_XID) ? vap->va_xid : ixid; projid = (mask & XFS_AT_PROJID) ? (xfs_prid_t)vap->va_projid : iprojid; --- linux-2.6.12.2/fs/xfs/xfs_vnodeops.c 2005-06-22 02:38:41 +0200 +++ linux-2.6.12.2-vs2.0-rc6.1/fs/xfs/xfs_vnodeops.c 2005-07-09 04:06:41 +0200 @@ -515,6 +522,7 @@ xfs_setattr( */ if ((XFS_IS_UQUOTA_ON(mp) && iuid != uid) || (XFS_IS_GQUOTA_ON(mp) && igid != gid)) { + /* FIXME: handle xid? */ ASSERT(tp); code = XFS_QM_DQVOPCHOWNRESV(mp, tp, ip, udqp, gdqp, capable(CAP_FOWNER) ? --- linux-2.6.12.2/fs/xfs/xfs_vnodeops.c 2005-06-22 02:38:41 +0200 +++ linux-2.6.12.2-vs2.0-rc6.1/fs/xfs/xfs_vnodeops.c 2005-07-09 04:06:41 +0200 @@ -747,7 +755,7 @@ xfs_setattr( * and can change the group id only to a group of which he * or she is a member. */ - if (mask & (XFS_AT_UID|XFS_AT_GID|XFS_AT_PROJID)) { + if (mask & (XFS_AT_UID|XFS_AT_GID|XFS_AT_XID|XFS_AT_PROJID)) { /* * CAP_FSETID overrides the following restrictions: * --- linux-2.6.12.2/fs/xfs/xfs_vnodeops.c 2005-06-22 02:38:41 +0200 +++ linux-2.6.12.2-vs2.0-rc6.1/fs/xfs/xfs_vnodeops.c 2005-07-09 04:06:41 +0200 @@ -763,6 +771,12 @@ xfs_setattr( * Change the ownerships and register quota modifications * in the transaction. */ + if (ixid != xid) { + if (XFS_IS_GQUOTA_ON(mp)) { + /* FIXME: handle xid quota? */ + } + ip->i_d.di_xid = xid; + } if (iuid != uid) { if (XFS_IS_UQUOTA_ON(mp)) { ASSERT(mask & XFS_AT_UID); --- linux-2.6.12.2/fs/xfs/xfs_clnt.h 2005-06-22 02:38:40 +0200 +++ linux-2.6.12.2-vs2.0-rc6.1/fs/xfs/xfs_clnt.h 2005-07-02 22:38:30 +0200 @@ -106,5 +106,6 @@ struct xfs_mount_args { #define XFSMNT_IHASHSIZE 0x20000000 /* inode hash table size */ #define XFSMNT_DIRSYNC 0x40000000 /* sync creat,link,unlink,rename * symlink,mkdir,rmdir,mknod */ +#define XFSMNT_TAGXID 0x80000000 /* context xid tagging */ #endif /* __XFS_CLNT_H__ */ --- linux-2.6.12.2/fs/xfs/xfs_itable.c 2005-06-22 02:38:40 +0200 +++ linux-2.6.12.2-vs2.0-rc6.1/fs/xfs/xfs_itable.c 2005-07-09 04:06:41 +0200 @@ -97,6 +97,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_xid = dic->di_xid; 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-2.6.12.2/fs/xfs/xfs_itable.c 2005-06-22 02:38:40 +0200 +++ linux-2.6.12.2-vs2.0-rc6.1/fs/xfs/xfs_itable.c 2005-07-09 04:06:41 +0200 @@ -172,6 +173,7 @@ xfs_bulkstat_one_dinode( buf->bs_mode = INT_GET(dic->di_mode, ARCH_CONVERT); buf->bs_uid = INT_GET(dic->di_uid, ARCH_CONVERT); buf->bs_gid = INT_GET(dic->di_gid, ARCH_CONVERT); + buf->bs_xid = INT_GET(dic->di_xid, ARCH_CONVERT); buf->bs_size = INT_GET(dic->di_size, ARCH_CONVERT); buf->bs_atime.tv_sec = INT_GET(dic->di_atime.t_sec, ARCH_CONVERT); buf->bs_atime.tv_nsec = INT_GET(dic->di_atime.t_nsec, ARCH_CONVERT);