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