Whamcloud - gitweb
LU-14550 libcfs: fix setting of debug_path
[fs/lustre-release.git] / lustre / osc / osc_request.c
index 0043b83..6cd0a2c 100644 (file)
@@ -36,7 +36,6 @@
 #include <libcfs/libcfs.h>
 #include <linux/falloc.h>
 #include <lprocfs_status.h>
-#include <lustre_debug.h>
 #include <lustre_dlm.h>
 #include <lustre_fid.h>
 #include <lustre_ha.h>
@@ -699,7 +698,7 @@ static void osc_announce_cached(struct client_obd *cli, struct obdo *oa,
 
        oa->o_valid |= bits;
        spin_lock(&cli->cl_loi_list_lock);
-       if (OCD_HAS_FLAG(&cli->cl_import->imp_connect_data, GRANT_PARAM))
+       if (cli->cl_ocd_grant_param)
                oa->o_dirty = cli->cl_dirty_grant;
        else
                oa->o_dirty = cli->cl_dirty_pages << PAGE_SHIFT;
@@ -730,13 +729,12 @@ static void osc_announce_cached(struct client_obd *cli, struct obdo *oa,
                nrpages *= cli->cl_max_rpcs_in_flight + 1;
                nrpages = max(nrpages, cli->cl_dirty_max_pages);
                undirty = nrpages << PAGE_SHIFT;
-               if (OCD_HAS_FLAG(&cli->cl_import->imp_connect_data,
-                                GRANT_PARAM)) {
+               if (cli->cl_ocd_grant_param) {
                        int nrextents;
 
                        /* take extent tax into account when asking for more
                         * grant space */
-                       nrextents = (nrpages + cli->cl_max_extent_pages - 1)  /
+                       nrextents = (nrpages + cli->cl_max_extent_pages - 1) /
                                     cli->cl_max_extent_pages;
                        undirty += nrextents * cli->cl_grant_extent_tax;
                }
@@ -747,11 +745,20 @@ static void osc_announce_cached(struct client_obd *cli, struct obdo *oa,
                                    ~(PTLRPC_MAX_BRW_SIZE * 4UL));
         }
        oa->o_grant = cli->cl_avail_grant + cli->cl_reserved_grant;
-        oa->o_dropped = cli->cl_lost_grant;
-        cli->cl_lost_grant = 0;
+       /* o_dropped AKA o_misc is 32 bits, but cl_lost_grant is 64 bits */
+       if (cli->cl_lost_grant > INT_MAX) {
+               CDEBUG(D_CACHE,
+                     "%s: avoided o_dropped overflow: cl_lost_grant %lu\n",
+                     cli_name(cli), cli->cl_lost_grant);
+               oa->o_dropped = INT_MAX;
+       } else {
+               oa->o_dropped = cli->cl_lost_grant;
+       }
+       cli->cl_lost_grant -= oa->o_dropped;
        spin_unlock(&cli->cl_loi_list_lock);
-       CDEBUG(D_CACHE, "dirty: %llu undirty: %u dropped %u grant: %llu\n",
-               oa->o_dirty, oa->o_undirty, oa->o_dropped, oa->o_grant);
+       CDEBUG(D_CACHE, "%s: dirty: %llu undirty: %u dropped %u grant: %llu"
+              " cl_lost_grant %lu\n", cli_name(cli), oa->o_dirty,
+              oa->o_undirty, oa->o_dropped, oa->o_grant, cli->cl_lost_grant);
 }
 
 void osc_update_next_shrink(struct client_obd *cli)
@@ -1053,10 +1060,10 @@ void osc_init_grant(struct client_obd *cli, struct obd_connect_data *ocd)
                                             ~chunk_mask) & chunk_mask;
                /* determine maximum extent size, in #pages */
                size = (u64)ocd->ocd_grant_max_blks << ocd->ocd_grant_blkbits;
-               cli->cl_max_extent_pages = size >> PAGE_SHIFT;
-               if (cli->cl_max_extent_pages == 0)
-                       cli->cl_max_extent_pages = 1;
+               cli->cl_max_extent_pages = (size >> PAGE_SHIFT) ?: 1;
+               cli->cl_ocd_grant_param = 1;
        } else {
+               cli->cl_ocd_grant_param = 0;
                cli->cl_grant_extent_tax = 0;
                cli->cl_chunkbits = PAGE_SHIFT;
                cli->cl_max_extent_pages = DT_MAX_BRW_PAGES;
@@ -1390,9 +1397,22 @@ osc_brw_prep_request(int cmd, struct client_obd *cli, struct obdo *oa,
        void *short_io_buf;
        const char *obd_name = cli->cl_import->imp_obd->obd_name;
        struct inode *inode;
+       bool directio = false;
 
        ENTRY;
        inode = page2inode(pga[0]->pg);
+       if (inode == NULL) {
+               /* Try to get reference to inode from cl_page if we are
+                * dealing with direct IO, as handled pages are not
+                * actual page cache pages.
+                */
+               struct osc_async_page *oap = brw_page2oap(pga[0]);
+               struct cl_page *clpage = oap2cl_page(oap);
+
+               inode = clpage->cp_inode;
+               if (inode)
+                       directio = true;
+       }
        if (OBD_FAIL_CHECK(OBD_FAIL_OSC_BRW_PREP_REQ))
                RETURN(-ENOMEM); /* Recoverable */
        if (OBD_FAIL_CHECK(OBD_FAIL_OSC_BRW_PREP_REQ2))
@@ -1417,6 +1437,8 @@ osc_brw_prep_request(int cmd, struct client_obd *cli, struct obdo *oa,
                        bool retried = false;
                        bool lockedbymyself;
                        u32 nunits = (pg->off & ~PAGE_MASK) + pg->count;
+                       struct address_space *map_orig = NULL;
+                       pgoff_t index_orig;
 
 retry_encrypt:
                        if (nunits & ~LUSTRE_ENCRYPTION_MASK)
@@ -1432,10 +1454,20 @@ retry_encrypt:
                         * which means only once the page is fully processed.
                         */
                        lockedbymyself = trylock_page(pg->pg);
+                       if (directio) {
+                               map_orig = pg->pg->mapping;
+                               pg->pg->mapping = inode->i_mapping;
+                               index_orig = pg->pg->index;
+                               pg->pg->index = pg->off >> PAGE_SHIFT;
+                       }
                        data_page =
                                llcrypt_encrypt_pagecache_blocks(pg->pg,
                                                                 nunits, 0,
                                                                 GFP_NOFS);
+                       if (directio) {
+                               pg->pg->mapping = map_orig;
+                               pg->pg->index = index_orig;
+                       }
                        if (lockedbymyself)
                                unlock_page(pg->pg);
                        if (IS_ERR(data_page)) {
@@ -1750,9 +1782,8 @@ static void dump_all_bulk_pages(struct obdo *oa, __u32 page_count,
         * file/fid, not during the resends/retries. */
        snprintf(dbgcksum_file_name, sizeof(dbgcksum_file_name),
                 "%s-checksum_dump-osc-"DFID":[%llu-%llu]-%x-%x",
-                (strncmp(libcfs_debug_file_path_arr, "NONE", 4) != 0 ?
-                 libcfs_debug_file_path_arr :
-                 LIBCFS_DEBUG_FILE_PATH_DEFAULT),
+                (strncmp(libcfs_debug_file_path, "NONE", 4) != 0 ?
+                 libcfs_debug_file_path : LIBCFS_DEBUG_FILE_PATH_DEFAULT),
                 oa->o_valid & OBD_MD_FLFID ? oa->o_parent_seq : 0ULL,
                 oa->o_valid & OBD_MD_FLFID ? oa->o_parent_oid : 0,
                 oa->o_valid & OBD_MD_FLFID ? oa->o_parent_ver : 0,
@@ -1895,6 +1926,7 @@ static int osc_brw_fini_request(struct ptlrpc_request *req, int rc)
        struct ost_body *body;
        u32 client_cksum = 0;
        struct inode *inode;
+       unsigned int blockbits = 0, blocksize = 0;
 
        ENTRY;
 
@@ -2084,6 +2116,19 @@ static int osc_brw_fini_request(struct ptlrpc_request *req, int rc)
        }
 
        inode = page2inode(aa->aa_ppga[0]->pg);
+       if (inode == NULL) {
+               /* Try to get reference to inode from cl_page if we are
+                * dealing with direct IO, as handled pages are not
+                * actual page cache pages.
+                */
+               struct osc_async_page *oap = brw_page2oap(aa->aa_ppga[0]);
+
+               inode = oap2cl_page(oap)->cp_inode;
+               if (inode) {
+                       blockbits = inode->i_blkbits;
+                       blocksize = 1 << blockbits;
+               }
+       }
        if (inode && IS_ENCRYPTED(inode)) {
                int idx;
 
@@ -2108,18 +2153,36 @@ static int osc_brw_fini_request(struct ptlrpc_request *req, int rc)
                                        break;
                                }
 
-                               /* The page is already locked when we arrive here,
-                                * except when we deal with a twisted page for
-                                * specific Direct IO support, in which case
-                                * PageChecked flag is set on page.
-                                */
-                               if (PageChecked(pg->pg))
-                                       lock_page(pg->pg);
-                               rc = llcrypt_decrypt_pagecache_blocks(pg->pg,
-                                                   LUSTRE_ENCRYPTION_UNIT_SIZE,
-                                                                     offs);
-                               if (PageChecked(pg->pg))
-                                       unlock_page(pg->pg);
+                               if (blockbits) {
+                                       /* This is direct IO case. Directly call
+                                        * decrypt function that takes inode as
+                                        * input parameter. Page does not need
+                                        * to be locked.
+                                        */
+                                       u64 lblk_num =
+                                               ((u64)(pg->off >> PAGE_SHIFT) <<
+                                                    (PAGE_SHIFT - blockbits)) +
+                                                      (offs >> blockbits);
+                                       unsigned int i;
+
+                                       for (i = offs;
+                                            i < offs +
+                                                   LUSTRE_ENCRYPTION_UNIT_SIZE;
+                                            i += blocksize, lblk_num++) {
+                                               rc =
+                                                 llcrypt_decrypt_block_inplace(
+                                                         inode, pg->pg,
+                                                         blocksize, i,
+                                                         lblk_num);
+                                               if (rc)
+                                                       break;
+                                       }
+                               } else {
+                                       rc = llcrypt_decrypt_pagecache_blocks(
+                                               pg->pg,
+                                               LUSTRE_ENCRYPTION_UNIT_SIZE,
+                                               offs);
+                               }
                                if (rc)
                                        GOTO(out, rc);
 
@@ -2345,7 +2408,7 @@ static int brw_interpret(const struct lu_env *env,
        list_for_each_entry_safe(ext, tmp, &aa->aa_exts, oe_link) {
                list_del_init(&ext->oe_link);
                osc_extent_finish(env, ext, 1,
-                                 rc && req->rq_no_delay ? -EWOULDBLOCK : rc);
+                                 rc && req->rq_no_delay ? -EAGAIN : rc);
        }
        LASSERT(list_empty(&aa->aa_exts));
        LASSERT(list_empty(&aa->aa_oaps));
@@ -2648,6 +2711,10 @@ int osc_enqueue_interpret(const struct lu_env *env, struct ptlrpc_request *req,
        struct ost_lvb *lvb = aa->oa_lvb;
        __u32 lvb_len = sizeof(*lvb);
        __u64 flags = 0;
+       struct ldlm_enqueue_info einfo = {
+               .ei_type = aa->oa_type,
+               .ei_mode = mode,
+       };
 
        ENTRY;
 
@@ -2677,9 +2744,8 @@ int osc_enqueue_interpret(const struct lu_env *env, struct ptlrpc_request *req,
        }
 
        /* Complete obtaining the lock procedure. */
-       rc = ldlm_cli_enqueue_fini(aa->oa_exp, req, aa->oa_type, 1,
-                                  aa->oa_mode, aa->oa_flags, lvb, lvb_len,
-                                  lockh, rc);
+       rc = ldlm_cli_enqueue_fini(aa->oa_exp, req, &einfo, 1, aa->oa_flags,
+                                  lvb, lvb_len, lockh, rc);
        /* Complete osc stuff. */
        rc = osc_enqueue_fini(req, aa->oa_upcall, aa->oa_cookie, lockh, mode,
                              aa->oa_flags, aa->oa_speculative, rc);
@@ -2784,23 +2850,6 @@ int osc_enqueue_base(struct obd_export *exp, struct ldlm_res_id *res_id,
        if (*flags & (LDLM_FL_TEST_LOCK | LDLM_FL_MATCH_LOCK))
                RETURN(-ENOLCK);
 
-       if (intent) {
-               req = ptlrpc_request_alloc(class_exp2cliimp(exp),
-                                          &RQF_LDLM_ENQUEUE_LVB);
-               if (req == NULL)
-                       RETURN(-ENOMEM);
-
-               rc = ldlm_prep_enqueue_req(exp, req, NULL, 0);
-               if (rc) {
-                        ptlrpc_request_free(req);
-                        RETURN(rc);
-                }
-
-                req_capsule_set_size(&req->rq_pill, &RMF_DLM_LVB, RCL_SERVER,
-                                     sizeof *lvb);
-                ptlrpc_request_set_replen(req);
-        }
-
         /* users of osc_enqueue() can pass this flag for ldlm_lock_match() */
         *flags &= ~LDLM_FL_BLOCK_GRANTED;
 
@@ -2830,16 +2879,12 @@ int osc_enqueue_base(struct obd_export *exp, struct ldlm_res_id *res_id,
 
                        req->rq_interpret_reply = osc_enqueue_interpret;
                        ptlrpc_set_add_req(rqset, req);
-               } else if (intent) {
-                       ptlrpc_req_finished(req);
                }
                RETURN(rc);
        }
 
        rc = osc_enqueue_fini(req, upcall, cookie, &lockh, einfo->ei_mode,
                              flags, speculative, rc);
-       if (intent)
-               ptlrpc_req_finished(req);
 
        RETURN(rc);
 }
@@ -2864,15 +2909,8 @@ int osc_match_base(const struct lu_env *env, struct obd_export *exp,
        policy->l_extent.end |= ~PAGE_MASK;
 
        /* Next, search for already existing extent locks that will cover us */
-       /* If we're trying to read, we also search for an existing PW lock.  The
-        * VFS and page cache already protect us locally, so lots of readers/
-         * writers can share a single PW lock. */
-       rc = mode;
-       if (mode == LCK_PR)
-               rc |= LCK_PW;
-
        rc = ldlm_lock_match_with_skip(obd->obd_namespace, lflags, 0,
-                                       res_id, type, policy, rc, lockh,
+                                       res_id, type, policy, mode, lockh,
                                        match_flags);
        if (rc == 0 || lflags & LDLM_FL_TEST_LOCK)
                RETURN(rc);
@@ -2996,19 +3034,17 @@ static int osc_statfs(const struct lu_env *env, struct obd_export *exp,
        struct obd_device     *obd = class_exp2obd(exp);
        struct obd_statfs     *msfs;
        struct ptlrpc_request *req;
-       struct obd_import     *imp = NULL;
+       struct obd_import     *imp, *imp0;
        int rc;
        ENTRY;
 
-
-        /*Since the request might also come from lprocfs, so we need
-         *sync this with client_disconnect_export Bug15684*/
-       down_read(&obd->u.cli.cl_sem);
-        if (obd->u.cli.cl_import)
-                imp = class_import_get(obd->u.cli.cl_import);
-       up_read(&obd->u.cli.cl_sem);
-        if (!imp)
-                RETURN(-ENODEV);
+       /*Since the request might also come from lprocfs, so we need
+        *sync this with client_disconnect_export Bug15684
+        */
+       with_imp_locked(obd, imp0, rc)
+               imp = class_import_get(imp0);
+       if (rc)
+               RETURN(rc);
 
        /* We could possibly pass max_age in the request (as an absolute
         * timestamp or a "seconds.usec ago") so the target can avoid doing
@@ -3578,21 +3614,28 @@ static const struct obd_ops osc_obd_ops = {
         .o_quotactl             = osc_quotactl,
 };
 
-static struct shrinker *osc_cache_shrinker;
 LIST_HEAD(osc_shrink_list);
 DEFINE_SPINLOCK(osc_shrink_lock);
 
-#ifndef HAVE_SHRINKER_COUNT
-static int osc_cache_shrink(SHRINKER_ARGS(sc, nr_to_scan, gfp_mask))
+#ifdef HAVE_SHRINKER_COUNT
+static struct shrinker osc_cache_shrinker = {
+       .count_objects  = osc_cache_shrink_count,
+       .scan_objects   = osc_cache_shrink_scan,
+       .seeks          = DEFAULT_SEEKS,
+};
+#else
+static int osc_cache_shrink(struct shrinker *shrinker,
+                           struct shrink_control *sc)
 {
-       struct shrink_control scv = {
-               .nr_to_scan = shrink_param(sc, nr_to_scan),
-               .gfp_mask   = shrink_param(sc, gfp_mask)
-       };
-       (void)osc_cache_shrink_scan(shrinker, &scv);
+       (void)osc_cache_shrink_scan(shrinker, sc);
 
-       return osc_cache_shrink_count(shrinker, &scv);
+       return osc_cache_shrink_count(shrinker, sc);
 }
+
+static struct shrinker osc_cache_shrinker = {
+       .shrink   = osc_cache_shrink,
+       .seeks    = DEFAULT_SEEKS,
+};
 #endif
 
 static int __init osc_init(void)
@@ -3600,8 +3643,6 @@ static int __init osc_init(void)
        unsigned int reqpool_size;
        unsigned int reqsize;
        int rc;
-       DEF_SHRINKER_VAR(osc_shvar, osc_cache_shrink,
-                        osc_cache_shrink_count, osc_cache_shrink_scan);
        ENTRY;
 
        /* print an address of _any_ initialized kernel symbol from this
@@ -3613,16 +3654,18 @@ static int __init osc_init(void)
        if (rc)
                RETURN(rc);
 
-       rc = class_register_type(&osc_obd_ops, NULL, true, NULL,
+       rc = class_register_type(&osc_obd_ops, NULL, true,
                                 LUSTRE_OSC_NAME, &osc_device_type);
        if (rc)
                GOTO(out_kmem, rc);
 
-       osc_cache_shrinker = set_shrinker(DEFAULT_SEEKS, &osc_shvar);
+       rc = register_shrinker(&osc_cache_shrinker);
+       if (rc)
+               GOTO(out_type, rc);
 
        /* This is obviously too much memory, only prevent overflow here */
        if (osc_reqpool_mem_max >= 1 << 12 || osc_reqpool_mem_max == 0)
-               GOTO(out_type, rc = -EINVAL);
+               GOTO(out_shrinker, rc = -EINVAL);
 
        reqpool_size = osc_reqpool_mem_max << 20;
 
@@ -3643,7 +3686,7 @@ static int __init osc_init(void)
                                          ptlrpc_add_rqs_to_pool);
 
        if (osc_rq_pool == NULL)
-               GOTO(out_type, rc = -ENOMEM);
+               GOTO(out_shrinker, rc = -ENOMEM);
 
        rc = osc_start_grant_work();
        if (rc != 0)
@@ -3653,6 +3696,8 @@ static int __init osc_init(void)
 
 out_req_pool:
        ptlrpc_free_rq_pool(osc_rq_pool);
+out_shrinker:
+       unregister_shrinker(&osc_cache_shrinker);
 out_type:
        class_unregister_type(LUSTRE_OSC_NAME);
 out_kmem:
@@ -3664,7 +3709,7 @@ out_kmem:
 static void __exit osc_exit(void)
 {
        osc_stop_grant_work();
-       remove_shrinker(osc_cache_shrinker);
+       unregister_shrinker(&osc_cache_shrinker);
        class_unregister_type(LUSTRE_OSC_NAME);
        lu_kmem_fini(osc_caches);
        ptlrpc_free_rq_pool(osc_rq_pool);