X-Git-Url: https://git.whamcloud.com/?a=blobdiff_plain;f=lustre%2Fmdd%2Fmdd_device.c;h=ac8133a2d12b1a3768e69fb1bfcefd99b65c1eb2;hb=b8785c155c81701a6e0d0ef397a347365e7de504;hp=9de0d803ac622a3296b86e49272fd812c2ebcaf9;hpb=2c74bfcb7a06addb42e79c1f561afb0acfaaa7d0;p=fs%2Flustre-release.git diff --git a/lustre/mdd/mdd_device.c b/lustre/mdd/mdd_device.c index 9de0d80..ac8133a 100644 --- a/lustre/mdd/mdd_device.c +++ b/lustre/mdd/mdd_device.c @@ -84,6 +84,7 @@ static int mdd_device_init(const struct lu_env *env, struct lu_device *d, mdd->mdd_txn_cb.dtc_txn_stop = mdd_txn_stop_cb; mdd->mdd_txn_cb.dtc_txn_commit = mdd_txn_commit_cb; mdd->mdd_txn_cb.dtc_cookie = mdd; + mdd->mdd_txn_cb.dtc_tag = LCT_MD_THREAD; CFS_INIT_LIST_HEAD(&mdd->mdd_txn_cb.dtc_linkage); mdd->mdd_atime_diff = MAX_ATIME_DIFF; @@ -115,8 +116,10 @@ static void mdd_device_shutdown(const struct lu_env *env, ENTRY; mdd_changelog_fini(env, m); dt_txn_callback_del(m->mdd_child, &m->mdd_txn_cb); - mdd_object_put(env, m->mdd_dot_lustre_objs.mdd_obf); - mdd_object_put(env, m->mdd_dot_lustre); + if (m->mdd_dot_lustre_objs.mdd_obf) + mdd_object_put(env, m->mdd_dot_lustre_objs.mdd_obf); + if (m->mdd_dot_lustre) + mdd_object_put(env, m->mdd_dot_lustre); if (m->mdd_obd_dev) mdd_fini_obd(env, m, cfg); orph_index_fini(env, m); @@ -192,7 +195,7 @@ static int mdd_changelog_llog_init(struct mdd_device *mdd) CERROR("changelog init failed: %d\n", rc); return rc; } - CDEBUG(D_INODE, "changelog starting index="LPU64"\n", + CDEBUG(D_IOCTL, "changelog starting index="LPU64"\n", mdd->mdd_cl.mc_index); /* Find last changelog user id */ @@ -214,7 +217,12 @@ static int mdd_changelog_llog_init(struct mdd_device *mdd) CERROR("changelog user init failed: %d\n", rc); return rc; } - return 0; + + /* If we have registered users, assume we want changelogs on */ + if (mdd->mdd_cl.mc_lastuser > 0) + rc = mdd_changelog_on(mdd, 1); + + return rc; } static int mdd_changelog_init(const struct lu_env *env, struct mdd_device *mdd) @@ -244,6 +252,34 @@ static void mdd_changelog_fini(const struct lu_env *env, struct mdd_device *mdd) mdd->mdd_cl.mc_flags = 0; } +/* Start / stop recording */ +int mdd_changelog_on(struct mdd_device *mdd, int on) +{ + int rc = 0; + + if ((on == 1) && ((mdd->mdd_cl.mc_flags & CLM_ON) == 0)) { + LCONSOLE_INFO("%s: changelog on\n", mdd2obd_dev(mdd)->obd_name); + if (mdd->mdd_cl.mc_flags & CLM_ERR) { + CERROR("Changelogs cannot be enabled due to error " + "condition (see %s log).\n", + mdd2obd_dev(mdd)->obd_name); + rc = -ESRCH; + } else { + spin_lock(&mdd->mdd_cl.mc_lock); + mdd->mdd_cl.mc_flags |= CLM_ON; + spin_unlock(&mdd->mdd_cl.mc_lock); + rc = mdd_changelog_write_header(mdd, CLM_START); + } + } else if ((on == 0) && ((mdd->mdd_cl.mc_flags & CLM_ON) == CLM_ON)) { + LCONSOLE_INFO("%s: changelog off\n",mdd2obd_dev(mdd)->obd_name); + rc = mdd_changelog_write_header(mdd, CLM_FINI); + spin_lock(&mdd->mdd_cl.mc_lock); + mdd->mdd_cl.mc_flags &= ~CLM_ON; + spin_unlock(&mdd->mdd_cl.mc_lock); + } + return rc; +} + /** Add a changelog entry \a rec to the changelog llog * \param mdd * \param rec @@ -379,13 +415,13 @@ static int create_dot_lustre_dir(const struct lu_env *env, struct mdd_device *m) memcpy(fid, &LU_DOT_LUSTRE_FID, sizeof(struct lu_fid)); mdo = llo_store_create_index(env, &m->mdd_md_dev, m->mdd_child, - mdd_root_dir_name, mdd_dot_lustre_name, + mdd_root_dir_name, dot_lustre_name, fid, &dt_directory_features); /* .lustre dir may be already present */ if (IS_ERR(mdo) && PTR_ERR(mdo) != -EEXIST) { rc = PTR_ERR(mdo); CERROR("creating obj [%s] fid = "DFID" rc = %d\n", - mdd_dot_lustre_name, PFID(fid), rc); + dot_lustre_name, PFID(fid), rc); RETURN(rc); } @@ -416,6 +452,12 @@ static int dot_lustre_xattr_get(const struct lu_env *env, return 0; } +static int dot_lustre_xattr_list(const struct lu_env *env, + struct md_object *obj, struct lu_buf *buf) +{ + return -EPERM; +} + static int dot_lustre_mdd_open(const struct lu_env *env, struct md_object *obj, int flags) { @@ -446,13 +488,30 @@ static int dot_lustre_close(const struct lu_env *env, struct md_object *obj, return 0; } +static dt_obj_version_t dot_lustre_version_get(const struct lu_env *env, + struct md_object *obj) +{ + return 0; +} + +static void dot_lustre_version_set(const struct lu_env *env, + struct md_object *obj, + dt_obj_version_t version) +{ + return; +} + + static struct md_object_operations mdd_dot_lustre_obj_ops = { .moo_attr_get = dot_lustre_attr_get, .moo_attr_set = dot_lustre_attr_set, .moo_xattr_get = dot_lustre_xattr_get, + .moo_xattr_list = dot_lustre_xattr_list, .moo_open = dot_lustre_mdd_open, .moo_close = dot_lustre_close, .moo_readpage = mdd_readpage, + .moo_version_get = dot_lustre_version_get, + .moo_version_set = dot_lustre_version_set, .moo_path = dot_lustre_path }; @@ -626,8 +685,7 @@ static int obf_lookup(const struct lu_env *env, struct md_object *p, while (*name == '[') name++; - sscanf(name, SFID, &(f->f_seq), &(f->f_oid), - &(f->f_ver)); + sscanf(name, SFID, RFID(f)); if (!fid_is_sane(f)) { CWARN("bad FID format [%s], should be "DFID"\n", lname->ln_name, (__u64)1, 2, 0); @@ -728,7 +786,7 @@ static int mdd_dot_lustre_setup(const struct lu_env *env, struct mdd_device *m) return rc; dt_dot_lustre = dt_store_open(env, m->mdd_child, mdd_root_dir_name, - mdd_dot_lustre_name, fid); + dot_lustre_name, fid); if (IS_ERR(dt_dot_lustre)) { rc = PTR_ERR(dt_dot_lustre); GOTO(out, rc); @@ -970,13 +1028,14 @@ static int mdd_update_capa_key(const struct lu_env *env, struct md_device *m, struct lustre_capa_key *key) { + struct mds_capa_info info = { .uuid = NULL, .capa = key }; struct mdd_device *mdd = lu2mdd_dev(&m->md_lu_dev); struct obd_export *lov_exp = mdd2obd_dev(mdd)->u.mds.mds_osc_exp; int rc; ENTRY; rc = obd_set_info_async(lov_exp, sizeof(KEY_CAPA_KEY), KEY_CAPA_KEY, - sizeof(*key), key, NULL); + sizeof(info), &info, NULL); RETURN(rc); } @@ -1081,9 +1140,13 @@ static int mdd_changelog_user_register(struct mdd_device *mdd, int *id) RETURN(-ENOMEM); } + /* Assume we want it on since somebody registered */ + rc = mdd_changelog_on(mdd, 1); + if (rc) + GOTO(out, rc); + rec->cur_hdr.lrh_len = sizeof(*rec); rec->cur_hdr.lrh_type = CHANGELOG_USER_REC; - rec->cur_endrec = 0ULL; spin_lock(&mdd->mdd_cl.mc_user_lock); if (mdd->mdd_cl.mc_lastuser == (unsigned int)(-1)) { spin_unlock(&mdd->mdd_cl.mc_user_lock); @@ -1091,10 +1154,12 @@ static int mdd_changelog_user_register(struct mdd_device *mdd, int *id) GOTO(out, rc = -EOVERFLOW); } *id = rec->cur_id = ++mdd->mdd_cl.mc_lastuser; + rec->cur_endrec = mdd->mdd_cl.mc_index; spin_unlock(&mdd->mdd_cl.mc_user_lock); + rc = llog_add(ctxt, &rec->cur_hdr, NULL, NULL, 0); - CDEBUG(D_INODE, "Registered changelog user %d\n", *id); + CDEBUG(D_IOCTL, "Registered changelog user %d\n", *id); out: OBD_FREE_PTR(rec); llog_ctxt_put(ctxt); @@ -1106,8 +1171,10 @@ struct mdd_changelog_user_data { __u64 mcud_minrec; /**< lowest changelog recno still referenced */ __u32 mcud_id; __u32 mcud_minid; /**< user id with lowest rec reference */ + __u32 mcud_usercount; int mcud_found:1; }; +#define MCUD_UNREGISTER -1LL /** Two things: * 1. Find the smallest record everyone is willing to purge @@ -1126,7 +1193,10 @@ static int mdd_changelog_user_purge_cb(struct llog_handle *llh, rec = (struct llog_changelog_user_rec *)hdr; - /* If we have a new endrec for this id, use it for the min check */ + mcud->mcud_usercount++; + + /* If we have a new endrec for this id, use it for the following + min check instead of its old value */ if (rec->cur_id == mcud->mcud_id) rec->cur_endrec = max(rec->cur_endrec, mcud->mcud_endrec); @@ -1142,13 +1212,15 @@ static int mdd_changelog_user_purge_cb(struct llog_handle *llh, /* Update this user's record */ mcud->mcud_found = 1; - /* Special case: unregister this user if endrec == -1 */ - if (mcud->mcud_endrec == -1) { + /* Special case: unregister this user */ + if (mcud->mcud_endrec == MCUD_UNREGISTER) { struct llog_cookie cookie; cookie.lgc_lgl = llh->lgh_id; cookie.lgc_index = hdr->lrh_index; rc = llog_cat_cancel_records(llh->u.phd.phd_cat_handle, 1, &cookie); + if (rc == 0) + mcud->mcud_usercount--; RETURN(rc); } @@ -1174,19 +1246,28 @@ static int mdd_changelog_user_purge(struct mdd_device *mdd, int id, CDEBUG(D_IOCTL, "Purge request: id=%d, endrec="LPD64"\n", id, endrec); + data.mcud_id = id; + data.mcud_minid = 0; + data.mcud_minrec = 0; + data.mcud_usercount = 0; + data.mcud_endrec = endrec; + spin_lock(&mdd->mdd_cl.mc_lock); + endrec = mdd->mdd_cl.mc_index; + spin_unlock(&mdd->mdd_cl.mc_lock); + if ((data.mcud_endrec == 0) || + ((data.mcud_endrec > endrec) && + (data.mcud_endrec != MCUD_UNREGISTER))) + data.mcud_endrec = endrec; + ctxt = llog_get_context(mdd2obd_dev(mdd),LLOG_CHANGELOG_USER_ORIG_CTXT); if (ctxt == NULL) return -ENXIO; LASSERT(ctxt->loc_handle->lgh_hdr->llh_flags & LLOG_F_IS_CAT); - data.mcud_id = id; - data.mcud_endrec = endrec; - data.mcud_minid = 0; - data.mcud_minrec = 0; rc = llog_cat_process(ctxt->loc_handle, mdd_changelog_user_purge_cb, (void *)&data, 0, 0); if ((rc >= 0) && (data.mcud_minrec > 0)) { - CDEBUG(D_INODE, "Purging CL entries up to "LPD64 + CDEBUG(D_IOCTL, "Purging changelog entries up to "LPD64 ", referenced by "CHANGELOG_USER_PREFIX"%d\n", data.mcud_minrec, data.mcud_minid); rc = mdd_changelog_llog_cancel(mdd, data.mcud_minrec); @@ -1195,6 +1276,8 @@ static int mdd_changelog_user_purge(struct mdd_device *mdd, int id, rc); } + llog_ctxt_put(ctxt); + if (!data.mcud_found) { CWARN("No entry for user %d. Last changelog reference is " LPD64" by changelog user %d\n", data.mcud_id, @@ -1202,14 +1285,17 @@ static int mdd_changelog_user_purge(struct mdd_device *mdd, int id, rc = -ENOENT; } - llog_ctxt_put(ctxt); + if (!rc && data.mcud_usercount == 0) + /* No more users; turn changelogs off */ + rc = mdd_changelog_on(mdd, 0); + RETURN (rc); } /** mdd_iocontrol * May be called remotely from mdt_iocontrol_handle or locally from - * mdt_iocontrol. Data may be freeform - remote handling doesn't enforce or - * swab an obd_ioctl_data format (but local ioctl handler does). + * mdt_iocontrol. Data may be freeform - remote handling doesn't enforce + * an obd_ioctl_data format (but local ioctl handler does). * \param cmd - ioc * \param len - data len * \param karg - ioctl data, in kernel space @@ -1227,10 +1313,6 @@ static int mdd_iocontrol(const struct lu_env *env, struct md_device *m, /* Doesn't use obd_ioctl_data */ if (cmd == OBD_IOC_CHANGELOG_CLEAR) { struct changelog_setinfo *cs = karg; - if (len != sizeof(*cs)) { - CERROR("Bad changelog_clear ioctl size %d\n", len); - RETURN(-EINVAL); - } rc = mdd_changelog_user_purge(mdd, cs->cs_id, cs->cs_recno); RETURN(rc); } @@ -1251,7 +1333,8 @@ static int mdd_iocontrol(const struct lu_env *env, struct md_device *m, rc = mdd_changelog_user_register(mdd, &data->ioc_u32_1); break; case OBD_IOC_CHANGELOG_DEREG: - rc = mdd_changelog_user_purge(mdd, data->ioc_u32_1, -1); + rc = mdd_changelog_user_purge(mdd, data->ioc_u32_1, + MCUD_UNREGISTER); break; default: rc = -EOPNOTSUPP;