aboutsummaryrefslogtreecommitdiffstats
path: root/fs/udf/namei.c
diff options
context:
space:
mode:
authorAndrea Bastoni <bastoni@cs.unc.edu>2010-05-30 19:16:45 -0400
committerAndrea Bastoni <bastoni@cs.unc.edu>2010-05-30 19:16:45 -0400
commitada47b5fe13d89735805b566185f4885f5a3f750 (patch)
tree644b88f8a71896307d71438e9b3af49126ffb22b /fs/udf/namei.c
parent43e98717ad40a4ae64545b5ba047c7b86aa44f4f (diff)
parent3280f21d43ee541f97f8cda5792150d2dbec20d5 (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.c84
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
37static inline int udf_match(int len1, const char *name1, int len2, 37static 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
144static struct fileIdentDesc *udf_find_entry(struct inode *dir, 144static 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
410add: 410add:
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 = {
1358const struct inode_operations udf_dir_inode_operations = { 1393const 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};
1405const 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};