From: Swapnil Pimpale <spimp...@ddn.com> Callers of ll_splice_alias() should not assign the returned pointer to the dentry since it can be an err pointer. Fixed the above bug using a temporary dentry pointer. This temporary pointer is assigned to dentry only if ll_splice_alias has not returned an err pointer.
Lustre-change: http://review.whamcloud.com/7460 Intel-bug-id: https://jira.hpdd.intel.com/browse/LU-3807 Signed-off-by: Swapnil Pimpale <spimp...@ddn.com> Reviewed-by: Fan Yong <fan.y...@intel.com> Reviewed-by: John L. Hammond <john.hamm...@intel.com> Reviewed-by: Oleg Drokin <oleg.dro...@intel.com> Signed-off-by: Peng Tao <bergw...@gmail.com> Signed-off-by: Andreas Dilger <andreas.dil...@intel.com> --- drivers/staging/lustre/lustre/llite/namei.c | 21 ++++++++++-------- drivers/staging/lustre/lustre/llite/statahead.c | 27 +++++++++++++---------- 2 files changed, 27 insertions(+), 21 deletions(-) diff --git a/drivers/staging/lustre/lustre/llite/namei.c b/drivers/staging/lustre/lustre/llite/namei.c index c760059..3cfd34d 100644 --- a/drivers/staging/lustre/lustre/llite/namei.c +++ b/drivers/staging/lustre/lustre/llite/namei.c @@ -428,12 +428,12 @@ struct dentry *ll_splice_alias(struct inode *inode, struct dentry *de) int ll_lookup_it_finish(struct ptlrpc_request *request, struct lookup_intent *it, void *data) { - struct it_cb_data *icbd = data; - struct dentry **de = icbd->icbd_childp; - struct inode *parent = icbd->icbd_parent; - struct inode *inode = NULL; - __u64 bits = 0; - int rc; + struct it_cb_data *icbd = data; + struct dentry **de = icbd->icbd_childp; + struct inode *parent = icbd->icbd_parent; + struct inode *inode = NULL; + __u64 bits = 0; + int rc; /* NB 1 request reference will be taken away by ll_intent_lock() * when I return */ @@ -460,9 +460,12 @@ int ll_lookup_it_finish(struct ptlrpc_request *request, * Atoimc_open may passin hashed dentries for open. */ if (d_unhashed(*de)) { - *de = ll_splice_alias(inode, *de); - if (IS_ERR(*de)) - return PTR_ERR(*de); + struct dentry *alias; + + alias = ll_splice_alias(inode, *de); + if (IS_ERR(alias)) + return PTR_ERR(alias); + *de = alias; } if (!it_disposition(it, DISP_LOOKUP_NEG)) { diff --git a/drivers/staging/lustre/lustre/llite/statahead.c b/drivers/staging/lustre/lustre/llite/statahead.c index 183b415..0db4006 100644 --- a/drivers/staging/lustre/lustre/llite/statahead.c +++ b/drivers/staging/lustre/lustre/llite/statahead.c @@ -1500,14 +1500,14 @@ ll_sai_unplug(struct ll_statahead_info *sai, struct ll_sa_entry *entry) int do_statahead_enter(struct inode *dir, struct dentry **dentryp, int only_unplug) { - struct ll_inode_info *lli = ll_i2info(dir); - struct ll_statahead_info *sai = lli->lli_sai; - struct dentry *parent; - struct ll_sa_entry *entry; - struct ptlrpc_thread *thread; - struct l_wait_info lwi = { 0 }; - int rc = 0; - struct ll_inode_info *plli; + struct ll_inode_info *lli = ll_i2info(dir); + struct ll_statahead_info *sai = lli->lli_sai; + struct dentry *parent; + struct ll_sa_entry *entry; + struct ptlrpc_thread *thread; + struct l_wait_info lwi = { 0 }; + int rc = 0; + struct ll_inode_info *plli; LASSERT(lli->lli_opendir_pid == current_pid()); @@ -1585,12 +1585,15 @@ int do_statahead_enter(struct inode *dir, struct dentry **dentryp, ll_inode2fid(inode), &bits); if (rc == 1) { if ((*dentryp)->d_inode == NULL) { - *dentryp = ll_splice_alias(inode, - *dentryp); - if (IS_ERR(*dentryp)) { + struct dentry *alias; + + alias = ll_splice_alias(inode, + *dentryp); + if (IS_ERR(alias)) { ll_sai_unplug(sai, entry); - return PTR_ERR(*dentryp); + return PTR_ERR(alias); } + *dentryp = alias; } else if ((*dentryp)->d_inode != inode) { /* revalidate, but inode is recreated */ CDEBUG(D_READA, -- 1.7.9.5 -- To unsubscribe from this list: send the line "unsubscribe linux-kernel" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html Please read the FAQ at http://www.tux.org/lkml/