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