diff options
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 | } |