From 3504d6033118805dcde9e8287ff8e8ef3338e3e5 Mon Sep 17 00:00:00 2001 From: lsy Date: Fri, 2 Sep 2005 13:31:46 +0000 Subject: [PATCH] fixes: * also round for short expiry, in case timer might miss. * add mds_mfd_put() because mds_handle2mfd() will add ref. * filter_verify_capa() logic error. --- lustre/include/linux/lustre_sec.h | 23 +++++++++------- lustre/llite/llite_capa.c | 56 ++++++++++++++++++++++++--------------- lustre/mdc/mdc_request.c | 6 +++-- lustre/mds/mds_capa.c | 6 +++-- lustre/mds/mds_internal.h | 1 + lustre/mds/mds_open.c | 2 +- lustre/obdclass/capa.c | 9 ++++--- lustre/obdfilter/filter_capa.c | 14 +++++++--- 8 files changed, 74 insertions(+), 43 deletions(-) diff --git a/lustre/include/linux/lustre_sec.h b/lustre/include/linux/lustre_sec.h index 56ca8f5..8805fc2 100644 --- a/lustre/include/linux/lustre_sec.h +++ b/lustre/include/linux/lustre_sec.h @@ -514,8 +514,8 @@ int svcsec_null_exit(void); #define CAPA_HMAC_ALG "sha1" /* capa ops */ -#define CAPA_READ MAY_READ /* 2 */ -#define CAPA_WRITE MAY_WRITE /* 4 */ +#define CAPA_WRITE MAY_WRITE /* 2 */ +#define CAPA_READ MAY_READ /* 4 */ #define CAPA_TRUNC 8 struct lustre_capa_data { @@ -619,31 +619,36 @@ int capa_is_to_expire(struct obd_capa *ocapa); #define CAPA_EXPIRY (1UL << CAPA_EXPIRY_SHIFT) #define CAPA_EXPIRY_MASK (~(CAPA_EXPIRY-1)) -#define CAPA_PRE_EXPIRY_NOROUND 3 /* sec */ +#define CAPA_PRE_EXPIRY_SHORT 3 /* sec */ #define CAPA_PRE_EXPIRY 300 /* sec */ /* struct lustre_capa.lc_flags */ -#define CAPA_FL_NOROUND 0x001 /* capa expiry not rounded */ +#define CAPA_FL_SHORT 0x001 /* short capa expiry */ #define CAPA_FL_REMUID 0x002 /* remote uid */ -#define CAPA_FL_TRUNC 0x004 /* truncate capa, this kind of capa won't be renewed */ static inline unsigned long capa_pre_expiry(struct lustre_capa *capa) { - return (capa->lc_flags & CAPA_FL_NOROUND) ? - CAPA_PRE_EXPIRY_NOROUND : CAPA_PRE_EXPIRY; + return (capa->lc_flags & CAPA_FL_SHORT) ? + CAPA_PRE_EXPIRY_SHORT : CAPA_PRE_EXPIRY; } static inline __u64 round_expiry(__u32 timeout) { struct timeval tv; + int capa_expiry = CAPA_EXPIRY; + int mask = CAPA_EXPIRY_MASK; __u64 expiry; do_gettimeofday(&tv); expiry = tv.tv_sec + timeout; - if (timeout > CAPA_EXPIRY) - expiry = (expiry + CAPA_EXPIRY - 1) & CAPA_EXPIRY_MASK; + if (timeout < CAPA_EXPIRY) { + capa_expiry = 64; + mask = ~63; + } + + expiry = (expiry + capa_expiry - 1) & mask; return expiry; } diff --git a/lustre/llite/llite_capa.c b/lustre/llite/llite_capa.c index 3f670d8..e3ac909 100644 --- a/lustre/llite/llite_capa.c +++ b/lustre/llite/llite_capa.c @@ -43,6 +43,7 @@ static struct thread_ctl { static inline int have_expired_capa(void) { struct obd_capa *ocapa; + struct lustre_capa *capa; int expired = 0; unsigned long expiry; ENTRY; @@ -50,14 +51,18 @@ static inline int have_expired_capa(void) spin_lock(&capa_lock); if (!list_empty(ll_capa_list)) { ocapa = list_entry(ll_capa_list->next, struct obd_capa, c_list); - expired = __capa_is_to_expire(ocapa); - if (!expired && !timer_pending(&ll_capa_timer)) { - /* the expired capa has been put, so set the timer to - * the expired of the next capa */ - expiry = expiry_to_jiffies(ocapa->c_capa.lc_expiry); - mod_timer(&ll_capa_timer, expiry); - CDEBUG(D_INFO, "ll_capa_timer new expiry: %lu\n", expiry); + + if (!expired) { + capa = &ocapa->c_capa; + expiry = expiry_to_jiffies(capa->lc_expiry - + capa_pre_expiry(capa)); + if (time_before(expiry, ll_capa_timer.expires) || + !timer_pending(&ll_capa_timer)) { + mod_timer(&ll_capa_timer, expiry); + CDEBUG(D_INFO,"ll_capa_timer new expiry: %lu\n", + expiry); + } } } spin_unlock(&capa_lock); @@ -81,13 +86,8 @@ static int ll_renew_capa(struct obd_capa *ocapa) int rc; ENTRY; - if (capa_expired(&ocapa->c_capa)) { - /* this is the second time try to renew since the last - * renewal failed, it means on one is openning it and - * should be put now. */ - capa_put(ocapa); - RETURN(0); - } + if (capa_expired(&ocapa->c_capa)) + RETURN(-ESTALE); rc = md_getattr(md_exp, &lli->lli_id, valid, NULL, NULL, 0, 0, ocapa, &req); @@ -98,6 +98,7 @@ static int ll_capa_thread(void *arg) { struct thread_ctl *ctl = arg; unsigned long flags; + int rc; ENTRY; { @@ -120,7 +121,7 @@ static int ll_capa_thread(void *arg) while (1) { struct l_wait_info lwi = { 0 }; - struct obd_capa *ocapa, *next = NULL, tcapa; + struct obd_capa *ocapa, *tmp, *next = NULL, tcapa; unsigned long expiry, sleep = CAPA_PRE_EXPIRY; l_wait_event(capa_thread.t_ctl_waitq, @@ -131,7 +132,10 @@ static int ll_capa_thread(void *arg) break; spin_lock(&capa_lock); - list_for_each_entry(ocapa, ll_capa_list, c_list) { + list_for_each_entry_safe(ocapa, tmp, ll_capa_list, c_list) { + if (ocapa->c_capa.lc_flags & CAPA_FL_SHORT) + sleep = CAPA_PRE_EXPIRY_SHORT; + if (ocapa->c_capa.lc_op == CAPA_TRUNC) continue; @@ -140,7 +144,9 @@ static int ll_capa_thread(void *arg) tcapa = *ocapa; spin_unlock(&capa_lock); - ll_renew_capa(&tcapa); + rc = ll_renew_capa(&tcapa); + if (rc) + capa_put(ocapa); spin_lock(&capa_lock); } else { @@ -148,12 +154,18 @@ static int ll_capa_thread(void *arg) break; } } + if (next) { - expiry = expiry_to_jiffies(next->c_capa.lc_expiry); - mod_timer(&ll_capa_timer, expiry); - CDEBUG(D_INFO, "ll_capa_timer new expiry: %lu\n", expiry); - if (next->c_capa.lc_flags & CAPA_FL_NOROUND) - sleep = CAPA_PRE_EXPIRY_NOROUND; + struct lustre_capa *capa = &next->c_capa; + + expiry = expiry_to_jiffies(capa->lc_expiry - + capa_pre_expiry(capa)); + if (time_before(expiry, ll_capa_timer.expires) || + !timer_pending(&ll_capa_timer)) { + mod_timer(&ll_capa_timer, expiry); + CDEBUG(D_INFO,"ll_capa_timer new expiry: %lu\n", + expiry); + } } spin_unlock(&capa_lock); diff --git a/lustre/mdc/mdc_request.c b/lustre/mdc/mdc_request.c index e69084f..0b9b880 100644 --- a/lustre/mdc/mdc_request.c +++ b/lustre/mdc/mdc_request.c @@ -112,7 +112,7 @@ mdc_interpret_getattr(struct ptlrpc_request *req, void *unused, int rc) ENTRY; if (rc) { - DEBUG_REQ(D_WARNING, req, + DEBUG_REQ(D_INFO, req, "async getattr failed: rc = %d", rc); RETURN(rc); } @@ -141,10 +141,12 @@ mdc_interpret_getattr(struct ptlrpc_request *req, void *unused, int rc) spin_lock(&capa_lock); expiry = expiry_to_jiffies(capa->lc_expiry - capa_pre_expiry(capa)); + CDEBUG(D_INFO, "expiry %lu vs timer %lu, base %p\n", + expiry, ll_capa_timer.expires, ll_capa_timer.base); if (time_before(expiry, ll_capa_timer.expires) || !timer_pending(&ll_capa_timer)) { mod_timer(&ll_capa_timer, expiry); - CDEBUG(D_INFO, "ll_capa_timer new timer: %lu\n", expiry); + CDEBUG(D_INFO, "ll_capa_timer new expiry: %lu\n", expiry); } spin_unlock(&capa_lock); diff --git a/lustre/mds/mds_capa.c b/lustre/mds/mds_capa.c index c7d0bda..06298e5 100644 --- a/lustre/mds/mds_capa.c +++ b/lustre/mds/mds_capa.c @@ -497,7 +497,7 @@ int mds_pack_capa(struct obd_device *obd, struct mds_export_data *med, mfd = mds_handle2mfd(&req_body->handle); if (mfd == NULL) { - DEBUG_CAPA(D_WARNING, req_capa, "no handle "LPX64" for", + DEBUG_CAPA(D_INFO, req_capa, "no handle "LPX64" for", req_body->handle.cookie); RETURN(-ESTALE); } @@ -508,6 +508,8 @@ int mds_pack_capa(struct obd_device *obd, struct mds_export_data *med, mode); RETURN(-EACCES); } + + mds_mfd_put(mfd); } LASSERT(repmsg->buflens[*offset] == sizeof(*capa)); @@ -533,7 +535,7 @@ int mds_pack_capa(struct obd_device *obd, struct mds_export_data *med, capa->lc_keyid = le32_to_cpu(CUR_CAPA_KEY_ID(mds)); capa->lc_expiry = round_expiry(mds->mds_capa_timeout); if (mds->mds_capa_timeout < CAPA_EXPIRY) - capa->lc_flags |= CAPA_FL_NOROUND; + capa->lc_flags |= CAPA_FL_SHORT; memcpy(key, CUR_CAPA_KEY(mds)->lk_key, sizeof(key)); spin_unlock(&mds_capa_lock); diff --git a/lustre/mds/mds_internal.h b/lustre/mds/mds_internal.h index d730ded..cb979af 100644 --- a/lustre/mds/mds_internal.h +++ b/lustre/mds/mds_internal.h @@ -200,6 +200,7 @@ int mds_mfd_close(struct ptlrpc_request *req, int offset, int mds_close(struct ptlrpc_request *req, int offset); int mds_done_writing(struct ptlrpc_request *req, int offset); struct mds_file_data *mds_handle2mfd(struct lustre_handle *handle); +void mds_mfd_put(struct mds_file_data *mfd); int mds_validate_size(struct obd_device *obd, struct inode *inode, struct mds_body *body, struct iattr *iattr); int accmode(int flags); diff --git a/lustre/mds/mds_open.c b/lustre/mds/mds_open.c index 8b7a9f5..1f0c4ee 100644 --- a/lustre/mds/mds_open.c +++ b/lustre/mds/mds_open.c @@ -94,7 +94,7 @@ struct mds_file_data *mds_handle2mfd(struct lustre_handle *handle) RETURN(class_handle2object(handle->cookie)); } -static void mds_mfd_put(struct mds_file_data *mfd) +void mds_mfd_put(struct mds_file_data *mfd) { CDEBUG(D_INFO, "PUTting mfd %p : new refcount %d\n", mfd, atomic_read(&mfd->mfd_refcount) - 1); diff --git a/lustre/obdclass/capa.c b/lustre/obdclass/capa.c index 7c98499..2dc1532 100644 --- a/lustre/obdclass/capa.c +++ b/lustre/obdclass/capa.c @@ -215,7 +215,7 @@ static inline void list_add_capa(struct obd_capa *ocapa, struct list_head *head) } } - list_add_tail(&ocapa->c_list, head); + list_add(&ocapa->c_list, head); } static inline void do_update_capa(struct obd_capa *ocapa, struct lustre_capa *capa) @@ -367,7 +367,7 @@ int capa_expired(struct lustre_capa *capa) struct timeval tv; do_gettimeofday(&tv); - return (capa->lc_expiry < tv.tv_sec) ? 1 : 0; + return ((unsigned long )capa->lc_expiry <= tv.tv_sec) ? 1 : 0; } int __capa_is_to_expire(struct obd_capa *ocapa) @@ -376,7 +376,10 @@ int __capa_is_to_expire(struct obd_capa *ocapa) int pre_expiry = capa_pre_expiry(&ocapa->c_capa); do_gettimeofday(&tv); - return (ocapa->c_capa.lc_expiry - pre_expiry - 1 <= tv.tv_sec)? 1 : 0; + /* XXX: in case the lock is inaccurate, minus one more + * pre_expiry to make sure the expiry won't miss */ + return ((unsigned long)ocapa->c_capa.lc_expiry - + 2 * pre_expiry <= tv.tv_sec)? 1 : 0; } int capa_is_to_expire(struct obd_capa *ocapa) diff --git a/lustre/obdfilter/filter_capa.c b/lustre/obdfilter/filter_capa.c index bb81534..ce01be7 100644 --- a/lustre/obdfilter/filter_capa.c +++ b/lustre/obdfilter/filter_capa.c @@ -254,9 +254,14 @@ verify: rc = memcmp(capa->lc_hmac, ocapa->c_bhmac, sizeof(capa->lc_hmac)); } else { - /* ocapa is obsolete */ - capa_put(ocapa); - spin_unlock(&filter->fo_capa_lock); + /* ocapa is obsolete too */ + ocapa->c_bvalid = 0; + goto new_capa; + } + + if (rc && __capa_is_to_expire(ocapa)) { + /* client should use new expiry now */ + ocapa->c_bvalid = 0; goto new_capa; } spin_unlock(&filter->fo_capa_lock); @@ -265,8 +270,8 @@ verify: RETURN(rc ? -EACCES : 0); } -new_capa: spin_lock(&filter->fo_capa_lock); +new_capa: list_for_each_entry(tmp, &filter->fo_capa_keys, k_list) { if (tmp->k_key.lk_mdsid == capa->lc_mdsid) { if (rkey == NULL) @@ -313,6 +318,7 @@ new_capa: spin_lock(&filter->fo_capa_lock); memcpy(ocapa->c_bhmac, tcapa.lc_hmac, sizeof(ocapa->c_bhmac)); + ocapa->c_bvalid = 1; spin_unlock(&filter->fo_capa_lock); } goto verify; -- 1.8.3.1