From: green Date: Sun, 14 Dec 2003 21:39:09 +0000 (+0000) Subject: r=shaver X-Git-Tag: 1.0.2~52 X-Git-Url: https://git.whamcloud.com/?a=commitdiff_plain;h=0bf18a0674b645cccee7848e13b7699dcb319daa;p=fs%2Flustre-release.git r=shaver fix for #2319, make osic to be allocated separately and implement proper refcounting for it. Also adds a test to sanity.sh that checks for (fixed) crash. --- diff --git a/lustre/include/linux/obd.h b/lustre/include/linux/obd.h index 8c85be5..2c5155e 100644 --- a/lustre/include/linux/obd.h +++ b/lustre/include/linux/obd.h @@ -111,6 +111,7 @@ struct obd_async_page_ops { struct obd_sync_io_container { spinlock_t osic_lock; + atomic_t osic_refcount; int osic_pending; int osic_rc; wait_queue_head_t osic_waitq; diff --git a/lustre/include/linux/obd_class.h b/lustre/include/linux/obd_class.h index b3a9769..da2dab9 100644 --- a/lustre/include/linux/obd_class.h +++ b/lustre/include/linux/obd_class.h @@ -66,9 +66,10 @@ struct obd_device * class_find_client_obd(struct obd_uuid *tgt_uuid, char * typ_name, struct obd_uuid *grp_uuid); -void osic_init(struct obd_sync_io_container *osic); +void osic_init(struct obd_sync_io_container **osic); void osic_add_one(struct obd_sync_io_container *osic); void osic_complete_one(struct obd_sync_io_container *osic, int rc); +void osic_release(struct obd_sync_io_container *osic); int osic_wait(struct obd_sync_io_container *osic); /* config.c */ diff --git a/lustre/liblustre/llite_lib.h b/lustre/liblustre/llite_lib.h index f258ec9..9e4340d 100644 --- a/lustre/liblustre/llite_lib.h +++ b/lustre/liblustre/llite_lib.h @@ -86,7 +86,7 @@ struct llu_inode_info { sizeof(struct page) * (x)) struct llu_sysio_cookie { - struct obd_sync_io_container lsc_osic; + struct obd_sync_io_container *lsc_osic; struct inode *lsc_inode; int lsc_npages; struct ll_async_page *lsc_llap; diff --git a/lustre/liblustre/rw.c b/lustre/liblustre/rw.c index 70fd26e..c05a7c9 100644 --- a/lustre/liblustre/rw.c +++ b/lustre/liblustre/rw.c @@ -466,6 +466,7 @@ void put_sysio_cookie(struct llu_sysio_cookie *cookie) I_RELE(cookie->lsc_inode); + osic_release(cookie->lsc_osic); OBD_FREE(cookie, LLU_SYSIO_COOKIE_SIZE(cookie->lsc_npages)); } @@ -525,7 +526,7 @@ int llu_prep_async_io(struct llu_sysio_cookie *cookie, int cmd, llap[i].llap_page = &pages[i]; llap[i].llap_inode = cookie->lsc_inode; - rc = obd_queue_sync_io(exp, lsm, NULL, &cookie->lsc_osic, + rc = obd_queue_sync_io(exp, lsm, NULL, cookie->lsc_osic, llap[i].llap_cookie, cmd, pages[i]._offset, pages[i]._count, 0); if (rc) @@ -543,7 +544,7 @@ int llu_start_async_io(struct llu_sysio_cookie *cookie) struct lov_stripe_md *lsm = llu_i2info(cookie->lsc_inode)->lli_smd; struct obd_export *exp = llu_i2obdexp(cookie->lsc_inode); - return obd_trigger_sync_io(exp, lsm, NULL, &cookie->lsc_osic); + return obd_trigger_sync_io(exp, lsm, NULL, cookie->lsc_osic); } /* @@ -783,7 +784,7 @@ int llu_iop_iodone(struct ioctx *ioctxp) for (i = 0; i < lsca->ncookies; i++) { cookie = lsca->cookies[i]; if (cookie) { - err = osic_wait(&cookie->lsc_osic); + err = osic_wait(cookie->lsc_osic); if (err && !rc) rc = err; if (!rc) diff --git a/lustre/llite/rw.c b/lustre/llite/rw.c index b8ff805..678c318 100644 --- a/lustre/llite/rw.c +++ b/lustre/llite/rw.c @@ -396,20 +396,22 @@ int ll_commit_write(struct file *file, struct page *page, unsigned from, rc = obd_queue_async_io(exp, lsm, NULL, llap->llap_cookie, OBD_BRW_WRITE, 0, 0, 0, 0); if (rc != 0) { /* async failed, try sync.. */ - struct obd_sync_io_container osic; + struct obd_sync_io_container *osic; osic_init(&osic); - rc = obd_queue_sync_io(exp, lsm, NULL, &osic, + rc = obd_queue_sync_io(exp, lsm, NULL, osic, llap->llap_cookie, OBD_BRW_WRITE, 0, to, 0); if (rc) - GOTO(out, rc); + GOTO(free_osic, rc); - rc = obd_trigger_sync_io(exp, lsm, NULL, &osic); + rc = obd_trigger_sync_io(exp, lsm, NULL, osic); if (rc) - GOTO(out, rc); + GOTO(free_osic, rc); - rc = osic_wait(&osic); + rc = osic_wait(osic); +free_osic: + osic_release(osic); GOTO(out, rc); } LL_CDEBUG_PAGE(page, "write queued\n"); diff --git a/lustre/obdclass/class_obd.c b/lustre/obdclass/class_obd.c index 3f72012..68f9442 100644 --- a/lustre/obdclass/class_obd.c +++ b/lustre/obdclass/class_obd.c @@ -575,6 +575,7 @@ EXPORT_SYMBOL(class_disconnect); EXPORT_SYMBOL(class_disconnect_exports); EXPORT_SYMBOL(osic_init); +EXPORT_SYMBOL(osic_release); EXPORT_SYMBOL(osic_add_one); EXPORT_SYMBOL(osic_wait); EXPORT_SYMBOL(osic_complete_one); diff --git a/lustre/obdclass/genops.c b/lustre/obdclass/genops.c index 12451d1..dc524cfa 100644 --- a/lustre/obdclass/genops.c +++ b/lustre/obdclass/genops.c @@ -622,14 +622,28 @@ void class_disconnect_exports(struct obd_device *obd, int flags) EXIT; } -void osic_init(struct obd_sync_io_container *osic) +void osic_init(struct obd_sync_io_container **osic_out) { + struct obd_sync_io_container *osic; + OBD_ALLOC(osic, sizeof(*osic)); spin_lock_init(&osic->osic_lock); osic->osic_rc = 0; osic->osic_pending = 0; + atomic_set(&osic->osic_refcount, 1); init_waitqueue_head(&osic->osic_waitq); + *osic_out = osic; }; +static inline void osic_grab(struct obd_sync_io_container *osic) +{ + atomic_inc(&osic->osic_refcount); +} +void osic_release(struct obd_sync_io_container *osic) +{ + if (atomic_dec_and_test(&osic->osic_refcount)) + OBD_FREE(osic, sizeof(*osic)); +} + void osic_add_one(struct obd_sync_io_container *osic) { unsigned long flags; @@ -637,6 +651,7 @@ void osic_add_one(struct obd_sync_io_container *osic) spin_lock_irqsave(&osic->osic_lock, flags); osic->osic_pending++; spin_unlock_irqrestore(&osic->osic_lock, flags); + osic_grab(osic); } void osic_complete_one(struct obd_sync_io_container *osic, int rc) @@ -657,6 +672,7 @@ void osic_complete_one(struct obd_sync_io_container *osic, int rc) osic->osic_pending); if (wake) wake_up(wake); + osic_release(osic); } static int osic_done(struct obd_sync_io_container *osic) diff --git a/lustre/tests/sanity.sh b/lustre/tests/sanity.sh index 87e1340..ed059e0 100644 --- a/lustre/tests/sanity.sh +++ b/lustre/tests/sanity.sh @@ -1604,6 +1604,24 @@ test_62() { } run_test 62 "verify obd_match failure doesn't LBUG (should -EIO)" +# bug 2319 - osic_wait() interrupted causes crash because of invalid waitq. +test_63() { + for i in /proc/fs/lustre/osc/*/max_dirty_mb ; do + echo 0 > $i + done + for i in `seq 10` ; do + dd if=/dev/zero of=$DIR/syncwrite_testfile bs=8k & + sleep 5 + kill $! + sleep 1 + done + + for i in /proc/fs/lustre/osc/*/max_dirty_mb ; do + echo $[ 60 * 1025 *1024 ] > $i + done +} +run_test 63 "Verify osic_wait interruption does not crash" + # on the LLNL clusters, runas will still pick up root's $TMP settings, # which will not be writable for the runas user, and then you get a CVS # error message with a corrupt path string (CVS bug) and panic.