|
Lines 49-58
Link Here
|
| 49 |
static mode_t udf_convert_permissions(struct fileEntry *); |
49 |
static mode_t udf_convert_permissions(struct fileEntry *); |
| 50 |
static int udf_update_inode(struct inode *, int); |
50 |
static int udf_update_inode(struct inode *, int); |
| 51 |
static void udf_fill_inode(struct inode *, struct buffer_head *); |
51 |
static void udf_fill_inode(struct inode *, struct buffer_head *); |
| 52 |
static struct buffer_head *inode_getblk(struct inode *, long, int *, |
52 |
static struct buffer_head *inode_getblk(struct inode *, sector_t, int *, |
| 53 |
long *, int *); |
53 |
long *, int *); |
| 54 |
static int8_t udf_insert_aext(struct inode *, kernel_lb_addr, int, |
54 |
static int8_t udf_insert_aext(struct inode *, struct extent_position, |
| 55 |
kernel_lb_addr, uint32_t, struct buffer_head *); |
55 |
kernel_lb_addr, uint32_t); |
| 56 |
static void udf_split_extents(struct inode *, int *, int, int, |
56 |
static void udf_split_extents(struct inode *, int *, int, int, |
| 57 |
kernel_long_ad [EXTENT_MERGE_SIZE], int *); |
57 |
kernel_long_ad [EXTENT_MERGE_SIZE], int *); |
| 58 |
static void udf_prealloc_extents(struct inode *, int, int, |
58 |
static void udf_prealloc_extents(struct inode *, int, int, |
|
Lines 61-67
Link Here
|
| 61 |
kernel_long_ad [EXTENT_MERGE_SIZE], int *); |
61 |
kernel_long_ad [EXTENT_MERGE_SIZE], int *); |
| 62 |
static void udf_update_extents(struct inode *, |
62 |
static void udf_update_extents(struct inode *, |
| 63 |
kernel_long_ad [EXTENT_MERGE_SIZE], int, int, |
63 |
kernel_long_ad [EXTENT_MERGE_SIZE], int, int, |
| 64 |
kernel_lb_addr, uint32_t, struct buffer_head **); |
64 |
struct extent_position *); |
| 65 |
static int udf_get_block(struct inode *, sector_t, struct buffer_head *, int); |
65 |
static int udf_get_block(struct inode *, sector_t, struct buffer_head *, int); |
| 66 |
|
66 |
|
| 67 |
/* |
67 |
/* |
|
Lines 100-113
Link Here
|
| 100 |
clear_inode(inode); |
100 |
clear_inode(inode); |
| 101 |
} |
101 |
} |
| 102 |
|
102 |
|
|
|
103 |
/* |
| 104 |
* If we are going to release inode from memory, we discard preallocation and |
| 105 |
* truncate last inode extent to proper length. We could use drop_inode() but |
| 106 |
* it's called under inode_lock and thus we cannot mark inode dirty there. We |
| 107 |
* use clear_inode() but we have to make sure to write inode as it's not written |
| 108 |
* automatically. |
| 109 |
*/ |
| 103 |
void udf_clear_inode(struct inode *inode) |
110 |
void udf_clear_inode(struct inode *inode) |
| 104 |
{ |
111 |
{ |
| 105 |
if (!(inode->i_sb->s_flags & MS_RDONLY)) { |
112 |
if (!(inode->i_sb->s_flags & MS_RDONLY)) { |
| 106 |
lock_kernel(); |
113 |
lock_kernel(); |
|
|
114 |
/* Discard preallocation for directories, symlinks, etc. */ |
| 107 |
udf_discard_prealloc(inode); |
115 |
udf_discard_prealloc(inode); |
|
|
116 |
udf_truncate_tail_extent(inode); |
| 108 |
unlock_kernel(); |
117 |
unlock_kernel(); |
|
|
118 |
write_inode_now(inode, 1); |
| 109 |
} |
119 |
} |
| 110 |
|
|
|
| 111 |
kfree(UDF_I_DATA(inode)); |
120 |
kfree(UDF_I_DATA(inode)); |
| 112 |
UDF_I_DATA(inode) = NULL; |
121 |
UDF_I_DATA(inode) = NULL; |
| 113 |
} |
122 |
} |
|
Lines 194-203
Link Here
|
| 194 |
struct buffer_head * udf_expand_dir_adinicb(struct inode *inode, int *block, int *err) |
203 |
struct buffer_head * udf_expand_dir_adinicb(struct inode *inode, int *block, int *err) |
| 195 |
{ |
204 |
{ |
| 196 |
int newblock; |
205 |
int newblock; |
| 197 |
struct buffer_head *sbh = NULL, *dbh = NULL; |
206 |
struct buffer_head *dbh = NULL; |
| 198 |
kernel_lb_addr bloc, eloc; |
207 |
kernel_lb_addr eloc; |
| 199 |
uint32_t elen, extoffset; |
208 |
uint32_t elen; |
| 200 |
uint8_t alloctype; |
209 |
uint8_t alloctype; |
|
|
210 |
struct extent_position epos; |
| 201 |
|
211 |
|
| 202 |
struct udf_fileident_bh sfibh, dfibh; |
212 |
struct udf_fileident_bh sfibh, dfibh; |
| 203 |
loff_t f_pos = udf_ext0_offset(inode) >> 2; |
213 |
loff_t f_pos = udf_ext0_offset(inode) >> 2; |
|
Lines 237-252
Link Here
|
| 237 |
mark_buffer_dirty_inode(dbh, inode); |
247 |
mark_buffer_dirty_inode(dbh, inode); |
| 238 |
|
248 |
|
| 239 |
sfibh.soffset = sfibh.eoffset = (f_pos & ((inode->i_sb->s_blocksize - 1) >> 2)) << 2; |
249 |
sfibh.soffset = sfibh.eoffset = (f_pos & ((inode->i_sb->s_blocksize - 1) >> 2)) << 2; |
| 240 |
sbh = sfibh.sbh = sfibh.ebh = NULL; |
250 |
sfibh.sbh = sfibh.ebh = NULL; |
| 241 |
dfibh.soffset = dfibh.eoffset = 0; |
251 |
dfibh.soffset = dfibh.eoffset = 0; |
| 242 |
dfibh.sbh = dfibh.ebh = dbh; |
252 |
dfibh.sbh = dfibh.ebh = dbh; |
| 243 |
while ( (f_pos < size) ) |
253 |
while ( (f_pos < size) ) |
| 244 |
{ |
254 |
{ |
| 245 |
UDF_I_ALLOCTYPE(inode) = ICBTAG_FLAG_AD_IN_ICB; |
255 |
UDF_I_ALLOCTYPE(inode) = ICBTAG_FLAG_AD_IN_ICB; |
| 246 |
sfi = udf_fileident_read(inode, &f_pos, &sfibh, &cfi, NULL, NULL, NULL, NULL, NULL, NULL); |
256 |
sfi = udf_fileident_read(inode, &f_pos, &sfibh, &cfi, NULL, NULL, NULL, NULL); |
| 247 |
if (!sfi) |
257 |
if (!sfi) |
| 248 |
{ |
258 |
{ |
| 249 |
udf_release_data(dbh); |
259 |
brelse(dbh); |
| 250 |
return NULL; |
260 |
return NULL; |
| 251 |
} |
261 |
} |
| 252 |
UDF_I_ALLOCTYPE(inode) = alloctype; |
262 |
UDF_I_ALLOCTYPE(inode) = alloctype; |
|
Lines 258-264
Link Here
|
| 258 |
sfi->fileIdent + le16_to_cpu(sfi->lengthOfImpUse))) |
268 |
sfi->fileIdent + le16_to_cpu(sfi->lengthOfImpUse))) |
| 259 |
{ |
269 |
{ |
| 260 |
UDF_I_ALLOCTYPE(inode) = ICBTAG_FLAG_AD_IN_ICB; |
270 |
UDF_I_ALLOCTYPE(inode) = ICBTAG_FLAG_AD_IN_ICB; |
| 261 |
udf_release_data(dbh); |
271 |
brelse(dbh); |
| 262 |
return NULL; |
272 |
return NULL; |
| 263 |
} |
273 |
} |
| 264 |
} |
274 |
} |
|
Lines 266-281
Link Here
|
| 266 |
|
276 |
|
| 267 |
memset(UDF_I_DATA(inode) + UDF_I_LENEATTR(inode), 0, UDF_I_LENALLOC(inode)); |
277 |
memset(UDF_I_DATA(inode) + UDF_I_LENEATTR(inode), 0, UDF_I_LENALLOC(inode)); |
| 268 |
UDF_I_LENALLOC(inode) = 0; |
278 |
UDF_I_LENALLOC(inode) = 0; |
| 269 |
bloc = UDF_I_LOCATION(inode); |
|
|
| 270 |
eloc.logicalBlockNum = *block; |
279 |
eloc.logicalBlockNum = *block; |
| 271 |
eloc.partitionReferenceNum = UDF_I_LOCATION(inode).partitionReferenceNum; |
280 |
eloc.partitionReferenceNum = UDF_I_LOCATION(inode).partitionReferenceNum; |
| 272 |
elen = inode->i_size; |
281 |
elen = inode->i_size; |
| 273 |
UDF_I_LENEXTENTS(inode) = elen; |
282 |
UDF_I_LENEXTENTS(inode) = elen; |
| 274 |
extoffset = udf_file_entry_alloc_offset(inode); |
283 |
epos.bh = NULL; |
| 275 |
udf_add_aext(inode, &bloc, &extoffset, eloc, elen, &sbh, 0); |
284 |
epos.block = UDF_I_LOCATION(inode); |
|
|
285 |
epos.offset = udf_file_entry_alloc_offset(inode); |
| 286 |
udf_add_aext(inode, &epos, eloc, elen, 0); |
| 276 |
/* UniqueID stuff */ |
287 |
/* UniqueID stuff */ |
| 277 |
|
288 |
|
| 278 |
udf_release_data(sbh); |
289 |
brelse(epos.bh); |
| 279 |
mark_inode_dirty(inode); |
290 |
mark_inode_dirty(inode); |
| 280 |
return dbh; |
291 |
return dbh; |
| 281 |
} |
292 |
} |
|
Lines 354-406
Link Here
|
| 354 |
return NULL; |
365 |
return NULL; |
| 355 |
} |
366 |
} |
| 356 |
|
367 |
|
| 357 |
static struct buffer_head * inode_getblk(struct inode * inode, long block, |
368 |
/* Extend the file by 'blocks' blocks, return the number of extents added */ |
|
|
369 |
int udf_extend_file(struct inode *inode, struct extent_position *last_pos, |
| 370 |
kernel_long_ad *last_ext, sector_t blocks) |
| 371 |
{ |
| 372 |
sector_t add; |
| 373 |
int count = 0, fake = !(last_ext->extLength & UDF_EXTENT_LENGTH_MASK); |
| 374 |
struct super_block *sb = inode->i_sb; |
| 375 |
kernel_lb_addr prealloc_loc = {0, 0}; |
| 376 |
int prealloc_len = 0; |
| 377 |
|
| 378 |
/* The previous extent is fake and we should not extend by anything |
| 379 |
* - there's nothing to do... */ |
| 380 |
if (!blocks && fake) |
| 381 |
return 0; |
| 382 |
/* Round the last extent up to a multiple of block size */ |
| 383 |
if (last_ext->extLength & (sb->s_blocksize - 1)) { |
| 384 |
last_ext->extLength = |
| 385 |
(last_ext->extLength & UDF_EXTENT_FLAG_MASK) | |
| 386 |
(((last_ext->extLength & UDF_EXTENT_LENGTH_MASK) + |
| 387 |
sb->s_blocksize - 1) & ~(sb->s_blocksize - 1)); |
| 388 |
UDF_I_LENEXTENTS(inode) = |
| 389 |
(UDF_I_LENEXTENTS(inode) + sb->s_blocksize - 1) & |
| 390 |
~(sb->s_blocksize - 1); |
| 391 |
} |
| 392 |
/* Last extent are just preallocated blocks? */ |
| 393 |
if ((last_ext->extLength & UDF_EXTENT_FLAG_MASK) == EXT_NOT_RECORDED_ALLOCATED) { |
| 394 |
/* Save the extent so that we can reattach it to the end */ |
| 395 |
prealloc_loc = last_ext->extLocation; |
| 396 |
prealloc_len = last_ext->extLength; |
| 397 |
/* Mark the extent as a hole */ |
| 398 |
last_ext->extLength = EXT_NOT_RECORDED_NOT_ALLOCATED | |
| 399 |
(last_ext->extLength & UDF_EXTENT_LENGTH_MASK); |
| 400 |
last_ext->extLocation.logicalBlockNum = 0; |
| 401 |
last_ext->extLocation.partitionReferenceNum = 0; |
| 402 |
} |
| 403 |
/* Can we merge with the previous extent? */ |
| 404 |
if ((last_ext->extLength & UDF_EXTENT_FLAG_MASK) == EXT_NOT_RECORDED_NOT_ALLOCATED) { |
| 405 |
add = ((1<<30) - sb->s_blocksize - (last_ext->extLength & |
| 406 |
UDF_EXTENT_LENGTH_MASK)) >> sb->s_blocksize_bits; |
| 407 |
if (add > blocks) |
| 408 |
add = blocks; |
| 409 |
blocks -= add; |
| 410 |
last_ext->extLength += add << sb->s_blocksize_bits; |
| 411 |
} |
| 412 |
|
| 413 |
if (fake) { |
| 414 |
udf_add_aext(inode, last_pos, last_ext->extLocation, |
| 415 |
last_ext->extLength, 1); |
| 416 |
count++; |
| 417 |
} |
| 418 |
else |
| 419 |
udf_write_aext(inode, last_pos, last_ext->extLocation, last_ext->extLength, 1); |
| 420 |
/* Managed to do everything necessary? */ |
| 421 |
if (!blocks) |
| 422 |
goto out; |
| 423 |
|
| 424 |
/* All further extents will be NOT_RECORDED_NOT_ALLOCATED */ |
| 425 |
last_ext->extLocation.logicalBlockNum = 0; |
| 426 |
last_ext->extLocation.partitionReferenceNum = 0; |
| 427 |
add = (1 << (30-sb->s_blocksize_bits)) - 1; |
| 428 |
last_ext->extLength = EXT_NOT_RECORDED_NOT_ALLOCATED | (add << sb->s_blocksize_bits); |
| 429 |
/* Create enough extents to cover the whole hole */ |
| 430 |
while (blocks > add) { |
| 431 |
blocks -= add; |
| 432 |
if (udf_add_aext(inode, last_pos, last_ext->extLocation, |
| 433 |
last_ext->extLength, 1) == -1) |
| 434 |
return -1; |
| 435 |
count++; |
| 436 |
} |
| 437 |
if (blocks) { |
| 438 |
last_ext->extLength = EXT_NOT_RECORDED_NOT_ALLOCATED | |
| 439 |
(blocks << sb->s_blocksize_bits); |
| 440 |
if (udf_add_aext(inode, last_pos, last_ext->extLocation, |
| 441 |
last_ext->extLength, 1) == -1) |
| 442 |
return -1; |
| 443 |
count++; |
| 444 |
} |
| 445 |
out: |
| 446 |
/* Do we have some preallocated blocks saved? */ |
| 447 |
if (prealloc_len) { |
| 448 |
if (udf_add_aext(inode, last_pos, prealloc_loc, prealloc_len, 1) == -1) |
| 449 |
return -1; |
| 450 |
last_ext->extLocation = prealloc_loc; |
| 451 |
last_ext->extLength = prealloc_len; |
| 452 |
count++; |
| 453 |
} |
| 454 |
/* last_pos should point to the last written extent... */ |
| 455 |
if (UDF_I_ALLOCTYPE(inode) == ICBTAG_FLAG_AD_SHORT) |
| 456 |
last_pos->offset -= sizeof(short_ad); |
| 457 |
else if (UDF_I_ALLOCTYPE(inode) == ICBTAG_FLAG_AD_LONG) |
| 458 |
last_pos->offset -= sizeof(long_ad); |
| 459 |
else |
| 460 |
return -1; |
| 461 |
return count; |
| 462 |
} |
| 463 |
|
| 464 |
static struct buffer_head * inode_getblk(struct inode * inode, sector_t block, |
| 358 |
int *err, long *phys, int *new) |
465 |
int *err, long *phys, int *new) |
| 359 |
{ |
466 |
{ |
| 360 |
struct buffer_head *pbh = NULL, *cbh = NULL, *nbh = NULL, *result = NULL; |
467 |
static sector_t last_block; |
|
|
468 |
struct buffer_head *result = NULL; |
| 361 |
kernel_long_ad laarr[EXTENT_MERGE_SIZE]; |
469 |
kernel_long_ad laarr[EXTENT_MERGE_SIZE]; |
| 362 |
uint32_t pextoffset = 0, cextoffset = 0, nextoffset = 0; |
470 |
struct extent_position prev_epos, cur_epos, next_epos; |
| 363 |
int count = 0, startnum = 0, endnum = 0; |
471 |
int count = 0, startnum = 0, endnum = 0; |
| 364 |
uint32_t elen = 0; |
472 |
uint32_t elen = 0, tmpelen; |
| 365 |
kernel_lb_addr eloc, pbloc, cbloc, nbloc; |
473 |
kernel_lb_addr eloc, tmpeloc; |
| 366 |
int c = 1; |
474 |
int c = 1; |
| 367 |
uint64_t lbcount = 0, b_off = 0; |
475 |
loff_t lbcount = 0, b_off = 0; |
| 368 |
uint32_t newblocknum, newblock, offset = 0; |
476 |
uint32_t newblocknum, newblock; |
|
|
477 |
sector_t offset = 0; |
| 369 |
int8_t etype; |
478 |
int8_t etype; |
| 370 |
int goal = 0, pgoal = UDF_I_LOCATION(inode).logicalBlockNum; |
479 |
int goal = 0, pgoal = UDF_I_LOCATION(inode).logicalBlockNum; |
| 371 |
char lastblock = 0; |
480 |
int lastblock = 0; |
| 372 |
|
481 |
|
| 373 |
pextoffset = cextoffset = nextoffset = udf_file_entry_alloc_offset(inode); |
482 |
prev_epos.offset = udf_file_entry_alloc_offset(inode); |
| 374 |
b_off = (uint64_t)block << inode->i_sb->s_blocksize_bits; |
483 |
prev_epos.block = UDF_I_LOCATION(inode); |
| 375 |
pbloc = cbloc = nbloc = UDF_I_LOCATION(inode); |
484 |
prev_epos.bh = NULL; |
|
|
485 |
cur_epos = next_epos = prev_epos; |
| 486 |
b_off = (loff_t)block << inode->i_sb->s_blocksize_bits; |
| 376 |
|
487 |
|
| 377 |
/* find the extent which contains the block we are looking for. |
488 |
/* find the extent which contains the block we are looking for. |
| 378 |
alternate between laarr[0] and laarr[1] for locations of the |
489 |
alternate between laarr[0] and laarr[1] for locations of the |
| 379 |
current extent, and the previous extent */ |
490 |
current extent, and the previous extent */ |
| 380 |
do |
491 |
do |
| 381 |
{ |
492 |
{ |
| 382 |
if (pbh != cbh) |
493 |
if (prev_epos.bh != cur_epos.bh) |
| 383 |
{ |
494 |
{ |
| 384 |
udf_release_data(pbh); |
495 |
brelse(prev_epos.bh); |
| 385 |
atomic_inc(&cbh->b_count); |
496 |
get_bh(cur_epos.bh); |
| 386 |
pbh = cbh; |
497 |
prev_epos.bh = cur_epos.bh; |
| 387 |
} |
498 |
} |
| 388 |
if (cbh != nbh) |
499 |
if (cur_epos.bh != next_epos.bh) |
| 389 |
{ |
500 |
{ |
| 390 |
udf_release_data(cbh); |
501 |
brelse(cur_epos.bh); |
| 391 |
atomic_inc(&nbh->b_count); |
502 |
get_bh(next_epos.bh); |
| 392 |
cbh = nbh; |
503 |
cur_epos.bh = next_epos.bh; |
| 393 |
} |
504 |
} |
| 394 |
|
505 |
|
| 395 |
lbcount += elen; |
506 |
lbcount += elen; |
| 396 |
|
507 |
|
| 397 |
pbloc = cbloc; |
508 |
prev_epos.block = cur_epos.block; |
| 398 |
cbloc = nbloc; |
509 |
cur_epos.block = next_epos.block; |
| 399 |
|
510 |
|
| 400 |
pextoffset = cextoffset; |
511 |
prev_epos.offset = cur_epos.offset; |
| 401 |
cextoffset = nextoffset; |
512 |
cur_epos.offset = next_epos.offset; |
| 402 |
|
513 |
|
| 403 |
if ((etype = udf_next_aext(inode, &nbloc, &nextoffset, &eloc, &elen, &nbh, 1)) == -1) |
514 |
if ((etype = udf_next_aext(inode, &next_epos, &eloc, &elen, 1)) == -1) |
| 404 |
break; |
515 |
break; |
| 405 |
|
516 |
|
| 406 |
c = !c; |
517 |
c = !c; |
|
Lines 418-423
Link Here
|
| 418 |
|
529 |
|
| 419 |
b_off -= lbcount; |
530 |
b_off -= lbcount; |
| 420 |
offset = b_off >> inode->i_sb->s_blocksize_bits; |
531 |
offset = b_off >> inode->i_sb->s_blocksize_bits; |
|
|
532 |
/* |
| 533 |
* Move prev_epos and cur_epos into indirect extent if we are at |
| 534 |
* the pointer to it |
| 535 |
*/ |
| 536 |
udf_next_aext(inode, &prev_epos, &tmpeloc, &tmpelen, 0); |
| 537 |
udf_next_aext(inode, &cur_epos, &tmpeloc, &tmpelen, 0); |
| 421 |
|
538 |
|
| 422 |
/* if the extent is allocated and recorded, return the block |
539 |
/* if the extent is allocated and recorded, return the block |
| 423 |
if the extent is not a multiple of the blocksize, round up */ |
540 |
if the extent is not a multiple of the blocksize, round up */ |
|
Lines 429-482
Link Here
|
| 429 |
elen = EXT_RECORDED_ALLOCATED | |
546 |
elen = EXT_RECORDED_ALLOCATED | |
| 430 |
((elen + inode->i_sb->s_blocksize - 1) & |
547 |
((elen + inode->i_sb->s_blocksize - 1) & |
| 431 |
~(inode->i_sb->s_blocksize - 1)); |
548 |
~(inode->i_sb->s_blocksize - 1)); |
| 432 |
etype = udf_write_aext(inode, nbloc, &cextoffset, eloc, elen, nbh, 1); |
549 |
etype = udf_write_aext(inode, &cur_epos, eloc, elen, 1); |
| 433 |
} |
550 |
} |
| 434 |
udf_release_data(pbh); |
551 |
brelse(prev_epos.bh); |
| 435 |
udf_release_data(cbh); |
552 |
brelse(cur_epos.bh); |
| 436 |
udf_release_data(nbh); |
553 |
brelse(next_epos.bh); |
| 437 |
newblock = udf_get_lb_pblock(inode->i_sb, eloc, offset); |
554 |
newblock = udf_get_lb_pblock(inode->i_sb, eloc, offset); |
| 438 |
*phys = newblock; |
555 |
*phys = newblock; |
| 439 |
return NULL; |
556 |
return NULL; |
| 440 |
} |
557 |
} |
| 441 |
|
558 |
|
|
|
559 |
last_block = block; |
| 560 |
/* Are we beyond EOF? */ |
| 442 |
if (etype == -1) |
561 |
if (etype == -1) |
| 443 |
{ |
562 |
{ |
| 444 |
endnum = startnum = ((count > 1) ? 1 : count); |
563 |
int ret; |
| 445 |
if (laarr[c].extLength & (inode->i_sb->s_blocksize - 1)) |
564 |
|
| 446 |
{ |
565 |
if (count) { |
| 447 |
laarr[c].extLength = |
566 |
if (c) |
| 448 |
(laarr[c].extLength & UDF_EXTENT_FLAG_MASK) | |
567 |
laarr[0] = laarr[1]; |
| 449 |
(((laarr[c].extLength & UDF_EXTENT_LENGTH_MASK) + |
568 |
startnum = 1; |
| 450 |
inode->i_sb->s_blocksize - 1) & |
569 |
} |
| 451 |
~(inode->i_sb->s_blocksize - 1)); |
570 |
else { |
| 452 |
UDF_I_LENEXTENTS(inode) = |
571 |
/* Create a fake extent when there's not one */ |
| 453 |
(UDF_I_LENEXTENTS(inode) + inode->i_sb->s_blocksize - 1) & |
572 |
memset(&laarr[0].extLocation, 0x00, sizeof(kernel_lb_addr)); |
| 454 |
~(inode->i_sb->s_blocksize - 1); |
573 |
laarr[0].extLength = EXT_NOT_RECORDED_NOT_ALLOCATED; |
|
|
574 |
/* Will udf_extend_file() create real extent from a fake one? */ |
| 575 |
startnum = (offset > 0); |
| 576 |
} |
| 577 |
/* Create extents for the hole between EOF and offset */ |
| 578 |
ret = udf_extend_file(inode, &prev_epos, laarr, offset); |
| 579 |
if (ret == -1) { |
| 580 |
brelse(prev_epos.bh); |
| 581 |
brelse(cur_epos.bh); |
| 582 |
brelse(next_epos.bh); |
| 583 |
/* We don't really know the error here so we just make |
| 584 |
* something up */ |
| 585 |
*err = -ENOSPC; |
| 586 |
return NULL; |
| 455 |
} |
587 |
} |
| 456 |
c = !c; |
588 |
c = 0; |
| 457 |
laarr[c].extLength = EXT_NOT_RECORDED_NOT_ALLOCATED | |
589 |
offset = 0; |
| 458 |
((offset + 1) << inode->i_sb->s_blocksize_bits); |
590 |
count += ret; |
| 459 |
memset(&laarr[c].extLocation, 0x00, sizeof(kernel_lb_addr)); |
591 |
/* We are not covered by a preallocated extent? */ |
| 460 |
count ++; |
592 |
if ((laarr[0].extLength & UDF_EXTENT_FLAG_MASK) != EXT_NOT_RECORDED_ALLOCATED) { |
| 461 |
endnum ++; |
593 |
/* Is there any real extent? - otherwise we overwrite |
|
|
594 |
* the fake one... */ |
| 595 |
if (count) |
| 596 |
c = !c; |
| 597 |
laarr[c].extLength = EXT_NOT_RECORDED_NOT_ALLOCATED | |
| 598 |
inode->i_sb->s_blocksize; |
| 599 |
memset(&laarr[c].extLocation, 0x00, sizeof(kernel_lb_addr)); |
| 600 |
count ++; |
| 601 |
endnum ++; |
| 602 |
} |
| 603 |
endnum = c+1; |
| 462 |
lastblock = 1; |
604 |
lastblock = 1; |
| 463 |
} |
605 |
} |
| 464 |
else |
606 |
else { |
| 465 |
endnum = startnum = ((count > 2) ? 2 : count); |
607 |
endnum = startnum = ((count > 2) ? 2 : count); |
| 466 |
|
608 |
|
| 467 |
/* if the current extent is in position 0, swap it with the previous */ |
609 |
/* if the current extent is in position 0, swap it with the previous */ |
| 468 |
if (!c && count != 1) |
610 |
if (!c && count != 1) |
| 469 |
{ |
611 |
{ |
| 470 |
laarr[2] = laarr[0]; |
612 |
laarr[2] = laarr[0]; |
| 471 |
laarr[0] = laarr[1]; |
613 |
laarr[0] = laarr[1]; |
| 472 |
laarr[1] = laarr[2]; |
614 |
laarr[1] = laarr[2]; |
| 473 |
c = 1; |
615 |
c = 1; |
| 474 |
} |
616 |
} |
| 475 |
|
617 |
|
| 476 |
/* if the current block is located in a extent, read the next extent */ |
618 |
/* if the current block is located in an extent, read the next extent */ |
| 477 |
if (etype != -1) |
619 |
if ((etype = udf_next_aext(inode, &next_epos, &eloc, &elen, 0)) != -1) |
| 478 |
{ |
|
|
| 479 |
if ((etype = udf_next_aext(inode, &nbloc, &nextoffset, &eloc, &elen, &nbh, 0)) != -1) |
| 480 |
{ |
620 |
{ |
| 481 |
laarr[c+1].extLength = (etype << 30) | elen; |
621 |
laarr[c+1].extLength = (etype << 30) | elen; |
| 482 |
laarr[c+1].extLocation = eloc; |
622 |
laarr[c+1].extLocation = eloc; |
|
Lines 484-494
Link Here
|
| 484 |
startnum ++; |
624 |
startnum ++; |
| 485 |
endnum ++; |
625 |
endnum ++; |
| 486 |
} |
626 |
} |
| 487 |
else |
627 |
else { |
| 488 |
lastblock = 1; |
628 |
lastblock = 1; |
|
|
629 |
} |
| 489 |
} |
630 |
} |
| 490 |
udf_release_data(cbh); |
|
|
| 491 |
udf_release_data(nbh); |
| 492 |
|
631 |
|
| 493 |
/* if the current extent is not recorded but allocated, get the |
632 |
/* if the current extent is not recorded but allocated, get the |
| 494 |
block in the extent corresponding to the requested block */ |
633 |
block in the extent corresponding to the requested block */ |
|
Lines 508-514
Link Here
|
| 508 |
if (!(newblocknum = udf_new_block(inode->i_sb, inode, |
647 |
if (!(newblocknum = udf_new_block(inode->i_sb, inode, |
| 509 |
UDF_I_LOCATION(inode).partitionReferenceNum, goal, err))) |
648 |
UDF_I_LOCATION(inode).partitionReferenceNum, goal, err))) |
| 510 |
{ |
649 |
{ |
| 511 |
udf_release_data(pbh); |
650 |
brelse(prev_epos.bh); |
| 512 |
*err = -ENOSPC; |
651 |
*err = -ENOSPC; |
| 513 |
return NULL; |
652 |
return NULL; |
| 514 |
} |
653 |
} |
|
Lines 529-539
Link Here
|
| 529 |
udf_merge_extents(inode, laarr, &endnum); |
668 |
udf_merge_extents(inode, laarr, &endnum); |
| 530 |
|
669 |
|
| 531 |
/* write back the new extents, inserting new extents if the new number |
670 |
/* write back the new extents, inserting new extents if the new number |
| 532 |
of extents is greater than the old number, and deleting extents if |
671 |
of extents is greater than the old number, and deleting extents if |
| 533 |
the new number of extents is less than the old number */ |
672 |
the new number of extents is less than the old number */ |
| 534 |
udf_update_extents(inode, laarr, startnum, endnum, pbloc, pextoffset, &pbh); |
673 |
udf_update_extents(inode, laarr, startnum, endnum, &prev_epos); |
| 535 |
|
674 |
|
| 536 |
udf_release_data(pbh); |
675 |
brelse(prev_epos.bh); |
| 537 |
|
676 |
|
| 538 |
if (!(newblock = udf_get_pblock(inode->i_sb, newblocknum, |
677 |
if (!(newblock = udf_get_pblock(inode->i_sb, newblocknum, |
| 539 |
UDF_I_LOCATION(inode).partitionReferenceNum, 0))) |
678 |
UDF_I_LOCATION(inode).partitionReferenceNum, 0))) |
|
Lines 795-801
Link Here
|
| 795 |
|
934 |
|
| 796 |
static void udf_update_extents(struct inode *inode, |
935 |
static void udf_update_extents(struct inode *inode, |
| 797 |
kernel_long_ad laarr[EXTENT_MERGE_SIZE], int startnum, int endnum, |
936 |
kernel_long_ad laarr[EXTENT_MERGE_SIZE], int startnum, int endnum, |
| 798 |
kernel_lb_addr pbloc, uint32_t pextoffset, struct buffer_head **pbh) |
937 |
struct extent_position *epos) |
| 799 |
{ |
938 |
{ |
| 800 |
int start = 0, i; |
939 |
int start = 0, i; |
| 801 |
kernel_lb_addr tmploc; |
940 |
kernel_lb_addr tmploc; |
|
Lines 804-831
Link Here
|
| 804 |
if (startnum > endnum) |
943 |
if (startnum > endnum) |
| 805 |
{ |
944 |
{ |
| 806 |
for (i=0; i<(startnum-endnum); i++) |
945 |
for (i=0; i<(startnum-endnum); i++) |
| 807 |
{ |
946 |
udf_delete_aext(inode, *epos, laarr[i].extLocation, |
| 808 |
udf_delete_aext(inode, pbloc, pextoffset, laarr[i].extLocation, |
947 |
laarr[i].extLength); |
| 809 |
laarr[i].extLength, *pbh); |
|
|
| 810 |
} |
| 811 |
} |
948 |
} |
| 812 |
else if (startnum < endnum) |
949 |
else if (startnum < endnum) |
| 813 |
{ |
950 |
{ |
| 814 |
for (i=0; i<(endnum-startnum); i++) |
951 |
for (i=0; i<(endnum-startnum); i++) |
| 815 |
{ |
952 |
{ |
| 816 |
udf_insert_aext(inode, pbloc, pextoffset, laarr[i].extLocation, |
953 |
udf_insert_aext(inode, *epos, laarr[i].extLocation, |
| 817 |
laarr[i].extLength, *pbh); |
954 |
laarr[i].extLength); |
| 818 |
udf_next_aext(inode, &pbloc, &pextoffset, &laarr[i].extLocation, |
955 |
udf_next_aext(inode, epos, &laarr[i].extLocation, |
| 819 |
&laarr[i].extLength, pbh, 1); |
956 |
&laarr[i].extLength, 1); |
| 820 |
start ++; |
957 |
start ++; |
| 821 |
} |
958 |
} |
| 822 |
} |
959 |
} |
| 823 |
|
960 |
|
| 824 |
for (i=start; i<endnum; i++) |
961 |
for (i=start; i<endnum; i++) |
| 825 |
{ |
962 |
{ |
| 826 |
udf_next_aext(inode, &pbloc, &pextoffset, &tmploc, &tmplen, pbh, 0); |
963 |
udf_next_aext(inode, epos, &tmploc, &tmplen, 0); |
| 827 |
udf_write_aext(inode, pbloc, &pextoffset, laarr[i].extLocation, |
964 |
udf_write_aext(inode, epos, laarr[i].extLocation, |
| 828 |
laarr[i].extLength, *pbh, 1); |
965 |
laarr[i].extLength, 1); |
| 829 |
} |
966 |
} |
| 830 |
} |
967 |
} |
| 831 |
|
968 |
|
|
Lines 916-923
Link Here
|
| 916 |
* i_nlink = 1 |
1053 |
* i_nlink = 1 |
| 917 |
* i_op = NULL; |
1054 |
* i_op = NULL; |
| 918 |
*/ |
1055 |
*/ |
| 919 |
inode->i_blksize = PAGE_SIZE; |
|
|
| 920 |
|
| 921 |
bh = udf_read_ptagged(inode->i_sb, UDF_I_LOCATION(inode), 0, &ident); |
1056 |
bh = udf_read_ptagged(inode->i_sb, UDF_I_LOCATION(inode), 0, &ident); |
| 922 |
|
1057 |
|
| 923 |
if (!bh) |
1058 |
if (!bh) |
|
Lines 933-939
Link Here
|
| 933 |
{ |
1068 |
{ |
| 934 |
printk(KERN_ERR "udf: udf_read_inode(ino %ld) failed ident=%d\n", |
1069 |
printk(KERN_ERR "udf: udf_read_inode(ino %ld) failed ident=%d\n", |
| 935 |
inode->i_ino, ident); |
1070 |
inode->i_ino, ident); |
| 936 |
udf_release_data(bh); |
1071 |
brelse(bh); |
| 937 |
make_bad_inode(inode); |
1072 |
make_bad_inode(inode); |
| 938 |
return; |
1073 |
return; |
| 939 |
} |
1074 |
} |
|
Lines 962-996
Link Here
|
| 962 |
ident == TAG_IDENT_EFE) |
1097 |
ident == TAG_IDENT_EFE) |
| 963 |
{ |
1098 |
{ |
| 964 |
memcpy(&UDF_I_LOCATION(inode), &loc, sizeof(kernel_lb_addr)); |
1099 |
memcpy(&UDF_I_LOCATION(inode), &loc, sizeof(kernel_lb_addr)); |
| 965 |
udf_release_data(bh); |
1100 |
brelse(bh); |
| 966 |
udf_release_data(ibh); |
1101 |
brelse(ibh); |
| 967 |
udf_release_data(nbh); |
1102 |
brelse(nbh); |
| 968 |
__udf_read_inode(inode); |
1103 |
__udf_read_inode(inode); |
| 969 |
return; |
1104 |
return; |
| 970 |
} |
1105 |
} |
| 971 |
else |
1106 |
else |
| 972 |
{ |
1107 |
{ |
| 973 |
udf_release_data(nbh); |
1108 |
brelse(nbh); |
| 974 |
udf_release_data(ibh); |
1109 |
brelse(ibh); |
| 975 |
} |
1110 |
} |
| 976 |
} |
1111 |
} |
| 977 |
else |
1112 |
else |
| 978 |
udf_release_data(ibh); |
1113 |
brelse(ibh); |
| 979 |
} |
1114 |
} |
| 980 |
} |
1115 |
} |
| 981 |
else |
1116 |
else |
| 982 |
udf_release_data(ibh); |
1117 |
brelse(ibh); |
| 983 |
} |
1118 |
} |
| 984 |
else if (le16_to_cpu(fe->icbTag.strategyType) != 4) |
1119 |
else if (le16_to_cpu(fe->icbTag.strategyType) != 4) |
| 985 |
{ |
1120 |
{ |
| 986 |
printk(KERN_ERR "udf: unsupported strategy type: %d\n", |
1121 |
printk(KERN_ERR "udf: unsupported strategy type: %d\n", |
| 987 |
le16_to_cpu(fe->icbTag.strategyType)); |
1122 |
le16_to_cpu(fe->icbTag.strategyType)); |
| 988 |
udf_release_data(bh); |
1123 |
brelse(bh); |
| 989 |
make_bad_inode(inode); |
1124 |
make_bad_inode(inode); |
| 990 |
return; |
1125 |
return; |
| 991 |
} |
1126 |
} |
| 992 |
udf_fill_inode(inode, bh); |
1127 |
udf_fill_inode(inode, bh); |
| 993 |
udf_release_data(bh); |
1128 |
|
|
|
1129 |
brelse(bh); |
| 994 |
} |
1130 |
} |
| 995 |
|
1131 |
|
| 996 |
static void udf_fill_inode(struct inode *inode, struct buffer_head *bh) |
1132 |
static void udf_fill_inode(struct inode *inode, struct buffer_head *bh) |
|
Lines 1333-1339
Link Here
|
| 1333 |
use->descTag.tagChecksum += ((uint8_t *)&(use->descTag))[i]; |
1469 |
use->descTag.tagChecksum += ((uint8_t *)&(use->descTag))[i]; |
| 1334 |
|
1470 |
|
| 1335 |
mark_buffer_dirty(bh); |
1471 |
mark_buffer_dirty(bh); |
| 1336 |
udf_release_data(bh); |
1472 |
brelse(bh); |
| 1337 |
return err; |
1473 |
return err; |
| 1338 |
} |
1474 |
} |
| 1339 |
|
1475 |
|
|
Lines 1522-1528
Link Here
|
| 1522 |
err = -EIO; |
1658 |
err = -EIO; |
| 1523 |
} |
1659 |
} |
| 1524 |
} |
1660 |
} |
| 1525 |
udf_release_data(bh); |
1661 |
brelse(bh); |
| 1526 |
return err; |
1662 |
return err; |
| 1527 |
} |
1663 |
} |
| 1528 |
|
1664 |
|
|
Lines 1558-1565
Link Here
|
| 1558 |
return NULL; |
1694 |
return NULL; |
| 1559 |
} |
1695 |
} |
| 1560 |
|
1696 |
|
| 1561 |
int8_t udf_add_aext(struct inode *inode, kernel_lb_addr *bloc, int *extoffset, |
1697 |
int8_t udf_add_aext(struct inode *inode, struct extent_position *epos, |
| 1562 |
kernel_lb_addr eloc, uint32_t elen, struct buffer_head **bh, int inc) |
1698 |
kernel_lb_addr eloc, uint32_t elen, int inc) |
| 1563 |
{ |
1699 |
{ |
| 1564 |
int adsize; |
1700 |
int adsize; |
| 1565 |
short_ad *sad = NULL; |
1701 |
short_ad *sad = NULL; |
|
Lines 1568-1577
Link Here
|
| 1568 |
int8_t etype; |
1704 |
int8_t etype; |
| 1569 |
uint8_t *ptr; |
1705 |
uint8_t *ptr; |
| 1570 |
|
1706 |
|
| 1571 |
if (!*bh) |
1707 |
if (!epos->bh) |
| 1572 |
ptr = UDF_I_DATA(inode) + *extoffset - udf_file_entry_alloc_offset(inode) + UDF_I_LENEATTR(inode); |
1708 |
ptr = UDF_I_DATA(inode) + epos->offset - udf_file_entry_alloc_offset(inode) + UDF_I_LENEATTR(inode); |
| 1573 |
else |
1709 |
else |
| 1574 |
ptr = (*bh)->b_data + *extoffset; |
1710 |
ptr = epos->bh->b_data + epos->offset; |
| 1575 |
|
1711 |
|
| 1576 |
if (UDF_I_ALLOCTYPE(inode) == ICBTAG_FLAG_AD_SHORT) |
1712 |
if (UDF_I_ALLOCTYPE(inode) == ICBTAG_FLAG_AD_SHORT) |
| 1577 |
adsize = sizeof(short_ad); |
1713 |
adsize = sizeof(short_ad); |
|
Lines 1580-1599
Link Here
|
| 1580 |
else |
1716 |
else |
| 1581 |
return -1; |
1717 |
return -1; |
| 1582 |
|
1718 |
|
| 1583 |
if (*extoffset + (2 * adsize) > inode->i_sb->s_blocksize) |
1719 |
if (epos->offset + (2 * adsize) > inode->i_sb->s_blocksize) |
| 1584 |
{ |
1720 |
{ |
| 1585 |
char *sptr, *dptr; |
1721 |
char *sptr, *dptr; |
| 1586 |
struct buffer_head *nbh; |
1722 |
struct buffer_head *nbh; |
| 1587 |
int err, loffset; |
1723 |
int err, loffset; |
| 1588 |
kernel_lb_addr obloc = *bloc; |
1724 |
kernel_lb_addr obloc = epos->block; |
| 1589 |
|
1725 |
|
| 1590 |
if (!(bloc->logicalBlockNum = udf_new_block(inode->i_sb, NULL, |
1726 |
if (!(epos->block.logicalBlockNum = udf_new_block(inode->i_sb, NULL, |
| 1591 |
obloc.partitionReferenceNum, obloc.logicalBlockNum, &err))) |
1727 |
obloc.partitionReferenceNum, obloc.logicalBlockNum, &err))) |
| 1592 |
{ |
1728 |
{ |
| 1593 |
return -1; |
1729 |
return -1; |
| 1594 |
} |
1730 |
} |
| 1595 |
if (!(nbh = udf_tgetblk(inode->i_sb, udf_get_lb_pblock(inode->i_sb, |
1731 |
if (!(nbh = udf_tgetblk(inode->i_sb, udf_get_lb_pblock(inode->i_sb, |
| 1596 |
*bloc, 0)))) |
1732 |
epos->block, 0)))) |
| 1597 |
{ |
1733 |
{ |
| 1598 |
return -1; |
1734 |
return -1; |
| 1599 |
} |
1735 |
} |
|
Lines 1606-1630
Link Here
|
| 1606 |
aed = (struct allocExtDesc *)(nbh->b_data); |
1742 |
aed = (struct allocExtDesc *)(nbh->b_data); |
| 1607 |
if (!UDF_QUERY_FLAG(inode->i_sb, UDF_FLAG_STRICT)) |
1743 |
if (!UDF_QUERY_FLAG(inode->i_sb, UDF_FLAG_STRICT)) |
| 1608 |
aed->previousAllocExtLocation = cpu_to_le32(obloc.logicalBlockNum); |
1744 |
aed->previousAllocExtLocation = cpu_to_le32(obloc.logicalBlockNum); |
| 1609 |
if (*extoffset + adsize > inode->i_sb->s_blocksize) |
1745 |
if (epos->offset + adsize > inode->i_sb->s_blocksize) |
| 1610 |
{ |
1746 |
{ |
| 1611 |
loffset = *extoffset; |
1747 |
loffset = epos->offset; |
| 1612 |
aed->lengthAllocDescs = cpu_to_le32(adsize); |
1748 |
aed->lengthAllocDescs = cpu_to_le32(adsize); |
| 1613 |
sptr = ptr - adsize; |
1749 |
sptr = ptr - adsize; |
| 1614 |
dptr = nbh->b_data + sizeof(struct allocExtDesc); |
1750 |
dptr = nbh->b_data + sizeof(struct allocExtDesc); |
| 1615 |
memcpy(dptr, sptr, adsize); |
1751 |
memcpy(dptr, sptr, adsize); |
| 1616 |
*extoffset = sizeof(struct allocExtDesc) + adsize; |
1752 |
epos->offset = sizeof(struct allocExtDesc) + adsize; |
| 1617 |
} |
1753 |
} |
| 1618 |
else |
1754 |
else |
| 1619 |
{ |
1755 |
{ |
| 1620 |
loffset = *extoffset + adsize; |
1756 |
loffset = epos->offset + adsize; |
| 1621 |
aed->lengthAllocDescs = cpu_to_le32(0); |
1757 |
aed->lengthAllocDescs = cpu_to_le32(0); |
| 1622 |
sptr = ptr; |
1758 |
sptr = ptr; |
| 1623 |
*extoffset = sizeof(struct allocExtDesc); |
1759 |
epos->offset = sizeof(struct allocExtDesc); |
| 1624 |
|
1760 |
|
| 1625 |
if (*bh) |
1761 |
if (epos->bh) |
| 1626 |
{ |
1762 |
{ |
| 1627 |
aed = (struct allocExtDesc *)(*bh)->b_data; |
1763 |
aed = (struct allocExtDesc *)epos->bh->b_data; |
| 1628 |
aed->lengthAllocDescs = |
1764 |
aed->lengthAllocDescs = |
| 1629 |
cpu_to_le32(le32_to_cpu(aed->lengthAllocDescs) + adsize); |
1765 |
cpu_to_le32(le32_to_cpu(aed->lengthAllocDescs) + adsize); |
| 1630 |
} |
1766 |
} |
|
Lines 1636-1645
Link Here
|
| 1636 |
} |
1772 |
} |
| 1637 |
if (UDF_SB_UDFREV(inode->i_sb) >= 0x0200) |
1773 |
if (UDF_SB_UDFREV(inode->i_sb) >= 0x0200) |
| 1638 |
udf_new_tag(nbh->b_data, TAG_IDENT_AED, 3, 1, |
1774 |
udf_new_tag(nbh->b_data, TAG_IDENT_AED, 3, 1, |
| 1639 |
bloc->logicalBlockNum, sizeof(tag)); |
1775 |
epos->block.logicalBlockNum, sizeof(tag)); |
| 1640 |
else |
1776 |
else |
| 1641 |
udf_new_tag(nbh->b_data, TAG_IDENT_AED, 2, 1, |
1777 |
udf_new_tag(nbh->b_data, TAG_IDENT_AED, 2, 1, |
| 1642 |
bloc->logicalBlockNum, sizeof(tag)); |
1778 |
epos->block.logicalBlockNum, sizeof(tag)); |
| 1643 |
switch (UDF_I_ALLOCTYPE(inode)) |
1779 |
switch (UDF_I_ALLOCTYPE(inode)) |
| 1644 |
{ |
1780 |
{ |
| 1645 |
case ICBTAG_FLAG_AD_SHORT: |
1781 |
case ICBTAG_FLAG_AD_SHORT: |
|
Lines 1648-1654
Link Here
|
| 1648 |
sad->extLength = cpu_to_le32( |
1784 |
sad->extLength = cpu_to_le32( |
| 1649 |
EXT_NEXT_EXTENT_ALLOCDECS | |
1785 |
EXT_NEXT_EXTENT_ALLOCDECS | |
| 1650 |
inode->i_sb->s_blocksize); |
1786 |
inode->i_sb->s_blocksize); |
| 1651 |
sad->extPosition = cpu_to_le32(bloc->logicalBlockNum); |
1787 |
sad->extPosition = cpu_to_le32(epos->block.logicalBlockNum); |
| 1652 |
break; |
1788 |
break; |
| 1653 |
} |
1789 |
} |
| 1654 |
case ICBTAG_FLAG_AD_LONG: |
1790 |
case ICBTAG_FLAG_AD_LONG: |
|
Lines 1657-1716
Link Here
|
| 1657 |
lad->extLength = cpu_to_le32( |
1793 |
lad->extLength = cpu_to_le32( |
| 1658 |
EXT_NEXT_EXTENT_ALLOCDECS | |
1794 |
EXT_NEXT_EXTENT_ALLOCDECS | |
| 1659 |
inode->i_sb->s_blocksize); |
1795 |
inode->i_sb->s_blocksize); |
| 1660 |
lad->extLocation = cpu_to_lelb(*bloc); |
1796 |
lad->extLocation = cpu_to_lelb(epos->block); |
| 1661 |
memset(lad->impUse, 0x00, sizeof(lad->impUse)); |
1797 |
memset(lad->impUse, 0x00, sizeof(lad->impUse)); |
| 1662 |
break; |
1798 |
break; |
| 1663 |
} |
1799 |
} |
| 1664 |
} |
1800 |
} |
| 1665 |
if (*bh) |
1801 |
if (epos->bh) |
| 1666 |
{ |
1802 |
{ |
| 1667 |
if (!UDF_QUERY_FLAG(inode->i_sb, UDF_FLAG_STRICT) || UDF_SB_UDFREV(inode->i_sb) >= 0x0201) |
1803 |
if (!UDF_QUERY_FLAG(inode->i_sb, UDF_FLAG_STRICT) || UDF_SB_UDFREV(inode->i_sb) >= 0x0201) |
| 1668 |
udf_update_tag((*bh)->b_data, loffset); |
1804 |
udf_update_tag(epos->bh->b_data, loffset); |
| 1669 |
else |
1805 |
else |
| 1670 |
udf_update_tag((*bh)->b_data, sizeof(struct allocExtDesc)); |
1806 |
udf_update_tag(epos->bh->b_data, sizeof(struct allocExtDesc)); |
| 1671 |
mark_buffer_dirty_inode(*bh, inode); |
1807 |
mark_buffer_dirty_inode(epos->bh, inode); |
| 1672 |
udf_release_data(*bh); |
1808 |
brelse(epos->bh); |
| 1673 |
} |
1809 |
} |
| 1674 |
else |
1810 |
else |
| 1675 |
mark_inode_dirty(inode); |
1811 |
mark_inode_dirty(inode); |
| 1676 |
*bh = nbh; |
1812 |
epos->bh = nbh; |
| 1677 |
} |
1813 |
} |
| 1678 |
|
1814 |
|
| 1679 |
etype = udf_write_aext(inode, *bloc, extoffset, eloc, elen, *bh, inc); |
1815 |
etype = udf_write_aext(inode, epos, eloc, elen, inc); |
| 1680 |
|
1816 |
|
| 1681 |
if (!*bh) |
1817 |
if (!epos->bh) |
| 1682 |
{ |
1818 |
{ |
| 1683 |
UDF_I_LENALLOC(inode) += adsize; |
1819 |
UDF_I_LENALLOC(inode) += adsize; |
| 1684 |
mark_inode_dirty(inode); |
1820 |
mark_inode_dirty(inode); |
| 1685 |
} |
1821 |
} |
| 1686 |
else |
1822 |
else |
| 1687 |
{ |
1823 |
{ |
| 1688 |
aed = (struct allocExtDesc *)(*bh)->b_data; |
1824 |
aed = (struct allocExtDesc *)epos->bh->b_data; |
| 1689 |
aed->lengthAllocDescs = |
1825 |
aed->lengthAllocDescs = |
| 1690 |
cpu_to_le32(le32_to_cpu(aed->lengthAllocDescs) + adsize); |
1826 |
cpu_to_le32(le32_to_cpu(aed->lengthAllocDescs) + adsize); |
| 1691 |
if (!UDF_QUERY_FLAG(inode->i_sb, UDF_FLAG_STRICT) || UDF_SB_UDFREV(inode->i_sb) >= 0x0201) |
1827 |
if (!UDF_QUERY_FLAG(inode->i_sb, UDF_FLAG_STRICT) || UDF_SB_UDFREV(inode->i_sb) >= 0x0201) |
| 1692 |
udf_update_tag((*bh)->b_data, *extoffset + (inc ? 0 : adsize)); |
1828 |
udf_update_tag(epos->bh->b_data, epos->offset + (inc ? 0 : adsize)); |
| 1693 |
else |
1829 |
else |
| 1694 |
udf_update_tag((*bh)->b_data, sizeof(struct allocExtDesc)); |
1830 |
udf_update_tag(epos->bh->b_data, sizeof(struct allocExtDesc)); |
| 1695 |
mark_buffer_dirty_inode(*bh, inode); |
1831 |
mark_buffer_dirty_inode(epos->bh, inode); |
| 1696 |
} |
1832 |
} |
| 1697 |
|
1833 |
|
| 1698 |
return etype; |
1834 |
return etype; |
| 1699 |
} |
1835 |
} |
| 1700 |
|
1836 |
|
| 1701 |
int8_t udf_write_aext(struct inode *inode, kernel_lb_addr bloc, int *extoffset, |
1837 |
int8_t udf_write_aext(struct inode *inode, struct extent_position *epos, |
| 1702 |
kernel_lb_addr eloc, uint32_t elen, struct buffer_head *bh, int inc) |
1838 |
kernel_lb_addr eloc, uint32_t elen, int inc) |
| 1703 |
{ |
1839 |
{ |
| 1704 |
int adsize; |
1840 |
int adsize; |
| 1705 |
uint8_t *ptr; |
1841 |
uint8_t *ptr; |
| 1706 |
|
1842 |
|
| 1707 |
if (!bh) |
1843 |
if (!epos->bh) |
| 1708 |
ptr = UDF_I_DATA(inode) + *extoffset - udf_file_entry_alloc_offset(inode) + UDF_I_LENEATTR(inode); |
1844 |
ptr = UDF_I_DATA(inode) + epos->offset - udf_file_entry_alloc_offset(inode) + UDF_I_LENEATTR(inode); |
| 1709 |
else |
1845 |
else |
| 1710 |
{ |
1846 |
ptr = epos->bh->b_data + epos->offset; |
| 1711 |
ptr = bh->b_data + *extoffset; |
|
|
| 1712 |
atomic_inc(&bh->b_count); |
| 1713 |
} |
| 1714 |
|
1847 |
|
| 1715 |
switch (UDF_I_ALLOCTYPE(inode)) |
1848 |
switch (UDF_I_ALLOCTYPE(inode)) |
| 1716 |
{ |
1849 |
{ |
|
Lines 1735-1774
Link Here
|
| 1735 |
return -1; |
1868 |
return -1; |
| 1736 |
} |
1869 |
} |
| 1737 |
|
1870 |
|
| 1738 |
if (bh) |
1871 |
if (epos->bh) |
| 1739 |
{ |
1872 |
{ |
| 1740 |
if (!UDF_QUERY_FLAG(inode->i_sb, UDF_FLAG_STRICT) || UDF_SB_UDFREV(inode->i_sb) >= 0x0201) |
1873 |
if (!UDF_QUERY_FLAG(inode->i_sb, UDF_FLAG_STRICT) || UDF_SB_UDFREV(inode->i_sb) >= 0x0201) |
| 1741 |
{ |
1874 |
{ |
| 1742 |
struct allocExtDesc *aed = (struct allocExtDesc *)(bh)->b_data; |
1875 |
struct allocExtDesc *aed = (struct allocExtDesc *)epos->bh->b_data; |
| 1743 |
udf_update_tag((bh)->b_data, |
1876 |
udf_update_tag(epos->bh->b_data, |
| 1744 |
le32_to_cpu(aed->lengthAllocDescs) + sizeof(struct allocExtDesc)); |
1877 |
le32_to_cpu(aed->lengthAllocDescs) + sizeof(struct allocExtDesc)); |
| 1745 |
} |
1878 |
} |
| 1746 |
mark_buffer_dirty_inode(bh, inode); |
1879 |
mark_buffer_dirty_inode(epos->bh, inode); |
| 1747 |
udf_release_data(bh); |
|
|
| 1748 |
} |
1880 |
} |
| 1749 |
else |
1881 |
else |
| 1750 |
mark_inode_dirty(inode); |
1882 |
mark_inode_dirty(inode); |
| 1751 |
|
1883 |
|
| 1752 |
if (inc) |
1884 |
if (inc) |
| 1753 |
*extoffset += adsize; |
1885 |
epos->offset += adsize; |
| 1754 |
return (elen >> 30); |
1886 |
return (elen >> 30); |
| 1755 |
} |
1887 |
} |
| 1756 |
|
1888 |
|
| 1757 |
int8_t udf_next_aext(struct inode *inode, kernel_lb_addr *bloc, int *extoffset, |
1889 |
int8_t udf_next_aext(struct inode *inode, struct extent_position *epos, |
| 1758 |
kernel_lb_addr *eloc, uint32_t *elen, struct buffer_head **bh, int inc) |
1890 |
kernel_lb_addr *eloc, uint32_t *elen, int inc) |
| 1759 |
{ |
1891 |
{ |
| 1760 |
int8_t etype; |
1892 |
int8_t etype; |
| 1761 |
|
1893 |
|
| 1762 |
while ((etype = udf_current_aext(inode, bloc, extoffset, eloc, elen, bh, inc)) == |
1894 |
while ((etype = udf_current_aext(inode, epos, eloc, elen, inc)) == |
| 1763 |
(EXT_NEXT_EXTENT_ALLOCDECS >> 30)) |
1895 |
(EXT_NEXT_EXTENT_ALLOCDECS >> 30)) |
| 1764 |
{ |
1896 |
{ |
| 1765 |
*bloc = *eloc; |
1897 |
epos->block = *eloc; |
| 1766 |
*extoffset = sizeof(struct allocExtDesc); |
1898 |
epos->offset = sizeof(struct allocExtDesc); |
| 1767 |
udf_release_data(*bh); |
1899 |
brelse(epos->bh); |
| 1768 |
if (!(*bh = udf_tread(inode->i_sb, udf_get_lb_pblock(inode->i_sb, *bloc, 0)))) |
1900 |
if (!(epos->bh = udf_tread(inode->i_sb, udf_get_lb_pblock(inode->i_sb, epos->block, 0)))) |
| 1769 |
{ |
1901 |
{ |
| 1770 |
udf_debug("reading block %d failed!\n", |
1902 |
udf_debug("reading block %d failed!\n", |
| 1771 |
udf_get_lb_pblock(inode->i_sb, *bloc, 0)); |
1903 |
udf_get_lb_pblock(inode->i_sb, epos->block, 0)); |
| 1772 |
return -1; |
1904 |
return -1; |
| 1773 |
} |
1905 |
} |
| 1774 |
} |
1906 |
} |
|
Lines 1776-1801
Link Here
|
| 1776 |
return etype; |
1908 |
return etype; |
| 1777 |
} |
1909 |
} |
| 1778 |
|
1910 |
|
| 1779 |
int8_t udf_current_aext(struct inode *inode, kernel_lb_addr *bloc, int *extoffset, |
1911 |
int8_t udf_current_aext(struct inode *inode, struct extent_position *epos, |
| 1780 |
kernel_lb_addr *eloc, uint32_t *elen, struct buffer_head **bh, int inc) |
1912 |
kernel_lb_addr *eloc, uint32_t *elen, int inc) |
| 1781 |
{ |
1913 |
{ |
| 1782 |
int alen; |
1914 |
int alen; |
| 1783 |
int8_t etype; |
1915 |
int8_t etype; |
| 1784 |
uint8_t *ptr; |
1916 |
uint8_t *ptr; |
| 1785 |
|
1917 |
|
| 1786 |
if (!*bh) |
1918 |
if (!epos->bh) |
| 1787 |
{ |
1919 |
{ |
| 1788 |
if (!(*extoffset)) |
1920 |
if (!epos->offset) |
| 1789 |
*extoffset = udf_file_entry_alloc_offset(inode); |
1921 |
epos->offset = udf_file_entry_alloc_offset(inode); |
| 1790 |
ptr = UDF_I_DATA(inode) + *extoffset - udf_file_entry_alloc_offset(inode) + UDF_I_LENEATTR(inode); |
1922 |
ptr = UDF_I_DATA(inode) + epos->offset - udf_file_entry_alloc_offset(inode) + UDF_I_LENEATTR(inode); |
| 1791 |
alen = udf_file_entry_alloc_offset(inode) + UDF_I_LENALLOC(inode); |
1923 |
alen = udf_file_entry_alloc_offset(inode) + UDF_I_LENALLOC(inode); |
| 1792 |
} |
1924 |
} |
| 1793 |
else |
1925 |
else |
| 1794 |
{ |
1926 |
{ |
| 1795 |
if (!(*extoffset)) |
1927 |
if (!epos->offset) |
| 1796 |
*extoffset = sizeof(struct allocExtDesc); |
1928 |
epos->offset = sizeof(struct allocExtDesc); |
| 1797 |
ptr = (*bh)->b_data + *extoffset; |
1929 |
ptr = epos->bh->b_data + epos->offset; |
| 1798 |
alen = sizeof(struct allocExtDesc) + le32_to_cpu(((struct allocExtDesc *)(*bh)->b_data)->lengthAllocDescs); |
1930 |
alen = sizeof(struct allocExtDesc) + le32_to_cpu(((struct allocExtDesc *)epos->bh->b_data)->lengthAllocDescs); |
| 1799 |
} |
1931 |
} |
| 1800 |
|
1932 |
|
| 1801 |
switch (UDF_I_ALLOCTYPE(inode)) |
1933 |
switch (UDF_I_ALLOCTYPE(inode)) |
|
Lines 1804-1810
Link Here
|
| 1804 |
{ |
1936 |
{ |
| 1805 |
short_ad *sad; |
1937 |
short_ad *sad; |
| 1806 |
|
1938 |
|
| 1807 |
if (!(sad = udf_get_fileshortad(ptr, alen, extoffset, inc))) |
1939 |
if (!(sad = udf_get_fileshortad(ptr, alen, &epos->offset, inc))) |
| 1808 |
return -1; |
1940 |
return -1; |
| 1809 |
|
1941 |
|
| 1810 |
etype = le32_to_cpu(sad->extLength) >> 30; |
1942 |
etype = le32_to_cpu(sad->extLength) >> 30; |
|
Lines 1817-1823
Link Here
|
| 1817 |
{ |
1949 |
{ |
| 1818 |
long_ad *lad; |
1950 |
long_ad *lad; |
| 1819 |
|
1951 |
|
| 1820 |
if (!(lad = udf_get_filelongad(ptr, alen, extoffset, inc))) |
1952 |
if (!(lad = udf_get_filelongad(ptr, alen, &epos->offset, inc))) |
| 1821 |
return -1; |
1953 |
return -1; |
| 1822 |
|
1954 |
|
| 1823 |
etype = le32_to_cpu(lad->extLength) >> 30; |
1955 |
etype = le32_to_cpu(lad->extLength) >> 30; |
|
Lines 1836-1876
Link Here
|
| 1836 |
} |
1968 |
} |
| 1837 |
|
1969 |
|
| 1838 |
static int8_t |
1970 |
static int8_t |
| 1839 |
udf_insert_aext(struct inode *inode, kernel_lb_addr bloc, int extoffset, |
1971 |
udf_insert_aext(struct inode *inode, struct extent_position epos, |
| 1840 |
kernel_lb_addr neloc, uint32_t nelen, struct buffer_head *bh) |
1972 |
kernel_lb_addr neloc, uint32_t nelen) |
| 1841 |
{ |
1973 |
{ |
| 1842 |
kernel_lb_addr oeloc; |
1974 |
kernel_lb_addr oeloc; |
| 1843 |
uint32_t oelen; |
1975 |
uint32_t oelen; |
| 1844 |
int8_t etype; |
1976 |
int8_t etype; |
| 1845 |
|
1977 |
|
| 1846 |
if (bh) |
1978 |
if (epos.bh) |
| 1847 |
atomic_inc(&bh->b_count); |
1979 |
get_bh(epos.bh); |
| 1848 |
|
1980 |
|
| 1849 |
while ((etype = udf_next_aext(inode, &bloc, &extoffset, &oeloc, &oelen, &bh, 0)) != -1) |
1981 |
while ((etype = udf_next_aext(inode, &epos, &oeloc, &oelen, 0)) != -1) |
| 1850 |
{ |
1982 |
{ |
| 1851 |
udf_write_aext(inode, bloc, &extoffset, neloc, nelen, bh, 1); |
1983 |
udf_write_aext(inode, &epos, neloc, nelen, 1); |
| 1852 |
|
1984 |
|
| 1853 |
neloc = oeloc; |
1985 |
neloc = oeloc; |
| 1854 |
nelen = (etype << 30) | oelen; |
1986 |
nelen = (etype << 30) | oelen; |
| 1855 |
} |
1987 |
} |
| 1856 |
udf_add_aext(inode, &bloc, &extoffset, neloc, nelen, &bh, 1); |
1988 |
udf_add_aext(inode, &epos, neloc, nelen, 1); |
| 1857 |
udf_release_data(bh); |
1989 |
brelse(epos.bh); |
| 1858 |
return (nelen >> 30); |
1990 |
return (nelen >> 30); |
| 1859 |
} |
1991 |
} |
| 1860 |
|
1992 |
|
| 1861 |
int8_t udf_delete_aext(struct inode *inode, kernel_lb_addr nbloc, int nextoffset, |
1993 |
int8_t udf_delete_aext(struct inode *inode, struct extent_position epos, |
| 1862 |
kernel_lb_addr eloc, uint32_t elen, struct buffer_head *nbh) |
1994 |
kernel_lb_addr eloc, uint32_t elen) |
| 1863 |
{ |
1995 |
{ |
| 1864 |
struct buffer_head *obh; |
1996 |
struct extent_position oepos; |
| 1865 |
kernel_lb_addr obloc; |
1997 |
int adsize; |
| 1866 |
int oextoffset, adsize; |
|
|
| 1867 |
int8_t etype; |
1998 |
int8_t etype; |
| 1868 |
struct allocExtDesc *aed; |
1999 |
struct allocExtDesc *aed; |
| 1869 |
|
2000 |
|
| 1870 |
if (nbh) |
2001 |
if (epos.bh) |
| 1871 |
{ |
2002 |
{ |
| 1872 |
atomic_inc(&nbh->b_count); |
2003 |
get_bh(epos.bh); |
| 1873 |
atomic_inc(&nbh->b_count); |
2004 |
get_bh(epos.bh); |
| 1874 |
} |
2005 |
} |
| 1875 |
|
2006 |
|
| 1876 |
if (UDF_I_ALLOCTYPE(inode) == ICBTAG_FLAG_AD_SHORT) |
2007 |
if (UDF_I_ALLOCTYPE(inode) == ICBTAG_FLAG_AD_SHORT) |
|
Lines 1880-1959
Link Here
|
| 1880 |
else |
2011 |
else |
| 1881 |
adsize = 0; |
2012 |
adsize = 0; |
| 1882 |
|
2013 |
|
| 1883 |
obh = nbh; |
2014 |
oepos = epos; |
| 1884 |
obloc = nbloc; |
2015 |
if (udf_next_aext(inode, &epos, &eloc, &elen, 1) == -1) |
| 1885 |
oextoffset = nextoffset; |
|
|
| 1886 |
|
| 1887 |
if (udf_next_aext(inode, &nbloc, &nextoffset, &eloc, &elen, &nbh, 1) == -1) |
| 1888 |
return -1; |
2016 |
return -1; |
| 1889 |
|
2017 |
|
| 1890 |
while ((etype = udf_next_aext(inode, &nbloc, &nextoffset, &eloc, &elen, &nbh, 1)) != -1) |
2018 |
while ((etype = udf_next_aext(inode, &epos, &eloc, &elen, 1)) != -1) |
| 1891 |
{ |
2019 |
{ |
| 1892 |
udf_write_aext(inode, obloc, &oextoffset, eloc, (etype << 30) | elen, obh, 1); |
2020 |
udf_write_aext(inode, &oepos, eloc, (etype << 30) | elen, 1); |
| 1893 |
if (obh != nbh) |
2021 |
if (oepos.bh != epos.bh) |
| 1894 |
{ |
2022 |
{ |
| 1895 |
obloc = nbloc; |
2023 |
oepos.block = epos.block; |
| 1896 |
udf_release_data(obh); |
2024 |
brelse(oepos.bh); |
| 1897 |
atomic_inc(&nbh->b_count); |
2025 |
get_bh(epos.bh); |
| 1898 |
obh = nbh; |
2026 |
oepos.bh = epos.bh; |
| 1899 |
oextoffset = nextoffset - adsize; |
2027 |
oepos.offset = epos.offset - adsize; |
| 1900 |
} |
2028 |
} |
| 1901 |
} |
2029 |
} |
| 1902 |
memset(&eloc, 0x00, sizeof(kernel_lb_addr)); |
2030 |
memset(&eloc, 0x00, sizeof(kernel_lb_addr)); |
| 1903 |
elen = 0; |
2031 |
elen = 0; |
| 1904 |
|
2032 |
|
| 1905 |
if (nbh != obh) |
2033 |
if (epos.bh != oepos.bh) |
| 1906 |
{ |
2034 |
{ |
| 1907 |
udf_free_blocks(inode->i_sb, inode, nbloc, 0, 1); |
2035 |
udf_free_blocks(inode->i_sb, inode, epos.block, 0, 1); |
| 1908 |
udf_write_aext(inode, obloc, &oextoffset, eloc, elen, obh, 1); |
2036 |
udf_write_aext(inode, &oepos, eloc, elen, 1); |
| 1909 |
udf_write_aext(inode, obloc, &oextoffset, eloc, elen, obh, 1); |
2037 |
udf_write_aext(inode, &oepos, eloc, elen, 1); |
| 1910 |
if (!obh) |
2038 |
if (!oepos.bh) |
| 1911 |
{ |
2039 |
{ |
| 1912 |
UDF_I_LENALLOC(inode) -= (adsize * 2); |
2040 |
UDF_I_LENALLOC(inode) -= (adsize * 2); |
| 1913 |
mark_inode_dirty(inode); |
2041 |
mark_inode_dirty(inode); |
| 1914 |
} |
2042 |
} |
| 1915 |
else |
2043 |
else |
| 1916 |
{ |
2044 |
{ |
| 1917 |
aed = (struct allocExtDesc *)(obh)->b_data; |
2045 |
aed = (struct allocExtDesc *)oepos.bh->b_data; |
| 1918 |
aed->lengthAllocDescs = |
2046 |
aed->lengthAllocDescs = |
| 1919 |
cpu_to_le32(le32_to_cpu(aed->lengthAllocDescs) - (2*adsize)); |
2047 |
cpu_to_le32(le32_to_cpu(aed->lengthAllocDescs) - (2*adsize)); |
| 1920 |
if (!UDF_QUERY_FLAG(inode->i_sb, UDF_FLAG_STRICT) || UDF_SB_UDFREV(inode->i_sb) >= 0x0201) |
2048 |
if (!UDF_QUERY_FLAG(inode->i_sb, UDF_FLAG_STRICT) || UDF_SB_UDFREV(inode->i_sb) >= 0x0201) |
| 1921 |
udf_update_tag((obh)->b_data, oextoffset - (2*adsize)); |
2049 |
udf_update_tag(oepos.bh->b_data, oepos.offset - (2*adsize)); |
| 1922 |
else |
2050 |
else |
| 1923 |
udf_update_tag((obh)->b_data, sizeof(struct allocExtDesc)); |
2051 |
udf_update_tag(oepos.bh->b_data, sizeof(struct allocExtDesc)); |
| 1924 |
mark_buffer_dirty_inode(obh, inode); |
2052 |
mark_buffer_dirty_inode(oepos.bh, inode); |
| 1925 |
} |
2053 |
} |
| 1926 |
} |
2054 |
} |
| 1927 |
else |
2055 |
else |
| 1928 |
{ |
2056 |
{ |
| 1929 |
udf_write_aext(inode, obloc, &oextoffset, eloc, elen, obh, 1); |
2057 |
udf_write_aext(inode, &oepos, eloc, elen, 1); |
| 1930 |
if (!obh) |
2058 |
if (!oepos.bh) |
| 1931 |
{ |
2059 |
{ |
| 1932 |
UDF_I_LENALLOC(inode) -= adsize; |
2060 |
UDF_I_LENALLOC(inode) -= adsize; |
| 1933 |
mark_inode_dirty(inode); |
2061 |
mark_inode_dirty(inode); |
| 1934 |
} |
2062 |
} |
| 1935 |
else |
2063 |
else |
| 1936 |
{ |
2064 |
{ |
| 1937 |
aed = (struct allocExtDesc *)(obh)->b_data; |
2065 |
aed = (struct allocExtDesc *)oepos.bh->b_data; |
| 1938 |
aed->lengthAllocDescs = |
2066 |
aed->lengthAllocDescs = |
| 1939 |
cpu_to_le32(le32_to_cpu(aed->lengthAllocDescs) - adsize); |
2067 |
cpu_to_le32(le32_to_cpu(aed->lengthAllocDescs) - adsize); |
| 1940 |
if (!UDF_QUERY_FLAG(inode->i_sb, UDF_FLAG_STRICT) || UDF_SB_UDFREV(inode->i_sb) >= 0x0201) |
2068 |
if (!UDF_QUERY_FLAG(inode->i_sb, UDF_FLAG_STRICT) || UDF_SB_UDFREV(inode->i_sb) >= 0x0201) |
| 1941 |
udf_update_tag((obh)->b_data, oextoffset - adsize); |
2069 |
udf_update_tag(oepos.bh->b_data, epos.offset - adsize); |
| 1942 |
else |
2070 |
else |
| 1943 |
udf_update_tag((obh)->b_data, sizeof(struct allocExtDesc)); |
2071 |
udf_update_tag(oepos.bh->b_data, sizeof(struct allocExtDesc)); |
| 1944 |
mark_buffer_dirty_inode(obh, inode); |
2072 |
mark_buffer_dirty_inode(oepos.bh, inode); |
| 1945 |
} |
2073 |
} |
| 1946 |
} |
2074 |
} |
| 1947 |
|
2075 |
|
| 1948 |
udf_release_data(nbh); |
2076 |
brelse(epos.bh); |
| 1949 |
udf_release_data(obh); |
2077 |
brelse(oepos.bh); |
| 1950 |
return (elen >> 30); |
2078 |
return (elen >> 30); |
| 1951 |
} |
2079 |
} |
| 1952 |
|
2080 |
|
| 1953 |
int8_t inode_bmap(struct inode *inode, int block, kernel_lb_addr *bloc, uint32_t *extoffset, |
2081 |
int8_t inode_bmap(struct inode *inode, sector_t block, struct extent_position *pos, |
| 1954 |
kernel_lb_addr *eloc, uint32_t *elen, uint32_t *offset, struct buffer_head **bh) |
2082 |
kernel_lb_addr *eloc, uint32_t *elen, sector_t *offset) |
| 1955 |
{ |
2083 |
{ |
| 1956 |
uint64_t lbcount = 0, bcount = (uint64_t)block << inode->i_sb->s_blocksize_bits; |
2084 |
loff_t lbcount = 0, bcount = (loff_t)block << inode->i_sb->s_blocksize_bits; |
| 1957 |
int8_t etype; |
2085 |
int8_t etype; |
| 1958 |
|
2086 |
|
| 1959 |
if (block < 0) |
2087 |
if (block < 0) |
|
Lines 1962-2003
Link Here
|
| 1962 |
return -1; |
2090 |
return -1; |
| 1963 |
} |
2091 |
} |
| 1964 |
|
2092 |
|
| 1965 |
*extoffset = 0; |
2093 |
pos->offset = 0; |
|
|
2094 |
pos->block = UDF_I_LOCATION(inode); |
| 2095 |
pos->bh = NULL; |
| 1966 |
*elen = 0; |
2096 |
*elen = 0; |
| 1967 |
*bloc = UDF_I_LOCATION(inode); |
|
|
| 1968 |
|
2097 |
|
| 1969 |
do |
2098 |
do |
| 1970 |
{ |
2099 |
{ |
| 1971 |
if ((etype = udf_next_aext(inode, bloc, extoffset, eloc, elen, bh, 1)) == -1) |
2100 |
if ((etype = udf_next_aext(inode, pos, eloc, elen, 1)) == -1) |
| 1972 |
{ |
2101 |
{ |
| 1973 |
*offset = bcount - lbcount; |
2102 |
*offset = (bcount - lbcount) >> inode->i_sb->s_blocksize_bits; |
| 1974 |
UDF_I_LENEXTENTS(inode) = lbcount; |
2103 |
UDF_I_LENEXTENTS(inode) = lbcount; |
| 1975 |
return -1; |
2104 |
return -1; |
| 1976 |
} |
2105 |
} |
| 1977 |
lbcount += *elen; |
2106 |
lbcount += *elen; |
| 1978 |
} while (lbcount <= bcount); |
2107 |
} while (lbcount <= bcount); |
| 1979 |
|
2108 |
|
| 1980 |
*offset = bcount + *elen - lbcount; |
2109 |
*offset = (bcount + *elen - lbcount) >> inode->i_sb->s_blocksize_bits; |
| 1981 |
|
2110 |
|
| 1982 |
return etype; |
2111 |
return etype; |
| 1983 |
} |
2112 |
} |
| 1984 |
|
2113 |
|
| 1985 |
long udf_block_map(struct inode *inode, long block) |
2114 |
long udf_block_map(struct inode *inode, sector_t block) |
| 1986 |
{ |
2115 |
{ |
| 1987 |
kernel_lb_addr eloc, bloc; |
2116 |
kernel_lb_addr eloc; |
| 1988 |
uint32_t offset, extoffset, elen; |
2117 |
uint32_t elen; |
| 1989 |
struct buffer_head *bh = NULL; |
2118 |
sector_t offset; |
|
|
2119 |
struct extent_position epos = { NULL, 0, { 0, 0}}; |
| 1990 |
int ret; |
2120 |
int ret; |
| 1991 |
|
2121 |
|
| 1992 |
lock_kernel(); |
2122 |
lock_kernel(); |
| 1993 |
|
2123 |
|
| 1994 |
if (inode_bmap(inode, block, &bloc, &extoffset, &eloc, &elen, &offset, &bh) == (EXT_RECORDED_ALLOCATED >> 30)) |
2124 |
if (inode_bmap(inode, block, &epos, &eloc, &elen, &offset) == (EXT_RECORDED_ALLOCATED >> 30)) |
| 1995 |
ret = udf_get_lb_pblock(inode->i_sb, eloc, offset >> inode->i_sb->s_blocksize_bits); |
2125 |
ret = udf_get_lb_pblock(inode->i_sb, eloc, offset); |
| 1996 |
else |
2126 |
else |
| 1997 |
ret = 0; |
2127 |
ret = 0; |
| 1998 |
|
2128 |
|
| 1999 |
unlock_kernel(); |
2129 |
unlock_kernel(); |
| 2000 |
udf_release_data(bh); |
2130 |
brelse(epos.bh); |
| 2001 |
|
2131 |
|
| 2002 |
if (UDF_QUERY_FLAG(inode->i_sb, UDF_FLAG_VARCONV)) |
2132 |
if (UDF_QUERY_FLAG(inode->i_sb, UDF_FLAG_VARCONV)) |
| 2003 |
return udf_fixed_to_variable(ret); |
2133 |
return udf_fixed_to_variable(ret); |