diff options
Diffstat (limited to 'fs/udf/namei.c')
| -rw-r--r-- | fs/udf/namei.c | 38 |
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 | ||
| 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 { |
| @@ -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); |
