Whamcloud - gitweb
LU-14911 osp: release thandle if it was created
[fs/lustre-release.git] / lustre / osp / osp_precreate.c
index c125948..805f87d 100644 (file)
@@ -27,7 +27,6 @@
  */
 /*
  * This file is part of Lustre, http://www.lustre.org/
- * Lustre is a trademark of Sun Microsystems, Inc.
  *
  * lustre/osp/osp_precreate.c
  *
@@ -139,6 +138,7 @@ static int osp_statfs_interpret(const struct lu_env *env,
        union ptlrpc_async_args *aa = args;
        struct obd_import *imp = req->rq_import;
        struct obd_statfs *msfs;
+       struct obd_statfs *sfs;
        struct osp_device *d;
        u64 maxage_ns;
 
@@ -167,7 +167,13 @@ static int osp_statfs_interpret(const struct lu_env *env,
                  jiffies + cfs_time_seconds(d->opd_statfs_maxage));
        d->opd_statfs_update_in_progress = 0;
 
-       CDEBUG(D_CACHE, "updated statfs %p\n", d);
+       sfs = &d->opd_statfs;
+       CDEBUG(D_CACHE, "%s (%p): %llu blocks, %llu free, %llu avail, "
+              "%u bsize, %u reserved mb low, %u reserved mb high,"
+              "%llu files, %llu free files\n", d->opd_obd->obd_name, d,
+              sfs->os_blocks, sfs->os_bfree, sfs->os_bavail, sfs->os_bsize,
+              d->opd_reserved_mb_low, d->opd_reserved_mb_high,
+              sfs->os_files, sfs->os_ffree);
 
        RETURN(0);
 out:
@@ -256,8 +262,8 @@ static int osp_statfs_update(const struct lu_env *env, struct osp_device *d)
                               d->opd_obd->obd_name,
                               atomic_read(&d->opd_sync_changes));
                        osp_sync_add_commit_cb_1s(env, d, th);
-                       dt_trans_stop(env, d->opd_storage, th);
                }
+               dt_trans_stop(env, d->opd_storage, th);
        }
 
 out:
@@ -668,6 +674,9 @@ static int osp_precreate_send(const struct lu_env *env, struct osp_device *d)
        if (rc) {
                CERROR("%s: can't precreate: rc = %d\n", d->opd_obd->obd_name,
                       rc);
+               if (req->rq_net_err)
+                       /* have osp_precreate_reserve() to wait for repeat */
+                       rc = -ENOTCONN;
                GOTO(out_req, rc);
        }
        LASSERT(req->rq_transno == 0);
@@ -715,6 +724,9 @@ out_req:
        osp_pre_update_status(d, rc);
        wake_up(&d->opd_pre_user_waitq);
 
+       /* pause to let osp_precreate_reserve to go first */
+       CFS_FAIL_TIMEOUT(OBD_FAIL_OSP_PRECREATE_PAUSE, 2);
+
        ptlrpc_req_finished(req);
        RETURN(rc);
 }
@@ -1025,9 +1037,9 @@ static void osp_pre_update_msfs(struct osp_device *d, struct obd_statfs *msfs)
 
        available_mb = (msfs->os_bavail * (msfs->os_bsize >> 10)) >> 10;
        if (msfs->os_ffree < reserved_ino_low)
-               msfs->os_state |= OS_STATE_ENOINO;
+               msfs->os_state |= OS_STATFS_ENOINO;
        else if (msfs->os_ffree <= reserved_ino_high)
-               msfs->os_state |= old_state & OS_STATE_ENOINO;
+               msfs->os_state |= old_state & OS_STATFS_ENOINO;
        /* else don't clear flags in new msfs->os_state sent from OST */
 
        CDEBUG(D_INFO,
@@ -1037,21 +1049,21 @@ static void osp_pre_update_msfs(struct osp_device *d, struct obd_statfs *msfs)
               msfs->os_files, msfs->os_ffree, msfs->os_state,
               d->opd_pre_status);
        if (available_mb < d->opd_reserved_mb_low)
-               msfs->os_state |= OS_STATE_ENOSPC;
+               msfs->os_state |= OS_STATFS_ENOSPC;
        else if (available_mb <= d->opd_reserved_mb_high)
-               msfs->os_state |= old_state & OS_STATE_ENOSPC;
+               msfs->os_state |= old_state & OS_STATFS_ENOSPC;
        /* else don't clear flags in new msfs->os_state sent from OST */
 
-       if (msfs->os_state & (OS_STATE_ENOINO | OS_STATE_ENOSPC)) {
+       if (msfs->os_state & (OS_STATFS_ENOINO | OS_STATFS_ENOSPC)) {
                d->opd_pre_status = -ENOSPC;
-               if (!(old_state & (OS_STATE_ENOINO | OS_STATE_ENOSPC)))
+               if (!(old_state & (OS_STATFS_ENOINO | OS_STATFS_ENOSPC)))
                        CDEBUG(D_INFO, "%s: full: state=%x: rc = %x\n",
                               d->opd_obd->obd_name, msfs->os_state,
                               d->opd_pre_status);
                CDEBUG(D_INFO, "uncommitted changes=%u in_progress=%u\n",
                       atomic_read(&d->opd_sync_changes),
                       atomic_read(&d->opd_sync_rpcs_in_progress));
-       } else if (old_state & (OS_STATE_ENOINO | OS_STATE_ENOSPC)) {
+       } else if (old_state & (OS_STATFS_ENOINO | OS_STATFS_ENOSPC)) {
                d->opd_pre_status = 0;
                spin_lock(&d->opd_pre_lock);
                d->opd_pre_create_slow = 0;
@@ -1070,7 +1082,7 @@ static void osp_pre_update_msfs(struct osp_device *d, struct obd_statfs *msfs)
 
        /* Object precreation skipped on OST if manually disabled */
        if (d->opd_pre_max_create_count == 0)
-               msfs->os_state |= OS_STATE_NOPRECREATE;
+               msfs->os_state |= OS_STATFS_NOPRECREATE;
        /* else don't clear flags in new msfs->os_state sent from OST */
 
        /* copy only new statfs state to make it visible to MDS threads */
@@ -1217,6 +1229,8 @@ static int osp_precreate_thread(void *_args)
                        if (!d->opd_new_connection)
                                continue;
 
+                       OBD_FAIL_TIMEOUT(OBD_FAIL_OSP_CON_EVENT_DELAY,
+                                        cfs_fail_val);
                        d->opd_new_connection = 0;
                        d->opd_got_disconnected = 0;
                        break;
@@ -1397,7 +1411,8 @@ static int osp_precreate_ready_condition(const struct lu_env *env,
  * \retval             -EAGAIN try later, slow precreation in progress
  * \retval             -EIO when no access to OST
  */
-int osp_precreate_reserve(const struct lu_env *env, struct osp_device *d)
+int osp_precreate_reserve(const struct lu_env *env, struct osp_device *d,
+                         bool can_block)
 {
        time64_t expire = ktime_get_seconds() + obd_timeout;
        int precreated, rc, synced = 0;
@@ -1466,8 +1481,9 @@ int osp_precreate_reserve(const struct lu_env *env, struct osp_device *d)
                                synced = 1;
                        }
                        if (atomic_read(&d->opd_sync_rpcs_in_progress)) {
-                               /* just wait till destroys are done */
-                               /* see l_wait_even() few lines below */
+                               /* just wait till destroys are done
+                                * see wait_event_idle_timeout() below
+                                */
                        }
                        if (atomic_read(&d->opd_sync_changes) +
                            atomic_read(&d->opd_sync_rpcs_in_progress) == 0) {
@@ -1484,6 +1500,12 @@ int osp_precreate_reserve(const struct lu_env *env, struct osp_device *d)
                        break;
                }
 
+               if (!can_block) {
+                       LASSERT(d->opd_pre);
+                       rc = -ENOBUFS;
+                       break;
+               }
+
                if (wait_event_idle_timeout(
                            d->opd_pre_user_waitq,
                            osp_precreate_ready_condition(env, d),
@@ -1620,12 +1642,12 @@ int osp_object_truncate(const struct lu_env *env, struct dt_object *dt,
         * XXX: decide how do we do here with resend
         * if we don't resend, then client may see wrong file size
         * if we do resend, then MDS thread can get stuck for quite long
-        * and if we don't resend, then client will also get -EWOULDBLOCK !!
+        * and if we don't resend, then client will also get -EAGAIN !!
         * (see LU-7975 and sanity/test_27F use cases)
         * but let's decide not to resend/delay this truncate request to OST
         * and allow Client to decide to resend, in a less agressive way from
         * after_reply(), by returning -EINPROGRESS instead of
-        * -EAGAIN/-EWOULDBLOCK upon return from ptlrpc_queue_wait() at the
+        * -EAGAIN/-EAGAIN upon return from ptlrpc_queue_wait() at the
         * end of this routine
         */
        req->rq_no_resend = req->rq_no_delay = 1;
@@ -1655,14 +1677,14 @@ int osp_object_truncate(const struct lu_env *env, struct dt_object *dt,
 
        rc = ptlrpc_queue_wait(req);
        if (rc) {
-               /* -EWOULDBLOCK/-EAGAIN means OST is unreachable at the moment
+               /* -EAGAIN/-EWOULDBLOCK means OST is unreachable at the moment
                 * since we have decided not to resend/delay, but this could
                 * lead to wrong size to be seen at Client side and even process
                 * trying to open to exit/fail if not itself handling -EAGAIN.
                 * So it should be better to return -EINPROGRESS instead and
                 * leave the decision to resend at Client side in after_reply()
                 */
-               if (rc == -EWOULDBLOCK) {
+               if (rc == -EAGAIN) {
                        rc = -EINPROGRESS;
                        CDEBUG(D_HA, "returning -EINPROGRESS instead of "
                               "-EWOULDBLOCK/-EAGAIN to allow Client to "