@@ -274,9 +274,11 @@ static int exfat_get_block(struct inode *inode, sector_t iblock,
274
274
sector_t last_block ;
275
275
sector_t phys = 0 ;
276
276
sector_t valid_blks ;
277
+ loff_t i_size ;
277
278
278
279
mutex_lock (& sbi -> s_lock );
279
- last_block = EXFAT_B_TO_BLK_ROUND_UP (i_size_read (inode ), sb );
280
+ i_size = i_size_read (inode );
281
+ last_block = EXFAT_B_TO_BLK_ROUND_UP (i_size , sb );
280
282
if (iblock >= last_block && !create )
281
283
goto done ;
282
284
@@ -305,102 +307,95 @@ static int exfat_get_block(struct inode *inode, sector_t iblock,
305
307
if (buffer_delay (bh_result ))
306
308
clear_buffer_delay (bh_result );
307
309
308
- if (create ) {
310
+ /*
311
+ * In most cases, we just need to set bh_result to mapped, unmapped
312
+ * or new status as follows:
313
+ * 1. i_size == valid_size
314
+ * 2. write case (create == 1)
315
+ * 3. direct_read (!bh_result->b_folio)
316
+ * -> the unwritten part will be zeroed in exfat_direct_IO()
317
+ *
318
+ * Otherwise, in the case of buffered read, it is necessary to take
319
+ * care the last nested block if valid_size is not equal to i_size.
320
+ */
321
+ if (i_size == ei -> valid_size || create || !bh_result -> b_folio )
309
322
valid_blks = EXFAT_B_TO_BLK_ROUND_UP (ei -> valid_size , sb );
323
+ else
324
+ valid_blks = EXFAT_B_TO_BLK (ei -> valid_size , sb );
310
325
311
- if (iblock + max_blocks < valid_blks ) {
312
- /* The range has been written, map it */
313
- goto done ;
314
- } else if (iblock < valid_blks ) {
315
- /*
316
- * The range has been partially written,
317
- * map the written part.
318
- */
319
- max_blocks = valid_blks - iblock ;
320
- goto done ;
321
- }
326
+ /* The range has been fully written, map it */
327
+ if (iblock + max_blocks < valid_blks )
328
+ goto done ;
322
329
323
- /* The area has not been written, map and mark as new. */
324
- set_buffer_new (bh_result );
330
+ /* The range has been partially written, map the written part */
331
+ if (iblock < valid_blks ) {
332
+ max_blocks = valid_blks - iblock ;
333
+ goto done ;
334
+ }
325
335
336
+ /* The area has not been written, map and mark as new for create case */
337
+ if (create ) {
338
+ set_buffer_new (bh_result );
326
339
ei -> valid_size = EXFAT_BLK_TO_B (iblock + max_blocks , sb );
327
340
mark_inode_dirty (inode );
328
- } else {
329
- valid_blks = EXFAT_B_TO_BLK ( ei -> valid_size , sb );
341
+ goto done ;
342
+ }
330
343
331
- if (iblock + max_blocks < valid_blks ) {
332
- /* The range has been written, map it */
333
- goto done ;
334
- } else if (iblock < valid_blks ) {
335
- /*
336
- * The area has been partially written,
337
- * map the written part.
338
- */
339
- max_blocks = valid_blks - iblock ;
344
+ /*
345
+ * The area has just one block partially written.
346
+ * In that case, we should read and fill the unwritten part of
347
+ * a block with zero.
348
+ */
349
+ if (bh_result -> b_folio && iblock == valid_blks &&
350
+ (ei -> valid_size & (sb -> s_blocksize - 1 ))) {
351
+ loff_t size , pos ;
352
+ void * addr ;
353
+
354
+ max_blocks = 1 ;
355
+
356
+ /*
357
+ * No buffer_head is allocated.
358
+ * (1) bmap: It's enough to set blocknr without I/O.
359
+ * (2) read: The unwritten part should be filled with zero.
360
+ * If a folio does not have any buffers,
361
+ * let's returns -EAGAIN to fallback to
362
+ * block_read_full_folio() for per-bh IO.
363
+ */
364
+ if (!folio_buffers (bh_result -> b_folio )) {
365
+ err = - EAGAIN ;
340
366
goto done ;
341
- } else if (iblock == valid_blks &&
342
- (ei -> valid_size & (sb -> s_blocksize - 1 ))) {
343
- /*
344
- * The block has been partially written,
345
- * zero the unwritten part and map the block.
346
- */
347
- loff_t size , pos ;
348
- void * addr ;
349
-
350
- max_blocks = 1 ;
351
-
352
- /*
353
- * For direct read, the unwritten part will be zeroed in
354
- * exfat_direct_IO()
355
- */
356
- if (!bh_result -> b_folio )
357
- goto done ;
358
-
359
- /*
360
- * No buffer_head is allocated.
361
- * (1) bmap: It's enough to fill bh_result without I/O.
362
- * (2) read: The unwritten part should be filled with 0
363
- * If a folio does not have any buffers,
364
- * let's returns -EAGAIN to fallback to
365
- * per-bh IO like block_read_full_folio().
366
- */
367
- if (!folio_buffers (bh_result -> b_folio )) {
368
- err = - EAGAIN ;
369
- goto done ;
370
- }
367
+ }
371
368
372
- pos = EXFAT_BLK_TO_B (iblock , sb );
373
- size = ei -> valid_size - pos ;
374
- addr = folio_address (bh_result -> b_folio ) +
375
- offset_in_folio (bh_result -> b_folio , pos );
369
+ pos = EXFAT_BLK_TO_B (iblock , sb );
370
+ size = ei -> valid_size - pos ;
371
+ addr = folio_address (bh_result -> b_folio ) +
372
+ offset_in_folio (bh_result -> b_folio , pos );
376
373
377
- /* Check if bh->b_data points to proper addr in folio */
378
- if (bh_result -> b_data != addr ) {
379
- exfat_fs_error_ratelimit (sb ,
374
+ /* Check if bh->b_data points to proper addr in folio */
375
+ if (bh_result -> b_data != addr ) {
376
+ exfat_fs_error_ratelimit (sb ,
380
377
"b_data(%p) != folio_addr(%p)" ,
381
378
bh_result -> b_data , addr );
382
- err = - EINVAL ;
383
- goto done ;
384
- }
385
-
386
- /* Read a block */
387
- err = bh_read (bh_result , 0 );
388
- if (err < 0 )
389
- goto done ;
379
+ err = - EINVAL ;
380
+ goto done ;
381
+ }
390
382
391
- /* Zero unwritten part of a block */
392
- memset (bh_result -> b_data + size , 0 ,
393
- bh_result -> b_size - size );
383
+ /* Read a block */
384
+ err = bh_read (bh_result , 0 );
385
+ if (err < 0 )
386
+ goto done ;
394
387
395
- err = 0 ;
396
- } else {
397
- /*
398
- * The range has not been written, clear the mapped flag
399
- * to only zero the cache and do not read from disk.
400
- */
401
- clear_buffer_mapped (bh_result );
402
- }
388
+ /* Zero unwritten part of a block */
389
+ memset (bh_result -> b_data + size , 0 , bh_result -> b_size - size );
390
+ err = 0 ;
391
+ goto done ;
403
392
}
393
+
394
+ /*
395
+ * The area has not been written, clear mapped for read/bmap cases.
396
+ * If so, it will be filled with zero without reading from disk.
397
+ */
398
+ clear_buffer_mapped (bh_result );
404
399
done :
405
400
bh_result -> b_size = EXFAT_BLK_TO_B (max_blocks , sb );
406
401
if (err < 0 )
0 commit comments