diff --git a/lustre/include/lustre_net.h b/lustre/include/lustre_net.h index 2391e80c577d3e85b65424c0d045ed218b78fefa..8543659c4e4012d8ba016cd79c0de73a661d4865 100644 --- a/lustre/include/lustre_net.h +++ b/lustre/include/lustre_net.h @@ -181,21 +181,16 @@ struct ptlrpc_request_set { cfs_waitq_t set_waitq; cfs_waitq_t *set_wakeup_ptr; struct list_head set_requests; - struct list_head set_cblist; /* list of completion callbacks */ set_interpreter_func set_interpret; /* completion callback */ void *set_arg; /* completion context */ + void *set_countp; /* pointer to NOB counter in case + * of directIO (bug11737) */ /* locked so that any old caller can communicate requests to * the set holder who can then fold them into the lock-free set */ spinlock_t set_new_req_lock; struct list_head set_new_requests; }; -struct ptlrpc_set_cbdata { - struct list_head psc_item; - set_interpreter_func psc_interpret; - void *psc_data; -}; - struct ptlrpc_bulk_desc; /* @@ -694,8 +689,6 @@ void ptlrpc_restart_req(struct ptlrpc_request *req); void ptlrpc_abort_inflight(struct obd_import *imp); struct ptlrpc_request_set *ptlrpc_prep_set(void); -int ptlrpc_set_add_cb(struct ptlrpc_request_set *set, - set_interpreter_func fn, void *data); int ptlrpc_set_next_timeout(struct ptlrpc_request_set *); int ptlrpc_check_set(struct ptlrpc_request_set *set); int ptlrpc_set_wait(struct ptlrpc_request_set *); diff --git a/lustre/include/obd_class.h b/lustre/include/obd_class.h index 19bf151fd070dae3ecab45407408db1a24225c8e..cfb217eab271236c5413867dbd2f70471ca21e4b 100644 --- a/lustre/include/obd_class.h +++ b/lustre/include/obd_class.h @@ -923,12 +923,15 @@ 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; @@ -937,6 +940,8 @@ 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/llite/rw26.c b/lustre/llite/rw26.c index 5ea3a6c0e87307d2ca66faddc89132f55384722b..d32a4472bb3807c53906b4f1b827a076c1362fef 100644 --- a/lustre/llite/rw26.c +++ b/lustre/llite/rw26.c @@ -133,14 +133,15 @@ static void ll_free_user_pages(struct page **pages, int npages, int do_dirty) static ssize_t ll_direct_IO_26_seg(int rw, struct inode *inode, struct address_space *mapping, - struct obd_info *oinfo, - struct ptlrpc_request_set *set, + struct lov_stripe_md *lsm, size_t size, loff_t file_offset, struct page **pages, int page_count) { struct brw_page *pga; + struct obdo oa; int i, rc = 0; size_t length; + loff_t file_offset_orig = file_offset; ENTRY; OBD_ALLOC(pga, sizeof(*pga) * page_count); @@ -162,11 +163,15 @@ static ssize_t ll_direct_IO_26_seg(int rw, struct inode *inode, POISON_PAGE(pages[i], 0x0d); } - rc = obd_brw_async(rw == WRITE ? OBD_BRW_WRITE : OBD_BRW_READ, - ll_i2obdexp(inode), oinfo, page_count, - pga, NULL, set); - if (rc == 0) - rc = size; + ll_inode_fill_obdo(inode, rw, &oa); + + rc = obd_brw_rqset(rw == WRITE ? OBD_BRW_WRITE : OBD_BRW_READ, + ll_i2obdexp(inode), &oa, lsm, page_count, pga, NULL); + if ((rc > 0) && (rw == WRITE)) { + lov_stripe_lock(lsm); + obd_adjust_kms(ll_i2obdexp(inode), lsm, file_offset_orig + rc, 0); + lov_stripe_unlock(lsm); + } OBD_FREE(pga, sizeof(*pga) * page_count); RETURN(rc); @@ -186,10 +191,6 @@ static ssize_t ll_direct_IO_26(int rw, struct kiocb *iocb, struct inode *inode = file->f_mapping->host; ssize_t count = iov_length(iov, nr_segs), tot_bytes = 0; struct ll_inode_info *lli = ll_i2info(inode); - struct lov_stripe_md *lsm = lli->lli_smd; - struct ptlrpc_request_set *set; - struct obd_info oinfo; - struct obdo oa; unsigned long seg; size_t size = MAX_DIO_SIZE; ENTRY; @@ -219,30 +220,10 @@ static ssize_t ll_direct_IO_26(int rw, struct kiocb *iocb, RETURN(-EINVAL); } - set = ptlrpc_prep_set(); - if (set == NULL) - RETURN(-ENOMEM); - - ll_inode_fill_obdo(inode, rw, &oa); - oinfo.oi_oa = &oa; - oinfo.oi_md = lsm; - - /* need locking between buffered and direct access. and race with - *size changing by concurrent truncates and writes. */ - if (rw == READ) - LOCK_INODE_MUTEX(inode); - for (seg = 0; seg < nr_segs; seg++) { size_t iov_left = iov[seg].iov_len; unsigned long user_addr = (unsigned long)iov[seg].iov_base; - if (rw == READ) { - if (file_offset >= inode->i_size) - break; - if (file_offset + iov_left > inode->i_size) - iov_left = inode->i_size - file_offset; - } - while (iov_left > 0) { struct page **pages; int page_count; @@ -255,7 +236,7 @@ static ssize_t ll_direct_IO_26(int rw, struct kiocb *iocb, if (page_count > 0) { result = ll_direct_IO_26_seg(rw, inode, file->f_mapping, - &oinfo, set, + lli->lli_smd, min(size,iov_left), file_offset, pages, page_count); @@ -280,8 +261,8 @@ static ssize_t ll_direct_IO_26(int rw, struct kiocb *iocb, continue; } if (tot_bytes > 0) - GOTO(wait_io, tot_bytes); - GOTO(out, tot_bytes = page_count < 0 ? page_count : result); + RETURN(tot_bytes); + RETURN(page_count < 0 ? page_count : result); } tot_bytes += result; @@ -290,24 +271,6 @@ static ssize_t ll_direct_IO_26(int rw, struct kiocb *iocb, user_addr += result; } } - - if (tot_bytes > 0) { - int rc; - wait_io: - rc = ptlrpc_set_wait(set); - if (rc) - GOTO(out, tot_bytes = rc); - if (rw == WRITE) { - lov_stripe_lock(lsm); - obd_adjust_kms(ll_i2obdexp(inode), lsm, file_offset, 0); - lov_stripe_unlock(lsm); - } - } -out: - if (rw == READ) - UNLOCK_INODE_MUTEX(inode); - - ptlrpc_set_destroy(set); RETURN(tot_bytes); } diff --git a/lustre/lov/lov_obd.c b/lustre/lov/lov_obd.c index 66c2ece7859acf8e68cb4bedf710c89aa51c2fbc..31569ca2168c4dd5a7048e16a0f4cb10922f91ae 100644 --- a/lustre/lov/lov_obd.c +++ b/lustre/lov/lov_obd.c @@ -1583,10 +1583,8 @@ static int lov_brw_async(int cmd, struct obd_export *exp, } LASSERT(rc == 0); LASSERT(set->set_interpret == NULL); - LASSERT(set->set_arg == NULL); - rc = ptlrpc_set_add_cb(set, lov_brw_interpret, lovset); - if (rc) - GOTO(out, rc); + set->set_interpret = (set_interpreter_func)lov_brw_interpret; + set->set_arg = (void *)lovset; RETURN(rc); out: diff --git a/lustre/osc/osc_request.c b/lustre/osc/osc_request.c index 955caa1b6a36f869e188a7fa5b01c9a7e4df44b5..381631cadffbb34876b79d97c3da31b9694073a9 100644 --- a/lustre/osc/osc_request.c +++ b/lustre/osc/osc_request.c @@ -1354,6 +1354,7 @@ static int brw_interpret(struct ptlrpc_request *request, void *data, int rc) { struct osc_brw_async_args *aa = data; int i; + int nob = rc; ENTRY; rc = osc_brw_fini_request(request, rc); @@ -1363,6 +1364,8 @@ 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 00a7f1949b33a1a644aa33a6b66ce5cb2752bceb..c182672cf12ab97791c53c8308e485f666351abe 100644 --- a/lustre/ptlrpc/client.c +++ b/lustre/ptlrpc/client.c @@ -573,8 +573,7 @@ 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); } @@ -633,23 +632,6 @@ 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) { @@ -1393,19 +1375,6 @@ 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 a769aa50605a2aea63898e2f4ae8a16c378a4f22..f427fbe0293f42fa93980e29be9e49f8e32d9118 100644 --- a/lustre/ptlrpc/ptlrpc_internal.h +++ b/lustre/ptlrpc/ptlrpc_internal.h @@ -35,7 +35,6 @@ 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 889aa2d3959a1c1b89fecfa742c4a8e1335fe6b3..66d51b9f8671dd84af0397fb359d6d5e133d48e0 100644 --- a/lustre/ptlrpc/ptlrpc_module.c +++ b/lustre/ptlrpc/ptlrpc_module.c @@ -38,7 +38,6 @@ #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; @@ -79,19 +78,10 @@ __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: @@ -111,7 +101,6 @@ static void __exit ptlrpc_exit(void) ptlrpc_stop_pinger(); ptlrpc_exit_portals(); ptlrpc_cleanup_connection(); - cfs_mem_cache_destroy(ptlrpc_cbdata_slab); } /* connection.c */ @@ -160,7 +149,6 @@ 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 1108cba9bdcf897aa3eb07d3329bb6e1146de7e4..ebcedb2c781063e69a3716234228b480efd27622 100644 --- a/lustre/tests/directio.c +++ b/lustre/tests/directio.c @@ -23,12 +23,11 @@ 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/readhole> file seek nr_blocks [blocksize]\n", argv[0]); + printf("Usage: %s <read/write/rdwr> file seek nr_blocks [blocksize]\n", argv[0]); return 1; } @@ -38,10 +37,7 @@ int main(int argc, char **argv) action = O_WRONLY; else if (!strcmp(argv[1], "rdwr")) action = O_RDWR; - else if (!strcmp(argv[1], "readhole")) { - action = O_RDONLY; - pad = 0; - } else { + else { printf("Usage: %s <read/write/rdwr> file seek nr_blocks [blocksize]\n", argv[0]); return 1; } @@ -78,7 +74,7 @@ int main(int argc, char **argv) printf("No memory %s\n", strerror(errno)); return 1; } - memset(wbuf, pad, len); + memset(wbuf, 0xba, 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 f397bd727d244669262acf1e9365ce7da2ea4811..ab063888d5b4bd76c23897981215b493c802c7de 100644 --- a/lustre/tests/sanity.sh +++ b/lustre/tests/sanity.sh @@ -4299,19 +4299,9 @@ 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_119c() # 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 119c "Testing for direct read hitting hole" - LDLM_POOL_CTL_RECALC=1 LDLM_POOL_CTL_SHRINK=2