struct dt_device *dev = lfsck_obj2dev(orphan);
struct dt_object *parent;
struct thandle *th = NULL;
- struct lustre_handle plh = { 0 };
+ struct lfsck_lock_handle *pllh = &info->lti_llh;
struct lustre_handle clh = { 0 };
struct linkea_data ldata = { NULL };
struct lu_buf linkea_buf;
parent = lfsck->li_lpf_obj;
pfid = lfsck_dto2fid(parent);
- /* Hold update lock on the parent to prevent others to access. */
- rc = lfsck_ibits_lock(env, lfsck, parent, &plh,
- MDS_INODELOCK_UPDATE, LCK_EX);
- if (rc != 0)
- GOTO(log, rc);
-
+again:
do {
namelen = snprintf(info->lti_key, NAME_MAX, DFID"%s-%s-%d",
PFID(cfid), infix, type, idx++);
exist = true;
} while (rc == 0 && !exist);
+ rc = lfsck_lock(env, lfsck, parent, info->lti_key, pllh,
+ MDS_INODELOCK_UPDATE, LCK_PW);
+ if (rc != 0)
+ GOTO(log, rc);
+
+ /* Re-check whether the name conflict with othrs after taken
+ * the ldlm lock. */
+ rc = dt_lookup(env, parent, (struct dt_rec *)&tfid,
+ (const struct dt_key *)info->lti_key, BYPASS_CAPA);
+ if (rc == 0) {
+ if (!lu_fid_eq(cfid, &tfid)) {
+ exist = false;
+ lfsck_unlock(pllh);
+ goto again;
+ }
+
+ exist = true;
+ } else if (rc != -ENOENT) {
+ GOTO(log, rc);
+ } else {
+ exist = false;
+ }
+
cname->ln_name = info->lti_key;
cname->ln_namelen = namelen;
rc = linkea_data_new(&ldata, &info->lti_linkea_buf2);
GOTO(log, rc);
rc = lfsck_ibits_lock(env, lfsck, orphan, &clh,
- MDS_INODELOCK_UPDATE | MDS_INODELOCK_LOOKUP,
- LCK_EX);
+ MDS_INODELOCK_UPDATE | MDS_INODELOCK_LOOKUP |
+ MDS_INODELOCK_XATTR, LCK_EX);
if (rc != 0)
GOTO(log, rc);
log:
lfsck_ibits_unlock(&clh, LCK_EX);
- lfsck_ibits_unlock(&plh, LCK_EX);
+ lfsck_unlock(pllh);
CDEBUG(D_LFSCK, "%s: namespace LFSCK insert orphan for the "
"object "DFID", name = %s: rc = %d\n",
lfsck_lfsck2name(lfsck), PFID(cfid),
struct dt_object *pobj = NULL;
struct dt_object *cobj = NULL;
struct thandle *th = NULL;
- struct lustre_handle lh = { 0 };
+ struct lfsck_lock_handle *llh = &info->lti_llh;
int rc = 0;
ENTRY;
if (lfsck->li_bookmark_ram.lb_param & LPF_DRYRUN)
GOTO(log, rc = 1);
- /* Hold update lock on the pobj to prevent others to access. */
- rc = lfsck_ibits_lock(env, lfsck, pobj, &lh,
- MDS_INODELOCK_UPDATE, LCK_EX);
+ rc = lfsck_lock(env, lfsck, parent, name, llh,
+ MDS_INODELOCK_UPDATE, LCK_PW);
if (rc != 0)
GOTO(log, rc);
dt_trans_stop(env, dev, th);
unlock:
- lfsck_ibits_unlock(&lh, LCK_EX);
+ lfsck_unlock(llh);
log:
CDEBUG(D_LFSCK, "%s: namespace LFSCK insert object "DFID" with "
struct dt_device *dev = lfsck_obj2dev(orphan);
struct dt_object *parent = NULL;
struct thandle *th = NULL;
- struct lustre_handle lh = { 0 };
+ struct lfsck_lock_handle *llh = &info->lti_llh;
struct linkea_data ldata = { NULL };
struct lu_buf linkea_buf;
struct lu_buf lmv_buf;
if (IS_ERR(dev))
GOTO(log, rc = PTR_ERR(dev));
- /* Hold update lock on the parent to prevent others to access. */
- rc = lfsck_ibits_lock(env, lfsck, parent, &lh,
- MDS_INODELOCK_UPDATE, LCK_EX);
- if (rc != 0)
- GOTO(log, rc);
-
idx = 0;
+
+again:
do {
namelen = snprintf(name, 31, DFID"-P-%d",
PFID(cfid), idx++);
rc = dt_lookup(env, parent, (struct dt_rec *)&tfid,
(const struct dt_key *)name, BYPASS_CAPA);
if (rc != 0 && rc != -ENOENT)
- GOTO(unlock1, rc);
+ GOTO(log, rc);
} while (rc == 0);
+ rc = lfsck_lock(env, lfsck, parent, name, llh,
+ MDS_INODELOCK_UPDATE, LCK_PW);
+ if (rc != 0)
+ GOTO(log, rc);
+
+ /* Re-check whether the name conflict with othrs after taken
+ * the ldlm lock. */
+ rc = dt_lookup(env, parent, (struct dt_rec *)&tfid,
+ (const struct dt_key *)name, BYPASS_CAPA);
+ if (unlikely(rc == 0)) {
+ lfsck_unlock(llh);
+ goto again;
+ }
+
+ if (rc != -ENOENT)
+ GOTO(unlock1, rc);
+
cname->ln_name = name;
cname->ln_namelen = namelen;
dt_trans_stop(env, dev, th);
unlock1:
- lfsck_ibits_unlock(&lh, LCK_EX);
+ lfsck_unlock(llh);
log:
CDEBUG(D_LFSCK, "%s: namespace LFSCK create orphan dir for "
ENTRY;
rc = lfsck_ibits_lock(env, lfsck, obj, &lh,
- MDS_INODELOCK_UPDATE |
- MDS_INODELOCK_XATTR, LCK_EX);
+ MDS_INODELOCK_UPDATE | MDS_INODELOCK_XATTR,
+ LCK_EX);
if (rc != 0)
GOTO(log, rc);
struct lu_name *cname,
struct lu_fid *pfid)
{
- struct lu_fid *cfid = &lfsck_env_info(env)->lti_fid3;
- struct lustre_handle lh = { 0 };
- int rc;
+ struct lfsck_thread_info *info = lfsck_env_info(env);
+ struct lu_fid *cfid = &info->lti_fid3;
+ struct lfsck_lock_handle *llh = &info->lti_llh;
+ int rc;
ENTRY;
- rc = lfsck_ibits_lock(env, com->lc_lfsck, parent, &lh,
- MDS_INODELOCK_UPDATE, LCK_EX);
+ rc = lfsck_lock(env, com->lc_lfsck, parent, cname->ln_name, llh,
+ MDS_INODELOCK_UPDATE, LCK_PR);
if (rc != 0)
RETURN(rc);
dt_read_lock(env, parent, 0);
if (unlikely(lfsck_is_dead_obj(parent))) {
dt_read_unlock(env, parent);
- lfsck_ibits_unlock(&lh, LCK_EX);
+ lfsck_unlock(llh);
rc = lfsck_namespace_shrink_linkea(env, com, child, ldata,
cname, pfid, true);
* has removed the specified linkEA entry by race, then it is OK,
* because the subsequent lfsck_namespace_shrink_linkea() can handle
* such case. */
- lfsck_ibits_unlock(&lh, LCK_EX);
+ lfsck_unlock(llh);
if (rc == -ENOENT) {
rc = lfsck_namespace_shrink_linkea(env, com, child, ldata,
cname, pfid, true);
const char *name = cname->ln_name;
struct dt_object *pobj = NULL;
struct dt_object *cobj = NULL;
- struct lustre_handle plh = { 0 };
+ struct lfsck_lock_handle *pllh = &info->lti_llh;
struct lustre_handle clh = { 0 };
struct linkea_data ldata = { NULL };
struct thandle *th = NULL;
if (unlikely(!dt_try_as_dir(env, pobj)))
GOTO(log, rc = -ENOTDIR);
- /* Hold update lock on the pobj to prevent others to access. */
- rc = lfsck_ibits_lock(env, lfsck, pobj, &plh,
- MDS_INODELOCK_UPDATE, LCK_EX);
+ rc = lfsck_lock(env, lfsck, parent, name, pllh,
+ MDS_INODELOCK_UPDATE, LCK_PW);
if (rc != 0)
GOTO(log, rc);
/* lock the object to be destroyed. */
rc = lfsck_ibits_lock(env, lfsck, cobj, &clh,
MDS_INODELOCK_UPDATE |
- MDS_INODELOCK_XATTR, LCK_EX);
+ MDS_INODELOCK_UPDATE | MDS_INODELOCK_XATTR,
+ LCK_EX);
if (rc != 0)
GOTO(log, rc);
log:
lfsck_ibits_unlock(&clh, LCK_EX);
- lfsck_ibits_unlock(&plh, LCK_EX);
+ lfsck_unlock(pllh);
if (cobj != NULL && !IS_ERR(cobj))
lfsck_object_put(env, cobj);
const char *name, const char *name2,
__u16 type, bool update, bool dec)
{
- struct dt_insert_rec *rec = &lfsck_env_info(env)->lti_dt_rec;
- const struct lu_fid *cfid = lfsck_dto2fid(child);
- struct lu_fid tfid;
- struct lfsck_instance *lfsck = com->lc_lfsck;
- struct dt_device *dev = lfsck_obj2dev(parent);
- struct thandle *th = NULL;
- struct lustre_handle lh = { 0 };
- int rc = 0;
+ struct lfsck_thread_info *info = lfsck_env_info(env);
+ struct dt_insert_rec *rec = &info->lti_dt_rec;
+ const struct lu_fid *cfid = lfsck_dto2fid(child);
+ struct lu_fid tfid;
+ struct lfsck_instance *lfsck = com->lc_lfsck;
+ struct dt_device *dev = lfsck->li_next;
+ struct thandle *th = NULL;
+ struct lfsck_lock_handle *llh = &info->lti_llh;
+ struct lustre_handle lh = { 0 };
+ int rc = 0;
ENTRY;
if (unlikely(!dt_try_as_dir(env, parent)))
GOTO(log, rc = -ENOTDIR);
- rc = lfsck_ibits_lock(env, lfsck, parent, &lh,
- MDS_INODELOCK_UPDATE, LCK_EX);
+ if (!update || strcmp(name, name2) == 0)
+ rc = lfsck_lock(env, lfsck, parent, name, llh,
+ MDS_INODELOCK_UPDATE, LCK_PW);
+ else
+ rc = lfsck_ibits_lock(env, lfsck, parent, &lh,
+ MDS_INODELOCK_UPDATE, LCK_PW);
if (rc != 0)
GOTO(log, rc);
LNTF_CHECK_LINKEA, true);
unlock1:
- lfsck_ibits_unlock(&lh, LCK_EX);
+ /* It is harmless even if unlock the unused lock_handle */
+ lfsck_ibits_unlock(&lh, LCK_PW);
+ lfsck_unlock(llh);
log:
CDEBUG(D_LFSCK, "%s: namespace LFSCK assistant found bad name "
LASSERT(S_ISREG(lfsck_object_type(obj)));
rc = lfsck_ibits_lock(env, lfsck, obj, &lh,
- MDS_INODELOCK_UPDATE |
- MDS_INODELOCK_XATTR, LCK_EX);
+ MDS_INODELOCK_UPDATE, LCK_PW);
if (rc != 0)
GOTO(log, rc);
dt_trans_stop(env, dev, th);
log:
- lfsck_ibits_unlock(&lh, LCK_EX);
+ lfsck_ibits_unlock(&lh, LCK_PW);
CDEBUG(D_LFSCK, "%s: namespace LFSCK repaired the object "DFID"'s "
"nlink count from %u to %u: rc = %d\n",
lfsck_lfsck2name(lfsck), PFID(cfid), old, la->la_nlink, rc);
struct dt_object *cobj = NULL;
const struct lu_name *cname;
struct linkea_data ldata = { NULL };
- struct lustre_handle lh = { 0 };
+ struct lfsck_lock_handle *llh = &info->lti_llh;
struct lu_buf linkea_buf;
struct lu_buf lmv_buf;
struct lfsck_instance *lfsck = com->lc_lfsck;
if (rc != 0)
GOTO(log, rc);
- rc = lfsck_ibits_lock(env, lfsck, pobj, &lh,
- MDS_INODELOCK_UPDATE, LCK_EX);
+ rc = lfsck_lock(env, lfsck, parent, lnr->lnr_name, llh,
+ MDS_INODELOCK_UPDATE, LCK_PR);
if (rc != 0)
GOTO(log, rc);
dt_trans_stop(env, dev, th);
log:
- lfsck_ibits_unlock(&lh, LCK_EX);
+ lfsck_unlock(llh);
CDEBUG(D_LFSCK, "%s: namespace LFSCK assistant found dangling "
"reference for: parent "DFID", child "DFID", type %u, "
"name %s. %s: rc = %d\n", lfsck_lfsck2name(lfsck),
struct dt_object *dir, const char *name,
const struct lu_fid *fid, __u32 type)
{
- struct dt_insert_rec *rec = &lfsck_env_info(env)->lti_dt_rec;
- struct dt_device *dev = lfsck_obj2dev(dir);
- struct lustre_handle lh = { 0 };
- struct thandle *th;
- int rc;
- bool exists = true;
+ struct lfsck_thread_info *info = lfsck_env_info(env);
+ struct dt_insert_rec *rec = &info->lti_dt_rec;
+ struct lfsck_lock_handle *llh = &info->lti_llh;
+ struct dt_device *dev = lfsck_obj2dev(dir);
+ struct thandle *th;
+ int rc;
+ bool exists = true;
ENTRY;
- rc = lfsck_ibits_lock(env, lfsck, dir, &lh,
- MDS_INODELOCK_UPDATE, LCK_EX);
+ rc = lfsck_lock(env, lfsck, dir, name, llh,
+ MDS_INODELOCK_UPDATE, LCK_PW);
if (rc != 0)
RETURN(rc);
dt_trans_stop(env, dev, th);
unlock:
- lfsck_ibits_unlock(&lh, LCK_EX);
+ lfsck_unlock(llh);
CDEBUG(D_LFSCK, "%s: update name entry "DFID"/%s with the FID "DFID
" and the type %o: rc = %d\n", lfsck_lfsck2name(lfsck),
PFID(lfsck_dto2fid(dir)), name, PFID(fid), type, rc);