aboutsummaryrefslogtreecommitdiffstats
path: root/fs/autofs4/expire.c
diff options
context:
space:
mode:
authorIan Kent <raven@themaw.net>2006-03-27 04:14:47 -0500
committerLinus Torvalds <torvalds@g5.osdl.org>2006-03-27 11:44:39 -0500
commite0a7aae94030b878601eb67686b696de4a3764f0 (patch)
tree721a08b9c124e5e9efe36bec1b501f7999657793 /fs/autofs4/expire.c
parent1aff3c8b0511b5bb54acf7859e0c6ec9ae7287a9 (diff)
[PATCH] autofs4: expire mounts that hold no (extra) references only
Alter the expire semantics that define how "busyness" is determined. Currently a last_used counter is updated on every revalidate from processes other than the mount owner process group. This patch changes that so that an expire candidate is busy only if it has a reference count greater than the expected minimum, such as when there is an open file or working directory in use. This method is the only way that busyness can be established for direct mounts within the new implementation. For consistency the expire semantic is made the same for all mounts. A side effect of the patch is that mounts which remain mounted unessessarily in the presence of some GUI programs that scan the filesystem should now expire. Signed-off-by: Ian Kent <raven@themaw.net> Signed-off-by: Andrew Morton <akpm@osdl.org> Signed-off-by: Linus Torvalds <torvalds@osdl.org>
Diffstat (limited to 'fs/autofs4/expire.c')
-rw-r--r--fs/autofs4/expire.c36
1 files changed, 22 insertions, 14 deletions
diff --git a/fs/autofs4/expire.c b/fs/autofs4/expire.c
index 053d92a745b9..6ae2fc8233ff 100644
--- a/fs/autofs4/expire.c
+++ b/fs/autofs4/expire.c
@@ -47,6 +47,7 @@ static inline int autofs4_can_expire(struct dentry *dentry,
47/* Check a mount point for busyness */ 47/* Check a mount point for busyness */
48static int autofs4_mount_busy(struct vfsmount *mnt, struct dentry *dentry) 48static int autofs4_mount_busy(struct vfsmount *mnt, struct dentry *dentry)
49{ 49{
50 struct dentry *top = dentry;
50 int status = 1; 51 int status = 1;
51 52
52 DPRINTK("dentry %p %.*s", 53 DPRINTK("dentry %p %.*s",
@@ -62,9 +63,14 @@ static int autofs4_mount_busy(struct vfsmount *mnt, struct dentry *dentry)
62 if (is_autofs4_dentry(dentry)) 63 if (is_autofs4_dentry(dentry))
63 goto done; 64 goto done;
64 65
65 /* The big question */ 66 /* Update the expiry counter if fs is busy */
66 if (may_umount_tree(mnt) == 0) 67 if (may_umount_tree(mnt)) {
67 status = 0; 68 struct autofs_info *ino = autofs4_dentry_ino(top);
69 ino->last_used = jiffies;
70 goto done;
71 }
72
73 status = 0;
68done: 74done:
69 DPRINTK("returning = %d", status); 75 DPRINTK("returning = %d", status);
70 mntput(mnt); 76 mntput(mnt);
@@ -101,7 +107,7 @@ static int autofs4_tree_busy(struct vfsmount *mnt,
101 unsigned long timeout, 107 unsigned long timeout,
102 int do_now) 108 int do_now)
103{ 109{
104 struct autofs_info *ino; 110 struct autofs_info *top_ino = autofs4_dentry_ino(top);
105 struct dentry *p; 111 struct dentry *p;
106 112
107 DPRINTK("top %p %.*s", 113 DPRINTK("top %p %.*s",
@@ -127,14 +133,16 @@ static int autofs4_tree_busy(struct vfsmount *mnt,
127 * Is someone visiting anywhere in the subtree ? 133 * Is someone visiting anywhere in the subtree ?
128 * If there's no mount we need to check the usage 134 * If there's no mount we need to check the usage
129 * count for the autofs dentry. 135 * count for the autofs dentry.
136 * If the fs is busy update the expiry counter.
130 */ 137 */
131 ino = autofs4_dentry_ino(p);
132 if (d_mountpoint(p)) { 138 if (d_mountpoint(p)) {
133 if (autofs4_mount_busy(mnt, p)) { 139 if (autofs4_mount_busy(mnt, p)) {
140 top_ino->last_used = jiffies;
134 dput(p); 141 dput(p);
135 return 1; 142 return 1;
136 } 143 }
137 } else { 144 } else {
145 struct autofs_info *ino = autofs4_dentry_ino(p);
138 unsigned int ino_count = atomic_read(&ino->count); 146 unsigned int ino_count = atomic_read(&ino->count);
139 147
140 /* allow for dget above and top is already dgot */ 148 /* allow for dget above and top is already dgot */
@@ -144,6 +152,7 @@ static int autofs4_tree_busy(struct vfsmount *mnt,
144 ino_count++; 152 ino_count++;
145 153
146 if (atomic_read(&p->d_count) > ino_count) { 154 if (atomic_read(&p->d_count) > ino_count) {
155 top_ino->last_used = jiffies;
147 dput(p); 156 dput(p);
148 return 1; 157 return 1;
149 } 158 }
@@ -183,14 +192,13 @@ static struct dentry *autofs4_check_leaves(struct vfsmount *mnt,
183 spin_unlock(&dcache_lock); 192 spin_unlock(&dcache_lock);
184 193
185 if (d_mountpoint(p)) { 194 if (d_mountpoint(p)) {
186 /* Can we expire this guy */ 195 /* Can we umount this guy */
187 if (!autofs4_can_expire(p, timeout, do_now)) 196 if (autofs4_mount_busy(mnt, p))
188 goto cont; 197 goto cont;
189 198
190 /* Can we umount this guy */ 199 /* Can we expire this guy */
191 if (!autofs4_mount_busy(mnt, p)) 200 if (autofs4_can_expire(p, timeout, do_now))
192 return p; 201 return p;
193
194 } 202 }
195cont: 203cont:
196 dput(p); 204 dput(p);
@@ -246,12 +254,12 @@ static struct dentry *autofs4_expire(struct super_block *sb,
246 DPRINTK("checking mountpoint %p %.*s", 254 DPRINTK("checking mountpoint %p %.*s",
247 dentry, (int)dentry->d_name.len, dentry->d_name.name); 255 dentry, (int)dentry->d_name.len, dentry->d_name.name);
248 256
249 /* Can we expire this guy */ 257 /* Can we umount this guy */
250 if (!autofs4_can_expire(dentry, timeout, do_now)) 258 if (autofs4_mount_busy(mnt, dentry))
251 goto next; 259 goto next;
252 260
253 /* Can we umount this guy */ 261 /* Can we expire this guy */
254 if (!autofs4_mount_busy(mnt, dentry)) { 262 if (autofs4_can_expire(dentry, timeout, do_now)) {
255 expired = dentry; 263 expired = dentry;
256 break; 264 break;
257 } 265 }