Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

afs: Support interacting with multiple user namespaces

Modify struct afs_file_status to store owner as a kuid_t and group as
a kgid_t.

In xdr_decode_AFSFetchStatus as owner is now a kuid_t and group is now
a kgid_t don't use the EXTRACT macro. Instead perform the work of
the extract macro explicitly. Read the value with ntohl and
convert it to the appropriate type with make_kuid or make_kgid.
Test if the value is different from what is stored in status and
update changed. Update the value in status.

In xdr_encode_AFS_StoreStatus call from_kuid or from_kgid as
we are computing the on the wire encoding.

Initialize uids with GLOBAL_ROOT_UID instead of 0.
Initialize gids with GLOBAL_ROOT_GID instead of 0.

Cc: David Howells <dhowells@redhat.com>
Acked-by: Serge Hallyn <serge.hallyn@canonical.com>
Signed-off-by: Eric W. Biederman <ebiederm@xmission.com>

+15 -10
+2 -2
fs/afs/afs.h
··· 119 119 u64 size; /* file size */ 120 120 afs_dataversion_t data_version; /* current data version */ 121 121 u32 author; /* author ID */ 122 - u32 owner; /* owner ID */ 123 - u32 group; /* group ID */ 122 + kuid_t owner; /* owner ID */ 123 + kgid_t group; /* group ID */ 124 124 afs_access_t caller_access; /* access rights for authenticated caller */ 125 125 afs_access_t anon_access; /* access rights for unauthenticated caller */ 126 126 umode_t mode; /* UNIX mode */
+10 -4
fs/afs/fsclient.c
··· 42 42 umode_t mode; 43 43 u64 data_version, size; 44 44 u32 changed = 0; /* becomes non-zero if ctime-type changes seen */ 45 + kuid_t owner; 46 + kgid_t group; 45 47 46 48 #define EXTRACT(DST) \ 47 49 do { \ ··· 58 56 size = ntohl(*bp++); 59 57 data_version = ntohl(*bp++); 60 58 EXTRACT(status->author); 61 - EXTRACT(status->owner); 59 + owner = make_kuid(&init_user_ns, ntohl(*bp++)); 60 + changed |= !uid_eq(owner, status->owner); 61 + status->owner = owner; 62 62 EXTRACT(status->caller_access); /* call ticket dependent */ 63 63 EXTRACT(status->anon_access); 64 64 EXTRACT(status->mode); ··· 69 65 bp++; /* seg size */ 70 66 status->mtime_client = ntohl(*bp++); 71 67 status->mtime_server = ntohl(*bp++); 72 - EXTRACT(status->group); 68 + group = make_kgid(&init_user_ns, ntohl(*bp++)); 69 + changed |= !gid_eq(group, status->group); 70 + status->group = group; 73 71 bp++; /* sync counter */ 74 72 data_version |= (u64) ntohl(*bp++) << 32; 75 73 EXTRACT(status->lock_count); ··· 187 181 188 182 if (attr->ia_valid & ATTR_UID) { 189 183 mask |= AFS_SET_OWNER; 190 - owner = attr->ia_uid; 184 + owner = from_kuid(&init_user_ns, attr->ia_uid); 191 185 } 192 186 193 187 if (attr->ia_valid & ATTR_GID) { 194 188 mask |= AFS_SET_GROUP; 195 - group = attr->ia_gid; 189 + group = from_kgid(&init_user_ns, attr->ia_gid); 196 190 } 197 191 198 192 if (attr->ia_valid & ATTR_MODE) {
+3 -3
fs/afs/inode.c
··· 69 69 70 70 set_nlink(inode, vnode->status.nlink); 71 71 inode->i_uid = vnode->status.owner; 72 - inode->i_gid = 0; 72 + inode->i_gid = GLOBAL_ROOT_GID; 73 73 inode->i_size = vnode->status.size; 74 74 inode->i_ctime.tv_sec = vnode->status.mtime_server; 75 75 inode->i_ctime.tv_nsec = 0; ··· 175 175 inode->i_mode = S_IFDIR | S_IRUGO | S_IXUGO; 176 176 inode->i_op = &afs_autocell_inode_operations; 177 177 set_nlink(inode, 2); 178 - inode->i_uid = 0; 179 - inode->i_gid = 0; 178 + inode->i_uid = GLOBAL_ROOT_UID; 179 + inode->i_gid = GLOBAL_ROOT_GID; 180 180 inode->i_ctime.tv_sec = get_seconds(); 181 181 inode->i_ctime.tv_nsec = 0; 182 182 inode->i_atime = inode->i_mtime = inode->i_ctime;
-1
init/Kconfig
··· 1071 1071 default y 1072 1072 1073 1073 # Filesystems 1074 - depends on AFS_FS = n 1075 1074 depends on CIFS = n 1076 1075 depends on CODA_FS = n 1077 1076 depends on GFS2_FS = n