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