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