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