Whamcloud - gitweb
LU-5261 osc: use wait_for_completion_killable() instead
[fs/lustre-release.git] / lustre / osc / osc_io.c
index a9bad93..0070308 100644 (file)
@@ -67,14 +67,18 @@ static struct osc_io *cl2osc_io(const struct lu_env *env,
         return oio;
 }
 
-static struct osc_page *osc_cl_page_osc(struct cl_page *page)
+static struct osc_page *osc_cl_page_osc(struct cl_page *page,
+                                       struct osc_object *osc)
 {
-        const struct cl_page_slice *slice;
+       const struct cl_page_slice *slice;
 
-        slice = cl_page_at(page, &osc_device_type);
-        LASSERT(slice != NULL);
+       if (osc != NULL)
+               slice = cl_object_page_slice(&osc->oo_cl, page);
+       else
+               slice = cl_page_at(page, &osc_device_type);
+       LASSERT(slice != NULL);
 
-        return cl2osc_page(slice);
+       return cl2osc_page(slice);
 }
 
 
@@ -99,13 +103,13 @@ static int osc_io_submit(const struct lu_env *env,
                          const struct cl_io_slice *ios,
                         enum cl_req_type crt, struct cl_2queue *queue)
 {
-        struct cl_page    *page;
-        struct cl_page    *tmp;
-        struct client_obd *cli  = NULL;
-        struct osc_object *osc  = NULL; /* to keep gcc happy */
-        struct osc_page   *opg;
-        struct cl_io      *io;
-       CFS_LIST_HEAD     (list);
+       struct cl_page    *page;
+       struct cl_page    *tmp;
+       struct client_obd *cli  = NULL;
+       struct osc_object *osc  = NULL; /* to keep gcc happy */
+       struct osc_page   *opg;
+       struct cl_io      *io;
+       struct list_head  list = LIST_HEAD_INIT(list);
 
        struct cl_page_list *qin      = &queue->c2_qin;
        struct cl_page_list *qout     = &queue->c2_qout;
@@ -137,12 +141,12 @@ static int osc_io_submit(const struct lu_env *env,
                 io = page->cp_owner;
                 LASSERT(io != NULL);
 
-                opg = osc_cl_page_osc(page);
-                oap = &opg->ops_oap;
+               opg = osc_cl_page_osc(page, osc);
+               oap = &opg->ops_oap;
                LASSERT(osc == oap->oap_obj);
 
-               if (!cfs_list_empty(&oap->oap_pending_item) ||
-                   !cfs_list_empty(&oap->oap_rpc_item)) {
+               if (!list_empty(&oap->oap_pending_item) ||
+                   !list_empty(&oap->oap_rpc_item)) {
                        CDEBUG(D_CACHE, "Busy oap %p page %p for submit.\n",
                               oap, opg);
                         result = -EBUSY;
@@ -163,14 +167,19 @@ static int osc_io_submit(const struct lu_env *env,
                        continue;
                 }
 
-               cl_page_list_move(qout, qin, page);
                spin_lock(&oap->oap_lock);
                oap->oap_async_flags = ASYNC_URGENT|ASYNC_READY;
                oap->oap_async_flags |= ASYNC_COUNT_STABLE;
                spin_unlock(&oap->oap_lock);
 
                osc_page_submit(env, opg, crt, brw_flags);
-               cfs_list_add_tail(&oap->oap_pending_item, &list);
+               list_add_tail(&oap->oap_pending_item, &list);
+
+               if (page->cp_sync_io != NULL)
+                       cl_page_list_move(qout, qin, page);
+               else /* async IO */
+                       cl_page_list_del(env, qin, page);
+
                if (++queued == max_pages) {
                        queued = 0;
                        result = osc_queue_sync_pages(env, osc, &list, cmd,
@@ -261,18 +270,14 @@ static int osc_io_commit_async(const struct lu_env *env,
                }
        }
 
-       /*
-        * NOTE: here @page is a top-level page. This is done to avoid
-        * creation of sub-page-list.
-        */
        while (qin->pl_nr > 0) {
                struct osc_async_page *oap;
 
                page = cl_page_list_first(qin);
-               opg = osc_cl_page_osc(page);
+               opg = osc_cl_page_osc(page, osc);
                oap = &opg->ops_oap;
 
-               if (!cfs_list_empty(&oap->oap_rpc_item)) {
+               if (!list_empty(&oap->oap_rpc_item)) {
                        CDEBUG(D_CACHE, "Busy oap %p page %p for submit.\n",
                               oap, opg);
                        result = -EBUSY;
@@ -280,14 +285,13 @@ static int osc_io_commit_async(const struct lu_env *env,
                }
 
                /* The page may be already in dirty cache. */
-               if (cfs_list_empty(&oap->oap_pending_item)) {
+               if (list_empty(&oap->oap_pending_item)) {
                        result = osc_page_cache_add(env, &opg->ops_cl, io);
                        if (result != 0)
                                break;
                }
 
-               osc_page_touch_at(env, osc2cl(osc),
-                                 opg->ops_cl.cpl_page->cp_index,
+               osc_page_touch_at(env, osc2cl(osc), osc_index(opg),
                                  page == last_page ? to : PAGE_SIZE);
 
                cl_page_list_del(env, qin, page);
@@ -332,15 +336,15 @@ static int osc_io_rw_iter_init(const struct lu_env *env,
        if (npages > max_pages)
                npages = max_pages;
 
-       c = cfs_atomic_read(cli->cl_lru_left);
+       c = atomic_read(cli->cl_lru_left);
        if (c < npages && osc_lru_reclaim(cli) > 0)
-               c = cfs_atomic_read(cli->cl_lru_left);
+               c = atomic_read(cli->cl_lru_left);
        while (c >= npages) {
-               if (c == cfs_atomic_cmpxchg(cli->cl_lru_left, c, c - npages)) {
+               if (c == atomic_cmpxchg(cli->cl_lru_left, c, c - npages)) {
                        oio->oi_lru_reserved = npages;
                        break;
                }
-               c = cfs_atomic_read(cli->cl_lru_left);
+               c = atomic_read(cli->cl_lru_left);
        }
 
        RETURN(0);
@@ -354,7 +358,7 @@ static void osc_io_rw_iter_fini(const struct lu_env *env,
        struct client_obd *cli = osc_cli(osc);
 
        if (oio->oi_lru_reserved > 0) {
-               cfs_atomic_add(oio->oi_lru_reserved, cli->cl_lru_left);
+               atomic_add(oio->oi_lru_reserved, cli->cl_lru_left);
                oio->oi_lru_reserved = 0;
        }
 }
@@ -404,18 +408,14 @@ static int trunc_check_cb(const struct lu_env *env, struct cl_io *io,
 
        oap = &ops->ops_oap;
        if (oap->oap_cmd & OBD_BRW_WRITE &&
-           !cfs_list_empty(&oap->oap_pending_item))
+           !list_empty(&oap->oap_pending_item))
                CL_PAGE_DEBUG(D_ERROR, env, page, "exists " LPU64 "/%s.\n",
                                start, current->comm);
 
 #ifdef __linux__
-       {
-               struct page *vmpage = cl_page_vmpage(env, page);
-               if (PageLocked(vmpage))
-                       CDEBUG(D_CACHE, "page %p index %lu locked for %d.\n",
-                              ops, page->cp_index,
-                              (oap->oap_cmd & OBD_BRW_RWMASK));
-       }
+       if (PageLocked(page->cp_vmpage))
+               CDEBUG(D_CACHE, "page %p index %lu locked for %d.\n",
+                      ops, osc_index(ops), oap->oap_cmd & OBD_BRW_RWMASK);
 #endif
 
        return CLP_GANG_OKAY;
@@ -542,8 +542,10 @@ static void osc_io_setattr_end(const struct lu_env *env,
         int result = 0;
 
        if (cbargs->opc_rpc_sent) {
-               wait_for_completion(&cbargs->opc_sync);
-               result = io->ci_result = cbargs->opc_rc;
+               result = wait_for_completion_killable(&cbargs->opc_sync);
+               if (result == 0)
+                       result = cbargs->opc_rc;
+               io->ci_result = result;
        }
         if (result == 0) {
                 if (oio->oi_lockless) {
@@ -569,13 +571,12 @@ static void osc_io_setattr_end(const struct lu_env *env,
 static int osc_io_read_start(const struct lu_env *env,
                              const struct cl_io_slice *slice)
 {
-       struct osc_io    *oio  = cl2osc_io(env, slice);
        struct cl_object *obj  = slice->cis_obj;
        struct cl_attr   *attr = &osc_env_info(env)->oti_attr;
        int rc = 0;
        ENTRY;
 
-       if (oio->oi_lockless == 0 && !slice->cis_io->ci_noatime) {
+       if (!slice->cis_io->ci_noatime) {
                cl_object_attr_lock(obj);
                attr->cat_atime = LTIME_S(CFS_CURRENT_TIME);
                rc = cl_object_attr_set(env, obj, attr, CAT_ATIME);
@@ -588,25 +589,18 @@ static int osc_io_read_start(const struct lu_env *env,
 static int osc_io_write_start(const struct lu_env *env,
                               const struct cl_io_slice *slice)
 {
-        struct osc_io    *oio   = cl2osc_io(env, slice);
-        struct cl_object *obj   = slice->cis_obj;
-        struct cl_attr   *attr  = &osc_env_info(env)->oti_attr;
-        int              result = 0;
-        ENTRY;
+       struct cl_object *obj   = slice->cis_obj;
+       struct cl_attr   *attr  = &osc_env_info(env)->oti_attr;
+       int rc = 0;
+       ENTRY;
 
-        if (oio->oi_lockless == 0) {
-               OBD_FAIL_TIMEOUT(OBD_FAIL_OSC_DELAY_SETTIME, 1);
-                cl_object_attr_lock(obj);
-                result = cl_object_attr_get(env, obj, attr);
-                if (result == 0) {
-                        attr->cat_mtime = attr->cat_ctime =
-                                LTIME_S(CFS_CURRENT_TIME);
-                        result = cl_object_attr_set(env, obj, attr,
-                                                    CAT_MTIME | CAT_CTIME);
-                }
-                cl_object_attr_unlock(obj);
-        }
-        RETURN(result);
+       OBD_FAIL_TIMEOUT(OBD_FAIL_OSC_DELAY_SETTIME, 1);
+       cl_object_attr_lock(obj);
+       attr->cat_mtime = attr->cat_ctime = LTIME_S(CFS_CURRENT_TIME);
+       rc = cl_object_attr_set(env, obj, attr, CAT_MTIME | CAT_CTIME);
+       cl_object_attr_unlock(obj);
+
+       RETURN(rc);
 }
 
 static int osc_fsync_ost(const struct lu_env *env, struct osc_object *obj,
@@ -696,7 +690,7 @@ static void osc_io_fsync_end(const struct lu_env *env,
                struct osc_io           *oio    = cl2osc_io(env, slice);
                struct osc_async_cbargs *cbargs = &oio->oi_cbarg;
 
-               wait_for_completion(&cbargs->opc_sync);
+               result = wait_for_completion_killable(&cbargs->opc_sync);
                if (result == 0)
                        result = cbargs->opc_rc;
        }
@@ -814,20 +808,23 @@ static void osc_req_attr_set(const struct lu_env *env,
                oa->o_valid |= OBD_MD_FLID;
        }
        if (flags & OBD_MD_FLHANDLE) {
-                clerq = slice->crs_req;
-                LASSERT(!cfs_list_empty(&clerq->crq_pages));
-                apage = container_of(clerq->crq_pages.next,
-                                     struct cl_page, cp_flight);
-                opg = osc_cl_page_osc(apage);
-                apage = opg->ops_cl.cpl_page; /* now apage is a sub-page */
-                lock = cl_lock_at_page(env, apage->cp_obj, apage, NULL, 1, 1);
-                if (lock == NULL) {
-                        struct cl_object_header *head;
-                        struct cl_lock          *scan;
-
-                        head = cl_object_header(apage->cp_obj);
-                        cfs_list_for_each_entry(scan, &head->coh_locks,
-                                                cll_linkage)
+               struct cl_object *subobj;
+
+               clerq = slice->crs_req;
+               LASSERT(!list_empty(&clerq->crq_pages));
+               apage = container_of(clerq->crq_pages.next,
+                                    struct cl_page, cp_flight);
+               opg = osc_cl_page_osc(apage, NULL);
+               subobj = opg->ops_cl.cpl_obj;
+               lock = cl_lock_at_pgoff(env, subobj, osc_index(opg),
+                                       NULL, 1, 1);
+               if (lock == NULL) {
+                       struct cl_object_header *head;
+                       struct cl_lock          *scan;
+
+                       head = cl_object_header(subobj);
+                       list_for_each_entry(scan, &head->coh_locks,
+                                           cll_linkage)
                                 CL_LOCK_DEBUG(D_ERROR, env, scan,
                                               "no cover page!\n");
                         CL_PAGE_DEBUG(D_ERROR, env, apage,
@@ -866,18 +863,18 @@ int osc_io_init(const struct lu_env *env,
 }
 
 int osc_req_init(const struct lu_env *env, struct cl_device *dev,
-                 struct cl_req *req)
+                struct cl_req *req)
 {
-        struct osc_req *or;
-        int result;
-
-       OBD_SLAB_ALLOC_PTR_GFP(or, osc_req_kmem, __GFP_IO);
-        if (or != NULL) {
-                cl_req_slice_add(req, &or->or_cl, dev, &osc_req_ops);
-                result = 0;
-        } else
-                result = -ENOMEM;
-        return result;
+       struct osc_req *or;
+       int result;
+
+       OBD_SLAB_ALLOC_PTR_GFP(or, osc_req_kmem, GFP_NOFS);
+       if (or != NULL) {
+               cl_req_slice_add(req, &or->or_cl, dev, &osc_req_ops);
+               result = 0;
+       } else
+               result = -ENOMEM;
+       return result;
 }
 
 /** @} osc */