diff --git a/fs/affs/dir.c b/fs/affs/dir.c
index c6339451b03f38815faaae72d4f25537700da604..460f8926d1024f6be9b7299b390484e831a9a272 100644
--- a/fs/affs/dir.c
+++ b/fs/affs/dir.c
@@ -79,7 +79,7 @@ affs_readdir(struct file *filp, void *dirent, filldir_t filldir)
 		stored++;
 	}
 	if (f_pos == 1) {
-		if (filldir(dirent, "..", 2, f_pos, filp->f_dentry->d_parent->d_inode->i_ino, DT_DIR) < 0)
+		if (filldir(dirent, "..", 2, f_pos, parent_ino(filp->f_dentry), DT_DIR) < 0)
 			return stored;
 		filp->f_pos = f_pos = 2;
 		stored++;
diff --git a/fs/devfs/base.c b/fs/devfs/base.c
index c1cbd58e8017f0086ffec352e4cc6a814ec49e78..3fac42a6957c4ab4502a837499f74cfa4cfc4ef2 100644
--- a/fs/devfs/base.c
+++ b/fs/devfs/base.c
@@ -2678,7 +2678,7 @@ static int devfs_readdir (struct file *file, void *dirent, filldir_t filldir)
       case 0:
 	scan_dir_for_removable (parent);
 	err = (*filldir) (dirent, "..", 2, file->f_pos,
-			  file->f_dentry->d_parent->d_inode->i_ino, DT_DIR);
+			  parent_ino(file->f_dentry), DT_DIR);
 	if (err == -EINVAL) break;
 	if (err < 0) return err;
 	file->f_pos++;
diff --git a/fs/fat/dir.c b/fs/fat/dir.c
index 6a81b8259688211021900699450f31278f982363..0beae388f1568eee3569c75309dec5f83a5bb479 100644
--- a/fs/fat/dir.c
+++ b/fs/fat/dir.c
@@ -531,7 +531,7 @@ static int fat_readdirx(struct inode *inode, struct file *filp, void *dirent,
 	if (!memcmp(de->name,MSDOS_DOT,11))
 		inum = inode->i_ino;
 	else if (!memcmp(de->name,MSDOS_DOTDOT,11)) {
-		inum = filp->f_dentry->d_parent->d_inode->i_ino;
+		inum = parent_ino(filp->f_dentry);
 	} else {
 		struct inode *tmp = fat_iget(sb, ino);
 		if (tmp) {
diff --git a/fs/isofs/dir.c b/fs/isofs/dir.c
index 9c7ff0c3b3493c4a5a3a4210b117775dde640c09..583ade0421c0f35af7f72dfe283f9529be82bb0f 100644
--- a/fs/isofs/dir.c
+++ b/fs/isofs/dir.c
@@ -185,7 +185,7 @@ static int do_isofs_readdir(struct inode *inode, struct file *filp,
 
 		/* Handle the case of the '..' directory */
 		if (de->name_len[0] == 1 && de->name[0] == 1) {
-			inode_number = filp->f_dentry->d_parent->d_inode->i_ino;
+			inode_number = parent_ino(filp->f_dentry);
 			if (filldir(dirent, "..", 2, filp->f_pos, inode_number, DT_DIR) < 0)
 				break;
 			filp->f_pos += de_len;
diff --git a/fs/jffs2/dir.c b/fs/jffs2/dir.c
index eb258ddba159a61c0ad89d56b309ab113a2b086f..daadcf077adeb0493f3ee048923cddb964d91755 100644
--- a/fs/jffs2/dir.c
+++ b/fs/jffs2/dir.c
@@ -157,8 +157,8 @@ static int jffs2_readdir(struct file *filp, void *dirent, filldir_t filldir)
 		offset++;
 	}
 	if (offset == 1) {
-		D1(printk(KERN_DEBUG "Dirent 1: \"..\", ino #%lu\n", filp->f_dentry->d_parent->d_inode->i_ino));
-		if (filldir(dirent, "..", 2, 1, filp->f_dentry->d_parent->d_inode->i_ino, DT_DIR) < 0)
+		D1(printk(KERN_DEBUG "Dirent 1: \"..\", ino #%lu\n", parent_ino(filp->f_dentry)));
+		if (filldir(dirent, "..", 2, 1, parent_ino(filp->f_dentry), DT_DIR) < 0)
 			goto out;
 		offset++;
 	}
diff --git a/fs/ncpfs/dir.c b/fs/ncpfs/dir.c
index 93647cb3b7317555dc6e5e6b1a810cf84f308fd7..61dd8ff82f77bf16b46fbace9f1044aa113f20f8 100644
--- a/fs/ncpfs/dir.c
+++ b/fs/ncpfs/dir.c
@@ -411,8 +411,7 @@ static int ncp_readdir(struct file *filp, void *dirent, filldir_t filldir)
 		filp->f_pos = 1;
 	}
 	if (filp->f_pos == 1) {
-		if (filldir(dirent, "..", 2, 1,
-				dentry->d_parent->d_inode->i_ino, DT_DIR))
+		if (filldir(dirent, "..", 2, 1, parent_ino(dentry), DT_DIR))
 			goto out;
 		filp->f_pos = 2;
 	}
diff --git a/fs/nfsd/nfsfh.c b/fs/nfsd/nfsfh.c
index 82152dc031d9fc737cd09c62e4af7b76c50fa46c..eaa328f37eae23027945ff29993aaefebf7cc96d 100644
--- a/fs/nfsd/nfsfh.c
+++ b/fs/nfsd/nfsfh.c
@@ -754,7 +754,7 @@ inline int _fh_update(struct dentry *dentry, struct svc_export *exp,
 		*maxsize = 2;
 		return 1;
 	}
-	*datap++ = ino_t_to_u32(dentry->d_parent->d_inode->i_ino);
+	*datap++ = ino_t_to_u32(parent_ino(dentry));
 	*maxsize = 3;
 	return 2;
 }
@@ -814,7 +814,7 @@ fh_compose(struct svc_fh *fhp, struct svc_export *exp, struct dentry *dentry, st
 		fhp->fh_handle.ofh_dev =  htonl((major(exp->ex_dev)<<16)| minor(exp->ex_dev));
 		fhp->fh_handle.ofh_xdev = fhp->fh_handle.ofh_dev;
 		fhp->fh_handle.ofh_xino = ino_t_to_u32(exp->ex_ino);
-		fhp->fh_handle.ofh_dirino = ino_t_to_u32(dentry->d_parent->d_inode->i_ino);
+		fhp->fh_handle.ofh_dirino = ino_t_to_u32(parent_ino(dentry));
 		if (inode)
 			_fh_update_old(dentry, exp, &fhp->fh_handle);
 	} else {
diff --git a/fs/ntfs/fs.c b/fs/ntfs/fs.c
index 097d76bc6832f1a0ee0411e2601b6b6cf4844361..a74fb1fd4499c348d46aaadb6066dcd420d339ca 100644
--- a/fs/ntfs/fs.c
+++ b/fs/ntfs/fs.c
@@ -276,10 +276,9 @@ static int ntfs_readdir(struct file* filp, void *dirent, filldir_t filldir)
 			ntfs_debug(DEBUG_OTHER, __FUNCTION__ "(): Calling "
 				    "filldir for .. with len 2, f_pos 0x%Lx, "
 				    "inode %lu, DT_DIR.\n", filp->f_pos,
-				    filp->f_dentry->d_parent->d_inode->i_ino);
+				    parent_ino(filp->f_dentry));
 			cb.ret_code = filldir(dirent, "..", 2, filp->f_pos,
-				    filp->f_dentry->d_parent->d_inode->i_ino,
-				    DT_DIR);
+				    parent_ino(filp->f_dentry), DT_DIR);
 			if (cb.ret_code)
 				goto done;
 			cb.pl++;
diff --git a/fs/proc/generic.c b/fs/proc/generic.c
index dd1f58f183549d64117383e390369d6c39ca48ce..09ee4e16c6578e88f8c3f21e0c5ddc97a939f19c 100644
--- a/fs/proc/generic.c
+++ b/fs/proc/generic.c
@@ -319,7 +319,7 @@ int proc_readdir(struct file * filp,
 			/* fall through */
 		case 1:
 			if (filldir(dirent, "..", 2, i,
-				    filp->f_dentry->d_parent->d_inode->i_ino,
+				    parent_ino(filp->f_dentry),
 				    DT_DIR) < 0)
 				return 0;
 			i++;
diff --git a/fs/readdir.c b/fs/readdir.c
index 8a09857a4c04d0e8c59aa741825a0c7ce63b949c..8d47d2c3220e610f202d20171a6b20adfbec0f6c 100644
--- a/fs/readdir.c
+++ b/fs/readdir.c
@@ -52,7 +52,7 @@ int dcache_readdir(struct file * filp, void * dirent, filldir_t filldir)
 			filp->f_pos++;
 			/* fallthrough */
 		case 1:
-			if (filldir(dirent, "..", 2, i, dentry->d_parent->d_inode->i_ino, DT_DIR) < 0)
+			if (filldir(dirent, "..", 2, i, parent_ino(dentry), DT_DIR) < 0)
 				break;
 			i++;
 			filp->f_pos++;
diff --git a/fs/smbfs/dir.c b/fs/smbfs/dir.c
index 0b9160565504f478dc16eff56eeb6c71676d3f2f..991822bc079642ed1e5eb2356d8b80342bb7c653 100644
--- a/fs/smbfs/dir.c
+++ b/fs/smbfs/dir.c
@@ -82,8 +82,7 @@ smb_readdir(struct file *filp, void *dirent, filldir_t filldir)
 		filp->f_pos = 1;
 		/* fallthrough */
 	case 1:
-		if (filldir(dirent, "..", 2, 1,
-			    dentry->d_parent->d_inode->i_ino, DT_DIR) < 0)
+		if (filldir(dirent, "..", 2, 1, parent_ino(dentry), DT_DIR) < 0)
 			goto out;
 		filp->f_pos = 2;
 	}
diff --git a/include/linux/fs.h b/include/linux/fs.h
index aa4e95913890d13140244173939961165e4b1030..1411debc77dc8dd9e42c5288667efb1007ec1e2e 100644
--- a/include/linux/fs.h
+++ b/include/linux/fs.h
@@ -1508,6 +1508,15 @@ extern int generic_osync_inode(struct inode *, int);
 extern int inode_change_ok(struct inode *, struct iattr *);
 extern int inode_setattr(struct inode *, struct iattr *);
 
+static inline ino_t parent_ino(struct dentry *dentry)
+{
+	ino_t res;
+	spin_lock(&dcache_lock);
+	res = dentry->d_parent->d_inode->i_ino;
+	spin_unlock(&dcache_lock);
+	return res;
+}
+
 #endif /* __KERNEL__ */
 
 #endif /* _LINUX_FS_H */