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