1 /* -*- c -*- --------------------------------------------------------------- *
3 * linux/fs/autofs/expire.c
5 * Copyright 1997-1998 Transmeta Corporation -- All Rights Reserved
6 * Copyright 1999-2000 Jeremy Fitzhardinge <jeremy@goop.org>
7 * Copyright 2001-2003 Ian Kent <raven@themaw.net>
9 * This file is part of the Linux kernel and is made available under
10 * the terms of the GNU General Public License, version 2, or at your
11 * option, any later version, incorporated herein by reference.
13 * ------------------------------------------------------------------------- */
17 static unsigned long now
;
19 /* Check if a dentry can be expired return 1 if it can else return 0 */
20 static inline int autofs4_can_expire(struct dentry
*dentry
,
21 unsigned long timeout
, int do_now
)
23 struct autofs_info
*ino
= autofs4_dentry_ino(dentry
);
25 /* dentry in the process of being deleted */
29 /* No point expiring a pending mount */
30 if (dentry
->d_flags
& DCACHE_AUTOFS_PENDING
)
34 /* Too young to die */
35 if (time_after(ino
->last_used
+ timeout
, now
))
38 /* update last_used here :-
39 - obviously makes sense if it is in use now
40 - less obviously, prevents rapid-fire expire
41 attempts if expire fails the first time */
48 /* Check a mount point for busyness return 1 if not busy, otherwise */
49 static int autofs4_check_mount(struct vfsmount
*mnt
, struct dentry
*dentry
)
53 DPRINTK("dentry %p %.*s",
54 dentry
, (int)dentry
->d_name
.len
, dentry
->d_name
.name
);
59 if (!follow_down(&mnt
, &dentry
))
62 while (d_mountpoint(dentry
) && follow_down(&mnt
, &dentry
))
65 /* This is an autofs submount, we can't expire it */
66 if (is_autofs4_dentry(dentry
))
69 /* The big question */
70 if (may_umount_tree(mnt
) == 0)
73 DPRINTK("returning = %d", status
);
79 /* Check a directory tree of mount points for busyness
80 * The tree is not busy iff no mountpoints are busy
81 * Return 1 if the tree is busy or 0 otherwise
83 static int autofs4_check_tree(struct vfsmount
*mnt
,
85 unsigned long timeout
,
88 struct dentry
*this_parent
= top
;
89 struct list_head
*next
;
91 DPRINTK("parent %p %.*s",
92 top
, (int)top
->d_name
.len
, top
->d_name
.name
);
94 /* Negative dentry - give up */
95 if (!simple_positive(top
))
98 /* Timeout of a tree mount is determined by its top dentry */
99 if (!autofs4_can_expire(top
, timeout
, do_now
))
102 /* Is someone visiting anywhere in the tree ? */
103 if (may_umount_tree(mnt
))
106 spin_lock(&dcache_lock
);
108 next
= this_parent
->d_subdirs
.next
;
110 while (next
!= &this_parent
->d_subdirs
) {
111 struct dentry
*dentry
= list_entry(next
, struct dentry
, d_child
);
113 /* Negative dentry - give up */
114 if (!simple_positive(dentry
)) {
119 DPRINTK("dentry %p %.*s",
120 dentry
, (int)dentry
->d_name
.len
, dentry
->d_name
.name
);
122 if (!simple_empty_nolock(dentry
)) {
123 this_parent
= dentry
;
127 dentry
= dget(dentry
);
128 spin_unlock(&dcache_lock
);
130 if (d_mountpoint(dentry
)) {
131 /* First busy => tree busy */
132 if (!autofs4_check_mount(mnt
, dentry
)) {
139 spin_lock(&dcache_lock
);
143 if (this_parent
!= top
) {
144 next
= this_parent
->d_child
.next
;
145 this_parent
= this_parent
->d_parent
;
148 spin_unlock(&dcache_lock
);
153 static struct dentry
*autofs4_check_leaves(struct vfsmount
*mnt
,
154 struct dentry
*parent
,
155 unsigned long timeout
,
158 struct dentry
*this_parent
= parent
;
159 struct list_head
*next
;
161 DPRINTK("parent %p %.*s",
162 parent
, (int)parent
->d_name
.len
, parent
->d_name
.name
);
164 spin_lock(&dcache_lock
);
166 next
= this_parent
->d_subdirs
.next
;
168 while (next
!= &this_parent
->d_subdirs
) {
169 struct dentry
*dentry
= list_entry(next
, struct dentry
, d_child
);
171 /* Negative dentry - give up */
172 if (!simple_positive(dentry
)) {
177 DPRINTK("dentry %p %.*s",
178 dentry
, (int)dentry
->d_name
.len
, dentry
->d_name
.name
);
180 if (!list_empty(&dentry
->d_subdirs
)) {
181 this_parent
= dentry
;
185 dentry
= dget(dentry
);
186 spin_unlock(&dcache_lock
);
188 if (d_mountpoint(dentry
)) {
189 /* Can we expire this guy */
190 if (!autofs4_can_expire(dentry
, timeout
, do_now
))
193 /* Can we umount this guy */
194 if (autofs4_check_mount(mnt
, dentry
))
200 spin_lock(&dcache_lock
);
204 if (this_parent
!= parent
) {
205 next
= this_parent
->d_child
.next
;
206 this_parent
= this_parent
->d_parent
;
209 spin_unlock(&dcache_lock
);
215 * Find an eligible tree to time-out
216 * A tree is eligible if :-
217 * - it is unused by any user process
218 * - it has been unused for exp_timeout time
220 static struct dentry
*autofs4_expire(struct super_block
*sb
,
221 struct vfsmount
*mnt
,
222 struct autofs_sb_info
*sbi
,
225 unsigned long timeout
;
226 struct dentry
*root
= sb
->s_root
;
227 struct dentry
*expired
= NULL
;
228 struct list_head
*next
;
229 int do_now
= how
& AUTOFS_EXP_IMMEDIATE
;
230 int exp_leaves
= how
& AUTOFS_EXP_LEAVES
;
232 if ( !sbi
->exp_timeout
|| !root
)
236 timeout
= sbi
->exp_timeout
;
238 spin_lock(&dcache_lock
);
239 next
= root
->d_subdirs
.next
;
241 /* On exit from the loop expire is set to a dgot dentry
242 * to expire or it's NULL */
243 while ( next
!= &root
->d_subdirs
) {
244 struct dentry
*dentry
= list_entry(next
, struct dentry
, d_child
);
246 /* Negative dentry - give up */
247 if ( !simple_positive(dentry
) ) {
252 dentry
= dget(dentry
);
253 spin_unlock(&dcache_lock
);
255 /* Case 1: indirect mount or top level direct mount */
256 if (d_mountpoint(dentry
)) {
257 DPRINTK("checking mountpoint %p %.*s",
258 dentry
, (int)dentry
->d_name
.len
, dentry
->d_name
.name
);
260 /* Can we expire this guy */
261 if (!autofs4_can_expire(dentry
, timeout
, do_now
))
264 /* Can we umount this guy */
265 if (autofs4_check_mount(mnt
, dentry
)) {
272 if ( simple_empty(dentry
) )
275 /* Case 2: tree mount, expire iff entire tree is not busy */
277 /* Lock the tree as we must expire as a whole */
278 spin_lock(&sbi
->fs_lock
);
279 if (autofs4_check_tree(mnt
, dentry
, timeout
, do_now
)) {
280 struct autofs_info
*inf
= autofs4_dentry_ino(dentry
);
282 /* Set this flag early to catch sys_chdir and the like */
283 inf
->flags
|= AUTOFS_INF_EXPIRING
;
284 spin_unlock(&sbi
->fs_lock
);
288 spin_unlock(&sbi
->fs_lock
);
289 /* Case 3: direct mount, expire individual leaves */
291 expired
= autofs4_check_leaves(mnt
, dentry
, timeout
, do_now
);
299 spin_lock(&dcache_lock
);
304 DPRINTK("returning %p %.*s",
305 expired
, (int)expired
->d_name
.len
, expired
->d_name
.name
);
306 spin_lock(&dcache_lock
);
307 list_del(&expired
->d_parent
->d_subdirs
);
308 list_add(&expired
->d_parent
->d_subdirs
, &expired
->d_child
);
309 spin_unlock(&dcache_lock
);
312 spin_unlock(&dcache_lock
);
317 /* Perform an expiry operation */
318 int autofs4_expire_run(struct super_block
*sb
,
319 struct vfsmount
*mnt
,
320 struct autofs_sb_info
*sbi
,
321 struct autofs_packet_expire __user
*pkt_p
)
323 struct autofs_packet_expire pkt
;
324 struct dentry
*dentry
;
326 memset(&pkt
,0,sizeof pkt
);
328 pkt
.hdr
.proto_version
= sbi
->version
;
329 pkt
.hdr
.type
= autofs_ptype_expire
;
331 if ((dentry
= autofs4_expire(sb
, mnt
, sbi
, 0)) == NULL
)
334 pkt
.len
= dentry
->d_name
.len
;
335 memcpy(pkt
.name
, dentry
->d_name
.name
, pkt
.len
);
336 pkt
.name
[pkt
.len
] = '\0';
339 if ( copy_to_user(pkt_p
, &pkt
, sizeof(struct autofs_packet_expire
)) )
345 /* Call repeatedly until it returns -EAGAIN, meaning there's nothing
347 int autofs4_expire_multi(struct super_block
*sb
, struct vfsmount
*mnt
,
348 struct autofs_sb_info
*sbi
, int __user
*arg
)
350 struct dentry
*dentry
;
354 if (arg
&& get_user(do_now
, arg
))
357 if ((dentry
= autofs4_expire(sb
, mnt
, sbi
, do_now
)) != NULL
) {
358 struct autofs_info
*de_info
= autofs4_dentry_ino(dentry
);
360 /* This is synchronous because it makes the daemon a
362 de_info
->flags
|= AUTOFS_INF_EXPIRING
;
363 ret
= autofs4_wait(sbi
, dentry
, NFY_EXPIRE
);
364 de_info
->flags
&= ~AUTOFS_INF_EXPIRING
;