* the rules are:
* - only normal FIDs or non-system IGIFs
* - same type of objects
- * - same owner/group (so quotas are still valid)
+ * - same owner/group (so quotas are still valid) unless this is from HSM
+ * release.
*/
static int mdd_layout_swap_allowed(const struct lu_env *env,
struct mdd_object *o1,
const struct lu_attr *attr1,
struct mdd_object *o2,
- const struct lu_attr *attr2)
+ const struct lu_attr *attr2,
+ __u64 flags)
{
const struct lu_fid *fid1, *fid2;
ENTRY;
RETURN(-EBADF);
}
+ if (flags & SWAP_LAYOUTS_MDS_HSM)
+ RETURN(0);
+
if ((attr1->la_uid != attr2->la_uid) ||
(attr1->la_gid != attr2->la_gid))
RETURN(-EPERM);
RETURN(rc);
/* check if layout swapping is allowed */
- rc = mdd_layout_swap_allowed(env, fst_o, fst_la, snd_o, snd_la);
+ rc = mdd_layout_swap_allowed(env, fst_o, fst_la, snd_o, snd_la, flags);
if (rc != 0)
RETURN(rc);
struct md_attr *ma)
{
struct mdt_lock_handle *lh = &info->mti_lh[MDT_LH_LAYOUT];
+ struct lu_ucred *uc = mdt_ucred(info);
struct close_data *data;
struct ldlm_lock *lease;
struct mdt_object *orphan;
struct md_attr *orp_ma;
struct lu_buf *buf;
+ cfs_cap_t cap;
bool lease_broken;
int rc;
int rc2;
orp_ma = &info->mti_u.hsm.attr;
orp_ma->ma_attr.la_mode = S_IFREG | S_IWUSR;
- orp_ma->ma_attr.la_uid = ma->ma_attr.la_uid;
- orp_ma->ma_attr.la_gid = ma->ma_attr.la_gid;
+ /* We use root ownership to bypass potential quota
+ * restrictions on the user and group of the file. */
+ orp_ma->ma_attr.la_uid = 0;
+ orp_ma->ma_attr.la_gid = 0;
orp_ma->ma_attr.la_valid = LA_MODE | LA_UID | LA_GID;
orp_ma->ma_lmm = ma->ma_lmm;
orp_ma->ma_lmm_size = ma->ma_lmm_size;
if (rc != 0)
GOTO(out_close, rc);
+ /* The orphan has root ownership so we need to raise
+ * CAP_FOWNER to set the HSM attributes. */
+ cap = uc->uc_cap;
+ uc->uc_cap |= MD_CAP_TO_MASK(CFS_CAP_FOWNER);
rc = mo_xattr_set(info->mti_env, mdt_object_child(orphan), buf,
XATTR_NAME_HSM, 0);
+ uc->uc_cap = cap;
+ if (rc != 0)
+ GOTO(out_layout_lock, rc);
- if (rc == 0)
- /* Swap layout with orphan object */
- rc = mo_swap_layouts(info->mti_env, mdt_object_child(o),
- mdt_object_child(orphan),
- SWAP_LAYOUTS_MDS_HSM);
+ /* Swap layout with orphan objects. */
+ rc = mo_swap_layouts(info->mti_env, mdt_object_child(o),
+ mdt_object_child(orphan),
+ SWAP_LAYOUTS_MDS_HSM);
+ EXIT;
+out_layout_lock:
/* Release exclusive LL */
mdt_object_unlock(info, o, lh, 1);
-
- EXIT;
-
out_close:
/* Close orphan object anyway */
rc2 = mo_close(info->mti_env, mdt_object_child(orphan), orp_ma,