Whamcloud - gitweb
LU-904 ptlrpc: redo io on -EINPROGRESS
[fs/lustre-release.git] / lustre / obdfilter / filter_io_26.c
index cc0d72c..cafb080 100644 (file)
@@ -29,8 +29,7 @@
  * Copyright (c) 2003, 2010, Oracle and/or its affiliates. All rights reserved.
  * Use is subject to license terms.
  *
- * Copyright (c) 2011 Whamcloud, Inc.
- *
+ * Copyright (c) 2011, 2012, Whamcloud, Inc.
  */
 /*
  * This file is part of Lustre, http://www.lustre.org/
@@ -484,7 +483,7 @@ int filter_direct_io(int rw, struct dentry *dchild, struct filter_iobuf *iobuf,
         struct inode *inode = dchild->d_inode;
         int blocks_per_page = CFS_PAGE_SIZE >> inode->i_blkbits;
         int rc, rc2, create;
-        cfs_semaphore_t *sem;
+        cfs_mutex_t *mutex;
         ENTRY;
 
         LASSERTF(iobuf->dr_npages <= iobuf->dr_max_pages, "%d,%d\n",
@@ -495,12 +494,12 @@ int filter_direct_io(int rw, struct dentry *dchild, struct filter_iobuf *iobuf,
                 if (iobuf->dr_npages == 0)
                         RETURN(0);
                 create = 0;
-                sem = NULL;
+                mutex = NULL;
         } else {
                 LASSERTF(rw == OBD_BRW_WRITE, "%x\n", rw);
                 LASSERT(iobuf->dr_npages > 0);
                 create = 1;
-                sem = &obd->u.filter.fo_alloc_lock;
+                mutex = &obd->u.filter.fo_alloc_lock;
 
                 lquota_enforce(filter_quota_interface_ref, obd,
                                iobuf->dr_ignore_quota);
@@ -512,7 +511,7 @@ int filter_direct_io(int rw, struct dentry *dchild, struct filter_iobuf *iobuf,
         } else {
                 rc = fsfilt_map_inode_pages(obd, inode, iobuf->dr_pages,
                                     iobuf->dr_npages, iobuf->dr_blocks,
-                                    obdfilter_created_scratchpad, create, sem);
+                                    obdfilter_created_scratchpad, create, mutex);
         }
 
         if (rw == OBD_BRW_WRITE) {
@@ -694,10 +693,12 @@ int filter_commitrw_write(struct obd_export *exp, struct obdo *oa,
         if (rc == -ENOTCONN)
                 GOTO(cleanup, rc);
 
+        if (OBD_FAIL_CHECK(OBD_FAIL_OST_DQACQ_NET))
+                GOTO(cleanup, rc = -EINPROGRESS);
+
         push_ctxt(&saved, &obd->obd_lvfs_ctxt, NULL);
         cleanup_phase = 2;
 
-        ll_vfs_dq_init(inode);
         fsfilt_check_slow(obd, now, "quota init");
 
 retry:
@@ -717,6 +718,9 @@ retry:
 
         fsfilt_check_slow(obd, now, "brw_start");
 
+        /* Locking order: i_mutex -> journal_lock -> dqptr_sem. LU-952 */
+        ll_vfs_dq_init(inode);
+
         i = OBD_MD_FLATIME | OBD_MD_FLMTIME | OBD_MD_FLCTIME;
 
         /* If the inode still has SUID+SGID bits set (see filter_precreate())
@@ -767,8 +771,8 @@ retry:
                 goto retry;
         }
 
-        obdo_from_inode(oa, inode, NULL, rc == 0 ? FILTER_VALID_FLAGS : 0 |
-                                                   OBD_MD_FLUID |OBD_MD_FLGID);
+        obdo_from_inode(oa, inode, (rc == 0 ? FILTER_VALID_FLAGS : 0) |
+                                   OBD_MD_FLUID | OBD_MD_FLGID);
 
         lquota_getflag(filter_quota_interface_ref, obd, oa);