@@ -49,12 +49,44 @@ xfs_alert_fsblock_zero(
4949 return - EFSCORRUPTED ;
5050}
5151
52+ u64
53+ xfs_iomap_inode_sequence (
54+ struct xfs_inode * ip ,
55+ u16 iomap_flags )
56+ {
57+ u64 cookie = 0 ;
58+
59+ if (iomap_flags & IOMAP_F_XATTR )
60+ return READ_ONCE (ip -> i_afp -> if_seq );
61+ if ((iomap_flags & IOMAP_F_SHARED ) && ip -> i_cowfp )
62+ cookie = (u64 )READ_ONCE (ip -> i_cowfp -> if_seq ) << 32 ;
63+ return cookie | READ_ONCE (ip -> i_df .if_seq );
64+ }
65+
66+ /*
67+ * Check that the iomap passed to us is still valid for the given offset and
68+ * length.
69+ */
70+ static bool
71+ xfs_iomap_valid (
72+ struct inode * inode ,
73+ const struct iomap * iomap )
74+ {
75+ return iomap -> validity_cookie ==
76+ xfs_iomap_inode_sequence (XFS_I (inode ), iomap -> flags );
77+ }
78+
79+ const struct iomap_page_ops xfs_iomap_page_ops = {
80+ .iomap_valid = xfs_iomap_valid ,
81+ };
82+
5283int
5384xfs_bmbt_to_iomap (
5485 struct xfs_inode * ip ,
5586 struct iomap * iomap ,
5687 struct xfs_bmbt_irec * imap ,
57- u16 flags )
88+ u16 flags ,
89+ u64 sequence_cookie )
5890{
5991 struct xfs_mount * mp = ip -> i_mount ;
6092 struct xfs_buftarg * target = xfs_inode_buftarg (ip );
@@ -85,6 +117,9 @@ xfs_bmbt_to_iomap(
85117 if (xfs_ipincount (ip ) &&
86118 (ip -> i_itemp -> ili_fsync_fields & ~XFS_ILOG_TIMESTAMP ))
87119 iomap -> flags |= IOMAP_F_DIRTY ;
120+
121+ iomap -> validity_cookie = sequence_cookie ;
122+ iomap -> page_ops = & xfs_iomap_page_ops ;
88123 return 0 ;
89124}
90125
@@ -188,7 +223,8 @@ xfs_iomap_write_direct(
188223 struct xfs_inode * ip ,
189224 xfs_fileoff_t offset_fsb ,
190225 xfs_fileoff_t count_fsb ,
191- struct xfs_bmbt_irec * imap )
226+ struct xfs_bmbt_irec * imap ,
227+ u64 * seq )
192228{
193229 struct xfs_mount * mp = ip -> i_mount ;
194230 struct xfs_trans * tp ;
@@ -276,6 +312,7 @@ xfs_iomap_write_direct(
276312 error = xfs_alert_fsblock_zero (ip , imap );
277313
278314out_unlock :
315+ * seq = xfs_iomap_inode_sequence (ip , 0 );
279316 xfs_iunlock (ip , XFS_ILOCK_EXCL );
280317 return error ;
281318
@@ -731,6 +768,7 @@ xfs_direct_write_iomap_begin(
731768 bool shared = false;
732769 u16 iomap_flags = 0 ;
733770 unsigned lockmode ;
771+ u64 seq ;
734772
735773 ASSERT (flags & (IOMAP_WRITE | IOMAP_ZERO ));
736774
@@ -798,9 +836,10 @@ xfs_direct_write_iomap_begin(
798836 goto out_unlock ;
799837 }
800838
839+ seq = xfs_iomap_inode_sequence (ip , iomap_flags );
801840 xfs_iunlock (ip , lockmode );
802841 trace_xfs_iomap_found (ip , offset , length , XFS_DATA_FORK , & imap );
803- return xfs_bmbt_to_iomap (ip , iomap , & imap , iomap_flags );
842+ return xfs_bmbt_to_iomap (ip , iomap , & imap , iomap_flags , seq );
804843
805844allocate_blocks :
806845 error = - EAGAIN ;
@@ -826,23 +865,26 @@ xfs_direct_write_iomap_begin(
826865 xfs_iunlock (ip , lockmode );
827866
828867 error = xfs_iomap_write_direct (ip , offset_fsb , end_fsb - offset_fsb ,
829- & imap );
868+ & imap , & seq );
830869 if (error )
831870 return error ;
832871
833872 trace_xfs_iomap_alloc (ip , offset , length , XFS_DATA_FORK , & imap );
834- return xfs_bmbt_to_iomap (ip , iomap , & imap , iomap_flags | IOMAP_F_NEW );
873+ return xfs_bmbt_to_iomap (ip , iomap , & imap ,
874+ iomap_flags | IOMAP_F_NEW , seq );
835875
836876out_found_cow :
837- xfs_iunlock (ip , lockmode );
838877 length = XFS_FSB_TO_B (mp , cmap .br_startoff + cmap .br_blockcount );
839878 trace_xfs_iomap_found (ip , offset , length - offset , XFS_COW_FORK , & cmap );
840879 if (imap .br_startblock != HOLESTARTBLOCK ) {
841- error = xfs_bmbt_to_iomap (ip , srcmap , & imap , 0 );
880+ seq = xfs_iomap_inode_sequence (ip , 0 );
881+ error = xfs_bmbt_to_iomap (ip , srcmap , & imap , 0 , seq );
842882 if (error )
843- return error ;
883+ goto out_unlock ;
844884 }
845- return xfs_bmbt_to_iomap (ip , iomap , & cmap , IOMAP_F_SHARED );
885+ seq = xfs_iomap_inode_sequence (ip , IOMAP_F_SHARED );
886+ xfs_iunlock (ip , lockmode );
887+ return xfs_bmbt_to_iomap (ip , iomap , & cmap , IOMAP_F_SHARED , seq );
846888
847889out_unlock :
848890 if (lockmode )
@@ -873,6 +915,7 @@ xfs_buffered_write_iomap_begin(
873915 bool eof = false, cow_eof = false, shared = false;
874916 int allocfork = XFS_DATA_FORK ;
875917 int error = 0 ;
918+ u64 seq ;
876919
877920 if (xfs_is_shutdown (mp ))
878921 return - EIO ;
@@ -1050,25 +1093,30 @@ xfs_buffered_write_iomap_begin(
10501093 * Flag newly allocated delalloc blocks with IOMAP_F_NEW so we punch
10511094 * them out if the write happens to fail.
10521095 */
1096+ seq = xfs_iomap_inode_sequence (ip , IOMAP_F_NEW );
10531097 xfs_iunlock (ip , XFS_ILOCK_EXCL );
10541098 trace_xfs_iomap_alloc (ip , offset , count , allocfork , & imap );
1055- return xfs_bmbt_to_iomap (ip , iomap , & imap , IOMAP_F_NEW );
1099+ return xfs_bmbt_to_iomap (ip , iomap , & imap , IOMAP_F_NEW , seq );
10561100
10571101found_imap :
1102+ seq = xfs_iomap_inode_sequence (ip , 0 );
10581103 xfs_iunlock (ip , XFS_ILOCK_EXCL );
1059- return xfs_bmbt_to_iomap (ip , iomap , & imap , 0 );
1104+ return xfs_bmbt_to_iomap (ip , iomap , & imap , 0 , seq );
10601105
10611106found_cow :
1062- xfs_iunlock (ip , XFS_ILOCK_EXCL );
1107+ seq = xfs_iomap_inode_sequence (ip , 0 );
10631108 if (imap .br_startoff <= offset_fsb ) {
1064- error = xfs_bmbt_to_iomap (ip , srcmap , & imap , 0 );
1109+ error = xfs_bmbt_to_iomap (ip , srcmap , & imap , 0 , seq );
10651110 if (error )
1066- return error ;
1067- return xfs_bmbt_to_iomap (ip , iomap , & cmap , IOMAP_F_SHARED );
1111+ goto out_unlock ;
1112+ seq = xfs_iomap_inode_sequence (ip , IOMAP_F_SHARED );
1113+ xfs_iunlock (ip , XFS_ILOCK_EXCL );
1114+ return xfs_bmbt_to_iomap (ip , iomap , & cmap , IOMAP_F_SHARED , seq );
10681115 }
10691116
10701117 xfs_trim_extent (& cmap , offset_fsb , imap .br_startoff - offset_fsb );
1071- return xfs_bmbt_to_iomap (ip , iomap , & cmap , 0 );
1118+ xfs_iunlock (ip , XFS_ILOCK_EXCL );
1119+ return xfs_bmbt_to_iomap (ip , iomap , & cmap , 0 , seq );
10721120
10731121out_unlock :
10741122 xfs_iunlock (ip , XFS_ILOCK_EXCL );
@@ -1148,6 +1196,7 @@ xfs_read_iomap_begin(
11481196 int nimaps = 1 , error = 0 ;
11491197 bool shared = false;
11501198 unsigned lockmode ;
1199+ u64 seq ;
11511200
11521201 ASSERT (!(flags & (IOMAP_WRITE | IOMAP_ZERO )));
11531202
@@ -1161,12 +1210,14 @@ xfs_read_iomap_begin(
11611210 & nimaps , 0 );
11621211 if (!error && (flags & IOMAP_REPORT ))
11631212 error = xfs_reflink_trim_around_shared (ip , & imap , & shared );
1213+ seq = xfs_iomap_inode_sequence (ip , shared ? IOMAP_F_SHARED : 0 );
11641214 xfs_iunlock (ip , lockmode );
11651215
11661216 if (error )
11671217 return error ;
11681218 trace_xfs_iomap_found (ip , offset , length , XFS_DATA_FORK , & imap );
1169- return xfs_bmbt_to_iomap (ip , iomap , & imap , shared ? IOMAP_F_SHARED : 0 );
1219+ return xfs_bmbt_to_iomap (ip , iomap , & imap ,
1220+ shared ? IOMAP_F_SHARED : 0 , seq );
11701221}
11711222
11721223const struct iomap_ops xfs_read_iomap_ops = {
@@ -1191,6 +1242,7 @@ xfs_seek_iomap_begin(
11911242 struct xfs_bmbt_irec imap , cmap ;
11921243 int error = 0 ;
11931244 unsigned lockmode ;
1245+ u64 seq ;
11941246
11951247 if (xfs_is_shutdown (mp ))
11961248 return - EIO ;
@@ -1225,7 +1277,9 @@ xfs_seek_iomap_begin(
12251277 if (data_fsb < cow_fsb + cmap .br_blockcount )
12261278 end_fsb = min (end_fsb , data_fsb );
12271279 xfs_trim_extent (& cmap , offset_fsb , end_fsb );
1228- error = xfs_bmbt_to_iomap (ip , iomap , & cmap , IOMAP_F_SHARED );
1280+ seq = xfs_iomap_inode_sequence (ip , IOMAP_F_SHARED );
1281+ error = xfs_bmbt_to_iomap (ip , iomap , & cmap ,
1282+ IOMAP_F_SHARED , seq );
12291283 /*
12301284 * This is a COW extent, so we must probe the page cache
12311285 * because there could be dirty page cache being backed
@@ -1246,8 +1300,9 @@ xfs_seek_iomap_begin(
12461300 imap .br_startblock = HOLESTARTBLOCK ;
12471301 imap .br_state = XFS_EXT_NORM ;
12481302done :
1303+ seq = xfs_iomap_inode_sequence (ip , 0 );
12491304 xfs_trim_extent (& imap , offset_fsb , end_fsb );
1250- error = xfs_bmbt_to_iomap (ip , iomap , & imap , 0 );
1305+ error = xfs_bmbt_to_iomap (ip , iomap , & imap , 0 , seq );
12511306out_unlock :
12521307 xfs_iunlock (ip , lockmode );
12531308 return error ;
@@ -1273,6 +1328,7 @@ xfs_xattr_iomap_begin(
12731328 struct xfs_bmbt_irec imap ;
12741329 int nimaps = 1 , error = 0 ;
12751330 unsigned lockmode ;
1331+ int seq = 0 ;
12761332
12771333 if (xfs_is_shutdown (mp ))
12781334 return - EIO ;
@@ -1289,12 +1345,15 @@ xfs_xattr_iomap_begin(
12891345 error = xfs_bmapi_read (ip , offset_fsb , end_fsb - offset_fsb , & imap ,
12901346 & nimaps , XFS_BMAPI_ATTRFORK );
12911347out_unlock :
1348+
1349+ if (ip -> i_afp )
1350+ seq = xfs_iomap_inode_sequence (ip , IOMAP_F_XATTR );
12921351 xfs_iunlock (ip , lockmode );
12931352
12941353 if (error )
12951354 return error ;
12961355 ASSERT (nimaps );
1297- return xfs_bmbt_to_iomap (ip , iomap , & imap , 0 );
1356+ return xfs_bmbt_to_iomap (ip , iomap , & imap , IOMAP_F_XATTR , seq );
12981357}
12991358
13001359const struct iomap_ops xfs_xattr_iomap_ops = {
0 commit comments