diff options
author | Andrea Bastoni <bastoni@cs.unc.edu> | 2010-05-30 19:16:45 -0400 |
---|---|---|
committer | Andrea Bastoni <bastoni@cs.unc.edu> | 2010-05-30 19:16:45 -0400 |
commit | ada47b5fe13d89735805b566185f4885f5a3f750 (patch) | |
tree | 644b88f8a71896307d71438e9b3af49126ffb22b /fs/udf/namei.c | |
parent | 43e98717ad40a4ae64545b5ba047c7b86aa44f4f (diff) | |
parent | 3280f21d43ee541f97f8cda5792150d2dbec20d5 (diff) |
Merge branch 'wip-2.6.34' into old-private-masterarchived-private-master
Diffstat (limited to 'fs/udf/namei.c')
-rw-r--r-- | fs/udf/namei.c | 84 |
1 files changed, 63 insertions, 21 deletions
diff --git a/fs/udf/namei.c b/fs/udf/namei.c index 21dad8c608f9..75816025f95f 100644 --- a/fs/udf/namei.c +++ b/fs/udf/namei.c | |||
@@ -34,8 +34,8 @@ | |||
34 | #include <linux/crc-itu-t.h> | 34 | #include <linux/crc-itu-t.h> |
35 | #include <linux/exportfs.h> | 35 | #include <linux/exportfs.h> |
36 | 36 | ||
37 | static inline int udf_match(int len1, const char *name1, int len2, | 37 | static inline int udf_match(int len1, const unsigned char *name1, int len2, |
38 | const char *name2) | 38 | const unsigned char *name2) |
39 | { | 39 | { |
40 | if (len1 != len2) | 40 | if (len1 != len2) |
41 | return 0; | 41 | return 0; |
@@ -142,15 +142,15 @@ int udf_write_fi(struct inode *inode, struct fileIdentDesc *cfi, | |||
142 | } | 142 | } |
143 | 143 | ||
144 | static struct fileIdentDesc *udf_find_entry(struct inode *dir, | 144 | static struct fileIdentDesc *udf_find_entry(struct inode *dir, |
145 | struct qstr *child, | 145 | const struct qstr *child, |
146 | struct udf_fileident_bh *fibh, | 146 | struct udf_fileident_bh *fibh, |
147 | struct fileIdentDesc *cfi) | 147 | struct fileIdentDesc *cfi) |
148 | { | 148 | { |
149 | struct fileIdentDesc *fi = NULL; | 149 | struct fileIdentDesc *fi = NULL; |
150 | loff_t f_pos; | 150 | loff_t f_pos; |
151 | int block, flen; | 151 | int block, flen; |
152 | char *fname = NULL; | 152 | unsigned char *fname = NULL; |
153 | char *nameptr; | 153 | unsigned char *nameptr; |
154 | uint8_t lfi; | 154 | uint8_t lfi; |
155 | uint16_t liu; | 155 | uint16_t liu; |
156 | loff_t size; | 156 | loff_t size; |
@@ -308,7 +308,7 @@ static struct fileIdentDesc *udf_add_entry(struct inode *dir, | |||
308 | { | 308 | { |
309 | struct super_block *sb = dir->i_sb; | 309 | struct super_block *sb = dir->i_sb; |
310 | struct fileIdentDesc *fi = NULL; | 310 | struct fileIdentDesc *fi = NULL; |
311 | char *name = NULL; | 311 | unsigned char *name = NULL; |
312 | int namelen; | 312 | int namelen; |
313 | loff_t f_pos; | 313 | loff_t f_pos; |
314 | loff_t size = udf_ext0_offset(dir) + dir->i_size; | 314 | loff_t size = udf_ext0_offset(dir) + dir->i_size; |
@@ -408,15 +408,6 @@ static struct fileIdentDesc *udf_add_entry(struct inode *dir, | |||
408 | } | 408 | } |
409 | 409 | ||
410 | add: | 410 | add: |
411 | /* Is there any extent whose size we need to round up? */ | ||
412 | if (dinfo->i_alloc_type != ICBTAG_FLAG_AD_IN_ICB && elen) { | ||
413 | elen = (elen + sb->s_blocksize - 1) & ~(sb->s_blocksize - 1); | ||
414 | if (dinfo->i_alloc_type == ICBTAG_FLAG_AD_SHORT) | ||
415 | epos.offset -= sizeof(struct short_ad); | ||
416 | else if (dinfo->i_alloc_type == ICBTAG_FLAG_AD_LONG) | ||
417 | epos.offset -= sizeof(struct long_ad); | ||
418 | udf_write_aext(dir, &epos, &eloc, elen, 1); | ||
419 | } | ||
420 | f_pos += nfidlen; | 411 | f_pos += nfidlen; |
421 | 412 | ||
422 | if (dinfo->i_alloc_type == ICBTAG_FLAG_AD_IN_ICB && | 413 | if (dinfo->i_alloc_type == ICBTAG_FLAG_AD_IN_ICB && |
@@ -439,6 +430,7 @@ add: | |||
439 | udf_current_aext(dir, &epos, &eloc, &elen, 1); | 430 | udf_current_aext(dir, &epos, &eloc, &elen, 1); |
440 | } | 431 | } |
441 | 432 | ||
433 | /* Entry fits into current block? */ | ||
442 | if (sb->s_blocksize - fibh->eoffset >= nfidlen) { | 434 | if (sb->s_blocksize - fibh->eoffset >= nfidlen) { |
443 | fibh->soffset = fibh->eoffset; | 435 | fibh->soffset = fibh->eoffset; |
444 | fibh->eoffset += nfidlen; | 436 | fibh->eoffset += nfidlen; |
@@ -462,6 +454,16 @@ add: | |||
462 | (fibh->sbh->b_data + fibh->soffset); | 454 | (fibh->sbh->b_data + fibh->soffset); |
463 | } | 455 | } |
464 | } else { | 456 | } else { |
457 | /* Round up last extent in the file */ | ||
458 | elen = (elen + sb->s_blocksize - 1) & ~(sb->s_blocksize - 1); | ||
459 | if (dinfo->i_alloc_type == ICBTAG_FLAG_AD_SHORT) | ||
460 | epos.offset -= sizeof(struct short_ad); | ||
461 | else if (dinfo->i_alloc_type == ICBTAG_FLAG_AD_LONG) | ||
462 | epos.offset -= sizeof(struct long_ad); | ||
463 | udf_write_aext(dir, &epos, &eloc, elen, 1); | ||
464 | dinfo->i_lenExtents = (dinfo->i_lenExtents + sb->s_blocksize | ||
465 | - 1) & ~(sb->s_blocksize - 1); | ||
466 | |||
465 | fibh->soffset = fibh->eoffset - sb->s_blocksize; | 467 | fibh->soffset = fibh->eoffset - sb->s_blocksize; |
466 | fibh->eoffset += nfidlen - sb->s_blocksize; | 468 | fibh->eoffset += nfidlen - sb->s_blocksize; |
467 | if (fibh->sbh != fibh->ebh) { | 469 | if (fibh->sbh != fibh->ebh) { |
@@ -508,6 +510,20 @@ add: | |||
508 | dir->i_size += nfidlen; | 510 | dir->i_size += nfidlen; |
509 | if (dinfo->i_alloc_type == ICBTAG_FLAG_AD_IN_ICB) | 511 | if (dinfo->i_alloc_type == ICBTAG_FLAG_AD_IN_ICB) |
510 | dinfo->i_lenAlloc += nfidlen; | 512 | dinfo->i_lenAlloc += nfidlen; |
513 | else { | ||
514 | /* Find the last extent and truncate it to proper size */ | ||
515 | while (udf_next_aext(dir, &epos, &eloc, &elen, 1) == | ||
516 | (EXT_RECORDED_ALLOCATED >> 30)) | ||
517 | ; | ||
518 | elen -= dinfo->i_lenExtents - dir->i_size; | ||
519 | if (dinfo->i_alloc_type == ICBTAG_FLAG_AD_SHORT) | ||
520 | epos.offset -= sizeof(struct short_ad); | ||
521 | else if (dinfo->i_alloc_type == ICBTAG_FLAG_AD_LONG) | ||
522 | epos.offset -= sizeof(struct long_ad); | ||
523 | udf_write_aext(dir, &epos, &eloc, elen, 1); | ||
524 | dinfo->i_lenExtents = dir->i_size; | ||
525 | } | ||
526 | |||
511 | mark_inode_dirty(dir); | 527 | mark_inode_dirty(dir); |
512 | goto out_ok; | 528 | goto out_ok; |
513 | } else { | 529 | } else { |
@@ -547,6 +563,8 @@ static int udf_create(struct inode *dir, struct dentry *dentry, int mode, | |||
547 | int err; | 563 | int err; |
548 | struct udf_inode_info *iinfo; | 564 | struct udf_inode_info *iinfo; |
549 | 565 | ||
566 | dquot_initialize(dir); | ||
567 | |||
550 | lock_kernel(); | 568 | lock_kernel(); |
551 | inode = udf_new_inode(dir, mode, &err); | 569 | inode = udf_new_inode(dir, mode, &err); |
552 | if (!inode) { | 570 | if (!inode) { |
@@ -600,6 +618,8 @@ static int udf_mknod(struct inode *dir, struct dentry *dentry, int mode, | |||
600 | if (!old_valid_dev(rdev)) | 618 | if (!old_valid_dev(rdev)) |
601 | return -EINVAL; | 619 | return -EINVAL; |
602 | 620 | ||
621 | dquot_initialize(dir); | ||
622 | |||
603 | lock_kernel(); | 623 | lock_kernel(); |
604 | err = -EIO; | 624 | err = -EIO; |
605 | inode = udf_new_inode(dir, mode, &err); | 625 | inode = udf_new_inode(dir, mode, &err); |
@@ -646,6 +666,8 @@ static int udf_mkdir(struct inode *dir, struct dentry *dentry, int mode) | |||
646 | struct udf_inode_info *dinfo = UDF_I(dir); | 666 | struct udf_inode_info *dinfo = UDF_I(dir); |
647 | struct udf_inode_info *iinfo; | 667 | struct udf_inode_info *iinfo; |
648 | 668 | ||
669 | dquot_initialize(dir); | ||
670 | |||
649 | lock_kernel(); | 671 | lock_kernel(); |
650 | err = -EMLINK; | 672 | err = -EMLINK; |
651 | if (dir->i_nlink >= (256 << sizeof(dir->i_nlink)) - 1) | 673 | if (dir->i_nlink >= (256 << sizeof(dir->i_nlink)) - 1) |
@@ -783,6 +805,8 @@ static int udf_rmdir(struct inode *dir, struct dentry *dentry) | |||
783 | struct fileIdentDesc *fi, cfi; | 805 | struct fileIdentDesc *fi, cfi; |
784 | struct kernel_lb_addr tloc; | 806 | struct kernel_lb_addr tloc; |
785 | 807 | ||
808 | dquot_initialize(dir); | ||
809 | |||
786 | retval = -ENOENT; | 810 | retval = -ENOENT; |
787 | lock_kernel(); | 811 | lock_kernel(); |
788 | fi = udf_find_entry(dir, &dentry->d_name, &fibh, &cfi); | 812 | fi = udf_find_entry(dir, &dentry->d_name, &fibh, &cfi); |
@@ -829,6 +853,8 @@ static int udf_unlink(struct inode *dir, struct dentry *dentry) | |||
829 | struct fileIdentDesc cfi; | 853 | struct fileIdentDesc cfi; |
830 | struct kernel_lb_addr tloc; | 854 | struct kernel_lb_addr tloc; |
831 | 855 | ||
856 | dquot_initialize(dir); | ||
857 | |||
832 | retval = -ENOENT; | 858 | retval = -ENOENT; |
833 | lock_kernel(); | 859 | lock_kernel(); |
834 | fi = udf_find_entry(dir, &dentry->d_name, &fibh, &cfi); | 860 | fi = udf_find_entry(dir, &dentry->d_name, &fibh, &cfi); |
@@ -869,20 +895,22 @@ static int udf_symlink(struct inode *dir, struct dentry *dentry, | |||
869 | { | 895 | { |
870 | struct inode *inode; | 896 | struct inode *inode; |
871 | struct pathComponent *pc; | 897 | struct pathComponent *pc; |
872 | char *compstart; | 898 | const char *compstart; |
873 | struct udf_fileident_bh fibh; | 899 | struct udf_fileident_bh fibh; |
874 | struct extent_position epos = {}; | 900 | struct extent_position epos = {}; |
875 | int eoffset, elen = 0; | 901 | int eoffset, elen = 0; |
876 | struct fileIdentDesc *fi; | 902 | struct fileIdentDesc *fi; |
877 | struct fileIdentDesc cfi; | 903 | struct fileIdentDesc cfi; |
878 | char *ea; | 904 | uint8_t *ea; |
879 | int err; | 905 | int err; |
880 | int block; | 906 | int block; |
881 | char *name = NULL; | 907 | unsigned char *name = NULL; |
882 | int namelen; | 908 | int namelen; |
883 | struct buffer_head *bh; | 909 | struct buffer_head *bh; |
884 | struct udf_inode_info *iinfo; | 910 | struct udf_inode_info *iinfo; |
885 | 911 | ||
912 | dquot_initialize(dir); | ||
913 | |||
886 | lock_kernel(); | 914 | lock_kernel(); |
887 | inode = udf_new_inode(dir, S_IFLNK, &err); | 915 | inode = udf_new_inode(dir, S_IFLNK, &err); |
888 | if (!inode) | 916 | if (!inode) |
@@ -897,7 +925,7 @@ static int udf_symlink(struct inode *dir, struct dentry *dentry, | |||
897 | iinfo = UDF_I(inode); | 925 | iinfo = UDF_I(inode); |
898 | inode->i_mode = S_IFLNK | S_IRWXUGO; | 926 | inode->i_mode = S_IFLNK | S_IRWXUGO; |
899 | inode->i_data.a_ops = &udf_symlink_aops; | 927 | inode->i_data.a_ops = &udf_symlink_aops; |
900 | inode->i_op = &page_symlink_inode_operations; | 928 | inode->i_op = &udf_symlink_inode_operations; |
901 | 929 | ||
902 | if (iinfo->i_alloc_type != ICBTAG_FLAG_AD_IN_ICB) { | 930 | if (iinfo->i_alloc_type != ICBTAG_FLAG_AD_IN_ICB) { |
903 | struct kernel_lb_addr eloc; | 931 | struct kernel_lb_addr eloc; |
@@ -922,7 +950,7 @@ static int udf_symlink(struct inode *dir, struct dentry *dentry, | |||
922 | block = udf_get_pblock(inode->i_sb, block, | 950 | block = udf_get_pblock(inode->i_sb, block, |
923 | iinfo->i_location.partitionReferenceNum, | 951 | iinfo->i_location.partitionReferenceNum, |
924 | 0); | 952 | 0); |
925 | epos.bh = udf_tread(inode->i_sb, block); | 953 | epos.bh = udf_tgetblk(inode->i_sb, block); |
926 | lock_buffer(epos.bh); | 954 | lock_buffer(epos.bh); |
927 | memset(epos.bh->b_data, 0x00, inode->i_sb->s_blocksize); | 955 | memset(epos.bh->b_data, 0x00, inode->i_sb->s_blocksize); |
928 | set_buffer_uptodate(epos.bh); | 956 | set_buffer_uptodate(epos.bh); |
@@ -954,7 +982,7 @@ static int udf_symlink(struct inode *dir, struct dentry *dentry, | |||
954 | 982 | ||
955 | pc = (struct pathComponent *)(ea + elen); | 983 | pc = (struct pathComponent *)(ea + elen); |
956 | 984 | ||
957 | compstart = (char *)symname; | 985 | compstart = symname; |
958 | 986 | ||
959 | do { | 987 | do { |
960 | symname++; | 988 | symname++; |
@@ -999,6 +1027,8 @@ static int udf_symlink(struct inode *dir, struct dentry *dentry, | |||
999 | inode->i_size = elen; | 1027 | inode->i_size = elen; |
1000 | if (iinfo->i_alloc_type == ICBTAG_FLAG_AD_IN_ICB) | 1028 | if (iinfo->i_alloc_type == ICBTAG_FLAG_AD_IN_ICB) |
1001 | iinfo->i_lenAlloc = inode->i_size; | 1029 | iinfo->i_lenAlloc = inode->i_size; |
1030 | else | ||
1031 | udf_truncate_tail_extent(inode); | ||
1002 | mark_inode_dirty(inode); | 1032 | mark_inode_dirty(inode); |
1003 | 1033 | ||
1004 | fi = udf_add_entry(dir, dentry, &fibh, &cfi, &err); | 1034 | fi = udf_add_entry(dir, dentry, &fibh, &cfi, &err); |
@@ -1051,6 +1081,8 @@ static int udf_link(struct dentry *old_dentry, struct inode *dir, | |||
1051 | int err; | 1081 | int err; |
1052 | struct buffer_head *bh; | 1082 | struct buffer_head *bh; |
1053 | 1083 | ||
1084 | dquot_initialize(dir); | ||
1085 | |||
1054 | lock_kernel(); | 1086 | lock_kernel(); |
1055 | if (inode->i_nlink >= (256 << sizeof(inode->i_nlink)) - 1) { | 1087 | if (inode->i_nlink >= (256 << sizeof(inode->i_nlink)) - 1) { |
1056 | unlock_kernel(); | 1088 | unlock_kernel(); |
@@ -1113,6 +1145,9 @@ static int udf_rename(struct inode *old_dir, struct dentry *old_dentry, | |||
1113 | struct kernel_lb_addr tloc; | 1145 | struct kernel_lb_addr tloc; |
1114 | struct udf_inode_info *old_iinfo = UDF_I(old_inode); | 1146 | struct udf_inode_info *old_iinfo = UDF_I(old_inode); |
1115 | 1147 | ||
1148 | dquot_initialize(old_dir); | ||
1149 | dquot_initialize(new_dir); | ||
1150 | |||
1116 | lock_kernel(); | 1151 | lock_kernel(); |
1117 | ofi = udf_find_entry(old_dir, &old_dentry->d_name, &ofibh, &ocfi); | 1152 | ofi = udf_find_entry(old_dir, &old_dentry->d_name, &ofibh, &ocfi); |
1118 | if (ofi) { | 1153 | if (ofi) { |
@@ -1358,6 +1393,7 @@ const struct export_operations udf_export_ops = { | |||
1358 | const struct inode_operations udf_dir_inode_operations = { | 1393 | const struct inode_operations udf_dir_inode_operations = { |
1359 | .lookup = udf_lookup, | 1394 | .lookup = udf_lookup, |
1360 | .create = udf_create, | 1395 | .create = udf_create, |
1396 | .setattr = udf_setattr, | ||
1361 | .link = udf_link, | 1397 | .link = udf_link, |
1362 | .unlink = udf_unlink, | 1398 | .unlink = udf_unlink, |
1363 | .symlink = udf_symlink, | 1399 | .symlink = udf_symlink, |
@@ -1366,3 +1402,9 @@ const struct inode_operations udf_dir_inode_operations = { | |||
1366 | .mknod = udf_mknod, | 1402 | .mknod = udf_mknod, |
1367 | .rename = udf_rename, | 1403 | .rename = udf_rename, |
1368 | }; | 1404 | }; |
1405 | const struct inode_operations udf_symlink_inode_operations = { | ||
1406 | .readlink = generic_readlink, | ||
1407 | .follow_link = page_follow_link_light, | ||
1408 | .put_link = page_put_link, | ||
1409 | .setattr = udf_setattr, | ||
1410 | }; | ||