From 84d08fa888e7c2d53b5bbc764db2ef02968b499c Mon Sep 17 00:00:00 2001
From: Al Viro <viro@zeniv.linux.org.uk>
Date: Fri, 5 Jul 2013 18:59:33 +0400
Subject: [PATCH] helper for reading ->d_count
Git-commit: 84d08fa88 (partial)
Patch-mainline: v3.11-rc1
Patch-filtered: include/linux/dcache.h
References: FATE#317271

Signed-off-by: Al Viro <viro@zeniv.linux.org.uk>
Acked-by: Jeff Mahoney <jeffm@suse.com>
[2014-12-09: added the excluded filesystem parts -- mmarek]mmarek
---
 fs/autofs4/expire.c    |   10 +++++-----
 fs/autofs4/root.c      |    2 +-
 fs/ceph/inode.c        |    4 ++--
 fs/ceph/mds_client.c   |    2 +-
 fs/coda/dir.c          |    2 +-
 fs/ecryptfs/inode.c    |    2 +-
 fs/locks.c             |    2 +-
 fs/nfs/dir.c           |    6 +++---
 fs/nfs/unlink.c        |    2 +-
 fs/nilfs2/super.c      |    2 +-
 include/linux/dcache.h |    5 +++++
 11 files changed, 22 insertions(+), 17 deletions(-)

--- a/fs/autofs4/expire.c
+++ b/fs/autofs4/expire.c
@@ -109,7 +109,7 @@ cont:
 
 	spin_lock_nested(&q->d_lock, DENTRY_D_LOCK_NESTED);
 	/* Already gone or negative dentry (under construction) - try next */
-	if (q->d_count == 0 || !simple_positive(q)) {
+	if (!d_count(q) || !simple_positive(q)) {
 		spin_unlock(&q->d_lock);
 		next = q->d_u.d_child.next;
 		goto cont;
@@ -267,7 +267,7 @@ static int autofs4_tree_busy(struct vfsm
 			else
 				ino_count++;
 
-			if (p->d_count > ino_count) {
+			if (d_count(p) > ino_count) {
 				top_ino->last_used = jiffies;
 				dput(p);
 				return 1;
@@ -392,7 +392,7 @@ struct dentry *autofs4_expire_indirect(s
 
 			/* Path walk currently on this dentry? */
 			ino_count = atomic_read(&ino->count) + 2;
-			if (dentry->d_count > ino_count)
+			if (d_count(dentry) > ino_count)
 				goto next;
 
 			/* Can we umount this guy */
@@ -414,7 +414,7 @@ struct dentry *autofs4_expire_indirect(s
 		if (!exp_leaves) {
 			/* Path walk currently on this dentry? */
 			ino_count = atomic_read(&ino->count) + 1;
-			if (dentry->d_count > ino_count)
+			if (d_count(dentry) > ino_count)
 				goto next;
 
 			if (!autofs4_tree_busy(mnt, dentry, timeout, do_now)) {
@@ -428,7 +428,7 @@ struct dentry *autofs4_expire_indirect(s
 		} else {
 			/* Path walk currently on this dentry? */
 			ino_count = atomic_read(&ino->count) + 1;
-			if (dentry->d_count > ino_count)
+			if (d_count(dentry) > ino_count)
 				goto next;
 
 			expired = autofs4_check_leaves(mnt, dentry, timeout, do_now);
--- a/fs/autofs4/root.c
+++ b/fs/autofs4/root.c
@@ -179,7 +179,7 @@ static struct dentry *autofs4_lookup_act
 		spin_lock(&active->d_lock);
 
 		/* Already gone? */
-		if (active->d_count == 0)
+		if (!d_count(active))
 			goto next;
 
 		qstr = &active->d_name;
--- a/fs/ceph/inode.c
+++ b/fs/ceph/inode.c
@@ -896,8 +896,8 @@ static struct dentry *splice_dentry(stru
 	} else if (realdn) {
 		dout("dn %p (%d) spliced with %p (%d) "
 		     "inode %p ino %llx.%llx\n",
-		     dn, dn->d_count,
-		     realdn, realdn->d_count,
+		     dn, d_count(dn),
+		     realdn, d_count(realdn),
 		     realdn->d_inode, ceph_vinop(realdn->d_inode));
 		dput(dn);
 		dn = realdn;
--- a/fs/ceph/mds_client.c
+++ b/fs/ceph/mds_client.c
@@ -1519,7 +1519,7 @@ retry:
 	*base = ceph_ino(temp->d_inode);
 	*plen = len;
 	dout("build_path on %p %d built %llx '%.*s'\n",
-	     dentry, dentry->d_count, *base, len, path);
+	     dentry, d_count(dentry), *base, len, path);
 	return path;
 }
 
--- a/fs/coda/dir.c
+++ b/fs/coda/dir.c
@@ -564,7 +564,7 @@ static int coda_dentry_revalidate(struct
 	if (cii->c_flags & C_FLUSH) 
 		coda_flag_inode_children(inode, C_FLUSH);
 
-	if (de->d_count > 1)
+	if (d_count(de) > 1)
 		/* pretend it's valid, but don't change the flags */
 		goto out;
 
--- a/fs/ecryptfs/inode.c
+++ b/fs/ecryptfs/inode.c
@@ -353,7 +353,7 @@ static int ecryptfs_lookup_interpose(str
 
 	lower_mnt = mntget(ecryptfs_dentry_to_lower_mnt(dentry->d_parent));
 	fsstack_copy_attr_atime(dir_inode, lower_dentry->d_parent->d_inode);
-	BUG_ON(!lower_dentry->d_count);
+	BUG_ON(!d_count(lower_dentry));
 
 	dentry_info = kmem_cache_alloc(ecryptfs_dentry_info_cache, GFP_KERNEL);
 	ecryptfs_set_dentry_private(dentry, dentry_info);
--- a/fs/locks.c
+++ b/fs/locks.c
@@ -1382,7 +1382,7 @@ int generic_setlease(struct file *filp,
 		if ((arg == F_RDLCK) && (atomic_read(&inode->i_writecount) > 0))
 			goto out;
 		if ((arg == F_WRLCK)
-		    && ((dentry->d_count > 1)
+		    && ((d_count(dentry) > 1)
 			|| (atomic_read(&inode->i_count) > 1)))
 			goto out;
 	}
--- a/fs/nfs/dir.c
+++ b/fs/nfs/dir.c
@@ -1819,7 +1819,7 @@ static int nfs_unlink(struct inode *dir,
 		dir->i_ino, dentry->d_name.name);
 
 	spin_lock(&dentry->d_lock);
-	if (dentry->d_count > 1) {
+	if (d_count(dentry) > 1) {
 		spin_unlock(&dentry->d_lock);
 		/* Start asynchronous writeout of the inode */
 		write_inode_now(dentry->d_inode, 0);
@@ -1965,7 +1965,7 @@ static int nfs_rename(struct inode *old_
 	dfprintk(VFS, "NFS: rename(%s/%s -> %s/%s, ct=%d)\n",
 		 old_dentry->d_parent->d_name.name, old_dentry->d_name.name,
 		 new_dentry->d_parent->d_name.name, new_dentry->d_name.name,
-		 new_dentry->d_count);
+		 d_count(new_dentry));
 
 	/*
 	 * For non-directories, check whether the target is busy and if so,
@@ -1983,7 +1983,7 @@ static int nfs_rename(struct inode *old_
 			rehash = new_dentry;
 		}
 
-		if (new_dentry->d_count > 2) {
+		if (d_count(new_dentry) > 2) {
 			int err;
 
 			/* copy the target dentry's name */
--- a/fs/nfs/unlink.c
+++ b/fs/nfs/unlink.c
@@ -516,7 +516,7 @@ nfs_sillyrename(struct inode *dir, struc
 
 	dfprintk(VFS, "NFS: silly-rename(%s/%s, ct=%d)\n",
 		dentry->d_parent->d_name.name, dentry->d_name.name,
-		dentry->d_count);
+		d_count(dentry));
 	nfs_inc_stats(dir, NFSIOS_SILLYRENAME);
 
 	/*
--- a/fs/nilfs2/super.c
+++ b/fs/nilfs2/super.c
@@ -983,7 +983,7 @@ static int nilfs_attach_snapshot(struct
 
 static int nilfs_tree_was_touched(struct dentry *root_dentry)
 {
-	return root_dentry->d_count > 1;
+	return d_count(root_dentry) > 1;
 }
 
 /**
--- a/include/linux/dcache.h
+++ b/include/linux/dcache.h
@@ -337,6 +337,11 @@ static inline int __d_rcu_to_refcount(st
 	return ret;
 }
 
+static inline unsigned d_count(struct dentry *dentry)
+{
+	return dentry->d_count;
+}
+
 /* validate "insecure" dentry pointer */
 extern int d_validate(struct dentry *, struct dentry *);
 
