diff options
author | Steve French <sfrench@us.ibm.com> | 2006-06-25 11:57:32 -0400 |
---|---|---|
committer | Steve French <sfrench@us.ibm.com> | 2006-06-25 11:57:32 -0400 |
commit | bbe5d235ee201705530a7153b57e141cd77d818b (patch) | |
tree | e98c31b4cb2ced6357a87a02596f9ecdbd6dbb26 /fs/jffs2/dir.c | |
parent | 189acaaef81b1d71aedd0d28810de24160c2e781 (diff) | |
parent | dfd8317d3340f03bc06eba6b58f0ec0861da4a13 (diff) |
Merge with /pub/scm/linux/kernel/git/torvalds/linux-2.6.git
Diffstat (limited to 'fs/jffs2/dir.c')
-rw-r--r-- | fs/jffs2/dir.c | 121 |
1 files changed, 86 insertions, 35 deletions
diff --git a/fs/jffs2/dir.c b/fs/jffs2/dir.c index 8bc7a5018e40..edd8371fc6a5 100644 --- a/fs/jffs2/dir.c +++ b/fs/jffs2/dir.c | |||
@@ -17,8 +17,8 @@ | |||
17 | #include <linux/fs.h> | 17 | #include <linux/fs.h> |
18 | #include <linux/crc32.h> | 18 | #include <linux/crc32.h> |
19 | #include <linux/jffs2.h> | 19 | #include <linux/jffs2.h> |
20 | #include <linux/jffs2_fs_i.h> | 20 | #include "jffs2_fs_i.h" |
21 | #include <linux/jffs2_fs_sb.h> | 21 | #include "jffs2_fs_sb.h" |
22 | #include <linux/time.h> | 22 | #include <linux/time.h> |
23 | #include "nodelist.h" | 23 | #include "nodelist.h" |
24 | 24 | ||
@@ -57,7 +57,12 @@ struct inode_operations jffs2_dir_inode_operations = | |||
57 | .rmdir = jffs2_rmdir, | 57 | .rmdir = jffs2_rmdir, |
58 | .mknod = jffs2_mknod, | 58 | .mknod = jffs2_mknod, |
59 | .rename = jffs2_rename, | 59 | .rename = jffs2_rename, |
60 | .permission = jffs2_permission, | ||
60 | .setattr = jffs2_setattr, | 61 | .setattr = jffs2_setattr, |
62 | .setxattr = jffs2_setxattr, | ||
63 | .getxattr = jffs2_getxattr, | ||
64 | .listxattr = jffs2_listxattr, | ||
65 | .removexattr = jffs2_removexattr | ||
61 | }; | 66 | }; |
62 | 67 | ||
63 | /***********************************************************************/ | 68 | /***********************************************************************/ |
@@ -78,6 +83,9 @@ static struct dentry *jffs2_lookup(struct inode *dir_i, struct dentry *target, | |||
78 | 83 | ||
79 | D1(printk(KERN_DEBUG "jffs2_lookup()\n")); | 84 | D1(printk(KERN_DEBUG "jffs2_lookup()\n")); |
80 | 85 | ||
86 | if (target->d_name.len > JFFS2_MAX_NAME_LEN) | ||
87 | return ERR_PTR(-ENAMETOOLONG); | ||
88 | |||
81 | dir_f = JFFS2_INODE_INFO(dir_i); | 89 | dir_f = JFFS2_INODE_INFO(dir_i); |
82 | c = JFFS2_SB_INFO(dir_i->i_sb); | 90 | c = JFFS2_SB_INFO(dir_i->i_sb); |
83 | 91 | ||
@@ -206,12 +214,15 @@ static int jffs2_create(struct inode *dir_i, struct dentry *dentry, int mode, | |||
206 | ret = jffs2_do_create(c, dir_f, f, ri, | 214 | ret = jffs2_do_create(c, dir_f, f, ri, |
207 | dentry->d_name.name, dentry->d_name.len); | 215 | dentry->d_name.name, dentry->d_name.len); |
208 | 216 | ||
209 | if (ret) { | 217 | if (ret) |
210 | make_bad_inode(inode); | 218 | goto fail; |
211 | iput(inode); | 219 | |
212 | jffs2_free_raw_inode(ri); | 220 | ret = jffs2_init_security(inode, dir_i); |
213 | return ret; | 221 | if (ret) |
214 | } | 222 | goto fail; |
223 | ret = jffs2_init_acl(inode, dir_i); | ||
224 | if (ret) | ||
225 | goto fail; | ||
215 | 226 | ||
216 | dir_i->i_mtime = dir_i->i_ctime = ITIME(je32_to_cpu(ri->ctime)); | 227 | dir_i->i_mtime = dir_i->i_ctime = ITIME(je32_to_cpu(ri->ctime)); |
217 | 228 | ||
@@ -221,6 +232,12 @@ static int jffs2_create(struct inode *dir_i, struct dentry *dentry, int mode, | |||
221 | D1(printk(KERN_DEBUG "jffs2_create: Created ino #%lu with mode %o, nlink %d(%d). nrpages %ld\n", | 232 | D1(printk(KERN_DEBUG "jffs2_create: Created ino #%lu with mode %o, nlink %d(%d). nrpages %ld\n", |
222 | inode->i_ino, inode->i_mode, inode->i_nlink, f->inocache->nlink, inode->i_mapping->nrpages)); | 233 | inode->i_ino, inode->i_mode, inode->i_nlink, f->inocache->nlink, inode->i_mapping->nrpages)); |
223 | return 0; | 234 | return 0; |
235 | |||
236 | fail: | ||
237 | make_bad_inode(inode); | ||
238 | iput(inode); | ||
239 | jffs2_free_raw_inode(ri); | ||
240 | return ret; | ||
224 | } | 241 | } |
225 | 242 | ||
226 | /***********************************************************************/ | 243 | /***********************************************************************/ |
@@ -291,7 +308,7 @@ static int jffs2_symlink (struct inode *dir_i, struct dentry *dentry, const char | |||
291 | struct jffs2_full_dnode *fn; | 308 | struct jffs2_full_dnode *fn; |
292 | struct jffs2_full_dirent *fd; | 309 | struct jffs2_full_dirent *fd; |
293 | int namelen; | 310 | int namelen; |
294 | uint32_t alloclen, phys_ofs; | 311 | uint32_t alloclen; |
295 | int ret, targetlen = strlen(target); | 312 | int ret, targetlen = strlen(target); |
296 | 313 | ||
297 | /* FIXME: If you care. We'd need to use frags for the target | 314 | /* FIXME: If you care. We'd need to use frags for the target |
@@ -310,8 +327,8 @@ static int jffs2_symlink (struct inode *dir_i, struct dentry *dentry, const char | |||
310 | * Just the node will do for now, though | 327 | * Just the node will do for now, though |
311 | */ | 328 | */ |
312 | namelen = dentry->d_name.len; | 329 | namelen = dentry->d_name.len; |
313 | ret = jffs2_reserve_space(c, sizeof(*ri) + targetlen, &phys_ofs, &alloclen, | 330 | ret = jffs2_reserve_space(c, sizeof(*ri) + targetlen, &alloclen, |
314 | ALLOC_NORMAL, JFFS2_SUMMARY_INODE_SIZE); | 331 | ALLOC_NORMAL, JFFS2_SUMMARY_INODE_SIZE); |
315 | 332 | ||
316 | if (ret) { | 333 | if (ret) { |
317 | jffs2_free_raw_inode(ri); | 334 | jffs2_free_raw_inode(ri); |
@@ -339,7 +356,7 @@ static int jffs2_symlink (struct inode *dir_i, struct dentry *dentry, const char | |||
339 | ri->data_crc = cpu_to_je32(crc32(0, target, targetlen)); | 356 | ri->data_crc = cpu_to_je32(crc32(0, target, targetlen)); |
340 | ri->node_crc = cpu_to_je32(crc32(0, ri, sizeof(*ri)-8)); | 357 | ri->node_crc = cpu_to_je32(crc32(0, ri, sizeof(*ri)-8)); |
341 | 358 | ||
342 | fn = jffs2_write_dnode(c, f, ri, target, targetlen, phys_ofs, ALLOC_NORMAL); | 359 | fn = jffs2_write_dnode(c, f, ri, target, targetlen, ALLOC_NORMAL); |
343 | 360 | ||
344 | jffs2_free_raw_inode(ri); | 361 | jffs2_free_raw_inode(ri); |
345 | 362 | ||
@@ -371,8 +388,20 @@ static int jffs2_symlink (struct inode *dir_i, struct dentry *dentry, const char | |||
371 | up(&f->sem); | 388 | up(&f->sem); |
372 | 389 | ||
373 | jffs2_complete_reservation(c); | 390 | jffs2_complete_reservation(c); |
374 | ret = jffs2_reserve_space(c, sizeof(*rd)+namelen, &phys_ofs, &alloclen, | 391 | |
375 | ALLOC_NORMAL, JFFS2_SUMMARY_DIRENT_SIZE(namelen)); | 392 | ret = jffs2_init_security(inode, dir_i); |
393 | if (ret) { | ||
394 | jffs2_clear_inode(inode); | ||
395 | return ret; | ||
396 | } | ||
397 | ret = jffs2_init_acl(inode, dir_i); | ||
398 | if (ret) { | ||
399 | jffs2_clear_inode(inode); | ||
400 | return ret; | ||
401 | } | ||
402 | |||
403 | ret = jffs2_reserve_space(c, sizeof(*rd)+namelen, &alloclen, | ||
404 | ALLOC_NORMAL, JFFS2_SUMMARY_DIRENT_SIZE(namelen)); | ||
376 | if (ret) { | 405 | if (ret) { |
377 | /* Eep. */ | 406 | /* Eep. */ |
378 | jffs2_clear_inode(inode); | 407 | jffs2_clear_inode(inode); |
@@ -404,7 +433,7 @@ static int jffs2_symlink (struct inode *dir_i, struct dentry *dentry, const char | |||
404 | rd->node_crc = cpu_to_je32(crc32(0, rd, sizeof(*rd)-8)); | 433 | rd->node_crc = cpu_to_je32(crc32(0, rd, sizeof(*rd)-8)); |
405 | rd->name_crc = cpu_to_je32(crc32(0, dentry->d_name.name, namelen)); | 434 | rd->name_crc = cpu_to_je32(crc32(0, dentry->d_name.name, namelen)); |
406 | 435 | ||
407 | fd = jffs2_write_dirent(c, dir_f, rd, dentry->d_name.name, namelen, phys_ofs, ALLOC_NORMAL); | 436 | fd = jffs2_write_dirent(c, dir_f, rd, dentry->d_name.name, namelen, ALLOC_NORMAL); |
408 | 437 | ||
409 | if (IS_ERR(fd)) { | 438 | if (IS_ERR(fd)) { |
410 | /* dirent failed to write. Delete the inode normally | 439 | /* dirent failed to write. Delete the inode normally |
@@ -442,7 +471,7 @@ static int jffs2_mkdir (struct inode *dir_i, struct dentry *dentry, int mode) | |||
442 | struct jffs2_full_dnode *fn; | 471 | struct jffs2_full_dnode *fn; |
443 | struct jffs2_full_dirent *fd; | 472 | struct jffs2_full_dirent *fd; |
444 | int namelen; | 473 | int namelen; |
445 | uint32_t alloclen, phys_ofs; | 474 | uint32_t alloclen; |
446 | int ret; | 475 | int ret; |
447 | 476 | ||
448 | mode |= S_IFDIR; | 477 | mode |= S_IFDIR; |
@@ -457,8 +486,8 @@ static int jffs2_mkdir (struct inode *dir_i, struct dentry *dentry, int mode) | |||
457 | * Just the node will do for now, though | 486 | * Just the node will do for now, though |
458 | */ | 487 | */ |
459 | namelen = dentry->d_name.len; | 488 | namelen = dentry->d_name.len; |
460 | ret = jffs2_reserve_space(c, sizeof(*ri), &phys_ofs, &alloclen, ALLOC_NORMAL, | 489 | ret = jffs2_reserve_space(c, sizeof(*ri), &alloclen, ALLOC_NORMAL, |
461 | JFFS2_SUMMARY_INODE_SIZE); | 490 | JFFS2_SUMMARY_INODE_SIZE); |
462 | 491 | ||
463 | if (ret) { | 492 | if (ret) { |
464 | jffs2_free_raw_inode(ri); | 493 | jffs2_free_raw_inode(ri); |
@@ -483,7 +512,7 @@ static int jffs2_mkdir (struct inode *dir_i, struct dentry *dentry, int mode) | |||
483 | ri->data_crc = cpu_to_je32(0); | 512 | ri->data_crc = cpu_to_je32(0); |
484 | ri->node_crc = cpu_to_je32(crc32(0, ri, sizeof(*ri)-8)); | 513 | ri->node_crc = cpu_to_je32(crc32(0, ri, sizeof(*ri)-8)); |
485 | 514 | ||
486 | fn = jffs2_write_dnode(c, f, ri, NULL, 0, phys_ofs, ALLOC_NORMAL); | 515 | fn = jffs2_write_dnode(c, f, ri, NULL, 0, ALLOC_NORMAL); |
487 | 516 | ||
488 | jffs2_free_raw_inode(ri); | 517 | jffs2_free_raw_inode(ri); |
489 | 518 | ||
@@ -501,8 +530,20 @@ static int jffs2_mkdir (struct inode *dir_i, struct dentry *dentry, int mode) | |||
501 | up(&f->sem); | 530 | up(&f->sem); |
502 | 531 | ||
503 | jffs2_complete_reservation(c); | 532 | jffs2_complete_reservation(c); |
504 | ret = jffs2_reserve_space(c, sizeof(*rd)+namelen, &phys_ofs, &alloclen, | 533 | |
505 | ALLOC_NORMAL, JFFS2_SUMMARY_DIRENT_SIZE(namelen)); | 534 | ret = jffs2_init_security(inode, dir_i); |
535 | if (ret) { | ||
536 | jffs2_clear_inode(inode); | ||
537 | return ret; | ||
538 | } | ||
539 | ret = jffs2_init_acl(inode, dir_i); | ||
540 | if (ret) { | ||
541 | jffs2_clear_inode(inode); | ||
542 | return ret; | ||
543 | } | ||
544 | |||
545 | ret = jffs2_reserve_space(c, sizeof(*rd)+namelen, &alloclen, | ||
546 | ALLOC_NORMAL, JFFS2_SUMMARY_DIRENT_SIZE(namelen)); | ||
506 | if (ret) { | 547 | if (ret) { |
507 | /* Eep. */ | 548 | /* Eep. */ |
508 | jffs2_clear_inode(inode); | 549 | jffs2_clear_inode(inode); |
@@ -534,7 +575,7 @@ static int jffs2_mkdir (struct inode *dir_i, struct dentry *dentry, int mode) | |||
534 | rd->node_crc = cpu_to_je32(crc32(0, rd, sizeof(*rd)-8)); | 575 | rd->node_crc = cpu_to_je32(crc32(0, rd, sizeof(*rd)-8)); |
535 | rd->name_crc = cpu_to_je32(crc32(0, dentry->d_name.name, namelen)); | 576 | rd->name_crc = cpu_to_je32(crc32(0, dentry->d_name.name, namelen)); |
536 | 577 | ||
537 | fd = jffs2_write_dirent(c, dir_f, rd, dentry->d_name.name, namelen, phys_ofs, ALLOC_NORMAL); | 578 | fd = jffs2_write_dirent(c, dir_f, rd, dentry->d_name.name, namelen, ALLOC_NORMAL); |
538 | 579 | ||
539 | if (IS_ERR(fd)) { | 580 | if (IS_ERR(fd)) { |
540 | /* dirent failed to write. Delete the inode normally | 581 | /* dirent failed to write. Delete the inode normally |
@@ -588,12 +629,12 @@ static int jffs2_mknod (struct inode *dir_i, struct dentry *dentry, int mode, de | |||
588 | struct jffs2_full_dnode *fn; | 629 | struct jffs2_full_dnode *fn; |
589 | struct jffs2_full_dirent *fd; | 630 | struct jffs2_full_dirent *fd; |
590 | int namelen; | 631 | int namelen; |
591 | jint16_t dev; | 632 | union jffs2_device_node dev; |
592 | int devlen = 0; | 633 | int devlen = 0; |
593 | uint32_t alloclen, phys_ofs; | 634 | uint32_t alloclen; |
594 | int ret; | 635 | int ret; |
595 | 636 | ||
596 | if (!old_valid_dev(rdev)) | 637 | if (!new_valid_dev(rdev)) |
597 | return -EINVAL; | 638 | return -EINVAL; |
598 | 639 | ||
599 | ri = jffs2_alloc_raw_inode(); | 640 | ri = jffs2_alloc_raw_inode(); |
@@ -602,17 +643,15 @@ static int jffs2_mknod (struct inode *dir_i, struct dentry *dentry, int mode, de | |||
602 | 643 | ||
603 | c = JFFS2_SB_INFO(dir_i->i_sb); | 644 | c = JFFS2_SB_INFO(dir_i->i_sb); |
604 | 645 | ||
605 | if (S_ISBLK(mode) || S_ISCHR(mode)) { | 646 | if (S_ISBLK(mode) || S_ISCHR(mode)) |
606 | dev = cpu_to_je16(old_encode_dev(rdev)); | 647 | devlen = jffs2_encode_dev(&dev, rdev); |
607 | devlen = sizeof(dev); | ||
608 | } | ||
609 | 648 | ||
610 | /* Try to reserve enough space for both node and dirent. | 649 | /* Try to reserve enough space for both node and dirent. |
611 | * Just the node will do for now, though | 650 | * Just the node will do for now, though |
612 | */ | 651 | */ |
613 | namelen = dentry->d_name.len; | 652 | namelen = dentry->d_name.len; |
614 | ret = jffs2_reserve_space(c, sizeof(*ri) + devlen, &phys_ofs, &alloclen, | 653 | ret = jffs2_reserve_space(c, sizeof(*ri) + devlen, &alloclen, |
615 | ALLOC_NORMAL, JFFS2_SUMMARY_INODE_SIZE); | 654 | ALLOC_NORMAL, JFFS2_SUMMARY_INODE_SIZE); |
616 | 655 | ||
617 | if (ret) { | 656 | if (ret) { |
618 | jffs2_free_raw_inode(ri); | 657 | jffs2_free_raw_inode(ri); |
@@ -639,7 +678,7 @@ static int jffs2_mknod (struct inode *dir_i, struct dentry *dentry, int mode, de | |||
639 | ri->data_crc = cpu_to_je32(crc32(0, &dev, devlen)); | 678 | ri->data_crc = cpu_to_je32(crc32(0, &dev, devlen)); |
640 | ri->node_crc = cpu_to_je32(crc32(0, ri, sizeof(*ri)-8)); | 679 | ri->node_crc = cpu_to_je32(crc32(0, ri, sizeof(*ri)-8)); |
641 | 680 | ||
642 | fn = jffs2_write_dnode(c, f, ri, (char *)&dev, devlen, phys_ofs, ALLOC_NORMAL); | 681 | fn = jffs2_write_dnode(c, f, ri, (char *)&dev, devlen, ALLOC_NORMAL); |
643 | 682 | ||
644 | jffs2_free_raw_inode(ri); | 683 | jffs2_free_raw_inode(ri); |
645 | 684 | ||
@@ -657,8 +696,20 @@ static int jffs2_mknod (struct inode *dir_i, struct dentry *dentry, int mode, de | |||
657 | up(&f->sem); | 696 | up(&f->sem); |
658 | 697 | ||
659 | jffs2_complete_reservation(c); | 698 | jffs2_complete_reservation(c); |
660 | ret = jffs2_reserve_space(c, sizeof(*rd)+namelen, &phys_ofs, &alloclen, | 699 | |
661 | ALLOC_NORMAL, JFFS2_SUMMARY_DIRENT_SIZE(namelen)); | 700 | ret = jffs2_init_security(inode, dir_i); |
701 | if (ret) { | ||
702 | jffs2_clear_inode(inode); | ||
703 | return ret; | ||
704 | } | ||
705 | ret = jffs2_init_acl(inode, dir_i); | ||
706 | if (ret) { | ||
707 | jffs2_clear_inode(inode); | ||
708 | return ret; | ||
709 | } | ||
710 | |||
711 | ret = jffs2_reserve_space(c, sizeof(*rd)+namelen, &alloclen, | ||
712 | ALLOC_NORMAL, JFFS2_SUMMARY_DIRENT_SIZE(namelen)); | ||
662 | if (ret) { | 713 | if (ret) { |
663 | /* Eep. */ | 714 | /* Eep. */ |
664 | jffs2_clear_inode(inode); | 715 | jffs2_clear_inode(inode); |
@@ -693,7 +744,7 @@ static int jffs2_mknod (struct inode *dir_i, struct dentry *dentry, int mode, de | |||
693 | rd->node_crc = cpu_to_je32(crc32(0, rd, sizeof(*rd)-8)); | 744 | rd->node_crc = cpu_to_je32(crc32(0, rd, sizeof(*rd)-8)); |
694 | rd->name_crc = cpu_to_je32(crc32(0, dentry->d_name.name, namelen)); | 745 | rd->name_crc = cpu_to_je32(crc32(0, dentry->d_name.name, namelen)); |
695 | 746 | ||
696 | fd = jffs2_write_dirent(c, dir_f, rd, dentry->d_name.name, namelen, phys_ofs, ALLOC_NORMAL); | 747 | fd = jffs2_write_dirent(c, dir_f, rd, dentry->d_name.name, namelen, ALLOC_NORMAL); |
697 | 748 | ||
698 | if (IS_ERR(fd)) { | 749 | if (IS_ERR(fd)) { |
699 | /* dirent failed to write. Delete the inode normally | 750 | /* dirent failed to write. Delete the inode normally |