diff --git a/lustre/include/obd_class.h b/lustre/include/obd_class.h index cfb217eab271236c5413867dbd2f70471ca21e4b..19bf151fd070dae3ecab45407408db1a24225c8e 100644 --- a/lustre/include/obd_class.h +++ b/lustre/include/obd_class.h @@ -923,15 +923,12 @@ static inline int obd_brw_rqset(int cmd, struct obd_export *exp, { struct ptlrpc_request_set *set = NULL; struct obd_info oinfo = { { { 0 } } }; - atomic_t nob; int rc = 0; ENTRY; set = ptlrpc_prep_set(); if (set == NULL) RETURN(-ENOMEM); - atomic_set(&nob, 0); - set->set_countp = &nob; oinfo.oi_oa = oa; oinfo.oi_md = lsm; @@ -940,8 +937,6 @@ static inline int obd_brw_rqset(int cmd, struct obd_export *exp, rc = ptlrpc_set_wait(set); if (rc) CERROR("error from callback: rc = %d\n", rc); - else - rc = atomic_read(&nob); } else { CDEBUG(rc == -ENOSPC ? D_INODE : D_ERROR, "error from obd_brw_async: rc = %d\n", rc); diff --git a/lustre/osc/osc_request.c b/lustre/osc/osc_request.c index 381631cadffbb34876b79d97c3da31b9694073a9..8f16dff6dd20e003814633e428b5f5cf0a302935 100644 --- a/lustre/osc/osc_request.c +++ b/lustre/osc/osc_request.c @@ -1364,8 +1364,6 @@ static int brw_interpret(struct ptlrpc_request *request, void *data, int rc) if (rc == 0) RETURN(0); } - if ((rc >= 0) && request->rq_set && request->rq_set->set_countp) - atomic_add(nob, (atomic_t *)request->rq_set->set_countp); client_obd_list_lock(&aa->aa_cli->cl_loi_list_lock); if (lustre_msg_get_opc(request->rq_reqmsg) == OST_WRITE) aa->aa_cli->cl_w_in_flight--; diff --git a/lustre/ptlrpc/client.c b/lustre/ptlrpc/client.c index c182672cf12ab97791c53c8308e485f666351abe..00a7f1949b33a1a644aa33a6b66ce5cb2752bceb 100644 --- a/lustre/ptlrpc/client.c +++ b/lustre/ptlrpc/client.c @@ -573,7 +573,8 @@ struct ptlrpc_request_set *ptlrpc_prep_set(void) set->set_remaining = 0; spin_lock_init(&set->set_new_req_lock); CFS_INIT_LIST_HEAD(&set->set_new_requests); - + CFS_INIT_LIST_HEAD(&set->set_cblist); + RETURN(set); } @@ -632,6 +633,23 @@ void ptlrpc_set_destroy(struct ptlrpc_request_set *set) EXIT; } +int ptlrpc_set_add_cb(struct ptlrpc_request_set *set, + set_interpreter_func fn, void *data) +{ + struct ptlrpc_set_cbdata *cbdata; + + OBD_SLAB_ALLOC(cbdata, ptlrpc_cbdata_slab, + CFS_ALLOC_STD, sizeof(*cbdata)); + if (cbdata == NULL) + RETURN(-ENOMEM); + + cbdata->psc_interpret = fn; + cbdata->psc_data = data; + list_add_tail(&cbdata->psc_item, &set->set_cblist); + + RETURN(0); +} + void ptlrpc_set_add_req(struct ptlrpc_request_set *set, struct ptlrpc_request *req) { @@ -1375,6 +1393,19 @@ int ptlrpc_set_wait(struct ptlrpc_request_set *set) int (*interpreter)(struct ptlrpc_request_set *set,void *,int) = set->set_interpret; rc = interpreter (set, set->set_arg, rc); + } else { + struct ptlrpc_set_cbdata *cbdata, *n; + int err; + + list_for_each_entry_safe(cbdata, n, + &set->set_cblist, psc_item) { + list_del_init(&cbdata->psc_item); + err = cbdata->psc_interpret(set, cbdata->psc_data, rc); + if (err && !rc) + rc = err; + OBD_SLAB_FREE(cbdata, ptlrpc_cbdata_slab, + sizeof(*cbdata)); + } } RETURN(rc); diff --git a/lustre/ptlrpc/ptlrpc_internal.h b/lustre/ptlrpc/ptlrpc_internal.h index f427fbe0293f42fa93980e29be9e49f8e32d9118..a769aa50605a2aea63898e2f4ae8a16c378a4f22 100644 --- a/lustre/ptlrpc/ptlrpc_internal.h +++ b/lustre/ptlrpc/ptlrpc_internal.h @@ -35,6 +35,7 @@ struct obd_import; struct ldlm_res_id; struct ptlrpc_request_set; extern int test_req_buffer_pressure; +extern cfs_mem_cache_t *ptlrpc_cbdata_slab; void ptlrpc_request_handle_notconn(struct ptlrpc_request *); void lustre_assert_wire_constants(void); diff --git a/lustre/ptlrpc/ptlrpc_module.c b/lustre/ptlrpc/ptlrpc_module.c index 66d51b9f8671dd84af0397fb359d6d5e133d48e0..889aa2d3959a1c1b89fecfa742c4a8e1335fe6b3 100644 --- a/lustre/ptlrpc/ptlrpc_module.c +++ b/lustre/ptlrpc/ptlrpc_module.c @@ -38,6 +38,7 @@ #include "ptlrpc_internal.h" +cfs_mem_cache_t *ptlrpc_cbdata_slab; extern spinlock_t ptlrpc_last_xid_lock; extern spinlock_t ptlrpc_rs_debug_lock; extern spinlock_t ptlrpc_all_services_lock; @@ -78,10 +79,19 @@ __init int ptlrpc_init(void) rc = ldlm_init(); if (rc) GOTO(cleanup, rc); + cleanup_phase = 4; + + ptlrpc_cbdata_slab = cfs_mem_cache_create("ptlrpc_cbdatas", + sizeof (struct ptlrpc_set_cbdata), 0, + SLAB_HWCACHE_ALIGN); + if (ptlrpc_cbdata_slab == NULL) + GOTO(cleanup, rc); RETURN(0); cleanup: switch(cleanup_phase) { + case 4: + ldlm_exit(); case 3: ptlrpc_stop_pinger(); case 2: @@ -101,6 +111,7 @@ static void __exit ptlrpc_exit(void) ptlrpc_stop_pinger(); ptlrpc_exit_portals(); ptlrpc_cleanup_connection(); + cfs_mem_cache_destroy(ptlrpc_cbdata_slab); } /* connection.c */ @@ -149,6 +160,7 @@ EXPORT_SYMBOL(ptlrpc_retain_replayable_request); EXPORT_SYMBOL(ptlrpc_next_xid); EXPORT_SYMBOL(ptlrpc_prep_set); +EXPORT_SYMBOL(ptlrpc_set_add_cb); EXPORT_SYMBOL(ptlrpc_set_add_req); EXPORT_SYMBOL(ptlrpc_set_add_new_req); EXPORT_SYMBOL(ptlrpc_set_destroy); diff --git a/lustre/tests/directio.c b/lustre/tests/directio.c index ebcedb2c781063e69a3716234228b480efd27622..1108cba9bdcf897aa3eb07d3329bb6e1146de7e4 100644 --- a/lustre/tests/directio.c +++ b/lustre/tests/directio.c @@ -23,11 +23,12 @@ int main(int argc, char **argv) long len; off64_t seek; struct stat64 st; + char pad = 0xba; int action; int rc; if (argc < 5 || argc > 6) { - printf("Usage: %s <read/write/rdwr> file seek nr_blocks [blocksize]\n", argv[0]); + printf("Usage: %s <read/write/rdwr/readhole> file seek nr_blocks [blocksize]\n", argv[0]); return 1; } @@ -37,7 +38,10 @@ int main(int argc, char **argv) action = O_WRONLY; else if (!strcmp(argv[1], "rdwr")) action = O_RDWR; - else { + else if (!strcmp(argv[1], "readhole")) { + action = O_RDONLY; + pad = 0; + } else { printf("Usage: %s <read/write/rdwr> file seek nr_blocks [blocksize]\n", argv[0]); return 1; } @@ -74,7 +78,7 @@ int main(int argc, char **argv) printf("No memory %s\n", strerror(errno)); return 1; } - memset(wbuf, 0xba, len); + memset(wbuf, pad, len); if (action == O_WRONLY || action == O_RDWR) { if (lseek64(fd, seek, SEEK_SET) < 0) { diff --git a/lustre/tests/sanity.sh b/lustre/tests/sanity.sh index ab063888d5b4bd76c23897981215b493c802c7de..391af95d56cecc37e3e24e24ef1cc504c153fa32 100644 --- a/lustre/tests/sanity.sh +++ b/lustre/tests/sanity.sh @@ -4299,9 +4299,19 @@ test_119b() # bug 11737 sync multiop $DIR/$tfile oO_RDONLY:O_DIRECT:r$((2048 * 1024)) || \ error "direct read failed" + rm -f $DIR/$tfile } run_test 119b "Sparse directIO read must return actual read amount" +test_119b() # bug 13099 +{ + BSIZE=1048576 + directio write $DIR/$tfile 3 1 $BSIZE || error "direct write failed" + directio readhole $DIR/$tfile 0 2 $BSIZE || error "reading hole failed" + rm -f $DIR/$tfile +} +run_test 119b "Testing for direct read hitting hole" + LDLM_POOL_CTL_RECALC=1 LDLM_POOL_CTL_SHRINK=2