Whamcloud - gitweb
LU-3365 lmv: support DNE with HSM.
[fs/lustre-release.git] / lustre / mdc / mdc_request.c
index 853143f..50f9600 100644 (file)
@@ -27,7 +27,7 @@
  * 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/
@@ -41,6 +41,7 @@
 # include <linux/pagemap.h>
 # include <linux/miscdevice.h>
 # include <linux/init.h>
+# include <linux/utsname.h>
 #else
 # include <liblustre.h>
 #endif
@@ -48,7 +49,6 @@
 #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>
@@ -226,6 +226,11 @@ int mdc_getattr(struct obd_export *exp, struct md_op_data *op_data,
         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)
@@ -466,7 +471,7 @@ static int mdc_unpack_acl(struct ptlrpc_request *req, struct lustre_md *md)
         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);
@@ -1071,10 +1076,10 @@ restart_bulk:
 
         /* 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);
@@ -1105,7 +1110,7 @@ restart_bulk:
         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);
         }
@@ -1198,9 +1203,9 @@ static int mdc_ioc_fid2path(struct obd_export *exp, struct getinfo_fid2path *gf)
         /* 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);
@@ -1229,10 +1234,15 @@ static int mdc_ioc_hsm_progress(struct obd_export *exp,
        if (req == NULL)
                GOTO(out, rc = -ENOMEM);
 
+       mdc_pack_body(req, NULL, NULL, OBD_MD_FLRMTPERM, 0, 0, 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);
 
@@ -1256,10 +1266,14 @@ static int mdc_ioc_hsm_ct_register(struct obd_import *imp, __u32 archives)
        if (req == NULL)
                GOTO(out, rc = -ENOMEM);
 
+       mdc_pack_body(req, NULL, NULL, OBD_MD_FLRMTPERM, 0, 0, 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);
@@ -1327,6 +1341,8 @@ static int mdc_ioc_hsm_ct_unregister(struct obd_import *imp)
        if (req == NULL)
                GOTO(out, rc = -ENOMEM);
 
+       mdc_pack_body(req, NULL, NULL, OBD_MD_FLRMTPERM, 0, 0, 0);
+
        ptlrpc_request_set_replen(req);
 
        rc = mdc_queue_wait(req);
@@ -1406,7 +1422,8 @@ static int mdc_ioc_hsm_state_set(struct obd_export *exp,
 
        /* 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);
@@ -1451,18 +1468,21 @@ static int mdc_ioc_hsm_request(struct obd_export *exp,
 
        /* 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);
@@ -1492,35 +1512,36 @@ static struct kuc_hdr *changelog_kuc_hdr(char *buf, int len, int flags)
 #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,
@@ -1552,13 +1573,6 @@ static int mdc_changelog_send_thread(void *csdata)
         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);
@@ -1580,7 +1594,7 @@ static int mdc_changelog_send_thread(void *csdata)
                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),
@@ -1590,17 +1604,15 @@ static int mdc_changelog_send_thread(void *csdata)
         }
 
 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, CR_MAXSIZE);
+       OBD_FREE_PTR(cs);
+       return rc;
 }
 
 static int mdc_ioc_changelog_send(struct obd_device *obd,
@@ -1614,19 +1626,22 @@ 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);
@@ -1809,6 +1824,9 @@ static int mdc_iocontrol(unsigned int cmd, struct obd_export *exp, int len,
                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);
@@ -1868,18 +1886,18 @@ static int mdc_iocontrol(unsigned int cmd, struct obd_export *exp, int len,
                         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);
@@ -1905,7 +1923,7 @@ static int mdc_iocontrol(unsigned int cmd, struct obd_export *exp, int len,
                 break;
         }
        case LL_IOC_GET_CONNECT_FLAGS: {
-               if (cfs_copy_to_user(uarg,
+               if (copy_to_user(uarg,
                                     exp_connect_flags_ptr(exp),
                                     sizeof(__u64)))
                        GOTO(out, rc = -EFAULT);
@@ -1960,19 +1978,20 @@ 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)
@@ -2027,18 +2046,10 @@ static int mdc_ioc_hsm_ct_start(struct obd_export *exp,
               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;
@@ -2363,7 +2374,7 @@ static int mdc_import_event(struct obd_device *obd, struct obd_import *imp,
         }
        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;