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        /* Update the expiry counter if fs is busy */
  67        if (!may_umount_tree(path.mnt)) {
  68                struct autofs_info *ino = autofs4_dentry_ino(top);
  69                ino->last_used = jiffies;
  70                goto done;
  71        }
  72
  73        status = 0;
  74done:
  75        DPRINTK("returning = %d", status);
  76        path_put(&path);
  77        return status;
  78}
  79
  80/*
  81 * Calculate and dget next entry in the subdirs list under root.
  82 */
  83static struct dentry *get_next_positive_subdir(struct dentry *prev,
  84                                                struct dentry *root)
  85{
  86        struct autofs_sb_info *sbi = autofs4_sbi(root->d_sb);
  87        struct list_head *next;
  88        struct dentry *q;
  89
  90        spin_lock(&sbi->lookup_lock);
  91        spin_lock(&root->d_lock);
  92
  93        if (prev)
  94                next = prev->d_u.d_child.next;
  95        else {
  96                prev = dget_dlock(root);
  97                next = prev->d_subdirs.next;
  98        }
  99
 100cont:
 101        if (next == &root->d_subdirs) {
 102                spin_unlock(&root->d_lock);
 103                spin_unlock(&sbi->lookup_lock);
 104                dput(prev);
 105                return NULL;
 106        }
 107
 108        q = list_entry(next, struct dentry, d_u.d_child);
 109
 110        spin_lock_nested(&q->d_lock, DENTRY_D_LOCK_NESTED);
 111        /* Already gone or negative dentry (under construction) - try next */
 112        if (!d_count(q) || !simple_positive(q)) {
 113                spin_unlock(&q->d_lock);
 114                next = q->d_u.d_child.next;
 115                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        dput(prev);
 123
 124        return q;
 125}
 126
 127/*
 128 * Calculate and dget next entry in top down tree traversal.
 129 */
 130static struct dentry *get_next_positive_dentry(struct dentry *prev,
 131                                                struct dentry *root)
 132{
 133        struct autofs_sb_info *sbi = autofs4_sbi(root->d_sb);
 134        struct list_head *next;
 135        struct dentry *p, *ret;
 136
 137        if (prev == NULL)
 138                return dget(root);
 139
 140        spin_lock(&sbi->lookup_lock);
 141relock:
 142        p = prev;
 143        spin_lock(&p->d_lock);
 144again:
 145        next = p->d_subdirs.next;
 146        if (next == &p->d_subdirs) {
 147                while (1) {
 148                        struct dentry *parent;
 149
 150                        if (p == root) {
 151                                spin_unlock(&p->d_lock);
 152                                spin_unlock(&sbi->lookup_lock);
 153                                dput(prev);
 154                                return NULL;
 155                        }
 156
 157                        parent = p->d_parent;
 158                        if (!spin_trylock(&parent->d_lock)) {
 159                                spin_unlock(&p->d_lock);
 160                                cpu_relax();
 161                                goto relock;
 162                        }
 163                        spin_unlock(&p->d_lock);
 164                        next = p->d_u.d_child.next;
 165                        p = parent;
 166                        if (next != &parent->d_subdirs)
 167                                break;
 168                }
 169        }
 170        ret = list_entry(next, struct dentry, d_u.d_child);
 171
 172        spin_lock_nested(&ret->d_lock, DENTRY_D_LOCK_NESTED);
 173        /* Negative dentry - try next */
 174        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                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        dput(prev);
 186
 187        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 */
 196static int autofs4_direct_busy(struct vfsmount *mnt,
 197                                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        if (!may_umount_tree(mnt)) {
 206                struct autofs_info *ino = autofs4_dentry_ino(top);
 207                if (ino)
 208                        ino->last_used = jiffies;
 209                return 1;
 210        }
 211
 212        /* Timeout of a direct mount is determined by its top dentry */
 213        if (!autofs4_can_expire(top, timeout, do_now))
 214                return 1;
 215
 216        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 */
 222static int autofs4_tree_busy(struct vfsmount *mnt,
 223                             struct dentry *top,
 224                             unsigned long timeout,
 225                             int do_now)
 226{
 227        struct autofs_info *top_ino = autofs4_dentry_ino(top);
 228        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        if (!simple_positive(top))
 235                return 1;
 236
 237        p = NULL;
 238        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                if (d_mountpoint(p)) {
 249                        if (autofs4_mount_busy(mnt, p)) {
 250                                top_ino->last_used = jiffies;
 251                                dput(p);
 252                                return 1;
 253                        }
 254                } else {
 255                        struct autofs_info *ino = autofs4_dentry_ino(p);
 256                        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                        d_invalidate(p);
 263
 264                        /* allow for dget above and top is already dgot */
 265                        if (p == top)
 266                                ino_count += 2;
 267                        else
 268                                ino_count++;
 269
 270                        if (d_count(p) > ino_count) {
 271                                top_ino->last_used = jiffies;
 272                                dput(p);
 273                                return 1;
 274                        }
 275                }
 276        }
 277
 278        /* Timeout of a tree mount is ultimately determined by its top dentry */
 279        if (!autofs4_can_expire(top, timeout, do_now))
 280                return 1;
 281
 282        return 0;
 283}
 284
 285static struct dentry *autofs4_check_leaves(struct vfsmount *mnt,
 286                                           struct dentry *parent,
 287                                           unsigned long timeout,
 288                                           int do_now)
 289{
 290        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        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                if (d_mountpoint(p)) {
 301                        /* Can we umount this guy */
 302                        if (autofs4_mount_busy(mnt, p))
 303                                continue;
 304
 305                        /* Can we expire this guy */
 306                        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) */
 314struct 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        struct dentry *root = dget(sb->s_root);
 321        int do_now = how & AUTOFS_EXP_IMMEDIATE;
 322        struct autofs_info *ino;
 323
 324        if (!root)
 325                return NULL;
 326
 327        now = jiffies;
 328        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        if (ino->flags & AUTOFS_INF_PENDING)
 334                goto out;
 335        if (!autofs4_direct_busy(mnt, root, timeout, do_now)) {
 336                struct autofs_info *ino = autofs4_dentry_ino(root);
 337                ino->flags |= AUTOFS_INF_EXPIRING;
 338                init_completion(&ino->expire_complete);
 339                spin_unlock(&sbi->fs_lock);
 340                return root;
 341        }
 342out:
 343        spin_unlock(&sbi->fs_lock);
 344        dput(root);
 345
 346        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 */
 355struct 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        struct dentry *root = sb->s_root;
 362        struct dentry *dentry;
 363        struct dentry *expired = NULL;
 364        int do_now = how & AUTOFS_EXP_IMMEDIATE;
 365        int exp_leaves = how & AUTOFS_EXP_LEAVES;
 366        struct autofs_info *ino;
 367        unsigned int ino_count;
 368
 369        if (!root)
 370                return NULL;
 371
 372        now = jiffies;
 373        timeout = sbi->exp_timeout;
 374
 375        dentry = NULL;
 376        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                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                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                        if (autofs4_mount_busy(mnt, dentry))
 395                                goto next;
 396
 397                        /* Can we expire this guy */
 398                        if (autofs4_can_expire(dentry, timeout, do_now)) {
 399                                expired = dentry;
 400                                goto found;
 401                        }
 402                        goto next;
 403                }
 404
 405                if (simple_empty(dentry))
 406                        goto next;
 407
 408                /* Case 2: tree mount, expire iff entire tree is not busy */
 409                if (!exp_leaves) {
 410                        /* Path walk currently on this dentry? */
 411                        ino_count = atomic_read(&ino->count) + 1;
 412                        if (d_count(dentry) > ino_count)
 413                                goto next;
 414
 415                        if (!autofs4_tree_busy(mnt, dentry, timeout, do_now)) {
 416                                expired = dentry;
 417                                goto found;
 418                        }
 419                /*
 420                 * Case 3: pseudo direct mount, expire individual leaves
 421                 *         (autofs-4.1).
 422                 */
 423                } else {
 424                        /* Path walk currently on this dentry? */
 425                        ino_count = atomic_read(&ino->count) + 1;
 426                        if (d_count(dentry) > ino_count)
 427                                goto next;
 428
 429                        expired = autofs4_check_leaves(mnt, dentry, timeout, do_now);
 430                        if (expired) {
 431                                dput(dentry);
 432                                goto found;
 433                        }
 434                }
 435next:
 436                spin_unlock(&sbi->fs_lock);
 437        }
 438        return NULL;
 439
 440found:
 441        DPRINTK("returning %p %.*s",
 442                expired, (int)expired->d_name.len, expired->d_name.name);
 443        ino = autofs4_dentry_ino(expired);
 444        ino->flags |= AUTOFS_INF_EXPIRING;
 445        init_completion(&ino->expire_complete);
 446        spin_unlock(&sbi->fs_lock);
 447        spin_lock(&sbi->lookup_lock);
 448        spin_lock(&expired->d_parent->d_lock);
 449        spin_lock_nested(&expired->d_lock, DENTRY_D_LOCK_NESTED);
 450        list_move(&expired->d_parent->d_subdirs, &expired->d_u.d_child);
 451        spin_unlock(&expired->d_lock);
 452        spin_unlock(&expired->d_parent->d_lock);
 453        spin_unlock(&sbi->lookup_lock);
 454        return expired;
 455}
 456
 457int autofs4_expire_wait(struct dentry *dentry)
 458{
 459        struct autofs_sb_info *sbi = autofs4_sbi(dentry->d_sb);
 460        struct autofs_info *ino = autofs4_dentry_ino(dentry);
 461        int status;
 462
 463        /* Block on any pending expire */
 464        spin_lock(&sbi->fs_lock);
 465        if (ino->flags & AUTOFS_INF_EXPIRING) {
 466                spin_unlock(&sbi->fs_lock);
 467
 468                DPRINTK("waiting for expire %p name=%.*s",
 469                         dentry, dentry->d_name.len, dentry->d_name.name);
 470
 471                status = autofs4_wait(sbi, dentry, NFY_NONE);
 472                wait_for_completion(&ino->expire_complete);
 473
 474                DPRINTK("expire done status=%d", status);
 475
 476                if (d_unhashed(dentry))
 477                        return -EAGAIN;
 478
 479                return status;
 480        }
 481        spin_unlock(&sbi->fs_lock);
 482
 483        return 0;
 484}
 485
 486/* Perform an expiry operation */
 487int autofs4_expire_run(struct super_block *sb,
 488                      struct vfsmount *mnt,
 489                      struct autofs_sb_info *sbi,
 490                      struct autofs_packet_expire __user *pkt_p)
 491{
 492        struct autofs_packet_expire pkt;
 493        struct autofs_info *ino;
 494        struct dentry *dentry;
 495        int ret = 0;
 496
 497        memset(&pkt,0,sizeof pkt);
 498
 499        pkt.hdr.proto_version = sbi->version;
 500        pkt.hdr.type = autofs_ptype_expire;
 501
 502        if ((dentry = autofs4_expire_indirect(sb, mnt, sbi, 0)) == NULL)
 503                return -EAGAIN;
 504
 505        pkt.len = dentry->d_name.len;
 506        memcpy(pkt.name, dentry->d_name.name, pkt.len);
 507        pkt.name[pkt.len] = '\0';
 508        dput(dentry);
 509
 510        if ( copy_to_user(pkt_p, &pkt, sizeof(struct autofs_packet_expire)) )
 511                ret = -EFAULT;
 512
 513        spin_lock(&sbi->fs_lock);
 514        ino = autofs4_dentry_ino(dentry);
 515        ino->flags &= ~AUTOFS_INF_EXPIRING;
 516        complete_all(&ino->expire_complete);
 517        spin_unlock(&sbi->fs_lock);
 518
 519        return ret;
 520}
 521
 522int autofs4_do_expire_multi(struct super_block *sb, struct vfsmount *mnt,
 523                            struct autofs_sb_info *sbi, int when)
 524{
 525        struct dentry *dentry;
 526        int ret = -EAGAIN;
 527
 528        if (autofs_type_trigger(sbi->type))
 529                dentry = autofs4_expire_direct(sb, mnt, sbi, when);
 530        else
 531                dentry = autofs4_expire_indirect(sb, mnt, sbi, when);
 532
 533        if (dentry) {
 534                struct autofs_info *ino = autofs4_dentry_ino(dentry);
 535
 536                /* This is synchronous because it makes the daemon a
 537                   little easier */
 538                ret = autofs4_wait(sbi, dentry, NFY_EXPIRE);
 539
 540                spin_lock(&sbi->fs_lock);
 541                ino->flags &= ~AUTOFS_INF_EXPIRING;
 542                complete_all(&ino->expire_complete);
 543                spin_unlock(&sbi->fs_lock);
 544                dput(dentry);
 545        }
 546
 547        return ret;
 548}
 549
 550/* Call repeatedly until it returns -EAGAIN, meaning there's nothing
 551   more to be done */
 552int autofs4_expire_multi(struct super_block *sb, struct vfsmount *mnt,
 553                        struct autofs_sb_info *sbi, int __user *arg)
 554{
 555        int do_now = 0;
 556
 557        if (arg && get_user(do_now, arg))
 558                return -EFAULT;
 559
 560        return autofs4_do_expire_multi(sb, mnt, sbi, do_now);
 561}
 562
 563
lxr.linux.no kindly hosted by Redpill Linpro AS, provider of Linux consulting and operations services since 1995.