Back to home page

OSCL-LXR

 
 

    


0001 // SPDX-License-Identifier: GPL-2.0
0002 /*
0003  * linux/fs/ext2/namei.c
0004  *
0005  * Rewrite to pagecache. Almost all code had been changed, so blame me
0006  * if the things go wrong. Please, send bug reports to
0007  * viro@parcelfarce.linux.theplanet.co.uk
0008  *
0009  * Stuff here is basically a glue between the VFS and generic UNIXish
0010  * filesystem that keeps everything in pagecache. All knowledge of the
0011  * directory layout is in fs/ext2/dir.c - it turned out to be easily separatable
0012  * and it's easier to debug that way. In principle we might want to
0013  * generalize that a bit and turn it into a library. Or not.
0014  *
0015  * The only non-static object here is ext2_dir_inode_operations.
0016  *
0017  * TODO: get rid of kmap() use, add readahead.
0018  *
0019  * Copyright (C) 1992, 1993, 1994, 1995
0020  * Remy Card (card@masi.ibp.fr)
0021  * Laboratoire MASI - Institut Blaise Pascal
0022  * Universite Pierre et Marie Curie (Paris VI)
0023  *
0024  *  from
0025  *
0026  *  linux/fs/minix/namei.c
0027  *
0028  *  Copyright (C) 1991, 1992  Linus Torvalds
0029  *
0030  *  Big-endian to little-endian byte-swapping/bitmaps by
0031  *        David S. Miller (davem@caip.rutgers.edu), 1995
0032  */
0033 
0034 #include <linux/pagemap.h>
0035 #include <linux/quotaops.h>
0036 #include "ext2.h"
0037 #include "xattr.h"
0038 #include "acl.h"
0039 
0040 static inline int ext2_add_nondir(struct dentry *dentry, struct inode *inode)
0041 {
0042     int err = ext2_add_link(dentry, inode);
0043     if (!err) {
0044         d_instantiate_new(dentry, inode);
0045         return 0;
0046     }
0047     inode_dec_link_count(inode);
0048     discard_new_inode(inode);
0049     return err;
0050 }
0051 
0052 /*
0053  * Methods themselves.
0054  */
0055 
0056 static struct dentry *ext2_lookup(struct inode * dir, struct dentry *dentry, unsigned int flags)
0057 {
0058     struct inode * inode;
0059     ino_t ino;
0060     int res;
0061     
0062     if (dentry->d_name.len > EXT2_NAME_LEN)
0063         return ERR_PTR(-ENAMETOOLONG);
0064 
0065     res = ext2_inode_by_name(dir, &dentry->d_name, &ino);
0066     if (res) {
0067         if (res != -ENOENT)
0068             return ERR_PTR(res);
0069         inode = NULL;
0070     } else {
0071         inode = ext2_iget(dir->i_sb, ino);
0072         if (inode == ERR_PTR(-ESTALE)) {
0073             ext2_error(dir->i_sb, __func__,
0074                     "deleted inode referenced: %lu",
0075                     (unsigned long) ino);
0076             return ERR_PTR(-EIO);
0077         }
0078     }
0079     return d_splice_alias(inode, dentry);
0080 }
0081 
0082 struct dentry *ext2_get_parent(struct dentry *child)
0083 {
0084     ino_t ino;
0085     int res;
0086 
0087     res = ext2_inode_by_name(d_inode(child), &dotdot_name, &ino);
0088     if (res)
0089         return ERR_PTR(res);
0090 
0091     return d_obtain_alias(ext2_iget(child->d_sb, ino));
0092 } 
0093 
0094 /*
0095  * By the time this is called, we already have created
0096  * the directory cache entry for the new file, but it
0097  * is so far negative - it has no inode.
0098  *
0099  * If the create succeeds, we fill in the inode information
0100  * with d_instantiate(). 
0101  */
0102 static int ext2_create (struct user_namespace * mnt_userns,
0103             struct inode * dir, struct dentry * dentry,
0104             umode_t mode, bool excl)
0105 {
0106     struct inode *inode;
0107     int err;
0108 
0109     err = dquot_initialize(dir);
0110     if (err)
0111         return err;
0112 
0113     inode = ext2_new_inode(dir, mode, &dentry->d_name);
0114     if (IS_ERR(inode))
0115         return PTR_ERR(inode);
0116 
0117     ext2_set_file_ops(inode);
0118     mark_inode_dirty(inode);
0119     return ext2_add_nondir(dentry, inode);
0120 }
0121 
0122 static int ext2_tmpfile(struct user_namespace *mnt_userns, struct inode *dir,
0123             struct dentry *dentry, umode_t mode)
0124 {
0125     struct inode *inode = ext2_new_inode(dir, mode, NULL);
0126     if (IS_ERR(inode))
0127         return PTR_ERR(inode);
0128 
0129     ext2_set_file_ops(inode);
0130     mark_inode_dirty(inode);
0131     d_tmpfile(dentry, inode);
0132     unlock_new_inode(inode);
0133     return 0;
0134 }
0135 
0136 static int ext2_mknod (struct user_namespace * mnt_userns, struct inode * dir,
0137     struct dentry *dentry, umode_t mode, dev_t rdev)
0138 {
0139     struct inode * inode;
0140     int err;
0141 
0142     err = dquot_initialize(dir);
0143     if (err)
0144         return err;
0145 
0146     inode = ext2_new_inode (dir, mode, &dentry->d_name);
0147     err = PTR_ERR(inode);
0148     if (!IS_ERR(inode)) {
0149         init_special_inode(inode, inode->i_mode, rdev);
0150         inode->i_op = &ext2_special_inode_operations;
0151         mark_inode_dirty(inode);
0152         err = ext2_add_nondir(dentry, inode);
0153     }
0154     return err;
0155 }
0156 
0157 static int ext2_symlink (struct user_namespace * mnt_userns, struct inode * dir,
0158     struct dentry * dentry, const char * symname)
0159 {
0160     struct super_block * sb = dir->i_sb;
0161     int err = -ENAMETOOLONG;
0162     unsigned l = strlen(symname)+1;
0163     struct inode * inode;
0164 
0165     if (l > sb->s_blocksize)
0166         goto out;
0167 
0168     err = dquot_initialize(dir);
0169     if (err)
0170         goto out;
0171 
0172     inode = ext2_new_inode (dir, S_IFLNK | S_IRWXUGO, &dentry->d_name);
0173     err = PTR_ERR(inode);
0174     if (IS_ERR(inode))
0175         goto out;
0176 
0177     if (l > sizeof (EXT2_I(inode)->i_data)) {
0178         /* slow symlink */
0179         inode->i_op = &ext2_symlink_inode_operations;
0180         inode_nohighmem(inode);
0181         inode->i_mapping->a_ops = &ext2_aops;
0182         err = page_symlink(inode, symname, l);
0183         if (err)
0184             goto out_fail;
0185     } else {
0186         /* fast symlink */
0187         inode->i_op = &ext2_fast_symlink_inode_operations;
0188         inode->i_link = (char*)EXT2_I(inode)->i_data;
0189         memcpy(inode->i_link, symname, l);
0190         inode->i_size = l-1;
0191     }
0192     mark_inode_dirty(inode);
0193 
0194     err = ext2_add_nondir(dentry, inode);
0195 out:
0196     return err;
0197 
0198 out_fail:
0199     inode_dec_link_count(inode);
0200     discard_new_inode(inode);
0201     goto out;
0202 }
0203 
0204 static int ext2_link (struct dentry * old_dentry, struct inode * dir,
0205     struct dentry *dentry)
0206 {
0207     struct inode *inode = d_inode(old_dentry);
0208     int err;
0209 
0210     err = dquot_initialize(dir);
0211     if (err)
0212         return err;
0213 
0214     inode->i_ctime = current_time(inode);
0215     inode_inc_link_count(inode);
0216     ihold(inode);
0217 
0218     err = ext2_add_link(dentry, inode);
0219     if (!err) {
0220         d_instantiate(dentry, inode);
0221         return 0;
0222     }
0223     inode_dec_link_count(inode);
0224     iput(inode);
0225     return err;
0226 }
0227 
0228 static int ext2_mkdir(struct user_namespace * mnt_userns,
0229     struct inode * dir, struct dentry * dentry, umode_t mode)
0230 {
0231     struct inode * inode;
0232     int err;
0233 
0234     err = dquot_initialize(dir);
0235     if (err)
0236         return err;
0237 
0238     inode_inc_link_count(dir);
0239 
0240     inode = ext2_new_inode(dir, S_IFDIR | mode, &dentry->d_name);
0241     err = PTR_ERR(inode);
0242     if (IS_ERR(inode))
0243         goto out_dir;
0244 
0245     inode->i_op = &ext2_dir_inode_operations;
0246     inode->i_fop = &ext2_dir_operations;
0247     inode->i_mapping->a_ops = &ext2_aops;
0248 
0249     inode_inc_link_count(inode);
0250 
0251     err = ext2_make_empty(inode, dir);
0252     if (err)
0253         goto out_fail;
0254 
0255     err = ext2_add_link(dentry, inode);
0256     if (err)
0257         goto out_fail;
0258 
0259     d_instantiate_new(dentry, inode);
0260 out:
0261     return err;
0262 
0263 out_fail:
0264     inode_dec_link_count(inode);
0265     inode_dec_link_count(inode);
0266     discard_new_inode(inode);
0267 out_dir:
0268     inode_dec_link_count(dir);
0269     goto out;
0270 }
0271 
0272 static int ext2_unlink(struct inode * dir, struct dentry *dentry)
0273 {
0274     struct inode * inode = d_inode(dentry);
0275     struct ext2_dir_entry_2 * de;
0276     struct page * page;
0277     void *page_addr;
0278     int err;
0279 
0280     err = dquot_initialize(dir);
0281     if (err)
0282         goto out;
0283 
0284     de = ext2_find_entry(dir, &dentry->d_name, &page, &page_addr);
0285     if (IS_ERR(de)) {
0286         err = PTR_ERR(de);
0287         goto out;
0288     }
0289 
0290     err = ext2_delete_entry (de, page, page_addr);
0291     ext2_put_page(page, page_addr);
0292     if (err)
0293         goto out;
0294 
0295     inode->i_ctime = dir->i_ctime;
0296     inode_dec_link_count(inode);
0297     err = 0;
0298 out:
0299     return err;
0300 }
0301 
0302 static int ext2_rmdir (struct inode * dir, struct dentry *dentry)
0303 {
0304     struct inode * inode = d_inode(dentry);
0305     int err = -ENOTEMPTY;
0306 
0307     if (ext2_empty_dir(inode)) {
0308         err = ext2_unlink(dir, dentry);
0309         if (!err) {
0310             inode->i_size = 0;
0311             inode_dec_link_count(inode);
0312             inode_dec_link_count(dir);
0313         }
0314     }
0315     return err;
0316 }
0317 
0318 static int ext2_rename (struct user_namespace * mnt_userns,
0319             struct inode * old_dir, struct dentry * old_dentry,
0320             struct inode * new_dir, struct dentry * new_dentry,
0321             unsigned int flags)
0322 {
0323     struct inode * old_inode = d_inode(old_dentry);
0324     struct inode * new_inode = d_inode(new_dentry);
0325     struct page * dir_page = NULL;
0326     void *dir_page_addr;
0327     struct ext2_dir_entry_2 * dir_de = NULL;
0328     struct page * old_page;
0329     void *old_page_addr;
0330     struct ext2_dir_entry_2 * old_de;
0331     int err;
0332 
0333     if (flags & ~RENAME_NOREPLACE)
0334         return -EINVAL;
0335 
0336     err = dquot_initialize(old_dir);
0337     if (err)
0338         goto out;
0339 
0340     err = dquot_initialize(new_dir);
0341     if (err)
0342         goto out;
0343 
0344     old_de = ext2_find_entry(old_dir, &old_dentry->d_name, &old_page,
0345                  &old_page_addr);
0346     if (IS_ERR(old_de)) {
0347         err = PTR_ERR(old_de);
0348         goto out;
0349     }
0350 
0351     if (S_ISDIR(old_inode->i_mode)) {
0352         err = -EIO;
0353         dir_de = ext2_dotdot(old_inode, &dir_page, &dir_page_addr);
0354         if (!dir_de)
0355             goto out_old;
0356     }
0357 
0358     if (new_inode) {
0359         void *page_addr;
0360         struct page *new_page;
0361         struct ext2_dir_entry_2 *new_de;
0362 
0363         err = -ENOTEMPTY;
0364         if (dir_de && !ext2_empty_dir (new_inode))
0365             goto out_dir;
0366 
0367         new_de = ext2_find_entry(new_dir, &new_dentry->d_name,
0368                      &new_page, &page_addr);
0369         if (IS_ERR(new_de)) {
0370             err = PTR_ERR(new_de);
0371             goto out_dir;
0372         }
0373         ext2_set_link(new_dir, new_de, new_page, page_addr, old_inode, 1);
0374         ext2_put_page(new_page, page_addr);
0375         new_inode->i_ctime = current_time(new_inode);
0376         if (dir_de)
0377             drop_nlink(new_inode);
0378         inode_dec_link_count(new_inode);
0379     } else {
0380         err = ext2_add_link(new_dentry, old_inode);
0381         if (err)
0382             goto out_dir;
0383         if (dir_de)
0384             inode_inc_link_count(new_dir);
0385     }
0386 
0387     /*
0388      * Like most other Unix systems, set the ctime for inodes on a
0389      * rename.
0390      */
0391     old_inode->i_ctime = current_time(old_inode);
0392     mark_inode_dirty(old_inode);
0393 
0394     ext2_delete_entry(old_de, old_page, old_page_addr);
0395 
0396     if (dir_de) {
0397         if (old_dir != new_dir)
0398             ext2_set_link(old_inode, dir_de, dir_page,
0399                       dir_page_addr, new_dir, 0);
0400 
0401         ext2_put_page(dir_page, dir_page_addr);
0402         inode_dec_link_count(old_dir);
0403     }
0404 
0405     ext2_put_page(old_page, old_page_addr);
0406     return 0;
0407 
0408 out_dir:
0409     if (dir_de)
0410         ext2_put_page(dir_page, dir_page_addr);
0411 out_old:
0412     ext2_put_page(old_page, old_page_addr);
0413 out:
0414     return err;
0415 }
0416 
0417 const struct inode_operations ext2_dir_inode_operations = {
0418     .create     = ext2_create,
0419     .lookup     = ext2_lookup,
0420     .link       = ext2_link,
0421     .unlink     = ext2_unlink,
0422     .symlink    = ext2_symlink,
0423     .mkdir      = ext2_mkdir,
0424     .rmdir      = ext2_rmdir,
0425     .mknod      = ext2_mknod,
0426     .rename     = ext2_rename,
0427     .listxattr  = ext2_listxattr,
0428     .getattr    = ext2_getattr,
0429     .setattr    = ext2_setattr,
0430     .get_acl    = ext2_get_acl,
0431     .set_acl    = ext2_set_acl,
0432     .tmpfile    = ext2_tmpfile,
0433     .fileattr_get   = ext2_fileattr_get,
0434     .fileattr_set   = ext2_fileattr_set,
0435 };
0436 
0437 const struct inode_operations ext2_special_inode_operations = {
0438     .listxattr  = ext2_listxattr,
0439     .getattr    = ext2_getattr,
0440     .setattr    = ext2_setattr,
0441     .get_acl    = ext2_get_acl,
0442     .set_acl    = ext2_set_acl,
0443 };