Whamcloud - gitweb
fixes:
authorlsy <lsy>
Fri, 2 Sep 2005 13:31:46 +0000 (13:31 +0000)
committerlsy <lsy>
Fri, 2 Sep 2005 13:31:46 +0000 (13:31 +0000)
* 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
lustre/llite/llite_capa.c
lustre/mdc/mdc_request.c
lustre/mds/mds_capa.c
lustre/mds/mds_internal.h
lustre/mds/mds_open.c
lustre/obdclass/capa.c
lustre/obdfilter/filter_capa.c

index 56ca8f5..8805fc2 100644 (file)
@@ -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;
 }
index 3f670d8..e3ac909 100644 (file)
@@ -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);
 
index e69084f..0b9b880 100644 (file)
@@ -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);
 
index c7d0bda..06298e5 100644 (file)
@@ -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);
 
index d730ded..cb979af 100644 (file)
@@ -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);
index 8b7a9f5..1f0c4ee 100644 (file)
@@ -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);
index 7c98499..2dc1532 100644 (file)
@@ -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)
index bb81534..ce01be7 100644 (file)
@@ -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;