diff options
author | Ian Kent <raven@themaw.net> | 2006-03-27 04:14:47 -0500 |
---|---|---|
committer | Linus Torvalds <torvalds@g5.osdl.org> | 2006-03-27 11:44:39 -0500 |
commit | e0a7aae94030b878601eb67686b696de4a3764f0 (patch) | |
tree | 721a08b9c124e5e9efe36bec1b501f7999657793 /fs/autofs4/expire.c | |
parent | 1aff3c8b0511b5bb54acf7859e0c6ec9ae7287a9 (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.c | 36 |
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 */ |
48 | static int autofs4_mount_busy(struct vfsmount *mnt, struct dentry *dentry) | 48 | static 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; | ||
68 | done: | 74 | done: |
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 | } |
195 | cont: | 203 | cont: |
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 | } |