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