Whamcloud - gitweb
LU-8900 snapshot: fork/erase configuration
[fs/lustre-release.git] / lustre / mgs / mgs_nids.c
index 8aacd89..2d14d2a 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, 2014, Intel Corporation.
+ * Copyright (c) 2011, 2015, Intel Corporation.
  */
 /*
  * This file is part of Lustre, http://www.lustre.org/
@@ -96,7 +92,7 @@ static int mgs_nidtbl_read(struct obd_export *exp, struct mgs_nidtbl *tbl,
 
         /* make sure unit_size is power 2 */
         LASSERT((unit_size & (unit_size - 1)) == 0);
-       LASSERT(nrpages << PAGE_CACHE_SHIFT >= units_total * unit_size);
+       LASSERT(nrpages << PAGE_SHIFT >= units_total * unit_size);
 
        mutex_lock(&tbl->mn_lock);
         LASSERT(nidtbl_is_sane(tbl));
@@ -146,7 +142,7 @@ static int mgs_nidtbl_read(struct obd_export *exp, struct mgs_nidtbl *tbl,
 
                        if (units_in_page == 0) {
                                /* allocate a new page */
-                               pages[index] = alloc_page(GFP_IOFS);
+                               pages[index] = alloc_page(GFP_KERNEL);
                                if (pages[index] == NULL) {
                                        rc = -ENOMEM;
                                        break;
@@ -160,7 +156,7 @@ static int mgs_nidtbl_read(struct obd_export *exp, struct mgs_nidtbl *tbl,
                                buf = kmap(pages[index]);
                                ++index;
 
-                               units_in_page = PAGE_CACHE_SIZE / unit_size;
+                               units_in_page = PAGE_SIZE / unit_size;
                                LASSERT(units_in_page > 0);
                        }
 
@@ -418,18 +414,15 @@ void mgs_ir_notify_complete(struct fs_db *fsdb)
 
 static int mgs_ir_notify(void *arg)
 {
-        struct fs_db      *fsdb   = arg;
-        struct ldlm_res_id resid;
-
-        char name[sizeof(fsdb->fsdb_name) + 20];
+       struct fs_db *fsdb = arg;
+       struct ldlm_res_id resid;
+       char name[sizeof(fsdb->fsdb_name) + 16];
 
-        LASSERTF(sizeof(name) < 32, "name is too large to be in stack.\n");
-        sprintf(name, "mgs_%s_notify", fsdb->fsdb_name);
+       LASSERTF(sizeof(name) < 40, "name is too large to be in stack.\n");
 
+       snprintf(name, sizeof(name) - 1, "mgs_%s_notify", fsdb->fsdb_name);
        complete(&fsdb->fsdb_notify_comp);
-
-        set_user_nice(current, -2);
-
+       set_user_nice(current, -2);
        mgc_fsname2resid(fsdb->fsdb_name, &resid, CONFIG_T_RECOVER);
        while (1) {
                struct l_wait_info   lwi = { 0 };
@@ -465,14 +458,8 @@ int mgs_ir_init_fs(const struct lu_env *env, struct mgs_device *mgs,
                            mgs->mgs_start_time + ir_timeout))
                fsdb->fsdb_ir_state = IR_STARTUP;
        fsdb->fsdb_nonir_clients = 0;
-       INIT_LIST_HEAD(&fsdb->fsdb_clients);
-
        /* start notify thread */
        fsdb->fsdb_mgs = mgs;
-       atomic_set(&fsdb->fsdb_notify_phase, 0);
-       init_waitqueue_head(&fsdb->fsdb_notify_waitq);
-       init_completion(&fsdb->fsdb_notify_comp);
-
        task = kthread_run(mgs_ir_notify, fsdb,
                               "mgs_%s_notify", fsdb->fsdb_name);
        if (!IS_ERR(task))
@@ -529,7 +516,7 @@ int mgs_ir_update(const struct lu_env *env, struct mgs_device *mgs,
 
        rc = mgs_nidtbl_write(env, fsdb, mti);
         if (rc)
-                return rc;
+               GOTO(out, rc);
 
         /* check ir state */
        mutex_lock(&fsdb->fsdb_mutex);
@@ -555,7 +542,10 @@ int mgs_ir_update(const struct lu_env *env, struct mgs_device *mgs,
                atomic_inc(&fsdb->fsdb_notify_phase);
                wake_up(&fsdb->fsdb_notify_waitq);
        }
-       return 0;
+
+out:
+       mgs_put_fsdb(mgs, fsdb);
+       return rc;
 }
 
 /* NID table can be cached by two entities: Clients and MDTs */
@@ -599,7 +589,7 @@ int mgs_get_ir_logs(struct ptlrpc_request *req)
 {
        struct lu_env     *env = req->rq_svc_thread->t_env;
        struct mgs_device *mgs = exp2mgs_dev(req->rq_export);
-        struct fs_db      *fsdb;
+       struct fs_db *fsdb = NULL;
         struct mgs_config_body  *body;
         struct mgs_config_res   *res;
         struct ptlrpc_bulk_desc *desc;
@@ -627,57 +617,71 @@ int mgs_get_ir_logs(struct ptlrpc_request *req)
         if (rc)
                 RETURN(rc);
 
+       bufsize = body->mcb_units << body->mcb_bits;
+       nrpages = (bufsize + PAGE_SIZE - 1) >> PAGE_SHIFT;
+       if (nrpages > PTLRPC_MAX_BRW_PAGES)
+               RETURN(-EINVAL);
+
        rc = mgs_find_or_make_fsdb(env, mgs, fsname, &fsdb);
-        if (rc)
+       if (rc)
                RETURN(rc);
 
-        bufsize = body->mcb_units << body->mcb_bits;
-       nrpages = (bufsize + PAGE_CACHE_SIZE - 1) >> PAGE_CACHE_SHIFT;
-        if (nrpages > PTLRPC_MAX_BRW_PAGES)
-                RETURN(-EINVAL);
-
-        CDEBUG(D_MGS, "Reading IR log %s bufsize %ld.\n",
-               body->mcb_name, bufsize);
+       CDEBUG(D_MGS, "Reading IR log %s bufsize %ld.\n",
+              body->mcb_name, bufsize);
 
-        OBD_ALLOC(pages, sizeof(*pages) * nrpages);
-        if (pages == NULL)
-                RETURN(-ENOMEM);
+       OBD_ALLOC(pages, sizeof(*pages) * nrpages);
+       if (!pages)
+               GOTO(out, rc = -ENOMEM);
 
-        res = req_capsule_server_get(&req->rq_pill, &RMF_MGS_CONFIG_RES);
-        if (res == NULL)
-                GOTO(out, rc = -EINVAL);
+       res = req_capsule_server_get(&req->rq_pill, &RMF_MGS_CONFIG_RES);
+       if (!res)
+               GOTO(out, rc = -EINVAL);
 
-        res->mcr_offset = body->mcb_offset;
-       unit_size = min_t(int, 1 << body->mcb_bits, PAGE_CACHE_SIZE);
+       res->mcr_offset = body->mcb_offset;
+       unit_size = min_t(int, 1 << body->mcb_bits, PAGE_SIZE);
        bytes = mgs_nidtbl_read(req->rq_export, &fsdb->fsdb_nidtbl, res,
                                pages, nrpages, bufsize / unit_size, unit_size);
        if (bytes < 0)
                GOTO(out, rc = bytes);
 
        /* start bulk transfer */
-       page_count = (bytes + PAGE_CACHE_SIZE - 1) >> PAGE_CACHE_SHIFT;
+       page_count = (bytes + PAGE_SIZE - 1) >> PAGE_SHIFT;
        LASSERT(page_count <= nrpages);
        desc = ptlrpc_prep_bulk_exp(req, page_count, 1,
-                                   BULK_PUT_SOURCE, MGS_BULK_PORTAL);
-       if (desc == NULL)
+                                   PTLRPC_BULK_PUT_SOURCE |
+                                       PTLRPC_BULK_BUF_KIOV,
+                                   MGS_BULK_PORTAL,
+                                   &ptlrpc_bulk_kiov_pin_ops);
+       if (!desc)
                GOTO(out, rc = -ENOMEM);
 
        for (i = 0; i < page_count && bytes > 0; i++) {
-               ptlrpc_prep_bulk_page_pin(desc, pages[i], 0,
-                                         min_t(int, bytes, PAGE_CACHE_SIZE));
-               bytes -= PAGE_CACHE_SIZE;
-        }
+               desc->bd_frag_ops->add_kiov_frag(desc, pages[i], 0,
+                                                min_t(int, bytes,
+                                                     PAGE_SIZE));
+               bytes -= PAGE_SIZE;
+       }
+
+       rc = target_bulk_io(req->rq_export, desc, &lwi);
+       ptlrpc_free_bulk(desc);
 
-        rc = target_bulk_io(req->rq_export, desc, &lwi);
-       ptlrpc_free_bulk_pin(desc);
+       GOTO(out, rc);
 
 out:
-       for (i = 0; i < nrpages; i++) {
-               if (pages[i] == NULL)
-                       break;
-               __free_page(pages[i]);
+       if (pages) {
+               for (i = 0; i < nrpages; i++) {
+                       if (!pages[i])
+                               break;
+
+                       __free_page(pages[i]);
+               }
+
+               OBD_FREE(pages, sizeof(*pages) * nrpages);
        }
-       OBD_FREE(pages, sizeof(*pages) * nrpages);
+
+       if (fsdb)
+               mgs_put_fsdb(mgs, fsdb);
+
        return rc;
 }
 
@@ -741,7 +745,7 @@ int lprocfs_wr_ir_state(struct file *file, const char __user *buffer,
         char *ptr;
         int rc = 0;
 
-       if (count == 0 || count >= PAGE_CACHE_SIZE)
+       if (count == 0 || count >= PAGE_SIZE)
                return -EINVAL;
 
        OBD_ALLOC(kbuf, count + 1);
@@ -840,9 +844,9 @@ ssize_t lprocfs_ir_timeout_seq_write(struct file *file,
 int mgs_fsc_attach(const struct lu_env *env, struct obd_export *exp,
                   char *fsname)
 {
-        struct mgs_export_data *data = &exp->u.eu_mgs_data;
+       struct mgs_export_data *data = &exp->u.eu_mgs_data;
        struct mgs_device *mgs = exp2mgs_dev(exp);
-        struct fs_db      *fsdb;
+       struct fs_db *fsdb = NULL;
         struct mgs_fsc    *fsc     = NULL;
         struct mgs_fsc    *new_fsc = NULL;
         bool               found   = false;
@@ -855,8 +859,8 @@ int mgs_fsc_attach(const struct lu_env *env, struct obd_export *exp,
 
         /* allocate a new fsc in case we need it in spinlock. */
         OBD_ALLOC_PTR(new_fsc);
-        if (new_fsc == NULL)
-                RETURN(-ENOMEM);
+       if (!new_fsc)
+               GOTO(out, rc = -ENOMEM);
 
        INIT_LIST_HEAD(&new_fsc->mfc_export_list);
        INIT_LIST_HEAD(&new_fsc->mfc_fsdb_list);
@@ -899,7 +903,10 @@ int mgs_fsc_attach(const struct lu_env *env, struct obd_export *exp,
                 class_export_put(new_fsc->mfc_export);
                 OBD_FREE_PTR(new_fsc);
         }
-        RETURN(rc);
+
+out:
+       mgs_put_fsdb(mgs, fsdb);
+       RETURN(rc);
 }
 
 void mgs_fsc_cleanup(struct obd_export *exp)