aboutsummaryrefslogtreecommitdiffstats
path: root/fs/udf/namei.c
diff options
context:
space:
mode:
Diffstat (limited to 'fs/udf/namei.c')
-rw-r--r--fs/udf/namei.c38
1 files changed, 28 insertions, 10 deletions
diff --git a/fs/udf/namei.c b/fs/udf/namei.c
index 21dad8c608f9..cd2115060fdc 100644
--- a/fs/udf/namei.c
+++ b/fs/udf/namei.c
@@ -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 {
@@ -922,7 +938,7 @@ static int udf_symlink(struct inode *dir, struct dentry *dentry,
922 block = udf_get_pblock(inode->i_sb, block, 938 block = udf_get_pblock(inode->i_sb, block,
923 iinfo->i_location.partitionReferenceNum, 939 iinfo->i_location.partitionReferenceNum,
924 0); 940 0);
925 epos.bh = udf_tread(inode->i_sb, block); 941 epos.bh = udf_tgetblk(inode->i_sb, block);
926 lock_buffer(epos.bh); 942 lock_buffer(epos.bh);
927 memset(epos.bh->b_data, 0x00, inode->i_sb->s_blocksize); 943 memset(epos.bh->b_data, 0x00, inode->i_sb->s_blocksize);
928 set_buffer_uptodate(epos.bh); 944 set_buffer_uptodate(epos.bh);
@@ -999,6 +1015,8 @@ static int udf_symlink(struct inode *dir, struct dentry *dentry,
999 inode->i_size = elen; 1015 inode->i_size = elen;
1000 if (iinfo->i_alloc_type == ICBTAG_FLAG_AD_IN_ICB) 1016 if (iinfo->i_alloc_type == ICBTAG_FLAG_AD_IN_ICB)
1001 iinfo->i_lenAlloc = inode->i_size; 1017 iinfo->i_lenAlloc = inode->i_size;
1018 else
1019 udf_truncate_tail_extent(inode);
1002 mark_inode_dirty(inode); 1020 mark_inode_dirty(inode);
1003 1021
1004 fi = udf_add_entry(dir, dentry, &fibh, &cfi, &err); 1022 fi = udf_add_entry(dir, dentry, &fibh, &cfi, &err);