diff --git a/lustre/autoconf/lustre-core.m4 b/lustre/autoconf/lustre-core.m4
index 527b8001d453f692bf3119b81df5d82295b7642c..da845ece1358e69ffc5f6cab626eb5122709429b 100644
--- a/lustre/autoconf/lustre-core.m4
+++ b/lustre/autoconf/lustre-core.m4
@@ -621,6 +621,22 @@ AC_DEFUN([LC_FUNC_SET_FS_PWD],
 ])
 ])
 
+#
+# check for FS_RENAME_DOES_D_MOVE flag
+#
+AC_DEFUN([LC_FS_RENAME_DOES_D_MOVE],
+[AC_MSG_CHECKING([if kernel has FS_RENAME_DOES_D_MOVE flag])
+LB_LINUX_TRY_COMPILE([
+        #include <linux/fs.h>
+],[
+        int v = FS_RENAME_DOES_D_MOVE;
+],[
+        AC_MSG_RESULT([yes])
+        AC_DEFINE(HAVE_FS_RENAME_DOES_D_MOVE, 1, [kernel has FS_RENAME_DOES_D_MOVE flag])
+],[
+        AC_MSG_RESULT([no])
+])
+])
 
 #
 # LC_FUNC_MS_FLOCK_LOCK
@@ -1342,6 +1358,7 @@ AC_DEFUN([LC_PROG_LINUX],
 	  
 	  # 2.6.22
           LC_INVALIDATE_BDEV_2ARG
+          LC_FS_RENAME_DOES_D_MOVE
           # 2.6.23
           LC_UNREGISTER_BLKDEV_RETURN_INT
           LC_KERNEL_SPLICE_READ
diff --git a/lustre/include/linux/lustre_compat25.h b/lustre/include/linux/lustre_compat25.h
index 1ff876555b64da2250c92eda834a0387d275ec55..861d95fe50a45e863a67bebb9ce42af227092217 100644
--- a/lustre/include/linux/lustre_compat25.h
+++ b/lustre/include/linux/lustre_compat25.h
@@ -538,5 +538,11 @@ int ll_unregister_blkdev(unsigned int dev, const char *name)
 #define ll_invalidate_bdev(a,b)         invalidate_bdev((a))
 #endif
 
+#ifdef HAVE_FS_RENAME_DOES_D_MOVE
+#define LL_RENAME_DOES_D_MOVE	FS_RENAME_DOES_D_MOVE
+#else
+#define LL_RENAME_DOES_D_MOVE	FS_ODD_RENAME
+#endif
+
 #endif /* __KERNEL__ */
 #endif /* _COMPAT25_H */
diff --git a/lustre/llite/namei.c b/lustre/llite/namei.c
index 2a0733fdd82fa6488d74de26785066356812ad04..b6a344dd94cbaacd1aa34ba99376df3ac990fbd0 100644
--- a/lustre/llite/namei.c
+++ b/lustre/llite/namei.c
@@ -1311,8 +1311,16 @@ static int ll_link(struct dentry *old_dentry, struct inode *dir,
 static int ll_rename(struct inode *old_dir, struct dentry *old_dentry,
                      struct inode *new_dir, struct dentry *new_dentry)
 {
-        return ll_rename_generic(old_dir, &old_dentry->d_name, new_dir,
-                                 &new_dentry->d_name);
+        int err;
+        err = ll_rename_generic(old_dir, &old_dentry->d_name, new_dir,
+                                &new_dentry->d_name);
+        if (!err) {
+#ifndef HAVE_FS_RENAME_DOES_D_MOVE
+                if (!S_ISDIR(old_dentry->d_inode->i_mode))
+#endif
+                        d_move(old_dentry, new_dentry);
+        }
+        return err;
 }
 #endif
 
diff --git a/lustre/obdclass/obd_mount.c b/lustre/obdclass/obd_mount.c
index 663015d62c25c5cbcdce48ddb6e0f3ce983b7ec8..ce82e45598e17e3293614559eb32a1a5e6b82bb1 100644
--- a/lustre/obdclass/obd_mount.c
+++ b/lustre/obdclass/obd_mount.c
@@ -2014,7 +2014,8 @@ struct file_system_type lustre_fs_type = {
         .name         = "lustre",
         .get_sb       = lustre_get_sb,
         .kill_sb      = lustre_kill_super,
-        .fs_flags     = FS_BINARY_MOUNTDATA | FS_REQUIRES_DEV,
+        .fs_flags     = FS_BINARY_MOUNTDATA | FS_REQUIRES_DEV |
+                        LL_RENAME_DOES_D_MOVE,
 };
 
 #else