ENTRY;
if (!nodemap_active)
- goto out;
+ GOTO(out, found_id);
if (unlikely(nodemap == NULL))
- goto out;
+ GOTO(out, found_id);
- if (id_type != NODEMAP_PROJID && id == 0) {
+ if (id_type == NODEMAP_UID) {
+ offset_start = nodemap->nm_offset_start_uid;
+ offset_limit = nodemap->nm_offset_limit_uid;
+ } else if (id_type == NODEMAP_GID) {
+ offset_start = nodemap->nm_offset_start_uid;
+ offset_limit = nodemap->nm_offset_limit_gid;
+ } else if (id_type == NODEMAP_PROJID) {
+ offset_start = nodemap->nm_offset_start_projid;
+ offset_limit = nodemap->nm_offset_limit_projid;
+ } else {
+ CERROR("%s: nodemap invalid id_type provided\n",
+ nodemap->nm_name);
+ GOTO(out, found_id);
+ }
+
+ /* if mapping from fs to client id space, start by un-offsetting */
+ if ((offset_start != 0 || offset_limit != 0) &&
+ tree_type == NODEMAP_FS_TO_CLIENT) {
+ if (found_id < offset_start ||
+ found_id >= offset_start + offset_limit) {
+ /* If we are outside boundaries, squash id */
+ CDEBUG(D_SEC,
+ "%s: id %d for type %u is below nodemap start %u, squash\n",
+ nodemap->nm_name, found_id, id_type,
+ offset_start);
+ GOTO(squash, found_id);
+ }
+ found_id -= offset_start;
+ }
+
+ if (id_type != NODEMAP_PROJID && found_id == 0) {
/* root id is mapped and offset just as the other ids. This
* means root cannot remain root as soon as offset is defined.
*/
if (nodemap->nmf_allow_root_access)
- goto offset;
- goto map;
+ GOTO(offset, found_id);
+ GOTO(map, found_id);
}
if (id_type == NODEMAP_UID &&
!(nodemap->nmf_map_mode & NODEMAP_MAP_UID))
- goto offset;
+ GOTO(offset, found_id);
if (id_type == NODEMAP_GID &&
!(nodemap->nmf_map_mode & NODEMAP_MAP_GID))
- goto offset;
+ GOTO(offset, found_id);
if (id_type == NODEMAP_PROJID &&
!(nodemap->nmf_map_mode & NODEMAP_MAP_PROJID))
- goto offset;
+ GOTO(offset, found_id);
if (nodemap->nmf_trust_client_ids)
- goto offset;
+ GOTO(offset, found_id);
map:
if (is_default_nodemap(nodemap))
- goto squash;
+ GOTO(squash, found_id);
down_read(&nodemap->nm_idmap_lock);
- idmap = idmap_search(nodemap, tree_type, id_type, id);
+ idmap = idmap_search(nodemap, tree_type, id_type, found_id);
if (idmap == NULL) {
up_read(&nodemap->nm_idmap_lock);
- goto squash;
+ GOTO(squash, found_id);
}
if (tree_type == NODEMAP_FS_TO_CLIENT)
else if (id_type == NODEMAP_PROJID)
found_id = nodemap->nm_squash_projid;
attempted_squash = true;
-offset:
- if (id_type == NODEMAP_UID) {
- offset_start = nodemap->nm_offset_start_uid;
- offset_limit = nodemap->nm_offset_limit_uid;
- } else if (id_type == NODEMAP_GID) {
- offset_start = nodemap->nm_offset_start_uid;
- offset_limit = nodemap->nm_offset_limit_gid;
- } else if (id_type == NODEMAP_PROJID) {
- offset_start = nodemap->nm_offset_start_projid;
- offset_limit = nodemap->nm_offset_limit_projid;
- } else {
- CERROR("%s: nodemap invalid id_type provided\n",
- nodemap->nm_name);
- GOTO(out, id);
- }
-
- if (offset_start == 0 && offset_limit == 0)
- GOTO(out, found_id);
- if (tree_type == NODEMAP_FS_TO_CLIENT) {
- if (found_id < offset_start) {
- /* If we are outside boundaries, try to squash before
- * offsetting, and return unmapped otherwise.
- */
- if (!attempted_squash)
- GOTO(squash, found_id);
-
- CDEBUG(D_SEC,
- "%s: squash_id for type %u is below nodemap start %u, use unmapped value %u\n",
- nodemap->nm_name, id_type, offset_start,
- found_id);
- GOTO(out, found_id);
- }
- found_id -= offset_start;
- } else {
+offset:
+ /* if mapping from client to fs id space, end with offsetting */
+ if ((offset_start != 0 || offset_limit != 0) &&
+ tree_type == NODEMAP_CLIENT_TO_FS) {
if (found_id >= offset_limit) {
/* If we are outside boundaries, try to squash before
* offsetting, and return unmapped otherwise.
*/
- if (!attempted_squash)
+ if (!attempted_squash) {
+ CDEBUG(D_SEC,
+ "%s: id %d for type %u is outside nodemap limit %u, squash\n",
+ nodemap->nm_name, found_id, id_type,
+ offset_limit);
GOTO(squash, found_id);
+ }
CDEBUG(D_SEC,
"%s: squash_id for type %u is outside nodemap limit %u, use unmapped value %u\n",
fi
}
-cleanup_55() {
+cleanup_local_client_nodemap_with_mounts() {
# unmount client
if is_mounted $MOUNT; then
umount_client $MOUNT || error "umount $MOUNT failed"
do_nodes $(comma_list $(all_mdts_nodes)) \
$LCTL set_param mdt.*.identity_upcall=NONE
- stack_trap cleanup_55 EXIT
+ stack_trap cleanup_local_client_nodemap_with_mounts EXIT
setup_local_client_nodemap "c0" 0 1
}
run_test 76 "suppgroups and gid mapping"
+test_77() {
+ local squash=100
+ local nm=c0
+
+ (( $MDS1_VERSION >= $(version_code 2.16.54) )) ||
+ skip "Need MDS version >= 2.16.54 for proper root offsetting"
+
+ do_nodes $(comma_list $(all_mdts_nodes)) \
+ $LCTL set_param mdt.*.identity_upcall=NONE
+
+ stack_trap cleanup_local_client_nodemap_with_mounts EXIT
+
+ # create dir before nodemap create
+ $LFS mkdir -i 0 -c 1 $DIR/$tdir || error "mkdir $DIR/$tdir failed"
+
+ # unmount client completely
+ umount_client $MOUNT || error "umount $MOUNT failed"
+ if is_mounted $MOUNT2; then
+ umount_client $MOUNT2 || error "umount $MOUNT2 failed"
+ fi
+
+ # setup nodemap with offset
+ setup_local_client_nodemap $nm 1 0
+ do_facet mgs $LCTL nodemap_modify --name $nm \
+ --property squash_uid --value $squash ||
+ error "Setting squash_uid=$squash on $nm failed"
+ do_facet mgs $LCTL nodemap_modify --name $nm \
+ --property squash_gid --value $squash ||
+ error "Setting squash_gid=$squash on $nm failed"
+ do_facet mgs $LCTL nodemap_modify --name $nm \
+ --property squash_projid --value $squash ||
+ error "Setting squash_projid=$squash on $nm failed"
+ do_facet mgs $LCTL nodemap_add_offset --name $nm \
+ --offset 100000 --limit 200000 ||
+ error "nodemap_add_offset failed"
+ wait_nm_sync $nm offset
+
+ # remount client to take nodemap into account
+ zconf_mount_clients $HOSTNAME $MOUNT $MOUNT_OPTS ||
+ error "remount failed"
+ wait_ssk
+
+ # create a file as root...
+ touch $DIR/$tdir/fileA
+ # the owner:group ids read back should be 0:0
+ ls -ln $DIR/$tdir/fileA
+ [[ $(stat -c "%u:%g" $DIR/$tdir/fileA) == "0:0" ]] ||
+ error "bad owner/group for root file"
+}
+run_test 77 "root offsetting"
+
log "cleanup: ======================================================"
sec_unsetup() {