Whamcloud - gitweb
LU-2193 ofd: look up FID to destroy before locking
[fs/lustre-release.git] / lustre / ofd / ofd_obd.c
index 415bfe8..2a05f1d 100644 (file)
@@ -44,6 +44,7 @@
 
 #include "ofd_internal.h"
 #include <obd_cksum.h>
+#include <lustre_quota.h>
 
 static int ofd_export_stats_init(struct ofd_device *ofd,
                                 struct obd_export *exp, void *client_nid)
@@ -424,6 +425,14 @@ static int ofd_destroy_export(struct obd_export *exp)
        return 0;
 }
 
+int ofd_postrecov(const struct lu_env *env, struct ofd_device *ofd)
+{
+       struct lu_device *ldev = &ofd->ofd_dt_dev.dd_lu_dev;
+
+       CDEBUG(D_HA, "%s: recovery is over\n", ofd_obd(ofd)->obd_name);
+       return ldev->ld_ops->ldo_recovery_complete(env, ldev);
+}
+
 int ofd_obd_postrecov(struct obd_device *obd)
 {
        struct lu_env            env;
@@ -437,7 +446,8 @@ int ofd_obd_postrecov(struct obd_device *obd)
                RETURN(rc);
        ofd_info_init(&env, obd->obd_self_export);
 
-       rc = ldev->ld_ops->ldo_recovery_complete(&env, ldev);
+       rc = ofd_postrecov(&env, ofd_dev(ldev));
+
        lu_env_fini(&env);
        RETURN(rc);
 }
@@ -728,10 +738,6 @@ static int ofd_statfs(const struct lu_env *env,  struct obd_export *exp,
               osfs->os_blocks, osfs->os_bfree, osfs->os_bavail,
               osfs->os_files, osfs->os_ffree, osfs->os_state);
 
-       if (OBD_FAIL_CHECK_VALUE(OBD_FAIL_OST_ENOSPC,
-                                ofd->ofd_lut.lut_lsd.lsd_ost_index))
-               osfs->os_bfree = osfs->os_bavail = 2;
-
        if (OBD_FAIL_CHECK_VALUE(OBD_FAIL_OST_ENOINO,
                                 ofd->ofd_lut.lut_lsd.lsd_ost_index))
                osfs->os_ffree = 0;
@@ -752,6 +758,10 @@ static int ofd_statfs(const struct lu_env *env,  struct obd_export *exp,
                osfs->os_bsize    = 1 << COMPAT_BSIZE_SHIFT;
        }
 
+       if (OBD_FAIL_CHECK_VALUE(OBD_FAIL_OST_ENOSPC,
+                                ofd->ofd_lut.lut_lsd.lsd_ost_index))
+               osfs->os_bfree = osfs->os_bavail = 2;
+
        EXIT;
 out:
        return rc;
@@ -834,10 +844,13 @@ int ofd_setattr(const struct lu_env *env, struct obd_export *exp,
        obdo_from_la(oinfo->oi_oa, &info->fti_attr,
                     OFD_VALID_FLAGS | LA_UID | LA_GID);
        ofd_info2oti(info, oti);
+
+       ofd_counter_incr(exp, LPROC_OFD_STATS_SETATTR, oti->oti_jobid, 1);
+       EXIT;
 out_unlock:
        ofd_object_put(env, fo);
 out:
-       RETURN(rc);
+       return rc;
 }
 
 static int ofd_punch(const struct lu_env *env, struct obd_export *exp,
@@ -915,10 +928,13 @@ static int ofd_punch(const struct lu_env *env, struct obd_export *exp,
        obdo_from_la(oinfo->oi_oa, &info->fti_attr,
                     OFD_VALID_FLAGS | LA_UID | LA_GID);
        ofd_info2oti(info, oti);
+
+       ofd_counter_incr(exp, LPROC_OFD_STATS_PUNCH, oti->oti_jobid, 1);
+       EXIT;
 out:
        ofd_object_put(env, fo);
 out_env:
-       RETURN(rc);
+       return rc;
 }
 
 static int ofd_destroy_by_fid(const struct lu_env *env,
@@ -935,6 +951,10 @@ static int ofd_destroy_by_fid(const struct lu_env *env,
 
        ENTRY;
 
+       fo = ofd_object_find(env, ofd, fid);
+       if (IS_ERR(fo))
+               RETURN(PTR_ERR(fo));
+
        /* Tell the clients that the object is gone now and that they should
         * throw away any cached pages. */
        ofd_build_resid(fid, &info->fti_resid);
@@ -947,9 +967,6 @@ static int ofd_destroy_by_fid(const struct lu_env *env,
        if (rc == ELDLM_OK)
                ldlm_lock_decref(&lockh, LCK_PW);
 
-       fo = ofd_object_find(env, ofd, fid);
-       if (IS_ERR(fo))
-               RETURN(PTR_ERR(fo));
        LASSERT(fo != NULL);
 
        rc = ofd_object_destroy(env, fo, orphan);
@@ -997,14 +1014,15 @@ int ofd_destroy(const struct lu_env *env, struct obd_export *exp,
                lrc = ofd_destroy_by_fid(env, ofd, &info->fti_fid, 0);
                if (lrc == -ENOENT) {
                        CDEBUG(D_INODE,
-                              "destroying non-existent object "LPU64"\n",
-                              oa->o_id);
+                              "%s: destroying non-existent object "DFID"\n",
+                              ofd_obd(ofd)->obd_name, PFID(&info->fti_fid));
                        /* rewrite rc with -ENOENT only if it is 0 */
                        if (rc == 0)
                                rc = lrc;
                } else if (lrc != 0) {
-                       CEMERG("error destroying object "LPU64": %d\n",
-                              oa->o_id, rc);
+                       CERROR("%s: error destroying object "DFID": %d\n",
+                              ofd_obd(ofd)->obd_name, PFID(&info->fti_fid),
+                              rc);
                        rc = lrc;
                }
                count--;
@@ -1102,10 +1120,10 @@ int ofd_create(const struct lu_env *env, struct obd_export *exp,
                    oa->o_id > ofd_last_id(ofd, oa->o_seq)) {
                        CERROR("recreate objid "LPU64" > last id "LPU64"\n",
                                        oa->o_id, ofd_last_id(ofd, oa->o_seq));
-                       GOTO(out, rc = -EINVAL);
+                       GOTO(out_nolock, rc = -EINVAL);
                }
                /* do nothing because we create objects during first write */
-               GOTO(out, rc = 0);
+               GOTO(out_nolock, rc = 0);
        }
        /* former ofd_handle_precreate */
        if ((oa->o_valid & OBD_MD_FLFLAGS) &&
@@ -1114,7 +1132,7 @@ int ofd_create(const struct lu_env *env, struct obd_export *exp,
                if (oti->oti_conn_cnt < exp->exp_conn_cnt) {
                        CERROR("%s: dropping old orphan cleanup request\n",
                               ofd_obd(ofd)->obd_name);
-                       GOTO(out, rc = 0);
+                       GOTO(out_nolock, rc = 0);
                }
                /* This causes inflight precreates to abort and drop lock */
                cfs_set_bit(oa->o_seq, &ofd->ofd_destroys_in_progress);
@@ -1152,8 +1170,10 @@ int ofd_create(const struct lu_env *env, struct obd_export *exp,
                }
        }
        if (diff > 0) {
-               obd_id next_id = ofd_last_id(ofd, oa->o_seq) + 1;
-               int i;
+               cfs_time_t       enough_time = cfs_time_shift(DISK_TIMEOUT);
+               obd_id           next_id;
+               int              created = 0;
+               int              count;
 
                if (!(oa->o_valid & OBD_MD_FLFLAGS) ||
                    !(oa->o_flags & OBD_FL_DELORPHAN)) {
@@ -1169,16 +1189,33 @@ int ofd_create(const struct lu_env *env, struct obd_export *exp,
                        }
                }
 
-               CDEBUG(D_HA,
-                      "%s: reserve %d objects in group "LPU64" at "LPU64"\n",
-                      ofd_obd(ofd)->obd_name, diff, oa->o_seq, next_id);
-               for (i = 0; i < diff; i++) {
-                       rc = ofd_precreate_object(env, ofd, next_id + i,
-                                                 oa->o_seq);
-                       if (rc)
+               while (diff > 0) {
+                       next_id = ofd_last_id(ofd, oa->o_seq) + 1;
+                       count = ofd_precreate_batch(ofd, diff);
+
+                       CDEBUG(D_HA, "%s: reserve %d objects in group "LPU64
+                              " at "LPU64"\n", ofd_obd(ofd)->obd_name,
+                              count, oa->o_seq, next_id);
+
+                       if (cfs_time_after(jiffies, enough_time)) {
+                               LCONSOLE_WARN("%s: Slow creates, %d/%d objects"
+                                             " created at a rate of %d/s\n",
+                                             ofd_obd(ofd)->obd_name,
+                                             created, diff + created,
+                                             created / DISK_TIMEOUT);
+                               break;
+               }
+
+                       rc = ofd_precreate_objects(env, ofd, next_id,
+                                                  oa->o_seq, count);
+                       if (rc > 0) {
+                               created += rc;
+                               diff -= rc;
+                       } else if (rc < 0) {
                                break;
+                       }
                }
-               if (i > 0) {
+               if (created > 0) {
                        /* some objects got created, we can return
                         * them, even if last creation failed */
                        oa->o_id = ofd_last_id(ofd, oa->o_seq);
@@ -1199,6 +1236,7 @@ int ofd_create(const struct lu_env *env, struct obd_export *exp,
        ofd_info2oti(info, oti);
 out:
        cfs_mutex_unlock(&ofd->ofd_create_locks[oa->o_seq]);
+out_nolock:
        if (rc == 0 && ea != NULL) {
                struct lov_stripe_md *lsm = *ea;
 
@@ -1280,20 +1318,23 @@ static int ofd_sync(const struct lu_env *env, struct obd_export *exp,
                GOTO(out, rc = PTR_ERR(fo));
        }
 
-       ofd_write_lock(env, fo);
        if (!ofd_object_exists(fo))
-               GOTO(unlock, rc = -ENOENT);
+               GOTO(put, rc = -ENOENT);
 
-       rc = dt_object_sync(env, ofd_object_child(fo));
-       if (rc)
-               GOTO(unlock, rc);
+       if (dt_version_get(env, ofd_object_child(fo)) >
+           ofd_obd(ofd)->obd_last_committed) {
+               rc = dt_object_sync(env, ofd_object_child(fo));
+               if (rc)
+                       GOTO(put, rc);
+       }
 
        oinfo->oi_oa->o_valid = OBD_MD_FLID;
        rc = ofd_attr_get(env, fo, &info->fti_attr);
        obdo_from_la(oinfo->oi_oa, &info->fti_attr, OFD_VALID_FLAGS);
+
+       ofd_counter_incr(exp, LPROC_OFD_STATS_SYNC, oinfo->oi_jobid, 1);
        EXIT;
-unlock:
-       ofd_write_unlock(env, fo);
+put:
        ofd_object_put(env, fo);
 out:
        return rc;
@@ -1355,20 +1396,27 @@ static int ofd_precleanup(struct obd_device *obd, enum obd_cleanup_stage stage)
 
 static int ofd_ping(const struct lu_env *env, struct obd_export *exp)
 {
+       ofd_fmd_expire(exp);
        return 0;
 }
 
-static int ofd_health_check(const struct lu_env *env, struct obd_device *obd)
+static int ofd_health_check(const struct lu_env *nul, struct obd_device *obd)
 {
        struct ofd_device       *ofd = ofd_dev(obd->obd_lu_dev);
        struct ofd_thread_info  *info;
+       struct lu_env            env;
 #ifdef USE_HEALTH_CHECK_WRITE
        struct thandle          *th;
 #endif
        int                      rc = 0;
 
-       info = ofd_info_init(env, NULL);
-       rc = dt_statfs(env, ofd->ofd_osd, &info->fti_u.osfs);
+       /* obd_proc_read_health pass NULL env, we need real one */
+       rc = lu_env_init(&env, LCT_DT_THREAD);
+       if (rc)
+               RETURN(rc);
+
+       info = ofd_info_init(&env, NULL);
+       rc = dt_statfs(&env, ofd->ofd_osd, &info->fti_u.osfs);
        if (unlikely(rc))
                GOTO(out, rc);
 
@@ -1383,27 +1431,28 @@ static int ofd_health_check(const struct lu_env *env, struct obd_device *obd)
        info->fti_buf.lb_len = CFS_PAGE_SIZE;
        info->fti_off = 0;
 
-       th = dt_trans_create(env, ofd->ofd_osd);
+       th = dt_trans_create(&env, ofd->ofd_osd);
        if (IS_ERR(th))
                GOTO(out, rc = PTR_ERR(th));
 
-       rc = dt_declare_record_write(env, ofd->ofd_health_check_file,
+       rc = dt_declare_record_write(&env, ofd->ofd_health_check_file,
                                     info->fti_buf.lb_len, info->fti_off, th);
        if (rc == 0) {
                th->th_sync = 1; /* sync IO is needed */
-               rc = dt_trans_start_local(env, ofd->ofd_osd, th);
+               rc = dt_trans_start_local(&env, ofd->ofd_osd, th);
                if (rc == 0)
-                       rc = dt_record_write(env, ofd->ofd_health_check_file,
+                       rc = dt_record_write(&env, ofd->ofd_health_check_file,
                                             &info->fti_buf, &info->fti_off,
                                             th);
        }
-       dt_trans_stop(env, ofd->ofd_osd, th);
+       dt_trans_stop(&env, ofd->ofd_osd, th);
 
        OBD_FREE(info->fti_buf.lb_buf, CFS_PAGE_SIZE);
 
        CDEBUG(D_INFO, "write 1 page synchronously for checking io rc %d\n",rc);
 #endif
 out:
+       lu_env_fini(&env);
        return !!rc;
 }
 
@@ -1425,21 +1474,7 @@ static int ofd_obd_notify(struct obd_device *obd, struct obd_device *unused,
 }
 
 /*
- * Handle quotacheck requests.
- *
- * \param obd - is the obd device associated with the ofd
- * \param exp - is the client's export
- * \param oqctl - is the obd_quotactl request to be processed
- */
-static int ofd_quotacheck(struct obd_device *obd, struct obd_export *exp,
-                         struct obd_quotactl *oqctl)
-{
-       return 0;
-}
-
-/*
- * Handle quota control requests to consult current usage/limit, but also
- * to configure quota enforcement
+ * Handle quota control requests to consult current usage/limit.
  *
  * \param obd - is the obd device associated with the ofd
  * \param exp - is the client's export
@@ -1448,7 +1483,24 @@ static int ofd_quotacheck(struct obd_device *obd, struct obd_export *exp,
 static int ofd_quotactl(struct obd_device *obd, struct obd_export *exp,
                        struct obd_quotactl *oqctl)
 {
-       return 0;
+       struct ofd_device  *ofd = ofd_dev(obd->obd_lu_dev);
+       struct lu_env       env;
+       int                 rc;
+       ENTRY;
+
+       /* report success for quota on/off for interoperability with current MDT
+        * stack */
+       if (oqctl->qc_cmd == Q_QUOTAON || oqctl->qc_cmd == Q_QUOTAOFF)
+               RETURN(0);
+
+       rc = lu_env_init(&env, LCT_DT_THREAD);
+       if (rc)
+               RETURN(rc);
+
+       rc = lquotactl_slv(&env, ofd->ofd_osd, oqctl);
+       lu_env_fini(&env);
+
+       RETURN(rc);
 }
 
 struct obd_ops ofd_obd_ops = {
@@ -1476,5 +1528,4 @@ struct obd_ops ofd_obd_ops = {
        .o_health_check         = ofd_health_check,
        .o_notify               = ofd_obd_notify,
        .o_quotactl             = ofd_quotactl,
-       .o_quotacheck           = ofd_quotacheck,
 };