diff options
Diffstat (limited to 'drivers/staging/lustre/lustre/llite/xattr_cache.c')
-rw-r--r-- | drivers/staging/lustre/lustre/llite/xattr_cache.c | 125 |
1 files changed, 22 insertions, 103 deletions
diff --git a/drivers/staging/lustre/lustre/llite/xattr_cache.c b/drivers/staging/lustre/lustre/llite/xattr_cache.c index 3e3be1f13502..4defa2fd83b3 100644 --- a/drivers/staging/lustre/lustre/llite/xattr_cache.c +++ b/drivers/staging/lustre/lustre/llite/xattr_cache.c @@ -98,13 +98,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, @@ -116,27 +116,8 @@ static int ll_xattr_cache_add(struct list_head *cache, 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); @@ -261,7 +242,7 @@ int ll_xattr_cache_valid(struct ll_inode_info *lli) * * Free all xattr memory. @lli is the inode info pointer. * - * \retval 0 no error occured + * \retval 0 no error occurred */ static int ll_xattr_cache_destroy_locked(struct ll_inode_info *lli) { @@ -292,14 +273,14 @@ 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, * the function handles it with a separate enq lock. * If successful, the function exits with the list lock held. * - * \retval 0 no error occured + * \retval 0 no error occurred * \retval -ENOMEM not enough memory */ static int ll_xattr_find_get_lock(struct inode *inode, @@ -322,9 +303,7 @@ static int ll_xattr_find_get_lock(struct inode *inode, 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)); + 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; @@ -340,13 +319,7 @@ 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); ll_finish_md_op_data(op_data); @@ -374,7 +347,7 @@ out: * a read or a write xattr lock depending on operation in @oit. * Intent is dropped on exit unless the operation is setxattr. * - * \retval 0 no error occured + * \retval 0 no error occurred * \retval -EPROTO network protocol error * \retval -ENOMEM not enough memory for the cache */ @@ -409,7 +382,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); @@ -447,6 +424,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); @@ -467,8 +449,7 @@ 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); if (rc != 0) @@ -496,7 +477,7 @@ out_destroy: * The resulting value/list is stored in @buffer if the former * is not larger than @size. * - * \retval 0 no error occured + * \retval 0 no error occurred * \retval -EPROTO network protocol error * \retval -ENOMEM not enough memory for the cache * \retval -ERANGE the buffer is not large enough @@ -553,65 +534,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; - - - - 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; -} |