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#include "xip.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                unlock_new_inode(inode);
  45                d_instantiate(dentry, inode);
  46                return 0;
  47        }
  48        inode_dec_link_count(inode);
  49        unlock_new_inode(inode);
  50        iput(inode);
  51        return err;
  52}
  53
  54/*
  55 * Methods themselves.
  56 */
  57
  58static struct dentry *ext2_lookup(struct inode * dir, struct dentry *dentry, unsigned int flags)
  59{
  60        struct inode * inode;
  61        ino_t ino;
  62        
  63        if (dentry->d_name.len > EXT2_NAME_LEN)
  64                return ERR_PTR(-ENAMETOOLONG);
  65
  66        ino = ext2_inode_by_name(dir, &dentry->d_name);
  67        inode = NULL;
  68        if (ino) {
  69                inode = ext2_iget(dir->i_sb, ino);
  70                if (inode == ERR_PTR(-ESTALE)) {
  71                        ext2_error(dir->i_sb, __func__,
  72                                        "deleted inode referenced: %lu",
  73                                        (unsigned long) ino);
  74                        return ERR_PTR(-EIO);
  75                }
  76        }
  77        return d_splice_alias(inode, dentry);
  78}
  79
  80struct dentry *ext2_get_parent(struct dentry *child)
  81{
  82        struct qstr dotdot = QSTR_INIT("..", 2);
  83        unsigned long ino = ext2_inode_by_name(child->d_inode, &dotdot);
  84        if (!ino)
  85                return ERR_PTR(-ENOENT);
  86        return d_obtain_alias(ext2_iget(child->d_inode->i_sb, ino));
  87} 
  88
  89/*
  90 * By the time this is called, we already have created
  91 * the directory cache entry for the new file, but it
  92 * is so far negative - it has no inode.
  93 *
  94 * If the create succeeds, we fill in the inode information
  95 * with d_instantiate(). 
  96 */
  97static int ext2_create (struct inode * dir, struct dentry * dentry, umode_t mode, bool excl)
  98{
  99        struct inode *inode;
 100
 101        dquot_initialize(dir);
 102
 103        inode = ext2_new_inode(dir, mode, &dentry->d_name);
 104        if (IS_ERR(inode))
 105                return PTR_ERR(inode);
 106
 107        inode->i_op = &ext2_file_inode_operations;
 108        if (ext2_use_xip(inode->i_sb)) {
 109                inode->i_mapping->a_ops = &ext2_aops_xip;
 110                inode->i_fop = &ext2_xip_file_operations;
 111        } else if (test_opt(inode->i_sb, NOBH)) {
 112                inode->i_mapping->a_ops = &ext2_nobh_aops;
 113                inode->i_fop = &ext2_file_operations;
 114        } else {
 115                inode->i_mapping->a_ops = &ext2_aops;
 116                inode->i_fop = &ext2_file_operations;
 117        }
 118        mark_inode_dirty(inode);
 119        return ext2_add_nondir(dentry, inode);
 120}
 121
 122static int ext2_tmpfile(struct inode *dir, struct dentry *dentry, umode_t mode)
 123{
 124        struct inode *inode = ext2_new_inode(dir, mode, NULL);
 125        if (IS_ERR(inode))
 126                return PTR_ERR(inode);
 127
 128        inode->i_op = &ext2_file_inode_operations;
 129        if (ext2_use_xip(inode->i_sb)) {
 130                inode->i_mapping->a_ops = &ext2_aops_xip;
 131                inode->i_fop = &ext2_xip_file_operations;
 132        } else if (test_opt(inode->i_sb, NOBH)) {
 133                inode->i_mapping->a_ops = &ext2_nobh_aops;
 134                inode->i_fop = &ext2_file_operations;
 135        } else {
 136                inode->i_mapping->a_ops = &ext2_aops;
 137                inode->i_fop = &ext2_file_operations;
 138        }
 139        mark_inode_dirty(inode);
 140        d_tmpfile(dentry, inode);
 141        unlock_new_inode(inode);
 142        return 0;
 143}
 144
 145static int ext2_mknod (struct inode * dir, struct dentry *dentry, umode_t mode, dev_t rdev)
 146{
 147        struct inode * inode;
 148        int err;
 149
 150        if (!new_valid_dev(rdev))
 151                return -EINVAL;
 152
 153        dquot_initialize(dir);
 154
 155        inode = ext2_new_inode (dir, mode, &dentry->d_name);
 156        err = PTR_ERR(inode);
 157        if (!IS_ERR(inode)) {
 158                init_special_inode(inode, inode->i_mode, rdev);
 159#ifdef CONFIG_EXT2_FS_XATTR
 160                inode->i_op = &ext2_special_inode_operations;
 161#endif
 162                mark_inode_dirty(inode);
 163                err = ext2_add_nondir(dentry, inode);
 164        }
 165        return err;
 166}
 167
 168static int ext2_symlink (struct inode * dir, struct dentry * dentry,
 169        const char * symname)
 170{
 171        struct super_block * sb = dir->i_sb;
 172        int err = -ENAMETOOLONG;
 173        unsigned l = strlen(symname)+1;
 174        struct inode * inode;
 175
 176        if (l > sb->s_blocksize)
 177                goto out;
 178
 179        dquot_initialize(dir);
 180
 181        inode = ext2_new_inode (dir, S_IFLNK | S_IRWXUGO, &dentry->d_name);
 182        err = PTR_ERR(inode);
 183        if (IS_ERR(inode))
 184                goto out;
 185
 186        if (l > sizeof (EXT2_I(inode)->i_data)) {
 187                /* slow symlink */
 188                inode->i_op = &ext2_symlink_inode_operations;
 189                if (test_opt(inode->i_sb, NOBH))
 190                        inode->i_mapping->a_ops = &ext2_nobh_aops;
 191                else
 192                        inode->i_mapping->a_ops = &ext2_aops;
 193                err = page_symlink(inode, symname, l);
 194                if (err)
 195                        goto out_fail;
 196        } else {
 197                /* fast symlink */
 198                inode->i_op = &ext2_fast_symlink_inode_operations;
 199                memcpy((char*)(EXT2_I(inode)->i_data),symname,l);
 200                inode->i_size = l-1;
 201        }
 202        mark_inode_dirty(inode);
 203
 204        err = ext2_add_nondir(dentry, inode);
 205out:
 206        return err;
 207
 208out_fail:
 209        inode_dec_link_count(inode);
 210        unlock_new_inode(inode);
 211        iput (inode);
 212        goto out;
 213}
 214
 215static int ext2_link (struct dentry * old_dentry, struct inode * dir,
 216        struct dentry *dentry)
 217{
 218        struct inode *inode = old_dentry->d_inode;
 219        int err;
 220
 221        dquot_initialize(dir);
 222
 223        inode->i_ctime = CURRENT_TIME_SEC;
 224        inode_inc_link_count(inode);
 225        ihold(inode);
 226
 227        err = ext2_add_link(dentry, inode);
 228        if (!err) {
 229                d_instantiate(dentry, inode);
 230                return 0;
 231        }
 232        inode_dec_link_count(inode);
 233        iput(inode);
 234        return err;
 235}
 236
 237static int ext2_mkdir(struct inode * dir, struct dentry * dentry, umode_t mode)
 238{
 239        struct inode * inode;
 240        int err;
 241
 242        dquot_initialize(dir);
 243
 244        inode_inc_link_count(dir);
 245
 246        inode = ext2_new_inode(dir, S_IFDIR | mode, &dentry->d_name);
 247        err = PTR_ERR(inode);
 248        if (IS_ERR(inode))
 249                goto out_dir;
 250
 251        inode->i_op = &ext2_dir_inode_operations;
 252        inode->i_fop = &ext2_dir_operations;
 253        if (test_opt(inode->i_sb, NOBH))
 254                inode->i_mapping->a_ops = &ext2_nobh_aops;
 255        else
 256                inode->i_mapping->a_ops = &ext2_aops;
 257
 258        inode_inc_link_count(inode);
 259
 260        err = ext2_make_empty(inode, dir);
 261        if (err)
 262                goto out_fail;
 263
 264        err = ext2_add_link(dentry, inode);
 265        if (err)
 266                goto out_fail;
 267
 268        unlock_new_inode(inode);
 269        d_instantiate(dentry, inode);
 270out:
 271        return err;
 272
 273out_fail:
 274        inode_dec_link_count(inode);
 275        inode_dec_link_count(inode);
 276        unlock_new_inode(inode);
 277        iput(inode);
 278out_dir:
 279        inode_dec_link_count(dir);
 280        goto out;
 281}
 282
 283static int ext2_unlink(struct inode * dir, struct dentry *dentry)
 284{
 285        struct inode * inode = dentry->d_inode;
 286        struct ext2_dir_entry_2 * de;
 287        struct page * page;
 288        int err = -ENOENT;
 289
 290        dquot_initialize(dir);
 291
 292        de = ext2_find_entry (dir, &dentry->d_name, &page);
 293        if (!de)
 294                goto out;
 295
 296        err = ext2_delete_entry (de, page);
 297        if (err)
 298                goto out;
 299
 300        inode->i_ctime = dir->i_ctime;
 301        inode_dec_link_count(inode);
 302        err = 0;
 303out:
 304        return err;
 305}
 306
 307static int ext2_rmdir (struct inode * dir, struct dentry *dentry)
 308{
 309        struct inode * inode = dentry->d_inode;
 310        int err = -ENOTEMPTY;
 311
 312        if (ext2_empty_dir(inode)) {
 313                err = ext2_unlink(dir, dentry);
 314                if (!err) {
 315                        inode->i_size = 0;
 316                        inode_dec_link_count(inode);
 317                        inode_dec_link_count(dir);
 318                }
 319        }
 320        return err;
 321}
 322
 323static int ext2_rename (struct inode * old_dir, struct dentry * old_dentry,
 324        struct inode * new_dir, struct dentry * new_dentry )
 325{
 326        struct inode * old_inode = old_dentry->d_inode;
 327        struct inode * new_inode = new_dentry->d_inode;
 328        struct page * dir_page = NULL;
 329        struct ext2_dir_entry_2 * dir_de = NULL;
 330        struct page * old_page;
 331        struct ext2_dir_entry_2 * old_de;
 332        int err = -ENOENT;
 333
 334        dquot_initialize(old_dir);
 335        dquot_initialize(new_dir);
 336
 337        old_de = ext2_find_entry (old_dir, &old_dentry->d_name, &old_page);
 338        if (!old_de)
 339                goto out;
 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_SEC;
 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_SEC;
 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                        page_cache_release(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                page_cache_release(dir_page);
 398        }
 399out_old:
 400        kunmap(old_page);
 401        page_cache_release(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        .setxattr       = generic_setxattr,
 418        .getxattr       = generic_getxattr,
 419        .listxattr      = ext2_listxattr,
 420        .removexattr    = generic_removexattr,
 421#endif
 422        .setattr        = ext2_setattr,
 423        .get_acl        = ext2_get_acl,
 424        .tmpfile        = ext2_tmpfile,
 425};
 426
 427const struct inode_operations ext2_special_inode_operations = {
 428#ifdef CONFIG_EXT2_FS_XATTR
 429        .setxattr       = generic_setxattr,
 430        .getxattr       = generic_getxattr,
 431        .listxattr      = ext2_listxattr,
 432        .removexattr    = generic_removexattr,
 433#endif
 434        .setattr        = ext2_setattr,
 435        .get_acl        = ext2_get_acl,
 436};
 437