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