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 (!autofs4_follow_mount(&mnt
, &dentry
))
62 /* This is an autofs submount, we can't expire it */
63 if (is_autofs4_dentry(dentry
))
66 /* The big question */
67 if (may_umount_tree(mnt
) == 0)
70 DPRINTK("returning = %d", status
);
76 /* Check a directory tree of mount points for busyness
77 * The tree is not busy iff no mountpoints are busy
78 * Return 1 if the tree is busy or 0 otherwise
80 static int autofs4_check_tree(struct vfsmount
*mnt
,
82 unsigned long timeout
,
85 struct dentry
*this_parent
= top
;
86 struct list_head
*next
;
88 DPRINTK("parent %p %.*s",
89 top
, (int)top
->d_name
.len
, top
->d_name
.name
);
91 /* Negative dentry - give up */
92 if (!simple_positive(top
))
95 /* Timeout of a tree mount is determined by its top dentry */
96 if (!autofs4_can_expire(top
, timeout
, do_now
))
99 /* Is someone visiting anywhere in the tree ? */
100 if (may_umount_tree(mnt
))
103 spin_lock(&dcache_lock
);
105 next
= this_parent
->d_subdirs
.next
;
107 while (next
!= &this_parent
->d_subdirs
) {
108 struct dentry
*dentry
= list_entry(next
, struct dentry
, d_u
.d_child
);
110 /* Negative dentry - give up */
111 if (!simple_positive(dentry
)) {
116 DPRINTK("dentry %p %.*s",
117 dentry
, (int)dentry
->d_name
.len
, dentry
->d_name
.name
);
119 if (!simple_empty_nolock(dentry
)) {
120 this_parent
= dentry
;
124 dentry
= dget(dentry
);
125 spin_unlock(&dcache_lock
);
127 if (d_mountpoint(dentry
)) {
128 /* First busy => tree busy */
129 if (!autofs4_check_mount(mnt
, dentry
)) {
136 spin_lock(&dcache_lock
);
140 if (this_parent
!= top
) {
141 next
= this_parent
->d_u
.d_child
.next
;
142 this_parent
= this_parent
->d_parent
;
145 spin_unlock(&dcache_lock
);
150 static struct dentry
*autofs4_check_leaves(struct vfsmount
*mnt
,
151 struct dentry
*parent
,
152 unsigned long timeout
,
155 struct dentry
*this_parent
= parent
;
156 struct list_head
*next
;
158 DPRINTK("parent %p %.*s",
159 parent
, (int)parent
->d_name
.len
, parent
->d_name
.name
);
161 spin_lock(&dcache_lock
);
163 next
= this_parent
->d_subdirs
.next
;
165 while (next
!= &this_parent
->d_subdirs
) {
166 struct dentry
*dentry
= list_entry(next
, struct dentry
, d_u
.d_child
);
168 /* Negative dentry - give up */
169 if (!simple_positive(dentry
)) {
174 DPRINTK("dentry %p %.*s",
175 dentry
, (int)dentry
->d_name
.len
, dentry
->d_name
.name
);
177 if (!list_empty(&dentry
->d_subdirs
)) {
178 this_parent
= dentry
;
182 dentry
= dget(dentry
);
183 spin_unlock(&dcache_lock
);
185 if (d_mountpoint(dentry
)) {
186 /* Can we expire this guy */
187 if (!autofs4_can_expire(dentry
, timeout
, do_now
))
190 /* Can we umount this guy */
191 if (autofs4_check_mount(mnt
, dentry
))
197 spin_lock(&dcache_lock
);
201 if (this_parent
!= parent
) {
202 next
= this_parent
->d_u
.d_child
.next
;
203 this_parent
= this_parent
->d_parent
;
206 spin_unlock(&dcache_lock
);
212 * Find an eligible tree to time-out
213 * A tree is eligible if :-
214 * - it is unused by any user process
215 * - it has been unused for exp_timeout time
217 static struct dentry
*autofs4_expire(struct super_block
*sb
,
218 struct vfsmount
*mnt
,
219 struct autofs_sb_info
*sbi
,
222 unsigned long timeout
;
223 struct dentry
*root
= sb
->s_root
;
224 struct dentry
*expired
= NULL
;
225 struct list_head
*next
;
226 int do_now
= how
& AUTOFS_EXP_IMMEDIATE
;
227 int exp_leaves
= how
& AUTOFS_EXP_LEAVES
;
229 if ( !sbi
->exp_timeout
|| !root
)
233 timeout
= sbi
->exp_timeout
;
235 spin_lock(&dcache_lock
);
236 next
= root
->d_subdirs
.next
;
238 /* On exit from the loop expire is set to a dgot dentry
239 * to expire or it's NULL */
240 while ( next
!= &root
->d_subdirs
) {
241 struct dentry
*dentry
= list_entry(next
, struct dentry
, d_u
.d_child
);
243 /* Negative dentry - give up */
244 if ( !simple_positive(dentry
) ) {
249 dentry
= dget(dentry
);
250 spin_unlock(&dcache_lock
);
252 /* Case 1: indirect mount or top level direct mount */
253 if (d_mountpoint(dentry
)) {
254 DPRINTK("checking mountpoint %p %.*s",
255 dentry
, (int)dentry
->d_name
.len
, dentry
->d_name
.name
);
257 /* Can we expire this guy */
258 if (!autofs4_can_expire(dentry
, timeout
, do_now
))
261 /* Can we umount this guy */
262 if (autofs4_check_mount(mnt
, dentry
)) {
269 if ( simple_empty(dentry
) )
272 /* Case 2: tree mount, expire iff entire tree is not busy */
274 /* Lock the tree as we must expire as a whole */
275 spin_lock(&sbi
->fs_lock
);
276 if (autofs4_check_tree(mnt
, dentry
, timeout
, do_now
)) {
277 struct autofs_info
*inf
= autofs4_dentry_ino(dentry
);
279 /* Set this flag early to catch sys_chdir and the like */
280 inf
->flags
|= AUTOFS_INF_EXPIRING
;
281 spin_unlock(&sbi
->fs_lock
);
285 spin_unlock(&sbi
->fs_lock
);
286 /* Case 3: direct mount, expire individual leaves */
288 expired
= autofs4_check_leaves(mnt
, dentry
, timeout
, do_now
);
296 spin_lock(&dcache_lock
);
301 DPRINTK("returning %p %.*s",
302 expired
, (int)expired
->d_name
.len
, expired
->d_name
.name
);
303 spin_lock(&dcache_lock
);
304 list_del(&expired
->d_parent
->d_subdirs
);
305 list_add(&expired
->d_parent
->d_subdirs
, &expired
->d_u
.d_child
);
306 spin_unlock(&dcache_lock
);
309 spin_unlock(&dcache_lock
);
314 /* Perform an expiry operation */
315 int autofs4_expire_run(struct super_block
*sb
,
316 struct vfsmount
*mnt
,
317 struct autofs_sb_info
*sbi
,
318 struct autofs_packet_expire __user
*pkt_p
)
320 struct autofs_packet_expire pkt
;
321 struct dentry
*dentry
;
323 memset(&pkt
,0,sizeof pkt
);
325 pkt
.hdr
.proto_version
= sbi
->version
;
326 pkt
.hdr
.type
= autofs_ptype_expire
;
328 if ((dentry
= autofs4_expire(sb
, mnt
, sbi
, 0)) == NULL
)
331 pkt
.len
= dentry
->d_name
.len
;
332 memcpy(pkt
.name
, dentry
->d_name
.name
, pkt
.len
);
333 pkt
.name
[pkt
.len
] = '\0';
336 if ( copy_to_user(pkt_p
, &pkt
, sizeof(struct autofs_packet_expire
)) )
342 /* Call repeatedly until it returns -EAGAIN, meaning there's nothing
344 int autofs4_expire_multi(struct super_block
*sb
, struct vfsmount
*mnt
,
345 struct autofs_sb_info
*sbi
, int __user
*arg
)
347 struct dentry
*dentry
;
351 if (arg
&& get_user(do_now
, arg
))
354 if ((dentry
= autofs4_expire(sb
, mnt
, sbi
, do_now
)) != NULL
) {
355 struct autofs_info
*de_info
= autofs4_dentry_ino(dentry
);
357 /* This is synchronous because it makes the daemon a
359 de_info
->flags
|= AUTOFS_INF_EXPIRING
;
360 ret
= autofs4_wait(sbi
, dentry
, NFY_EXPIRE
);
361 de_info
->flags
&= ~AUTOFS_INF_EXPIRING
;