Whamcloud - gitweb
several fixes: expiry timer adjusted.
authorlsy <lsy>
Fri, 19 Aug 2005 07:29:33 +0000 (07:29 +0000)
committerlsy <lsy>
Fri, 19 Aug 2005 07:29:33 +0000 (07:29 +0000)
add support for ost-authorization-revocation and fid verification.

29 files changed:
lustre/cmobd/cm_oss_reint.c
lustre/cobd/cache_obd.c
lustre/include/linux/lustre_idl.h
lustre/include/linux/lustre_sec.h
lustre/include/linux/obd.h
lustre/include/linux/obd_class.h
lustre/liblustre/super.c
lustre/llite/llite_capa.c
lustre/llite/llite_lib.c
lustre/lov/lov_obd.c
lustre/mdc/mdc_request.c
lustre/mds/handler.c
lustre/mds/lproc_mds.c
lustre/mds/mds_capa.c
lustre/mds/mds_fs.c
lustre/mds/mds_internal.h
lustre/mds/mds_lib.c
lustre/mds/mds_open.c
lustre/mds/mds_reint.c
lustre/obdclass/capa.c
lustre/obdecho/echo.c
lustre/obdecho/echo_client.c
lustre/obdfilter/filter.c
lustre/obdfilter/filter_capa.c
lustre/obdfilter/filter_internal.h
lustre/obdfilter/filter_io.c
lustre/osc/osc_request.c
lustre/ost/ost_handler.c
lustre/utils/wiretest.c

index 348e182..4e4e630 100644 (file)
@@ -91,7 +91,7 @@ static int cmobd_setattr_reint(struct obd_device *obd, void *rec)
         if (rc)
                 GOTO(out, rc);
 
-        rc = obd_setattr(exp, oa, lsm, NULL);
+        rc = obd_setattr(exp, oa, lsm, NULL, NULL);
 
         cmobd_free_lsm(&lsm);
 out:
index 65aad33..073ff70 100644 (file)
@@ -712,7 +712,8 @@ static int cobd_dt_getattr_async(struct obd_export *exp,
 
 static int cobd_dt_setattr(struct obd_export *exp, struct obdo *obdo,
                            struct lov_stripe_md *ea,
-                           struct obd_trans_info *oti)
+                           struct obd_trans_info *oti,
+                           struct lustre_capa *capa)
 {
         struct obd_device *obd = class_exp2obd(exp);
         struct obd_export *cobd_exp;
@@ -725,7 +726,7 @@ static int cobd_dt_setattr(struct obd_export *exp, struct obdo *obdo,
                 RETURN(-EINVAL);
         }
         cobd_exp = cobd_get_exp(obd);
-        rc = obd_setattr(cobd_exp, obdo, ea, oti);
+        rc = obd_setattr(cobd_exp, obdo, ea, oti, capa);
         RETURN(rc);
 }
 
index 81835c7..67a1784 100644 (file)
@@ -1043,11 +1043,12 @@ struct ptlbd_rsp {
 
 extern void lustre_swab_ptlbd_rsp (struct ptlbd_rsp *r);
 
-#define CAPA_KEY_LEN           16
-#define CAPA_DIGEST_SIZE       16
+#define CAPA_KEY_LEN           20 /* SHA1_DIGEST_LENGTH */
+#define CAPA_DIGEST_SIZE       20 /* SHA1_DIGEST_LENGTH */
 
 struct lustre_capa {
-        __u32   lc_uid;       /* uid */
+        __u32   lc_uid;       /* uid, mapped uid */
+        __u32   lc_ruid;      /* remote uid on client */
         __u32   lc_op;        /* operations allowed */
         __u64   lc_ino;       /* inode# */
         __u32   lc_mdsid;     /* mds# */
index eea64ab..723f76a 100644 (file)
@@ -526,8 +526,10 @@ struct client_capa {
         struct inode             *inode;      /* this should be always valid
                                                * if c_refc > 0 */
         struct lustre_handle      handle;     /* handle of mds_file_data */
+#if 0   /* TODO: support multi mount point */
         struct list_head         *list;       /* the capa list belong to this client */
         struct timer_list        *timer;      /* timer belong to this client */
+#endif
 };
 
 struct filter_capa {
@@ -562,6 +564,29 @@ enum lustre_capa_type {
         FILTER_CAPA = 2,
 };
 
+#define DEBUG_CAPA(level, capa, fmt, args...)                                  \
+do {                                                                           \
+CDEBUG(level, fmt " capa@%p uid %u op %u ino "LPU64" mdsid %d keyid %d "       \
+       "expiry "LPU64" flags %u\n",                                            \
+       ##args, capa, (capa)->lc_uid, (capa)->lc_op, (capa)->lc_ino,            \
+       (capa)->lc_mdsid, (capa)->lc_keyid, (capa)->lc_expiry,                  \
+       (capa)->lc_flags);                                                      \
+} while (0)
+
+#define DEBUG_CAPA_KEY(level, key, fmt, args...)                               \
+do {                                                                           \
+CDEBUG(level, fmt " capa key@%p mdsid %d keyid %d expiry "LPU64"\n",           \
+       ##args, key, (key)->lk_mdsid, (key)->lk_keyid, (key)->lk_expiry);       \
+} while (0)
+
+#define DEBUG_MDS_CAPA_KEY(level, mkey, fmt, args...)                          \
+do {                                                                           \
+CDEBUG(level, fmt " capa key@%p mdsid %d keyid %d expiry "LPU64"\n",           \
+       ##args, mkey, le32_to_cpu((mkey)->k_key->lk_mdsid),                     \
+       le32_to_cpu((mkey)->k_key->lk_keyid),                                   \
+       le64_to_cpu((mkey)->k_key->lk_expiry));                                 \
+} while (0)
+
 extern spinlock_t capa_lock;
 extern struct hlist_head *capa_hash;
 extern struct list_head capa_list[];
@@ -592,6 +617,7 @@ int capa_is_to_expire(struct obd_capa *ocapa);
 
 /* struct lustre_capa.lc_flags */
 #define CAPA_FL_NOROUND   0x001 /* capa expiry not rounded */
+#define CAPA_FL_REMUID    0x002 /* remote uid */
 
 static inline unsigned long capa_pre_expiry(struct lustre_capa *capa)
 {
@@ -617,7 +643,7 @@ round_expiry(__u32 timeout)
 static inline int
 capa_key_cmp(struct lustre_capa_key *k1, struct lustre_capa_key *k2)
 {
-        return le32_to_cpu(k1->lk_keyid) - le32_to_cpu(k2->lk_keyid);
+        return k1->lk_keyid - k2->lk_keyid;
 }
 
 static inline unsigned long
@@ -625,9 +651,11 @@ expiry_to_jiffies(__u64 expiry)
 {
         /* sec -> jiffies */
         struct timeval tv;
+        unsigned long timeout;
 
         do_gettimeofday(&tv);
-        return jiffies + ((unsigned long)expiry - tv.tv_sec) * HZ;
+        timeout = jiffies + ((unsigned long)expiry - tv.tv_sec) * HZ;
+        return timeout;
 }
 
 struct mds_capa_key {
index 12569d5..1a9071e 100644 (file)
@@ -849,7 +849,8 @@ struct obd_ops {
         int (*o_destroy)(struct obd_export *exp, struct obdo *oa,
                          struct lov_stripe_md *ea, struct obd_trans_info *oti);
         int (*o_setattr)(struct obd_export *exp, struct obdo *oa,
-                         struct lov_stripe_md *ea, struct obd_trans_info *oti);
+                         struct lov_stripe_md *ea, struct obd_trans_info *oti,
+                         struct lustre_capa *capa);
         int (*o_getattr)(struct obd_export *exp, struct obdo *oa,
                          struct lov_stripe_md *ea);
         int (*o_getattr_async)(struct obd_export *exp, struct obdo *oa,
index e956380..ffa3727 100644 (file)
@@ -553,7 +553,8 @@ static inline int obd_getattr_async(struct obd_export *exp,
 
 static inline int obd_setattr(struct obd_export *exp, struct obdo *obdo,
                               struct lov_stripe_md *ea,
-                              struct obd_trans_info *oti)
+                              struct obd_trans_info *oti,
+                              struct lustre_capa *capa)
 {
         int rc;
         ENTRY;
@@ -561,7 +562,7 @@ static inline int obd_setattr(struct obd_export *exp, struct obdo *obdo,
         EXP_CHECK_OP(exp, setattr);
         OBD_COUNTER_INCREMENT(exp->exp_obd, setattr);
 
-        rc = OBP(exp->exp_obd, setattr)(exp, obdo, ea, oti);
+        rc = OBP(exp->exp_obd, setattr)(exp, obdo, ea, oti, capa);
         RETURN(rc);
 }
 static inline int obd_add_conn(struct obd_import *imp, struct obd_uuid *uuid,
index 3ac318b..1215f38 100644 (file)
@@ -783,7 +783,7 @@ int llu_setattr_raw(struct inode *inode, struct iattr *attr)
                 oa.o_valid = OBD_MD_FLID;
                 obdo_from_inode(&oa, inode, OBD_MD_FLTYPE | OBD_MD_FLATIME |
                                             OBD_MD_FLMTIME | OBD_MD_FLCTIME);
-                rc = obd_setattr(sbi->ll_dt_exp, &oa, lsm, NULL);
+                rc = obd_setattr(sbi->ll_dt_exp, &oa, lsm, NULL, NULL);
                 if (rc)
                         CERROR("obd_setattr fails: rc=%d\n", rc);
         }
index 4bebb59..a19ac2f 100644 (file)
@@ -43,6 +43,7 @@ static inline int have_expired_capa(void)
 {
         struct obd_capa *ocapa;
         int expired = 0;
+        unsigned long expiry;
         ENTRY;
 
         spin_lock(&capa_lock);
@@ -50,6 +51,13 @@ static inline int have_expired_capa(void)
                 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);
+                }
         }
         spin_unlock(&capa_lock);
 
@@ -108,7 +116,7 @@ static int ll_capa_thread_main(void *arg)
         while (1) {
                 struct l_wait_info lwi = { 0 };
                 struct obd_capa *ocapa, *next = NULL;
-                int sleep = CAPA_PRE_EXPIRY;
+                unsigned long expiry, sleep = CAPA_PRE_EXPIRY;
 
                 l_wait_event(ll_capa_thread.t_ctl_waitq,
                              (have_expired_capa() || ll_capa_check_stop()),
@@ -130,8 +138,9 @@ static int ll_capa_thread_main(void *arg)
                         }
                 }
                 if (next) {
-                        mod_timer(&ll_capa_timer,
-                                  expiry_to_jiffies(next->c_capa.lc_expiry));
+                        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;
                 }
@@ -222,10 +231,18 @@ int ll_set_och_capa(struct inode *inode, struct lookup_intent *it,
         if (!och->och_capa)
                 rc = -ENOMEM;
 
+        DEBUG_CAPA(D_INFO, capa, "ll_set_och_capa");
+
         expiry = expiry_to_jiffies(capa->lc_expiry - capa_pre_expiry(capa));
+
+        spin_lock(&capa_lock);
         if (time_before(expiry, ll_capa_timer.expires) ||
-            !timer_pending(&ll_capa_timer))
+            !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);
 
         RETURN(rc);
 }
+
index 8c625cd..e2267ff 100644 (file)
@@ -1326,6 +1326,7 @@ int ll_setattr_raw(struct inode *inode, struct iattr *attr)
                                         OBD_FREE(lli->lli_trunc_capa,
                                                  sizeof(*trunc_capa));
                                 lli->lli_trunc_capa = trunc_capa;
+                                DEBUG_CAPA(D_INFO, trunc_capa, "truncate");
                         }
                         spin_unlock(&lli->lli_lock);
                 }
@@ -1449,7 +1450,7 @@ int ll_setattr_raw(struct inode *inode, struct iattr *attr)
 
                 obdo_from_inode(oa, inode, OBD_MD_FLTYPE | OBD_MD_FLATIME |
                                 OBD_MD_FLMTIME | OBD_MD_FLCTIME);
-                rc = obd_setattr(sbi->ll_dt_exp, oa, lsm, NULL);
+                rc = obd_setattr(sbi->ll_dt_exp, oa, lsm, NULL, NULL);
                 obdo_free(oa);
                 if (rc)
                         CERROR("obd_setattr fails: rc = %d\n", rc);
@@ -2303,7 +2304,7 @@ int ll_iocontrol(struct inode *inode, struct file *file,
                 oa->o_valid = OBD_MD_FLID | OBD_MD_FLFLAGS | OBD_MD_FLGROUP 
                               | OBD_MD_FLIFID;
 
-                rc = obd_setattr(sbi->ll_dt_exp, oa, lsm, NULL);
+                rc = obd_setattr(sbi->ll_dt_exp, oa, lsm, NULL, NULL);
                 obdo_free(oa);
                 if (rc) {
                         if (rc != -EPERM && rc != -EACCES)
index e79f1c0..e41219d 100644 (file)
@@ -995,7 +995,8 @@ out:
 }
 
 static int lov_setattr(struct obd_export *exp, struct obdo *src_oa,
-                       struct lov_stripe_md *lsm, struct obd_trans_info *oti)
+                       struct lov_stripe_md *lsm, struct obd_trans_info *oti,
+                       struct lustre_capa *capa)
 {
         struct lov_request_set *set;
         struct lov_obd *lov;
@@ -1028,7 +1029,7 @@ static int lov_setattr(struct obd_export *exp, struct obdo *src_oa,
                 req = list_entry(pos, struct lov_request, rq_link);
                 
                 rc = obd_setattr(lov->tgts[req->rq_idx].ltd_exp, req->rq_oa,
-                                 NULL, NULL);
+                                 NULL, NULL, NULL);
                 err = lov_update_common_set(set, req, rc);
                 if (err) {
                         CERROR("error: setattr objid "LPX64" subobj "
index 3154f93..0783b35 100644 (file)
@@ -138,10 +138,16 @@ mdc_interpret_getattr(struct ptlrpc_request *req, void *unused, int rc)
         if (rc)
                 RETURN(rc);
 
+        DEBUG_CAPA(D_INFO, capa, "capa renewal");
+
+        spin_lock(&capa_lock);
         expiry = expiry_to_jiffies(capa->lc_expiry - capa_pre_expiry(capa));
         if (time_before(expiry, ll_capa_timer.expires) ||
-            !timer_pending(&ll_capa_timer))
+            !timer_pending(&ll_capa_timer)) {
                 mod_timer(&ll_capa_timer, expiry);
+                CDEBUG(D_INFO, "ll_capa_timer new timer: %lu\n", expiry);
+        }
+        spin_unlock(&capa_lock);
 
         RETURN(rc);
 }
@@ -151,7 +157,7 @@ int mdc_getattr_async(struct obd_export *exp, struct ptlrpc_request *req)
         int repsize[2] = {sizeof(struct mds_body), sizeof(struct lustre_capa)};
         ENTRY;
 
-        req->rq_replen = lustre_msg_size(1, repsize);
+        req->rq_replen = lustre_msg_size(2, repsize);
         req->rq_interpret_reply = mdc_interpret_getattr;
         ptlrpcd_add_req(req);
 
index 044d84b..bea8ec7 100644 (file)
@@ -1270,7 +1270,7 @@ static int mds_getattr_internal(struct obd_device *obd, struct dentry *dentry,
                 }
 
                 offset = reply_off + 1;
-                rc = mds_pack_capa(obd, reqbody, req_capa, req->rq_repmsg,
+                rc = mds_pack_capa(obd, med, reqbody, req_capa, req,
                                    &offset, body);
         }
 
@@ -3331,8 +3331,6 @@ int mds_handle(struct ptlrpc_request *req)
 
         LASSERT(current->journal_info == NULL);
 
-        EXIT;
-
         /* If we're DISCONNECTing, the mds_export_data is already freed */
         if (!rc && req->rq_reqmsg->opc != MDS_DISCONNECT) {
                 struct mds_export_data *med = &req->rq_export->exp_mds_data;
@@ -3357,7 +3355,7 @@ int mds_handle(struct ptlrpc_request *req)
 
 
         target_send_reply(req, rc, fail);
-        return 0;
+        RETURN(0);
 }
 
 /* Update the server data on disk.  This stores the new mount_count and also the
index 1122d8a..1386670 100644 (file)
@@ -153,7 +153,7 @@ static int lprocfs_wr_capa(struct file *file, const char *buffer,
         if (rc)
                 return rc;
 
-        obd->u.mds.mds_capa_stat = val;
+        mds_update_capa_stat(obd, val);
         return count;
 }
 
@@ -177,7 +177,7 @@ static int lprocfs_wr_capa_timeout(struct file *file, const char *buffer,
         if (rc)
                 return rc;
 
-        obd->u.mds.mds_capa_timeout = val;
+        mds_update_capa_timeout(obd, val);
         return count;
 }
 
@@ -201,8 +201,8 @@ static int lprocfs_wr_capa_key_timeout(struct file *file, const char *buffer,
         if (rc)
                 return rc;
 
-        obd->u.mds.mds_capa_key_timeout = val;
-        return count;
+        rc = mds_update_capa_key_timeout(obd, val);
+        return rc ?: count;
 }
 
 struct lprocfs_vars lprocfs_mds_obd_vars[] = {
index dd85ab6..23e349f 100644 (file)
@@ -45,15 +45,18 @@ static struct thread_ctl {
 } mds_eck_ctl;
 
 static LIST_HEAD(mds_capa_key_list);
-static LIST_HEAD(mds_expired_capa_keys);
 static spinlock_t mds_capa_lock; /* protect capa and capa key */
 struct timer_list mds_eck_timer;
 
-#define CUR_MDS_CAPA_KEY(mds) mds->mds_capa_keys[mds->mds_capa_key_idx]
+#define CAPA_KEY_JIFFIES(key) \
+        expiry_to_jiffies(le64_to_cpu((key)->k_key->lk_expiry))
+
+#define CUR_MDS_CAPA_KEY(mds) (mds)->mds_capa_keys[(mds)->mds_capa_key_idx]
 #define CUR_CAPA_KEY(mds) CUR_MDS_CAPA_KEY(mds).k_key
 #define CUR_CAPA_KEY_ID(mds) CUR_MDS_CAPA_KEY(mds).k_key->lk_keyid
-#define CUR_CAPA_KEY_EXPIRY(mds) expiry_to_jiffies(CUR_CAPA_KEY(mds)->lk_expiry)
 #define CUR_CAPA_KEY_LIST(mds) CUR_MDS_CAPA_KEY(mds).k_list
+#define CUR_CAPA_KEY_EXPIRY(mds) le64_to_cpu(CUR_CAPA_KEY(mds)->lk_expiry)
+#define CUR_CAPA_KEY_JIFFIES(mds) CAPA_KEY_JIFFIES(&CUR_MDS_CAPA_KEY(mds))
 
 static int mds_write_capa_key(struct obd_device *obd, int force_sync)
 {
@@ -83,8 +86,8 @@ static int mds_write_capa_key(struct obd_device *obd, int force_sync)
 static inline int
 mds_capa_key_cmp(struct mds_obd *mds)
 {
-        return capa_key_cmp(mds->mds_capa_keys[0].k_key,
-                            mds->mds_capa_keys[1].k_key);
+        return le32_to_cpu(mds->mds_capa_keys[0].k_key->lk_keyid) -
+               le32_to_cpu(mds->mds_capa_keys[1].k_key->lk_keyid);
 }
 
 static void
@@ -94,8 +97,10 @@ do_update_capa_key(struct mds_obd *mds, struct lustre_capa_key *key)
         __u64 expiry_rounded;
 
         if (CUR_CAPA_KEY(mds))
-                keyid = le32_to_cpu(CUR_CAPA_KEY(mds)->lk_keyid) + 1;
+                keyid = le32_to_cpu(CUR_CAPA_KEY_ID(mds)) + 1;
+        spin_lock(&mds_capa_lock);
         expiry_rounded = round_expiry(mds->mds_capa_key_timeout);
+        spin_unlock(&mds_capa_lock);
 
         key->lk_mdsid = cpu_to_le32(mds->mds_num);
         key->lk_keyid = cpu_to_le32(keyid);
@@ -108,13 +113,15 @@ static void list_add_capa_key(struct mds_capa_key *key, struct list_head *head)
         struct mds_capa_key *tmp;
 
         list_for_each_entry_reverse(tmp, head, k_list) {
-                if (key->k_key->lk_expiry > tmp->k_key->lk_expiry) {
-                        list_add(&key->k_list, &tmp->k_list);
+                if (le64_to_cpu(key->k_key->lk_expiry) <
+                    le64_to_cpu(tmp->k_key->lk_expiry)) {
+                        /* put key before tmp */
+                        list_add_tail(&key->k_list, &tmp->k_list);
                         return;
                 }
         }
 
-        list_add(&key->k_list, head);
+        list_add_tail(&key->k_list, head);
 }
 
 int mds_read_capa_key(struct obd_device *obd, struct file *file)
@@ -123,6 +130,7 @@ int mds_read_capa_key(struct obd_device *obd, struct file *file)
         struct mds_obd *mds = &obd->u.mds;
         struct lustre_capa_key *key;
         unsigned long capa_keys_size = file->f_dentry->d_inode->i_size;
+        unsigned long expiry;
         int i = 0, rc = 0;
         ENTRY;
 
@@ -173,11 +181,11 @@ int mds_read_capa_key(struct obd_device *obd, struct file *file)
                         mds->mds_capa_key_idx = 1;
         }
 
+        expiry = CUR_CAPA_KEY_JIFFIES(mds);
         spin_lock(&mds_capa_lock);
-        if (time_before(CUR_CAPA_KEY_EXPIRY(mds), mds_eck_timer.expires)
-            || !timer_pending(&mds_eck_timer))
-                mod_timer(&mds_eck_timer, CUR_CAPA_KEY_EXPIRY(mds));
-
+        if (time_before(expiry, mds_eck_timer.expires) ||
+            !timer_pending(&mds_eck_timer))
+                mod_timer(&mds_eck_timer, expiry);
         list_add_capa_key(&CUR_MDS_CAPA_KEY(mds), &mds_capa_key_list);
         spin_unlock(&mds_capa_lock);
 out:
@@ -189,6 +197,7 @@ void mds_capa_keys_cleanup(struct obd_device *obd)
         struct mds_obd *mds = &obd->u.mds;
         int i;
 
+        del_timer(&mds_eck_timer);
         spin_lock(&mds_capa_lock);
         if (CUR_CAPA_KEY(mds))
                 list_del_init(&CUR_CAPA_KEY_LIST(mds));
@@ -208,9 +217,6 @@ static int mds_set_capa_key(struct obd_device *obd, struct lustre_capa_key *key)
 
         rc = obd_set_info(mds->mds_dt_exp, strlen("capa_key"), "capa_key",
                           sizeof(*key), key);
-        if (rc)
-                CERROR("obd_set_info capa_key failed: rc = %d\n", rc);
-
         RETURN(rc);
 }
 
@@ -219,10 +225,11 @@ mds_update_capa_key(struct obd_device *obd, struct mds_capa_key *mkey,
                     int force_sync)
 {
         struct mds_obd *mds = &obd->u.mds;
-        int to_update = mds->mds_capa_key_idx ^ 1;
+        int to_update = !mds->mds_capa_key_idx;
         struct lustre_capa_key *key = mds->mds_capa_keys[to_update].k_key;
         __u32 keyid;
-        int rc = 0;
+        unsigned long expiry;
+        int rc, rc2;
         ENTRY;
 
         LASSERT(mkey != &mds->mds_capa_keys[to_update]);
@@ -241,28 +248,31 @@ mds_update_capa_key(struct obd_device *obd, struct mds_capa_key *mkey,
         keyid = le32_to_cpu(key->lk_keyid);
 
         rc = mds_set_capa_key(obd, key);
-        if (rc) {
+        if (rc)
+                /* XXX: anyway, it will be replayed */
                 CERROR("error set capa key(id %u), err = %d\n", keyid, rc);
-                GOTO(out, rc);
-        }
-
-        CDEBUG(D_INFO, "MDS capa_keyid is %u\n", keyid);
 
-        rc = mds_write_capa_key(obd, 1);
-        if (rc)
-                GOTO(out, rc);
+        rc2 = mds_write_capa_key(obd, 1);
+        if (rc2)
+                GOTO(out, rc2);
         
-        CDEBUG(D_INFO, "wrote capa keyid %u: err = %d\n", keyid, rc);
+        CDEBUG(D_INFO, "wrote capa keyid %u\n", keyid);
 
         spin_lock(&mds_capa_lock);
         list_del_init(&CUR_CAPA_KEY_LIST(mds));
         mds->mds_capa_key_idx = to_update;
+        expiry = CUR_CAPA_KEY_JIFFIES(mds);
         list_add_capa_key(&CUR_MDS_CAPA_KEY(mds), &mds_capa_key_list);
+
+        if (time_before(expiry, mds_eck_timer.expires) ||
+            !timer_pending(&mds_eck_timer))
+                mod_timer(&mds_eck_timer, expiry);
         spin_unlock(&mds_capa_lock);
 
-        /* TODO: update timer here */
+        DEBUG_MDS_CAPA_KEY(D_INFO, &CUR_MDS_CAPA_KEY(mds),
+                           "mds_update_capa_key");
 out:
-        RETURN(rc);
+        RETURN(rc2);
 }
 
 static inline int have_expired_capa_key(void)
@@ -275,8 +285,9 @@ static inline int have_expired_capa_key(void)
         if (!list_empty(&mds_capa_key_list)) {
                 key = list_entry(mds_capa_key_list.next, struct mds_capa_key,
                                  k_list);
-                expired = time_before(expiry_to_jiffies(key->k_key->lk_expiry),
-                                      jiffies);
+                /* expiry is in sec, so in case it misses, the result will
+                 * minus HZ and then compare with jiffies. */
+                expired = time_before(CAPA_KEY_JIFFIES(key) - HZ, jiffies);
         }
         spin_unlock(&mds_capa_lock);
 
@@ -292,18 +303,18 @@ static int mds_capa_key_thread_main(void *arg)
 {
         struct thread_ctl *ctl = arg;
         unsigned long flags;
+        int rc;
         ENTRY;
 
-        {
-                char name[sizeof(current->comm)];
-                snprintf(name, sizeof(name) - 1, "mds_ck");
-                kportal_daemonize(name);
-        }
+        lock_kernel();
+        ptlrpc_daemonize();
 
         SIGNAL_MASK_LOCK(current, flags);
         sigfillset(&current->blocked);
         RECALC_SIGPENDING;
         SIGNAL_MASK_UNLOCK(current, flags);
+        THREAD_NAME(current->comm, sizeof(current->comm), "mds_ck");
+        unlock_kernel();
 
         /*
          * letting starting function know, that we are ready and control may be
@@ -323,26 +334,24 @@ static int mds_capa_key_thread_main(void *arg)
 
                 spin_lock(&mds_capa_lock);
                 list_for_each_entry_safe(key, tmp, &mds_capa_key_list, k_list) {
-                        if (time_after(expiry_to_jiffies(key->k_key->lk_expiry),
-                                       jiffies)) {
+                        if (time_after(CAPA_KEY_JIFFIES(key), jiffies)) {
                                 next = key;
                                 break;
                         }
 
                         spin_unlock(&mds_capa_lock);
 
-                        CDEBUG(D_INFO, "mds capa key expired, wake up updating "
-                                       "thread: mds #%u, key #%u\n",
+                        CDEBUG(D_INFO, "mds capa key expired: "
+                               "mds #%u, key #%u\n",
                                le32_to_cpu(key->k_key->lk_mdsid),
                                le32_to_cpu(key->k_key->lk_keyid));
 
-                        mds_update_capa_key(key->k_obd, key, 1);
+                        rc = mds_update_capa_key(key->k_obd, key, 1);
                         spin_lock(&mds_capa_lock);
                 }
 
                 if (next)
-                        mod_timer(&mds_eck_timer,
-                                  expiry_to_jiffies(next->k_key->lk_expiry));
+                        mod_timer(&mds_eck_timer, CAPA_KEY_JIFFIES(next));
                 spin_unlock(&mds_capa_lock);
         }
 
@@ -395,18 +404,82 @@ void mds_capa_key_stop_thread(void)
         EXIT;
 }
 
-int mds_pack_capa(struct obd_device *obd, struct mds_body *req_body,
-                  struct lustre_capa *req_capa, struct lustre_msg *repmsg,
-                  int *offset, struct mds_body *body)
+void mds_update_capa_stat(struct obd_device *obd, int stat)
+{
+        struct mds_obd *mds = &obd->u.mds;
+
+        spin_lock(&mds_capa_lock);
+        mds->mds_capa_stat = stat;
+        spin_unlock(&mds_capa_lock);
+}
+
+void mds_update_capa_timeout(struct obd_device *obd, unsigned long timeout)
+{
+        struct mds_obd *mds = &obd->u.mds;
+
+        spin_lock(&mds_capa_lock);
+        mds->mds_capa_timeout = timeout;
+        /* XXX: update all capabilities in cache if their expiry too long */
+        spin_unlock(&mds_capa_lock);
+}
+
+int mds_update_capa_key_timeout(struct obd_device *obd, unsigned long timeout)
+{
+        struct mds_obd *mds = &obd->u.mds;
+        struct timeval tv;
+        int rc;
+        ENTRY;
+
+        do_gettimeofday(&tv);
+
+        spin_lock(&mds_capa_lock);
+        mds->mds_capa_key_timeout = timeout;
+        if (CUR_CAPA_KEY_EXPIRY(mds) < tv.tv_sec + timeout) {
+                spin_unlock(&mds_capa_lock);
+                RETURN(0);
+        }
+        spin_unlock(&mds_capa_lock);
+
+        rc = mds_update_capa_key(obd, &CUR_MDS_CAPA_KEY(mds), 1);
+
+        RETURN(rc);
+}
+
+static void mds_capa_reverse_map(struct mds_export_data *med,
+                                 struct lustre_capa *capa)
+{
+        uid_t uid;
+
+        if (!med->med_remote)
+                return;
+
+        ENTRY;
+        uid = mds_idmap_lookup_uid(med->med_idmap, 1, capa->lc_uid);
+        if (uid == MDS_IDMAP_NOTFOUND)
+                uid = med->med_nllu;
+        capa->lc_ruid = uid;
+        capa->lc_flags |= CAPA_FL_REMUID;
+        EXIT;
+}
+
+
+int mds_pack_capa(struct obd_device *obd, struct mds_export_data *med,
+                  struct mds_body *req_body, struct lustre_capa *req_capa,
+                  struct ptlrpc_request *req, int *offset, struct mds_body *body)
 {
         struct mds_obd *mds = &obd->u.mds;
         struct lustre_capa *capa;
+        struct lustre_msg *repmsg = req->rq_repmsg;
         struct obd_capa *ocapa;
         __u8 key[CAPA_KEY_LEN];  /* key */
-        int expired, rc = 0;
+        int stat, expired, rc = 0;
         ENTRY;
 
-        if (mds->mds_capa_stat == 0) {
+        spin_lock(&mds_capa_lock);
+        stat = mds->mds_capa_stat;
+        spin_unlock(&mds_capa_lock);
+
+        if (stat == 0) {
                 (*offset)++;
                 RETURN(0); /* capability is disabled */
         }
@@ -431,7 +504,8 @@ int mds_pack_capa(struct obd_device *obd, struct mds_body *req_body,
                 if (!(req_capa->lc_op & mode)) {
                         CERROR("invalid capa to renew ino "LPD64
                                ": op %d mismatch with mode %d\n",
-                               req_capa->lc_ino, req_capa->lc_op, mfd->mfd_mode);
+                               req_capa->lc_ino, req_capa->lc_op,
+                               mfd->mfd_mode);
                         RETURN(-EACCES);
                 }
         }
@@ -453,6 +527,7 @@ int mds_pack_capa(struct obd_device *obd, struct mds_body *req_body,
         }
 
         memcpy(capa, req_capa, sizeof(*capa));
+        mds_capa_reverse_map(med, capa);
 
         spin_lock(&mds_capa_lock);
         capa->lc_keyid = le32_to_cpu(CUR_CAPA_KEY_ID(mds));
index f4c2b91..fcba3b8 100644 (file)
@@ -1014,13 +1014,11 @@ int mds_fs_setup(struct obd_device *obd, struct vfsmount *mnt)
                 GOTO(err_capa_keyid, rc = -ENOENT);
         }
 
-#if 0
         rc = mds_read_capa_key(obd, file);
         if (rc) {
                 CERROR("cannot read %s: rc = %d\n", CAPA_KEYS, rc);
                 GOTO(err_capa_keyid, rc);
         }
-#endif
 
         /* reint fidext thumb by last fid after root and virt are initialized */
         mds->mds_fidext_thumb = mds->mds_last_fid;
index 4b910f2..f20e42e 100644 (file)
@@ -362,8 +362,12 @@ void mds_capa_keys_cleanup(struct obd_device *obd);
 void mds_capa_key_timer_callback(unsigned long data);
 int mds_capa_key_start_thread(void);
 void mds_capa_key_stop_thread(void);
-int mds_pack_capa(struct obd_device *obd, struct mds_body *req_body,
-                  struct lustre_capa *req_capa, struct lustre_msg *repmsg,
-                  int *offset, struct mds_body *body);
+int mds_pack_capa(struct obd_device *obd, struct mds_export_data *med, 
+                  struct mds_body *req_body, struct lustre_capa *req_capa,
+                  struct ptlrpc_request *req, int *offset, 
+                  struct mds_body *body);
+void mds_update_capa_stat(struct obd_device *obd, int stat);
+void mds_update_capa_timeout(struct obd_device *obd, unsigned long timeout);
+int mds_update_capa_key_timeout(struct obd_device *obd, unsigned long timeout);
 
 #endif /* _MDS_INTERNAL_H */
index c0f2323..b97f854 100644 (file)
@@ -267,7 +267,6 @@ int mds_pack_gskey(struct obd_device *obd, struct lustre_msg *repmsg,
                 if (size < 0) 
                         CERROR("Can not get gskey from MDS ino %lu rc %d\n",
                                 inode->i_ino, size);
-                (*offset) += 2; /* XXX: ignore crypto in case size == 0 */
                 GOTO(out, rc = size); 
         }
         if (le32_to_cpu(md_key->md_magic) != MD_KEY_MAGIC) {
index 60d7477..a26d148 100644 (file)
@@ -441,7 +441,7 @@ mds_create_objects(struct obd_device *obd, struct ptlrpc_request *req,
                 obdo_from_inode(oa, inode, OBD_MD_FLTYPE | OBD_MD_FLATIME |
                                 OBD_MD_FLMTIME | OBD_MD_FLCTIME | OBD_MD_FLSIZE);
                 
-                rc = obd_setattr(mds->mds_dt_exp, oa, lsm, &oti);
+                rc = obd_setattr(mds->mds_dt_exp, oa, lsm, &oti, NULL);
                 if (rc) {
                         CERROR("error setting attrs for inode %lu: rc %d\n",
                                inode->i_ino, rc);
@@ -704,6 +704,7 @@ static int mds_finish_open(struct ptlrpc_request *req, struct dentry *dchild,
 {
         struct obd_device *obd = req->rq_export->exp_obd;
         struct mds_obd *mds = mds_req2mds(req);
+        struct mds_export_data *med = &req->rq_export->u.eu_mds_data;
         struct mds_file_data *mfd = NULL;
         obd_id *ids = NULL;
         unsigned mode;
@@ -782,7 +783,7 @@ static int mds_finish_open(struct ptlrpc_request *req, struct dentry *dchild,
                         .lc_mdsid = mds->mds_num,
                 };
 
-                rc = mds_pack_capa(obd, NULL, &capa, req->rq_repmsg,
+                rc = mds_pack_capa(obd, med, NULL, &capa, req,
                                    &reply_off, body);
                 if (rc < 0) {
                         CERROR("mds_pack_capa: rc = %d\n", rc);
index eb21196..8fafdfa 100644 (file)
@@ -691,8 +691,8 @@ static int mds_reint_setattr(struct mds_update_record *rec, int offset,
                 int offset = 1;
 
                 LASSERT(capa.lc_mdsid == mds->mds_num);
-                rc = mds_pack_capa(obd, NULL, &capa, req->rq_repmsg, &offset,
-                                   body);
+                rc = mds_pack_capa(obd, med, NULL, &capa, req,
+                                   &offset, body);
                 if (rc < 0) {
                         CERROR("mds_pack_capa: rc = %d\n", rc);
                         RETURN(rc);
index 0fa7afe..c3bbaee 100644 (file)
@@ -89,26 +89,34 @@ find_capa(struct hlist_head *head, uid_t uid, int capa_op, __u64 mdsid,
 {
         struct hlist_node *pos;
         struct obd_capa *ocapa;
-        ENTRY;
+        uid_t ouid;
 
         CDEBUG(D_CACHE, "find_capa uid %u op %u mdsid "LPU64" ino %lu "
                "type %d\n", uid, capa_op, mdsid, ino, type);
 
         hlist_for_each_entry(ocapa, pos, head, c_hash) {
-                if (ocapa->c_capa.lc_uid != uid)
-                        continue;
-                if (ocapa->c_capa.lc_op != capa_op)
+                if (ocapa->c_capa.lc_ino != ino)
                         continue;
                 if (ocapa->c_capa.lc_mdsid != mdsid)
                         continue;
-                if (ocapa->c_capa.lc_ino != ino)
+                if (ocapa->c_capa.lc_op != capa_op)
                         continue;
                 if (ocapa->c_type != type)
                         continue;
-                RETURN(ocapa);
+
+                if (ocapa->c_type == CLIENT_CAPA &&
+                    ocapa->c_capa.lc_flags & CAPA_FL_REMUID)
+                        ouid = ocapa->c_capa.lc_ruid;
+                else
+                        ouid = ocapa->c_capa.lc_uid;
+
+                if (ouid != uid)
+                        continue;
+
+                return ocapa;
         }
 
-        RETURN(NULL);
+        return NULL;
 }
 
 inline void __capa_get(struct obd_capa *ocapa)
@@ -135,7 +143,6 @@ find_capa_locked(struct hlist_head *head, uid_t uid, int capa_op, __u64 mdsid,
 static struct obd_capa *alloc_capa(void)
 {
         struct obd_capa *ocapa;
-        ENTRY;
 
         OBD_SLAB_ALLOC(ocapa, capa_cachep, SLAB_NOFS, sizeof(*ocapa));
         if (ocapa) {
@@ -143,7 +150,7 @@ static struct obd_capa *alloc_capa(void)
                 INIT_LIST_HEAD(&ocapa->c_list);
         }
 
-        RETURN(ocapa);
+        return ocapa;
 }
 
 static void destroy_capa(struct obd_capa *ocapa)
@@ -177,6 +184,7 @@ void capa_cache_cleanup(void)
         struct hlist_node *pos, *n;
 
         hlist_for_each_entry_safe(ocapa, pos, n, capa_hash, c_hash) {
+                LASSERT(ocapa->c_type != CLIENT_CAPA);
                 hlist_del(&ocapa->c_hash);
                 list_del(&ocapa->c_list);
                 OBD_FREE(ocapa, sizeof(*ocapa));
@@ -203,20 +211,19 @@ static inline void list_add_capa(struct obd_capa *ocapa, struct list_head *head)
         list_add_tail(&ocapa->c_list, head);
 }
 
-#define DEBUG_CAPA(level, ocapa, fmt, args...)                                 \
-do {                                                                           \
-CDEBUG(level, fmt " capa@%p uid %u op %u ino "LPU64" mdsid %d keyid %d "       \
-       "expiry "LPU64" flags %u type %d\n",                                    \
-       ##args, ocapa, ocapa->c_capa.lc_uid, ocapa->c_capa.lc_op,               \
-       ocapa->c_capa.lc_ino, ocapa->c_capa.lc_mdsid, ocapa->c_capa.lc_keyid,   \
-       ocapa->c_capa.lc_expiry, ocapa->c_capa.lc_flags, ocapa->c_type);        \
-} while (0)
+static inline void do_update_capa(struct obd_capa *ocapa, struct lustre_capa *capa)
+{
+        memcpy(&ocapa->c_capa, capa, sizeof(*capa));
+}
 
 static struct obd_capa *
-get_new_capa_locked(struct hlist_head *head, uid_t uid, int capa_op,__u64 mdsid,
-                    unsigned long ino, int type, struct lustre_capa *capa,
+get_new_capa_locked(struct hlist_head *head, int type, struct lustre_capa *capa,
                     struct inode *inode, struct lustre_handle *handle)
 {
+        uid_t uid = capa->lc_uid;
+        int capa_op = capa->lc_op;
+        __u64 mdsid = capa->lc_mdsid;
+        unsigned long ino = capa->lc_ino;
         struct obd_capa *ocapa, *old;
         ENTRY;
 
@@ -227,21 +234,25 @@ get_new_capa_locked(struct hlist_head *head, uid_t uid, int capa_op,__u64 mdsid,
         spin_lock(&capa_lock);
         old = find_capa(head, uid, capa_op, mdsid, ino, type);
         if (!old) {
-                memcpy(&ocapa->c_capa, capa, sizeof(*capa));
+                do_update_capa(ocapa, capa);
                 ocapa->c_type = type;
+
                 if (type == CLIENT_CAPA) {
                         LASSERT(inode);
+                        LASSERT(handle);
 #ifdef __KERNEL__
                         igrab(inode);
 #endif
                         ocapa->c_inode = inode;
                         memcpy(&ocapa->c_handle, handle, sizeof(*handle));
                 }
+
                 list_add_capa(ocapa, &capa_list[type]);
                 hlist_add_head(&ocapa->c_hash, capa_hash);
                 capa_count[type]++;
-                DEBUG_CAPA(D_CACHE, ocapa, "get_new_capa_locked");
+
                 __capa_get(ocapa);
+
                 if (type != CLIENT_CAPA && capa_count[type] > CAPA_CACHE_SIZE) {
                         struct list_head *node = capa_list[type].next;
                         struct obd_capa *tcapa;
@@ -254,7 +265,9 @@ get_new_capa_locked(struct hlist_head *head, uid_t uid, int capa_op,__u64 mdsid,
                                 if (atomic_read(&tcapa->c_refc) > 0)
                                         continue;
                                 list_del(&tcapa->c_list);
+                                hlist_del(&tcapa->c_hash);
                                 destroy_capa(tcapa);
+                                capa_count[type]--;
                                 count++;
                         }
                 }
@@ -265,9 +278,9 @@ get_new_capa_locked(struct hlist_head *head, uid_t uid, int capa_op,__u64 mdsid,
 
         __capa_get(old);
         spin_unlock(&capa_lock);
+
         destroy_capa(ocapa);
-        ocapa = old;
-        RETURN(ocapa);
+        RETURN(old);
 }
 
 static struct obd_capa *
@@ -285,8 +298,7 @@ capa_get_locked(uid_t uid, int capa_op,__u64 mdsid, unsigned long ino,
                 RETURN(ocapa);
         
         if (capa)
-                ocapa = get_new_capa_locked(head, uid, capa_op, mdsid, ino,
-                                            type, capa, inode, handle);
+                ocapa = get_new_capa_locked(head, type, capa, inode, handle);
         RETURN(ocapa);
 }
 
@@ -326,11 +338,6 @@ void capa_put(struct obd_capa *ocapa, int type)
         EXIT;
 }
 
-static inline void __update_capa(struct obd_capa *ocapa, struct lustre_capa *capa)
-{
-        memcpy(&ocapa->c_capa, capa, sizeof(*capa));
-}
-
 static int update_capa_locked(struct lustre_capa *capa, int type)
 {
         uid_t uid = capa->lc_uid;
@@ -345,12 +352,13 @@ static int update_capa_locked(struct lustre_capa *capa, int type)
         spin_lock(&capa_lock);
         ocapa = find_capa(head, uid, capa_op, mdsid, ino, type);
         if (ocapa)
-                __update_capa(ocapa, capa);
+                do_update_capa(ocapa, capa);
         spin_unlock(&capa_lock);
 
-        if (ocapa == NULL && type == MDS_CAPA)
-                ocapa = get_new_capa_locked(head, uid, capa_op, mdsid, ino, type,
-                                            capa, NULL, NULL);
+        if (ocapa == NULL && type == MDS_CAPA) {
+                ocapa = get_new_capa_locked(head, type, capa, NULL, NULL);
+                capa_put(ocapa, type);
+        }
 
         RETURN(ocapa ? 0 : -ENOENT);
 }
@@ -368,11 +376,9 @@ void capa_hmac(struct crypto_tfm *tfm, __u8 *key, struct lustre_capa *capa)
                 .offset = (unsigned long)(capa) % PAGE_SIZE,
                 .length = sizeof(struct lustre_capa_data),
         };
-        ENTRY;
 
         LASSERT(tfm);
         crypto_hmac(tfm, key, &keylen, &sl, 1, capa->lc_hmac);
-        EXIT;
 }
 
 void capa_dup(void *dst, struct obd_capa *ocapa)
@@ -403,7 +409,7 @@ 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 < tv.tv_sec)? 1 : 0;
+        return (ocapa->c_capa.lc_expiry - pre_expiry - 1 <= tv.tv_sec)? 1 : 0;
 }
 
 int capa_is_to_expire(struct obd_capa *ocapa)
index 0962dd9..5ff6c71 100644 (file)
@@ -189,7 +189,8 @@ static int echo_getattr(struct obd_export *exp, struct obdo *oa,
 }
 
 static int echo_setattr(struct obd_export *exp, struct obdo *oa,
-                        struct lov_stripe_md *md, struct obd_trans_info *oti)
+                        struct lov_stripe_md *md, struct obd_trans_info *oti,
+                        struct lustre_capa *capa)
 {
         struct obd_device *obd = class_exp2obd(exp);
 
index b96b59f..f16a1ed 100644 (file)
@@ -1247,7 +1247,7 @@ echo_client_iocontrol(unsigned int cmd, struct obd_export *exp,
                 rc = echo_get_object (&eco, obd, &data->ioc_obdo1);
                 if (rc == 0) {
                         rc = obd_setattr(ec->ec_exp, &data->ioc_obdo1,
-                                         eco->eco_lsm, NULL);
+                                         eco->eco_lsm, NULL, NULL);
                         echo_put_object(eco);
                 }
                 GOTO(out, rc);
index aaa6b04..7134fb3 100644 (file)
@@ -1020,8 +1020,9 @@ static void filter_post(struct obd_device *obd)
 
         filter_cleanup_groups(obd);
         filter_free_server_data(filter);
-        filter_free_capa_keys(filter);
         pop_ctxt(&saved, &obd->obd_lvfs_ctxt, NULL);
+
+        filter_free_capa_keys(filter);
 }
 
 static void filter_set_last_id(struct filter_obd *filter, int group, obd_id id)
@@ -2164,7 +2165,8 @@ out_unlock:
 
 /* this is called from filter_truncate() until we have filter_punch() */
 int filter_setattr(struct obd_export *exp, struct obdo *oa,
-                   struct lov_stripe_md *md, struct obd_trans_info *oti)
+                   struct lov_stripe_md *md, struct obd_trans_info *oti,
+                   struct lustre_capa *capa)
 {
         struct ldlm_res_id res_id = { .name = { oa->o_id, 0, oa->o_gr, 0 } };
         struct ldlm_valblock_ops *ns_lvbo;
@@ -2189,6 +2191,9 @@ int filter_setattr(struct obd_export *exp, struct obdo *oa,
         if (IS_ERR(dentry))
                 GOTO(out_pop, rc = PTR_ERR(dentry));
 
+        rc = filter_verify_capa(OBD_BRW_WRITE, exp, dentry->d_inode, capa);
+        if (rc)
+                RETURN(rc);
         lock_kernel();
 
         /* setting objects attributes (including owner/group) */
@@ -2739,12 +2744,9 @@ static int filter_truncate(struct obd_export *exp, struct obdo *oa,
 
         CDEBUG(D_INODE, "calling truncate for object "LPU64", valid = "LPU64", "
                "o_size = "LPD64"\n", oa->o_id, oa->o_valid, start);
-        error = filter_verify_capa(OBD_BRW_WRITE, exp, capa);
-        if (error)
-                RETURN(error);
 
         oa->o_size = start;
-        error = filter_setattr(exp, oa, NULL, oti);
+        error = filter_setattr(exp, oa, NULL, oti, capa);
         RETURN(error);
 }
 
index 3f52db0..258c16c 100644 (file)
@@ -38,10 +38,12 @@ void filter_free_capa_keys(struct filter_obd *filter)
 {
         struct filter_capa_key *key, *n;
 
+        spin_lock(&filter->fo_capa_lock);
         list_for_each_entry_safe(key, n, &filter->fo_capa_keys, k_list) {
-                list_del(&key->k_list);
+                list_del_init(&key->k_list);
                 OBD_FREE(key, sizeof(*key));
         }
+        spin_unlock(&filter->fo_capa_lock);
 }
 
 int filter_update_capa_key(struct obd_device *obd, struct lustre_capa_key *key)
@@ -53,12 +55,13 @@ int filter_update_capa_key(struct obd_device *obd, struct lustre_capa_key *key)
 
         spin_lock(&filter->fo_capa_lock);
         list_for_each_entry(tmp, &filter->fo_capa_keys, k_list) {
-                if (tmp->k_key.lk_mdsid == le32_to_cpu(key->lk_mdsid)) {
-                        if (rkey == NULL)
-                                rkey = tmp;
-                        else
-                                bkey = tmp;
-                }
+                if (tmp->k_key.lk_mdsid != le32_to_cpu(key->lk_mdsid))
+                        continue;
+
+                if (rkey == NULL)
+                        rkey = tmp;
+                else
+                        bkey = tmp;
         }
         spin_unlock(&filter->fo_capa_lock);
 
@@ -68,33 +71,38 @@ int filter_update_capa_key(struct obd_device *obd, struct lustre_capa_key *key)
                 bkey = tmp;
         }
 
-        if (!bkey || !tmp) {
+        if (bkey) {
+                tmp = bkey;
+        } else {
                 OBD_ALLOC(tmp, sizeof(*tmp));
                 if (!tmp)
                         GOTO(out, rc = -ENOMEM);
-
-                spin_lock(&filter->fo_capa_lock);
-                list_add_tail(&tmp->k_list, &filter->fo_capa_keys);
-                spin_unlock(&filter->fo_capa_lock);
         }
 
         /* fields in lustre_capa_key are in cpu order */
+        spin_lock(&filter->fo_capa_lock);
         tmp->k_key.lk_mdsid = le32_to_cpu(key->lk_mdsid);
         tmp->k_key.lk_keyid = le32_to_cpu(key->lk_keyid);
         tmp->k_key.lk_expiry = le64_to_cpu(key->lk_expiry);
         memcpy(&tmp->k_key.lk_key, key->lk_key, sizeof(key->lk_key));
 
+        if (!bkey)
+                list_add_tail(&tmp->k_list, &filter->fo_capa_keys);
+        spin_unlock(&filter->fo_capa_lock);
+
+        DEBUG_CAPA_KEY(D_INFO, &tmp->k_key, "filter_update_capa_key");
 out:
         RETURN(rc);
 }
 
-int filter_verify_capa(int cmd, struct obd_export *exp,
+int filter_verify_capa(int cmd, struct obd_export *exp, struct inode *inode,
                        struct lustre_capa *capa)
 {
         struct obd_device *obd = exp->exp_obd;
         struct filter_obd *filter = &obd->u.filter;
         struct obd_capa *ocapa;
         struct lustre_capa tcapa;
+        struct lustre_id fid;
         struct filter_capa_key *rkey = NULL, *bkey = NULL, *tmp;
         __u8 hmac_key[CAPA_KEY_LEN];
         int rc = 0;
@@ -107,7 +115,7 @@ int filter_verify_capa(int cmd, struct obd_export *exp,
         if (capa == NULL)
                 RETURN(-EACCES);
 
-        if (cmd == OBD_BRW_WRITE && !(capa->lc_op & MAY_WRITE))
+        if (cmd == OBD_BRW_WRITE && capa->lc_op != MAY_WRITE)
                 RETURN(-EACCES);
         if (cmd == OBD_BRW_READ && !(capa->lc_op & (MAY_WRITE | MAY_READ)))
                 RETURN(-EACCES);
@@ -115,7 +123,15 @@ int filter_verify_capa(int cmd, struct obd_export *exp,
         if (OBD_FAIL_CHECK(OBD_FAIL_FILTER_VERIFY_CAPA))
                 RETURN(-EACCES);
 
-        /* TODO: get fid from EA, and verify that against capa */
+        rc = fsfilt_get_md(obd, inode, &fid, sizeof(fid), EA_SID);
+        if (rc < 0) {
+                CERROR("get fid from object failed! rc:%d\n", rc);
+                RETURN(rc);
+        } else if (rc > 0) {
+                if (capa->lc_mdsid != id_group(&fid) ||
+                    capa->lc_ino != id_ino(&fid))
+                        RETURN(-EINVAL);
+        }
 
         if (capa_expired(capa))
                 RETURN(-ESTALE);
index 7288807..98ce1dc 100644 (file)
@@ -109,7 +109,8 @@ int filter_setattr_internal(struct obd_export *exp, struct dentry *dentry,
                             struct obdo *oa, struct obd_trans_info *oti);
 
 int filter_setattr(struct obd_export *exp, struct obdo *oa,
-                   struct lov_stripe_md *md, struct obd_trans_info *oti);
+                   struct lov_stripe_md *md, struct obd_trans_info *oti,
+                   struct lustre_capa *capa);
 
 int filter_create_object(struct obd_device *obd, struct obdo *oa);
 
@@ -199,6 +200,7 @@ static inline lproc_filter_attach_seqstat(struct obd_device *dev) {}
 int filter_init_capa_keys(struct obd_device *obd);
 void filter_free_capa_keys(struct filter_obd *filter);
 int filter_update_capa_key(struct obd_device *obd, struct lustre_capa_key *key);
-int filter_verify_capa(int cmd, struct obd_export *exp, struct lustre_capa *capa);
+int filter_verify_capa(int cmd, struct obd_export *exp, struct inode *inode, 
+                       struct lustre_capa *capa);
 
 #endif
index bb2d61a..0201ce4 100644 (file)
@@ -264,7 +264,8 @@ static int filter_preprw_read(int cmd, struct obd_export *exp, struct obdo *oa,
                               int objcount, struct obd_ioobj *obj,
                               int niocount, struct niobuf_remote *nb,
                               struct niobuf_local *res,
-                              struct obd_trans_info *oti)
+                              struct obd_trans_info *oti,
+                              struct lustre_capa *capa)
 {
         struct obd_device *obd = exp->exp_obd;
         struct lvfs_run_ctxt saved;
@@ -303,6 +304,10 @@ static int filter_preprw_read(int cmd, struct obd_export *exp, struct obdo *oa,
 
         inode = dentry->d_inode; 
 
+        rc = filter_verify_capa(cmd, exp, inode, capa);
+        if (rc)
+                return rc;
+
         fsfilt_check_slow(now, obd_timeout, "preprw_read setup");
 
         for (i = 0, lnb = res, rnb = nb; i < obj->ioo_bufcnt;
@@ -495,7 +500,8 @@ static int filter_preprw_write(int cmd, struct obd_export *exp, struct obdo *oa,
                                int objcount, struct obd_ioobj *obj,
                                int niocount, struct niobuf_remote *nb,
                                struct niobuf_local *res,
-                               struct obd_trans_info *oti)
+                               struct obd_trans_info *oti,
+                               struct lustre_capa *capa)
 {
         int rc = 0, i, tot_bytes = 0, cleanup_phase = 0;
         struct obd_device *obd = exp->exp_obd;
@@ -532,6 +538,10 @@ static int filter_preprw_write(int cmd, struct obd_export *exp, struct obdo *oa,
         if (IS_ERR(dentry))
                 GOTO(cleanup, rc = PTR_ERR(dentry));
 
+        rc = filter_verify_capa(cmd, exp, dentry->d_inode, capa);
+        if (rc)
+                return rc;
+
         cleanup_phase = 2;
 
         fso.fso_dentry = dentry;
@@ -639,19 +649,13 @@ int filter_preprw(int cmd, struct obd_export *exp, struct obdo *oa,
                   struct niobuf_remote *nb, struct niobuf_local *res,
                   struct obd_trans_info *oti, struct lustre_capa *capa)
 {
-        int rc;
-
-        rc = filter_verify_capa(cmd, exp, capa);
-        if (rc)
-                return rc;
-
         if (cmd == OBD_BRW_WRITE)
                 return filter_preprw_write(cmd, exp, oa, objcount, obj,
-                                           niocount, nb, res, oti);
+                                           niocount, nb, res, oti, capa);
 
         if (cmd == OBD_BRW_READ)
                 return filter_preprw_read(cmd, exp, oa, objcount, obj,
-                                          niocount, nb, res, oti);
+                                          niocount, nb, res, oti, capa);
 
         LBUG();
         return -EPROTO;
index 57a626b..529b064 100644 (file)
@@ -253,7 +253,8 @@ static int osc_getattr(struct obd_export *exp, struct obdo *oa,
 }
 
 static int osc_setattr(struct obd_export *exp, struct obdo *oa,
-                       struct lov_stripe_md *md, struct obd_trans_info *oti)
+                       struct lov_stripe_md *md, struct obd_trans_info *oti,
+                       struct lustre_capa *capa)
 {
         struct ptlrpc_request *request;
         struct ost_body *body;
index a945bda..dd23493 100644 (file)
@@ -237,7 +237,7 @@ static int ost_setattr(struct obd_export *exp, struct ptlrpc_request *req,
         repbody = lustre_msg_buf(req->rq_repmsg, 0, sizeof(*repbody));
         memcpy(&repbody->oa, &body->oa, sizeof(body->oa));
 
-        req->rq_status = obd_setattr(exp, &repbody->oa, NULL, oti);
+        req->rq_status = obd_setattr(exp, &repbody->oa, NULL, oti, NULL);
         RETURN(0);
 }
 
@@ -940,7 +940,7 @@ static int ost_set_info(struct obd_export *exp, struct ptlrpc_request *req)
         } else if (keylen == 9 && strcmp(key, "audit_obj") == 0) {
                 lustre_swab_reqbuf(req, 1, sizeof(struct obdo),
                                    lustre_swab_obdo);
-        } else if (keylen == 8 && strcmp(key, "capa_key") == 0) {
+        } else if (keylen == 8 && memcmp(key, "capa_key", 8) == 0) {
                 lustre_swab_reqbuf(req, 1, sizeof(struct lustre_capa_key),
                                    lustre_swab_lustre_capa_key);
         }
index dc2c190..1772652 100644 (file)
@@ -1410,37 +1410,37 @@ void lustre_assert_wire_constants(void)
                  (unsigned long long)(int)sizeof(((struct llogd_conn_body *)0)->lgdc_ctxt_idx));
 
         /* Checks for struct lustre_capa */
-        LASSERTF((int)sizeof(struct lustre_capa) == 52, " found %llu\n",
+        LASSERTF((int)sizeof(struct lustre_capa) == 56, " found %llu\n",
                  (unsigned long long)(int)sizeof(struct lustre_capa));
         LASSERTF((int)offsetof(struct lustre_capa, lc_uid) == 0, " found %llu\n",
                  (unsigned long long)(int)offsetof(struct lustre_capa, lc_uid));
         LASSERTF((int)sizeof(((struct lustre_capa *)0)->lc_uid) == 4, " found %llu\n",
                  (unsigned long long)(int)sizeof(((struct lustre_capa *)0)->lc_uid));
-        LASSERTF((int)offsetof(struct lustre_capa, lc_op) == 4, " found %llu\n",
+        LASSERTF((int)offsetof(struct lustre_capa, lc_op) == 8, " found %llu\n",
                  (unsigned long long)(int)offsetof(struct lustre_capa, lc_op));
         LASSERTF((int)sizeof(((struct lustre_capa *)0)->lc_op) == 4, " found %llu\n",
                  (unsigned long long)(int)sizeof(((struct lustre_capa *)0)->lc_op));
-        LASSERTF((int)offsetof(struct lustre_capa, lc_ino) == 8, " found %llu\n",
+        LASSERTF((int)offsetof(struct lustre_capa, lc_ino) == 12, " found %llu\n",
                  (unsigned long long)(int)offsetof(struct lustre_capa, lc_ino));
         LASSERTF((int)sizeof(((struct lustre_capa *)0)->lc_ino) == 8, " found %llu\n",
                  (unsigned long long)(int)sizeof(((struct lustre_capa *)0)->lc_ino));
-        LASSERTF((int)offsetof(struct lustre_capa, lc_mdsid) == 16, " found %llu\n",
+        LASSERTF((int)offsetof(struct lustre_capa, lc_mdsid) == 20, " found %llu\n",
                  (unsigned long long)(int)offsetof(struct lustre_capa, lc_mdsid));
         LASSERTF((int)sizeof(((struct lustre_capa *)0)->lc_mdsid) == 4, " found %llu\n",
                  (unsigned long long)(int)sizeof(((struct lustre_capa *)0)->lc_mdsid));
-        LASSERTF((int)offsetof(struct lustre_capa, lc_keyid) == 20, " found %llu\n",
+        LASSERTF((int)offsetof(struct lustre_capa, lc_keyid) == 24, " found %llu\n",
                  (unsigned long long)(int)offsetof(struct lustre_capa, lc_keyid));
         LASSERTF((int)sizeof(((struct lustre_capa *)0)->lc_keyid) == 4, " found %llu\n",
                  (unsigned long long)(int)sizeof(((struct lustre_capa *)0)->lc_keyid));
-        LASSERTF((int)offsetof(struct lustre_capa, lc_expiry) == 24, " found %llu\n",
+        LASSERTF((int)offsetof(struct lustre_capa, lc_expiry) == 28, " found %llu\n",
                  (unsigned long long)(int)offsetof(struct lustre_capa, lc_expiry));
         LASSERTF((int)sizeof(((struct lustre_capa *)0)->lc_expiry) == 8, " found %llu\n",
                  (unsigned long long)(int)sizeof(((struct lustre_capa *)0)->lc_expiry));
-        LASSERTF((int)offsetof(struct lustre_capa, lc_flags) == 32, " found %llu\n",
+        LASSERTF((int)offsetof(struct lustre_capa, lc_flags) == 36, " found %llu\n",
                  (unsigned long long)(int)offsetof(struct lustre_capa, lc_flags));
         LASSERTF((int)sizeof(((struct lustre_capa *)0)->lc_flags) == 4, " found %llu\n",
                  (unsigned long long)(int)sizeof(((struct lustre_capa *)0)->lc_flags));
-        LASSERTF((int)offsetof(struct lustre_capa, lc_hmac) == 36, " found %llu\n",
+        LASSERTF((int)offsetof(struct lustre_capa, lc_hmac) == 40, " found %llu\n",
                  (unsigned long long)(int)offsetof(struct lustre_capa, lc_hmac));
         LASSERTF((int)sizeof(((struct lustre_capa *)0)->lc_hmac) == 16, " found %llu\n",
                  (unsigned long long)(int)sizeof(((struct lustre_capa *)0)->lc_hmac));