* Copyright (c) 2001, 2010, Oracle and/or its affiliates. All rights reserved.
* Use is subject to license terms.
*
- * Copyright (c) 2011, 2012, Intel Corporation.
+ * Copyright (c) 2011, 2013, Intel Corporation.
*/
/*
* This file is part of Lustre, http://www.lustre.org/
# include <linux/pagemap.h>
# include <linux/miscdevice.h>
# include <linux/init.h>
+# include <linux/utsname.h>
#else
# include <liblustre.h>
#endif
#include <lustre_acl.h>
#include <obd_class.h>
#include <lustre_fid.h>
-#include <md_object.h>
#include <lprocfs_status.h>
#include <lustre_param.h>
#include <lustre_log.h>
}
}
+static inline int mdc_queue_wait(struct ptlrpc_request *req)
+{
+ struct client_obd *cli = &req->rq_import->imp_obd->u.cli;
+ int rc;
+
+ /* mdc_enter_request() ensures that this client has no more
+ * than cl_max_rpcs_in_flight RPCs simultaneously inf light
+ * against an MDT. */
+ rc = mdc_enter_request(cli);
+ if (rc != 0)
+ return rc;
+
+ rc = ptlrpc_queue_wait(req);
+ mdc_exit_request(cli);
+
+ return rc;
+}
+
/* Helper that implements most of mdc_getstatus and signal_completed_replay. */
/* XXX this should become mdc_get_info("key"), sending MDS_GET_INFO RPC */
static int send_getstatus(struct obd_import *imp, struct lu_fid *rootfid,
int rc;
ENTRY;
+ /* Single MDS without an LMV case */
+ if (op_data->op_flags & MF_GET_MDT_IDX) {
+ op_data->op_mds = 0;
+ RETURN(0);
+ }
*request = NULL;
req = ptlrpc_request_alloc(class_exp2cliimp(exp), &RQF_MDS_GETATTR);
if (req == NULL)
input_size);
}
- rc = ptlrpc_request_pack(req, LUSTRE_MDS_VERSION, opcode);
- if (rc) {
- ptlrpc_request_free(req);
- RETURN(rc);
- }
+ /* Flush local XATTR locks to get rid of a possible cancel RPC */
+ if (opcode == MDS_REINT && fid_is_sane(fid) &&
+ exp->exp_connect_data.ocd_ibits_known & MDS_INODELOCK_XATTR) {
+ CFS_LIST_HEAD(cancels);
+ int count;
+
+ /* Without that packing would fail */
+ if (input_size == 0)
+ req_capsule_set_size(&req->rq_pill, &RMF_EADATA,
+ RCL_CLIENT, 0);
+
+ count = mdc_resource_get_unused(exp, fid,
+ &cancels, LCK_EX,
+ MDS_INODELOCK_XATTR);
+
+ rc = mdc_prep_elc_req(exp, req, MDS_REINT, &cancels, count);
+ if (rc) {
+ ptlrpc_request_free(req);
+ RETURN(rc);
+ }
+ } else {
+ rc = ptlrpc_request_pack(req, LUSTRE_MDS_VERSION, opcode);
+ if (rc) {
+ ptlrpc_request_free(req);
+ RETURN(rc);
+ }
+ }
if (opcode == MDS_REINT) {
struct mdt_rec_setxattr *rec;
CLASSERT(sizeof(struct mdt_rec_setxattr) ==
sizeof(struct mdt_rec_reint));
- rec = req_capsule_client_get(&req->rq_pill, &RMF_REC_REINT);
- rec->sx_opcode = REINT_SETXATTR;
- /* TODO:
- * cfs_curproc_fs{u,g}id() should replace
- * current->fs{u,g}id for portability.
- */
- rec->sx_fsuid = cfs_curproc_fsuid();
- rec->sx_fsgid = cfs_curproc_fsgid();
- rec->sx_cap = cfs_curproc_cap_pack();
- rec->sx_suppgid1 = suppgid;
+ rec = req_capsule_client_get(&req->rq_pill, &RMF_REC_REINT);
+ rec->sx_opcode = REINT_SETXATTR;
+ rec->sx_fsuid = current_fsuid();
+ rec->sx_fsgid = current_fsgid();
+ rec->sx_cap = cfs_curproc_cap_pack();
+ rec->sx_suppgid1 = suppgid;
rec->sx_suppgid2 = -1;
rec->sx_fid = *fid;
rec->sx_valid = valid | OBD_MD_FLCTIME;
if (!buf)
RETURN(-EPROTO);
- acl = posix_acl_from_xattr(buf, body->aclsize);
+ acl = posix_acl_from_xattr(&init_user_ns, buf, body->aclsize);
if (IS_ERR(acl)) {
rc = PTR_ERR(acl);
CERROR("convert xattr to acl: %d\n", rc);
int mdc_close(struct obd_export *exp, struct md_op_data *op_data,
struct md_open_data *mod, struct ptlrpc_request **request)
{
- struct obd_device *obd = class_exp2obd(exp);
- struct ptlrpc_request *req;
- int rc;
- ENTRY;
+ struct obd_device *obd = class_exp2obd(exp);
+ struct ptlrpc_request *req;
+ struct req_format *req_fmt;
+ int rc;
+ int saved_rc = 0;
+ ENTRY;
- *request = NULL;
- req = ptlrpc_request_alloc(class_exp2cliimp(exp), &RQF_MDS_CLOSE);
+ req_fmt = &RQF_MDS_CLOSE;
+ if (op_data->op_bias & MDS_HSM_RELEASE) {
+ req_fmt = &RQF_MDS_RELEASE_CLOSE;
+
+ /* allocate a FID for volatile file */
+ rc = mdc_fid_alloc(exp, &op_data->op_fid2, op_data);
+ if (rc < 0) {
+ CERROR("%s: "DFID" failed to allocate FID: %d\n",
+ obd->obd_name, PFID(&op_data->op_fid1), rc);
+ /* save the errcode and proceed to close */
+ saved_rc = rc;
+ }
+ }
+
+ *request = NULL;
+ req = ptlrpc_request_alloc(class_exp2cliimp(exp), req_fmt);
if (req == NULL)
RETURN(-ENOMEM);
}
*request = req;
mdc_close_handle_reply(req, op_data, rc);
- RETURN(rc);
+ RETURN(rc < 0 ? rc : saved_rc);
}
int mdc_done_writing(struct obd_export *exp, struct md_op_data *op_data,
#endif
int mdc_readpage(struct obd_export *exp, struct md_op_data *op_data,
- struct page **pages, struct ptlrpc_request **request)
-{
- struct ptlrpc_request *req;
- struct ptlrpc_bulk_desc *desc;
- int i;
- cfs_waitq_t waitq;
- int resends = 0;
- struct l_wait_info lwi;
- int rc;
- ENTRY;
+ struct page **pages, struct ptlrpc_request **request)
+{
+ struct ptlrpc_request *req;
+ struct ptlrpc_bulk_desc *desc;
+ int i;
+ wait_queue_head_t waitq;
+ int resends = 0;
+ struct l_wait_info lwi;
+ int rc;
+ ENTRY;
- *request = NULL;
- cfs_waitq_init(&waitq);
+ *request = NULL;
+ init_waitqueue_head(&waitq);
restart_bulk:
req = ptlrpc_request_alloc(class_exp2cliimp(exp), &RQF_MDS_READPAGE);
/* NB req now owns desc and will free it when it gets freed */
for (i = 0; i < op_data->op_npages; i++)
- ptlrpc_prep_bulk_page_pin(desc, pages[i], 0, CFS_PAGE_SIZE);
+ ptlrpc_prep_bulk_page_pin(desc, pages[i], 0, PAGE_CACHE_SIZE);
mdc_readdir_pack(req, op_data->op_offset,
- CFS_PAGE_SIZE * op_data->op_npages,
+ PAGE_CACHE_SIZE * op_data->op_npages,
&op_data->op_fid1, op_data->op_capa1);
ptlrpc_request_set_replen(req);
if (req->rq_bulk->bd_nob_transferred & ~LU_PAGE_MASK) {
CERROR("Unexpected # bytes transferred: %d (%ld expected)\n",
req->rq_bulk->bd_nob_transferred,
- CFS_PAGE_SIZE * op_data->op_npages);
+ PAGE_CACHE_SIZE * op_data->op_npages);
ptlrpc_req_finished(req);
RETURN(-EPROTO);
}
/* Val is struct getinfo_fid2path result plus path */
vallen = sizeof(*gf) + gf->gf_pathlen;
- rc = obd_get_info(NULL, exp, keylen, key, &vallen, gf, NULL);
- if (rc)
- GOTO(out, rc);
+ rc = obd_get_info(NULL, exp, keylen, key, &vallen, gf, NULL);
+ if (rc != 0 && rc != -EREMOTE)
+ GOTO(out, rc);
if (vallen <= sizeof(*gf))
GOTO(out, rc = -EPROTO);
if (req == NULL)
GOTO(out, rc = -ENOMEM);
+ mdc_pack_body(req, NULL, NULL, OBD_MD_FLRMTPERM, 0, -1, 0);
+
/* Copy hsm_progress struct */
req_hpk = req_capsule_client_get(&req->rq_pill, &RMF_MDS_HSM_PROGRESS);
- LASSERT(req_hpk);
+ if (req_hpk == NULL)
+ GOTO(out, rc = -EPROTO);
+
*req_hpk = *hpk;
+ req_hpk->hpk_errval = lustre_errno_hton(hpk->hpk_errval);
ptlrpc_request_set_replen(req);
- rc = ptlrpc_queue_wait(req);
+ rc = mdc_queue_wait(req);
GOTO(out, rc);
out:
ptlrpc_req_finished(req);
if (req == NULL)
GOTO(out, rc = -ENOMEM);
+ mdc_pack_body(req, NULL, NULL, OBD_MD_FLRMTPERM, 0, -1, 0);
+
/* Copy hsm_progress struct */
archive_mask = req_capsule_client_get(&req->rq_pill,
&RMF_MDS_HSM_ARCHIVE);
- LASSERT(archive_mask);
+ if (archive_mask == NULL)
+ GOTO(out, rc = -EPROTO);
+
*archive_mask = archives;
ptlrpc_request_set_replen(req);
- rc = ptlrpc_queue_wait(req);
+ rc = mdc_queue_wait(req);
GOTO(out, rc);
out:
ptlrpc_req_finished(req);
ptlrpc_request_set_replen(req);
- rc = ptlrpc_queue_wait(req);
+ rc = mdc_queue_wait(req);
if (rc)
GOTO(out, rc);
if (req == NULL)
GOTO(out, rc = -ENOMEM);
+ mdc_pack_body(req, NULL, NULL, OBD_MD_FLRMTPERM, 0, -1, 0);
+
ptlrpc_request_set_replen(req);
- rc = ptlrpc_queue_wait(req);
+ rc = mdc_queue_wait(req);
GOTO(out, rc);
out:
ptlrpc_req_finished(req);
ptlrpc_request_set_replen(req);
- rc = ptlrpc_queue_wait(req);
+ rc = mdc_queue_wait(req);
if (rc)
GOTO(out, rc);
/* Copy states */
req_hss = req_capsule_client_get(&req->rq_pill, &RMF_HSM_STATE_SET);
- LASSERT(req_hss);
+ if (req_hss == NULL)
+ GOTO(out, rc = -EPROTO);
*req_hss = *hss;
ptlrpc_request_set_replen(req);
- rc = ptlrpc_queue_wait(req);
+ rc = mdc_queue_wait(req);
GOTO(out, rc);
EXIT;
RETURN(rc);
}
- mdc_pack_body(req, NULL, NULL, OBD_MD_FLRMTPERM, 0, 0, 0);
+ mdc_pack_body(req, NULL, NULL, OBD_MD_FLRMTPERM, 0, -1, 0);
/* Copy hsm_request struct */
req_hr = req_capsule_client_get(&req->rq_pill, &RMF_MDS_HSM_REQUEST);
- LASSERT(req_hr);
+ if (req_hr == NULL)
+ GOTO(out, rc = -EPROTO);
*req_hr = hur->hur_request;
/* Copy hsm_user_item structs */
req_hui = req_capsule_client_get(&req->rq_pill, &RMF_MDS_HSM_USER_ITEM);
- LASSERT(req_hui);
+ if (req_hui == NULL)
+ GOTO(out, rc = -EPROTO);
memcpy(req_hui, hur->hur_user_item,
hur->hur_request.hr_itemcount * sizeof(struct hsm_user_item));
/* Copy opaque field */
req_opaque = req_capsule_client_get(&req->rq_pill, &RMF_GENERIC_DATA);
- LASSERT(req_opaque);
+ if (req_opaque == NULL)
+ GOTO(out, rc = -EPROTO);
memcpy(req_opaque, hur_data(hur), hur->hur_request.hr_data_len);
ptlrpc_request_set_replen(req);
- rc = ptlrpc_queue_wait(req);
+ rc = mdc_queue_wait(req);
GOTO(out, rc);
out:
static struct kuc_hdr *changelog_kuc_hdr(char *buf, int len, int flags)
{
- struct kuc_hdr *lh = (struct kuc_hdr *)buf;
+ struct kuc_hdr *lh = (struct kuc_hdr *)buf;
- LASSERT(len <= CR_MAXSIZE);
+ LASSERT(len <= KUC_CHANGELOG_MSG_MAXSIZE);
- lh->kuc_magic = KUC_MAGIC;
- lh->kuc_transport = KUC_TRANSPORT_CHANGELOG;
- lh->kuc_flags = flags;
- lh->kuc_msgtype = CL_RECORD;
- lh->kuc_msglen = len;
- return lh;
+ lh->kuc_magic = KUC_MAGIC;
+ lh->kuc_transport = KUC_TRANSPORT_CHANGELOG;
+ lh->kuc_flags = flags;
+ lh->kuc_msgtype = CL_RECORD;
+ lh->kuc_msglen = len;
+ return lh;
}
#define D_CHANGELOG 0
struct changelog_show {
- __u64 cs_startrec;
- __u32 cs_flags;
- cfs_file_t *cs_fp;
- char *cs_buf;
- struct obd_device *cs_obd;
+ __u64 cs_startrec;
+ __u32 cs_flags;
+ struct file *cs_fp;
+ char *cs_buf;
+ struct obd_device *cs_obd;
};
-static int changelog_show_cb(const struct lu_env *env, struct llog_handle *llh,
+static int changelog_kkuc_cb(const struct lu_env *env, struct llog_handle *llh,
struct llog_rec_hdr *hdr, void *data)
{
- struct changelog_show *cs = data;
- struct llog_changelog_rec *rec = (struct llog_changelog_rec *)hdr;
- struct kuc_hdr *lh;
- int len, rc;
- ENTRY;
+ struct changelog_show *cs = data;
+ struct llog_changelog_rec *rec = (struct llog_changelog_rec *)hdr;
+ struct kuc_hdr *lh;
+ int len, rc;
+ ENTRY;
- if ((rec->cr_hdr.lrh_type != CHANGELOG_REC) ||
- (rec->cr.cr_type >= CL_LAST)) {
- CERROR("Not a changelog rec %d/%d\n", rec->cr_hdr.lrh_type,
- rec->cr.cr_type);
- RETURN(-EINVAL);
- }
+ if (rec->cr_hdr.lrh_type != CHANGELOG_REC) {
+ rc = -EINVAL;
+ CERROR("%s: not a changelog rec %x/%d: rc = %d\n",
+ cs->cs_obd->obd_name, rec->cr_hdr.lrh_type,
+ rec->cr.cr_type, rc);
+ RETURN(rc);
+ }
- if (rec->cr.cr_index < cs->cs_startrec) {
- /* Skip entries earlier than what we are interested in */
- CDEBUG(D_CHANGELOG, "rec="LPU64" start="LPU64"\n",
- rec->cr.cr_index, cs->cs_startrec);
- RETURN(0);
- }
+ if (rec->cr.cr_index < cs->cs_startrec) {
+ /* Skip entries earlier than what we are interested in */
+ CDEBUG(D_CHANGELOG, "rec="LPU64" start="LPU64"\n",
+ rec->cr.cr_index, cs->cs_startrec);
+ RETURN(0);
+ }
CDEBUG(D_CHANGELOG, LPU64" %02d%-5s "LPU64" 0x%x t="DFID" p="DFID
" %.*s\n", rec->cr.cr_index, rec->cr.cr_type,
static int mdc_changelog_send_thread(void *csdata)
{
- struct changelog_show *cs = csdata;
- struct llog_ctxt *ctxt = NULL;
- struct llog_handle *llh = NULL;
- struct kuc_hdr *kuch;
- int rc;
+ struct changelog_show *cs = csdata;
+ struct llog_ctxt *ctxt = NULL;
+ struct llog_handle *llh = NULL;
+ struct kuc_hdr *kuch;
+ int rc;
- CDEBUG(D_CHANGELOG, "changelog to fp=%p start "LPU64"\n",
- cs->cs_fp, cs->cs_startrec);
+ CDEBUG(D_CHANGELOG, "changelog to fp=%p start "LPU64"\n",
+ cs->cs_fp, cs->cs_startrec);
- /*
- * It's important to daemonize here to close unused FDs.
- * The write fd from pipe is already opened by the caller,
- * so it's fine to clear all files here
- */
- cfs_daemonize("mdc_clg_send_thread");
-
- OBD_ALLOC(cs->cs_buf, CR_MAXSIZE);
- if (cs->cs_buf == NULL)
- GOTO(out, rc = -ENOMEM);
+ OBD_ALLOC(cs->cs_buf, KUC_CHANGELOG_MSG_MAXSIZE);
+ if (cs->cs_buf == NULL)
+ GOTO(out, rc = -ENOMEM);
/* Set up the remote catalog handle */
ctxt = llog_get_context(cs->cs_obd, LLOG_CHANGELOG_REPL_CTXT);
GOTO(out, rc);
}
- rc = llog_cat_process(NULL, llh, changelog_show_cb, cs, 0, 0);
+ rc = llog_cat_process(NULL, llh, changelog_kkuc_cb, cs, 0, 0);
/* Send EOF no matter what our result */
if ((kuch = changelog_kuc_hdr(cs->cs_buf, sizeof(*kuch),
}
out:
- cfs_put_file(cs->cs_fp);
- if (llh)
+ fput(cs->cs_fp);
+ if (llh)
llog_cat_close(NULL, llh);
if (ctxt)
llog_ctxt_put(ctxt);
- if (cs->cs_buf)
- OBD_FREE(cs->cs_buf, CR_MAXSIZE);
- OBD_FREE_PTR(cs);
- /* detach from parent process so we get cleaned up */
- cfs_daemonize("cl_send");
- return rc;
+ if (cs->cs_buf)
+ OBD_FREE(cs->cs_buf, KUC_CHANGELOG_MSG_MAXSIZE);
+ OBD_FREE_PTR(cs);
+ return rc;
}
static int mdc_ioc_changelog_send(struct obd_device *obd,
if (!cs)
return -ENOMEM;
- cs->cs_obd = obd;
- cs->cs_startrec = icc->icc_recno;
- /* matching cfs_put_file in mdc_changelog_send_thread */
- cs->cs_fp = cfs_get_fd(icc->icc_id);
- cs->cs_flags = icc->icc_flags;
+ cs->cs_obd = obd;
+ cs->cs_startrec = icc->icc_recno;
+ /* matching fput in mdc_changelog_send_thread */
+ cs->cs_fp = fget(icc->icc_id);
+ cs->cs_flags = icc->icc_flags;
- /* New thread because we should return to user app before
- writing into our pipe */
- rc = cfs_create_thread(mdc_changelog_send_thread, cs, CFS_DAEMON_FLAGS);
- if (rc >= 0) {
- CDEBUG(D_CHANGELOG, "start changelog thread: %d\n", rc);
- return 0;
- }
+ /*
+ * New thread because we should return to user app before
+ * writing into our pipe
+ */
+ rc = PTR_ERR(kthread_run(mdc_changelog_send_thread, cs,
+ "mdc_clg_send_thread"));
+ if (!IS_ERR_VALUE(rc)) {
+ CDEBUG(D_CHANGELOG, "start changelog thread\n");
+ return 0;
+ }
CERROR("Failed to start changelog thread: %d\n", rc);
OBD_FREE_PTR(cs);
int rc;
ENTRY;
- if (!cfs_try_module_get(THIS_MODULE)) {
- CERROR("Can't get module. Is it alive?");
- return -EINVAL;
- }
+ if (!try_module_get(THIS_MODULE)) {
+ CERROR("Can't get module. Is it alive?");
+ return -EINVAL;
+ }
switch (cmd) {
case OBD_IOC_CHANGELOG_SEND:
rc = mdc_ioc_changelog_send(obd, karg);
GOTO(out, rc);
case LL_IOC_HSM_CT_START:
rc = mdc_ioc_hsm_ct_start(exp, karg);
+ /* ignore if it was already registered on this MDS. */
+ if (rc == -EEXIST)
+ rc = 0;
GOTO(out, rc);
case LL_IOC_HSM_PROGRESS:
rc = mdc_ioc_hsm_progress(exp, karg);
GOTO(out, rc);
case LL_IOC_HSM_STATE_SET:
rc = mdc_ioc_hsm_state_set(exp, karg);
+ GOTO(out, rc);
case LL_IOC_HSM_ACTION:
rc = mdc_ioc_hsm_current_action(exp, karg);
GOTO(out, rc);
GOTO(out, rc = -ENODEV);
/* copy UUID */
- if (cfs_copy_to_user(data->ioc_pbuf2, obd2cli_tgt(obd),
- min((int) data->ioc_plen2,
- (int) sizeof(struct obd_uuid))))
- GOTO(out, rc = -EFAULT);
+ if (copy_to_user(data->ioc_pbuf2, obd2cli_tgt(obd),
+ min((int)data->ioc_plen2,
+ (int)sizeof(struct obd_uuid))))
+ GOTO(out, rc = -EFAULT);
- rc = mdc_statfs(NULL, obd->obd_self_export, &stat_buf,
- cfs_time_shift_64(-OBD_STATFS_CACHE_SECONDS),
- 0);
- if (rc != 0)
- GOTO(out, rc);
+ rc = mdc_statfs(NULL, obd->obd_self_export, &stat_buf,
+ cfs_time_shift_64(-OBD_STATFS_CACHE_SECONDS),
+ 0);
+ if (rc != 0)
+ GOTO(out, rc);
- if (cfs_copy_to_user(data->ioc_pbuf1, &stat_buf,
+ if (copy_to_user(data->ioc_pbuf1, &stat_buf,
min((int) data->ioc_plen1,
(int) sizeof(stat_buf))))
GOTO(out, rc = -EFAULT);
GOTO(out, rc = 0);
}
- case OBD_IOC_QUOTACTL: {
- struct if_quotactl *qctl = karg;
- struct obd_quotactl *oqctl;
+ case OBD_IOC_QUOTACTL: {
+ struct if_quotactl *qctl = karg;
+ struct obd_quotactl *oqctl;
- OBD_ALLOC_PTR(oqctl);
- if (!oqctl)
- RETURN(-ENOMEM);
+ OBD_ALLOC_PTR(oqctl);
+ if (oqctl == NULL)
+ GOTO(out, rc = -ENOMEM);
- QCTL_COPY(oqctl, qctl);
- rc = obd_quotactl(exp, oqctl);
- if (rc == 0) {
- QCTL_COPY(qctl, oqctl);
- qctl->qc_valid = QC_MDTIDX;
- qctl->obd_uuid = obd->u.cli.cl_target_uuid;
- }
- OBD_FREE_PTR(oqctl);
- break;
- }
- case LL_IOC_GET_CONNECT_FLAGS: {
- if (cfs_copy_to_user(uarg,
- exp_connect_flags_ptr(exp),
- sizeof(__u64)))
- GOTO(out, rc = -EFAULT);
- else
- GOTO(out, rc = 0);
+ QCTL_COPY(oqctl, qctl);
+ rc = obd_quotactl(exp, oqctl);
+ if (rc == 0) {
+ QCTL_COPY(qctl, oqctl);
+ qctl->qc_valid = QC_MDTIDX;
+ qctl->obd_uuid = obd->u.cli.cl_target_uuid;
+ }
+
+ OBD_FREE_PTR(oqctl);
+ GOTO(out, rc);
}
- case LL_IOC_LOV_SWAP_LAYOUTS: {
+ case LL_IOC_GET_CONNECT_FLAGS:
+ if (copy_to_user(uarg, exp_connect_flags_ptr(exp),
+ sizeof(*exp_connect_flags_ptr(exp))))
+ GOTO(out, rc = -EFAULT);
+
+ GOTO(out, rc = 0);
+ case LL_IOC_LOV_SWAP_LAYOUTS:
rc = mdc_ioc_swap_layouts(exp, karg);
- break;
+ GOTO(out, rc);
+ default:
+ CERROR("unrecognised ioctl: cmd = %#x\n", cmd);
+ GOTO(out, rc = -ENOTTY);
}
- default:
- CERROR("mdc_ioctl(): unrecognised ioctl %#x\n", cmd);
- GOTO(out, rc = -ENOTTY);
- }
out:
- cfs_module_put(THIS_MODULE);
+ module_put(THIS_MODULE);
- return rc;
+ return rc;
}
int mdc_get_info_rpc(struct obd_export *exp,
RCL_SERVER, vallen);
ptlrpc_request_set_replen(req);
- rc = ptlrpc_queue_wait(req);
- if (rc == 0) {
- tmp = req_capsule_server_get(&req->rq_pill, &RMF_GETINFO_VAL);
- memcpy(val, tmp, vallen);
- if (ptlrpc_rep_need_swab(req)) {
- if (KEY_IS(KEY_FID2PATH)) {
- lustre_swab_fid2path(val);
- }
- }
- }
- ptlrpc_req_finished(req);
+ rc = ptlrpc_queue_wait(req);
+ /* -EREMOTE means the get_info result is partial, and it needs to
+ * continue on another MDT, see fid2path part in lmv_iocontrol */
+ if (rc == 0 || rc == -EREMOTE) {
+ tmp = req_capsule_server_get(&req->rq_pill, &RMF_GETINFO_VAL);
+ memcpy(val, tmp, vallen);
+ if (ptlrpc_rep_need_swab(req)) {
+ if (KEY_IS(KEY_FID2PATH))
+ lustre_swab_fid2path(val);
+ }
+ }
+ ptlrpc_req_finished(req);
- RETURN(rc);
+ RETURN(rc);
}
static void lustre_swab_hai(struct hsm_action_item *h)
__swab32s(&h->hal_count);
__swab32s(&h->hal_archive_id);
__swab64s(&h->hal_flags);
- hai = hai_zero(h);
- for (i = 0; i < h->hal_count; i++) {
+ hai = hai_first(h);
+ for (i = 0; i < h->hal_count; i++, hai = hai_next(hai))
lustre_swab_hai(hai);
- hai = hai_next(hai);
- }
}
static void lustre_swab_kuch(struct kuc_hdr *l)
lk->lk_uid, lk->lk_group, lk->lk_flags);
if (lk->lk_flags & LK_FLG_STOP) {
- rc = libcfs_kkuc_group_rem(lk->lk_uid, lk->lk_group);
/* Unregister with the coordinator */
- if (rc == 0)
- rc = mdc_ioc_hsm_ct_unregister(imp);
+ rc = mdc_ioc_hsm_ct_unregister(imp);
} else {
- cfs_file_t *fp = cfs_get_fd(lk->lk_wfd);
- rc = libcfs_kkuc_group_add(fp, lk->lk_uid, lk->lk_group,
- lk->lk_data);
- if (rc && fp)
- cfs_put_file(fp);
- if (rc == 0)
- rc = mdc_ioc_hsm_ct_register(imp, archive);
+ rc = mdc_ioc_hsm_ct_register(imp, archive);
}
return rc;
/**
* callback function passed to kuc for re-registering each HSM copytool
* running on MDC, after MDT shutdown/recovery.
- * @param data archive id served by the copytool
+ * @param data copytool registration data
* @param cb_arg callback argument (obd_import)
*/
-static int mdc_hsm_ct_reregister(__u32 data, void *cb_arg)
+static int mdc_hsm_ct_reregister(void *data, void *cb_arg)
{
+ struct kkuc_ct_data *kcd = data;
struct obd_import *imp = (struct obd_import *)cb_arg;
- __u32 archive = data;
int rc;
- CDEBUG(D_HA, "recover copytool registration to MDT (archive=%#x)\n",
- archive);
- rc = mdc_ioc_hsm_ct_register(imp, archive);
+ if (kcd == NULL || kcd->kcd_magic != KKUC_CT_DATA_MAGIC)
+ return -EPROTO;
+
+ if (!obd_uuid_equals(&kcd->kcd_uuid, &imp->imp_obd->obd_uuid))
+ return 0;
+
+ CDEBUG(D_HA, "%s: recover copytool registration to MDT (archive=%#x)\n",
+ imp->imp_obd->obd_name, kcd->kcd_archive);
+ rc = mdc_ioc_hsm_ct_register(imp, kcd->kcd_archive);
/* ignore error if the copytool is already registered */
- return ((rc != 0) && (rc != -EEXIST)) ? rc : 0;
+ return (rc == -EEXIST) ? 0 : rc;
}
/**
sptlrpc_import_flush_my_ctx(imp);
RETURN(0);
}
- if (KEY_IS(KEY_MDS_CONN)) {
- /* mds-mds import */
- spin_lock(&imp->imp_lock);
- imp->imp_server_timeout = 1;
- spin_unlock(&imp->imp_lock);
- imp->imp_client->cli_request_portal = MDS_MDS_PORTAL;
- CDEBUG(D_OTHER, "%s: timeout / 2\n", exp->exp_obd->obd_name);
- RETURN(0);
- }
if (KEY_IS(KEY_CHANGELOG_CLEAR)) {
rc = do_set_info_async(imp, MDS_SET_INFO, LUSTRE_MDS_VERSION,
keylen, key, vallen, val, set);
RETURN(rc);
}
-int mdc_sync(struct obd_export *exp, const struct lu_fid *fid,
- struct obd_capa *oc, struct ptlrpc_request **request)
+int mdc_fsync(struct obd_export *exp, const struct lu_fid *fid,
+ struct obd_capa *oc, struct ptlrpc_request **request)
{
struct ptlrpc_request *req;
int rc;
}
case IMP_EVENT_ACTIVE:
rc = obd_notify_observer(obd, obd, OBD_NOTIFY_ACTIVE, NULL);
- /* restore re-establish kuc registration after reconnecting */
+ /* redo the kuc registration after reconnecting */
if (rc == 0)
rc = mdc_kuc_reregister(imp);
break;
RETURN(1);
}
+static int mdc_resource_inode_free(struct ldlm_resource *res)
+{
+ if (res->lr_lvb_inode)
+ res->lr_lvb_inode = NULL;
+
+ return 0;
+}
+
+struct ldlm_valblock_ops inode_lvbo = {
+ lvbo_free: mdc_resource_inode_free
+};
+
static int mdc_setup(struct obd_device *obd, struct lustre_cfg *cfg)
{
- struct client_obd *cli = &obd->u.cli;
- struct lprocfs_static_vars lvars = { 0 };
- int rc;
- ENTRY;
+ struct client_obd *cli = &obd->u.cli;
+ struct lprocfs_static_vars lvars = { 0 };
+ int rc;
+ ENTRY;
OBD_ALLOC(cli->cl_rpc_lock, sizeof (*cli->cl_rpc_lock));
if (!cli->cl_rpc_lock)
RETURN(-ENOMEM);
mdc_init_rpc_lock(cli->cl_rpc_lock);
- ptlrpcd_addref();
+ rc = ptlrpcd_addref();
+ if (rc < 0)
+ GOTO(err_rpc_lock, rc);
OBD_ALLOC(cli->cl_close_lock, sizeof (*cli->cl_close_lock));
if (!cli->cl_close_lock)
- GOTO(err_rpc_lock, rc = -ENOMEM);
+ GOTO(err_ptlrpcd_decref, rc = -ENOMEM);
mdc_init_rpc_lock(cli->cl_close_lock);
rc = client_obd_setup(obd, cfg);
GOTO(err_close_lock, rc);
lprocfs_mdc_init_vars(&lvars);
lprocfs_obd_setup(obd, lvars.obd_vars);
+ lprocfs_alloc_md_stats(obd, 0);
sptlrpc_lprocfs_cliobd_attach(obd);
ptlrpc_lprocfs_register_obd(obd);
ns_register_cancel(obd->obd_namespace, mdc_cancel_for_recovery);
+ obd->obd_namespace->ns_lvbo = &inode_lvbo;
+
rc = obd_llog_init(obd, &obd->obd_olg, obd, NULL);
if (rc) {
mdc_cleanup(obd);
err_close_lock:
OBD_FREE(cli->cl_close_lock, sizeof (*cli->cl_close_lock));
+err_ptlrpcd_decref:
+ ptlrpcd_decref();
err_rpc_lock:
OBD_FREE(cli->cl_rpc_lock, sizeof (*cli->cl_rpc_lock));
- ptlrpcd_decref();
RETURN(rc);
}
case OBD_CLEANUP_EARLY:
break;
case OBD_CLEANUP_EXPORTS:
- /* Failsafe, ok if racy */
- if (obd->obd_type->typ_refcnt <= 1)
- libcfs_kkuc_group_rem(0, KUC_GRP_HSM);
+ /* Failsafe, ok if racy */
+ if (obd->obd_type->typ_refcnt <= 1)
+ libcfs_kkuc_group_rem(0, KUC_GRP_HSM, NULL);
obd_cleanup_client_import(obd);
ptlrpc_lprocfs_unregister_obd(obd);
lprocfs_obd_cleanup(obd);
+ lprocfs_free_md_stats(obd);
rc = obd_llog_finish(obd, 0);
if (rc != 0)
RETURN(0);
}
-static int mdc_connect(const struct lu_env *env,
- struct obd_export **exp,
- struct obd_device *obd, struct obd_uuid *cluuid,
- struct obd_connect_data *data,
- void *localdata)
-{
- struct obd_import *imp = obd->u.cli.cl_import;
-
- /* mds-mds import features */
- if (data && (data->ocd_connect_flags & OBD_CONNECT_MDS_MDS)) {
- spin_lock(&imp->imp_lock);
- imp->imp_server_timeout = 1;
- spin_unlock(&imp->imp_lock);
- imp->imp_client->cli_request_portal = MDS_MDS_PORTAL;
- CDEBUG(D_OTHER, "%s: Set 'mds' portal and timeout\n",
- obd->obd_name);
- }
-
- return client_connect_import(env, exp, obd, cluuid, data, NULL);
-}
-
struct obd_ops mdc_obd_ops = {
.o_owner = THIS_MODULE,
.o_setup = mdc_setup,
.o_cleanup = mdc_cleanup,
.o_add_conn = client_import_add_conn,
.o_del_conn = client_import_del_conn,
- .o_connect = mdc_connect,
+ .o_connect = client_connect_import,
.o_disconnect = client_disconnect_export,
.o_iocontrol = mdc_iocontrol,
.o_set_info_async = mdc_set_info_async,
struct md_ops mdc_md_ops = {
.m_getstatus = mdc_getstatus,
- .m_change_cbdata = mdc_change_cbdata,
+ .m_null_inode = mdc_null_inode,
.m_find_cbdata = mdc_find_cbdata,
.m_close = mdc_close,
.m_create = mdc_create,
.m_setattr = mdc_setattr,
.m_setxattr = mdc_setxattr,
.m_getxattr = mdc_getxattr,
- .m_sync = mdc_sync,
+ .m_fsync = mdc_fsync,
.m_readpage = mdc_readpage,
.m_unlink = mdc_unlink,
.m_cancel_unused = mdc_cancel_unused,