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        
  61        if (dentry->d_name.len > EXT2_NAME_LEN)
  62                return ERR_PTR(-ENAMETOOLONG);
  63
  64        ino = ext2_inode_by_name(dir, &dentry->d_name);
  65        inode = NULL;
  66        if (ino) {
  67                inode = ext2_iget(dir->i_sb, ino);
  68                if (inode == ERR_PTR(-ESTALE)) {
  69                        ext2_error(dir->i_sb, __func__,
  70                                        "deleted inode referenced: %lu",
  71                                        (unsigned long) ino);
  72                        return ERR_PTR(-EIO);
  73                }
  74        }
  75        return d_splice_alias(inode, dentry);
  76}
  77
  78struct dentry *ext2_get_parent(struct dentry *child)
  79{
  80        struct qstr dotdot = QSTR_INIT("..", 2);
  81        unsigned long ino = ext2_inode_by_name(d_inode(child), &dotdot);
  82        if (!ino)
  83                return ERR_PTR(-ENOENT);
  84        return d_obtain_alias(ext2_iget(child->d_sb, ino));
  85} 
  86
  87/*
  88 * By the time this is called, we already have created
  89 * the directory cache entry for the new file, but it
  90 * is so far negative - it has no inode.
  91 *
  92 * If the create succeeds, we fill in the inode information
  93 * with d_instantiate(). 
  94 */
  95static int ext2_create (struct inode * dir, struct dentry * dentry, umode_t mode, bool excl)
  96{
  97        struct inode *inode;
  98        int err;
  99
 100        err = dquot_initialize(dir);
 101        if (err)
 102                return err;
 103
 104        inode = ext2_new_inode(dir, mode, &dentry->d_name);
 105        if (IS_ERR(inode))
 106                return PTR_ERR(inode);
 107
 108        ext2_set_file_ops(inode);
 109        mark_inode_dirty(inode);
 110        return ext2_add_nondir(dentry, inode);
 111}
 112
 113static int ext2_tmpfile(struct inode *dir, struct dentry *dentry, umode_t mode)
 114{
 115        struct inode *inode = ext2_new_inode(dir, mode, NULL);
 116        if (IS_ERR(inode))
 117                return PTR_ERR(inode);
 118
 119        ext2_set_file_ops(inode);
 120        mark_inode_dirty(inode);
 121        d_tmpfile(dentry, inode);
 122        unlock_new_inode(inode);
 123        return 0;
 124}
 125
 126static int ext2_mknod (struct inode * dir, struct dentry *dentry, umode_t mode, dev_t rdev)
 127{
 128        struct inode * inode;
 129        int err;
 130
 131        err = dquot_initialize(dir);
 132        if (err)
 133                return err;
 134
 135        inode = ext2_new_inode (dir, mode, &dentry->d_name);
 136        err = PTR_ERR(inode);
 137        if (!IS_ERR(inode)) {
 138                init_special_inode(inode, inode->i_mode, rdev);
 139#ifdef CONFIG_EXT2_FS_XATTR
 140                inode->i_op = &ext2_special_inode_operations;
 141#endif
 142                mark_inode_dirty(inode);
 143                err = ext2_add_nondir(dentry, inode);
 144        }
 145        return err;
 146}
 147
 148static int ext2_symlink (struct inode * dir, struct dentry * dentry,
 149        const char * symname)
 150{
 151        struct super_block * sb = dir->i_sb;
 152        int err = -ENAMETOOLONG;
 153        unsigned l = strlen(symname)+1;
 154        struct inode * inode;
 155
 156        if (l > sb->s_blocksize)
 157                goto out;
 158
 159        err = dquot_initialize(dir);
 160        if (err)
 161                goto out;
 162
 163        inode = ext2_new_inode (dir, S_IFLNK | S_IRWXUGO, &dentry->d_name);
 164        err = PTR_ERR(inode);
 165        if (IS_ERR(inode))
 166                goto out;
 167
 168        if (l > sizeof (EXT2_I(inode)->i_data)) {
 169                /* slow symlink */
 170                inode->i_op = &ext2_symlink_inode_operations;
 171                inode_nohighmem(inode);
 172                if (test_opt(inode->i_sb, NOBH))
 173                        inode->i_mapping->a_ops = &ext2_nobh_aops;
 174                else
 175                        inode->i_mapping->a_ops = &ext2_aops;
 176                err = page_symlink(inode, symname, l);
 177                if (err)
 178                        goto out_fail;
 179        } else {
 180                /* fast symlink */
 181                inode->i_op = &ext2_fast_symlink_inode_operations;
 182                inode->i_link = (char*)EXT2_I(inode)->i_data;
 183                memcpy(inode->i_link, symname, l);
 184                inode->i_size = l-1;
 185        }
 186        mark_inode_dirty(inode);
 187
 188        err = ext2_add_nondir(dentry, inode);
 189out:
 190        return err;
 191
 192out_fail:
 193        inode_dec_link_count(inode);
 194        discard_new_inode(inode);
 195        goto out;
 196}
 197
 198static int ext2_link (struct dentry * old_dentry, struct inode * dir,
 199        struct dentry *dentry)
 200{
 201        struct inode *inode = d_inode(old_dentry);
 202        int err;
 203
 204        err = dquot_initialize(dir);
 205        if (err)
 206                return err;
 207
 208        inode->i_ctime = current_time(inode);
 209        inode_inc_link_count(inode);
 210        ihold(inode);
 211
 212        err = ext2_add_link(dentry, inode);
 213        if (!err) {
 214                d_instantiate(dentry, inode);
 215                return 0;
 216        }
 217        inode_dec_link_count(inode);
 218        iput(inode);
 219        return err;
 220}
 221
 222static int ext2_mkdir(struct inode * dir, struct dentry * dentry, umode_t mode)
 223{
 224        struct inode * inode;
 225        int err;
 226
 227        err = dquot_initialize(dir);
 228        if (err)
 229                return err;
 230
 231        inode_inc_link_count(dir);
 232
 233        inode = ext2_new_inode(dir, S_IFDIR | mode, &dentry->d_name);
 234        err = PTR_ERR(inode);
 235        if (IS_ERR(inode))
 236                goto out_dir;
 237
 238        inode->i_op = &ext2_dir_inode_operations;
 239        inode->i_fop = &ext2_dir_operations;
 240        if (test_opt(inode->i_sb, NOBH))
 241                inode->i_mapping->a_ops = &ext2_nobh_aops;
 242        else
 243                inode->i_mapping->a_ops = &ext2_aops;
 244
 245        inode_inc_link_count(inode);
 246
 247        err = ext2_make_empty(inode, dir);
 248        if (err)
 249                goto out_fail;
 250
 251        err = ext2_add_link(dentry, inode);
 252        if (err)
 253                goto out_fail;
 254
 255        d_instantiate_new(dentry, inode);
 256out:
 257        return err;
 258
 259out_fail:
 260        inode_dec_link_count(inode);
 261        inode_dec_link_count(inode);
 262        discard_new_inode(inode);
 263out_dir:
 264        inode_dec_link_count(dir);
 265        goto out;
 266}
 267
 268static int ext2_unlink(struct inode * dir, struct dentry *dentry)
 269{
 270        struct inode * inode = d_inode(dentry);
 271        struct ext2_dir_entry_2 * de;
 272        struct page * page;
 273        int err;
 274
 275        err = dquot_initialize(dir);
 276        if (err)
 277                goto out;
 278
 279        de = ext2_find_entry (dir, &dentry->d_name, &page);
 280        if (!de) {
 281                err = -ENOENT;
 282                goto out;
 283        }
 284
 285        err = ext2_delete_entry (de, page);
 286        if (err)
 287                goto out;
 288
 289        inode->i_ctime = dir->i_ctime;
 290        inode_dec_link_count(inode);
 291        err = 0;
 292out:
 293        return err;
 294}
 295
 296static int ext2_rmdir (struct inode * dir, struct dentry *dentry)
 297{
 298        struct inode * inode = d_inode(dentry);
 299        int err = -ENOTEMPTY;
 300
 301        if (ext2_empty_dir(inode)) {
 302                err = ext2_unlink(dir, dentry);
 303                if (!err) {
 304                        inode->i_size = 0;
 305                        inode_dec_link_count(inode);
 306                        inode_dec_link_count(dir);
 307                }
 308        }
 309        return err;
 310}
 311
 312static int ext2_rename (struct inode * old_dir, struct dentry * old_dentry,
 313                        struct inode * new_dir, struct dentry * new_dentry,
 314                        unsigned int flags)
 315{
 316        struct inode * old_inode = d_inode(old_dentry);
 317        struct inode * new_inode = d_inode(new_dentry);
 318        struct page * dir_page = NULL;
 319        struct ext2_dir_entry_2 * dir_de = NULL;
 320        struct page * old_page;
 321        struct ext2_dir_entry_2 * old_de;
 322        int err;
 323
 324        if (flags & ~RENAME_NOREPLACE)
 325                return -EINVAL;
 326
 327        err = dquot_initialize(old_dir);
 328        if (err)
 329                goto out;
 330
 331        err = dquot_initialize(new_dir);
 332        if (err)
 333                goto out;
 334
 335        old_de = ext2_find_entry (old_dir, &old_dentry->d_name, &old_page);
 336        if (!old_de) {
 337                err = -ENOENT;
 338                goto out;
 339        }
 340
 341        if (S_ISDIR(old_inode->i_mode)) {
 342                err = -EIO;
 343                dir_de = ext2_dotdot(old_inode, &dir_page);
 344                if (!dir_de)
 345                        goto out_old;
 346        }
 347
 348        if (new_inode) {
 349                struct page *new_page;
 350                struct ext2_dir_entry_2 *new_de;
 351
 352                err = -ENOTEMPTY;
 353                if (dir_de && !ext2_empty_dir (new_inode))
 354                        goto out_dir;
 355
 356                err = -ENOENT;
 357                new_de = ext2_find_entry (new_dir, &new_dentry->d_name, &new_page);
 358                if (!new_de)
 359                        goto out_dir;
 360                ext2_set_link(new_dir, new_de, new_page, old_inode, 1);
 361                new_inode->i_ctime = current_time(new_inode);
 362                if (dir_de)
 363                        drop_nlink(new_inode);
 364                inode_dec_link_count(new_inode);
 365        } else {
 366                err = ext2_add_link(new_dentry, old_inode);
 367                if (err)
 368                        goto out_dir;
 369                if (dir_de)
 370                        inode_inc_link_count(new_dir);
 371        }
 372
 373        /*
 374         * Like most other Unix systems, set the ctime for inodes on a
 375         * rename.
 376         */
 377        old_inode->i_ctime = current_time(old_inode);
 378        mark_inode_dirty(old_inode);
 379
 380        ext2_delete_entry (old_de, old_page);
 381
 382        if (dir_de) {
 383                if (old_dir != new_dir)
 384                        ext2_set_link(old_inode, dir_de, dir_page, new_dir, 0);
 385                else {
 386                        kunmap(dir_page);
 387                        put_page(dir_page);
 388                }
 389                inode_dec_link_count(old_dir);
 390        }
 391        return 0;
 392
 393
 394out_dir:
 395        if (dir_de) {
 396                kunmap(dir_page);
 397                put_page(dir_page);
 398        }
 399out_old:
 400        kunmap(old_page);
 401        put_page(old_page);
 402out:
 403        return err;
 404}
 405
 406const struct inode_operations ext2_dir_inode_operations = {
 407        .create         = ext2_create,
 408        .lookup         = ext2_lookup,
 409        .link           = ext2_link,
 410        .unlink         = ext2_unlink,
 411        .symlink        = ext2_symlink,
 412        .mkdir          = ext2_mkdir,
 413        .rmdir          = ext2_rmdir,
 414        .mknod          = ext2_mknod,
 415        .rename         = ext2_rename,
 416#ifdef CONFIG_EXT2_FS_XATTR
 417        .listxattr      = ext2_listxattr,
 418#endif
 419        .setattr        = ext2_setattr,
 420        .get_acl        = ext2_get_acl,
 421        .set_acl        = ext2_set_acl,
 422        .tmpfile        = ext2_tmpfile,
 423};
 424
 425const struct inode_operations ext2_special_inode_operations = {
 426#ifdef CONFIG_EXT2_FS_XATTR
 427        .listxattr      = ext2_listxattr,
 428#endif
 429        .setattr        = ext2_setattr,
 430        .get_acl        = ext2_get_acl,
 431        .set_acl        = ext2_set_acl,
 432};
 433