From 3501d55024131ec8cf33f7113b188603768606da Mon Sep 17 00:00:00 2001 From: adilger Date: Tue, 30 Jul 2002 21:01:47 +0000 Subject: [PATCH] Always return a valid pointer or an error code from mds_*2locked_dentry(). --- lustre/mds/handler.c | 12 +++++++----- lustre/mds/mds_reint.c | 27 ++++++++++++++++----------- 2 files changed, 23 insertions(+), 16 deletions(-) diff --git a/lustre/mds/handler.c b/lustre/mds/handler.c index b720eca..48667cc 100644 --- a/lustre/mds/handler.c +++ b/lustre/mds/handler.c @@ -98,7 +98,7 @@ static int mds_sendpage(struct ptlrpc_request *req, struct file *file, struct dentry *mds_name2locked_dentry(struct mds_obd *mds, struct dentry *dir, struct vfsmount **mnt, char *name, int namelen, int lock_mode, - struct lustre_handle *lockh, + struct lustre_handle *lockh, int dir_lock_mode) { struct dentry *dchild; @@ -112,10 +112,11 @@ struct dentry *mds_name2locked_dentry(struct mds_obd *mds, struct dentry *dir, CERROR("child lookup error %ld\n", PTR_ERR(dchild)); up(&dir->d_inode->i_sem); LBUG(); + RETURN(dchild); } - if (dir_lock_mode != LCK_EX && dir_lock_mode != LCK_PW) { + if (dir_lock_mode != LCK_EX && dir_lock_mode != LCK_PW) { up(&dir->d_inode->i_sem); - ldlm_lock_decref(lockh, dir_lock_mode); + ldlm_lock_decref(lockh, dir_lock_mode); } if (lock_mode == 0 || !dchild->d_inode) @@ -130,7 +131,8 @@ struct dentry *mds_name2locked_dentry(struct mds_obd *mds, struct dentry *dir, 0, lockh); if (rc != ELDLM_OK) { l_dput(dchild); - RETURN(NULL); + up(&dir->d_inode->i_sem); + RETURN(ERR_PTR(-ENOLCK)); /* XXX translate ldlm code */ } RETURN(dchild); @@ -157,7 +159,7 @@ struct dentry *mds_fid2locked_dentry(struct mds_obd *mds, struct ll_fid *fid, 0, lockh); if (rc != ELDLM_OK) { l_dput(de); - retval = NULL; + retval = ERR_PTR(-ENOLCK); /* XXX translate ldlm code */ } RETURN(retval); diff --git a/lustre/mds/mds_reint.c b/lustre/mds/mds_reint.c index f41a621..edbe1b6 100644 --- a/lustre/mds/mds_reint.c +++ b/lustre/mds/mds_reint.c @@ -449,20 +449,21 @@ static int mds_reint_unlink(struct mds_update_record *rec, int offset, lock_mode = (req->rq_reqmsg->opc == MDS_REINT) ? LCK_CW : LCK_PW; de = mds_fid2locked_dentry(mds, rec->ur_fid1, NULL, lock_mode, &lockh); - if (!de || IS_ERR(de)) { + if (IS_ERR(de)) { LBUG(); - RETURN(-ESTALE); + RETURN(PTR_ERR(de)); } - + + name = lustre_msg_buf(req->rq_reqmsg, offset + 1); namelen = req->rq_reqmsg->buflens[offset + 1] - 1; + dchild = mds_name2locked_dentry(mds, de, NULL, name, namelen, - LCK_EX, &child_lockh, lock_mode); + LCK_EX, &child_lockh, lock_mode); - if (!dchild || IS_ERR(dchild) - || OBD_FAIL_CHECK(OBD_FAIL_MDS_REINT_UNLINK)) { + if (IS_ERR(dchild) || OBD_FAIL_CHECK(OBD_FAIL_MDS_REINT_UNLINK)) { LBUG(); - GOTO(out_unlink, rc = -ESTALE); + GOTO(out_unlink, rc = PTR_ERR(dchild)); } dir = de->d_inode; @@ -472,6 +473,7 @@ static int mds_reint_unlink(struct mds_update_record *rec, int offset, if (!inode) { CDEBUG(D_INODE, "child doesn't exist (dir %ld, name %s\n", dir->i_ino, rec->ur_name); + /* XXX should be out_unlink_cancel, or do we keep child_lockh?*/ GOTO(out_unlink_dchild, rc = -ENOENT); } else if (offset) { struct mds_body *body = lustre_msg_buf(req->rq_repmsg, 1); @@ -520,13 +522,16 @@ static int mds_reint_unlink(struct mds_update_record *rec, int offset, out_unlink_cancel: ldlm_lock_decref(&child_lockh, LCK_EX); - rc = ldlm_cli_cancel(&child_lockh); - if (rc < 0) - CERROR("failed to cancel child inode lock ino\n"); + err = ldlm_cli_cancel(&child_lockh); + if (err < 0) { + CERROR("failed to cancel child inode lock: err = %d\n", err); + if (!rc) + rc = -ENOLCK; /*XXX translate LDLM lock error */ + } out_unlink_dchild: l_dput(dchild); -out_unlink: up(&dir->i_sem); +out_unlink: ldlm_lock_decref(&lockh, lock_mode); l_dput(de); req->rq_status = rc; -- 1.8.3.1