linux/fs/nilfs2/namei.c
<<
>>
Prefs
   1/*
   2 * namei.c - NILFS pathname lookup operations.
   3 *
   4 * Copyright (C) 2005-2008 Nippon Telegraph and Telephone Corporation.
   5 *
   6 * This program is free software; you can redistribute it and/or modify
   7 * it under the terms of the GNU General Public License as published by
   8 * the Free Software Foundation; either version 2 of the License, or
   9 * (at your option) any later version.
  10 *
  11 * This program is distributed in the hope that it will be useful,
  12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
  13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  14 * GNU General Public License for more details.
  15 *
  16 * Modified for NILFS by Amagai Yoshiji and Ryusuke Konishi.
  17 */
  18/*
  19 *  linux/fs/ext2/namei.c
  20 *
  21 * Copyright (C) 1992, 1993, 1994, 1995
  22 * Remy Card (card@masi.ibp.fr)
  23 * Laboratoire MASI - Institut Blaise Pascal
  24 * Universite Pierre et Marie Curie (Paris VI)
  25 *
  26 *  from
  27 *
  28 *  linux/fs/minix/namei.c
  29 *
  30 *  Copyright (C) 1991, 1992  Linus Torvalds
  31 *
  32 *  Big-endian to little-endian byte-swapping/bitmaps by
  33 *        David S. Miller (davem@caip.rutgers.edu), 1995
  34 */
  35
  36#include <linux/pagemap.h>
  37#include "nilfs.h"
  38#include "export.h"
  39
  40#define NILFS_FID_SIZE_NON_CONNECTABLE \
  41        (offsetof(struct nilfs_fid, parent_gen) / 4)
  42#define NILFS_FID_SIZE_CONNECTABLE      (sizeof(struct nilfs_fid) / 4)
  43
  44static inline int nilfs_add_nondir(struct dentry *dentry, struct inode *inode)
  45{
  46        int err = nilfs_add_link(dentry, inode);
  47
  48        if (!err) {
  49                d_instantiate(dentry, inode);
  50                unlock_new_inode(inode);
  51                return 0;
  52        }
  53        inode_dec_link_count(inode);
  54        unlock_new_inode(inode);
  55        iput(inode);
  56        return err;
  57}
  58
  59/*
  60 * Methods themselves.
  61 */
  62
  63static struct dentry *
  64nilfs_lookup(struct inode *dir, struct dentry *dentry, unsigned int flags)
  65{
  66        struct inode *inode;
  67        ino_t ino;
  68
  69        if (dentry->d_name.len > NILFS_NAME_LEN)
  70                return ERR_PTR(-ENAMETOOLONG);
  71
  72        ino = nilfs_inode_by_name(dir, &dentry->d_name);
  73        inode = ino ? nilfs_iget(dir->i_sb, NILFS_I(dir)->i_root, ino) : NULL;
  74        return d_splice_alias(inode, dentry);
  75}
  76
  77/*
  78 * By the time this is called, we already have created
  79 * the directory cache entry for the new file, but it
  80 * is so far negative - it has no inode.
  81 *
  82 * If the create succeeds, we fill in the inode information
  83 * with d_instantiate().
  84 */
  85static int nilfs_create(struct inode *dir, struct dentry *dentry, umode_t mode,
  86                        bool excl)
  87{
  88        struct inode *inode;
  89        struct nilfs_transaction_info ti;
  90        int err;
  91
  92        err = nilfs_transaction_begin(dir->i_sb, &ti, 1);
  93        if (err)
  94                return err;
  95        inode = nilfs_new_inode(dir, mode);
  96        err = PTR_ERR(inode);
  97        if (!IS_ERR(inode)) {
  98                inode->i_op = &nilfs_file_inode_operations;
  99                inode->i_fop = &nilfs_file_operations;
 100                inode->i_mapping->a_ops = &nilfs_aops;
 101                nilfs_mark_inode_dirty(inode);
 102                err = nilfs_add_nondir(dentry, inode);
 103        }
 104        if (!err)
 105                err = nilfs_transaction_commit(dir->i_sb);
 106        else
 107                nilfs_transaction_abort(dir->i_sb);
 108
 109        return err;
 110}
 111
 112static int
 113nilfs_mknod(struct inode *dir, struct dentry *dentry, umode_t mode, dev_t rdev)
 114{
 115        struct inode *inode;
 116        struct nilfs_transaction_info ti;
 117        int err;
 118
 119        err = nilfs_transaction_begin(dir->i_sb, &ti, 1);
 120        if (err)
 121                return err;
 122        inode = nilfs_new_inode(dir, mode);
 123        err = PTR_ERR(inode);
 124        if (!IS_ERR(inode)) {
 125                init_special_inode(inode, inode->i_mode, rdev);
 126                nilfs_mark_inode_dirty(inode);
 127                err = nilfs_add_nondir(dentry, inode);
 128        }
 129        if (!err)
 130                err = nilfs_transaction_commit(dir->i_sb);
 131        else
 132                nilfs_transaction_abort(dir->i_sb);
 133
 134        return err;
 135}
 136
 137static int nilfs_symlink(struct inode *dir, struct dentry *dentry,
 138                         const char *symname)
 139{
 140        struct nilfs_transaction_info ti;
 141        struct super_block *sb = dir->i_sb;
 142        unsigned int l = strlen(symname) + 1;
 143        struct inode *inode;
 144        int err;
 145
 146        if (l > sb->s_blocksize)
 147                return -ENAMETOOLONG;
 148
 149        err = nilfs_transaction_begin(dir->i_sb, &ti, 1);
 150        if (err)
 151                return err;
 152
 153        inode = nilfs_new_inode(dir, S_IFLNK | S_IRWXUGO);
 154        err = PTR_ERR(inode);
 155        if (IS_ERR(inode))
 156                goto out;
 157
 158        /* slow symlink */
 159        inode->i_op = &nilfs_symlink_inode_operations;
 160        inode_nohighmem(inode);
 161        inode->i_mapping->a_ops = &nilfs_aops;
 162        err = page_symlink(inode, symname, l);
 163        if (err)
 164                goto out_fail;
 165
 166        /* mark_inode_dirty(inode); */
 167        /* page_symlink() do this */
 168
 169        err = nilfs_add_nondir(dentry, inode);
 170out:
 171        if (!err)
 172                err = nilfs_transaction_commit(dir->i_sb);
 173        else
 174                nilfs_transaction_abort(dir->i_sb);
 175
 176        return err;
 177
 178out_fail:
 179        drop_nlink(inode);
 180        nilfs_mark_inode_dirty(inode);
 181        unlock_new_inode(inode);
 182        iput(inode);
 183        goto out;
 184}
 185
 186static int nilfs_link(struct dentry *old_dentry, struct inode *dir,
 187                      struct dentry *dentry)
 188{
 189        struct inode *inode = d_inode(old_dentry);
 190        struct nilfs_transaction_info ti;
 191        int err;
 192
 193        err = nilfs_transaction_begin(dir->i_sb, &ti, 1);
 194        if (err)
 195                return err;
 196
 197        inode->i_ctime = CURRENT_TIME;
 198        inode_inc_link_count(inode);
 199        ihold(inode);
 200
 201        err = nilfs_add_link(dentry, inode);
 202        if (!err) {
 203                d_instantiate(dentry, inode);
 204                err = nilfs_transaction_commit(dir->i_sb);
 205        } else {
 206                inode_dec_link_count(inode);
 207                iput(inode);
 208                nilfs_transaction_abort(dir->i_sb);
 209        }
 210
 211        return err;
 212}
 213
 214static int nilfs_mkdir(struct inode *dir, struct dentry *dentry, umode_t mode)
 215{
 216        struct inode *inode;
 217        struct nilfs_transaction_info ti;
 218        int err;
 219
 220        err = nilfs_transaction_begin(dir->i_sb, &ti, 1);
 221        if (err)
 222                return err;
 223
 224        inc_nlink(dir);
 225
 226        inode = nilfs_new_inode(dir, S_IFDIR | mode);
 227        err = PTR_ERR(inode);
 228        if (IS_ERR(inode))
 229                goto out_dir;
 230
 231        inode->i_op = &nilfs_dir_inode_operations;
 232        inode->i_fop = &nilfs_dir_operations;
 233        inode->i_mapping->a_ops = &nilfs_aops;
 234
 235        inc_nlink(inode);
 236
 237        err = nilfs_make_empty(inode, dir);
 238        if (err)
 239                goto out_fail;
 240
 241        err = nilfs_add_link(dentry, inode);
 242        if (err)
 243                goto out_fail;
 244
 245        nilfs_mark_inode_dirty(inode);
 246        d_instantiate(dentry, inode);
 247        unlock_new_inode(inode);
 248out:
 249        if (!err)
 250                err = nilfs_transaction_commit(dir->i_sb);
 251        else
 252                nilfs_transaction_abort(dir->i_sb);
 253
 254        return err;
 255
 256out_fail:
 257        drop_nlink(inode);
 258        drop_nlink(inode);
 259        nilfs_mark_inode_dirty(inode);
 260        unlock_new_inode(inode);
 261        iput(inode);
 262out_dir:
 263        drop_nlink(dir);
 264        nilfs_mark_inode_dirty(dir);
 265        goto out;
 266}
 267
 268static int nilfs_do_unlink(struct inode *dir, struct dentry *dentry)
 269{
 270        struct inode *inode;
 271        struct nilfs_dir_entry *de;
 272        struct page *page;
 273        int err;
 274
 275        err = -ENOENT;
 276        de = nilfs_find_entry(dir, &dentry->d_name, &page);
 277        if (!de)
 278                goto out;
 279
 280        inode = d_inode(dentry);
 281        err = -EIO;
 282        if (le64_to_cpu(de->inode) != inode->i_ino)
 283                goto out;
 284
 285        if (!inode->i_nlink) {
 286                nilfs_msg(inode->i_sb, KERN_WARNING,
 287                          "deleting nonexistent file (ino=%lu), %d",
 288                          inode->i_ino, inode->i_nlink);
 289                set_nlink(inode, 1);
 290        }
 291        err = nilfs_delete_entry(de, page);
 292        if (err)
 293                goto out;
 294
 295        inode->i_ctime = dir->i_ctime;
 296        drop_nlink(inode);
 297        err = 0;
 298out:
 299        return err;
 300}
 301
 302static int nilfs_unlink(struct inode *dir, struct dentry *dentry)
 303{
 304        struct nilfs_transaction_info ti;
 305        int err;
 306
 307        err = nilfs_transaction_begin(dir->i_sb, &ti, 0);
 308        if (err)
 309                return err;
 310
 311        err = nilfs_do_unlink(dir, dentry);
 312
 313        if (!err) {
 314                nilfs_mark_inode_dirty(dir);
 315                nilfs_mark_inode_dirty(d_inode(dentry));
 316                err = nilfs_transaction_commit(dir->i_sb);
 317        } else
 318                nilfs_transaction_abort(dir->i_sb);
 319
 320        return err;
 321}
 322
 323static int nilfs_rmdir(struct inode *dir, struct dentry *dentry)
 324{
 325        struct inode *inode = d_inode(dentry);
 326        struct nilfs_transaction_info ti;
 327        int err;
 328
 329        err = nilfs_transaction_begin(dir->i_sb, &ti, 0);
 330        if (err)
 331                return err;
 332
 333        err = -ENOTEMPTY;
 334        if (nilfs_empty_dir(inode)) {
 335                err = nilfs_do_unlink(dir, dentry);
 336                if (!err) {
 337                        inode->i_size = 0;
 338                        drop_nlink(inode);
 339                        nilfs_mark_inode_dirty(inode);
 340                        drop_nlink(dir);
 341                        nilfs_mark_inode_dirty(dir);
 342                }
 343        }
 344        if (!err)
 345                err = nilfs_transaction_commit(dir->i_sb);
 346        else
 347                nilfs_transaction_abort(dir->i_sb);
 348
 349        return err;
 350}
 351
 352static int nilfs_rename(struct inode *old_dir, struct dentry *old_dentry,
 353                        struct inode *new_dir,  struct dentry *new_dentry)
 354{
 355        struct inode *old_inode = d_inode(old_dentry);
 356        struct inode *new_inode = d_inode(new_dentry);
 357        struct page *dir_page = NULL;
 358        struct nilfs_dir_entry *dir_de = NULL;
 359        struct page *old_page;
 360        struct nilfs_dir_entry *old_de;
 361        struct nilfs_transaction_info ti;
 362        int err;
 363
 364        err = nilfs_transaction_begin(old_dir->i_sb, &ti, 1);
 365        if (unlikely(err))
 366                return err;
 367
 368        err = -ENOENT;
 369        old_de = nilfs_find_entry(old_dir, &old_dentry->d_name, &old_page);
 370        if (!old_de)
 371                goto out;
 372
 373        if (S_ISDIR(old_inode->i_mode)) {
 374                err = -EIO;
 375                dir_de = nilfs_dotdot(old_inode, &dir_page);
 376                if (!dir_de)
 377                        goto out_old;
 378        }
 379
 380        if (new_inode) {
 381                struct page *new_page;
 382                struct nilfs_dir_entry *new_de;
 383
 384                err = -ENOTEMPTY;
 385                if (dir_de && !nilfs_empty_dir(new_inode))
 386                        goto out_dir;
 387
 388                err = -ENOENT;
 389                new_de = nilfs_find_entry(new_dir, &new_dentry->d_name, &new_page);
 390                if (!new_de)
 391                        goto out_dir;
 392                nilfs_set_link(new_dir, new_de, new_page, old_inode);
 393                nilfs_mark_inode_dirty(new_dir);
 394                new_inode->i_ctime = CURRENT_TIME;
 395                if (dir_de)
 396                        drop_nlink(new_inode);
 397                drop_nlink(new_inode);
 398                nilfs_mark_inode_dirty(new_inode);
 399        } else {
 400                err = nilfs_add_link(new_dentry, old_inode);
 401                if (err)
 402                        goto out_dir;
 403                if (dir_de) {
 404                        inc_nlink(new_dir);
 405                        nilfs_mark_inode_dirty(new_dir);
 406                }
 407        }
 408
 409        /*
 410         * Like most other Unix systems, set the ctime for inodes on a
 411         * rename.
 412         */
 413        old_inode->i_ctime = CURRENT_TIME;
 414
 415        nilfs_delete_entry(old_de, old_page);
 416
 417        if (dir_de) {
 418                nilfs_set_link(old_inode, dir_de, dir_page, new_dir);
 419                drop_nlink(old_dir);
 420        }
 421        nilfs_mark_inode_dirty(old_dir);
 422        nilfs_mark_inode_dirty(old_inode);
 423
 424        err = nilfs_transaction_commit(old_dir->i_sb);
 425        return err;
 426
 427out_dir:
 428        if (dir_de) {
 429                kunmap(dir_page);
 430                put_page(dir_page);
 431        }
 432out_old:
 433        kunmap(old_page);
 434        put_page(old_page);
 435out:
 436        nilfs_transaction_abort(old_dir->i_sb);
 437        return err;
 438}
 439
 440/*
 441 * Export operations
 442 */
 443static struct dentry *nilfs_get_parent(struct dentry *child)
 444{
 445        unsigned long ino;
 446        struct inode *inode;
 447        struct qstr dotdot = QSTR_INIT("..", 2);
 448        struct nilfs_root *root;
 449
 450        ino = nilfs_inode_by_name(d_inode(child), &dotdot);
 451        if (!ino)
 452                return ERR_PTR(-ENOENT);
 453
 454        root = NILFS_I(d_inode(child))->i_root;
 455
 456        inode = nilfs_iget(child->d_sb, root, ino);
 457        if (IS_ERR(inode))
 458                return ERR_CAST(inode);
 459
 460        return d_obtain_alias(inode);
 461}
 462
 463static struct dentry *nilfs_get_dentry(struct super_block *sb, u64 cno,
 464                                       u64 ino, u32 gen)
 465{
 466        struct nilfs_root *root;
 467        struct inode *inode;
 468
 469        if (ino < NILFS_FIRST_INO(sb) && ino != NILFS_ROOT_INO)
 470                return ERR_PTR(-ESTALE);
 471
 472        root = nilfs_lookup_root(sb->s_fs_info, cno);
 473        if (!root)
 474                return ERR_PTR(-ESTALE);
 475
 476        inode = nilfs_iget(sb, root, ino);
 477        nilfs_put_root(root);
 478
 479        if (IS_ERR(inode))
 480                return ERR_CAST(inode);
 481        if (gen && inode->i_generation != gen) {
 482                iput(inode);
 483                return ERR_PTR(-ESTALE);
 484        }
 485        return d_obtain_alias(inode);
 486}
 487
 488static struct dentry *nilfs_fh_to_dentry(struct super_block *sb, struct fid *fh,
 489                                         int fh_len, int fh_type)
 490{
 491        struct nilfs_fid *fid = (struct nilfs_fid *)fh;
 492
 493        if (fh_len < NILFS_FID_SIZE_NON_CONNECTABLE ||
 494            (fh_type != FILEID_NILFS_WITH_PARENT &&
 495             fh_type != FILEID_NILFS_WITHOUT_PARENT))
 496                return NULL;
 497
 498        return nilfs_get_dentry(sb, fid->cno, fid->ino, fid->gen);
 499}
 500
 501static struct dentry *nilfs_fh_to_parent(struct super_block *sb, struct fid *fh,
 502                                         int fh_len, int fh_type)
 503{
 504        struct nilfs_fid *fid = (struct nilfs_fid *)fh;
 505
 506        if (fh_len < NILFS_FID_SIZE_CONNECTABLE ||
 507            fh_type != FILEID_NILFS_WITH_PARENT)
 508                return NULL;
 509
 510        return nilfs_get_dentry(sb, fid->cno, fid->parent_ino, fid->parent_gen);
 511}
 512
 513static int nilfs_encode_fh(struct inode *inode, __u32 *fh, int *lenp,
 514                           struct inode *parent)
 515{
 516        struct nilfs_fid *fid = (struct nilfs_fid *)fh;
 517        struct nilfs_root *root = NILFS_I(inode)->i_root;
 518        int type;
 519
 520        if (parent && *lenp < NILFS_FID_SIZE_CONNECTABLE) {
 521                *lenp = NILFS_FID_SIZE_CONNECTABLE;
 522                return FILEID_INVALID;
 523        }
 524        if (*lenp < NILFS_FID_SIZE_NON_CONNECTABLE) {
 525                *lenp = NILFS_FID_SIZE_NON_CONNECTABLE;
 526                return FILEID_INVALID;
 527        }
 528
 529        fid->cno = root->cno;
 530        fid->ino = inode->i_ino;
 531        fid->gen = inode->i_generation;
 532
 533        if (parent) {
 534                fid->parent_ino = parent->i_ino;
 535                fid->parent_gen = parent->i_generation;
 536                type = FILEID_NILFS_WITH_PARENT;
 537                *lenp = NILFS_FID_SIZE_CONNECTABLE;
 538        } else {
 539                type = FILEID_NILFS_WITHOUT_PARENT;
 540                *lenp = NILFS_FID_SIZE_NON_CONNECTABLE;
 541        }
 542
 543        return type;
 544}
 545
 546const struct inode_operations nilfs_dir_inode_operations = {
 547        .create         = nilfs_create,
 548        .lookup         = nilfs_lookup,
 549        .link           = nilfs_link,
 550        .unlink         = nilfs_unlink,
 551        .symlink        = nilfs_symlink,
 552        .mkdir          = nilfs_mkdir,
 553        .rmdir          = nilfs_rmdir,
 554        .mknod          = nilfs_mknod,
 555        .rename         = nilfs_rename,
 556        .setattr        = nilfs_setattr,
 557        .permission     = nilfs_permission,
 558        .fiemap         = nilfs_fiemap,
 559};
 560
 561const struct inode_operations nilfs_special_inode_operations = {
 562        .setattr        = nilfs_setattr,
 563        .permission     = nilfs_permission,
 564};
 565
 566const struct inode_operations nilfs_symlink_inode_operations = {
 567        .readlink       = generic_readlink,
 568        .get_link       = page_get_link,
 569        .permission     = nilfs_permission,
 570};
 571
 572const struct export_operations nilfs_export_ops = {
 573        .encode_fh = nilfs_encode_fh,
 574        .fh_to_dentry = nilfs_fh_to_dentry,
 575        .fh_to_parent = nilfs_fh_to_parent,
 576        .get_parent = nilfs_get_parent,
 577};
 578