xfs: xfs_seek_data() refinement with unwritten extents check up from page cache
PATCH v7 3/4 xfs: xfs_seek_data() refinement with unwritten extents check up from page cache
Improve xfs_seek_data() to search data offset from page cache for unwritten extents.
--- fs/xfs/xfs_file.c | 70 +++++++++++++++++++++++++++++++++++++++------------- 1 files changed, 52 insertions(+), 18 deletions(-)
fs/xfs/xfs_file.c +52 -18
@@ -1187,8 +1187,6 @@ xfs_seek_data(struct inode *inode = file->f_mapping->host;struct xfs_inode *ip =XFS_I (inode);struct xfs_mount *mp = ip->i_mount; -struct xfs_bmbt_irec map[2 ]; -int nmap =2 ;loff_t uninitialized_var (offset );xfs_fsize_t isize;xfs_fileoff_t fsbno;
@@ -1204,36 +1202,72 @@ xfs_seek_data( goto out_unlock; } - fsbno =XFS_B_TO_FSBT (mp, start); -/* * Try to read extents from the first block indicated * by fsbno to the end block of the file. */ + fsbno =XFS_B_TO_FSBT (mp, start); end =XFS_B_TO_FSB (mp, isize); +for (;;) { +struct xfs_bmbt_irec map[2 ]; +int nmap =2 ; +unsigned int i; - error =xfs_bmapi_read (ip, fsbno, end - fsbno, map, &nmap, -XFS_BMAPI_ENTIRE ); -if (error) - goto out_unlock; + error =xfs_bmapi_read (ip, fsbno, end - fsbno, map, &nmap, +XFS_BMAPI_ENTIRE ); +if (error) + goto out_unlock; -/* -* Treat unwritten extent as data extent since it might -* contains dirty data in page cache. -*/ -if (map[0 ].br_startblock !=HOLESTARTBLOCK ) { - offset =max_t (loff_t, start, -XFS_FSB_TO_B (mp, map[0 ].br_startoff)); - }else { +/* No extents at given offset, must be beyond EOF */ +if (nmap ==0 ) { + error =ENXIO ; + goto out_unlock; + } + +for (i =0 ; i < nmap; i++) { + offset =max_t (loff_t, start, +XFS_FSB_TO_B (mp, map[i].br_startoff)); + +/* Landed in a data extent */ +if (map[i].br_startblock ==DELAYSTARTBLOCK || + (map[i].br_state ==XFS_EXT_NORM && + !isnullstartblock (map[i].br_startblock))) + goto out; + +/* +* Landed in an unwritten extent, try to search data +* from page cache. +*/ +if (map[i].br_state ==XFS_EXT_UNWRITTEN ) { +if (xfs_find_get_desired_pgoff (inode, &map[i], +DATA_OFF , &offset)) + goto out; + } + } + +/* +* map[0] is hole or its an unwritten extent but +* without data in page cache. Probably means that +* we are reading after EOF if nothing in map[1]. +*/ if (nmap ==1 ) { error =ENXIO ; goto out_unlock; } - offset =max_t (loff_t, start, -XFS_FSB_TO_B (mp, map[1 ].br_startoff)); +/* +* Nothing was found, proceed to the next round of search +* if reading offset not beyond or hit EOF. +*/ + fsbno = map[i -1 ].br_startoff + map[i -1 ].br_blockcount; + start =XFS_FSB_TO_B (mp, fsbno); +if (start >= isize) { + error =ENXIO ; + goto out_unlock; + } } +out:if (offset != file->f_pos) file->f_pos = offset;
Signature · 6 lines
1.7.4.1 _______________________________________________ xfs mailing list [email protected] http://oss.sgi.com/mailman/listinfo/xfs
Quoted 5 lines · Jeff Liu
Improve
xfs_seek_data()to search data offset from page cache for unwritten extents.Signed-off-by Jie Liu<[email protected]>---
Looks good.
_______________________________________________
xfs mailing list
[email protected]
http://oss.sgi.com/mailman/listinfo/xfs
Quoted 3 lines · Jeff Liu
Improve
xfs_seek_data()to search data offset from page cache for unwritten extents.Signed-off-by Jie Liu <[email protected]>
One minor addition, otherwise
....
Quoted 7 lines
fs/xfs/xfs_file.c +6
-0+ +/* +* map[0] is hole or its an unwritten extent but +* without data in page cache. Probably means that +* we are reading after EOF if nothing in map[1]. +*/ if (nmap ==1 ) {
fs/xfs/xfs_file.c xfs_seek_data( · line 1261
Quoted 10 lines
fs/xfs/xfs_file.c +4
-2error =ENXIO ; goto out_unlock; } - offset =max_t (loff_t, start, -XFS_FSB_TO_B (mp, map[1 ].br_startoff)); +/* +* Nothing was found, proceed to the next round of search +* if reading offset not beyond or hit EOF. +*/
ASSERT(i > 1);
fs/xfs/xfs_file.c xfs_seek_data( · line 1272
Quoted 11 lines
fs/xfs/xfs_file.c +7
-0+ fsbno = map[i -1 ].br_startoff + map[i -1 ].br_blockcount; + start =XFS_FSB_TO_B (mp, fsbno); +if (start >= isize) { + error =ENXIO ; + goto out_unlock; + } } +out:if (offset != file->f_pos) file->f_pos = offset;
Cheers,
Dave.
Signature · 7 lines
Dave Chinner [email protected] _______________________________________________ xfs mailing list [email protected] http://oss.sgi.com/mailman/listinfo/xfs
Quoted 20 lines · Dave Chinner
Quoted 3 lines · Jeff Liu
Improve
xfs_seek_data()to search data offset from page cache for unwritten extents.Signed-off-by Jie Liu <[email protected]>One minor addition, otherwise
Reviewed-by Dave Chinner <[email protected]>....
Quoted 11 lines
fs/xfs/xfs_file.c +6
-0+ +/* +* map[0] is hole or its an unwritten extent but +* without data in page cache. Probably means that +* we are reading after EOF if nothing in map[1]. +*/ if (nmap ==1 ) { error =ENXIO ; goto out_unlock; }
Quoted 7 lines
fs/xfs/xfs_file.c xfs_seek_data( · line 1261
Quoted 6 lines
fs/xfs/xfs_file.c +4
-2- offset =max_t (loff_t, start, -XFS_FSB_TO_B (mp, map[1 ].br_startoff)); +/* +* Nothing was found, proceed to the next round of search +* if reading offset not beyond or hit EOF. +*/ ASSERT(i > 1);
Will add this check up.
Thanks,
-Jeff
Quoted 9 lines
Quoted 9 lines
fs/xfs/xfs_file.c +6
-0+ fsbno = map[i -1 ].br_startoff + map[i -1 ].br_blockcount; + start =XFS_FSB_TO_B (mp, fsbno); +if (start >= isize) { + error =ENXIO ; + goto out_unlock; + } }
Quoted 6 lines
fs/xfs/xfs_file.c xfs_seek_data( · line 1272
Quoted 3 lines
fs/xfs/xfs_file.c +1
-0+out:if (offset != file->f_pos) file->f_pos = offset;Cheers,
Dave.
_______________________________________________
xfs mailing list
[email protected]
http://oss.sgi.com/mailman/listinfo/xfs