Whamcloud - gitweb
LU-9224 fid: race between client_fid_fini and seq_client_flush
[fs/lustre-release.git] / lustre / fid / fid_request.c
index 7f96185..28a6b1e 100644 (file)
  *
  * You should have received a copy of the GNU General Public License
  * version 2 along with this program; If not, see
- * http://www.sun.com/software/products/lustre/docs/GPLv2.pdf
- *
- * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
- * CA 95054 USA or visit www.sun.com if you need additional information or
- * have any questions.
+ * http://www.gnu.org/licenses/gpl-2.0.html
  *
  * GPL HEADER END
  */
@@ -27,7 +23,7 @@
  * Copyright (c) 2007, 2010, Oracle and/or its affiliates. All rights reserved.
  * Use is subject to license terms.
  *
- * Copyright (c) 2011, 2015, Intel Corporation.
+ * Copyright (c) 2011, 2016, Intel Corporation.
  */
 /*
  * This file is part of Lustre, http://www.lustre.org/
@@ -198,6 +194,17 @@ static int seq_client_alloc_meta(const struct lu_env *env,
                         * (MDT0)yet */
                        rc = seq_client_rpc(seq, &seq->lcs_space,
                                            SEQ_ALLOC_META, "meta");
+                       if (rc == -EINPROGRESS || rc == -EAGAIN) {
+                               wait_queue_head_t waitq;
+                               struct l_wait_info  lwi;
+
+                               /* MDT0 is not ready, let's wait for 2
+                                * seconds and retry. */
+                               init_waitqueue_head(&waitq);
+                               lwi = LWI_TIMEOUT(cfs_time_seconds(2), NULL,
+                                                 NULL);
+                               l_wait_event(waitq, 0, &lwi);
+                       }
                } while (rc == -EINPROGRESS || rc == -EAGAIN);
         }
 
@@ -231,7 +238,7 @@ static int seq_client_alloc_seq(const struct lu_env *env,
        *seqnr = seq->lcs_space.lsr_start;
        seq->lcs_space.lsr_start += 1;
 
-        CDEBUG(D_INFO, "%s: Allocated sequence ["LPX64"]\n", seq->lcs_name,
+       CDEBUG(D_INFO, "%s: Allocated sequence [%#llx]\n", seq->lcs_name,
                *seqnr);
 
         RETURN(rc);
@@ -266,7 +273,7 @@ static void seq_fid_alloc_fini(struct lu_client_seq *seq, __u64 seqnr,
 
        mutex_lock(&seq->lcs_mutex);
        if (seqnr != 0) {
-               CDEBUG(D_INFO, "%s: New sequence [0x%16.16"LPF64"x]\n",
+               CDEBUG(D_INFO, "%s: New sequence [0x%16.16llx]\n",
                       seq->lcs_name, seqnr);
 
                seq->lcs_fid.f_seq = seqnr;
@@ -537,26 +544,30 @@ int client_fid_init(struct obd_device *obd,
        int rc;
        ENTRY;
 
+       down_write(&cli->cl_seq_rwsem);
        OBD_ALLOC_PTR(cli->cl_seq);
-       if (cli->cl_seq == NULL)
-               RETURN(-ENOMEM);
+       if (!cli->cl_seq)
+               GOTO(out, rc = -ENOMEM);
 
        OBD_ALLOC(prefix, MAX_OBD_NAME + 5);
-       if (prefix == NULL)
-               GOTO(out_free_seq, rc = -ENOMEM);
+       if (!prefix)
+               GOTO(out, rc = -ENOMEM);
 
        snprintf(prefix, MAX_OBD_NAME + 5, "cli-%s", obd->obd_name);
 
        /* Init client side sequence-manager */
        rc = seq_client_init(cli->cl_seq, exp, type, prefix, NULL);
        OBD_FREE(prefix, MAX_OBD_NAME + 5);
-       if (rc)
-               GOTO(out_free_seq, rc);
 
-       RETURN(rc);
-out_free_seq:
-       OBD_FREE_PTR(cli->cl_seq);
-       cli->cl_seq = NULL;
+       GOTO(out, rc);
+
+out:
+       if (rc && cli->cl_seq) {
+               OBD_FREE_PTR(cli->cl_seq);
+               cli->cl_seq = NULL;
+       }
+       up_write(&cli->cl_seq_rwsem);
+
        return rc;
 }
 EXPORT_SYMBOL(client_fid_init);
@@ -566,11 +577,13 @@ int client_fid_fini(struct obd_device *obd)
        struct client_obd *cli = &obd->u.cli;
        ENTRY;
 
-       if (cli->cl_seq != NULL) {
+       down_write(&cli->cl_seq_rwsem);
+       if (cli->cl_seq) {
                seq_client_fini(cli->cl_seq);
                OBD_FREE_PTR(cli->cl_seq);
                cli->cl_seq = NULL;
        }
+       up_write(&cli->cl_seq_rwsem);
 
        RETURN(0);
 }