Whamcloud - gitweb
LU-7830 ost: do not evict during truncate
[fs/lustre-release.git] / lustre / ofd / ofd_dev.c
index 57b3bdd..0a2ec19 100644 (file)
@@ -42,7 +42,7 @@
  * The OBD Filter Device (OFD) module belongs to the Object Storage
  * Server stack and connects the RPC oriented Unified Target (TGT)
  * layer (see lustre/include/lu_target.h) to the storage oriented OSD
- * layer (see lustre/doc/osd-api.txt).
+ * layer (see Documentation/osd-api.txt).
  *
  *     TGT
  *      |      DT and OBD APIs
@@ -167,6 +167,7 @@ static int ofd_stack_init(const struct lu_env *env,
        struct lu_device        *d;
        struct ofd_thread_info  *info = ofd_info(env);
        struct lustre_mount_info *lmi;
+       struct lustre_mount_data *lmd;
        int                      rc;
        char                    *osdname;
 
@@ -178,6 +179,10 @@ static int ofd_stack_init(const struct lu_env *env,
                RETURN(-ENODEV);
        }
 
+       lmd = s2lsi(lmi->lmi_sb)->lsi_lmd;
+       if (lmd != NULL && lmd->lmd_flags & LMD_FLG_SKIP_LFSCK)
+               m->ofd_skip_lfsck = 1;
+
        /* find bottom osd */
        OBD_ALLOC(osdname, MTI_NAME_MAXLEN);
        if (osdname == NULL)
@@ -629,21 +634,26 @@ static int ofd_prepare(const struct lu_env *env, struct lu_device *pdev,
 static int ofd_recovery_complete(const struct lu_env *env,
                                 struct lu_device *dev)
 {
+       struct ofd_thread_info  *oti = ofd_info(env);
        struct ofd_device       *ofd = ofd_dev(dev);
        struct lu_device        *next = &ofd->ofd_osd->dd_lu_dev;
-       int                      rc = 0, max_precreate;
+       int                      rc = 0;
 
        ENTRY;
 
        /*
         * Grant space for object precreation on the self export.
-        * This initial reserved space (i.e. 10MB for zfs and 280KB for ldiskfs)
+        * The initial reserved space (i.e. 10MB for zfs and 280KB for ldiskfs)
         * is enough to create 10k objects. More space is then acquired for
         * precreation in ofd_grant_create().
         */
-       max_precreate = OST_MAX_PRECREATE * ofd->ofd_dt_conf.ddp_inodespace / 2;
-       ofd_grant_connect(env, dev->ld_obd->obd_self_export, max_precreate,
-                         false);
+       memset(&oti->fti_ocd, 0, sizeof(oti->fti_ocd));
+       oti->fti_ocd.ocd_grant = OST_MAX_PRECREATE / 2;
+       oti->fti_ocd.ocd_grant *= ofd->ofd_dt_conf.ddp_inodespace;
+       oti->fti_ocd.ocd_connect_flags = OBD_CONNECT_GRANT |
+                                        OBD_CONNECT_GRANT_PARAM;
+       ofd_grant_connect(env, dev->ld_obd->obd_self_export, &oti->fti_ocd,
+                         true);
        rc = next->ld_ops->ldo_recovery_complete(env, next);
        RETURN(rc);
 }
@@ -824,60 +834,52 @@ int ofd_fid_init(const struct lu_env *env, struct ofd_device *ofd)
        ss->ss_lu = lu->ld_site;
        ss->ss_node_id = ofd->ofd_lut.lut_lsd.lsd_osd_index;
 
+       OBD_ALLOC(name, sizeof(obd_name) * 2 + 10);
+       if (name == NULL)
+               return -ENOMEM;
+
        OBD_ALLOC_PTR(ss->ss_server_seq);
        if (ss->ss_server_seq == NULL)
-               GOTO(out_free, rc = -ENOMEM);
-
-       OBD_ALLOC(name, strlen(obd_name) + 10);
-       if (!name) {
-               OBD_FREE_PTR(ss->ss_server_seq);
-               ss->ss_server_seq = NULL;
-               GOTO(out_free, rc = -ENOMEM);
-       }
+               GOTO(out_name, rc = -ENOMEM);
 
        rc = seq_server_init(env, ss->ss_server_seq, ofd->ofd_osd, obd_name,
                             LUSTRE_SEQ_SERVER, ss);
        if (rc) {
                CERROR("%s : seq server init error %d\n", obd_name, rc);
-               GOTO(out_free, rc);
+               GOTO(out_server, rc);
        }
        ss->ss_server_seq->lss_space.lsr_index = ss->ss_node_id;
 
        OBD_ALLOC_PTR(ss->ss_client_seq);
        if (ss->ss_client_seq == NULL)
-               GOTO(out_free, rc = -ENOMEM);
+               GOTO(out_server, rc = -ENOMEM);
 
-       snprintf(name, strlen(obd_name) + 6, "%p-super", obd_name);
+       /*
+        * It always printed as "%p", so that the name is unique in the kernel,
+        * even if the filesystem is mounted twice. So sizeof(.) * 2 is enough.
+        */
+       snprintf(name, sizeof(obd_name) * 2 + 7, "%p-super", obd_name);
        rc = seq_client_init(ss->ss_client_seq, NULL, LUSTRE_SEQ_DATA,
                             name, NULL);
        if (rc) {
                CERROR("%s : seq client init error %d\n", obd_name, rc);
-               GOTO(out_free, rc);
+               GOTO(out_client, rc);
        }
-       OBD_FREE(name, strlen(obd_name) + 10);
-       name = NULL;
 
        rc = seq_server_set_cli(env, ss->ss_server_seq, ss->ss_client_seq);
 
-out_free:
        if (rc) {
-               if (ss->ss_server_seq) {
-                       seq_server_fini(ss->ss_server_seq, env);
-                       OBD_FREE_PTR(ss->ss_server_seq);
-                       ss->ss_server_seq = NULL;
-               }
-
-               if (ss->ss_client_seq) {
-                       seq_client_fini(ss->ss_client_seq);
-                       OBD_FREE_PTR(ss->ss_client_seq);
-                       ss->ss_client_seq = NULL;
-               }
-
-               if (name) {
-                       OBD_FREE(name, strlen(obd_name) + 10);
-                       name = NULL;
-               }
+out_client:
+               seq_client_fini(ss->ss_client_seq);
+               OBD_FREE_PTR(ss->ss_client_seq);
+               ss->ss_client_seq = NULL;
+out_server:
+               seq_server_fini(ss->ss_server_seq, env);
+               OBD_FREE_PTR(ss->ss_server_seq);
+               ss->ss_server_seq = NULL;
        }
+out_name:
+       OBD_FREE(name, sizeof(obd_name) * 2 + 10);
 
        return rc;
 }
@@ -2019,6 +2021,8 @@ static int ofd_punch_hdl(struct tgt_session_info *tsi)
 
        ENTRY;
 
+       OBD_FAIL_TIMEOUT(OBD_FAIL_OST_PAUSE_PUNCH, cfs_fail_val);
+
        /* check that we do support OBD_CONNECT_TRUNCLOCK. */
        CLASSERT(OST_CONNECT_SUPPORTED & OBD_CONNECT_TRUNCLOCK);
 
@@ -2104,6 +2108,97 @@ out:
 }
 
 /**
+ * OFD request handler for OST_LADVISE RPC.
+ *
+ * Tune cache or perfetch policies according to advices.
+ *
+ * \param[in] tsi      target session environment for this request
+ *
+ * \retval             0 if successful
+ * \retval             negative errno on error
+ */
+static int ofd_ladvise_hdl(struct tgt_session_info *tsi)
+{
+       struct ptlrpc_request   *req = tgt_ses_req(tsi);
+       struct obd_export       *exp = tsi->tsi_exp;
+       struct ofd_device       *ofd = ofd_exp(exp);
+       struct ost_body         *body, *repbody;
+       struct ofd_thread_info  *info;
+       struct ofd_object       *fo;
+       const struct lu_env     *env = req->rq_svc_thread->t_env;
+       int                      rc = 0;
+       struct lu_ladvise       *ladvise;
+       int                      num_advise;
+       struct ladvise_hdr      *ladvise_hdr;
+       int                      i;
+       ENTRY;
+
+       body = tsi->tsi_ost_body;
+
+       if ((body->oa.o_valid & OBD_MD_FLID) != OBD_MD_FLID)
+               RETURN(err_serious(-EPROTO));
+
+       ladvise_hdr = req_capsule_client_get(tsi->tsi_pill,
+                                            &RMF_OST_LADVISE_HDR);
+       if (ladvise_hdr == NULL)
+               RETURN(err_serious(-EPROTO));
+
+       if (ladvise_hdr->lah_magic != LADVISE_MAGIC ||
+           ladvise_hdr->lah_count < 1)
+               RETURN(err_serious(-EPROTO));
+
+       if ((ladvise_hdr->lah_flags & (~LF_MASK)) != 0)
+               RETURN(err_serious(-EPROTO));
+
+       ladvise = req_capsule_client_get(tsi->tsi_pill, &RMF_OST_LADVISE);
+       if (ladvise == NULL)
+               RETURN(err_serious(-EPROTO));
+
+       num_advise = req_capsule_get_size(&req->rq_pill,
+                                         &RMF_OST_LADVISE, RCL_CLIENT) /
+                    sizeof(*ladvise);
+       if (num_advise < ladvise_hdr->lah_count)
+               RETURN(err_serious(-EPROTO));
+
+       repbody = req_capsule_server_get(&req->rq_pill, &RMF_OST_BODY);
+       repbody->oa = body->oa;
+
+       info = ofd_info_init(env, exp);
+
+       rc = ostid_to_fid(&info->fti_fid, &body->oa.o_oi,
+                         ofd->ofd_lut.lut_lsd.lsd_osd_index);
+       if (rc != 0)
+               RETURN(rc);
+
+       fo = ofd_object_find(env, ofd, &info->fti_fid);
+       if (IS_ERR(fo)) {
+               rc = PTR_ERR(fo);
+               RETURN(rc);
+       }
+       LASSERT(fo != NULL);
+
+       for (i = 0; i < num_advise; i++, ladvise++) {
+               if (ladvise->lla_end <= ladvise->lla_start) {
+                       rc = err_serious(-EPROTO);
+                       break;
+               }
+
+               /* Handle different advice types */
+               switch (ladvise->lla_advice) {
+               default:
+                       rc = -ENOTSUPP;
+                       break;
+               }
+               if (rc != 0)
+                       break;
+       }
+
+       ofd_object_put(env, fo);
+       req->rq_status = rc;
+       RETURN(rc);
+}
+
+/**
  * OFD request handler for OST_QUOTACTL RPC.
  *
  * This is part of request processing to validate incoming request fields,
@@ -2116,11 +2211,10 @@ out:
  */
 static int ofd_quotactl(struct tgt_session_info *tsi)
 {
-       struct obd_quotactl     *oqctl, *repoqc;
-       struct lu_nodemap       *nodemap =
-               tsi->tsi_exp->exp_target_data.ted_nodemap;
-       int                      id;
-       int                      rc;
+       struct obd_quotactl *oqctl, *repoqc;
+       struct lu_nodemap *nodemap;
+       int id;
+       int rc;
 
        ENTRY;
 
@@ -2134,6 +2228,10 @@ static int ofd_quotactl(struct tgt_session_info *tsi)
 
        *repoqc = *oqctl;
 
+       nodemap = nodemap_get_from_exp(tsi->tsi_exp);
+       if (IS_ERR(nodemap))
+               RETURN(PTR_ERR(nodemap));
+
        id = repoqc->qc_id;
        if (oqctl->qc_type == USRQUOTA)
                id = nodemap_map_id(nodemap, NODEMAP_UID,
@@ -2144,6 +2242,8 @@ static int ofd_quotactl(struct tgt_session_info *tsi)
                                    NODEMAP_CLIENT_TO_FS,
                                    repoqc->qc_id);
 
+       nodemap_putref(nodemap);
+
        if (repoqc->qc_id != id)
                swap(repoqc->qc_id, id);
 
@@ -2448,6 +2548,10 @@ static int ofd_punch_hpreq_lock_match(struct ptlrpc_request *req,
                                      struct ldlm_lock *lock)
 {
        struct tgt_session_info *tsi;
+       struct obdo             *oa;
+       struct ldlm_extent       ext;
+
+       ENTRY;
 
        /* Don't use tgt_ses_info() to get session info, because lock_match()
         * can be called while request has no processing thread yet. */
@@ -2460,9 +2564,20 @@ static int ofd_punch_hpreq_lock_match(struct ptlrpc_request *req,
        LASSERT(tsi->tsi_ost_body != NULL);
        if (tsi->tsi_ost_body->oa.o_valid & OBD_MD_FLHANDLE &&
            tsi->tsi_ost_body->oa.o_handle.cookie == lock->l_handle.h_cookie)
-               return 1;
+               RETURN(1);
 
-       return 0;
+       oa = &tsi->tsi_ost_body->oa;
+       ext.start = oa->o_size;
+       ext.end   = oa->o_blocks;
+
+       LASSERT(lock->l_resource != NULL);
+       if (!ostid_res_name_eq(&oa->o_oi, &lock->l_resource->lr_name))
+               RETURN(0);
+
+       if (!(lock->l_granted_mode & (LCK_PW | LCK_GROUP)))
+               RETURN(0);
+
+       RETURN(ldlm_extent_overlap(&lock->l_policy_data.l_extent, &ext));
 }
 
 /**
@@ -2622,6 +2737,7 @@ TGT_OST_HDL_HP(HABEO_CORPUS| HABEO_REFERO | MUTABOR,
                                                        ofd_hp_punch),
 TGT_OST_HDL(HABEO_CORPUS| HABEO_REFERO,        OST_SYNC,       ofd_sync_hdl),
 TGT_OST_HDL(0          | HABEO_REFERO, OST_QUOTACTL,   ofd_quotactl),
+TGT_OST_HDL(HABEO_CORPUS | HABEO_REFERO, OST_LADVISE,  ofd_ladvise_hdl),
 };
 
 static struct tgt_opc_slice ofd_common_slice[] = {
@@ -2749,6 +2865,7 @@ static int ofd_init0(const struct lu_env *env, struct ofd_device *m,
        ofd_slc_set(m);
        m->ofd_grant_compat_disable = 0;
        m->ofd_soft_sync_limit = OFD_SOFT_SYNC_LIMIT_DEFAULT;
+       m->ofd_brw_size = ONE_MB_BRW_SIZE;
 
        /* statfs data */
        spin_lock_init(&m->ofd_osfs_lock);
@@ -2844,14 +2961,6 @@ static int ofd_init0(const struct lu_env *env, struct ofd_device *m,
 
        dt_conf_get(env, m->ofd_osd, &m->ofd_dt_conf);
 
-       /* Allow at most ddp_grant_reserved% of the available filesystem space
-        * to be granted to clients, so that any errors in the grant overhead
-        * calculations do not allow granting more space to clients than can be
-        * written. Assumes that in aggregate the grant overhead calculations do
-        * not have more than ddp_grant_reserved% estimation error in them. */
-       m->ofd_grant_ratio =
-               ofd_grant_ratio_conv(m->ofd_dt_conf.ddp_grant_reserved);
-
        rc = tgt_init(env, &m->ofd_lut, obd, m->ofd_osd, ofd_common_slice,
                      OBD_FAIL_OST_ALL_REQUEST_NET,
                      OBD_FAIL_OST_ALL_REPLY_NET);