1 /* -*- c -*- --------------------------------------------------------------- *
3 * linux/fs/autofs/expire.c
5 * Copyright 1997-1998 Transmeta Corporation -- All Rights Reserved
6 * Copyright 1999 Jeremy Fitzhardinge <jeremy@goop.org>
8 * This file is part of the Linux kernel and is made available under
9 * the terms of the GNU General Public License, version 2, or at your
10 * option, any later version, incorporated herein by reference.
12 * ------------------------------------------------------------------------- */
17 * Determine if a dentry tree is in use. This is much the
18 * same as the standard is_root_busy() function, except
20 * - the extra dentry reference in autofs dentries is not
21 * considered to be busy
22 * - mountpoints within the tree are not busy
23 * - it traverses across mountpoints
24 * XXX doesn't consider children of covered dentries at mountpoints
26 static int is_tree_busy(struct dentry
*root
)
28 struct dentry
*this_parent
;
29 struct list_head
*next
;
32 root
= root
->d_mounts
;
34 count
= root
->d_count
;
37 DPRINTK(("is_tree_busy: starting at %.*s/%.*s, d_count=%d\n",
38 root
->d_covers
->d_parent
->d_name
.len
,
39 root
->d_covers
->d_parent
->d_name
.name
,
40 root
->d_name
.len
, root
->d_name
.name
,
43 /* Ignore autofs's extra reference */
44 if (is_autofs4_dentry(root
)) {
45 DPRINTK(("is_tree_busy: autofs\n"));
49 /* Mountpoints don't count (either mountee or mounter) */
50 if (d_mountpoint(root
) ||
51 root
!= root
->d_covers
) {
52 DPRINTK(("is_tree_busy: mountpoint\n"));
57 next
= this_parent
->d_mounts
->d_subdirs
.next
;
59 while (next
!= &this_parent
->d_mounts
->d_subdirs
) {
61 struct list_head
*tmp
= next
;
62 struct dentry
*dentry
= list_entry(tmp
, struct dentry
,
67 dentry
= dentry
->d_mounts
;
69 DPRINTK(("is_tree_busy: considering %.*s/%.*s, d_count=%d, count=%d\n",
70 this_parent
->d_name
.len
,
71 this_parent
->d_name
.name
,
72 dentry
->d_covers
->d_name
.len
,
73 dentry
->d_covers
->d_name
.name
,
74 dentry
->d_count
, count
));
76 /* Decrement count for unused children */
77 count
+= (dentry
->d_count
- 1);
79 /* Mountpoints don't count */
80 if (d_mountpoint(dentry
)) {
81 DPRINTK(("is_tree_busy: mountpoint dentry=%p covers=%p mounts=%p\n",
82 dentry
, dentry
->d_covers
, dentry
->d_mounts
));
86 /* ... and roots - twice as much... */
87 if (dentry
!= dentry
->d_covers
) {
88 DPRINTK(("is_tree_busy: mountpoint dentry=%p covers=%p mounts=%p\n",
89 dentry
, dentry
->d_covers
, dentry
->d_mounts
));
93 /* Ignore autofs's extra reference */
94 if (is_autofs4_dentry(dentry
)) {
95 DPRINTK(("is_tree_busy: autofs\n"));
101 if (!list_empty(&dentry
->d_mounts
->d_subdirs
)) {
102 this_parent
= dentry
->d_mounts
;
106 /* root is busy if any leaf is busy */
107 if (dentry
->d_count
!= adj
) {
108 DPRINTK(("is_tree_busy: busy leaf (d_count=%d adj=%d)\n",
109 dentry
->d_count
, adj
));
114 * All done at this level ... ascend and resume the search.
116 if (this_parent
!= root
) {
117 next
= this_parent
->d_covers
->d_child
.next
;
118 this_parent
= this_parent
->d_covers
->d_parent
;
122 DPRINTK(("is_tree_busy: count=%d\n", count
));
123 return count
!= 0; /* remaining users? */
127 * Find an eligible tree to time-out
128 * A tree is eligible if :-
129 * - it is unused by any user process
130 * - it has been unused for exp_timeout time
132 static struct dentry
*autofs4_expire(struct super_block
*sb
,
133 struct autofs_sb_info
*sbi
,
136 unsigned long now
= jiffies
; /* snapshot of now */
137 unsigned long timeout
;
138 struct dentry
*root
= sb
->s_root
;
139 struct list_head
*tmp
;
141 if (!sbi
->exp_timeout
|| !root
)
144 timeout
= sbi
->exp_timeout
;
146 for(tmp
= root
->d_subdirs
.next
;
147 tmp
!= &root
->d_subdirs
;
149 struct autofs_info
*ino
;
150 struct dentry
*dentry
= list_entry(tmp
, struct dentry
, d_child
);
152 if (dentry
->d_inode
== NULL
)
155 ino
= autofs4_dentry_ino(dentry
);
158 /* dentry in the process of being deleted */
162 /* No point expiring a pending mount */
163 if (dentry
->d_flags
& DCACHE_AUTOFS_PENDING
)
167 /* Too young to die */
168 if (time_after(ino
->last_used
+timeout
, now
))
171 /* update last_used here :-
172 - obviously makes sense if it is in use now
173 - less obviously, prevents rapid-fire expire
174 attempts if expire fails the first time */
175 ino
->last_used
= now
;
178 if (!is_tree_busy(dentry
)) {
179 DPRINTK(("autofs_expire: returning %p %.*s\n",
180 dentry
, dentry
->d_name
.len
, dentry
->d_name
.name
));
181 /* Start from here next time */
182 list_del(&root
->d_subdirs
);
183 list_add(&root
->d_subdirs
, &dentry
->d_child
);
191 /* Perform an expiry operation */
192 int autofs4_expire_run(struct super_block
*sb
,
193 struct autofs_sb_info
*sbi
,
194 struct autofs_packet_expire
*pkt_p
)
196 struct autofs_packet_expire pkt
;
197 struct dentry
*dentry
;
199 memset(&pkt
,0,sizeof pkt
);
201 pkt
.hdr
.proto_version
= sbi
->version
;
202 pkt
.hdr
.type
= autofs_ptype_expire
;
204 if ((dentry
= autofs4_expire(sb
, sbi
, 0)) == NULL
)
207 pkt
.len
= dentry
->d_name
.len
;
208 memcpy(pkt
.name
, dentry
->d_name
.name
, pkt
.len
);
209 pkt
.name
[pkt
.len
] = '\0';
211 if ( copy_to_user(pkt_p
, &pkt
, sizeof(struct autofs_packet_expire
)) )
217 /* Call repeatedly until it returns -EAGAIN, meaning there's nothing
219 int autofs4_expire_multi(struct super_block
*sb
,
220 struct autofs_sb_info
*sbi
, int *arg
)
222 struct dentry
*dentry
;
226 if (arg
&& get_user(do_now
, arg
))
229 if ((dentry
= autofs4_expire(sb
, sbi
, do_now
)) != NULL
) {
230 struct autofs_info
*de_info
= autofs4_dentry_ino(dentry
);
232 /* This is synchronous because it makes the daemon a
234 de_info
->flags
|= AUTOFS_INF_EXPIRING
;
235 ret
= autofs4_wait(sbi
, &dentry
->d_name
, NFY_EXPIRE
);
236 de_info
->flags
&= ~AUTOFS_INF_EXPIRING
;