X-Git-Url: https://git.whamcloud.com/?a=blobdiff_plain;f=lustre%2Fllite%2Fxattr_cache.c;h=d23808aad932a2ace80fb9bb383749c55b5d1cab;hb=c5fa6f85b6bceef574a52752eefc4847d1b571f5;hp=9df1bfa24581e514799a4d761098bdecae7edc23;hpb=e53d1c18ea9f8c08d55d573e8f0993e582c44c20;p=fs%2Flustre-release.git diff --git a/lustre/llite/xattr_cache.c b/lustre/llite/xattr_cache.c index 9df1bfa..d23808a 100644 --- a/lustre/llite/xattr_cache.c +++ b/lustre/llite/xattr_cache.c @@ -84,7 +84,7 @@ static void ll_xattr_cache_init(struct ll_inode_info *lli) LASSERT(lli != NULL); - CFS_INIT_LIST_HEAD(&lli->lli_xattrs); + INIT_LIST_HEAD(&lli->lli_xattrs); lli->lli_flags |= LLIF_XATTR_CACHE; } @@ -121,13 +121,13 @@ static int ll_xattr_cache_find(struct list_head *cache, } /** - * This adds or updates an xattr. + * This adds an xattr. * * Add @xattr_name attr with @xattr_val value and @xattr_val_len length, - * if the attribute already exists, then update its value. * * \retval 0 success * \retval -ENOMEM if no memory could be allocated for the cached attr + * \retval -EPROTO if duplicate xattr is being added */ static int ll_xattr_cache_add(struct list_head *cache, const char *xattr_name, @@ -139,31 +139,11 @@ static int ll_xattr_cache_add(struct list_head *cache, ENTRY; if (ll_xattr_cache_find(cache, xattr_name, &xattr) == 0) { - /* Found a cached EA, update it */ - - if (xattr_val_len != xattr->xe_vallen) { - char *val; - OBD_ALLOC(val, xattr_val_len); - if (val == NULL) { - CDEBUG(D_CACHE, "failed to allocate %u bytes " - "for xattr %s update\n", - xattr_val_len, - xattr_name); - RETURN(-ENOMEM); - } - OBD_FREE(xattr->xe_value, xattr->xe_vallen); - xattr->xe_value = val; - xattr->xe_vallen = xattr_val_len; - } - memcpy(xattr->xe_value, xattr_val, xattr_val_len); - - CDEBUG(D_CACHE, "update: [%s]=%.*s\n", xattr_name, - xattr_val_len, xattr_val); - - RETURN(0); + CDEBUG(D_CACHE, "duplicate xattr: [%s]\n", xattr_name); + RETURN(-EPROTO); } - OBD_SLAB_ALLOC_PTR_GFP(xattr, xattr_kmem, __GFP_IO); + OBD_SLAB_ALLOC_PTR_GFP(xattr, xattr_kmem, GFP_NOFS); if (xattr == NULL) { CDEBUG(D_CACHE, "failed to allocate xattr\n"); RETURN(-ENOMEM); @@ -275,7 +255,7 @@ static int ll_xattr_cache_list(struct list_head *cache, * \retval 0 @cache is not initialized * \retval 1 @cache is initialized */ -int ll_xattr_cache_valid(struct ll_inode_info *lli) +static int ll_xattr_cache_valid(struct ll_inode_info *lli) { return !!(lli->lli_flags & LLIF_XATTR_CACHE); } @@ -316,7 +296,7 @@ int ll_xattr_cache_destroy(struct inode *inode) } /** - * Match or enqueue a PR or PW LDLM lock. + * Match or enqueue a PR lock. * * Find or request an LDLM lock with xattr data. * Since LDLM does not provide API for atomic match_or_enqueue, @@ -334,10 +314,12 @@ static int ll_xattr_find_get_lock(struct inode *inode, struct lustre_handle lockh = { 0 }; struct md_op_data *op_data; struct ll_inode_info *lli = ll_i2info(inode); - struct ldlm_enqueue_info einfo = { .ei_type = LDLM_IBITS, - .ei_mode = it_to_lock_mode(oit), - .ei_cb_bl = ll_md_blocking_ast, - .ei_cb_cp = ldlm_completion_ast }; + struct ldlm_enqueue_info einfo = { + .ei_type = LDLM_IBITS, + .ei_mode = it_to_lock_mode(oit), + .ei_cb_bl = &ll_md_blocking_ast, + .ei_cb_cp = &ldlm_completion_ast, + }; struct ll_sb_info *sbi = ll_i2sbi(inode); struct obd_export *exp = sbi->ll_md_exp; int rc; @@ -345,15 +327,18 @@ static int ll_xattr_find_get_lock(struct inode *inode, ENTRY; mutex_lock(&lli->lli_xattrs_enq_lock); - /* Try matching first. */ - mode = ll_take_md_lock(inode, MDS_INODELOCK_XATTR, &lockh, 0, - oit->it_op == IT_SETXATTR ? LCK_PW : - (LCK_PR | LCK_PW)); - if (mode != 0) { - /* fake oit in mdc_revalidate_lock() manner */ - oit->d.lustre.it_lock_handle = lockh.cookie; - oit->d.lustre.it_lock_mode = mode; - goto out; + /* inode may have been shrunk and recreated, so data is gone, match lock + * only when data exists. */ + if (ll_xattr_cache_valid(lli)) { + /* Try matching first. */ + mode = ll_take_md_lock(inode, MDS_INODELOCK_XATTR, &lockh, 0, + LCK_PR); + if (mode != 0) { + /* fake oit in mdc_revalidate_lock() manner */ + oit->d.lustre.it_lock_handle = lockh.cookie; + oit->d.lustre.it_lock_mode = mode; + goto out; + } } /* Enqueue if the lock isn't cached locally. */ @@ -364,15 +349,9 @@ static int ll_xattr_find_get_lock(struct inode *inode, RETURN(PTR_ERR(op_data)); } - op_data->op_valid = OBD_MD_FLXATTR | OBD_MD_FLXATTRLS | - OBD_MD_FLXATTRLOCKED; -#ifdef CONFIG_FS_POSIX_ACL - /* If working with ACLs, we would like to cache local ACLs */ - if (sbi->ll_flags & LL_SBI_RMT_CLIENT) - op_data->op_valid |= OBD_MD_FLRMTLGETFACL; -#endif + op_data->op_valid = OBD_MD_FLXATTR | OBD_MD_FLXATTRLS; - rc = md_enqueue(exp, &einfo, oit, op_data, &lockh, NULL, 0, NULL, 0); + rc = md_enqueue(exp, &einfo, NULL, oit, op_data, &lockh, 0); ll_finish_md_op_data(op_data); if (rc < 0) { @@ -432,7 +411,11 @@ static int ll_xattr_cache_refill(struct inode *inode, struct lookup_intent *oit) if (oit->d.lustre.it_status < 0) { CDEBUG(D_CACHE, "getxattr intent returned %d for fid "DFID"\n", oit->d.lustre.it_status, PFID(ll_inode2fid(inode))); - GOTO(out_destroy, rc = oit->d.lustre.it_status); + rc = oit->d.lustre.it_status; + /* xattr data is so large that we don't want to cache it */ + if (rc == -ERANGE) + rc = -EAGAIN; + GOTO(out_destroy, rc); } body = req_capsule_server_get(&req->rq_pill, &RMF_MDT_BODY); @@ -442,24 +425,25 @@ static int ll_xattr_cache_refill(struct inode *inode, struct lookup_intent *oit) } /* do not need swab xattr data */ xdata = req_capsule_server_sized_get(&req->rq_pill, &RMF_EADATA, - body->eadatasize); + body->mbo_eadatasize); xval = req_capsule_server_sized_get(&req->rq_pill, &RMF_EAVALS, - body->aclsize); + body->mbo_aclsize); xsizes = req_capsule_server_sized_get(&req->rq_pill, &RMF_EAVALS_LENS, - body->max_mdsize * sizeof(__u32)); + body->mbo_max_mdsize * + sizeof(__u32)); if (xdata == NULL || xval == NULL || xsizes == NULL) { CERROR("wrong setxattr reply\n"); GOTO(out_destroy, rc = -EPROTO); } - xtail = xdata + body->eadatasize; - xvtail = xval + body->aclsize; + xtail = xdata + body->mbo_eadatasize; + xvtail = xval + body->mbo_aclsize; CDEBUG(D_CACHE, "caching: xdata=%p xtail=%p\n", xdata, xtail); ll_xattr_cache_init(lli); - for (i = 0; i < body->max_mdsize; i++) { + for (i = 0; i < body->mbo_max_mdsize; i++) { CDEBUG(D_CACHE, "caching [%s]=%.*s\n", xdata, *xsizes, xval); /* Perform consistency checks: attr names and vals in pill */ if (memchr(xdata, 0, xtail - xdata) == NULL) { @@ -470,6 +454,11 @@ static int ll_xattr_cache_refill(struct inode *inode, struct lookup_intent *oit) rc = -EPROTO; } else if (OBD_FAIL_CHECK(OBD_FAIL_LLITE_XATTR_ENOMEM)) { rc = -ENOMEM; + } else if (!strcmp(xdata, XATTR_NAME_ACL_ACCESS)) { + /* Filter out ACL ACCESS since it's cached separately */ + CDEBUG(D_CACHE, "not caching %s\n", + XATTR_NAME_ACL_ACCESS); + rc = 0; } else { rc = ll_xattr_cache_add(&lli->lli_xattrs, xdata, xval, *xsizes); @@ -490,9 +479,8 @@ static int ll_xattr_cache_refill(struct inode *inode, struct lookup_intent *oit) GOTO(out_maybe_drop, rc); out_maybe_drop: - /* drop lock on error or getxattr */ - if (rc != 0 || oit->it_op != IT_SETXATTR) - ll_intent_drop_lock(oit); + + ll_intent_drop_lock(oit); if (rc != 0) up_write(&lli->lli_xattrs_list_rwsem); @@ -577,64 +565,3 @@ out: return rc; } - -/** - * Set/update an xattr value or remove xattr using the write-through cache. - * - * Set/update the xattr value (if @valid has OBD_MD_FLXATTR) of @name to @newval - * or - * remove the xattr @name (@valid has OBD_MD_FLXATTRRM set) from @inode. - * @flags is either XATTR_CREATE or XATTR_REPLACE as defined by setxattr(2) - * - * \retval 0 no error occured - * \retval -EPROTO network protocol error - * \retval -ENOMEM not enough memory for the cache - * \retval -ERANGE the buffer is not large enough - * \retval -ENODATA no such attr (in the removal case) - */ -int ll_xattr_cache_update(struct inode *inode, - const char *name, - const char *newval, - size_t size, - __u64 valid, - int flags) -{ - struct lookup_intent oit = { .it_op = IT_SETXATTR }; - struct ll_sb_info *sbi = ll_i2sbi(inode); - struct ptlrpc_request *req = NULL; - struct ll_inode_info *lli = ll_i2info(inode); - struct obd_capa *oc; - int rc; - - ENTRY; - - LASSERT(!!(valid & OBD_MD_FLXATTR) ^ !!(valid & OBD_MD_FLXATTRRM)); - - rc = ll_xattr_cache_refill(inode, &oit); - if (rc) - RETURN(rc); - - oc = ll_mdscapa_get(inode); - rc = md_setxattr(sbi->ll_md_exp, ll_inode2fid(inode), oc, - valid | OBD_MD_FLXATTRLOCKED, name, newval, - size, 0, flags, ll_i2suppgid(inode), &req); - capa_put(oc); - - if (rc) { - ll_intent_drop_lock(&oit); - GOTO(out, rc); - } - - if (valid & OBD_MD_FLXATTR) - rc = ll_xattr_cache_add(&lli->lli_xattrs, name, newval, size); - else if (valid & OBD_MD_FLXATTRRM) - rc = ll_xattr_cache_del(&lli->lli_xattrs, name); - - ll_intent_drop_lock(&oit); - GOTO(out, rc); -out: - up_write(&lli->lli_xattrs_list_rwsem); - ptlrpc_req_finished(req); - - return rc; -}