diff options
Diffstat (limited to 'fs/autofs4/expire.c')
-rw-r--r-- | fs/autofs4/expire.c | 34 |
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 | ||