+ if (rc < 0)
+ GOTO(out, rc = err_serious(rc));
+
+ lh = &info->mti_lh[MDT_LH_CHILD];
+ mdt_lock_reg_init(lh, LCK_PW);
+ rc = mdt_object_lock(info, obj, lh, MDS_INODELOCK_LOOKUP |
+ MDS_INODELOCK_XATTR, MDT_LOCAL_LOCK);
+ if (rc < 0)
+ GOTO(out_ucred, rc);
+
+ if (req_capsule_get_size(info->mti_pill, &RMF_CAPA1, RCL_CLIENT))
+ mdt_set_capainfo(info, 0, &info->mti_body->mbo_fid1,
+ req_capsule_client_get(info->mti_pill, &RMF_CAPA1));
+
+ /* Detect out-of range masks */
+ if ((hss->hss_setmask | hss->hss_clearmask) & ~HSM_FLAGS_MASK) {
+ CDEBUG(D_HSM, "Incompatible masks provided (set "LPX64
+ ", clear "LPX64") vs supported set (%#x).\n",
+ hss->hss_setmask, hss->hss_clearmask, HSM_FLAGS_MASK);
+ GOTO(out_unlock, rc = -EINVAL);
+ }
+
+ /* Non-root users are forbidden to set or clear flags which are
+ * NOT defined in HSM_USER_MASK. */
+ if (((hss->hss_setmask | hss->hss_clearmask) & ~HSM_USER_MASK) &&
+ !md_capable(mdt_ucred(info), CFS_CAP_SYS_ADMIN)) {
+ CDEBUG(D_HSM, "Incompatible masks provided (set "LPX64
+ ", clear "LPX64") vs unprivileged set (%#x).\n",
+ hss->hss_setmask, hss->hss_clearmask, HSM_USER_MASK);
+ GOTO(out_unlock, rc = -EPERM);
+ }