From 20452784f0b21f4d8beb032651fcaef28aa0b15a Mon Sep 17 00:00:00 2001 From: lsy Date: Fri, 19 Aug 2005 07:29:33 +0000 Subject: [PATCH] several fixes: expiry timer adjusted. add support for ost-authorization-revocation and fid verification. --- lustre/cmobd/cm_oss_reint.c | 2 +- lustre/cobd/cache_obd.c | 5 +- lustre/include/linux/lustre_idl.h | 7 +- lustre/include/linux/lustre_sec.h | 32 ++++++- lustre/include/linux/obd.h | 3 +- lustre/include/linux/obd_class.h | 5 +- lustre/liblustre/super.c | 2 +- lustre/llite/llite_capa.c | 25 +++++- lustre/llite/llite_lib.c | 5 +- lustre/lov/lov_obd.c | 5 +- lustre/mdc/mdc_request.c | 10 ++- lustre/mds/handler.c | 6 +- lustre/mds/lproc_mds.c | 8 +- lustre/mds/mds_capa.c | 173 ++++++++++++++++++++++++++----------- lustre/mds/mds_fs.c | 2 - lustre/mds/mds_internal.h | 10 ++- lustre/mds/mds_lib.c | 1 - lustre/mds/mds_open.c | 5 +- lustre/mds/mds_reint.c | 4 +- lustre/obdclass/capa.c | 80 +++++++++-------- lustre/obdecho/echo.c | 3 +- lustre/obdecho/echo_client.c | 2 +- lustre/obdfilter/filter.c | 14 +-- lustre/obdfilter/filter_capa.c | 46 ++++++---- lustre/obdfilter/filter_internal.h | 6 +- lustre/obdfilter/filter_io.c | 24 ++--- lustre/osc/osc_request.c | 3 +- lustre/ost/ost_handler.c | 4 +- lustre/utils/wiretest.c | 16 ++-- 29 files changed, 336 insertions(+), 172 deletions(-) diff --git a/lustre/cmobd/cm_oss_reint.c b/lustre/cmobd/cm_oss_reint.c index 348e182..4e4e630 100644 --- a/lustre/cmobd/cm_oss_reint.c +++ b/lustre/cmobd/cm_oss_reint.c @@ -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: diff --git a/lustre/cobd/cache_obd.c b/lustre/cobd/cache_obd.c index 65aad33..073ff70 100644 --- a/lustre/cobd/cache_obd.c +++ b/lustre/cobd/cache_obd.c @@ -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); } diff --git a/lustre/include/linux/lustre_idl.h b/lustre/include/linux/lustre_idl.h index 81835c7..67a1784 100644 --- a/lustre/include/linux/lustre_idl.h +++ b/lustre/include/linux/lustre_idl.h @@ -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# */ diff --git a/lustre/include/linux/lustre_sec.h b/lustre/include/linux/lustre_sec.h index eea64ab..723f76a 100644 --- a/lustre/include/linux/lustre_sec.h +++ b/lustre/include/linux/lustre_sec.h @@ -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 { diff --git a/lustre/include/linux/obd.h b/lustre/include/linux/obd.h index 12569d5..1a9071e 100644 --- a/lustre/include/linux/obd.h +++ b/lustre/include/linux/obd.h @@ -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, diff --git a/lustre/include/linux/obd_class.h b/lustre/include/linux/obd_class.h index e956380..ffa3727 100644 --- a/lustre/include/linux/obd_class.h +++ b/lustre/include/linux/obd_class.h @@ -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, diff --git a/lustre/liblustre/super.c b/lustre/liblustre/super.c index 3ac318b..1215f38 100644 --- a/lustre/liblustre/super.c +++ b/lustre/liblustre/super.c @@ -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); } diff --git a/lustre/llite/llite_capa.c b/lustre/llite/llite_capa.c index 4bebb59..a19ac2f 100644 --- a/lustre/llite/llite_capa.c +++ b/lustre/llite/llite_capa.c @@ -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); } + diff --git a/lustre/llite/llite_lib.c b/lustre/llite/llite_lib.c index 8c625cd..e2267ff 100644 --- a/lustre/llite/llite_lib.c +++ b/lustre/llite/llite_lib.c @@ -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) diff --git a/lustre/lov/lov_obd.c b/lustre/lov/lov_obd.c index e79f1c0..e41219d 100644 --- a/lustre/lov/lov_obd.c +++ b/lustre/lov/lov_obd.c @@ -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 " diff --git a/lustre/mdc/mdc_request.c b/lustre/mdc/mdc_request.c index 3154f93..0783b35 100644 --- a/lustre/mdc/mdc_request.c +++ b/lustre/mdc/mdc_request.c @@ -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); diff --git a/lustre/mds/handler.c b/lustre/mds/handler.c index 044d84b..bea8ec7 100644 --- a/lustre/mds/handler.c +++ b/lustre/mds/handler.c @@ -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 diff --git a/lustre/mds/lproc_mds.c b/lustre/mds/lproc_mds.c index 1122d8a..1386670 100644 --- a/lustre/mds/lproc_mds.c +++ b/lustre/mds/lproc_mds.c @@ -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[] = { diff --git a/lustre/mds/mds_capa.c b/lustre/mds/mds_capa.c index dd85ab6..23e349f 100644 --- a/lustre/mds/mds_capa.c +++ b/lustre/mds/mds_capa.c @@ -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(¤t->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)); diff --git a/lustre/mds/mds_fs.c b/lustre/mds/mds_fs.c index f4c2b91..fcba3b8 100644 --- a/lustre/mds/mds_fs.c +++ b/lustre/mds/mds_fs.c @@ -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; diff --git a/lustre/mds/mds_internal.h b/lustre/mds/mds_internal.h index 4b910f2..f20e42e 100644 --- a/lustre/mds/mds_internal.h +++ b/lustre/mds/mds_internal.h @@ -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 */ diff --git a/lustre/mds/mds_lib.c b/lustre/mds/mds_lib.c index c0f2323..b97f854 100644 --- a/lustre/mds/mds_lib.c +++ b/lustre/mds/mds_lib.c @@ -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) { diff --git a/lustre/mds/mds_open.c b/lustre/mds/mds_open.c index 60d7477..a26d148 100644 --- a/lustre/mds/mds_open.c +++ b/lustre/mds/mds_open.c @@ -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); diff --git a/lustre/mds/mds_reint.c b/lustre/mds/mds_reint.c index eb21196..8fafdfa 100644 --- a/lustre/mds/mds_reint.c +++ b/lustre/mds/mds_reint.c @@ -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); diff --git a/lustre/obdclass/capa.c b/lustre/obdclass/capa.c index 0fa7afe..c3bbaee 100644 --- a/lustre/obdclass/capa.c +++ b/lustre/obdclass/capa.c @@ -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) diff --git a/lustre/obdecho/echo.c b/lustre/obdecho/echo.c index 0962dd9..5ff6c71 100644 --- a/lustre/obdecho/echo.c +++ b/lustre/obdecho/echo.c @@ -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); diff --git a/lustre/obdecho/echo_client.c b/lustre/obdecho/echo_client.c index b96b59f..f16a1ed 100644 --- a/lustre/obdecho/echo_client.c +++ b/lustre/obdecho/echo_client.c @@ -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); diff --git a/lustre/obdfilter/filter.c b/lustre/obdfilter/filter.c index aaa6b04..7134fb3 100644 --- a/lustre/obdfilter/filter.c +++ b/lustre/obdfilter/filter.c @@ -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); } diff --git a/lustre/obdfilter/filter_capa.c b/lustre/obdfilter/filter_capa.c index 3f52db0..258c16c 100644 --- a/lustre/obdfilter/filter_capa.c +++ b/lustre/obdfilter/filter_capa.c @@ -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); diff --git a/lustre/obdfilter/filter_internal.h b/lustre/obdfilter/filter_internal.h index 7288807..98ce1dc 100644 --- a/lustre/obdfilter/filter_internal.h +++ b/lustre/obdfilter/filter_internal.h @@ -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 diff --git a/lustre/obdfilter/filter_io.c b/lustre/obdfilter/filter_io.c index bb2d61a..0201ce4 100644 --- a/lustre/obdfilter/filter_io.c +++ b/lustre/obdfilter/filter_io.c @@ -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; diff --git a/lustre/osc/osc_request.c b/lustre/osc/osc_request.c index 57a626b..529b064 100644 --- a/lustre/osc/osc_request.c +++ b/lustre/osc/osc_request.c @@ -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; diff --git a/lustre/ost/ost_handler.c b/lustre/ost/ost_handler.c index a945bda..dd23493 100644 --- a/lustre/ost/ost_handler.c +++ b/lustre/ost/ost_handler.c @@ -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); } diff --git a/lustre/utils/wiretest.c b/lustre/utils/wiretest.c index dc2c190..1772652 100644 --- a/lustre/utils/wiretest.c +++ b/lustre/utils/wiretest.c @@ -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)); -- 1.8.3.1