@@ -1288,28 +1288,29 @@ struct dentry_info_args {
12881288};
12891289
12901290static inline void tl_to_darg (struct dentry_info_args * darg ,
1291- struct ext4_fc_tl * tl )
1291+ struct ext4_fc_tl * tl , u8 * val )
12921292{
1293- struct ext4_fc_dentry_info * fcd ;
1293+ struct ext4_fc_dentry_info fcd ;
12941294
1295- fcd = ( struct ext4_fc_dentry_info * ) ext4_fc_tag_val ( tl );
1295+ memcpy ( & fcd , val , sizeof ( fcd ) );
12961296
1297- darg -> parent_ino = le32_to_cpu (fcd -> fc_parent_ino );
1298- darg -> ino = le32_to_cpu (fcd -> fc_ino );
1299- darg -> dname = fcd -> fc_dname ;
1300- darg -> dname_len = ext4_fc_tag_len (tl ) -
1301- sizeof (struct ext4_fc_dentry_info );
1297+ darg -> parent_ino = le32_to_cpu (fcd . fc_parent_ino );
1298+ darg -> ino = le32_to_cpu (fcd . fc_ino );
1299+ darg -> dname = val + offsetof( struct ext4_fc_dentry_info , fc_dname ) ;
1300+ darg -> dname_len = le16_to_cpu (tl -> fc_len ) -
1301+ sizeof (struct ext4_fc_dentry_info );
13021302}
13031303
13041304/* Unlink replay function */
1305- static int ext4_fc_replay_unlink (struct super_block * sb , struct ext4_fc_tl * tl )
1305+ static int ext4_fc_replay_unlink (struct super_block * sb , struct ext4_fc_tl * tl ,
1306+ u8 * val )
13061307{
13071308 struct inode * inode , * old_parent ;
13081309 struct qstr entry ;
13091310 struct dentry_info_args darg ;
13101311 int ret = 0 ;
13111312
1312- tl_to_darg (& darg , tl );
1313+ tl_to_darg (& darg , tl , val );
13131314
13141315 trace_ext4_fc_replay (sb , EXT4_FC_TAG_UNLINK , darg .ino ,
13151316 darg .parent_ino , darg .dname_len );
@@ -1399,13 +1400,14 @@ static int ext4_fc_replay_link_internal(struct super_block *sb,
13991400}
14001401
14011402/* Link replay function */
1402- static int ext4_fc_replay_link (struct super_block * sb , struct ext4_fc_tl * tl )
1403+ static int ext4_fc_replay_link (struct super_block * sb , struct ext4_fc_tl * tl ,
1404+ u8 * val )
14031405{
14041406 struct inode * inode ;
14051407 struct dentry_info_args darg ;
14061408 int ret = 0 ;
14071409
1408- tl_to_darg (& darg , tl );
1410+ tl_to_darg (& darg , tl , val );
14091411 trace_ext4_fc_replay (sb , EXT4_FC_TAG_LINK , darg .ino ,
14101412 darg .parent_ino , darg .dname_len );
14111413
@@ -1450,19 +1452,20 @@ static int ext4_fc_record_modified_inode(struct super_block *sb, int ino)
14501452/*
14511453 * Inode replay function
14521454 */
1453- static int ext4_fc_replay_inode (struct super_block * sb , struct ext4_fc_tl * tl )
1455+ static int ext4_fc_replay_inode (struct super_block * sb , struct ext4_fc_tl * tl ,
1456+ u8 * val )
14541457{
1455- struct ext4_fc_inode * fc_inode ;
1458+ struct ext4_fc_inode fc_inode ;
14561459 struct ext4_inode * raw_inode ;
14571460 struct ext4_inode * raw_fc_inode ;
14581461 struct inode * inode = NULL ;
14591462 struct ext4_iloc iloc ;
14601463 int inode_len , ino , ret , tag = le16_to_cpu (tl -> fc_tag );
14611464 struct ext4_extent_header * eh ;
14621465
1463- fc_inode = ( struct ext4_fc_inode * ) ext4_fc_tag_val ( tl );
1466+ memcpy ( & fc_inode , val , sizeof ( fc_inode ) );
14641467
1465- ino = le32_to_cpu (fc_inode -> fc_ino );
1468+ ino = le32_to_cpu (fc_inode . fc_ino );
14661469 trace_ext4_fc_replay (sb , tag , ino , 0 , 0 );
14671470
14681471 inode = ext4_iget (sb , ino , EXT4_IGET_NORMAL );
@@ -1474,12 +1477,13 @@ static int ext4_fc_replay_inode(struct super_block *sb, struct ext4_fc_tl *tl)
14741477
14751478 ext4_fc_record_modified_inode (sb , ino );
14761479
1477- raw_fc_inode = (struct ext4_inode * )fc_inode -> fc_raw_inode ;
1480+ raw_fc_inode = (struct ext4_inode * )
1481+ (val + offsetof(struct ext4_fc_inode , fc_raw_inode ));
14781482 ret = ext4_get_fc_inode_loc (sb , ino , & iloc );
14791483 if (ret )
14801484 goto out ;
14811485
1482- inode_len = ext4_fc_tag_len (tl ) - sizeof (struct ext4_fc_inode );
1486+ inode_len = le16_to_cpu (tl -> fc_len ) - sizeof (struct ext4_fc_inode );
14831487 raw_inode = ext4_raw_inode (& iloc );
14841488
14851489 memcpy (raw_inode , raw_fc_inode , offsetof(struct ext4_inode , i_block ));
@@ -1547,14 +1551,15 @@ static int ext4_fc_replay_inode(struct super_block *sb, struct ext4_fc_tl *tl)
15471551 * inode for which we are trying to create a dentry here, should already have
15481552 * been replayed before we start here.
15491553 */
1550- static int ext4_fc_replay_create (struct super_block * sb , struct ext4_fc_tl * tl )
1554+ static int ext4_fc_replay_create (struct super_block * sb , struct ext4_fc_tl * tl ,
1555+ u8 * val )
15511556{
15521557 int ret = 0 ;
15531558 struct inode * inode = NULL ;
15541559 struct inode * dir = NULL ;
15551560 struct dentry_info_args darg ;
15561561
1557- tl_to_darg (& darg , tl );
1562+ tl_to_darg (& darg , tl , val );
15581563
15591564 trace_ext4_fc_replay (sb , EXT4_FC_TAG_CREAT , darg .ino ,
15601565 darg .parent_ino , darg .dname_len );
@@ -1633,9 +1638,9 @@ static int ext4_fc_record_regions(struct super_block *sb, int ino,
16331638
16341639/* Replay add range tag */
16351640static int ext4_fc_replay_add_range (struct super_block * sb ,
1636- struct ext4_fc_tl * tl )
1641+ struct ext4_fc_tl * tl , u8 * val )
16371642{
1638- struct ext4_fc_add_range * fc_add_ex ;
1643+ struct ext4_fc_add_range fc_add_ex ;
16391644 struct ext4_extent newex , * ex ;
16401645 struct inode * inode ;
16411646 ext4_lblk_t start , cur ;
@@ -1645,15 +1650,14 @@ static int ext4_fc_replay_add_range(struct super_block *sb,
16451650 struct ext4_ext_path * path = NULL ;
16461651 int ret ;
16471652
1648- fc_add_ex = ( struct ext4_fc_add_range * ) ext4_fc_tag_val ( tl );
1649- ex = (struct ext4_extent * )& fc_add_ex -> fc_ex ;
1653+ memcpy ( & fc_add_ex , val , sizeof ( fc_add_ex ) );
1654+ ex = (struct ext4_extent * )& fc_add_ex . fc_ex ;
16501655
16511656 trace_ext4_fc_replay (sb , EXT4_FC_TAG_ADD_RANGE ,
1652- le32_to_cpu (fc_add_ex -> fc_ino ), le32_to_cpu (ex -> ee_block ),
1657+ le32_to_cpu (fc_add_ex . fc_ino ), le32_to_cpu (ex -> ee_block ),
16531658 ext4_ext_get_actual_len (ex ));
16541659
1655- inode = ext4_iget (sb , le32_to_cpu (fc_add_ex -> fc_ino ),
1656- EXT4_IGET_NORMAL );
1660+ inode = ext4_iget (sb , le32_to_cpu (fc_add_ex .fc_ino ), EXT4_IGET_NORMAL );
16571661 if (IS_ERR (inode )) {
16581662 jbd_debug (1 , "Inode not found." );
16591663 return 0 ;
@@ -1762,32 +1766,33 @@ static int ext4_fc_replay_add_range(struct super_block *sb,
17621766
17631767/* Replay DEL_RANGE tag */
17641768static int
1765- ext4_fc_replay_del_range (struct super_block * sb , struct ext4_fc_tl * tl )
1769+ ext4_fc_replay_del_range (struct super_block * sb , struct ext4_fc_tl * tl ,
1770+ u8 * val )
17661771{
17671772 struct inode * inode ;
1768- struct ext4_fc_del_range * lrange ;
1773+ struct ext4_fc_del_range lrange ;
17691774 struct ext4_map_blocks map ;
17701775 ext4_lblk_t cur , remaining ;
17711776 int ret ;
17721777
1773- lrange = ( struct ext4_fc_del_range * ) ext4_fc_tag_val ( tl );
1774- cur = le32_to_cpu (lrange -> fc_lblk );
1775- remaining = le32_to_cpu (lrange -> fc_len );
1778+ memcpy ( & lrange , val , sizeof ( lrange ) );
1779+ cur = le32_to_cpu (lrange . fc_lblk );
1780+ remaining = le32_to_cpu (lrange . fc_len );
17761781
17771782 trace_ext4_fc_replay (sb , EXT4_FC_TAG_DEL_RANGE ,
1778- le32_to_cpu (lrange -> fc_ino ), cur , remaining );
1783+ le32_to_cpu (lrange . fc_ino ), cur , remaining );
17791784
1780- inode = ext4_iget (sb , le32_to_cpu (lrange -> fc_ino ), EXT4_IGET_NORMAL );
1785+ inode = ext4_iget (sb , le32_to_cpu (lrange . fc_ino ), EXT4_IGET_NORMAL );
17811786 if (IS_ERR (inode )) {
1782- jbd_debug (1 , "Inode %d not found" , le32_to_cpu (lrange -> fc_ino ));
1787+ jbd_debug (1 , "Inode %d not found" , le32_to_cpu (lrange . fc_ino ));
17831788 return 0 ;
17841789 }
17851790
17861791 ret = ext4_fc_record_modified_inode (sb , inode -> i_ino );
17871792
17881793 jbd_debug (1 , "DEL_RANGE, inode %ld, lblk %d, len %d\n" ,
1789- inode -> i_ino , le32_to_cpu (lrange -> fc_lblk ),
1790- le32_to_cpu (lrange -> fc_len ));
1794+ inode -> i_ino , le32_to_cpu (lrange . fc_lblk ),
1795+ le32_to_cpu (lrange . fc_len ));
17911796 while (remaining > 0 ) {
17921797 map .m_lblk = cur ;
17931798 map .m_len = remaining ;
@@ -1808,8 +1813,8 @@ ext4_fc_replay_del_range(struct super_block *sb, struct ext4_fc_tl *tl)
18081813 }
18091814
18101815 ret = ext4_punch_hole (inode ,
1811- le32_to_cpu (lrange -> fc_lblk ) << sb -> s_blocksize_bits ,
1812- le32_to_cpu (lrange -> fc_len ) << sb -> s_blocksize_bits );
1816+ le32_to_cpu (lrange . fc_lblk ) << sb -> s_blocksize_bits ,
1817+ le32_to_cpu (lrange . fc_len ) << sb -> s_blocksize_bits );
18131818 if (ret )
18141819 jbd_debug (1 , "ext4_punch_hole returned %d" , ret );
18151820 ext4_ext_replay_shrink_inode (inode ,
@@ -1925,11 +1930,11 @@ static int ext4_fc_replay_scan(journal_t *journal,
19251930 struct ext4_sb_info * sbi = EXT4_SB (sb );
19261931 struct ext4_fc_replay_state * state ;
19271932 int ret = JBD2_FC_REPLAY_CONTINUE ;
1928- struct ext4_fc_add_range * ext ;
1929- struct ext4_fc_tl * tl ;
1930- struct ext4_fc_tail * tail ;
1931- __u8 * start , * end ;
1932- struct ext4_fc_head * head ;
1933+ struct ext4_fc_add_range ext ;
1934+ struct ext4_fc_tl tl ;
1935+ struct ext4_fc_tail tail ;
1936+ __u8 * start , * end , * cur , * val ;
1937+ struct ext4_fc_head head ;
19331938 struct ext4_extent * ex ;
19341939
19351940 state = & sbi -> s_fc_replay_state ;
@@ -1956,15 +1961,17 @@ static int ext4_fc_replay_scan(journal_t *journal,
19561961 }
19571962
19581963 state -> fc_replay_expected_off ++ ;
1959- fc_for_each_tl (start , end , tl ) {
1964+ for (cur = start ; cur < end ; cur = cur + sizeof (tl ) + le16_to_cpu (tl .fc_len )) {
1965+ memcpy (& tl , cur , sizeof (tl ));
1966+ val = cur + sizeof (tl );
19601967 jbd_debug (3 , "Scan phase, tag:%s, blk %lld\n" ,
1961- tag2str (le16_to_cpu (tl -> fc_tag )), bh -> b_blocknr );
1962- switch (le16_to_cpu (tl -> fc_tag )) {
1968+ tag2str (le16_to_cpu (tl . fc_tag )), bh -> b_blocknr );
1969+ switch (le16_to_cpu (tl . fc_tag )) {
19631970 case EXT4_FC_TAG_ADD_RANGE :
1964- ext = ( struct ext4_fc_add_range * ) ext4_fc_tag_val ( tl );
1965- ex = (struct ext4_extent * )& ext -> fc_ex ;
1971+ memcpy ( & ext , val , sizeof ( ext ) );
1972+ ex = (struct ext4_extent * )& ext . fc_ex ;
19661973 ret = ext4_fc_record_regions (sb ,
1967- le32_to_cpu (ext -> fc_ino ),
1974+ le32_to_cpu (ext . fc_ino ),
19681975 le32_to_cpu (ex -> ee_block ), ext4_ext_pblock (ex ),
19691976 ext4_ext_get_actual_len (ex ));
19701977 if (ret < 0 )
@@ -1978,18 +1985,18 @@ static int ext4_fc_replay_scan(journal_t *journal,
19781985 case EXT4_FC_TAG_INODE :
19791986 case EXT4_FC_TAG_PAD :
19801987 state -> fc_cur_tag ++ ;
1981- state -> fc_crc = ext4_chksum (sbi , state -> fc_crc , tl ,
1982- sizeof (* tl ) + ext4_fc_tag_len (tl ));
1988+ state -> fc_crc = ext4_chksum (sbi , state -> fc_crc , cur ,
1989+ sizeof (tl ) + le16_to_cpu (tl . fc_len ));
19831990 break ;
19841991 case EXT4_FC_TAG_TAIL :
19851992 state -> fc_cur_tag ++ ;
1986- tail = ( struct ext4_fc_tail * ) ext4_fc_tag_val ( tl );
1987- state -> fc_crc = ext4_chksum (sbi , state -> fc_crc , tl ,
1988- sizeof (* tl ) +
1993+ memcpy ( & tail , val , sizeof ( tail ) );
1994+ state -> fc_crc = ext4_chksum (sbi , state -> fc_crc , cur ,
1995+ sizeof (tl ) +
19891996 offsetof(struct ext4_fc_tail ,
19901997 fc_crc ));
1991- if (le32_to_cpu (tail -> fc_tid ) == expected_tid &&
1992- le32_to_cpu (tail -> fc_crc ) == state -> fc_crc ) {
1998+ if (le32_to_cpu (tail . fc_tid ) == expected_tid &&
1999+ le32_to_cpu (tail . fc_crc ) == state -> fc_crc ) {
19932000 state -> fc_replay_num_tags = state -> fc_cur_tag ;
19942001 state -> fc_regions_valid =
19952002 state -> fc_regions_used ;
@@ -2000,19 +2007,19 @@ static int ext4_fc_replay_scan(journal_t *journal,
20002007 state -> fc_crc = 0 ;
20012008 break ;
20022009 case EXT4_FC_TAG_HEAD :
2003- head = ( struct ext4_fc_head * ) ext4_fc_tag_val ( tl );
2004- if (le32_to_cpu (head -> fc_features ) &
2010+ memcpy ( & head , val , sizeof ( head ) );
2011+ if (le32_to_cpu (head . fc_features ) &
20052012 ~EXT4_FC_SUPPORTED_FEATURES ) {
20062013 ret = - EOPNOTSUPP ;
20072014 break ;
20082015 }
2009- if (le32_to_cpu (head -> fc_tid ) != expected_tid ) {
2016+ if (le32_to_cpu (head . fc_tid ) != expected_tid ) {
20102017 ret = JBD2_FC_REPLAY_STOP ;
20112018 break ;
20122019 }
20132020 state -> fc_cur_tag ++ ;
2014- state -> fc_crc = ext4_chksum (sbi , state -> fc_crc , tl ,
2015- sizeof (* tl ) + ext4_fc_tag_len (tl ));
2021+ state -> fc_crc = ext4_chksum (sbi , state -> fc_crc , cur ,
2022+ sizeof (tl ) + le16_to_cpu (tl . fc_len ));
20162023 break ;
20172024 default :
20182025 ret = state -> fc_replay_num_tags ?
@@ -2036,11 +2043,11 @@ static int ext4_fc_replay(journal_t *journal, struct buffer_head *bh,
20362043{
20372044 struct super_block * sb = journal -> j_private ;
20382045 struct ext4_sb_info * sbi = EXT4_SB (sb );
2039- struct ext4_fc_tl * tl ;
2040- __u8 * start , * end ;
2046+ struct ext4_fc_tl tl ;
2047+ __u8 * start , * end , * cur , * val ;
20412048 int ret = JBD2_FC_REPLAY_CONTINUE ;
20422049 struct ext4_fc_replay_state * state = & sbi -> s_fc_replay_state ;
2043- struct ext4_fc_tail * tail ;
2050+ struct ext4_fc_tail tail ;
20442051
20452052 if (pass == PASS_SCAN ) {
20462053 state -> fc_current_pass = PASS_SCAN ;
@@ -2067,49 +2074,52 @@ static int ext4_fc_replay(journal_t *journal, struct buffer_head *bh,
20672074 start = (u8 * )bh -> b_data ;
20682075 end = (__u8 * )bh -> b_data + journal -> j_blocksize - 1 ;
20692076
2070- fc_for_each_tl (start , end , tl ) {
2077+ for (cur = start ; cur < end ; cur = cur + sizeof (tl ) + le16_to_cpu (tl .fc_len )) {
2078+ memcpy (& tl , cur , sizeof (tl ));
2079+ val = cur + sizeof (tl );
2080+
20712081 if (state -> fc_replay_num_tags == 0 ) {
20722082 ret = JBD2_FC_REPLAY_STOP ;
20732083 ext4_fc_set_bitmaps_and_counters (sb );
20742084 break ;
20752085 }
20762086 jbd_debug (3 , "Replay phase, tag:%s\n" ,
2077- tag2str (le16_to_cpu (tl -> fc_tag )));
2087+ tag2str (le16_to_cpu (tl . fc_tag )));
20782088 state -> fc_replay_num_tags -- ;
2079- switch (le16_to_cpu (tl -> fc_tag )) {
2089+ switch (le16_to_cpu (tl . fc_tag )) {
20802090 case EXT4_FC_TAG_LINK :
2081- ret = ext4_fc_replay_link (sb , tl );
2091+ ret = ext4_fc_replay_link (sb , & tl , val );
20822092 break ;
20832093 case EXT4_FC_TAG_UNLINK :
2084- ret = ext4_fc_replay_unlink (sb , tl );
2094+ ret = ext4_fc_replay_unlink (sb , & tl , val );
20852095 break ;
20862096 case EXT4_FC_TAG_ADD_RANGE :
2087- ret = ext4_fc_replay_add_range (sb , tl );
2097+ ret = ext4_fc_replay_add_range (sb , & tl , val );
20882098 break ;
20892099 case EXT4_FC_TAG_CREAT :
2090- ret = ext4_fc_replay_create (sb , tl );
2100+ ret = ext4_fc_replay_create (sb , & tl , val );
20912101 break ;
20922102 case EXT4_FC_TAG_DEL_RANGE :
2093- ret = ext4_fc_replay_del_range (sb , tl );
2103+ ret = ext4_fc_replay_del_range (sb , & tl , val );
20942104 break ;
20952105 case EXT4_FC_TAG_INODE :
2096- ret = ext4_fc_replay_inode (sb , tl );
2106+ ret = ext4_fc_replay_inode (sb , & tl , val );
20972107 break ;
20982108 case EXT4_FC_TAG_PAD :
20992109 trace_ext4_fc_replay (sb , EXT4_FC_TAG_PAD , 0 ,
2100- ext4_fc_tag_len (tl ), 0 );
2110+ le16_to_cpu (tl . fc_len ), 0 );
21012111 break ;
21022112 case EXT4_FC_TAG_TAIL :
21032113 trace_ext4_fc_replay (sb , EXT4_FC_TAG_TAIL , 0 ,
2104- ext4_fc_tag_len (tl ), 0 );
2105- tail = ( struct ext4_fc_tail * ) ext4_fc_tag_val ( tl );
2106- WARN_ON (le32_to_cpu (tail -> fc_tid ) != expected_tid );
2114+ le16_to_cpu (tl . fc_len ), 0 );
2115+ memcpy ( & tail , val , sizeof ( tail ) );
2116+ WARN_ON (le32_to_cpu (tail . fc_tid ) != expected_tid );
21072117 break ;
21082118 case EXT4_FC_TAG_HEAD :
21092119 break ;
21102120 default :
2111- trace_ext4_fc_replay (sb , le16_to_cpu (tl -> fc_tag ), 0 ,
2112- ext4_fc_tag_len (tl ), 0 );
2121+ trace_ext4_fc_replay (sb , le16_to_cpu (tl . fc_tag ), 0 ,
2122+ le16_to_cpu (tl . fc_len ), 0 );
21132123 ret = - ECANCELED ;
21142124 break ;
21152125 }
0 commit comments