@@ -274,9 +274,11 @@ static int exfat_get_block(struct inode *inode, sector_t iblock,
274274 sector_t last_block ;
275275 sector_t phys = 0 ;
276276 sector_t valid_blks ;
277+ loff_t i_size ;
277278
278279 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 );
280282 if (iblock >= last_block && !create )
281283 goto done ;
282284
@@ -305,77 +307,99 @@ static int exfat_get_block(struct inode *inode, sector_t iblock,
305307 if (buffer_delay (bh_result ))
306308 clear_buffer_delay (bh_result );
307309
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 )
309322 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 );
310325
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 ;
322329
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+ }
325335
336+ /* The area has not been written, map and mark as new for create case */
337+ if (create ) {
338+ set_buffer_new (bh_result );
326339 ei -> valid_size = EXFAT_BLK_TO_B (iblock + max_blocks , sb );
327340 mark_inode_dirty (inode );
328- } else {
329- valid_blks = EXFAT_B_TO_BLK ( ei -> valid_size , sb );
341+ goto done ;
342+ }
330343
331- if (iblock + max_blocks < valid_blks ) {
332- /* The range has been written, map it */
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 ;
333366 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 ;
367+ }
368+
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 );
373+
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 ,
377+ "b_data(%p) != folio_addr(%p)" ,
378+ bh_result -> b_data , addr );
379+ err = - EINVAL ;
340380 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 , off , pos ;
348-
349- max_blocks = 1 ;
350-
351- /*
352- * For direct read, the unwritten part will be zeroed in
353- * exfat_direct_IO()
354- */
355- if (!bh_result -> b_folio )
356- goto done ;
357-
358- pos = EXFAT_BLK_TO_B (iblock , sb );
359- size = ei -> valid_size - pos ;
360- off = pos & (PAGE_SIZE - 1 );
361-
362- folio_set_bh (bh_result , bh_result -> b_folio , off );
363- err = bh_read (bh_result , 0 );
364- if (err < 0 )
365- goto unlock_ret ;
366-
367- folio_zero_segment (bh_result -> b_folio , off + size ,
368- off + sb -> s_blocksize );
369- } else {
370- /*
371- * The range has not been written, clear the mapped flag
372- * to only zero the cache and do not read from disk.
373- */
374- clear_buffer_mapped (bh_result );
375381 }
382+
383+ /* Read a block */
384+ err = bh_read (bh_result , 0 );
385+ if (err < 0 )
386+ goto done ;
387+
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 ;
376392 }
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 );
377399done :
378400 bh_result -> b_size = EXFAT_BLK_TO_B (max_blocks , sb );
401+ if (err < 0 )
402+ clear_buffer_mapped (bh_result );
379403unlock_ret :
380404 mutex_unlock (& sbi -> s_lock );
381405 return err ;
0 commit comments