Branch data Line data Source code
1 : : /* -*- c -*- --------------------------------------------------------------- *
2 : : *
3 : : * linux/fs/autofs/expire.c
4 : : *
5 : : * Copyright 1997-1998 Transmeta Corporation -- All Rights Reserved
6 : : * Copyright 1999-2000 Jeremy Fitzhardinge <jeremy@goop.org>
7 : : * Copyright 2001-2006 Ian Kent <raven@themaw.net>
8 : : *
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.
12 : : *
13 : : * ------------------------------------------------------------------------- */
14 : :
15 : : #include "autofs_i.h"
16 : :
17 : : static unsigned long now;
18 : :
19 : : /* Check if a dentry can be expired */
20 : 0 : static inline int autofs4_can_expire(struct dentry *dentry,
21 : : unsigned long timeout, int do_now)
22 : : {
23 : : struct autofs_info *ino = autofs4_dentry_ino(dentry);
24 : :
25 : : /* dentry in the process of being deleted */
26 [ # # ][ # # ]: 0 : if (ino == NULL)
[ # # ][ # # ]
[ # # ]
27 : : return 0;
28 : :
29 [ # # ][ # # ]: 0 : if (!do_now) {
[ # # ][ # # ]
[ # # ]
30 : : /* Too young to die */
31 [ # # ][ # # ]: 0 : if (!timeout || time_after(ino->last_used + timeout, now))
[ # # ][ # # ]
[ # # ][ # # ]
[ # # ][ # # ]
[ # # ][ # # ]
32 : : return 0;
33 : :
34 : : /* update last_used here :-
35 : : - obviously makes sense if it is in use now
36 : : - less obviously, prevents rapid-fire expire
37 : : attempts if expire fails the first time */
38 : 0 : ino->last_used = now;
39 : : }
40 : : return 1;
41 : : }
42 : :
43 : : /* Check a mount point for busyness */
44 : 0 : static int autofs4_mount_busy(struct vfsmount *mnt, struct dentry *dentry)
45 : : {
46 : 0 : struct dentry *top = dentry;
47 : 0 : struct path path = {.mnt = mnt, .dentry = dentry};
48 : : int status = 1;
49 : :
50 : : DPRINTK("dentry %p %.*s",
51 : : dentry, (int)dentry->d_name.len, dentry->d_name.name);
52 : :
53 : 0 : path_get(&path);
54 : :
55 [ # # ]: 0 : if (!follow_down_one(&path))
56 : : goto done;
57 : :
58 [ # # ]: 0 : if (is_autofs4_dentry(path.dentry)) {
59 : 0 : struct autofs_sb_info *sbi = autofs4_sbi(path.dentry->d_sb);
60 : :
61 : : /* This is an autofs submount, we can't expire it */
62 [ # # ]: 0 : if (autofs_type_indirect(sbi->type))
63 : : goto done;
64 : : }
65 : :
66 : : /* Update the expiry counter if fs is busy */
67 [ # # ]: 0 : if (!may_umount_tree(path.mnt)) {
68 : : struct autofs_info *ino = autofs4_dentry_ino(top);
69 : 0 : ino->last_used = jiffies;
70 : 0 : goto done;
71 : : }
72 : :
73 : : status = 0;
74 : : done:
75 : : DPRINTK("returning = %d", status);
76 : 0 : path_put(&path);
77 : 0 : return status;
78 : : }
79 : :
80 : : /*
81 : : * Calculate and dget next entry in the subdirs list under root.
82 : : */
83 : 0 : static struct dentry *get_next_positive_subdir(struct dentry *prev,
84 : : struct dentry *root)
85 : : {
86 : 0 : struct autofs_sb_info *sbi = autofs4_sbi(root->d_sb);
87 : : struct list_head *next;
88 : 0 : struct dentry *q;
89 : :
90 : : spin_lock(&sbi->lookup_lock);
91 : : spin_lock(&root->d_lock);
92 : :
93 [ # # ]: 0 : if (prev)
94 : 0 : next = prev->d_u.d_child.next;
95 : : else {
96 : : prev = dget_dlock(root);
97 : 0 : next = prev->d_subdirs.next;
98 : : }
99 : :
100 : : cont:
101 [ # # ]: 0 : if (next == &root->d_subdirs) {
102 : : spin_unlock(&root->d_lock);
103 : : spin_unlock(&sbi->lookup_lock);
104 : 0 : dput(prev);
105 : 0 : return NULL;
106 : : }
107 : :
108 : 0 : q = list_entry(next, struct dentry, d_u.d_child);
109 : :
110 : 0 : spin_lock_nested(&q->d_lock, DENTRY_D_LOCK_NESTED);
111 : : /* Already gone or negative dentry (under construction) - try next */
112 [ # # ][ # # ]: 0 : if (!d_count(q) || !simple_positive(q)) {
113 : : spin_unlock(&q->d_lock);
114 : 0 : next = q->d_u.d_child.next;
115 : 0 : goto cont;
116 : : }
117 : : dget_dlock(q);
118 : : spin_unlock(&q->d_lock);
119 : : spin_unlock(&root->d_lock);
120 : : spin_unlock(&sbi->lookup_lock);
121 : :
122 : 0 : dput(prev);
123 : :
124 : 0 : return q;
125 : : }
126 : :
127 : : /*
128 : : * Calculate and dget next entry in top down tree traversal.
129 : : */
130 : 0 : static struct dentry *get_next_positive_dentry(struct dentry *prev,
131 : : struct dentry *root)
132 : : {
133 : 0 : struct autofs_sb_info *sbi = autofs4_sbi(root->d_sb);
134 : : struct list_head *next;
135 : : struct dentry *p, *ret;
136 : :
137 [ # # ]: 0 : if (prev == NULL)
138 : 0 : return dget(root);
139 : :
140 : : spin_lock(&sbi->lookup_lock);
141 : : relock:
142 : : p = prev;
143 : : spin_lock(&p->d_lock);
144 : : again:
145 : 0 : next = p->d_subdirs.next;
146 [ # # ]: 0 : if (next == &p->d_subdirs) {
147 : : while (1) {
148 : : struct dentry *parent;
149 : :
150 [ # # ]: 0 : if (p == root) {
151 : : spin_unlock(&p->d_lock);
152 : : spin_unlock(&sbi->lookup_lock);
153 : 0 : dput(prev);
154 : 0 : return NULL;
155 : : }
156 : :
157 : 0 : parent = p->d_parent;
158 [ # # ]: 0 : if (!spin_trylock(&parent->d_lock)) {
159 : : spin_unlock(&p->d_lock);
160 : 0 : cpu_relax();
161 : 0 : goto relock;
162 : : }
163 : : spin_unlock(&p->d_lock);
164 : 0 : next = p->d_u.d_child.next;
165 : : p = parent;
166 [ # # ]: 0 : if (next != &parent->d_subdirs)
167 : : break;
168 : : }
169 : : }
170 : 0 : ret = list_entry(next, struct dentry, d_u.d_child);
171 : :
172 : 0 : spin_lock_nested(&ret->d_lock, DENTRY_D_LOCK_NESTED);
173 : : /* Negative dentry - try next */
174 [ # # ]: 0 : if (!simple_positive(ret)) {
175 : : spin_unlock(&p->d_lock);
176 : : lock_set_subclass(&ret->d_lock.dep_map, 0, _RET_IP_);
177 : : p = ret;
178 : 0 : goto again;
179 : : }
180 : : dget_dlock(ret);
181 : : spin_unlock(&ret->d_lock);
182 : : spin_unlock(&p->d_lock);
183 : : spin_unlock(&sbi->lookup_lock);
184 : :
185 : 0 : dput(prev);
186 : :
187 : 0 : return ret;
188 : : }
189 : :
190 : : /*
191 : : * Check a direct mount point for busyness.
192 : : * Direct mounts have similar expiry semantics to tree mounts.
193 : : * The tree is not busy iff no mountpoints are busy and there are no
194 : : * autofs submounts.
195 : : */
196 : 0 : static int autofs4_direct_busy(struct vfsmount *mnt,
197 : 0 : struct dentry *top,
198 : : unsigned long timeout,
199 : : int do_now)
200 : : {
201 : : DPRINTK("top %p %.*s",
202 : : top, (int) top->d_name.len, top->d_name.name);
203 : :
204 : : /* If it's busy update the expiry counters */
205 [ # # ]: 0 : if (!may_umount_tree(mnt)) {
206 : : struct autofs_info *ino = autofs4_dentry_ino(top);
207 [ # # ]: 0 : if (ino)
208 : 0 : ino->last_used = jiffies;
209 : : return 1;
210 : : }
211 : :
212 : : /* Timeout of a direct mount is determined by its top dentry */
213 [ # # ]: 0 : if (!autofs4_can_expire(top, timeout, do_now))
214 : : return 1;
215 : :
216 : 0 : return 0;
217 : : }
218 : :
219 : : /* Check a directory tree of mount points for busyness
220 : : * The tree is not busy iff no mountpoints are busy
221 : : */
222 : 0 : static int autofs4_tree_busy(struct vfsmount *mnt,
223 : 0 : struct dentry *top,
224 : : unsigned long timeout,
225 : : int do_now)
226 : : {
227 : : struct autofs_info *top_ino = autofs4_dentry_ino(top);
228 : 0 : struct dentry *p;
229 : :
230 : : DPRINTK("top %p %.*s",
231 : : top, (int)top->d_name.len, top->d_name.name);
232 : :
233 : : /* Negative dentry - give up */
234 [ # # ]: 0 : if (!simple_positive(top))
235 : : return 1;
236 : :
237 : : p = NULL;
238 [ # # ]: 0 : while ((p = get_next_positive_dentry(p, top))) {
239 : : DPRINTK("dentry %p %.*s",
240 : : p, (int) p->d_name.len, p->d_name.name);
241 : :
242 : : /*
243 : : * Is someone visiting anywhere in the subtree ?
244 : : * If there's no mount we need to check the usage
245 : : * count for the autofs dentry.
246 : : * If the fs is busy update the expiry counter.
247 : : */
248 [ # # ]: 0 : if (d_mountpoint(p)) {
249 [ # # ]: 0 : if (autofs4_mount_busy(mnt, p)) {
250 : 0 : top_ino->last_used = jiffies;
251 : 0 : dput(p);
252 : 0 : return 1;
253 : : }
254 : : } else {
255 : : struct autofs_info *ino = autofs4_dentry_ino(p);
256 : 0 : unsigned int ino_count = atomic_read(&ino->count);
257 : :
258 : : /*
259 : : * Clean stale dentries below that have not been
260 : : * invalidated after a mount fail during lookup
261 : : */
262 : 0 : d_invalidate(p);
263 : :
264 : : /* allow for dget above and top is already dgot */
265 [ # # ]: 0 : if (p == top)
266 : 0 : ino_count += 2;
267 : : else
268 : 0 : ino_count++;
269 : :
270 [ # # ]: 0 : if (d_count(p) > ino_count) {
271 : 0 : top_ino->last_used = jiffies;
272 : 0 : dput(p);
273 : 0 : return 1;
274 : : }
275 : : }
276 : : }
277 : :
278 : : /* Timeout of a tree mount is ultimately determined by its top dentry */
279 [ # # ]: 0 : if (!autofs4_can_expire(top, timeout, do_now))
280 : : return 1;
281 : :
282 : 0 : return 0;
283 : : }
284 : :
285 : 0 : static struct dentry *autofs4_check_leaves(struct vfsmount *mnt,
286 : : struct dentry *parent,
287 : : unsigned long timeout,
288 : : int do_now)
289 : : {
290 : 0 : struct dentry *p;
291 : :
292 : : DPRINTK("parent %p %.*s",
293 : : parent, (int)parent->d_name.len, parent->d_name.name);
294 : :
295 : : p = NULL;
296 [ # # ]: 0 : while ((p = get_next_positive_dentry(p, parent))) {
297 : : DPRINTK("dentry %p %.*s",
298 : : p, (int) p->d_name.len, p->d_name.name);
299 : :
300 [ # # ]: 0 : if (d_mountpoint(p)) {
301 : : /* Can we umount this guy */
302 [ # # ]: 0 : if (autofs4_mount_busy(mnt, p))
303 : 0 : continue;
304 : :
305 : : /* Can we expire this guy */
306 [ # # ]: 0 : if (autofs4_can_expire(p, timeout, do_now))
307 : : return p;
308 : : }
309 : : }
310 : : return NULL;
311 : : }
312 : :
313 : : /* Check if we can expire a direct mount (possibly a tree) */
314 : 0 : struct dentry *autofs4_expire_direct(struct super_block *sb,
315 : : struct vfsmount *mnt,
316 : : struct autofs_sb_info *sbi,
317 : : int how)
318 : : {
319 : : unsigned long timeout;
320 : 0 : struct dentry *root = dget(sb->s_root);
321 : 0 : int do_now = how & AUTOFS_EXP_IMMEDIATE;
322 : : struct autofs_info *ino;
323 : :
324 [ # # ]: 0 : if (!root)
325 : : return NULL;
326 : :
327 : 0 : now = jiffies;
328 : 0 : timeout = sbi->exp_timeout;
329 : :
330 : : spin_lock(&sbi->fs_lock);
331 : : ino = autofs4_dentry_ino(root);
332 : : /* No point expiring a pending mount */
333 [ # # ]: 0 : if (ino->flags & AUTOFS_INF_PENDING)
334 : : goto out;
335 [ # # ]: 0 : if (!autofs4_direct_busy(mnt, root, timeout, do_now)) {
336 : : struct autofs_info *ino = autofs4_dentry_ino(root);
337 : 0 : ino->flags |= AUTOFS_INF_EXPIRING;
338 : : init_completion(&ino->expire_complete);
339 : : spin_unlock(&sbi->fs_lock);
340 : 0 : return root;
341 : : }
342 : : out:
343 : : spin_unlock(&sbi->fs_lock);
344 : 0 : dput(root);
345 : :
346 : 0 : return NULL;
347 : : }
348 : :
349 : : /*
350 : : * Find an eligible tree to time-out
351 : : * A tree is eligible if :-
352 : : * - it is unused by any user process
353 : : * - it has been unused for exp_timeout time
354 : : */
355 : 0 : struct dentry *autofs4_expire_indirect(struct super_block *sb,
356 : : struct vfsmount *mnt,
357 : : struct autofs_sb_info *sbi,
358 : : int how)
359 : : {
360 : : unsigned long timeout;
361 : 0 : struct dentry *root = sb->s_root;
362 : 0 : struct dentry *dentry;
363 : 0 : struct dentry *expired = NULL;
364 : 0 : int do_now = how & AUTOFS_EXP_IMMEDIATE;
365 : 0 : int exp_leaves = how & AUTOFS_EXP_LEAVES;
366 : : struct autofs_info *ino;
367 : : unsigned int ino_count;
368 : :
369 [ # # ]: 0 : if (!root)
370 : : return NULL;
371 : :
372 : 0 : now = jiffies;
373 : 0 : timeout = sbi->exp_timeout;
374 : :
375 : : dentry = NULL;
376 [ # # ]: 0 : while ((dentry = get_next_positive_subdir(dentry, root))) {
377 : : spin_lock(&sbi->fs_lock);
378 : : ino = autofs4_dentry_ino(dentry);
379 : : /* No point expiring a pending mount */
380 [ # # ]: 0 : if (ino->flags & AUTOFS_INF_PENDING)
381 : : goto next;
382 : :
383 : : /*
384 : : * Case 1: (i) indirect mount or top level pseudo direct mount
385 : : * (autofs-4.1).
386 : : * (ii) indirect mount with offset mount, check the "/"
387 : : * offset (autofs-5.0+).
388 : : */
389 [ # # ]: 0 : if (d_mountpoint(dentry)) {
390 : : DPRINTK("checking mountpoint %p %.*s",
391 : : dentry, (int)dentry->d_name.len, dentry->d_name.name);
392 : :
393 : : /* Can we umount this guy */
394 [ # # ]: 0 : if (autofs4_mount_busy(mnt, dentry))
395 : : goto next;
396 : :
397 : : /* Can we expire this guy */
398 [ # # ]: 0 : if (autofs4_can_expire(dentry, timeout, do_now)) {
399 : : expired = dentry;
400 : : goto found;
401 : : }
402 : : goto next;
403 : : }
404 : :
405 [ # # ][ # # ]: 0 : if (dentry->d_inode && S_ISLNK(dentry->d_inode->i_mode)) {
406 : : DPRINTK("checking symlink %p %.*s",
407 : : dentry, (int)dentry->d_name.len, dentry->d_name.name);
408 : : /*
409 : : * A symlink can't be "busy" in the usual sense so
410 : : * just check last used for expire timeout.
411 : : */
412 [ # # ]: 0 : if (autofs4_can_expire(dentry, timeout, do_now)) {
413 : : expired = dentry;
414 : : goto found;
415 : : }
416 : : goto next;
417 : : }
418 : :
419 [ # # ]: 0 : if (simple_empty(dentry))
420 : : goto next;
421 : :
422 : : /* Case 2: tree mount, expire iff entire tree is not busy */
423 [ # # ]: 0 : if (!exp_leaves) {
424 : : /* Path walk currently on this dentry? */
425 : 0 : ino_count = atomic_read(&ino->count) + 1;
426 [ # # ]: 0 : if (d_count(dentry) > ino_count)
427 : : goto next;
428 : :
429 [ # # ]: 0 : if (!autofs4_tree_busy(mnt, dentry, timeout, do_now)) {
430 : : expired = dentry;
431 : : goto found;
432 : : }
433 : : /*
434 : : * Case 3: pseudo direct mount, expire individual leaves
435 : : * (autofs-4.1).
436 : : */
437 : : } else {
438 : : /* Path walk currently on this dentry? */
439 : 0 : ino_count = atomic_read(&ino->count) + 1;
440 [ # # ]: 0 : if (d_count(dentry) > ino_count)
441 : : goto next;
442 : :
443 : 0 : expired = autofs4_check_leaves(mnt, dentry, timeout, do_now);
444 [ # # ]: 0 : if (expired) {
445 : 0 : dput(dentry);
446 : 0 : goto found;
447 : : }
448 : : }
449 : : next:
450 : : spin_unlock(&sbi->fs_lock);
451 : : }
452 : : return NULL;
453 : :
454 : : found:
455 : : DPRINTK("returning %p %.*s",
456 : : expired, (int)expired->d_name.len, expired->d_name.name);
457 : : ino = autofs4_dentry_ino(expired);
458 : 0 : ino->flags |= AUTOFS_INF_EXPIRING;
459 : : init_completion(&ino->expire_complete);
460 : : spin_unlock(&sbi->fs_lock);
461 : : spin_lock(&sbi->lookup_lock);
462 : 0 : spin_lock(&expired->d_parent->d_lock);
463 : 0 : spin_lock_nested(&expired->d_lock, DENTRY_D_LOCK_NESTED);
464 : 0 : list_move(&expired->d_parent->d_subdirs, &expired->d_u.d_child);
465 : : spin_unlock(&expired->d_lock);
466 : 0 : spin_unlock(&expired->d_parent->d_lock);
467 : : spin_unlock(&sbi->lookup_lock);
468 : 0 : return expired;
469 : : }
470 : :
471 : 0 : int autofs4_expire_wait(struct dentry *dentry)
472 : : {
473 : 0 : struct autofs_sb_info *sbi = autofs4_sbi(dentry->d_sb);
474 : : struct autofs_info *ino = autofs4_dentry_ino(dentry);
475 : : int status;
476 : :
477 : : /* Block on any pending expire */
478 : : spin_lock(&sbi->fs_lock);
479 [ # # ]: 0 : if (ino->flags & AUTOFS_INF_EXPIRING) {
480 : : spin_unlock(&sbi->fs_lock);
481 : :
482 : : DPRINTK("waiting for expire %p name=%.*s",
483 : : dentry, dentry->d_name.len, dentry->d_name.name);
484 : :
485 : 0 : status = autofs4_wait(sbi, dentry, NFY_NONE);
486 : 0 : wait_for_completion(&ino->expire_complete);
487 : :
488 : : DPRINTK("expire done status=%d", status);
489 : :
490 [ # # ]: 0 : if (d_unhashed(dentry))
491 : : return -EAGAIN;
492 : :
493 : 0 : return status;
494 : : }
495 : : spin_unlock(&sbi->fs_lock);
496 : :
497 : 0 : return 0;
498 : : }
499 : :
500 : : /* Perform an expiry operation */
501 : 0 : int autofs4_expire_run(struct super_block *sb,
502 : : struct vfsmount *mnt,
503 : : struct autofs_sb_info *sbi,
504 : : struct autofs_packet_expire __user *pkt_p)
505 : : {
506 : : struct autofs_packet_expire pkt;
507 : : struct autofs_info *ino;
508 : 0 : struct dentry *dentry;
509 : : int ret = 0;
510 : :
511 : 0 : memset(&pkt,0,sizeof pkt);
512 : :
513 : 0 : pkt.hdr.proto_version = sbi->version;
514 : 0 : pkt.hdr.type = autofs_ptype_expire;
515 : :
516 [ # # ]: 0 : if ((dentry = autofs4_expire_indirect(sb, mnt, sbi, 0)) == NULL)
517 : : return -EAGAIN;
518 : :
519 : 0 : pkt.len = dentry->d_name.len;
520 : 0 : memcpy(pkt.name, dentry->d_name.name, pkt.len);
521 : 0 : pkt.name[pkt.len] = '\0';
522 : 0 : dput(dentry);
523 : :
524 [ # # ]: 0 : if ( copy_to_user(pkt_p, &pkt, sizeof(struct autofs_packet_expire)) )
525 : : ret = -EFAULT;
526 : :
527 : : spin_lock(&sbi->fs_lock);
528 : : ino = autofs4_dentry_ino(dentry);
529 : 0 : ino->flags &= ~AUTOFS_INF_EXPIRING;
530 : 0 : complete_all(&ino->expire_complete);
531 : : spin_unlock(&sbi->fs_lock);
532 : :
533 : 0 : return ret;
534 : : }
535 : :
536 : 0 : int autofs4_do_expire_multi(struct super_block *sb, struct vfsmount *mnt,
537 : : struct autofs_sb_info *sbi, int when)
538 : : {
539 : 0 : struct dentry *dentry;
540 : : int ret = -EAGAIN;
541 : :
542 [ # # ]: 0 : if (autofs_type_trigger(sbi->type))
543 : 0 : dentry = autofs4_expire_direct(sb, mnt, sbi, when);
544 : : else
545 : 0 : dentry = autofs4_expire_indirect(sb, mnt, sbi, when);
546 : :
547 [ # # ]: 0 : if (dentry) {
548 : : struct autofs_info *ino = autofs4_dentry_ino(dentry);
549 : :
550 : : /* This is synchronous because it makes the daemon a
551 : : little easier */
552 : 0 : ret = autofs4_wait(sbi, dentry, NFY_EXPIRE);
553 : :
554 : : spin_lock(&sbi->fs_lock);
555 : 0 : ino->flags &= ~AUTOFS_INF_EXPIRING;
556 : 0 : complete_all(&ino->expire_complete);
557 : : spin_unlock(&sbi->fs_lock);
558 : 0 : dput(dentry);
559 : : }
560 : :
561 : 0 : return ret;
562 : : }
563 : :
564 : : /* Call repeatedly until it returns -EAGAIN, meaning there's nothing
565 : : more to be done */
566 : 0 : int autofs4_expire_multi(struct super_block *sb, struct vfsmount *mnt,
567 : : struct autofs_sb_info *sbi, int __user *arg)
568 : : {
569 : : int do_now = 0;
570 : :
571 [ # # ][ # # ]: 0 : if (arg && get_user(do_now, arg))
572 : : return -EFAULT;
573 : :
574 : 0 : return autofs4_do_expire_multi(sb, mnt, sbi, do_now);
575 : : }
576 : :
|