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(struct dir_context *ctx, 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        put_page(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(struct dir_context *ctx, const char *name,
 395                              int nlen, loff_t fpos, u64 ino, unsigned dtype)
 396{
 397        struct afs_lookup_cookie *cookie =
 398                container_of(ctx, struct afs_lookup_cookie, ctx);
 399
 400        _enter("{%s,%u},%s,%u,,%llu,%u",
 401               cookie->name.name, cookie->name.len, name, nlen,
 402               (unsigned long long) ino, dtype);
 403
 404        /* insanity checks first */
 405        BUILD_BUG_ON(sizeof(union afs_dir_block) != 2048);
 406        BUILD_BUG_ON(sizeof(union afs_dirent) != 32);
 407
 408        if (cookie->name.len != nlen ||
 409            memcmp(cookie->name.name, name, nlen) != 0) {
 410                _leave(" = 0 [no]");
 411                return 0;
 412        }
 413
 414        cookie->fid.vnode = ino;
 415        cookie->fid.unique = dtype;
 416        cookie->found = 1;
 417
 418        _leave(" = -1 [found]");
 419        return -1;
 420}
 421
 422/*
 423 * do a lookup in a directory
 424 * - just returns the FID the dentry name maps to if found
 425 */
 426static int afs_do_lookup(struct inode *dir, struct dentry *dentry,
 427                         struct afs_fid *fid, struct key *key)
 428{
 429        struct afs_super_info *as = dir->i_sb->s_fs_info;
 430        struct afs_lookup_cookie cookie = {
 431                .ctx.actor = afs_lookup_filldir,
 432                .name = dentry->d_name,
 433                .fid.vid = as->volume->vid
 434        };
 435        int ret;
 436
 437        _enter("{%lu},%p{%pd},", dir->i_ino, dentry, dentry);
 438
 439        /* search the directory */
 440        ret = afs_dir_iterate(dir, &cookie.ctx, key);
 441        if (ret < 0) {
 442                _leave(" = %d [iter]", ret);
 443                return ret;
 444        }
 445
 446        ret = -ENOENT;
 447        if (!cookie.found) {
 448                _leave(" = -ENOENT [not found]");
 449                return -ENOENT;
 450        }
 451
 452        *fid = cookie.fid;
 453        _leave(" = 0 { vn=%u u=%u }", fid->vnode, fid->unique);
 454        return 0;
 455}
 456
 457/*
 458 * Try to auto mount the mountpoint with pseudo directory, if the autocell
 459 * operation is setted.
 460 */
 461static struct inode *afs_try_auto_mntpt(
 462        int ret, struct dentry *dentry, struct inode *dir, struct key *key,
 463        struct afs_fid *fid)
 464{
 465        const char *devname = dentry->d_name.name;
 466        struct afs_vnode *vnode = AFS_FS_I(dir);
 467        struct inode *inode;
 468
 469        _enter("%d, %p{%pd}, {%x:%u}, %p",
 470               ret, dentry, dentry, vnode->fid.vid, vnode->fid.vnode, key);
 471
 472        if (ret != -ENOENT ||
 473            !test_bit(AFS_VNODE_AUTOCELL, &vnode->flags))
 474                goto out;
 475
 476        inode = afs_iget_autocell(dir, devname, strlen(devname), key);
 477        if (IS_ERR(inode)) {
 478                ret = PTR_ERR(inode);
 479                goto out;
 480        }
 481
 482        *fid = AFS_FS_I(inode)->fid;
 483        _leave("= %p", inode);
 484        return inode;
 485
 486out:
 487        _leave("= %d", ret);
 488        return ERR_PTR(ret);
 489}
 490
 491/*
 492 * look up an entry in a directory
 493 */
 494static struct dentry *afs_lookup(struct inode *dir, struct dentry *dentry,
 495                                 unsigned int flags)
 496{
 497        struct afs_vnode *vnode;
 498        struct afs_fid fid;
 499        struct inode *inode;
 500        struct key *key;
 501        int ret;
 502
 503        vnode = AFS_FS_I(dir);
 504
 505        _enter("{%x:%u},%p{%pd},",
 506               vnode->fid.vid, vnode->fid.vnode, dentry, dentry);
 507
 508        ASSERTCMP(d_inode(dentry), ==, NULL);
 509
 510        if (dentry->d_name.len >= AFSNAMEMAX) {
 511                _leave(" = -ENAMETOOLONG");
 512                return ERR_PTR(-ENAMETOOLONG);
 513        }
 514
 515        if (test_bit(AFS_VNODE_DELETED, &vnode->flags)) {
 516                _leave(" = -ESTALE");
 517                return ERR_PTR(-ESTALE);
 518        }
 519
 520        key = afs_request_key(vnode->volume->cell);
 521        if (IS_ERR(key)) {
 522                _leave(" = %ld [key]", PTR_ERR(key));
 523                return ERR_CAST(key);
 524        }
 525
 526        ret = afs_validate(vnode, key);
 527        if (ret < 0) {
 528                key_put(key);
 529                _leave(" = %d [val]", ret);
 530                return ERR_PTR(ret);
 531        }
 532
 533        ret = afs_do_lookup(dir, dentry, &fid, key);
 534        if (ret < 0) {
 535                inode = afs_try_auto_mntpt(ret, dentry, dir, key, &fid);
 536                if (!IS_ERR(inode)) {
 537                        key_put(key);
 538                        goto success;
 539                }
 540
 541                ret = PTR_ERR(inode);
 542                key_put(key);
 543                if (ret == -ENOENT) {
 544                        d_add(dentry, NULL);
 545                        _leave(" = NULL [negative]");
 546                        return NULL;
 547                }
 548                _leave(" = %d [do]", ret);
 549                return ERR_PTR(ret);
 550        }
 551        dentry->d_fsdata = (void *)(unsigned long) vnode->status.data_version;
 552
 553        /* instantiate the dentry */
 554        inode = afs_iget(dir->i_sb, key, &fid, NULL, NULL);
 555        key_put(key);
 556        if (IS_ERR(inode)) {
 557                _leave(" = %ld", PTR_ERR(inode));
 558                return ERR_CAST(inode);
 559        }
 560
 561success:
 562        d_add(dentry, inode);
 563        _leave(" = 0 { vn=%u u=%u } -> { ino=%lu v=%u }",
 564               fid.vnode,
 565               fid.unique,
 566               d_inode(dentry)->i_ino,
 567               d_inode(dentry)->i_generation);
 568
 569        return NULL;
 570}
 571
 572/*
 573 * check that a dentry lookup hit has found a valid entry
 574 * - NOTE! the hit can be a negative hit too, so we can't assume we have an
 575 *   inode
 576 */
 577static int afs_d_revalidate(struct dentry *dentry, unsigned int flags)
 578{
 579        struct afs_vnode *vnode, *dir;
 580        struct afs_fid uninitialized_var(fid);
 581        struct dentry *parent;
 582        struct key *key;
 583        void *dir_version;
 584        int ret;
 585
 586        if (flags & LOOKUP_RCU)
 587                return -ECHILD;
 588
 589        vnode = AFS_FS_I(d_inode(dentry));
 590
 591        if (d_really_is_positive(dentry))
 592                _enter("{v={%x:%u} n=%pd fl=%lx},",
 593                       vnode->fid.vid, vnode->fid.vnode, dentry,
 594                       vnode->flags);
 595        else
 596                _enter("{neg n=%pd}", dentry);
 597
 598        key = afs_request_key(AFS_FS_S(dentry->d_sb)->volume->cell);
 599        if (IS_ERR(key))
 600                key = NULL;
 601
 602        /* lock down the parent dentry so we can peer at it */
 603        parent = dget_parent(dentry);
 604        dir = AFS_FS_I(d_inode(parent));
 605
 606        /* validate the parent directory */
 607        if (test_bit(AFS_VNODE_MODIFIED, &dir->flags))
 608                afs_validate(dir, key);
 609
 610        if (test_bit(AFS_VNODE_DELETED, &dir->flags)) {
 611                _debug("%pd: parent dir deleted", dentry);
 612                goto out_bad;
 613        }
 614
 615        dir_version = (void *) (unsigned long) dir->status.data_version;
 616        if (dentry->d_fsdata == dir_version)
 617                goto out_valid; /* the dir contents are unchanged */
 618
 619        _debug("dir modified");
 620
 621        /* search the directory for this vnode */
 622        ret = afs_do_lookup(&dir->vfs_inode, dentry, &fid, key);
 623        switch (ret) {
 624        case 0:
 625                /* the filename maps to something */
 626                if (d_really_is_negative(dentry))
 627                        goto out_bad;
 628                if (is_bad_inode(d_inode(dentry))) {
 629                        printk("kAFS: afs_d_revalidate: %pd2 has bad inode\n",
 630                               dentry);
 631                        goto out_bad;
 632                }
 633
 634                /* if the vnode ID has changed, then the dirent points to a
 635                 * different file */
 636                if (fid.vnode != vnode->fid.vnode) {
 637                        _debug("%pd: dirent changed [%u != %u]",
 638                               dentry, fid.vnode,
 639                               vnode->fid.vnode);
 640                        goto not_found;
 641                }
 642
 643                /* if the vnode ID uniqifier has changed, then the file has
 644                 * been deleted and replaced, and the original vnode ID has
 645                 * been reused */
 646                if (fid.unique != vnode->fid.unique) {
 647                        _debug("%pd: file deleted (uq %u -> %u I:%u)",
 648                               dentry, fid.unique,
 649                               vnode->fid.unique,
 650                               d_inode(dentry)->i_generation);
 651                        spin_lock(&vnode->lock);
 652                        set_bit(AFS_VNODE_DELETED, &vnode->flags);
 653                        spin_unlock(&vnode->lock);
 654                        goto not_found;
 655                }
 656                goto out_valid;
 657
 658        case -ENOENT:
 659                /* the filename is unknown */
 660                _debug("%pd: dirent not found", dentry);
 661                if (d_really_is_positive(dentry))
 662                        goto not_found;
 663                goto out_valid;
 664
 665        default:
 666                _debug("failed to iterate dir %pd: %d",
 667                       parent, ret);
 668                goto out_bad;
 669        }
 670
 671out_valid:
 672        dentry->d_fsdata = dir_version;
 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        _debug("dropping dentry %pd2", dentry);
 686        dput(parent);
 687        key_put(key);
 688
 689        _leave(" = 0 [bad]");
 690        return 0;
 691}
 692
 693/*
 694 * allow the VFS to enquire as to whether a dentry should be unhashed (mustn't
 695 * sleep)
 696 * - called from dput() when d_count is going to 0.
 697 * - return 1 to request dentry be unhashed, 0 otherwise
 698 */
 699static int afs_d_delete(const struct dentry *dentry)
 700{
 701        _enter("%pd", dentry);
 702
 703        if (dentry->d_flags & DCACHE_NFSFS_RENAMED)
 704                goto zap;
 705
 706        if (d_really_is_positive(dentry) &&
 707            (test_bit(AFS_VNODE_DELETED,   &AFS_FS_I(d_inode(dentry))->flags) ||
 708             test_bit(AFS_VNODE_PSEUDODIR, &AFS_FS_I(d_inode(dentry))->flags)))
 709                goto zap;
 710
 711        _leave(" = 0 [keep]");
 712        return 0;
 713
 714zap:
 715        _leave(" = 1 [zap]");
 716        return 1;
 717}
 718
 719/*
 720 * handle dentry release
 721 */
 722static void afs_d_release(struct dentry *dentry)
 723{
 724        _enter("%pd", dentry);
 725}
 726
 727/*
 728 * create a directory on an AFS filesystem
 729 */
 730static int afs_mkdir(struct inode *dir, struct dentry *dentry, umode_t mode)
 731{
 732        struct afs_file_status status;
 733        struct afs_callback cb;
 734        struct afs_server *server;
 735        struct afs_vnode *dvnode, *vnode;
 736        struct afs_fid fid;
 737        struct inode *inode;
 738        struct key *key;
 739        int ret;
 740
 741        dvnode = AFS_FS_I(dir);
 742
 743        _enter("{%x:%u},{%pd},%ho",
 744               dvnode->fid.vid, dvnode->fid.vnode, dentry, mode);
 745
 746        key = afs_request_key(dvnode->volume->cell);
 747        if (IS_ERR(key)) {
 748                ret = PTR_ERR(key);
 749                goto error;
 750        }
 751
 752        mode |= S_IFDIR;
 753        ret = afs_vnode_create(dvnode, key, dentry->d_name.name,
 754                               mode, &fid, &status, &cb, &server);
 755        if (ret < 0)
 756                goto mkdir_error;
 757
 758        inode = afs_iget(dir->i_sb, key, &fid, &status, &cb);
 759        if (IS_ERR(inode)) {
 760                /* ENOMEM at a really inconvenient time - just abandon the new
 761                 * directory on the server */
 762                ret = PTR_ERR(inode);
 763                goto iget_error;
 764        }
 765
 766        /* apply the status report we've got for the new vnode */
 767        vnode = AFS_FS_I(inode);
 768        spin_lock(&vnode->lock);
 769        vnode->update_cnt++;
 770        spin_unlock(&vnode->lock);
 771        afs_vnode_finalise_status_update(vnode, server);
 772        afs_put_server(server);
 773
 774        d_instantiate(dentry, inode);
 775        if (d_unhashed(dentry)) {
 776                _debug("not hashed");
 777                d_rehash(dentry);
 778        }
 779        key_put(key);
 780        _leave(" = 0");
 781        return 0;
 782
 783iget_error:
 784        afs_put_server(server);
 785mkdir_error:
 786        key_put(key);
 787error:
 788        d_drop(dentry);
 789        _leave(" = %d", ret);
 790        return ret;
 791}
 792
 793/*
 794 * remove a directory from an AFS filesystem
 795 */
 796static int afs_rmdir(struct inode *dir, struct dentry *dentry)
 797{
 798        struct afs_vnode *dvnode, *vnode;
 799        struct key *key;
 800        int ret;
 801
 802        dvnode = AFS_FS_I(dir);
 803
 804        _enter("{%x:%u},{%pd}",
 805               dvnode->fid.vid, dvnode->fid.vnode, dentry);
 806
 807        key = afs_request_key(dvnode->volume->cell);
 808        if (IS_ERR(key)) {
 809                ret = PTR_ERR(key);
 810                goto error;
 811        }
 812
 813        ret = afs_vnode_remove(dvnode, key, dentry->d_name.name, true);
 814        if (ret < 0)
 815                goto rmdir_error;
 816
 817        if (d_really_is_positive(dentry)) {
 818                vnode = AFS_FS_I(d_inode(dentry));
 819                clear_nlink(&vnode->vfs_inode);
 820                set_bit(AFS_VNODE_DELETED, &vnode->flags);
 821                afs_discard_callback_on_delete(vnode);
 822        }
 823
 824        key_put(key);
 825        _leave(" = 0");
 826        return 0;
 827
 828rmdir_error:
 829        key_put(key);
 830error:
 831        _leave(" = %d", ret);
 832        return ret;
 833}
 834
 835/*
 836 * remove a file from an AFS filesystem
 837 */
 838static int afs_unlink(struct inode *dir, struct dentry *dentry)
 839{
 840        struct afs_vnode *dvnode, *vnode;
 841        struct key *key;
 842        int ret;
 843
 844        dvnode = AFS_FS_I(dir);
 845
 846        _enter("{%x:%u},{%pd}",
 847               dvnode->fid.vid, dvnode->fid.vnode, dentry);
 848
 849        ret = -ENAMETOOLONG;
 850        if (dentry->d_name.len >= AFSNAMEMAX)
 851                goto error;
 852
 853        key = afs_request_key(dvnode->volume->cell);
 854        if (IS_ERR(key)) {
 855                ret = PTR_ERR(key);
 856                goto error;
 857        }
 858
 859        if (d_really_is_positive(dentry)) {
 860                vnode = AFS_FS_I(d_inode(dentry));
 861
 862                /* make sure we have a callback promise on the victim */
 863                ret = afs_validate(vnode, key);
 864                if (ret < 0)
 865                        goto error;
 866        }
 867
 868        ret = afs_vnode_remove(dvnode, key, dentry->d_name.name, false);
 869        if (ret < 0)
 870                goto remove_error;
 871
 872        if (d_really_is_positive(dentry)) {
 873                /* if the file wasn't deleted due to excess hard links, the
 874                 * fileserver will break the callback promise on the file - if
 875                 * it had one - before it returns to us, and if it was deleted,
 876                 * it won't
 877                 *
 878                 * however, if we didn't have a callback promise outstanding,
 879                 * or it was outstanding on a different server, then it won't
 880                 * break it either...
 881                 */
 882                vnode = AFS_FS_I(d_inode(dentry));
 883                if (test_bit(AFS_VNODE_DELETED, &vnode->flags))
 884                        _debug("AFS_VNODE_DELETED");
 885                if (test_bit(AFS_VNODE_CB_BROKEN, &vnode->flags))
 886                        _debug("AFS_VNODE_CB_BROKEN");
 887                set_bit(AFS_VNODE_CB_BROKEN, &vnode->flags);
 888                ret = afs_validate(vnode, key);
 889                _debug("nlink %d [val %d]", vnode->vfs_inode.i_nlink, ret);
 890        }
 891
 892        key_put(key);
 893        _leave(" = 0");
 894        return 0;
 895
 896remove_error:
 897        key_put(key);
 898error:
 899        _leave(" = %d", ret);
 900        return ret;
 901}
 902
 903/*
 904 * create a regular file on an AFS filesystem
 905 */
 906static int afs_create(struct inode *dir, struct dentry *dentry, umode_t mode,
 907                      bool excl)
 908{
 909        struct afs_file_status status;
 910        struct afs_callback cb;
 911        struct afs_server *server;
 912        struct afs_vnode *dvnode, *vnode;
 913        struct afs_fid fid;
 914        struct inode *inode;
 915        struct key *key;
 916        int ret;
 917
 918        dvnode = AFS_FS_I(dir);
 919
 920        _enter("{%x:%u},{%pd},%ho,",
 921               dvnode->fid.vid, dvnode->fid.vnode, dentry, mode);
 922
 923        key = afs_request_key(dvnode->volume->cell);
 924        if (IS_ERR(key)) {
 925                ret = PTR_ERR(key);
 926                goto error;
 927        }
 928
 929        mode |= S_IFREG;
 930        ret = afs_vnode_create(dvnode, key, dentry->d_name.name,
 931                               mode, &fid, &status, &cb, &server);
 932        if (ret < 0)
 933                goto create_error;
 934
 935        inode = afs_iget(dir->i_sb, key, &fid, &status, &cb);
 936        if (IS_ERR(inode)) {
 937                /* ENOMEM at a really inconvenient time - just abandon the new
 938                 * directory on the server */
 939                ret = PTR_ERR(inode);
 940                goto iget_error;
 941        }
 942
 943        /* apply the status report we've got for the new vnode */
 944        vnode = AFS_FS_I(inode);
 945        spin_lock(&vnode->lock);
 946        vnode->update_cnt++;
 947        spin_unlock(&vnode->lock);
 948        afs_vnode_finalise_status_update(vnode, server);
 949        afs_put_server(server);
 950
 951        d_instantiate(dentry, inode);
 952        if (d_unhashed(dentry)) {
 953                _debug("not hashed");
 954                d_rehash(dentry);
 955        }
 956        key_put(key);
 957        _leave(" = 0");
 958        return 0;
 959
 960iget_error:
 961        afs_put_server(server);
 962create_error:
 963        key_put(key);
 964error:
 965        d_drop(dentry);
 966        _leave(" = %d", ret);
 967        return ret;
 968}
 969
 970/*
 971 * create a hard link between files in an AFS filesystem
 972 */
 973static int afs_link(struct dentry *from, struct inode *dir,
 974                    struct dentry *dentry)
 975{
 976        struct afs_vnode *dvnode, *vnode;
 977        struct key *key;
 978        int ret;
 979
 980        vnode = AFS_FS_I(d_inode(from));
 981        dvnode = AFS_FS_I(dir);
 982
 983        _enter("{%x:%u},{%x:%u},{%pd}",
 984               vnode->fid.vid, vnode->fid.vnode,
 985               dvnode->fid.vid, dvnode->fid.vnode,
 986               dentry);
 987
 988        key = afs_request_key(dvnode->volume->cell);
 989        if (IS_ERR(key)) {
 990                ret = PTR_ERR(key);
 991                goto error;
 992        }
 993
 994        ret = afs_vnode_link(dvnode, vnode, key, dentry->d_name.name);
 995        if (ret < 0)
 996                goto link_error;
 997
 998        ihold(&vnode->vfs_inode);
 999        d_instantiate(dentry, &vnode->vfs_inode);
1000        key_put(key);
1001        _leave(" = 0");
1002        return 0;
1003
1004link_error:
1005        key_put(key);
1006error:
1007        d_drop(dentry);
1008        _leave(" = %d", ret);
1009        return ret;
1010}
1011
1012/*
1013 * create a symlink in an AFS filesystem
1014 */
1015static int afs_symlink(struct inode *dir, struct dentry *dentry,
1016                       const char *content)
1017{
1018        struct afs_file_status status;
1019        struct afs_server *server;
1020        struct afs_vnode *dvnode, *vnode;
1021        struct afs_fid fid;
1022        struct inode *inode;
1023        struct key *key;
1024        int ret;
1025
1026        dvnode = AFS_FS_I(dir);
1027
1028        _enter("{%x:%u},{%pd},%s",
1029               dvnode->fid.vid, dvnode->fid.vnode, dentry,
1030               content);
1031
1032        ret = -EINVAL;
1033        if (strlen(content) >= AFSPATHMAX)
1034                goto error;
1035
1036        key = afs_request_key(dvnode->volume->cell);
1037        if (IS_ERR(key)) {
1038                ret = PTR_ERR(key);
1039                goto error;
1040        }
1041
1042        ret = afs_vnode_symlink(dvnode, key, dentry->d_name.name, content,
1043                                &fid, &status, &server);
1044        if (ret < 0)
1045                goto create_error;
1046
1047        inode = afs_iget(dir->i_sb, key, &fid, &status, NULL);
1048        if (IS_ERR(inode)) {
1049                /* ENOMEM at a really inconvenient time - just abandon the new
1050                 * directory on the server */
1051                ret = PTR_ERR(inode);
1052                goto iget_error;
1053        }
1054
1055        /* apply the status report we've got for the new vnode */
1056        vnode = AFS_FS_I(inode);
1057        spin_lock(&vnode->lock);
1058        vnode->update_cnt++;
1059        spin_unlock(&vnode->lock);
1060        afs_vnode_finalise_status_update(vnode, server);
1061        afs_put_server(server);
1062
1063        d_instantiate(dentry, inode);
1064        if (d_unhashed(dentry)) {
1065                _debug("not hashed");
1066                d_rehash(dentry);
1067        }
1068        key_put(key);
1069        _leave(" = 0");
1070        return 0;
1071
1072iget_error:
1073        afs_put_server(server);
1074create_error:
1075        key_put(key);
1076error:
1077        d_drop(dentry);
1078        _leave(" = %d", ret);
1079        return ret;
1080}
1081
1082/*
1083 * rename a file in an AFS filesystem and/or move it between directories
1084 */
1085static int afs_rename(struct inode *old_dir, struct dentry *old_dentry,
1086                      struct inode *new_dir, struct dentry *new_dentry)
1087{
1088        struct afs_vnode *orig_dvnode, *new_dvnode, *vnode;
1089        struct key *key;
1090        int ret;
1091
1092        vnode = AFS_FS_I(d_inode(old_dentry));
1093        orig_dvnode = AFS_FS_I(old_dir);
1094        new_dvnode = AFS_FS_I(new_dir);
1095
1096        _enter("{%x:%u},{%x:%u},{%x:%u},{%pd}",
1097               orig_dvnode->fid.vid, orig_dvnode->fid.vnode,
1098               vnode->fid.vid, vnode->fid.vnode,
1099               new_dvnode->fid.vid, new_dvnode->fid.vnode,
1100               new_dentry);
1101
1102        key = afs_request_key(orig_dvnode->volume->cell);
1103        if (IS_ERR(key)) {
1104                ret = PTR_ERR(key);
1105                goto error;
1106        }
1107
1108        ret = afs_vnode_rename(orig_dvnode, new_dvnode, key,
1109                               old_dentry->d_name.name,
1110                               new_dentry->d_name.name);
1111        if (ret < 0)
1112                goto rename_error;
1113        key_put(key);
1114        _leave(" = 0");
1115        return 0;
1116
1117rename_error:
1118        key_put(key);
1119error:
1120        d_drop(new_dentry);
1121        _leave(" = %d", ret);
1122        return ret;
1123}
1124