Whamcloud - gitweb
LU-2744 build: fix race issues thanks to oap_lock
[fs/lustre-release.git] / lustre / osc / osc_io.c
index a94ac61..bf93df5 100644 (file)
@@ -27,7 +27,7 @@
  * Copyright (c) 2008, 2010, Oracle and/or its affiliates. All rights reserved.
  * Use is subject to license terms.
  *
- * Copyright (c) 2011, Whamcloud, Inc.
+ * Copyright (c) 2011, 2013, Intel Corporation.
  */
 /*
  * This file is part of Lustre, http://www.lustre.org/
@@ -99,7 +99,6 @@ 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 obd_export *exp;
         struct cl_page    *page;
         struct cl_page    *tmp;
         struct client_obd *cli  = NULL;
@@ -121,7 +120,6 @@ static int osc_io_submit(const struct lu_env *env,
        CDEBUG(D_CACHE, "%d %d\n", qin->pl_nr, crt);
 
        osc = cl2osc(ios->cis_obj);
-       exp = osc_export(osc);
        cli = osc_cli(osc);
        max_pages = cli->cl_max_pages_per_rpc;
 
@@ -166,8 +164,10 @@ static int osc_io_submit(const struct lu_env *env,
                 }
 
                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);
@@ -339,7 +339,7 @@ static int osc_async_upcall(void *a, int rc)
        struct osc_async_cbargs *args = a;
 
         args->opc_rc = rc;
-        cfs_complete(&args->opc_sync);
+       complete(&args->opc_sync);
         return 0;
 }
 
@@ -367,7 +367,7 @@ static int trunc_check_cb(const struct lu_env *env, struct cl_io *io,
 
 #ifdef __linux__
        {
-               cfs_page_t *vmpage = cl_page_vmpage(env, page);
+               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,
@@ -451,13 +451,12 @@ static int osc_io_setattr_start(const struct lu_env *env,
         }
         memset(oa, 0, sizeof(*oa));
         if (result == 0) {
-                oa->o_id = loi->loi_id;
-                oa->o_seq = loi->loi_seq;
-                oa->o_mtime = attr->cat_mtime;
-                oa->o_atime = attr->cat_atime;
-                oa->o_ctime = attr->cat_ctime;
-                oa->o_valid = OBD_MD_FLID | OBD_MD_FLGROUP | OBD_MD_FLATIME |
-                        OBD_MD_FLCTIME | OBD_MD_FLMTIME;
+               oa->o_oi = loi->loi_oi;
+               oa->o_mtime = attr->cat_mtime;
+               oa->o_atime = attr->cat_atime;
+               oa->o_ctime = attr->cat_ctime;
+               oa->o_valid = OBD_MD_FLID | OBD_MD_FLGROUP | OBD_MD_FLATIME |
+                       OBD_MD_FLCTIME | OBD_MD_FLMTIME;
                 if (ia_valid & ATTR_SIZE) {
                         oa->o_size = size;
                         oa->o_blocks = OBD_OBJECT_EOF;
@@ -473,7 +472,7 @@ static int osc_io_setattr_start(const struct lu_env *env,
 
                 oinfo.oi_oa = oa;
                 oinfo.oi_capa = io->u.ci_setattr.sa_capa;
-                cfs_init_completion(&cbargs->opc_sync);
+               init_completion(&cbargs->opc_sync);
 
                 if (ia_valid & ATTR_SIZE)
                         result = osc_punch_base(osc_export(cl2osc(obj)),
@@ -484,6 +483,7 @@ static int osc_io_setattr_start(const struct lu_env *env,
                                                         &oinfo, NULL,
                                                        osc_async_upcall,
                                                         cbargs, PTLRPCD_SET);
+               cbargs->opc_rpc_sent = result == 0;
         }
         return result;
 }
@@ -495,11 +495,12 @@ static void osc_io_setattr_end(const struct lu_env *env,
        struct osc_io    *oio = cl2osc_io(env, slice);
        struct cl_object *obj = slice->cis_obj;
        struct osc_async_cbargs *cbargs = &oio->oi_cbarg;
-        int result;
-
-        cfs_wait_for_completion(&cbargs->opc_sync);
+        int result = 0;
 
-        result = io->ci_result = cbargs->opc_rc;
+       if (cbargs->opc_rpc_sent) {
+               wait_for_completion(&cbargs->opc_sync);
+               result = io->ci_result = cbargs->opc_rc;
+       }
         if (result == 0) {
                 if (oio->oi_lockless) {
                         /* lockless truncate */
@@ -524,23 +525,20 @@ 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              result = 0;
-        ENTRY;
+       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) {
-                cl_object_attr_lock(obj);
-                result = cl_object_attr_get(env, obj, attr);
-                if (result == 0) {
-                        attr->cat_atime = LTIME_S(CFS_CURRENT_TIME);
-                        result = cl_object_attr_set(env, obj, attr,
-                                                    CAT_ATIME);
-                }
-                cl_object_attr_unlock(obj);
-        }
-        RETURN(result);
+       if (oio->oi_lockless == 0 && !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);
+               cl_object_attr_unlock(obj);
+       }
+
+       RETURN(rc);
 }
 
 static int osc_io_write_start(const struct lu_env *env,
@@ -553,6 +551,7 @@ static int osc_io_write_start(const struct lu_env *env,
         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) {
@@ -578,8 +577,7 @@ static int osc_fsync_ost(const struct lu_env *env, struct osc_object *obj,
        ENTRY;
 
        memset(oa, 0, sizeof(*oa));
-       oa->o_id = loi->loi_id;
-       oa->o_seq = loi->loi_seq;
+       oa->o_oi = loi->loi_oi;
        oa->o_valid = OBD_MD_FLID | OBD_MD_FLGROUP;
 
        /* reload size abd blocks for start and end of sync range */
@@ -592,7 +590,7 @@ static int osc_fsync_ost(const struct lu_env *env, struct osc_object *obj,
        memset(oinfo, 0, sizeof(*oinfo));
        oinfo->oi_oa = oa;
        oinfo->oi_capa = fio->fi_capa;
-       cfs_init_completion(&cbargs->opc_sync);
+       init_completion(&cbargs->opc_sync);
 
        rc = osc_sync_base(osc_export(obj), oinfo, osc_async_upcall, cbargs,
                           PTLRPCD_SET);
@@ -654,7 +652,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;
 
-               cfs_wait_for_completion(&cbargs->opc_sync);
+               wait_for_completion(&cbargs->opc_sync);
                if (result == 0)
                        result = cbargs->opc_rc;
        }
@@ -740,29 +738,44 @@ static void osc_req_completion(const struct lu_env *env,
  * fields.
  */
 static void osc_req_attr_set(const struct lu_env *env,
-                             const struct cl_req_slice *slice,
-                             const struct cl_object *obj,
-                             struct cl_req_attr *attr, obd_valid flags)
+                            const struct cl_req_slice *slice,
+                            const struct cl_object *obj,
+                            struct cl_req_attr *attr, obd_valid flags)
 {
-        struct lov_oinfo *oinfo;
-        struct cl_req    *clerq;
-        struct cl_page   *apage; /* _some_ page in @clerq */
-        struct cl_lock   *lock;  /* _some_ lock protecting @apage */
-        struct osc_lock  *olck;
-        struct osc_page  *opg;
-        struct obdo      *oa;
-
-        oa = attr->cra_oa;
-        oinfo = cl2osc(obj)->oo_oinfo;
-        if (flags & OBD_MD_FLID) {
-                oa->o_id = oinfo->loi_id;
-                oa->o_valid |= OBD_MD_FLID;
-        }
-        if (flags & OBD_MD_FLGROUP) {
-                oa->o_seq = oinfo->loi_seq;
-                oa->o_valid |= OBD_MD_FLGROUP;
-        }
-        if (flags & OBD_MD_FLHANDLE) {
+       struct lov_oinfo *oinfo;
+       struct cl_req    *clerq;
+       struct cl_page   *apage; /* _some_ page in @clerq */
+       struct cl_lock   *lock;  /* _some_ lock protecting @apage */
+       struct osc_lock  *olck;
+       struct osc_page  *opg;
+       struct obdo      *oa;
+       struct ost_lvb   *lvb;
+
+       oinfo   = cl2osc(obj)->oo_oinfo;
+       lvb     = &oinfo->loi_lvb;
+       oa      = attr->cra_oa;
+
+       if ((flags & OBD_MD_FLMTIME) != 0) {
+               oa->o_mtime = lvb->lvb_mtime;
+               oa->o_valid |= OBD_MD_FLMTIME;
+       }
+       if ((flags & OBD_MD_FLATIME) != 0) {
+               oa->o_atime = lvb->lvb_atime;
+               oa->o_valid |= OBD_MD_FLATIME;
+       }
+       if ((flags & OBD_MD_FLCTIME) != 0) {
+               oa->o_ctime = lvb->lvb_ctime;
+               oa->o_valid |= OBD_MD_FLCTIME;
+       }
+       if (flags & OBD_MD_FLGROUP) {
+               ostid_set_seq(&oa->o_oi, ostid_seq(&oinfo->loi_oi));
+               oa->o_valid |= OBD_MD_FLGROUP;
+       }
+       if (flags & OBD_MD_FLID) {
+               ostid_set_id(&oa->o_oi, ostid_id(&oinfo->loi_oi));
+               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,
@@ -820,7 +833,7 @@ int osc_req_init(const struct lu_env *env, struct cl_device *dev,
         struct osc_req *or;
         int result;
 
-        OBD_SLAB_ALLOC_PTR_GFP(or, osc_req_kmem, CFS_ALLOC_IO);
+       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;