linux/fs/afs/dir.c
<<
>>
Prefs
   1/* dir.c: AFS filesystem directory handling
   2 *
   3 * Copyright (C) 2002 Red Hat, Inc. All Rights Reserved.
   4 * Written by David Howells (dhowells@redhat.com)
   5 *
   6 * This program is free software; you can redistribute it and/or
   7 * modify it under the terms of the GNU General Public License
   8 * as published by the Free Software Foundation; either version
   9 * 2 of the License, or (at your option) any later version.
  10 */
  11
  12#include <linux/kernel.h>
  13#include <linux/module.h>
  14#include <linux/init.h>
  15#include <linux/fs.h>
  16#include <linux/namei.h>
  17#include <linux/pagemap.h>
  18#include <linux/ctype.h>
  19#include <linux/sched.h>
  20#include "internal.h"
  21
  22static struct dentry *afs_lookup(struct inode *dir, struct dentry *dentry,
  23                                 unsigned int flags);
  24static int afs_dir_open(struct inode *inode, struct file *file);
  25static int afs_readdir(struct file *file, struct dir_context *ctx);
  26static int afs_d_revalidate(struct dentry *dentry, unsigned int flags);
  27static int afs_d_delete(const struct dentry *dentry);
  28static void afs_d_release(struct dentry *dentry);
  29static int afs_lookup_filldir(void *_cookie, const char *name, int nlen,
  30                                  loff_t fpos, u64 ino, unsigned dtype);
  31static int afs_create(struct inode *dir, struct dentry *dentry, umode_t mode,
  32                      bool excl);
  33static int afs_mkdir(struct inode *dir, struct dentry *dentry, umode_t mode);
  34static int afs_rmdir(struct inode *dir, struct dentry *dentry);
  35static int afs_unlink(struct inode *dir, struct dentry *dentry);
  36static int afs_link(struct dentry *from, struct inode *dir,
  37                    struct dentry *dentry);
  38static int afs_symlink(struct inode *dir, struct dentry *dentry,
  39                       const char *content);
  40static int afs_rename(struct inode *old_dir, struct dentry *old_dentry,
  41                      struct inode *new_dir, struct dentry *new_dentry);
  42
  43const struct file_operations afs_dir_file_operations = {
  44        .open           = afs_dir_open,
  45        .release        = afs_release,
  46        .iterate        = afs_readdir,
  47        .lock           = afs_lock,
  48        .llseek         = generic_file_llseek,
  49};
  50
  51const struct inode_operations afs_dir_inode_operations = {
  52        .create         = afs_create,
  53        .lookup         = afs_lookup,
  54        .link           = afs_link,
  55        .unlink         = afs_unlink,
  56        .symlink        = afs_symlink,
  57        .mkdir          = afs_mkdir,
  58        .rmdir          = afs_rmdir,
  59        .rename         = afs_rename,
  60        .permission     = afs_permission,
  61        .getattr        = afs_getattr,
  62        .setattr        = afs_setattr,
  63};
  64
  65const struct dentry_operations afs_fs_dentry_operations = {
  66        .d_revalidate   = afs_d_revalidate,
  67        .d_delete       = afs_d_delete,
  68        .d_release      = afs_d_release,
  69        .d_automount    = afs_d_automount,
  70};
  71
  72#define AFS_DIR_HASHTBL_SIZE    128
  73#define AFS_DIR_DIRENT_SIZE     32
  74#define AFS_DIRENT_PER_BLOCK    64
  75
  76union afs_dirent {
  77        struct {
  78                uint8_t         valid;
  79                uint8_t         unused[1];
  80                __be16          hash_next;
  81                __be32          vnode;
  82                __be32          unique;
  83                uint8_t         name[16];
  84                uint8_t         overflow[4];    /* if any char of the name (inc
  85                                                 * NUL) reaches here, consume
  86                                                 * the next dirent too */
  87        } u;
  88        uint8_t extended_name[32];
  89};
  90
  91/* AFS directory page header (one at the beginning of every 2048-byte chunk) */
  92struct afs_dir_pagehdr {
  93        __be16          npages;
  94        __be16          magic;
  95#define AFS_DIR_MAGIC htons(1234)
  96        uint8_t         nentries;
  97        uint8_t         bitmap[8];
  98        uint8_t         pad[19];
  99};
 100
 101/* directory block layout */
 102union afs_dir_block {
 103
 104        struct afs_dir_pagehdr pagehdr;
 105
 106        struct {
 107                struct afs_dir_pagehdr  pagehdr;
 108                uint8_t                 alloc_ctrs[128];
 109                /* dir hash table */
 110                uint16_t                hashtable[AFS_DIR_HASHTBL_SIZE];
 111        } hdr;
 112
 113        union afs_dirent dirents[AFS_DIRENT_PER_BLOCK];
 114};
 115
 116/* layout on a linux VM page */
 117struct afs_dir_page {
 118        union afs_dir_block blocks[PAGE_SIZE / sizeof(union afs_dir_block)];
 119};
 120
 121struct afs_lookup_cookie {
 122        struct dir_context ctx;
 123        struct afs_fid  fid;
 124        struct qstr name;
 125        int             found;
 126};
 127
 128/*
 129 * check that a directory page is valid
 130 */
 131static inline void afs_dir_check_page(struct inode *dir, struct page *page)
 132{
 133        struct afs_dir_page *dbuf;
 134        loff_t latter;
 135        int tmp, qty;
 136
 137#if 0
 138        /* check the page count */
 139        qty = desc.size / sizeof(dbuf->blocks[0]);
 140        if (qty == 0)
 141                goto error;
 142
 143        if (page->index == 0 && qty != ntohs(dbuf->blocks[0].pagehdr.npages)) {
 144                printk("kAFS: %s(%lu): wrong number of dir blocks %d!=%hu\n",
 145                       __func__, dir->i_ino, qty,
 146                       ntohs(dbuf->blocks[0].pagehdr.npages));
 147                goto error;
 148        }
 149#endif
 150
 151        /* determine how many magic numbers there should be in this page */
 152        latter = dir->i_size - page_offset(page);
 153        if (latter >= PAGE_SIZE)
 154                qty = PAGE_SIZE;
 155        else
 156                qty = latter;
 157        qty /= sizeof(union afs_dir_block);
 158
 159        /* check them */
 160        dbuf = page_address(page);
 161        for (tmp = 0; tmp < qty; tmp++) {
 162                if (dbuf->blocks[tmp].pagehdr.magic != AFS_DIR_MAGIC) {
 163                        printk("kAFS: %s(%lu): bad magic %d/%d is %04hx\n",
 164                               __func__, dir->i_ino, tmp, qty,
 165                               ntohs(dbuf->blocks[tmp].pagehdr.magic));
 166                        goto error;
 167                }
 168        }
 169
 170        SetPageChecked(page);
 171        return;
 172
 173error:
 174        SetPageChecked(page);
 175        SetPageError(page);
 176}
 177
 178/*
 179 * discard a page cached in the pagecache
 180 */
 181static inline void afs_dir_put_page(struct page *page)
 182{
 183        kunmap(page);
 184        page_cache_release(page);
 185}
 186
 187/*
 188 * get a page into the pagecache
 189 */
 190static struct page *afs_dir_get_page(struct inode *dir, unsigned long index,
 191                                     struct key *key)
 192{
 193        struct page *page;
 194        _enter("{%lu},%lu", dir->i_ino, index);
 195
 196        page = read_cache_page(dir->i_mapping, index, afs_page_filler, key);
 197        if (!IS_ERR(page)) {
 198                kmap(page);
 199                if (!PageChecked(page))
 200                        afs_dir_check_page(dir, page);
 201                if (PageError(page))
 202                        goto fail;
 203        }
 204        return page;
 205
 206fail:
 207        afs_dir_put_page(page);
 208        _leave(" = -EIO");
 209        return ERR_PTR(-EIO);
 210}
 211
 212/*
 213 * open an AFS directory file
 214 */
 215static int afs_dir_open(struct inode *inode, struct file *file)
 216{
 217        _enter("{%lu}", inode->i_ino);
 218
 219        BUILD_BUG_ON(sizeof(union afs_dir_block) != 2048);
 220        BUILD_BUG_ON(sizeof(union afs_dirent) != 32);
 221
 222        if (test_bit(AFS_VNODE_DELETED, &AFS_FS_I(inode)->flags))
 223                return -ENOENT;
 224
 225        return afs_open(inode, file);
 226}
 227
 228/*
 229 * deal with one block in an AFS directory
 230 */
 231static int afs_dir_iterate_block(struct dir_context *ctx,
 232                                 union afs_dir_block *block,
 233                                 unsigned blkoff)
 234{
 235        union afs_dirent *dire;
 236        unsigned offset, next, curr;
 237        size_t nlen;
 238        int tmp;
 239
 240        _enter("%u,%x,%p,,",(unsigned)ctx->pos,blkoff,block);
 241
 242        curr = (ctx->pos - blkoff) / sizeof(union afs_dirent);
 243
 244        /* walk through the block, an entry at a time */
 245        for (offset = AFS_DIRENT_PER_BLOCK - block->pagehdr.nentries;
 246             offset < AFS_DIRENT_PER_BLOCK;
 247             offset = next
 248             ) {
 249                next = offset + 1;
 250
 251                /* skip entries marked unused in the bitmap */
 252                if (!(block->pagehdr.bitmap[offset / 8] &
 253                      (1 << (offset % 8)))) {
 254                        _debug("ENT[%Zu.%u]: unused",
 255                               blkoff / sizeof(union afs_dir_block), offset);
 256                        if (offset >= curr)
 257                                ctx->pos = blkoff +
 258                                        next * sizeof(union afs_dirent);
 259                        continue;
 260                }
 261
 262                /* got a valid entry */
 263                dire = &block->dirents[offset];
 264                nlen = strnlen(dire->u.name,
 265                               sizeof(*block) -
 266                               offset * sizeof(union afs_dirent));
 267
 268                _debug("ENT[%Zu.%u]: %s %Zu \"%s\"",
 269                       blkoff / sizeof(union afs_dir_block), offset,
 270                       (offset < curr ? "skip" : "fill"),
 271                       nlen, dire->u.name);
 272
 273                /* work out where the next possible entry is */
 274                for (tmp = nlen; tmp > 15; tmp -= sizeof(union afs_dirent)) {
 275                        if (next >= AFS_DIRENT_PER_BLOCK) {
 276                                _debug("ENT[%Zu.%u]:"
 277                                       " %u travelled beyond end dir block"
 278                                       " (len %u/%Zu)",
 279                                       blkoff / sizeof(union afs_dir_block),
 280                                       offset, next, tmp, nlen);
 281                                return -EIO;
 282                        }
 283                        if (!(block->pagehdr.bitmap[next / 8] &
 284                              (1 << (next % 8)))) {
 285                                _debug("ENT[%Zu.%u]:"
 286                                       " %u unmarked extension (len %u/%Zu)",
 287                                       blkoff / sizeof(union afs_dir_block),
 288                                       offset, next, tmp, nlen);
 289                                return -EIO;
 290                        }
 291
 292                        _debug("ENT[%Zu.%u]: ext %u/%Zu",
 293                               blkoff / sizeof(union afs_dir_block),
 294                               next, tmp, nlen);
 295                        next++;
 296                }
 297
 298                /* skip if starts before the current position */
 299                if (offset < curr)
 300                        continue;
 301
 302                /* found the next entry */
 303                if (!dir_emit(ctx, dire->u.name, nlen,
 304                              ntohl(dire->u.vnode),
 305                              ctx->actor == afs_lookup_filldir ?
 306                              ntohl(dire->u.unique) : DT_UNKNOWN)) {
 307                        _leave(" = 0 [full]");
 308                        return 0;
 309                }
 310
 311                ctx->pos = blkoff + next * sizeof(union afs_dirent);
 312        }
 313
 314        _leave(" = 1 [more]");
 315        return 1;
 316}
 317
 318/*
 319 * iterate through the data blob that lists the contents of an AFS directory
 320 */
 321static int afs_dir_iterate(struct inode *dir, struct dir_context *ctx,
 322                           struct key *key)
 323{
 324        union afs_dir_block *dblock;
 325        struct afs_dir_page *dbuf;
 326        struct page *page;
 327        unsigned blkoff, limit;
 328        int ret;
 329
 330        _enter("{%lu},%u,,", dir->i_ino, (unsigned)ctx->pos);
 331
 332        if (test_bit(AFS_VNODE_DELETED, &AFS_FS_I(dir)->flags)) {
 333                _leave(" = -ESTALE");
 334                return -ESTALE;
 335        }
 336
 337        /* round the file position up to the next entry boundary */
 338        ctx->pos += sizeof(union afs_dirent) - 1;
 339        ctx->pos &= ~(sizeof(union afs_dirent) - 1);
 340
 341        /* walk through the blocks in sequence */
 342        ret = 0;
 343        while (ctx->pos < dir->i_size) {
 344                blkoff = ctx->pos & ~(sizeof(union afs_dir_block) - 1);
 345
 346                /* fetch the appropriate page from the directory */
 347                page = afs_dir_get_page(dir, blkoff / PAGE_SIZE, key);
 348                if (IS_ERR(page)) {
 349                        ret = PTR_ERR(page);
 350                        break;
 351                }
 352
 353                limit = blkoff & ~(PAGE_SIZE - 1);
 354
 355                dbuf = page_address(page);
 356
 357                /* deal with the individual blocks stashed on this page */
 358                do {
 359                        dblock = &dbuf->blocks[(blkoff % PAGE_SIZE) /
 360                                               sizeof(union afs_dir_block)];
 361                        ret = afs_dir_iterate_block(ctx, dblock, blkoff);
 362                        if (ret != 1) {
 363                                afs_dir_put_page(page);
 364                                goto out;
 365                        }
 366
 367                        blkoff += sizeof(union afs_dir_block);
 368
 369                } while (ctx->pos < dir->i_size && blkoff < limit);
 370
 371                afs_dir_put_page(page);
 372                ret = 0;
 373        }
 374
 375out:
 376        _leave(" = %d", ret);
 377        return ret;
 378}
 379
 380/*
 381 * read an AFS directory
 382 */
 383static int afs_readdir(struct file *file, struct dir_context *ctx)
 384{
 385        return afs_dir_iterate(file_inode(file), 
 386                              ctx, file->private_data);
 387}
 388
 389/*
 390 * search the directory for a name
 391 * - if afs_dir_iterate_block() spots this function, it'll pass the FID
 392 *   uniquifier through dtype
 393 */
 394static int afs_lookup_filldir(void *_cookie, const char *name, int nlen,
 395                              loff_t fpos, u64 ino, unsigned dtype)
 396{
 397        struct afs_lookup_cookie *cookie = _cookie;
 398
 399        _enter("{%s,%u},%s,%u,,%llu,%u",
 400               cookie->name.name, cookie->name.len, name, nlen,
 401               (unsigned long long) ino, dtype);
 402
 403        /* insanity checks first */
 404        BUILD_BUG_ON(sizeof(union afs_dir_block) != 2048);
 405        BUILD_BUG_ON(sizeof(union afs_dirent) != 32);
 406
 407        if (cookie->name.len != nlen ||
 408            memcmp(cookie->name.name, name, nlen) != 0) {
 409                _leave(" = 0 [no]");
 410                return 0;
 411        }
 412
 413        cookie->fid.vnode = ino;
 414        cookie->fid.unique = dtype;
 415        cookie->found = 1;
 416
 417        _leave(" = -1 [found]");
 418        return -1;
 419}
 420
 421/*
 422 * do a lookup in a directory
 423 * - just returns the FID the dentry name maps to if found
 424 */
 425static int afs_do_lookup(struct inode *dir, struct dentry *dentry,
 426                         struct afs_fid *fid, struct key *key)
 427{
 428        struct afs_super_info *as = dir->i_sb->s_fs_info;
 429        struct afs_lookup_cookie cookie = {
 430                .ctx.actor = afs_lookup_filldir,
 431                .name = dentry->d_name,
 432                .fid.vid = as->volume->vid
 433        };
 434        int ret;
 435
 436        _enter("{%lu},%p{%s},", dir->i_ino, dentry, dentry->d_name.name);
 437
 438        /* search the directory */
 439        ret = afs_dir_iterate(dir, &cookie.ctx, key);
 440        if (ret < 0) {
 441                _leave(" = %d [iter]", ret);
 442                return ret;
 443        }
 444
 445        ret = -ENOENT;
 446        if (!cookie.found) {
 447                _leave(" = -ENOENT [not found]");
 448                return -ENOENT;
 449        }
 450
 451        *fid = cookie.fid;
 452        _leave(" = 0 { vn=%u u=%u }", fid->vnode, fid->unique);
 453        return 0;
 454}
 455
 456/*
 457 * Try to auto mount the mountpoint with pseudo directory, if the autocell
 458 * operation is setted.
 459 */
 460static struct inode *afs_try_auto_mntpt(
 461        int ret, struct dentry *dentry, struct inode *dir, struct key *key,
 462        struct afs_fid *fid)
 463{
 464        const char *devname = dentry->d_name.name;
 465        struct afs_vnode *vnode = AFS_FS_I(dir);
 466        struct inode *inode;
 467
 468        _enter("%d, %p{%s}, {%x:%u}, %p",
 469               ret, dentry, devname, vnode->fid.vid, vnode->fid.vnode, key);
 470
 471        if (ret != -ENOENT ||
 472            !test_bit(AFS_VNODE_AUTOCELL, &vnode->flags))
 473                goto out;
 474
 475        inode = afs_iget_autocell(dir, devname, strlen(devname), key);
 476        if (IS_ERR(inode)) {
 477                ret = PTR_ERR(inode);
 478                goto out;
 479        }
 480
 481        *fid = AFS_FS_I(inode)->fid;
 482        _leave("= %p", inode);
 483        return inode;
 484
 485out:
 486        _leave("= %d", ret);
 487        return ERR_PTR(ret);
 488}
 489
 490/*
 491 * look up an entry in a directory
 492 */
 493static struct dentry *afs_lookup(struct inode *dir, struct dentry *dentry,
 494                                 unsigned int flags)
 495{
 496        struct afs_vnode *vnode;
 497        struct afs_fid fid;
 498        struct inode *inode;
 499        struct key *key;
 500        int ret;
 501
 502        vnode = AFS_FS_I(dir);
 503
 504        _enter("{%x:%u},%p{%s},",
 505               vnode->fid.vid, vnode->fid.vnode, dentry, dentry->d_name.name);
 506
 507        ASSERTCMP(dentry->d_inode, ==, NULL);
 508
 509        if (dentry->d_name.len >= AFSNAMEMAX) {
 510                _leave(" = -ENAMETOOLONG");
 511                return ERR_PTR(-ENAMETOOLONG);
 512        }
 513
 514        if (test_bit(AFS_VNODE_DELETED, &vnode->flags)) {
 515                _leave(" = -ESTALE");
 516                return ERR_PTR(-ESTALE);
 517        }
 518
 519        key = afs_request_key(vnode->volume->cell);
 520        if (IS_ERR(key)) {
 521                _leave(" = %ld [key]", PTR_ERR(key));
 522                return ERR_CAST(key);
 523        }
 524
 525        ret = afs_validate(vnode, key);
 526        if (ret < 0) {
 527                key_put(key);
 528                _leave(" = %d [val]", ret);
 529                return ERR_PTR(ret);
 530        }
 531
 532        ret = afs_do_lookup(dir, dentry, &fid, key);
 533        if (ret < 0) {
 534                inode = afs_try_auto_mntpt(ret, dentry, dir, key, &fid);
 535                if (!IS_ERR(inode)) {
 536                        key_put(key);
 537                        goto success;
 538                }
 539
 540                ret = PTR_ERR(inode);
 541                key_put(key);
 542                if (ret == -ENOENT) {
 543                        d_add(dentry, NULL);
 544                        _leave(" = NULL [negative]");
 545                        return NULL;
 546                }
 547                _leave(" = %d [do]", ret);
 548                return ERR_PTR(ret);
 549        }
 550        dentry->d_fsdata = (void *)(unsigned long) vnode->status.data_version;
 551
 552        /* instantiate the dentry */
 553        inode = afs_iget(dir->i_sb, key, &fid, NULL, NULL);
 554        key_put(key);
 555        if (IS_ERR(inode)) {
 556                _leave(" = %ld", PTR_ERR(inode));
 557                return ERR_CAST(inode);
 558        }
 559
 560success:
 561        d_add(dentry, inode);
 562        _leave(" = 0 { vn=%u u=%u } -> { ino=%lu v=%u }",
 563               fid.vnode,
 564               fid.unique,
 565               dentry->d_inode->i_ino,
 566               dentry->d_inode->i_generation);
 567
 568        return NULL;
 569}
 570
 571/*
 572 * check that a dentry lookup hit has found a valid entry
 573 * - NOTE! the hit can be a negative hit too, so we can't assume we have an
 574 *   inode
 575 */
 576static int afs_d_revalidate(struct dentry *dentry, unsigned int flags)
 577{
 578        struct afs_vnode *vnode, *dir;
 579        struct afs_fid uninitialized_var(fid);
 580        struct dentry *parent;
 581        struct key *key;
 582        void *dir_version;
 583        int ret;
 584
 585        if (flags & LOOKUP_RCU)
 586                return -ECHILD;
 587
 588        vnode = AFS_FS_I(dentry->d_inode);
 589
 590        if (dentry->d_inode)
 591                _enter("{v={%x:%u} n=%s fl=%lx},",
 592                       vnode->fid.vid, vnode->fid.vnode, dentry->d_name.name,
 593                       vnode->flags);
 594        else
 595                _enter("{neg n=%s}", dentry->d_name.name);
 596
 597        key = afs_request_key(AFS_FS_S(dentry->d_sb)->volume->cell);
 598        if (IS_ERR(key))
 599                key = NULL;
 600
 601        /* lock down the parent dentry so we can peer at it */
 602        parent = dget_parent(dentry);
 603        dir = AFS_FS_I(parent->d_inode);
 604
 605        /* validate the parent directory */
 606        if (test_bit(AFS_VNODE_MODIFIED, &dir->flags))
 607                afs_validate(dir, key);
 608
 609        if (test_bit(AFS_VNODE_DELETED, &dir->flags)) {
 610                _debug("%s: parent dir deleted", dentry->d_name.name);
 611                goto out_bad;
 612        }
 613
 614        dir_version = (void *) (unsigned long) dir->status.data_version;
 615        if (dentry->d_fsdata == dir_version)
 616                goto out_valid; /* the dir contents are unchanged */
 617
 618        _debug("dir modified");
 619
 620        /* search the directory for this vnode */
 621        ret = afs_do_lookup(&dir->vfs_inode, dentry, &fid, key);
 622        switch (ret) {
 623        case 0:
 624                /* the filename maps to something */
 625                if (!dentry->d_inode)
 626                        goto out_bad;
 627                if (is_bad_inode(dentry->d_inode)) {
 628                        printk("kAFS: afs_d_revalidate: %s/%s has bad inode\n",
 629                               parent->d_name.name, dentry->d_name.name);
 630                        goto out_bad;
 631                }
 632
 633                /* if the vnode ID has changed, then the dirent points to a
 634                 * different file */
 635                if (fid.vnode != vnode->fid.vnode) {
 636                        _debug("%s: dirent changed [%u != %u]",
 637                               dentry->d_name.name, fid.vnode,
 638                               vnode->fid.vnode);
 639                        goto not_found;
 640                }
 641
 642                /* if the vnode ID uniqifier has changed, then the file has
 643                 * been deleted and replaced, and the original vnode ID has
 644                 * been reused */
 645                if (fid.unique != vnode->fid.unique) {
 646                        _debug("%s: file deleted (uq %u -> %u I:%u)",
 647                               dentry->d_name.name, fid.unique,
 648                               vnode->fid.unique,
 649                               dentry->d_inode->i_generation);
 650                        spin_lock(&vnode->lock);
 651                        set_bit(AFS_VNODE_DELETED, &vnode->flags);
 652                        spin_unlock(&vnode->lock);
 653                        goto not_found;
 654                }
 655                goto out_valid;
 656
 657        case -ENOENT:
 658                /* the filename is unknown */
 659                _debug("%s: dirent not found", dentry->d_name.name);
 660                if (dentry->d_inode)
 661                        goto not_found;
 662                goto out_valid;
 663
 664        default:
 665                _debug("failed to iterate dir %s: %d",
 666                       parent->d_name.name, ret);
 667                goto out_bad;
 668        }
 669
 670out_valid:
 671        dentry->d_fsdata = dir_version;
 672out_skip:
 673        dput(parent);
 674        key_put(key);
 675        _leave(" = 1 [valid]");
 676        return 1;
 677
 678        /* the dirent, if it exists, now points to a different vnode */
 679not_found:
 680        spin_lock(&dentry->d_lock);
 681        dentry->d_flags |= DCACHE_NFSFS_RENAMED;
 682        spin_unlock(&dentry->d_lock);
 683
 684out_bad:
 685        /* don't unhash if we have submounts */
 686        if (check_submounts_and_drop(dentry) != 0)
 687                goto out_skip;
 688
 689        _debug("dropping dentry %s/%s",
 690               parent->d_name.name, dentry->d_name.name);
 691        dput(parent);
 692        key_put(key);
 693
 694        _leave(" = 0 [bad]");
 695        return 0;
 696}
 697
 698/*
 699 * allow the VFS to enquire as to whether a dentry should be unhashed (mustn't
 700 * sleep)
 701 * - called from dput() when d_count is going to 0.
 702 * - return 1 to request dentry be unhashed, 0 otherwise
 703 */
 704static int afs_d_delete(const struct dentry *dentry)
 705{
 706        _enter("%s", dentry->d_name.name);
 707
 708        if (dentry->d_flags & DCACHE_NFSFS_RENAMED)
 709                goto zap;
 710
 711        if (dentry->d_inode &&
 712            (test_bit(AFS_VNODE_DELETED,   &AFS_FS_I(dentry->d_inode)->flags) ||
 713             test_bit(AFS_VNODE_PSEUDODIR, &AFS_FS_I(dentry->d_inode)->flags)))
 714                goto zap;
 715
 716        _leave(" = 0 [keep]");
 717        return 0;
 718
 719zap:
 720        _leave(" = 1 [zap]");
 721        return 1;
 722}
 723
 724/*
 725 * handle dentry release
 726 */
 727static void afs_d_release(struct dentry *dentry)
 728{
 729        _enter("%s", dentry->d_name.name);
 730}
 731
 732/*
 733 * create a directory on an AFS filesystem
 734 */
 735static int afs_mkdir(struct inode *dir, struct dentry *dentry, umode_t mode)
 736{
 737        struct afs_file_status status;
 738        struct afs_callback cb;
 739        struct afs_server *server;
 740        struct afs_vnode *dvnode, *vnode;
 741        struct afs_fid fid;
 742        struct inode *inode;
 743        struct key *key;
 744        int ret;
 745
 746        dvnode = AFS_FS_I(dir);
 747
 748        _enter("{%x:%u},{%s},%ho",
 749               dvnode->fid.vid, dvnode->fid.vnode, dentry->d_name.name, mode);
 750
 751        key = afs_request_key(dvnode->volume->cell);
 752        if (IS_ERR(key)) {
 753                ret = PTR_ERR(key);
 754                goto error;
 755        }
 756
 757        mode |= S_IFDIR;
 758        ret = afs_vnode_create(dvnode, key, dentry->d_name.name,
 759                               mode, &fid, &status, &cb, &server);
 760        if (ret < 0)
 761                goto mkdir_error;
 762
 763        inode = afs_iget(dir->i_sb, key, &fid, &status, &cb);
 764        if (IS_ERR(inode)) {
 765                /* ENOMEM at a really inconvenient time - just abandon the new
 766                 * directory on the server */
 767                ret = PTR_ERR(inode);
 768                goto iget_error;
 769        }
 770
 771        /* apply the status report we've got for the new vnode */
 772        vnode = AFS_FS_I(inode);
 773        spin_lock(&vnode->lock);
 774        vnode->update_cnt++;
 775        spin_unlock(&vnode->lock);
 776        afs_vnode_finalise_status_update(vnode, server);
 777        afs_put_server(server);
 778
 779        d_instantiate(dentry, inode);
 780        if (d_unhashed(dentry)) {
 781                _debug("not hashed");
 782                d_rehash(dentry);
 783        }
 784        key_put(key);
 785        _leave(" = 0");
 786        return 0;
 787
 788iget_error:
 789        afs_put_server(server);
 790mkdir_error:
 791        key_put(key);
 792error:
 793        d_drop(dentry);
 794        _leave(" = %d", ret);
 795        return ret;
 796}
 797
 798/*
 799 * remove a directory from an AFS filesystem
 800 */
 801static int afs_rmdir(struct inode *dir, struct dentry *dentry)
 802{
 803        struct afs_vnode *dvnode, *vnode;
 804        struct key *key;
 805        int ret;
 806
 807        dvnode = AFS_FS_I(dir);
 808
 809        _enter("{%x:%u},{%s}",
 810               dvnode->fid.vid, dvnode->fid.vnode, dentry->d_name.name);
 811
 812        key = afs_request_key(dvnode->volume->cell);
 813        if (IS_ERR(key)) {
 814                ret = PTR_ERR(key);
 815                goto error;
 816        }
 817
 818        ret = afs_vnode_remove(dvnode, key, dentry->d_name.name, true);
 819        if (ret < 0)
 820                goto rmdir_error;
 821
 822        if (dentry->d_inode) {
 823                vnode = AFS_FS_I(dentry->d_inode);
 824                clear_nlink(&vnode->vfs_inode);
 825                set_bit(AFS_VNODE_DELETED, &vnode->flags);
 826                afs_discard_callback_on_delete(vnode);
 827        }
 828
 829        key_put(key);
 830        _leave(" = 0");
 831        return 0;
 832
 833rmdir_error:
 834        key_put(key);
 835error:
 836        _leave(" = %d", ret);
 837        return ret;
 838}
 839
 840/*
 841 * remove a file from an AFS filesystem
 842 */
 843static int afs_unlink(struct inode *dir, struct dentry *dentry)
 844{
 845        struct afs_vnode *dvnode, *vnode;
 846        struct key *key;
 847        int ret;
 848
 849        dvnode = AFS_FS_I(dir);
 850
 851        _enter("{%x:%u},{%s}",
 852               dvnode->fid.vid, dvnode->fid.vnode, dentry->d_name.name);
 853
 854        ret = -ENAMETOOLONG;
 855        if (dentry->d_name.len >= AFSNAMEMAX)
 856                goto error;
 857
 858        key = afs_request_key(dvnode->volume->cell);
 859        if (IS_ERR(key)) {
 860                ret = PTR_ERR(key);
 861                goto error;
 862        }
 863
 864        if (dentry->d_inode) {
 865                vnode = AFS_FS_I(dentry->d_inode);
 866
 867                /* make sure we have a callback promise on the victim */
 868                ret = afs_validate(vnode, key);
 869                if (ret < 0)
 870                        goto error;
 871        }
 872
 873        ret = afs_vnode_remove(dvnode, key, dentry->d_name.name, false);
 874        if (ret < 0)
 875                goto remove_error;
 876
 877        if (dentry->d_inode) {
 878                /* if the file wasn't deleted due to excess hard links, the
 879                 * fileserver will break the callback promise on the file - if
 880                 * it had one - before it returns to us, and if it was deleted,
 881                 * it won't
 882                 *
 883                 * however, if we didn't have a callback promise outstanding,
 884                 * or it was outstanding on a different server, then it won't
 885                 * break it either...
 886                 */
 887                vnode = AFS_FS_I(dentry->d_inode);
 888                if (test_bit(AFS_VNODE_DELETED, &vnode->flags))
 889                        _debug("AFS_VNODE_DELETED");
 890                if (test_bit(AFS_VNODE_CB_BROKEN, &vnode->flags))
 891                        _debug("AFS_VNODE_CB_BROKEN");
 892                set_bit(AFS_VNODE_CB_BROKEN, &vnode->flags);
 893                ret = afs_validate(vnode, key);
 894                _debug("nlink %d [val %d]", vnode->vfs_inode.i_nlink, ret);
 895        }
 896
 897        key_put(key);
 898        _leave(" = 0");
 899        return 0;
 900
 901remove_error:
 902        key_put(key);
 903error:
 904        _leave(" = %d", ret);
 905        return ret;
 906}
 907
 908/*
 909 * create a regular file on an AFS filesystem
 910 */
 911static int afs_create(struct inode *dir, struct dentry *dentry, umode_t mode,
 912                      bool excl)
 913{
 914        struct afs_file_status status;
 915        struct afs_callback cb;
 916        struct afs_server *server;
 917        struct afs_vnode *dvnode, *vnode;
 918        struct afs_fid fid;
 919        struct inode *inode;
 920        struct key *key;
 921        int ret;
 922
 923        dvnode = AFS_FS_I(dir);
 924
 925        _enter("{%x:%u},{%s},%ho,",
 926               dvnode->fid.vid, dvnode->fid.vnode, dentry->d_name.name, mode);
 927
 928        key = afs_request_key(dvnode->volume->cell);
 929        if (IS_ERR(key)) {
 930                ret = PTR_ERR(key);
 931                goto error;
 932        }
 933
 934        mode |= S_IFREG;
 935        ret = afs_vnode_create(dvnode, key, dentry->d_name.name,
 936                               mode, &fid, &status, &cb, &server);
 937        if (ret < 0)
 938                goto create_error;
 939
 940        inode = afs_iget(dir->i_sb, key, &fid, &status, &cb);
 941        if (IS_ERR(inode)) {
 942                /* ENOMEM at a really inconvenient time - just abandon the new
 943                 * directory on the server */
 944                ret = PTR_ERR(inode);
 945                goto iget_error;
 946        }
 947
 948        /* apply the status report we've got for the new vnode */
 949        vnode = AFS_FS_I(inode);
 950        spin_lock(&vnode->lock);
 951        vnode->update_cnt++;
 952        spin_unlock(&vnode->lock);
 953        afs_vnode_finalise_status_update(vnode, server);
 954        afs_put_server(server);
 955
 956        d_instantiate(dentry, inode);
 957        if (d_unhashed(dentry)) {
 958                _debug("not hashed");
 959                d_rehash(dentry);
 960        }
 961        key_put(key);
 962        _leave(" = 0");
 963        return 0;
 964
 965iget_error:
 966        afs_put_server(server);
 967create_error:
 968        key_put(key);
 969error:
 970        d_drop(dentry);
 971        _leave(" = %d", ret);
 972        return ret;
 973}
 974
 975/*
 976 * create a hard link between files in an AFS filesystem
 977 */
 978static int afs_link(struct dentry *from, struct inode *dir,
 979                    struct dentry *dentry)
 980{
 981        struct afs_vnode *dvnode, *vnode;
 982        struct key *key;
 983        int ret;
 984
 985        vnode = AFS_FS_I(from->d_inode);
 986        dvnode = AFS_FS_I(dir);
 987
 988        _enter("{%x:%u},{%x:%u},{%s}",
 989               vnode->fid.vid, vnode->fid.vnode,
 990               dvnode->fid.vid, dvnode->fid.vnode,
 991               dentry->d_name.name);
 992
 993        key = afs_request_key(dvnode->volume->cell);
 994        if (IS_ERR(key)) {
 995                ret = PTR_ERR(key);
 996                goto error;
 997        }
 998
 999        ret = afs_vnode_link(dvnode, vnode, key, dentry->d_name.name);
1000        if (ret < 0)
1001                goto link_error;
1002
1003        ihold(&vnode->vfs_inode);
1004        d_instantiate(dentry, &vnode->vfs_inode);
1005        key_put(key);
1006        _leave(" = 0");
1007        return 0;
1008
1009link_error:
1010        key_put(key);
1011error:
1012        d_drop(dentry);
1013        _leave(" = %d", ret);
1014        return ret;
1015}
1016
1017/*
1018 * create a symlink in an AFS filesystem
1019 */
1020static int afs_symlink(struct inode *dir, struct dentry *dentry,
1021                       const char *content)
1022{
1023        struct afs_file_status status;
1024        struct afs_server *server;
1025        struct afs_vnode *dvnode, *vnode;
1026        struct afs_fid fid;
1027        struct inode *inode;
1028        struct key *key;
1029        int ret;
1030
1031        dvnode = AFS_FS_I(dir);
1032
1033        _enter("{%x:%u},{%s},%s",
1034               dvnode->fid.vid, dvnode->fid.vnode, dentry->d_name.name,
1035               content);
1036
1037        ret = -EINVAL;
1038        if (strlen(content) >= AFSPATHMAX)
1039                goto error;
1040
1041        key = afs_request_key(dvnode->volume->cell);
1042        if (IS_ERR(key)) {
1043                ret = PTR_ERR(key);
1044                goto error;
1045        }
1046
1047        ret = afs_vnode_symlink(dvnode, key, dentry->d_name.name, content,
1048                                &fid, &status, &server);
1049        if (ret < 0)
1050                goto create_error;
1051
1052        inode = afs_iget(dir->i_sb, key, &fid, &status, NULL);
1053        if (IS_ERR(inode)) {
1054                /* ENOMEM at a really inconvenient time - just abandon the new
1055                 * directory on the server */
1056                ret = PTR_ERR(inode);
1057                goto iget_error;
1058        }
1059
1060        /* apply the status report we've got for the new vnode */
1061        vnode = AFS_FS_I(inode);
1062        spin_lock(&vnode->lock);
1063        vnode->update_cnt++;
1064        spin_unlock(&vnode->lock);
1065        afs_vnode_finalise_status_update(vnode, server);
1066        afs_put_server(server);
1067
1068        d_instantiate(dentry, inode);
1069        if (d_unhashed(dentry)) {
1070                _debug("not hashed");
1071                d_rehash(dentry);
1072        }
1073        key_put(key);
1074        _leave(" = 0");
1075        return 0;
1076
1077iget_error:
1078        afs_put_server(server);
1079create_error:
1080        key_put(key);
1081error:
1082        d_drop(dentry);
1083        _leave(" = %d", ret);
1084        return ret;
1085}
1086
1087/*
1088 * rename a file in an AFS filesystem and/or move it between directories
1089 */
1090static int afs_rename(struct inode *old_dir, struct dentry *old_dentry,
1091                      struct inode *new_dir, struct dentry *new_dentry)
1092{
1093        struct afs_vnode *orig_dvnode, *new_dvnode, *vnode;
1094        struct key *key;
1095        int ret;
1096
1097        vnode = AFS_FS_I(old_dentry->d_inode);
1098        orig_dvnode = AFS_FS_I(old_dir);
1099        new_dvnode = AFS_FS_I(new_dir);
1100
1101        _enter("{%x:%u},{%x:%u},{%x:%u},{%s}",
1102               orig_dvnode->fid.vid, orig_dvnode->fid.vnode,
1103               vnode->fid.vid, vnode->fid.vnode,
1104               new_dvnode->fid.vid, new_dvnode->fid.vnode,
1105               new_dentry->d_name.name);
1106
1107        key = afs_request_key(orig_dvnode->volume->cell);
1108        if (IS_ERR(key)) {
1109                ret = PTR_ERR(key);
1110                goto error;
1111        }
1112
1113        ret = afs_vnode_rename(orig_dvnode, new_dvnode, key,
1114                               old_dentry->d_name.name,
1115                               new_dentry->d_name.name);
1116        if (ret < 0)
1117                goto rename_error;
1118        key_put(key);
1119        _leave(" = 0");
1120        return 0;
1121
1122rename_error:
1123        key_put(key);
1124error:
1125        d_drop(new_dentry);
1126        _leave(" = %d", ret);
1127        return ret;
1128}
1129