aboutsummaryrefslogtreecommitdiffstats
path: root/fs/autofs4/expire.c
diff options
context:
space:
mode:
Diffstat (limited to 'fs/autofs4/expire.c')
-rw-r--r--fs/autofs4/expire.c34
1 files changed, 25 insertions, 9 deletions
diff --git a/fs/autofs4/expire.c b/fs/autofs4/expire.c
index 165fe9e2d570..053d92a745b9 100644
--- a/fs/autofs4/expire.c
+++ b/fs/autofs4/expire.c
@@ -101,6 +101,7 @@ static int autofs4_tree_busy(struct vfsmount *mnt,
101 unsigned long timeout, 101 unsigned long timeout,
102 int do_now) 102 int do_now)
103{ 103{
104 struct autofs_info *ino;
104 struct dentry *p; 105 struct dentry *p;
105 106
106 DPRINTK("top %p %.*s", 107 DPRINTK("top %p %.*s",
@@ -110,14 +111,6 @@ static int autofs4_tree_busy(struct vfsmount *mnt,
110 if (!simple_positive(top)) 111 if (!simple_positive(top))
111 return 1; 112 return 1;
112 113
113 /* Timeout of a tree mount is determined by its top dentry */
114 if (!autofs4_can_expire(top, timeout, do_now))
115 return 1;
116
117 /* Is someone visiting anywhere in the tree ? */
118 if (may_umount_tree(mnt))
119 return 1;
120
121 spin_lock(&dcache_lock); 114 spin_lock(&dcache_lock);
122 for (p = top; p; p = next_dentry(p, top)) { 115 for (p = top; p; p = next_dentry(p, top)) {
123 /* Negative dentry - give up */ 116 /* Negative dentry - give up */
@@ -130,17 +123,40 @@ static int autofs4_tree_busy(struct vfsmount *mnt,
130 p = dget(p); 123 p = dget(p);
131 spin_unlock(&dcache_lock); 124 spin_unlock(&dcache_lock);
132 125
126 /*
127 * Is someone visiting anywhere in the subtree ?
128 * If there's no mount we need to check the usage
129 * count for the autofs dentry.
130 */
131 ino = autofs4_dentry_ino(p);
133 if (d_mountpoint(p)) { 132 if (d_mountpoint(p)) {
134 /* First busy => tree busy */
135 if (autofs4_mount_busy(mnt, p)) { 133 if (autofs4_mount_busy(mnt, p)) {
136 dput(p); 134 dput(p);
137 return 1; 135 return 1;
138 } 136 }
137 } else {
138 unsigned int ino_count = atomic_read(&ino->count);
139
140 /* allow for dget above and top is already dgot */
141 if (p == top)
142 ino_count += 2;
143 else
144 ino_count++;
145
146 if (atomic_read(&p->d_count) > ino_count) {
147 dput(p);
148 return 1;
149 }
139 } 150 }
140 dput(p); 151 dput(p);
141 spin_lock(&dcache_lock); 152 spin_lock(&dcache_lock);
142 } 153 }
143 spin_unlock(&dcache_lock); 154 spin_unlock(&dcache_lock);
155
156 /* Timeout of a tree mount is ultimately determined by its top dentry */
157 if (!autofs4_can_expire(top, timeout, do_now))
158 return 1;
159
144 return 0; 160 return 0;
145} 161}
146 162