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
  44
  45static inline int nilfs_add_nondir(struct dentry *dentry, struct inode *inode)
  46{
  47        int err = nilfs_add_link(dentry, inode);
  48        if (!err) {
  49                d_instantiate(dentry, inode);
  50                return 0;
  51        }
  52        inode_dec_link_count(inode);
  53        iput(inode);
  54        return err;
  55}
  56
  57/*
  58 * Methods themselves.
  59 */
  60
  61static struct dentry *
  62nilfs_lookup(struct inode *dir, struct dentry *dentry, struct nameidata *nd)
  63{
  64        struct inode *inode;
  65        ino_t ino;
  66
  67        if (dentry->d_name.len > NILFS_NAME_LEN)
  68                return ERR_PTR(-ENAMETOOLONG);
  69
  70        ino = nilfs_inode_by_name(dir, dentry);
  71        inode = NULL;
  72        if (ino) {
  73                inode = nilfs_iget(dir->i_sb, ino);
  74                if (IS_ERR(inode))
  75                        return ERR_CAST(inode);
  76        }
  77        return d_splice_alias(inode, dentry);
  78}
  79
  80struct dentry *nilfs_get_parent(struct dentry *child)
  81{
  82        unsigned long ino;
  83        struct inode *inode;
  84        struct dentry dotdot;
  85
  86        dotdot.d_name.name = "..";
  87        dotdot.d_name.len = 2;
  88
  89        ino = nilfs_inode_by_name(child->d_inode, &dotdot);
  90        if (!ino)
  91                return ERR_PTR(-ENOENT);
  92
  93        inode = nilfs_iget(child->d_inode->i_sb, ino);
  94        if (IS_ERR(inode))
  95                return ERR_CAST(inode);
  96        return d_obtain_alias(inode);
  97}
  98
  99/*
 100 * By the time this is called, we already have created
 101 * the directory cache entry for the new file, but it
 102 * is so far negative - it has no inode.
 103 *
 104 * If the create succeeds, we fill in the inode information
 105 * with d_instantiate().
 106 */
 107static int nilfs_create(struct inode *dir, struct dentry *dentry, int mode,
 108                        struct nameidata *nd)
 109{
 110        struct inode *inode;
 111        struct nilfs_transaction_info ti;
 112        int err;
 113
 114        err = nilfs_transaction_begin(dir->i_sb, &ti, 1);
 115        if (err)
 116                return err;
 117        inode = nilfs_new_inode(dir, mode);
 118        err = PTR_ERR(inode);
 119        if (!IS_ERR(inode)) {
 120                inode->i_op = &nilfs_file_inode_operations;
 121                inode->i_fop = &nilfs_file_operations;
 122                inode->i_mapping->a_ops = &nilfs_aops;
 123                mark_inode_dirty(inode);
 124                err = nilfs_add_nondir(dentry, inode);
 125        }
 126        if (!err)
 127                err = nilfs_transaction_commit(dir->i_sb);
 128        else
 129                nilfs_transaction_abort(dir->i_sb);
 130
 131        return err;
 132}
 133
 134static int
 135nilfs_mknod(struct inode *dir, struct dentry *dentry, int mode, dev_t rdev)
 136{
 137        struct inode *inode;
 138        struct nilfs_transaction_info ti;
 139        int err;
 140
 141        if (!new_valid_dev(rdev))
 142                return -EINVAL;
 143
 144        err = nilfs_transaction_begin(dir->i_sb, &ti, 1);
 145        if (err)
 146                return err;
 147        inode = nilfs_new_inode(dir, mode);
 148        err = PTR_ERR(inode);
 149        if (!IS_ERR(inode)) {
 150                init_special_inode(inode, inode->i_mode, rdev);
 151                mark_inode_dirty(inode);
 152                err = nilfs_add_nondir(dentry, inode);
 153        }
 154        if (!err)
 155                err = nilfs_transaction_commit(dir->i_sb);
 156        else
 157                nilfs_transaction_abort(dir->i_sb);
 158
 159        return err;
 160}
 161
 162static int nilfs_symlink(struct inode *dir, struct dentry *dentry,
 163                         const char *symname)
 164{
 165        struct nilfs_transaction_info ti;
 166        struct super_block *sb = dir->i_sb;
 167        unsigned l = strlen(symname)+1;
 168        struct inode *inode;
 169        int err;
 170
 171        if (l > sb->s_blocksize)
 172                return -ENAMETOOLONG;
 173
 174        err = nilfs_transaction_begin(dir->i_sb, &ti, 1);
 175        if (err)
 176                return err;
 177
 178        inode = nilfs_new_inode(dir, S_IFLNK | S_IRWXUGO);
 179        err = PTR_ERR(inode);
 180        if (IS_ERR(inode))
 181                goto out;
 182
 183        /* slow symlink */
 184        inode->i_op = &nilfs_symlink_inode_operations;
 185        inode->i_mapping->a_ops = &nilfs_aops;
 186        err = page_symlink(inode, symname, l);
 187        if (err)
 188                goto out_fail;
 189
 190        /* mark_inode_dirty(inode); */
 191        /* nilfs_new_inode() and page_symlink() do this */
 192
 193        err = nilfs_add_nondir(dentry, inode);
 194out:
 195        if (!err)
 196                err = nilfs_transaction_commit(dir->i_sb);
 197        else
 198                nilfs_transaction_abort(dir->i_sb);
 199
 200        return err;
 201
 202out_fail:
 203        inode_dec_link_count(inode);
 204        iput(inode);
 205        goto out;
 206}
 207
 208static int nilfs_link(struct dentry *old_dentry, struct inode *dir,
 209                      struct dentry *dentry)
 210{
 211        struct inode *inode = old_dentry->d_inode;
 212        struct nilfs_transaction_info ti;
 213        int err;
 214
 215        if (inode->i_nlink >= NILFS_LINK_MAX)
 216                return -EMLINK;
 217
 218        err = nilfs_transaction_begin(dir->i_sb, &ti, 1);
 219        if (err)
 220                return err;
 221
 222        inode->i_ctime = CURRENT_TIME;
 223        inode_inc_link_count(inode);
 224        atomic_inc(&inode->i_count);
 225
 226        err = nilfs_add_nondir(dentry, inode);
 227        if (!err)
 228                err = nilfs_transaction_commit(dir->i_sb);
 229        else
 230                nilfs_transaction_abort(dir->i_sb);
 231
 232        return err;
 233}
 234
 235static int nilfs_mkdir(struct inode *dir, struct dentry *dentry, int mode)
 236{
 237        struct inode *inode;
 238        struct nilfs_transaction_info ti;
 239        int err;
 240
 241        if (dir->i_nlink >= NILFS_LINK_MAX)
 242                return -EMLINK;
 243
 244        err = nilfs_transaction_begin(dir->i_sb, &ti, 1);
 245        if (err)
 246                return err;
 247
 248        inode_inc_link_count(dir);
 249
 250        inode = nilfs_new_inode(dir, S_IFDIR | mode);
 251        err = PTR_ERR(inode);
 252        if (IS_ERR(inode))
 253                goto out_dir;
 254
 255        inode->i_op = &nilfs_dir_inode_operations;
 256        inode->i_fop = &nilfs_dir_operations;
 257        inode->i_mapping->a_ops = &nilfs_aops;
 258
 259        inode_inc_link_count(inode);
 260
 261        err = nilfs_make_empty(inode, dir);
 262        if (err)
 263                goto out_fail;
 264
 265        err = nilfs_add_link(dentry, inode);
 266        if (err)
 267                goto out_fail;
 268
 269        d_instantiate(dentry, inode);
 270out:
 271        if (!err)
 272                err = nilfs_transaction_commit(dir->i_sb);
 273        else
 274                nilfs_transaction_abort(dir->i_sb);
 275
 276        return err;
 277
 278out_fail:
 279        inode_dec_link_count(inode);
 280        inode_dec_link_count(inode);
 281        iput(inode);
 282out_dir:
 283        inode_dec_link_count(dir);
 284        goto out;
 285}
 286
 287static int nilfs_unlink(struct inode *dir, struct dentry *dentry)
 288{
 289        struct inode *inode;
 290        struct nilfs_dir_entry *de;
 291        struct page *page;
 292        struct nilfs_transaction_info ti;
 293        int err;
 294
 295        err = nilfs_transaction_begin(dir->i_sb, &ti, 0);
 296        if (err)
 297                return err;
 298
 299        err = -ENOENT;
 300        de = nilfs_find_entry(dir, dentry, &page);
 301        if (!de)
 302                goto out;
 303
 304        inode = dentry->d_inode;
 305        err = -EIO;
 306        if (le64_to_cpu(de->inode) != inode->i_ino)
 307                goto out;
 308
 309        if (!inode->i_nlink) {
 310                nilfs_warning(inode->i_sb, __func__,
 311                              "deleting nonexistent file (%lu), %d\n",
 312                              inode->i_ino, inode->i_nlink);
 313                inode->i_nlink = 1;
 314        }
 315        err = nilfs_delete_entry(de, page);
 316        if (err)
 317                goto out;
 318
 319        inode->i_ctime = dir->i_ctime;
 320        inode_dec_link_count(inode);
 321        err = 0;
 322out:
 323        if (!err)
 324                err = nilfs_transaction_commit(dir->i_sb);
 325        else
 326                nilfs_transaction_abort(dir->i_sb);
 327
 328        return err;
 329}
 330
 331static int nilfs_rmdir(struct inode *dir, struct dentry *dentry)
 332{
 333        struct inode *inode = dentry->d_inode;
 334        struct nilfs_transaction_info ti;
 335        int err;
 336
 337        err = nilfs_transaction_begin(dir->i_sb, &ti, 0);
 338        if (err)
 339                return err;
 340
 341        err = -ENOTEMPTY;
 342        if (nilfs_empty_dir(inode)) {
 343                err = nilfs_unlink(dir, dentry);
 344                if (!err) {
 345                        inode->i_size = 0;
 346                        inode_dec_link_count(inode);
 347                        inode_dec_link_count(dir);
 348                }
 349        }
 350        if (!err)
 351                err = nilfs_transaction_commit(dir->i_sb);
 352        else
 353                nilfs_transaction_abort(dir->i_sb);
 354
 355        return err;
 356}
 357
 358static int nilfs_rename(struct inode *old_dir, struct dentry *old_dentry,
 359                        struct inode *new_dir,  struct dentry *new_dentry)
 360{
 361        struct inode *old_inode = old_dentry->d_inode;
 362        struct inode *new_inode = new_dentry->d_inode;
 363        struct page *dir_page = NULL;
 364        struct nilfs_dir_entry *dir_de = NULL;
 365        struct page *old_page;
 366        struct nilfs_dir_entry *old_de;
 367        struct nilfs_transaction_info ti;
 368        int err;
 369
 370        err = nilfs_transaction_begin(old_dir->i_sb, &ti, 1);
 371        if (unlikely(err))
 372                return err;
 373
 374        err = -ENOENT;
 375        old_de = nilfs_find_entry(old_dir, old_dentry, &old_page);
 376        if (!old_de)
 377                goto out;
 378
 379        if (S_ISDIR(old_inode->i_mode)) {
 380                err = -EIO;
 381                dir_de = nilfs_dotdot(old_inode, &dir_page);
 382                if (!dir_de)
 383                        goto out_old;
 384        }
 385
 386        if (new_inode) {
 387                struct page *new_page;
 388                struct nilfs_dir_entry *new_de;
 389
 390                err = -ENOTEMPTY;
 391                if (dir_de && !nilfs_empty_dir(new_inode))
 392                        goto out_dir;
 393
 394                err = -ENOENT;
 395                new_de = nilfs_find_entry(new_dir, new_dentry, &new_page);
 396                if (!new_de)
 397                        goto out_dir;
 398                inode_inc_link_count(old_inode);
 399                nilfs_set_link(new_dir, new_de, new_page, old_inode);
 400                new_inode->i_ctime = CURRENT_TIME;
 401                if (dir_de)
 402                        drop_nlink(new_inode);
 403                inode_dec_link_count(new_inode);
 404        } else {
 405                if (dir_de) {
 406                        err = -EMLINK;
 407                        if (new_dir->i_nlink >= NILFS_LINK_MAX)
 408                                goto out_dir;
 409                }
 410                inode_inc_link_count(old_inode);
 411                err = nilfs_add_link(new_dentry, old_inode);
 412                if (err) {
 413                        inode_dec_link_count(old_inode);
 414                        goto out_dir;
 415                }
 416                if (dir_de)
 417                        inode_inc_link_count(new_dir);
 418        }
 419
 420        /*
 421         * Like most other Unix systems, set the ctime for inodes on a
 422         * rename.
 423         * inode_dec_link_count() will mark the inode dirty.
 424         */
 425        old_inode->i_ctime = CURRENT_TIME;
 426
 427        nilfs_delete_entry(old_de, old_page);
 428        inode_dec_link_count(old_inode);
 429
 430        if (dir_de) {
 431                nilfs_set_link(old_inode, dir_de, dir_page, new_dir);
 432                inode_dec_link_count(old_dir);
 433        }
 434
 435        err = nilfs_transaction_commit(old_dir->i_sb);
 436        return err;
 437
 438out_dir:
 439        if (dir_de) {
 440                kunmap(dir_page);
 441                page_cache_release(dir_page);
 442        }
 443out_old:
 444        kunmap(old_page);
 445        page_cache_release(old_page);
 446out:
 447        nilfs_transaction_abort(old_dir->i_sb);
 448        return err;
 449}
 450
 451const struct inode_operations nilfs_dir_inode_operations = {
 452        .create         = nilfs_create,
 453        .lookup         = nilfs_lookup,
 454        .link           = nilfs_link,
 455        .unlink         = nilfs_unlink,
 456        .symlink        = nilfs_symlink,
 457        .mkdir          = nilfs_mkdir,
 458        .rmdir          = nilfs_rmdir,
 459        .mknod          = nilfs_mknod,
 460        .rename         = nilfs_rename,
 461        .setattr        = nilfs_setattr,
 462        .permission     = nilfs_permission,
 463};
 464
 465const struct inode_operations nilfs_special_inode_operations = {
 466        .setattr        = nilfs_setattr,
 467        .permission     = nilfs_permission,
 468};
 469
 470const struct inode_operations nilfs_symlink_inode_operations = {
 471        .readlink       = generic_readlink,
 472        .follow_link    = page_follow_link_light,
 473        .put_link       = page_put_link,
 474};
 475