X-Git-Url: https://git.whamcloud.com/?a=blobdiff_plain;f=lustre%2Fobdclass%2Fcapa.c;h=be92e790e3c7c124a17473aa6fd08af33ff026d4;hb=da54b94dbb971b7ee163928bde59640f3eaf10e3;hp=8d2cb215ca76ab79e7abbb46b92bfb2507089fe5;hpb=7c4035f317111463f62b708f073cee8ef01e52dd;p=fs%2Flustre-release.git diff --git a/lustre/obdclass/capa.c b/lustre/obdclass/capa.c index 8d2cb21..be92e79 100644 --- a/lustre/obdclass/capa.c +++ b/lustre/obdclass/capa.c @@ -28,6 +28,7 @@ #define DEBUG_SUBSYSTEM S_SEC +#ifdef __KERNEL__ #include #include #include @@ -39,7 +40,12 @@ #include #include #include +#else +#include +#endif + #include +#include kmem_cache_t *capa_cachep = NULL; @@ -83,31 +89,39 @@ find_capa(struct hlist_head *head, uid_t uid, int capa_op, __u64 mdsid, { struct hlist_node *pos; struct obd_capa *ocapa; - ENTRY; - - CDEBUG(D_CACHE, "find_capa uid %u op %u mdsid "LPU64" ino %lu " - "type %d\n", uid, capa_op, mdsid, ino, type); + uid_t ouid; 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; + + DEBUG_CAPA(D_CACHE, &ocapa->c_capa, "found"); + + return ocapa; } - RETURN(NULL); + return NULL; } inline void __capa_get(struct obd_capa *ocapa) { - atomic_inc(&ocapa->c_refc); + if (ocapa->c_type != CLIENT_CAPA) + atomic_inc(&ocapa->c_refc); } static struct obd_capa * @@ -115,7 +129,6 @@ find_capa_locked(struct hlist_head *head, uid_t uid, int capa_op, __u64 mdsid, unsigned long ino, int type) { struct obd_capa *ocapa; - ENTRY; spin_lock(&capa_lock); ocapa = find_capa(head, uid, capa_op, mdsid, ino, type); @@ -123,13 +136,12 @@ find_capa_locked(struct hlist_head *head, uid_t uid, int capa_op, __u64 mdsid, __capa_get(ocapa); spin_unlock(&capa_lock); - RETURN(ocapa); + return ocapa; } static struct obd_capa *alloc_capa(void) { struct obd_capa *ocapa; - ENTRY; OBD_SLAB_ALLOC(ocapa, capa_cachep, SLAB_NOFS, sizeof(*ocapa)); if (ocapa) { @@ -137,7 +149,14 @@ static struct obd_capa *alloc_capa(void) INIT_LIST_HEAD(&ocapa->c_list); } - RETURN(ocapa); + return ocapa; +} + +static void __capa_put(struct obd_capa *ocapa) +{ + hlist_del_init(&ocapa->c_hash); + list_del_init(&ocapa->c_list); + capa_count[ocapa->c_type]--; } static void destroy_capa(struct obd_capa *ocapa) @@ -147,20 +166,19 @@ static void destroy_capa(struct obd_capa *ocapa) int capa_cache_init(void) { - int order = 0, nr_hash, i; + int nr_hash, i; - capa_hash = (struct hlist_head *) - __get_free_pages(GFP_ATOMIC, order); + OBD_ALLOC(capa_hash, PAGE_SIZE); if (!capa_hash) - panic("Cannot create capa_hash hash table"); + return -ENOMEM; - nr_hash = (1UL << order) * PAGE_SIZE / sizeof(struct hlist_head); + nr_hash = PAGE_SIZE / sizeof(struct hlist_head); LASSERT(nr_hash > NR_CAPAHASH); for (i = 0; i < NR_CAPAHASH; i++) INIT_HLIST_HEAD(capa_hash + i); - for (i =0; i < 3; i++) + for (i = 0; i < 3; i++) INIT_LIST_HEAD(&capa_list[i]); return 0; @@ -172,10 +190,13 @@ void capa_cache_cleanup(void) struct hlist_node *pos, *n; hlist_for_each_entry_safe(ocapa, pos, n, capa_hash, c_hash) { - hlist_del(&ocapa->c_hash); - list_del(&ocapa->c_list); - OBD_FREE(ocapa, sizeof(*ocapa)); + LASSERT(ocapa->c_type != CLIENT_CAPA); +// list_del_init(&ocapa->u.client.lli_list); + __capa_put(ocapa); + destroy_capa(ocapa); } + + OBD_FREE(capa_hash, PAGE_SIZE); } @@ -196,43 +217,44 @@ 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; ocapa = alloc_capa(); if (!ocapa) - RETURN(NULL); + return NULL; 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); - igrab(inode); + + if (type == CLIENT_CAPA && inode) { + LASSERT(handle); ocapa->c_inode = inode; memcpy(&ocapa->c_handle, handle, sizeof(*handle)); + INIT_LIST_HEAD(&ocapa->u.client.lli_list); } + + DEBUG_CAPA(D_CACHE, &ocapa->c_capa, "new"); + 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; @@ -244,83 +266,60 @@ get_new_capa_locked(struct hlist_head *head, uid_t uid, int capa_op,__u64 mdsid, node = node->next; if (atomic_read(&tcapa->c_refc) > 0) continue; - list_del(&tcapa->c_list); + __capa_put(tcapa); destroy_capa(tcapa); count++; } } spin_unlock(&capa_lock); - RETURN(ocapa); + return ocapa; } - - __capa_get(old); spin_unlock(&capa_lock); + destroy_capa(ocapa); - ocapa = old; - RETURN(ocapa); + return old; } -static struct obd_capa * -capa_get_locked(uid_t uid, int capa_op,__u64 mdsid, unsigned long ino, - int type, struct lustre_capa *capa, struct inode *inode, - struct lustre_handle *handle) +struct obd_capa * +capa_get(uid_t uid, int capa_op,__u64 mdsid, unsigned long ino, + int type, struct lustre_capa *capa, struct inode *inode, + struct lustre_handle *handle) { struct hlist_head *head = capa_hash + capa_hashfn(uid, capa_op, mdsid, ino); struct obd_capa *ocapa; - ENTRY; ocapa = find_capa_locked(head, uid, capa_op, mdsid, ino, type); if (ocapa) - RETURN(ocapa); + return ocapa; - if (capa) - ocapa = get_new_capa_locked(head, uid, capa_op, mdsid, ino, - type, capa, inode, handle); - RETURN(ocapa); -} - -struct obd_capa * -capa_get(uid_t uid, int capa_op, __u64 mdsid, unsigned long ino, int type, - struct lustre_capa *capa, struct inode *inode, - struct lustre_handle *handle) -{ - return capa_get_locked(uid, capa_op, mdsid, ino, type, capa, inode, - handle); -} - -static void __capa_put(struct obd_capa *ocapa, int type) -{ - hlist_del_init(&ocapa->c_hash); - list_del_init(&ocapa->c_list); - capa_count[type]--; + if (capa) { + ocapa = get_new_capa_locked(head, type, capa, inode, handle); + if (ocapa) + __capa_get(ocapa); + } + return ocapa; } -void capa_put(struct obd_capa *ocapa, int type) +void capa_put(struct obd_capa *ocapa) { - ENTRY; + if (!ocapa) + return; - if (ocapa) { - if (atomic_dec_and_lock(&ocapa->c_refc, &capa_lock)) { - if (type == CLIENT_CAPA) { - iput(ocapa->c_inode); - __capa_put(ocapa, type); - destroy_capa(ocapa); - } - spin_unlock(&capa_lock); - } + DEBUG_CAPA(D_CACHE, &ocapa->c_capa, "put"); + spin_lock(&capa_lock); + if (ocapa->c_type == CLIENT_CAPA) { + list_del_init(&ocapa->u.client.lli_list); + __capa_put(ocapa); + destroy_capa(ocapa); + } else { + atomic_dec(&ocapa->c_refc); } - - EXIT; -} - -static inline void __update_capa(struct obd_capa *ocapa, struct lustre_capa *capa) -{ - memcpy(&ocapa->c_capa, capa, sizeof(*capa)); + spin_unlock(&capa_lock); } -static int update_capa_locked(struct lustre_capa *capa, int type) +static struct obd_capa *update_capa_locked(struct lustre_capa *capa, int type) { uid_t uid = capa->lc_uid; int capa_op = capa->lc_op; @@ -329,27 +328,31 @@ static int update_capa_locked(struct lustre_capa *capa, int type) struct hlist_head *head = capa_hash + capa_hashfn(uid, capa_op, mdsid, ino); struct obd_capa *ocapa; - ENTRY; 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) + return ocapa; + + if (type == MDS_CAPA || + (type == CLIENT_CAPA && capa->lc_op == CAPA_TRUNC)) + ocapa = get_new_capa_locked(head, type, capa, NULL, NULL); - RETURN(ocapa ? 0 : -ENOENT); + return ocapa; } -int capa_renew(struct lustre_capa *capa, int type) +struct obd_capa *capa_renew(struct lustre_capa *capa, int type) { + DEBUG_CAPA(D_INFO, capa, "renew"); + return update_capa_locked(capa, type); } -void capa_hmac(struct crypto_tfm *tfm, u8 *key, struct lustre_capa *capa) +void capa_hmac(struct crypto_tfm *tfm, __u8 *key, struct lustre_capa *capa) { int keylen = CAPA_KEY_LEN; struct scatterlist sl = { @@ -357,11 +360,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) @@ -392,7 +393,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)