linux/fs/ext2/namei.c
<<
>>
Prefs
   1// SPDX-License-Identifier: GPL-2.0
   2/*
   3 * linux/fs/ext2/namei.c
   4 *
   5 * Rewrite to pagecache. Almost all code had been changed, so blame me
   6 * if the things go wrong. Please, send bug reports to
   7 * viro@parcelfarce.linux.theplanet.co.uk
   8 *
   9 * Stuff here is basically a glue between the VFS and generic UNIXish
  10 * filesystem that keeps everything in pagecache. All knowledge of the
  11 * directory layout is in fs/ext2/dir.c - it turned out to be easily separatable
  12 * and it's easier to debug that way. In principle we might want to
  13 * generalize that a bit and turn it into a library. Or not.
  14 *
  15 * The only non-static object here is ext2_dir_inode_operations.
  16 *
  17 * TODO: get rid of kmap() use, add readahead.
  18 *
  19 * Copyright (C) 1992, 1993, 1994, 1995
  20 * Remy Card (card@masi.ibp.fr)
  21 * Laboratoire MASI - Institut Blaise Pascal
  22 * Universite Pierre et Marie Curie (Paris VI)
  23 *
  24 *  from
  25 *
  26 *  linux/fs/minix/namei.c
  27 *
  28 *  Copyright (C) 1991, 1992  Linus Torvalds
  29 *
  30 *  Big-endian to little-endian byte-swapping/bitmaps by
  31 *        David S. Miller (davem@caip.rutgers.edu), 1995
  32 */
  33
  34#include <linux/pagemap.h>
  35#include <linux/quotaops.h>
  36#include "ext2.h"
  37#include "xattr.h"
  38#include "acl.h"
  39
  40static inline int ext2_add_nondir(struct dentry *dentry, struct inode *inode)
  41{
  42        int err = ext2_add_link(dentry, inode);
  43        if (!err) {
  44                d_instantiate_new(dentry, inode);
  45                return 0;
  46        }
  47        inode_dec_link_count(inode);
  48        discard_new_inode(inode);
  49        return err;
  50}
  51
  52/*
  53 * Methods themselves.
  54 */
  55
  56static struct dentry *ext2_lookup(struct inode * dir, struct dentry *dentry, unsigned int flags)
  57{
  58        struct inode * inode;
  59        ino_t ino;
  60        int res;
  61        
  62        if (dentry->d_name.len > EXT2_NAME_LEN)
  63                return ERR_PTR(-ENAMETOOLONG);
  64
  65        res = ext2_inode_by_name(dir, &dentry->d_name, &ino);
  66        if (res) {
  67                if (res != -ENOENT)
  68                        return ERR_PTR(res);
  69                inode = NULL;
  70        } else {
  71                inode = ext2_iget(dir->i_sb, ino);
  72                if (inode == ERR_PTR(-ESTALE)) {
  73                        ext2_error(dir->i_sb, __func__,
  74                                        "deleted inode referenced: %lu",
  75                                        (unsigned long) ino);
  76                        return ERR_PTR(-EIO);
  77                }
  78        }
  79        return d_splice_alias(inode, dentry);
  80}
  81
  82struct dentry *ext2_get_parent(struct dentry *child)
  83{
  84        ino_t ino;
  85        int res;
  86
  87        res = ext2_inode_by_name(d_inode(child), &dotdot_name, &ino);
  88        if (res)
  89                return ERR_PTR(res);
  90
  91        return d_obtain_alias(ext2_iget(child->d_sb, ino));
  92} 
  93
  94/*
  95 * By the time this is called, we already have created
  96 * the directory cache entry for the new file, but it
  97 * is so far negative - it has no inode.
  98 *
  99 * If the create succeeds, we fill in the inode information
 100 * with d_instantiate(). 
 101 */
 102static int ext2_create (struct user_namespace * mnt_userns,
 103                        struct inode * dir, struct dentry * dentry,
 104                        umode_t mode, bool excl)
 105{
 106        struct inode *inode;
 107        int err;
 108
 109        err = dquot_initialize(dir);
 110        if (err)
 111                return err;
 112
 113        inode = ext2_new_inode(dir, mode, &dentry->d_name);
 114        if (IS_ERR(inode))
 115                return PTR_ERR(inode);
 116
 117        ext2_set_file_ops(inode);
 118        mark_inode_dirty(inode);
 119        return ext2_add_nondir(dentry, inode);
 120}
 121
 122static int ext2_tmpfile(struct user_namespace *mnt_userns, struct inode *dir,
 123                        struct dentry *dentry, umode_t mode)
 124{
 125        struct inode *inode = ext2_new_inode(dir, mode, NULL);
 126        if (IS_ERR(inode))
 127                return PTR_ERR(inode);
 128
 129        ext2_set_file_ops(inode);
 130        mark_inode_dirty(inode);
 131        d_tmpfile(dentry, inode);
 132        unlock_new_inode(inode);
 133        return 0;
 134}
 135
 136static int ext2_mknod (struct user_namespace * mnt_userns, struct inode * dir,
 137        struct dentry *dentry, umode_t mode, dev_t rdev)
 138{
 139        struct inode * inode;
 140        int err;
 141
 142        err = dquot_initialize(dir);
 143        if (err)
 144                return err;
 145
 146        inode = ext2_new_inode (dir, mode, &dentry->d_name);
 147        err = PTR_ERR(inode);
 148        if (!IS_ERR(inode)) {
 149                init_special_inode(inode, inode->i_mode, rdev);
 150                inode->i_op = &ext2_special_inode_operations;
 151                mark_inode_dirty(inode);
 152                err = ext2_add_nondir(dentry, inode);
 153        }
 154        return err;
 155}
 156
 157static int ext2_symlink (struct user_namespace * mnt_userns, struct inode * dir,
 158        struct dentry * dentry, const char * symname)
 159{
 160        struct super_block * sb = dir->i_sb;
 161        int err = -ENAMETOOLONG;
 162        unsigned l = strlen(symname)+1;
 163        struct inode * inode;
 164
 165        if (l > sb->s_blocksize)
 166                goto out;
 167
 168        err = dquot_initialize(dir);
 169        if (err)
 170                goto out;
 171
 172        inode = ext2_new_inode (dir, S_IFLNK | S_IRWXUGO, &dentry->d_name);
 173        err = PTR_ERR(inode);
 174        if (IS_ERR(inode))
 175                goto out;
 176
 177        if (l > sizeof (EXT2_I(inode)->i_data)) {
 178                /* slow symlink */
 179                inode->i_op = &ext2_symlink_inode_operations;
 180                inode_nohighmem(inode);
 181                if (test_opt(inode->i_sb, NOBH))
 182                        inode->i_mapping->a_ops = &ext2_nobh_aops;
 183                else
 184                        inode->i_mapping->a_ops = &ext2_aops;
 185                err = page_symlink(inode, symname, l);
 186                if (err)
 187                        goto out_fail;
 188        } else {
 189                /* fast symlink */
 190                inode->i_op = &ext2_fast_symlink_inode_operations;
 191                inode->i_link = (char*)EXT2_I(inode)->i_data;
 192                memcpy(inode->i_link, symname, l);
 193                inode->i_size = l-1;
 194        }
 195        mark_inode_dirty(inode);
 196
 197        err = ext2_add_nondir(dentry, inode);
 198out:
 199        return err;
 200
 201out_fail:
 202        inode_dec_link_count(inode);
 203        discard_new_inode(inode);
 204        goto out;
 205}
 206
 207static int ext2_link (struct dentry * old_dentry, struct inode * dir,
 208        struct dentry *dentry)
 209{
 210        struct inode *inode = d_inode(old_dentry);
 211        int err;
 212
 213        err = dquot_initialize(dir);
 214        if (err)
 215                return err;
 216
 217        inode->i_ctime = current_time(inode);
 218        inode_inc_link_count(inode);
 219        ihold(inode);
 220
 221        err = ext2_add_link(dentry, inode);
 222        if (!err) {
 223                d_instantiate(dentry, inode);
 224                return 0;
 225        }
 226        inode_dec_link_count(inode);
 227        iput(inode);
 228        return err;
 229}
 230
 231static int ext2_mkdir(struct user_namespace * mnt_userns,
 232        struct inode * dir, struct dentry * dentry, umode_t mode)
 233{
 234        struct inode * inode;
 235        int err;
 236
 237        err = dquot_initialize(dir);
 238        if (err)
 239                return err;
 240
 241        inode_inc_link_count(dir);
 242
 243        inode = ext2_new_inode(dir, S_IFDIR | mode, &dentry->d_name);
 244        err = PTR_ERR(inode);
 245        if (IS_ERR(inode))
 246                goto out_dir;
 247
 248        inode->i_op = &ext2_dir_inode_operations;
 249        inode->i_fop = &ext2_dir_operations;
 250        if (test_opt(inode->i_sb, NOBH))
 251                inode->i_mapping->a_ops = &ext2_nobh_aops;
 252        else
 253                inode->i_mapping->a_ops = &ext2_aops;
 254
 255        inode_inc_link_count(inode);
 256
 257        err = ext2_make_empty(inode, dir);
 258        if (err)
 259                goto out_fail;
 260
 261        err = ext2_add_link(dentry, inode);
 262        if (err)
 263                goto out_fail;
 264
 265        d_instantiate_new(dentry, inode);
 266out:
 267        return err;
 268
 269out_fail:
 270        inode_dec_link_count(inode);
 271        inode_dec_link_count(inode);
 272        discard_new_inode(inode);
 273out_dir:
 274        inode_dec_link_count(dir);
 275        goto out;
 276}
 277
 278static int ext2_unlink(struct inode * dir, struct dentry *dentry)
 279{
 280        struct inode * inode = d_inode(dentry);
 281        struct ext2_dir_entry_2 * de;
 282        struct page * page;
 283        void *page_addr;
 284        int err;
 285
 286        err = dquot_initialize(dir);
 287        if (err)
 288                goto out;
 289
 290        de = ext2_find_entry(dir, &dentry->d_name, &page, &page_addr);
 291        if (IS_ERR(de)) {
 292                err = PTR_ERR(de);
 293                goto out;
 294        }
 295
 296        err = ext2_delete_entry (de, page, page_addr);
 297        ext2_put_page(page, page_addr);
 298        if (err)
 299                goto out;
 300
 301        inode->i_ctime = dir->i_ctime;
 302        inode_dec_link_count(inode);
 303        err = 0;
 304out:
 305        return err;
 306}
 307
 308static int ext2_rmdir (struct inode * dir, struct dentry *dentry)
 309{
 310        struct inode * inode = d_inode(dentry);
 311        int err = -ENOTEMPTY;
 312
 313        if (ext2_empty_dir(inode)) {
 314                err = ext2_unlink(dir, dentry);
 315                if (!err) {
 316                        inode->i_size = 0;
 317                        inode_dec_link_count(inode);
 318                        inode_dec_link_count(dir);
 319                }
 320        }
 321        return err;
 322}
 323
 324static int ext2_rename (struct user_namespace * mnt_userns,
 325                        struct inode * old_dir, struct dentry * old_dentry,
 326                        struct inode * new_dir, struct dentry * new_dentry,
 327                        unsigned int flags)
 328{
 329        struct inode * old_inode = d_inode(old_dentry);
 330        struct inode * new_inode = d_inode(new_dentry);
 331        struct page * dir_page = NULL;
 332        void *dir_page_addr;
 333        struct ext2_dir_entry_2 * dir_de = NULL;
 334        struct page * old_page;
 335        void *old_page_addr;
 336        struct ext2_dir_entry_2 * old_de;
 337        int err;
 338
 339        if (flags & ~RENAME_NOREPLACE)
 340                return -EINVAL;
 341
 342        err = dquot_initialize(old_dir);
 343        if (err)
 344                goto out;
 345
 346        err = dquot_initialize(new_dir);
 347        if (err)
 348                goto out;
 349
 350        old_de = ext2_find_entry(old_dir, &old_dentry->d_name, &old_page,
 351                                 &old_page_addr);
 352        if (IS_ERR(old_de)) {
 353                err = PTR_ERR(old_de);
 354                goto out;
 355        }
 356
 357        if (S_ISDIR(old_inode->i_mode)) {
 358                err = -EIO;
 359                dir_de = ext2_dotdot(old_inode, &dir_page, &dir_page_addr);
 360                if (!dir_de)
 361                        goto out_old;
 362        }
 363
 364        if (new_inode) {
 365                void *page_addr;
 366                struct page *new_page;
 367                struct ext2_dir_entry_2 *new_de;
 368
 369                err = -ENOTEMPTY;
 370                if (dir_de && !ext2_empty_dir (new_inode))
 371                        goto out_dir;
 372
 373                new_de = ext2_find_entry(new_dir, &new_dentry->d_name,
 374                                         &new_page, &page_addr);
 375                if (IS_ERR(new_de)) {
 376                        err = PTR_ERR(new_de);
 377                        goto out_dir;
 378                }
 379                ext2_set_link(new_dir, new_de, new_page, page_addr, old_inode, 1);
 380                ext2_put_page(new_page, page_addr);
 381                new_inode->i_ctime = current_time(new_inode);
 382                if (dir_de)
 383                        drop_nlink(new_inode);
 384                inode_dec_link_count(new_inode);
 385        } else {
 386                err = ext2_add_link(new_dentry, old_inode);
 387                if (err)
 388                        goto out_dir;
 389                if (dir_de)
 390                        inode_inc_link_count(new_dir);
 391        }
 392
 393        /*
 394         * Like most other Unix systems, set the ctime for inodes on a
 395         * rename.
 396         */
 397        old_inode->i_ctime = current_time(old_inode);
 398        mark_inode_dirty(old_inode);
 399
 400        ext2_delete_entry(old_de, old_page, old_page_addr);
 401
 402        if (dir_de) {
 403                if (old_dir != new_dir)
 404                        ext2_set_link(old_inode, dir_de, dir_page,
 405                                      dir_page_addr, new_dir, 0);
 406
 407                ext2_put_page(dir_page, dir_page_addr);
 408                inode_dec_link_count(old_dir);
 409        }
 410
 411        ext2_put_page(old_page, old_page_addr);
 412        return 0;
 413
 414out_dir:
 415        if (dir_de)
 416                ext2_put_page(dir_page, dir_page_addr);
 417out_old:
 418        ext2_put_page(old_page, old_page_addr);
 419out:
 420        return err;
 421}
 422
 423const struct inode_operations ext2_dir_inode_operations = {
 424        .create         = ext2_create,
 425        .lookup         = ext2_lookup,
 426        .link           = ext2_link,
 427        .unlink         = ext2_unlink,
 428        .symlink        = ext2_symlink,
 429        .mkdir          = ext2_mkdir,
 430        .rmdir          = ext2_rmdir,
 431        .mknod          = ext2_mknod,
 432        .rename         = ext2_rename,
 433        .listxattr      = ext2_listxattr,
 434        .getattr        = ext2_getattr,
 435        .setattr        = ext2_setattr,
 436        .get_acl        = ext2_get_acl,
 437        .set_acl        = ext2_set_acl,
 438        .tmpfile        = ext2_tmpfile,
 439        .fileattr_get   = ext2_fileattr_get,
 440        .fileattr_set   = ext2_fileattr_set,
 441};
 442
 443const struct inode_operations ext2_special_inode_operations = {
 444        .listxattr      = ext2_listxattr,
 445        .getattr        = ext2_getattr,
 446        .setattr        = ext2_setattr,
 447        .get_acl        = ext2_get_acl,
 448        .set_acl        = ext2_set_acl,
 449};
 450