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