From: johann Date: Thu, 12 Nov 2009 09:57:44 +0000 (+0000) Subject: Branch b_release_1_8_1 X-Git-Tag: GIT_EPOCH_B_RELEASE_1_8_1~2^2~4 X-Git-Url: https://git.whamcloud.com/?a=commitdiff_plain;h=755867f781a218cbd4d794b2835361db7479516e;p=fs%2Flustre-release.git Branch b_release_1_8_1 b=20892 i=shadow i=yangsheng Use lock_rename instead of the BKL. --- diff --git a/lustre/ChangeLog b/lustre/ChangeLog index d1330a8..0f6940a 100644 --- a/lustre/ChangeLog +++ b/lustre/ChangeLog @@ -12,6 +12,12 @@ TBD Sun Microsystems, Inc. * ext4 support for RHEL5 is experimental and thus should not be used in production. +Severity : major +Bugzilla : 20892 +Description: bad entry in directory xxx: inode out of bounds +Details : fix locking issue in the rename path which could race with any + other operations updating the same directory. + ------------------------------------------------------------------------------- 2009-10-16 Sun Microsystems, Inc. diff --git a/lustre/mds/mds_fs.c b/lustre/mds/mds_fs.c index 44f2560..bca2e22 100644 --- a/lustre/mds/mds_fs.c +++ b/lustre/mds/mds_fs.c @@ -1001,10 +1001,8 @@ int mds_obd_create(struct obd_export *exp, struct obdo *oa, if (IS_ERR(handle)) GOTO(out_dput2, rc = PTR_ERR(handle)); - lock_kernel(); rc = ll_vfs_rename(parent_inode, dchild, mds->mds_vfsmnt, parent_inode, new_child, mds->mds_vfsmnt); - unlock_kernel(); if (rc) CERROR("error renaming new object "LPU64":%u: rc %d\n", oa->o_id, oa->o_generation, rc); diff --git a/lustre/mds/mds_reint.c b/lustre/mds/mds_reint.c index e39f313..73ae161 100644 --- a/lustre/mds/mds_reint.c +++ b/lustre/mds/mds_reint.c @@ -2490,6 +2490,7 @@ static int mds_reint_rename(struct mds_update_record *rec, int offset, struct dentry *de_tgtdir = NULL; struct dentry *de_old = NULL; struct dentry *de_new = NULL; + struct dentry *trap; struct inode *old_inode = NULL, *new_inode = NULL; struct inode *inodes[PTLRPC_NUM_VERSIONS] = { NULL }; struct mds_obd *mds = mds_req2mds(req); @@ -2604,11 +2605,6 @@ no_unlink: OBD_FAIL_WRITE(obd, OBD_FAIL_MDS_REINT_RENAME_WRITE, de_srcdir->d_inode->i_sb); - /* Check if we are moving old entry into its child. 2.6 does not - check for this in vfs_rename() anymore */ - if (is_subdir(de_new, de_old)) - GOTO(cleanup, rc = -EINVAL); - lmm = lustre_msg_buf(req->rq_repmsg, offset + 1, 0); /* check that lmm size is not 0 */ sz = lustre_msg_buflen(req->rq_repmsg, offset + 1) > 0 ? @@ -2619,13 +2615,23 @@ no_unlink: if (IS_ERR(handle)) GOTO(cleanup, rc = PTR_ERR(handle)); - lock_kernel(); + trap = lock_rename(de_tgtdir, de_srcdir); + /* source should not be ancestor of target */ + if (de_old == trap) { + unlock_rename(de_tgtdir, de_srcdir); + GOTO(cleanup, rc = -EINVAL); + } + /* target should not be an ancestor of source */ + if (de_new == trap) { + unlock_rename(de_tgtdir, de_srcdir); + GOTO(cleanup, rc = -ENOTEMPTY); + } de_old->d_fsdata = req; de_new->d_fsdata = req; - rc = ll_vfs_rename(de_srcdir->d_inode, de_old, mds->mds_vfsmnt, + rc = ll_vfs_rename(de_srcdir->d_inode, de_old, mds->mds_vfsmnt, de_tgtdir->d_inode, de_new, mds->mds_vfsmnt); - unlock_kernel(); + unlock_rename(de_tgtdir, de_srcdir); if (rc == 0) { struct iattr iattr;