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