diff options
Diffstat (limited to 'drivers/staging/lustre/lustre/llite/namei.c')
-rw-r--r-- | drivers/staging/lustre/lustre/llite/namei.c | 124 |
1 files changed, 67 insertions, 57 deletions
diff --git a/drivers/staging/lustre/lustre/llite/namei.c b/drivers/staging/lustre/lustre/llite/namei.c index fc8d264f6c9a..25a6ea580f00 100644 --- a/drivers/staging/lustre/lustre/llite/namei.c +++ b/drivers/staging/lustre/lustre/llite/namei.c @@ -195,101 +195,107 @@ static void ll_invalidate_negative_children(struct inode *dir) int ll_md_blocking_ast(struct ldlm_lock *lock, struct ldlm_lock_desc *desc, void *data, int flag) { - int rc; struct lustre_handle lockh; + int rc; switch (flag) { case LDLM_CB_BLOCKING: ldlm_lock2handle(lock, &lockh); rc = ldlm_cli_cancel(&lockh, LCF_ASYNC); if (rc < 0) { - CDEBUG(D_INODE, "ldlm_cli_cancel: %d\n", rc); + CDEBUG(D_INODE, "ldlm_cli_cancel: rc = %d\n", rc); return rc; } break; case LDLM_CB_CANCELING: { struct inode *inode = ll_inode_from_resource_lock(lock); - struct ll_inode_info *lli; __u64 bits = lock->l_policy_data.l_inodebits.bits; - struct lu_fid *fid; - ldlm_mode_t mode = lock->l_req_mode; /* Inode is set to lock->l_resource->lr_lvb_inode * for mdc - bug 24555 */ LASSERT(lock->l_ast_data == NULL); - /* Invalidate all dentries associated with this inode */ if (inode == NULL) break; + /* Invalidate all dentries associated with this inode */ LASSERT(lock->l_flags & LDLM_FL_CANCELING); - if (bits & MDS_INODELOCK_XATTR) + if (!fid_res_name_eq(ll_inode2fid(inode), + &lock->l_resource->lr_name)) { + LDLM_ERROR(lock, "data mismatch with object "DFID"(%p)", + PFID(ll_inode2fid(inode)), inode); + LBUG(); + } + + if (bits & MDS_INODELOCK_XATTR) { ll_xattr_cache_destroy(inode); + bits &= ~MDS_INODELOCK_XATTR; + } /* For OPEN locks we differentiate between lock modes * LCK_CR, LCK_CW, LCK_PR - bug 22891 */ - if (bits & (MDS_INODELOCK_LOOKUP | MDS_INODELOCK_UPDATE | - MDS_INODELOCK_LAYOUT | MDS_INODELOCK_PERM)) - ll_have_md_lock(inode, &bits, LCK_MINMODE); - if (bits & MDS_INODELOCK_OPEN) - ll_have_md_lock(inode, &bits, mode); - - fid = ll_inode2fid(inode); - if (!fid_res_name_eq(fid, &lock->l_resource->lr_name)) - LDLM_ERROR(lock, "data mismatch with object " - DFID" (%p)", PFID(fid), inode); + ll_have_md_lock(inode, &bits, lock->l_req_mode); if (bits & MDS_INODELOCK_OPEN) { - int flags = 0; + fmode_t fmode; + switch (lock->l_req_mode) { case LCK_CW: - flags = FMODE_WRITE; + fmode = FMODE_WRITE; break; case LCK_PR: - flags = FMODE_EXEC; + fmode = FMODE_EXEC; break; case LCK_CR: - flags = FMODE_READ; + fmode = FMODE_READ; break; default: - CERROR("Unexpected lock mode for OPEN lock " - "%d, inode %ld\n", lock->l_req_mode, - inode->i_ino); + LDLM_ERROR(lock, "bad lock mode for OPEN lock"); + LBUG(); } - ll_md_real_close(inode, flags); + + ll_md_real_close(inode, fmode); } - lli = ll_i2info(inode); + if (bits & (MDS_INODELOCK_LOOKUP | MDS_INODELOCK_UPDATE | + MDS_INODELOCK_LAYOUT | MDS_INODELOCK_PERM)) + ll_have_md_lock(inode, &bits, LCK_MINMODE); + if (bits & MDS_INODELOCK_LAYOUT) { - struct cl_object_conf conf = { { 0 } }; + struct cl_object_conf conf = { + .coc_opc = OBJECT_CONF_INVALIDATE, + .coc_inode = inode, + }; - conf.coc_opc = OBJECT_CONF_INVALIDATE; - conf.coc_inode = inode; rc = ll_layout_conf(inode, &conf); - if (rc) - CDEBUG(D_INODE, "invaliding layout %d.\n", rc); + if (rc < 0) + CDEBUG(D_INODE, "cannot invalidate layout of " + DFID": rc = %d\n", + PFID(ll_inode2fid(inode)), rc); } if (bits & MDS_INODELOCK_UPDATE) { + struct ll_inode_info *lli = ll_i2info(inode); + spin_lock(&lli->lli_lock); lli->lli_flags &= ~LLIF_MDS_SIZE_LOCK; spin_unlock(&lli->lli_lock); } - if (S_ISDIR(inode->i_mode) && - (bits & MDS_INODELOCK_UPDATE)) { + if ((bits & MDS_INODELOCK_UPDATE) && S_ISDIR(inode->i_mode)) { CDEBUG(D_INODE, "invalidating inode %lu\n", inode->i_ino); truncate_inode_pages(inode->i_mapping, 0); ll_invalidate_negative_children(inode); } - if (inode->i_sb->s_root && - inode != inode->i_sb->s_root->d_inode && - (bits & (MDS_INODELOCK_LOOKUP | MDS_INODELOCK_PERM))) + if ((bits & (MDS_INODELOCK_LOOKUP | MDS_INODELOCK_PERM)) && + inode->i_sb->s_root != NULL && + inode != inode->i_sb->s_root->d_inode) ll_invalidate_aliases(inode); + iput(inode); break; } @@ -400,11 +406,16 @@ static struct dentry *ll_find_alias(struct inode *inode, struct dentry *dentry) struct dentry *ll_splice_alias(struct inode *inode, struct dentry *de) { struct dentry *new; + int rc; if (inode) { new = ll_find_alias(inode, de); if (new) { - ll_dops_init(new, 1, 1); + rc = ll_d_init(new); + if (rc < 0) { + dput(new); + return ERR_PTR(rc); + } d_move(new, de); iput(inode); CDEBUG(D_DENTRY, @@ -413,8 +424,9 @@ struct dentry *ll_splice_alias(struct inode *inode, struct dentry *de) return new; } } - ll_dops_init(de, 1, 1); - __d_lustre_invalidate(de); + rc = ll_d_init(de); + if (rc < 0) + return ERR_PTR(rc); d_add(de, inode); CDEBUG(D_DENTRY, "Add dentry %p inode %p refc %d flags %#x\n", de, de->d_inode, d_count(de), de->d_flags); @@ -453,10 +465,22 @@ int ll_lookup_it_finish(struct ptlrpc_request *request, } /* Only hash *de if it is unhashed (new dentry). - * Atoimc_open may passin hashed dentries for open. + * Atoimc_open may passing hashed dentries for open. */ - if (d_unhashed(*de)) - *de = ll_splice_alias(inode, *de); + if (d_unhashed(*de)) { + struct dentry *alias; + + alias = ll_splice_alias(inode, *de); + if (IS_ERR(alias)) + return PTR_ERR(alias); + *de = alias; + } else if (!it_disposition(it, DISP_LOOKUP_NEG) && + !it_disposition(it, DISP_OPEN_CREATE)) { + /* With DISP_OPEN_CREATE dentry will + instantiated in ll_create_it. */ + LASSERT((*de)->d_inode == NULL); + d_instantiate(*de, inode); + } if (!it_disposition(it, DISP_LOOKUP_NEG)) { /* we have lookup look - unhide dentry */ @@ -505,16 +529,6 @@ static struct dentry *ll_lookup_it(struct inode *parent, struct dentry *dentry, ll_frob_intent(&it, &lookup_it); - /* As do_lookup is called before follow_mount, root dentry may be left - * not valid, revalidate it here. */ - if (parent->i_sb->s_root && (parent->i_sb->s_root->d_inode == parent) && - (it->it_op & (IT_OPEN | IT_CREAT))) { - rc = ll_inode_revalidate_it(parent->i_sb->s_root, it, - MDS_INODELOCK_LOOKUP); - if (rc) - return ERR_PTR(rc); - } - if (it->it_op == IT_GETATTR) { rc = ll_statahead_enter(parent, &dentry, 0); if (rc == 1) { @@ -584,12 +598,8 @@ static struct dentry *ll_lookup_nd(struct inode *parent, struct dentry *dentry, parent->i_generation, parent, flags); /* Optimize away (CREATE && !OPEN). Let .create handle the race. */ - if ((flags & LOOKUP_CREATE ) && !(flags & LOOKUP_OPEN)) { - ll_dops_init(dentry, 1, 1); - __d_lustre_invalidate(dentry); - d_add(dentry, NULL); + if ((flags & LOOKUP_CREATE) && !(flags & LOOKUP_OPEN)) return NULL; - } if (flags & (LOOKUP_PARENT|LOOKUP_OPEN|LOOKUP_CREATE)) itp = NULL; |