diff --git a/lustre/mds/mds_reint.c b/lustre/mds/mds_reint.c
index 22ca65b567f0e64aca18142ff0c1d893efcb9ddc..626248d4040a888469e8d0e8d3479d59504aac7d 100644
--- a/lustre/mds/mds_reint.c
+++ b/lustre/mds/mds_reint.c
@@ -1664,6 +1664,10 @@ static int mds_reint_rename(struct mds_update_record *rec, int offset,
              de_new->d_inode->i_ino == de_tgtdir->d_inode->i_ino))
                 GOTO(cleanup, rc = -EINVAL);
 
+        if (de_old->d_inode == de_new->d_inode) {
+                GOTO(cleanup, rc = 0);
+        }
+
         /* if we are about to remove the target at first, pass the EA of
          * that inode to client to perform and cleanup on OST */
         body = lustre_msg_buf(req->rq_repmsg, 0, sizeof (*body));
diff --git a/lustre/tests/multiop.c b/lustre/tests/multiop.c
index 2be0b93d10a81033328a43f873e31d68cce8eecc..de59be64fd7e3a701b6ed2e712f7a9cbbcd5e4be 100755
--- a/lustre/tests/multiop.c
+++ b/lustre/tests/multiop.c
@@ -21,10 +21,13 @@ char usage[] =
 "        D  open(O_DIRECTORY)\n"
 "        o  open(O_RDONLY)\n"
 "        O  open(O_CREAT|O_RDWR)\n"
+"        L  link\n"
+"        l  symlink\n"
 "        u  unlink\n"
 "        U  munmap\n"
 "        m  mknod\n"
 "        M  rw mmap to EOF (must open and stat prior)\n"
+"        N  rename\n"
 "        c  close\n"
 "        _  wait for signal\n"
 "        R  reference entire mmap-ed region\n"
@@ -41,15 +44,28 @@ char usage[] =
 
 void null_handler(int unused) { }
 
+static const char *
+pop_arg(int argc, char *argv[])
+{
+	static int cur_arg = 3;
+
+	if (cur_arg >= argc)
+		return NULL;
+
+	return argv[cur_arg++];
+}
+#define POP_ARG() (pop_arg(argc, argv))
+
 int main(int argc, char **argv)
 {
         char *fname, *commands;
+	const char *newfile;
         struct stat st;
 	size_t mmap_len, i;
 	unsigned char *mmap_ptr = NULL, junk = 0;
         int fd = -1;
 
-        if (argc != 3) {
+        if (argc < 3) {
                 fprintf(stderr, usage, argv[0]);
                 exit(1);
         }
@@ -82,6 +98,24 @@ int main(int argc, char **argv)
 				exit(1);
 			}
 			break;
+		case 'l':
+			newfile = POP_ARG();
+			if (!newfile)
+				newfile = fname;
+			if (symlink(fname, newfile)) {
+				perror("symlink()");
+				exit(1);
+			}
+			break;
+		case 'L':
+			newfile = POP_ARG();
+			if (!newfile)
+				newfile = fname;
+			if (link(fname, newfile)) {
+				perror("symlink()");
+				exit(1);
+			}
+			break;
                 case 'm':
                         if (mknod(fname, S_IFREG | 0644, 0) == -1) {
                                 perror("mknod(S_IFREG|0644, 0)");
@@ -97,6 +131,15 @@ int main(int argc, char **argv)
 				exit(1);
 			}
 			break;
+		case 'N':
+			newfile = POP_ARG();
+			if (!newfile)
+				newfile = fname;
+			if (rename (fname, newfile)) {
+				perror("rename()");
+				exit(1);
+			}
+			break;
                 case 'O':
                         fd = open(fname, O_CREAT|O_RDWR, 0644);
                         if (fd == -1) {
diff --git a/lustre/tests/rename.pl b/lustre/tests/rename.pl
index ee9bb4d228428a6c9be4b425db82eb354442d2b6..dd6b5dc15874e06b555571308639a9c4b0faab76 100644
--- a/lustre/tests/rename.pl
+++ b/lustre/tests/rename.pl
@@ -93,7 +93,7 @@ for (my $i=1; $i<=$num_threads; $i++) {
 # Wait for all our threads to finish.
 my $child = 0;
 do {
-    $child = waitpid(-1, WNOHANG);
+    $child = waitpid(-1, 0);
 } until $child > 0;
 sleep 1;
 
diff --git a/lustre/tests/sanity.sh b/lustre/tests/sanity.sh
index 0e9f0b09267f23774f2bacb7554d226d4a57cba0..1147bcf65cf6dcaa42eab06b21c7b6c9b4668800 100644
--- a/lustre/tests/sanity.sh
+++ b/lustre/tests/sanity.sh
@@ -611,6 +611,19 @@ test_24k() {
 }
 run_test 24k "touch .../R11a/f; mv .../R11a/f .../R11a/d ======="
 
+# bug 2429 - rename foo foo foo creates invalid file
+test_24l() {
+	f="$DIR/f24l"
+	multiop $f OcNs || error
+}
+run_test 24l "Renaming a file to itself ========================"
+
+test_24m() {
+	f="$DIR/f24m"
+	multiop $f OcLN ${f}2 ${f}2 || error
+}
+run_test 24m "Renaming a file to a hard link to itself ========="
+
 test_25a() {
 	echo '== symlink sanity ============================================='
 	mkdir $DIR/d25