X-Git-Url: https://git.whamcloud.com/?p=fs%2Flustre-release.git;a=blobdiff_plain;f=lustre%2Fobdclass%2Fllog_osd.c;h=92d71869e5a914d7defacd485fe20ac641a1fb8f;hp=54f3dd46f217575ab37e78d54b93bd53a69caaca;hb=82c6e42d6137f39a1f2394b7bc6e8d600eb36181;hpb=d6bd5e9cc49b3bb9901ada503107e8b0eca44f7e diff --git a/lustre/obdclass/llog_osd.c b/lustre/obdclass/llog_osd.c index 54f3dd4..92d7186 100644 --- a/lustre/obdclass/llog_osd.c +++ b/lustre/obdclass/llog_osd.c @@ -412,6 +412,9 @@ static int llog_osd_write_rec(const struct lu_env *env, LASSERT(llh->llh_size == reclen); } + /* return error if osp object is stale */ + if (idx != LLOG_HEADER_IDX && dt_object_stale(o)) + RETURN(-ESTALE); rc = dt_attr_get(env, o, &lgi->lgi_attr); if (rc) RETURN(rc); @@ -437,7 +440,7 @@ static int llog_osd_write_rec(const struct lu_env *env, /* llog can be empty only when first record is being written */ LASSERT(ergo(idx > 0, lgi->lgi_attr.la_size > 0)); - if (!ext2_test_bit(idx, LLOG_HDR_BITMAP(llh))) { + if (!test_bit_le(idx, LLOG_HDR_BITMAP(llh))) { CERROR("%s: modify unset record %u\n", o->do_lu.lo_dev->ld_obd->obd_name, idx); RETURN(-ENOENT); @@ -611,9 +614,10 @@ static int llog_osd_write_rec(const struct lu_env *env, /* the lgh_hdr_mutex protects llog header data from concurrent * update/cancel, the llh_count and llh_bitmap are protected */ mutex_lock(&loghandle->lgh_hdr_mutex); - if (ext2_set_bit(index, LLOG_HDR_BITMAP(llh))) { - CERROR("%s: index %u already set in log bitmap\n", - o->do_lu.lo_dev->ld_obd->obd_name, index); + if (__test_and_set_bit_le(index, LLOG_HDR_BITMAP(llh))) { + CERROR("%s: index %u already set in llog bitmap "DFID"\n", + o->do_lu.lo_dev->ld_obd->obd_name, index, + PFID(lu_object_fid(&o->do_lu))); mutex_unlock(&loghandle->lgh_hdr_mutex); LBUG(); /* should never happen */ } @@ -722,7 +726,7 @@ out_unlock: out: /* cleanup llog for error case */ mutex_lock(&loghandle->lgh_hdr_mutex); - ext2_clear_bit(index, LLOG_HDR_BITMAP(llh)); + clear_bit_le(index, LLOG_HDR_BITMAP(llh)); llh->llh_count--; mutex_unlock(&loghandle->lgh_hdr_mutex); @@ -910,8 +914,9 @@ static int llog_osd_next_block(const struct lu_env *env, if (rc) GOTO(out, rc); - CDEBUG(D_OTHER, "looking for log index %u (cur idx %u off" - "%llu), size %llu\n", next_idx, *cur_idx, + CDEBUG(D_OTHER, + "looking for log index %u (cur idx %u off %llu), size %llu\n", + next_idx, *cur_idx, *cur_offset, lgi->lgi_attr.la_size); while (*cur_offset < lgi->lgi_attr.la_size) { @@ -966,9 +971,25 @@ static int llog_osd_next_block(const struct lu_env *env, rec = buf; if (LLOG_REC_HDR_NEEDS_SWABBING(rec)) lustre_swab_llog_rec(rec); - tail = (struct llog_rec_tail *)((char *)buf + rc - sizeof(struct llog_rec_tail)); + + if (llog_verify_record(loghandle, rec)) { + /* + * the block seems corrupted. make a pad record so the + * caller can skip the block and try with the next one + */ + rec->lrh_len = rc; + rec->lrh_index = next_idx; + rec->lrh_type = LLOG_PAD_MAGIC; + + tail = rec_tail(rec); + tail->lrt_len = rc; + tail->lrt_index = next_idx; + + GOTO(out, rc = 0); + } + /* get the last record in block */ last_rec = (struct llog_rec_hdr *)((char *)buf + rc - tail->lrt_len); @@ -977,9 +998,7 @@ static int llog_osd_next_block(const struct lu_env *env, lustre_swab_llog_rec(last_rec); if (last_rec->lrh_index != tail->lrt_index) { - CERROR("%s: invalid llog tail at log id "DFID":%x " - "offset %llu last_rec idx %u tail idx %u" - "lrt len %u read_size %d\n", + CERROR("%s: invalid llog tail at log id "DFID":%x offset %llu last_rec idx %u tail idx %u lrt len %u read_size %d\n", o->do_lu.lo_dev->ld_obd->obd_name, PFID(&loghandle->lgh_id.lgl_oi.oi_fid), loghandle->lgh_id.lgl_ogen, *cur_offset, @@ -1007,7 +1026,7 @@ static int llog_osd_next_block(const struct lu_env *env, /* sanity check that the start of the new buffer is no farther * than the record that we wanted. This shouldn't happen. */ - if (rec->lrh_index > next_idx) { + if (next_idx && rec->lrh_index > next_idx) { if (!force_mini_rec && next_idx > last_idx) goto retry; @@ -1248,8 +1267,7 @@ static int llog_osd_open(const struct lu_env *env, struct llog_handle *handle, } else { /* If logid == NULL, then it means the caller needs * to allocate new FID (llog_cat_declare_add_rec()). */ - rc = obd_fid_alloc(env, ctxt->loc_exp, - &lgi->lgi_fid, NULL); + rc = dt_fid_alloc(env, dt, &lgi->lgi_fid, NULL, NULL); if (rc < 0) RETURN(rc); rc = 0; @@ -1310,7 +1328,12 @@ generate: GOTO(out, rc); new_id = true; } - + if (OBD_FAIL_PRECHECK(OBD_FAIL_MDS_LLOG_UMOUNT_RACE) && + cfs_fail_val == 1) { + cfs_fail_val = 2; + OBD_RACE(OBD_FAIL_MDS_LLOG_UMOUNT_RACE); + msleep(MSEC_PER_SEC); + } o = ls_locate(env, ls, &lgi->lgi_fid, NULL); if (IS_ERR(o)) GOTO(out_name, rc = PTR_ERR(o)); @@ -2011,7 +2034,7 @@ int llog_osd_get_cat_list(const struct lu_env *env, struct dt_device *d, if (IS_ERR(th)) GOTO(out, rc = PTR_ERR(th)); - lgi->lgi_attr.la_valid = LA_MODE; + lgi->lgi_attr.la_valid = LA_MODE | LA_TYPE; lgi->lgi_attr.la_mode = S_IFREG | S_IRUGO | S_IWUSR; lgi->lgi_dof.dof_type = dt_mode_to_dft(S_IFREG);