0001
0002
0003
0004
0005
0006
0007
0008
0009
0010
0011
0012
0013
0014
0015
0016
0017
0018
0019
0020
0021
0022
0023
0024
0025
0026
0027
0028
0029
0030
0031
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
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
0096
0097
0098
0099
0100
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
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
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
0389
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 };