*
* You should have received a copy of the GNU General Public License
* version 2 along with this program; If not, see
- * http://www.sun.com/software/products/lustre/docs/GPLv2.pdf
- *
- * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
- * CA 95054 USA or visit www.sun.com if you need additional information or
- * have any questions.
+ * http://www.gnu.org/licenses/gpl-2.0.html
*
* GPL HEADER END
*/
* Copyright (c) 2007, 2010, Oracle and/or its affiliates. All rights reserved.
* Use is subject to license terms.
*
- * Copyright (c) 2011, 2015, Intel Corporation.
+ * Copyright (c) 2011, 2016, Intel Corporation.
*/
/*
* This file is part of Lustre, http://www.lustre.org/
static void mdt_obj_version_get(struct mdt_thread_info *info,
struct mdt_object *o, __u64 *version)
{
- LASSERT(o);
+ LASSERT(o);
+
if (mdt_object_exists(o) && !mdt_object_remote(o) &&
!fid_is_obf(mdt_object_fid(o)))
- *version = dt_version_get(info->mti_env, mdt_obj2dt(o));
- else
- *version = ENOENT_VERSION;
- CDEBUG(D_INODE, "FID "DFID" version is "LPX64"\n",
- PFID(mdt_object_fid(o)), *version);
+ *version = dt_version_get(info->mti_env, mdt_obj2dt(o));
+ else
+ *version = ENOENT_VERSION;
+ CDEBUG(D_INODE, "FID "DFID" version is %#llx\n",
+ PFID(mdt_object_fid(o)), *version);
}
/**
spin_unlock(&req->rq_export->exp_lock);
RETURN(-EOVERFLOW);
} else if (pre_ver[idx] != version) {
- CDEBUG(D_INODE, "Version mismatch "LPX64" != "LPX64"\n",
+ CDEBUG(D_INODE, "Version mismatch %#llx != %#llx\n",
pre_ver[idx], version);
spin_lock(&req->rq_export->exp_lock);
req->rq_export->exp_vbr_failed = 1;
/* borrow s0_lh temporarily to do mdt unlock */
mdt_lock_reg_init(s0_lh, einfo->ei_mode);
s0_lh->mlh_rreg_lh = slave_locks->handles[i];
- mdt_object_unlock(mti, obj, s0_lh, decref);
+ mdt_object_unlock(mti, NULL, s0_lh, decref);
slave_locks->handles[i].cookie = 0ull;
}
}
int rc;
ENTRY;
+ memset(einfo, 0, sizeof(*einfo));
+
rc = mdt_init_slaves(mti, obj, s0_fid);
if (rc <= 0)
RETURN(rc);
}
}
- memset(einfo, 0, sizeof(*einfo));
einfo->ei_type = LDLM_IBITS;
einfo->ei_mode = mode;
einfo->ei_cb_bl = mdt_remote_blocking_ast;
* 2 - child. Version of child by FID. Must be ENOENT. It is mostly sanity
* check.
*/
-static int mdt_md_create(struct mdt_thread_info *info)
+static int mdt_create(struct mdt_thread_info *info)
{
struct mdt_device *mdt = info->mti_mdt;
struct mdt_object *parent;
struct md_attr *ma)
{
struct mdt_lock_handle *lh;
- int do_vbr = ma->ma_attr.la_valid & (LA_MODE|LA_UID|LA_GID|LA_FLAGS);
+ int do_vbr = ma->ma_attr.la_valid &
+ (LA_MODE | LA_UID | LA_GID | LA_PROJID | LA_FLAGS);
__u64 lockpart = MDS_INODELOCK_UPDATE;
struct ldlm_enqueue_info *einfo = &info->mti_einfo;
struct lu_fid *s0_fid = &info->mti_tmp_fid1;
}
/* Ensure constant striping during chown(). See LU-2789. */
- if (ma->ma_attr.la_valid & (LA_UID|LA_GID))
+ if (ma->ma_attr.la_valid & (LA_UID|LA_GID|LA_PROJID))
mutex_lock(&mo->mot_lov_mutex);
/* all attrs are packed into mti_attr in unpack_setattr */
rc = mo_attr_set(info->mti_env, mdt_object_child(mo), ma);
- if (ma->ma_attr.la_valid & (LA_UID|LA_GID))
+ if (ma->ma_attr.la_valid & (LA_UID|LA_GID|LA_PROJID))
mutex_unlock(&mo->mot_lov_mutex);
if (rc != 0)
/* If an up2date copy exists in the backend, add dirty flag */
if ((ma->ma_valid & MA_HSM) && (ma->ma_hsm.mh_flags & HS_EXISTS)
&& !(ma->ma_hsm.mh_flags & (HS_DIRTY|HS_RELEASED))) {
- struct mdt_lock_handle *lh = &info->mti_lh[MDT_LH_CHILD];
-
ma->ma_hsm.mh_flags |= HS_DIRTY;
- mdt_lock_reg_init(lh, LCK_PW);
- rc = mdt_object_lock(info, mo, lh, MDS_INODELOCK_XATTR);
- if (rc != 0)
- RETURN(rc);
-
rc = mdt_hsm_attr_set(info, mo, &ma->ma_hsm);
if (rc)
CERROR("file attribute change error for "DFID": %d\n",
PFID(mdt_object_fid(mo)), rc);
- mdt_object_unlock(info, mo, lh, rc);
}
RETURN(rc);
GOTO(out_put, rc = -EPROTO);
rc = mdt_attr_set(info, mo, ma);
- if (rc)
- GOTO(out_put, rc);
- } else if ((ma->ma_valid & MA_LOV) && (ma->ma_valid & MA_INODE)) {
- struct lu_buf *buf = &info->mti_buf;
-
- if (ma->ma_attr.la_valid != 0)
- GOTO(out_put, rc = -EPROTO);
-
- buf->lb_buf = ma->ma_lmm;
- buf->lb_len = ma->ma_lmm_size;
- rc = mo_xattr_set(info->mti_env, mdt_object_child(mo),
- buf, XATTR_NAME_LOV, 0);
if (rc)
GOTO(out_put, rc);
- } else if ((ma->ma_valid & MA_LMV) && (ma->ma_valid & MA_INODE)) {
+ } else if ((ma->ma_valid & (MA_LOV | MA_LMV)) &&
+ (ma->ma_valid & MA_INODE)) {
struct lu_buf *buf = &info->mti_buf;
struct mdt_lock_handle *lh;
lh = &info->mti_lh[MDT_LH_PARENT];
mdt_lock_reg_init(lh, LCK_PW);
- rc = mdt_object_lock(info, mo, lh,
- MDS_INODELOCK_XATTR);
+ rc = mdt_object_lock(info, mo, lh, MDS_INODELOCK_XATTR);
if (rc != 0)
GOTO(out_put, rc);
- buf->lb_buf = ma->ma_lmv;
- buf->lb_len = ma->ma_lmv_size;
- rc = mo_xattr_set(info->mti_env, mdt_object_child(mo),
- buf, XATTR_NAME_DEFAULT_LMV, 0);
+ if (ma->ma_valid & MA_LOV) {
+ buf->lb_buf = ma->ma_lmm;
+ buf->lb_len = ma->ma_lmm_size;
+ } else {
+ buf->lb_buf = ma->ma_lmv;
+ buf->lb_len = ma->ma_lmv_size;
+ }
+ rc = mo_xattr_set(info->mti_env, mdt_object_child(mo), buf,
+ (ma->ma_valid & MA_LOV) ?
+ XATTR_NAME_LOV : XATTR_NAME_DEFAULT_LMV,
+ 0);
mdt_object_unlock(info, mo, lh, rc);
if (rc)
RETURN(err_serious(-EOPNOTSUPP));
}
- rc = mdt_md_create(info);
+ rc = mdt_create(info);
RETURN(rc);
}
if (IS_ERR(mp))
RETURN(PTR_ERR(mp));
- if (!mdt_object_remote(mp)) {
+ if (mdt_object_remote(mp)) {
+ cos_incompat = true;
+ } else {
rc = mdt_version_get_check_save(info, mp, 0);
if (rc)
GOTO(put_parent, rc);
}
+relock:
+ parent_lh = &info->mti_lh[MDT_LH_PARENT];
+ mdt_lock_pdo_init(parent_lh, LCK_PW, &rr->rr_name);
+ rc = mdt_reint_object_lock(info, mp, parent_lh, MDS_INODELOCK_UPDATE,
+ cos_incompat);
+ if (rc != 0)
+ GOTO(put_parent, rc);
+
/* lookup child object along with version checking */
fid_zero(child_fid);
rc = mdt_lookup_version_check(info, mp, &rr->rr_name, child_fid, 1);
no_name = 1;
*child_fid = *rr->rr_fid2;
} else {
- GOTO(put_parent, rc);
+ GOTO(unlock_parent, rc);
}
}
if (!fid_is_md_operative(child_fid))
- GOTO(put_parent, rc = -EPERM);
+ GOTO(unlock_parent, rc = -EPERM);
/* We will lock the child regardless it is local or remote. No harm. */
mc = mdt_object_find(info->mti_env, info->mti_mdt, child_fid);
if (IS_ERR(mc))
- GOTO(put_parent, rc = PTR_ERR(mc));
+ GOTO(unlock_parent, rc = PTR_ERR(mc));
- rc = mdt_init_slaves(info, mc, s0_fid);
- cos_incompat = (mdt_object_remote(mp) || (rc > 0));
-
- parent_lh = &info->mti_lh[MDT_LH_PARENT];
- mdt_lock_pdo_init(parent_lh, LCK_PW, &rr->rr_name);
- rc = mdt_reint_object_lock(info, mp, parent_lh, MDS_INODELOCK_UPDATE,
- cos_incompat);
- if (rc != 0)
- GOTO(put_child, rc);
+ if (!cos_incompat && mdt_init_slaves(info, mc, s0_fid) > 0) {
+ cos_incompat = true;
+ mdt_object_put(info->mti_env, mc);
+ mdt_object_unlock(info, mp, parent_lh, -EAGAIN);
+ goto relock;
+ }
child_lh = &info->mti_lh[MDT_LH_CHILD];
mdt_lock_reg_init(child_lh, LCK_EX);
if (!mdt_is_dne_client(req->rq_export))
/* Return -ENOTSUPP for old client */
- GOTO(unlock_parent, rc = -ENOTSUPP);
+ GOTO(put_child, rc = -ENOTSUPP);
if (!md_capable(uc, CFS_CAP_SYS_ADMIN))
- GOTO(unlock_parent, rc = -EPERM);
+ GOTO(put_child, rc = -EPERM);
ma->ma_need = MA_INODE;
ma->ma_valid = 0;
rc = mdo_unlink(info->mti_env, mdt_object_child(mp),
NULL, &rr->rr_name, ma, no_name);
- GOTO(unlock_parent, rc);
+ GOTO(put_child, rc);
}
if (mdt_object_remote(mc)) {
CDEBUG(D_INFO, "%s: name "DNAME" cannot find "DFID"\n",
mdt_obd_name(info->mti_mdt),
PNAME(&rr->rr_name), PFID(mdt_object_fid(mc)));
- GOTO(unlock_parent, rc = -ENOENT);
+ GOTO(put_child, rc = -ENOENT);
}
CDEBUG(D_INFO, "%s: name "DNAME": "DFID" is on another MDT\n",
mdt_obd_name(info->mti_mdt),
if (!mdt_is_dne_client(req->rq_export))
/* Return -ENOTSUPP for old client */
- GOTO(unlock_parent, rc = -ENOTSUPP);
+ GOTO(put_child, rc = -ENOTSUPP);
/* Revoke the LOOKUP lock of the remote object granted by
* this MDT. Since the unlink will happen on another MDT,
child_lh->mlh_rreg_mode,
MDS_INODELOCK_LOOKUP, false);
if (rc != ELDLM_OK)
- GOTO(unlock_parent, rc);
+ GOTO(put_child, rc);
lock_ibits &= ~MDS_INODELOCK_LOOKUP;
}
mdt_unlock_slaves(info, mc, MDS_INODELOCK_UPDATE, s0_lh, s0_obj, einfo,
rc);
mdt_object_unlock(info, mc, child_lh, rc);
-unlock_parent:
- mdt_object_unlock(info, mp, parent_lh, rc);
put_child:
mdt_object_put(info->mti_env, mc);
+unlock_parent:
+ mdt_object_unlock(info, mp, parent_lh, rc);
put_parent:
mdt_object_put(info->mti_env, mp);
return rc;
struct mdt_lock_list *mll;
struct lu_name name;
struct lu_fid fid;
+ __u64 ibits;
linkea_entry_unpack(ldata.ld_lee, &ldata.ld_reclen,
&name, &fid);
* cannot be gotten because of conflicting locks, then drop all
* current locks, send an AST to the client, and start again. */
mdt_lock_pdo_init(&mll->mll_lh, LCK_PW, &name);
- rc = mdt_reint_object_lock_try(info, mdt_pobj, &mll->mll_lh,
- MDS_INODELOCK_UPDATE, true);
- if (rc == 0) {
+ ibits = 0;
+ rc = mdt_object_lock_try(info, mdt_pobj, &mll->mll_lh, &ibits,
+ MDS_INODELOCK_UPDATE, true);
+ if (!(ibits & MDS_INODELOCK_UPDATE)) {
mdt_unlock_list(info, lock_list, rc);
CDEBUG(D_INFO, "%s: busy lock on "DFID" %s retry %d\n",
/* 1: lock the source dir. */
msrcdir = mdt_object_find(info->mti_env, info->mti_mdt, rr->rr_fid1);
if (IS_ERR(msrcdir)) {
- CERROR("%s: cannot find source dir "DFID" : rc = %d\n",
+ CDEBUG(D_OTHER, "%s: cannot find source dir "DFID" : rc = %d\n",
mdt_obd_name(info->mti_mdt), PFID(rr->rr_fid1),
(int)PTR_ERR(msrcdir));
RETURN(PTR_ERR(msrcdir));
GOTO(out_unlock_parent, rc = PTR_ERR(mold));
if (mdt_object_remote(mold)) {
- CERROR("%s: source "DFID" is on the remote MDT\n",
+ CDEBUG(D_OTHER, "%s: source "DFID" is on the remote MDT\n",
mdt_obd_name(info->mti_mdt), PFID(old_fid));
GOTO(out_put_child, rc = -EREMOTE);
}
if (S_ISREG(lu_object_attr(&mold->mot_obj)) &&
!mdt_object_remote(msrcdir)) {
- CERROR("%s: parent "DFID" is still on the same"
+ CDEBUG(D_OTHER, "%s: parent "DFID" is still on the same"
" MDT, which should be migrated first:"
" rc = %d\n", mdt_obd_name(info->mti_mdt),
PFID(mdt_object_fid(msrcdir)), -EPERM);
lease_broken = ldlm_is_cancel(lease);
unlock_res_and_lock(lease);
- LDLM_DEBUG(lease, DFID " lease broken? %d\n",
+ LDLM_DEBUG(lease, DFID " lease broken? %d",
PFID(mdt_object_fid(mold)), lease_broken);
/* Cancel server side lease. Client side counterpart should
if ((ma->ma_valid & MA_HSM) && ma->ma_hsm.mh_flags != 0) {
rc = -ENOSYS;
- CERROR("%s: cannot migrate HSM archived file "DFID": rc = %d\n",
+ CDEBUG(D_OTHER,
+ "%s: cannot migrate HSM archived file "DFID": rc = %d\n",
mdt_obd_name(info->mti_mdt), PFID(old_fid), rc);
GOTO(out_unlock_child, rc);
}
lmv_le_to_cpu(ma->ma_lmv, ma->ma_lmv);
lmm1 = &ma->ma_lmv->lmv_md_v1;
if (!(lmm1->lmv_hash_type & LMV_HASH_FLAG_MIGRATION)) {
- CERROR("%s: can not migrate striped dir "DFID
+ CDEBUG(D_OTHER, "%s: can not migrate striped dir "DFID
": rc = %d\n", mdt_obd_name(info->mti_mdt),
PFID(mdt_object_fid(mold)), -EPERM);
GOTO(out_unlock_child, rc = -EPERM);
GOTO(out_unlock_child, rc = PTR_ERR(mnew));
if (!mdt_object_remote(mnew)) {
- CERROR("%s: "DFID" being migrated is on this MDT:"
+ CDEBUG(D_OTHER,
+ "%s: "DFID" being migrated is on this MDT:"
" rc = %d\n", mdt_obd_name(info->mti_mdt),
PFID(rr->rr_fid2), -EPERM);
GOTO(out_put_new, rc = -EPERM);
if (IS_ERR(mnew))
GOTO(out_unlock_child, rc = PTR_ERR(mnew));
if (!mdt_object_remote(mnew)) {
- CERROR("%s: Migration "DFID" is on this MDT:"
+ CDEBUG(D_OTHER, "%s: Migration "DFID" is on this MDT:"
" rc = %d\n", mdt_obd_name(info->mti_mdt),
PFID(rr->rr_fid2), -EXDEV);
GOTO(out_put_new, rc = -EXDEV);
rc = mdt_object_lock_save(info, msrcdir, lh_srcdirp, 0,
cos_incompat);
+ if (rc != 0) {
+ mdt_object_unlock(info, mtgtdir, lh_tgtdirp, rc);
+ GOTO(out_put_tgtdir, rc);
+ }
} else {
rc = mdt_object_lock_save(info, msrcdir, lh_srcdirp, 0,
cos_incompat);
cos_incompat);
OBD_FAIL_TIMEOUT(OBD_FAIL_MDS_PDO_LOCK2, 10);
}
+ if (rc != 0) {
+ mdt_object_unlock(info, msrcdir, lh_srcdirp, rc);
+ GOTO(out_put_tgtdir, rc);
+ }
}
- if (rc)
- GOTO(out_unlock_parents, rc);
OBD_FAIL_TIMEOUT(OBD_FAIL_MDS_RENAME4, 5);
OBD_FAIL_TIMEOUT(OBD_FAIL_MDS_RENAME2, 5);