LCOV - code coverage report
Current view: top level - fs/ext4 - migrate.c (source / functions) Hit Total Coverage
Test: combined.info Lines: 0 342 0.0 %
Date: 2022-03-28 13:20:08 Functions: 0 13 0.0 %
Branches: 0 166 0.0 %

           Branch data     Line data    Source code
       1                 :            : // SPDX-License-Identifier: LGPL-2.1
       2                 :            : /*
       3                 :            :  * Copyright IBM Corporation, 2007
       4                 :            :  * Author Aneesh Kumar K.V <aneesh.kumar@linux.vnet.ibm.com>
       5                 :            :  *
       6                 :            :  */
       7                 :            : 
       8                 :            : #include <linux/slab.h>
       9                 :            : #include "ext4_jbd2.h"
      10                 :            : #include "ext4_extents.h"
      11                 :            : 
      12                 :            : /*
      13                 :            :  * The contiguous blocks details which can be
      14                 :            :  * represented by a single extent
      15                 :            :  */
      16                 :            : struct migrate_struct {
      17                 :            :         ext4_lblk_t first_block, last_block, curr_block;
      18                 :            :         ext4_fsblk_t first_pblock, last_pblock;
      19                 :            : };
      20                 :            : 
      21                 :          0 : static int finish_range(handle_t *handle, struct inode *inode,
      22                 :            :                                 struct migrate_struct *lb)
      23                 :            : 
      24                 :            : {
      25                 :          0 :         int retval = 0, needed;
      26                 :          0 :         struct ext4_extent newext;
      27                 :          0 :         struct ext4_ext_path *path;
      28         [ #  # ]:          0 :         if (lb->first_pblock == 0)
      29                 :            :                 return 0;
      30                 :            : 
      31                 :            :         /* Add the extent to temp inode*/
      32                 :          0 :         newext.ee_block = cpu_to_le32(lb->first_block);
      33                 :          0 :         newext.ee_len   = cpu_to_le16(lb->last_block - lb->first_block + 1);
      34                 :          0 :         ext4_ext_store_pblock(&newext, lb->first_pblock);
      35                 :            :         /* Locking only for convinience since we are operating on temp inode */
      36                 :          0 :         down_write(&EXT4_I(inode)->i_data_sem);
      37                 :          0 :         path = ext4_find_extent(inode, lb->first_block, NULL, 0);
      38         [ #  # ]:          0 :         if (IS_ERR(path)) {
      39                 :          0 :                 retval = PTR_ERR(path);
      40                 :          0 :                 path = NULL;
      41                 :          0 :                 goto err_out;
      42                 :            :         }
      43                 :            : 
      44                 :            :         /*
      45                 :            :          * Calculate the credit needed to inserting this extent
      46                 :            :          * Since we are doing this in loop we may accumalate extra
      47                 :            :          * credit. But below we try to not accumalate too much
      48                 :            :          * of them by restarting the journal.
      49                 :            :          */
      50                 :          0 :         needed = ext4_ext_calc_credits_for_single_extent(inode,
      51                 :          0 :                     lb->last_block - lb->first_block + 1, path);
      52                 :            : 
      53                 :          0 :         retval = ext4_datasem_ensure_credits(handle, inode, needed, needed, 0);
      54         [ #  # ]:          0 :         if (retval < 0)
      55                 :          0 :                 goto err_out;
      56                 :          0 :         retval = ext4_ext_insert_extent(handle, inode, &path, &newext, 0);
      57                 :          0 : err_out:
      58                 :          0 :         up_write((&EXT4_I(inode)->i_data_sem));
      59                 :          0 :         ext4_ext_drop_refs(path);
      60                 :          0 :         kfree(path);
      61                 :          0 :         lb->first_pblock = 0;
      62                 :          0 :         return retval;
      63                 :            : }
      64                 :            : 
      65                 :          0 : static int update_extent_range(handle_t *handle, struct inode *inode,
      66                 :            :                                ext4_fsblk_t pblock, struct migrate_struct *lb)
      67                 :            : {
      68                 :          0 :         int retval;
      69                 :            :         /*
      70                 :            :          * See if we can add on to the existing range (if it exists)
      71                 :            :          */
      72         [ #  # ]:          0 :         if (lb->first_pblock &&
      73         [ #  # ]:          0 :                 (lb->last_pblock+1 == pblock) &&
      74         [ #  # ]:          0 :                 (lb->last_block+1 == lb->curr_block)) {
      75                 :          0 :                 lb->last_pblock = pblock;
      76                 :          0 :                 lb->last_block = lb->curr_block;
      77                 :          0 :                 lb->curr_block++;
      78                 :          0 :                 return 0;
      79                 :            :         }
      80                 :            :         /*
      81                 :            :          * Start a new range.
      82                 :            :          */
      83                 :          0 :         retval = finish_range(handle, inode, lb);
      84                 :          0 :         lb->first_pblock = lb->last_pblock = pblock;
      85                 :          0 :         lb->first_block = lb->last_block = lb->curr_block;
      86                 :          0 :         lb->curr_block++;
      87                 :          0 :         return retval;
      88                 :            : }
      89                 :            : 
      90                 :          0 : static int update_ind_extent_range(handle_t *handle, struct inode *inode,
      91                 :            :                                    ext4_fsblk_t pblock,
      92                 :            :                                    struct migrate_struct *lb)
      93                 :            : {
      94                 :          0 :         struct buffer_head *bh;
      95                 :          0 :         __le32 *i_data;
      96                 :          0 :         int i, retval = 0;
      97                 :          0 :         unsigned long max_entries = inode->i_sb->s_blocksize >> 2;
      98                 :            : 
      99                 :          0 :         bh = ext4_sb_bread(inode->i_sb, pblock, 0);
     100         [ #  # ]:          0 :         if (IS_ERR(bh))
     101                 :          0 :                 return PTR_ERR(bh);
     102                 :            : 
     103                 :          0 :         i_data = (__le32 *)bh->b_data;
     104         [ #  # ]:          0 :         for (i = 0; i < max_entries; i++) {
     105         [ #  # ]:          0 :                 if (i_data[i]) {
     106                 :          0 :                         retval = update_extent_range(handle, inode,
     107                 :            :                                                 le32_to_cpu(i_data[i]), lb);
     108         [ #  # ]:          0 :                         if (retval)
     109                 :            :                                 break;
     110                 :            :                 } else {
     111                 :          0 :                         lb->curr_block++;
     112                 :            :                 }
     113                 :            :         }
     114                 :          0 :         put_bh(bh);
     115                 :          0 :         return retval;
     116                 :            : 
     117                 :            : }
     118                 :            : 
     119                 :          0 : static int update_dind_extent_range(handle_t *handle, struct inode *inode,
     120                 :            :                                     ext4_fsblk_t pblock,
     121                 :            :                                     struct migrate_struct *lb)
     122                 :            : {
     123                 :          0 :         struct buffer_head *bh;
     124                 :          0 :         __le32 *i_data;
     125                 :          0 :         int i, retval = 0;
     126                 :          0 :         unsigned long max_entries = inode->i_sb->s_blocksize >> 2;
     127                 :            : 
     128                 :          0 :         bh = ext4_sb_bread(inode->i_sb, pblock, 0);
     129         [ #  # ]:          0 :         if (IS_ERR(bh))
     130                 :          0 :                 return PTR_ERR(bh);
     131                 :            : 
     132                 :          0 :         i_data = (__le32 *)bh->b_data;
     133         [ #  # ]:          0 :         for (i = 0; i < max_entries; i++) {
     134         [ #  # ]:          0 :                 if (i_data[i]) {
     135                 :          0 :                         retval = update_ind_extent_range(handle, inode,
     136                 :            :                                                 le32_to_cpu(i_data[i]), lb);
     137         [ #  # ]:          0 :                         if (retval)
     138                 :            :                                 break;
     139                 :            :                 } else {
     140                 :            :                         /* Only update the file block number */
     141                 :          0 :                         lb->curr_block += max_entries;
     142                 :            :                 }
     143                 :            :         }
     144                 :          0 :         put_bh(bh);
     145                 :          0 :         return retval;
     146                 :            : 
     147                 :            : }
     148                 :            : 
     149                 :          0 : static int update_tind_extent_range(handle_t *handle, struct inode *inode,
     150                 :            :                                     ext4_fsblk_t pblock,
     151                 :            :                                     struct migrate_struct *lb)
     152                 :            : {
     153                 :          0 :         struct buffer_head *bh;
     154                 :          0 :         __le32 *i_data;
     155                 :          0 :         int i, retval = 0;
     156                 :          0 :         unsigned long max_entries = inode->i_sb->s_blocksize >> 2;
     157                 :            : 
     158                 :          0 :         bh = ext4_sb_bread(inode->i_sb, pblock, 0);
     159         [ #  # ]:          0 :         if (IS_ERR(bh))
     160                 :          0 :                 return PTR_ERR(bh);
     161                 :            : 
     162                 :          0 :         i_data = (__le32 *)bh->b_data;
     163         [ #  # ]:          0 :         for (i = 0; i < max_entries; i++) {
     164         [ #  # ]:          0 :                 if (i_data[i]) {
     165                 :          0 :                         retval = update_dind_extent_range(handle, inode,
     166                 :            :                                                 le32_to_cpu(i_data[i]), lb);
     167         [ #  # ]:          0 :                         if (retval)
     168                 :            :                                 break;
     169                 :            :                 } else {
     170                 :            :                         /* Only update the file block number */
     171                 :          0 :                         lb->curr_block += max_entries * max_entries;
     172                 :            :                 }
     173                 :            :         }
     174                 :          0 :         put_bh(bh);
     175                 :          0 :         return retval;
     176                 :            : 
     177                 :            : }
     178                 :            : 
     179                 :          0 : static int free_dind_blocks(handle_t *handle,
     180                 :            :                                 struct inode *inode, __le32 i_data)
     181                 :            : {
     182                 :          0 :         int i;
     183                 :          0 :         __le32 *tmp_idata;
     184                 :          0 :         struct buffer_head *bh;
     185                 :          0 :         struct super_block *sb = inode->i_sb;
     186                 :          0 :         unsigned long max_entries = inode->i_sb->s_blocksize >> 2;
     187                 :          0 :         int err;
     188                 :            : 
     189                 :          0 :         bh = ext4_sb_bread(sb, le32_to_cpu(i_data), 0);
     190         [ #  # ]:          0 :         if (IS_ERR(bh))
     191                 :          0 :                 return PTR_ERR(bh);
     192                 :            : 
     193                 :          0 :         tmp_idata = (__le32 *)bh->b_data;
     194         [ #  # ]:          0 :         for (i = 0; i < max_entries; i++) {
     195         [ #  # ]:          0 :                 if (tmp_idata[i]) {
     196                 :          0 :                         err = ext4_journal_ensure_credits(handle,
     197                 :            :                                 EXT4_RESERVE_TRANS_BLOCKS,
     198                 :            :                                 ext4_free_metadata_revoke_credits(sb, 1));
     199         [ #  # ]:          0 :                         if (err < 0) {
     200                 :          0 :                                 put_bh(bh);
     201                 :          0 :                                 return err;
     202                 :            :                         }
     203                 :          0 :                         ext4_free_blocks(handle, inode, NULL,
     204                 :          0 :                                          le32_to_cpu(tmp_idata[i]), 1,
     205                 :            :                                          EXT4_FREE_BLOCKS_METADATA |
     206                 :            :                                          EXT4_FREE_BLOCKS_FORGET);
     207                 :            :                 }
     208                 :            :         }
     209                 :          0 :         put_bh(bh);
     210                 :          0 :         err = ext4_journal_ensure_credits(handle, EXT4_RESERVE_TRANS_BLOCKS,
     211                 :            :                                 ext4_free_metadata_revoke_credits(sb, 1));
     212         [ #  # ]:          0 :         if (err < 0)
     213                 :            :                 return err;
     214                 :          0 :         ext4_free_blocks(handle, inode, NULL, le32_to_cpu(i_data), 1,
     215                 :            :                          EXT4_FREE_BLOCKS_METADATA |
     216                 :            :                          EXT4_FREE_BLOCKS_FORGET);
     217                 :          0 :         return 0;
     218                 :            : }
     219                 :            : 
     220                 :          0 : static int free_tind_blocks(handle_t *handle,
     221                 :            :                                 struct inode *inode, __le32 i_data)
     222                 :            : {
     223                 :          0 :         int i, retval = 0;
     224                 :          0 :         __le32 *tmp_idata;
     225                 :          0 :         struct buffer_head *bh;
     226                 :          0 :         unsigned long max_entries = inode->i_sb->s_blocksize >> 2;
     227                 :            : 
     228                 :          0 :         bh = ext4_sb_bread(inode->i_sb, le32_to_cpu(i_data), 0);
     229         [ #  # ]:          0 :         if (IS_ERR(bh))
     230                 :          0 :                 return PTR_ERR(bh);
     231                 :            : 
     232                 :          0 :         tmp_idata = (__le32 *)bh->b_data;
     233         [ #  # ]:          0 :         for (i = 0; i < max_entries; i++) {
     234         [ #  # ]:          0 :                 if (tmp_idata[i]) {
     235                 :          0 :                         retval = free_dind_blocks(handle,
     236                 :            :                                         inode, tmp_idata[i]);
     237         [ #  # ]:          0 :                         if (retval) {
     238                 :          0 :                                 put_bh(bh);
     239                 :          0 :                                 return retval;
     240                 :            :                         }
     241                 :            :                 }
     242                 :            :         }
     243                 :          0 :         put_bh(bh);
     244                 :          0 :         retval = ext4_journal_ensure_credits(handle, EXT4_RESERVE_TRANS_BLOCKS,
     245                 :            :                         ext4_free_metadata_revoke_credits(inode->i_sb, 1));
     246         [ #  # ]:          0 :         if (retval < 0)
     247                 :            :                 return retval;
     248                 :          0 :         ext4_free_blocks(handle, inode, NULL, le32_to_cpu(i_data), 1,
     249                 :            :                          EXT4_FREE_BLOCKS_METADATA |
     250                 :            :                          EXT4_FREE_BLOCKS_FORGET);
     251                 :          0 :         return 0;
     252                 :            : }
     253                 :            : 
     254                 :          0 : static int free_ind_block(handle_t *handle, struct inode *inode, __le32 *i_data)
     255                 :            : {
     256                 :          0 :         int retval;
     257                 :            : 
     258                 :            :         /* ei->i_data[EXT4_IND_BLOCK] */
     259         [ #  # ]:          0 :         if (i_data[0]) {
     260                 :          0 :                 retval = ext4_journal_ensure_credits(handle,
     261                 :            :                         EXT4_RESERVE_TRANS_BLOCKS,
     262                 :            :                         ext4_free_metadata_revoke_credits(inode->i_sb, 1));
     263         [ #  # ]:          0 :                 if (retval < 0)
     264                 :            :                         return retval;
     265                 :          0 :                 ext4_free_blocks(handle, inode, NULL,
     266                 :          0 :                                 le32_to_cpu(i_data[0]), 1,
     267                 :            :                                  EXT4_FREE_BLOCKS_METADATA |
     268                 :            :                                  EXT4_FREE_BLOCKS_FORGET);
     269                 :            :         }
     270                 :            : 
     271                 :            :         /* ei->i_data[EXT4_DIND_BLOCK] */
     272         [ #  # ]:          0 :         if (i_data[1]) {
     273                 :          0 :                 retval = free_dind_blocks(handle, inode, i_data[1]);
     274         [ #  # ]:          0 :                 if (retval)
     275                 :            :                         return retval;
     276                 :            :         }
     277                 :            : 
     278                 :            :         /* ei->i_data[EXT4_TIND_BLOCK] */
     279         [ #  # ]:          0 :         if (i_data[2]) {
     280                 :          0 :                 retval = free_tind_blocks(handle, inode, i_data[2]);
     281         [ #  # ]:          0 :                 if (retval)
     282                 :          0 :                         return retval;
     283                 :            :         }
     284                 :            :         return 0;
     285                 :            : }
     286                 :            : 
     287                 :          0 : static int ext4_ext_swap_inode_data(handle_t *handle, struct inode *inode,
     288                 :            :                                                 struct inode *tmp_inode)
     289                 :            : {
     290                 :          0 :         int retval;
     291                 :          0 :         __le32  i_data[3];
     292                 :          0 :         struct ext4_inode_info *ei = EXT4_I(inode);
     293                 :          0 :         struct ext4_inode_info *tmp_ei = EXT4_I(tmp_inode);
     294                 :            : 
     295                 :            :         /*
     296                 :            :          * One credit accounted for writing the
     297                 :            :          * i_data field of the original inode
     298                 :            :          */
     299                 :          0 :         retval = ext4_journal_ensure_credits(handle, 1, 0);
     300         [ #  # ]:          0 :         if (retval < 0)
     301                 :          0 :                 goto err_out;
     302                 :            : 
     303                 :          0 :         i_data[0] = ei->i_data[EXT4_IND_BLOCK];
     304                 :          0 :         i_data[1] = ei->i_data[EXT4_DIND_BLOCK];
     305                 :          0 :         i_data[2] = ei->i_data[EXT4_TIND_BLOCK];
     306                 :            : 
     307                 :          0 :         down_write(&EXT4_I(inode)->i_data_sem);
     308                 :            :         /*
     309                 :            :          * if EXT4_STATE_EXT_MIGRATE is cleared a block allocation
     310                 :            :          * happened after we started the migrate. We need to
     311                 :            :          * fail the migrate
     312                 :            :          */
     313         [ #  # ]:          0 :         if (!ext4_test_inode_state(inode, EXT4_STATE_EXT_MIGRATE)) {
     314                 :          0 :                 retval = -EAGAIN;
     315                 :          0 :                 up_write(&EXT4_I(inode)->i_data_sem);
     316                 :          0 :                 goto err_out;
     317                 :            :         } else
     318                 :          0 :                 ext4_clear_inode_state(inode, EXT4_STATE_EXT_MIGRATE);
     319                 :            :         /*
     320                 :            :          * We have the extent map build with the tmp inode.
     321                 :            :          * Now copy the i_data across
     322                 :            :          */
     323                 :          0 :         ext4_set_inode_flag(inode, EXT4_INODE_EXTENTS);
     324                 :          0 :         memcpy(ei->i_data, tmp_ei->i_data, sizeof(ei->i_data));
     325                 :            : 
     326                 :            :         /*
     327                 :            :          * Update i_blocks with the new blocks that got
     328                 :            :          * allocated while adding extents for extent index
     329                 :            :          * blocks.
     330                 :            :          *
     331                 :            :          * While converting to extents we need not
     332                 :            :          * update the original inode i_blocks for extent blocks
     333                 :            :          * via quota APIs. The quota update happened via tmp_inode already.
     334                 :            :          */
     335                 :          0 :         spin_lock(&inode->i_lock);
     336                 :          0 :         inode->i_blocks += tmp_inode->i_blocks;
     337                 :          0 :         spin_unlock(&inode->i_lock);
     338                 :          0 :         up_write(&EXT4_I(inode)->i_data_sem);
     339                 :            : 
     340                 :            :         /*
     341                 :            :          * We mark the inode dirty after, because we decrement the
     342                 :            :          * i_blocks when freeing the indirect meta-data blocks
     343                 :            :          */
     344                 :          0 :         retval = free_ind_block(handle, inode, i_data);
     345                 :          0 :         ext4_mark_inode_dirty(handle, inode);
     346                 :            : 
     347                 :          0 : err_out:
     348                 :          0 :         return retval;
     349                 :            : }
     350                 :            : 
     351                 :          0 : static int free_ext_idx(handle_t *handle, struct inode *inode,
     352                 :            :                                         struct ext4_extent_idx *ix)
     353                 :            : {
     354                 :          0 :         int i, retval = 0;
     355                 :          0 :         ext4_fsblk_t block;
     356                 :          0 :         struct buffer_head *bh;
     357                 :          0 :         struct ext4_extent_header *eh;
     358                 :            : 
     359                 :          0 :         block = ext4_idx_pblock(ix);
     360                 :          0 :         bh = ext4_sb_bread(inode->i_sb, block, 0);
     361         [ #  # ]:          0 :         if (IS_ERR(bh))
     362                 :          0 :                 return PTR_ERR(bh);
     363                 :            : 
     364                 :          0 :         eh = (struct ext4_extent_header *)bh->b_data;
     365         [ #  # ]:          0 :         if (eh->eh_depth != 0) {
     366                 :          0 :                 ix = EXT_FIRST_INDEX(eh);
     367         [ #  # ]:          0 :                 for (i = 0; i < le16_to_cpu(eh->eh_entries); i++, ix++) {
     368                 :          0 :                         retval = free_ext_idx(handle, inode, ix);
     369         [ #  # ]:          0 :                         if (retval) {
     370                 :          0 :                                 put_bh(bh);
     371                 :          0 :                                 return retval;
     372                 :            :                         }
     373                 :            :                 }
     374                 :            :         }
     375                 :          0 :         put_bh(bh);
     376                 :          0 :         retval = ext4_journal_ensure_credits(handle, EXT4_RESERVE_TRANS_BLOCKS,
     377                 :            :                         ext4_free_metadata_revoke_credits(inode->i_sb, 1));
     378         [ #  # ]:          0 :         if (retval < 0)
     379                 :            :                 return retval;
     380                 :          0 :         ext4_free_blocks(handle, inode, NULL, block, 1,
     381                 :            :                          EXT4_FREE_BLOCKS_METADATA | EXT4_FREE_BLOCKS_FORGET);
     382                 :          0 :         return 0;
     383                 :            : }
     384                 :            : 
     385                 :            : /*
     386                 :            :  * Free the extent meta data blocks only
     387                 :            :  */
     388                 :          0 : static int free_ext_block(handle_t *handle, struct inode *inode)
     389                 :            : {
     390                 :          0 :         int i, retval = 0;
     391         [ #  # ]:          0 :         struct ext4_inode_info *ei = EXT4_I(inode);
     392                 :          0 :         struct ext4_extent_header *eh = (struct ext4_extent_header *)ei->i_data;
     393                 :          0 :         struct ext4_extent_idx *ix;
     394         [ #  # ]:          0 :         if (eh->eh_depth == 0)
     395                 :            :                 /*
     396                 :            :                  * No extra blocks allocated for extent meta data
     397                 :            :                  */
     398                 :            :                 return 0;
     399                 :          0 :         ix = EXT_FIRST_INDEX(eh);
     400         [ #  # ]:          0 :         for (i = 0; i < le16_to_cpu(eh->eh_entries); i++, ix++) {
     401                 :          0 :                 retval = free_ext_idx(handle, inode, ix);
     402         [ #  # ]:          0 :                 if (retval)
     403                 :          0 :                         return retval;
     404                 :            :         }
     405                 :            :         return retval;
     406                 :            : }
     407                 :            : 
     408                 :          0 : int ext4_ext_migrate(struct inode *inode)
     409                 :            : {
     410         [ #  # ]:          0 :         struct ext4_sb_info *sbi = EXT4_SB(inode->i_sb);
     411                 :          0 :         handle_t *handle;
     412                 :          0 :         int retval = 0, i;
     413                 :          0 :         __le32 *i_data;
     414                 :          0 :         struct ext4_inode_info *ei;
     415                 :          0 :         struct inode *tmp_inode = NULL;
     416                 :          0 :         struct migrate_struct lb;
     417                 :          0 :         unsigned long max_entries;
     418                 :          0 :         __u32 goal;
     419                 :          0 :         uid_t owner[2];
     420                 :            : 
     421                 :            :         /*
     422                 :            :          * If the filesystem does not support extents, or the inode
     423                 :            :          * already is extent-based, error out.
     424                 :            :          */
     425   [ #  #  #  # ]:          0 :         if (!ext4_has_feature_extents(inode->i_sb) ||
     426                 :            :             (ext4_test_inode_flag(inode, EXT4_INODE_EXTENTS)))
     427                 :          0 :                 return -EINVAL;
     428                 :            : 
     429   [ #  #  #  # ]:          0 :         if (S_ISLNK(inode->i_mode) && inode->i_blocks == 0)
     430                 :            :                 /*
     431                 :            :                  * don't migrate fast symlink
     432                 :            :                  */
     433                 :            :                 return retval;
     434                 :            : 
     435                 :          0 :         percpu_down_write(&sbi->s_writepages_rwsem);
     436                 :            : 
     437                 :            :         /*
     438                 :            :          * Worst case we can touch the allocation bitmaps, a bgd
     439                 :            :          * block, and a block to link in the orphan list.  We do need
     440                 :            :          * need to worry about credits for modifying the quota inode.
     441                 :            :          */
     442   [ #  #  #  # ]:          0 :         handle = ext4_journal_start(inode, EXT4_HT_MIGRATE,
     443                 :            :                 4 + EXT4_MAXQUOTAS_TRANS_BLOCKS(inode->i_sb));
     444                 :            : 
     445         [ #  # ]:          0 :         if (IS_ERR(handle)) {
     446                 :          0 :                 retval = PTR_ERR(handle);
     447                 :          0 :                 goto out_unlock;
     448                 :            :         }
     449                 :          0 :         goal = (((inode->i_ino - 1) / EXT4_INODES_PER_GROUP(inode->i_sb)) *
     450                 :          0 :                 EXT4_INODES_PER_GROUP(inode->i_sb)) + 1;
     451                 :          0 :         owner[0] = i_uid_read(inode);
     452                 :          0 :         owner[1] = i_gid_read(inode);
     453                 :          0 :         tmp_inode = ext4_new_inode(handle, d_inode(inode->i_sb->s_root),
     454                 :            :                                    S_IFREG, NULL, goal, owner, 0);
     455         [ #  # ]:          0 :         if (IS_ERR(tmp_inode)) {
     456                 :          0 :                 retval = PTR_ERR(tmp_inode);
     457                 :          0 :                 ext4_journal_stop(handle);
     458                 :          0 :                 goto out_unlock;
     459                 :            :         }
     460                 :          0 :         i_size_write(tmp_inode, i_size_read(inode));
     461                 :            :         /*
     462                 :            :          * Set the i_nlink to zero so it will be deleted later
     463                 :            :          * when we drop inode reference.
     464                 :            :          */
     465                 :          0 :         clear_nlink(tmp_inode);
     466                 :            : 
     467                 :          0 :         ext4_ext_tree_init(handle, tmp_inode);
     468                 :          0 :         ext4_orphan_add(handle, tmp_inode);
     469                 :          0 :         ext4_journal_stop(handle);
     470                 :            : 
     471                 :            :         /*
     472                 :            :          * start with one credit accounted for
     473                 :            :          * superblock modification.
     474                 :            :          *
     475                 :            :          * For the tmp_inode we already have committed the
     476                 :            :          * transaction that created the inode. Later as and
     477                 :            :          * when we add extents we extent the journal
     478                 :            :          */
     479                 :            :         /*
     480                 :            :          * Even though we take i_mutex we can still cause block
     481                 :            :          * allocation via mmap write to holes. If we have allocated
     482                 :            :          * new blocks we fail migrate.  New block allocation will
     483                 :            :          * clear EXT4_STATE_EXT_MIGRATE flag.  The flag is updated
     484                 :            :          * with i_data_sem held to prevent racing with block
     485                 :            :          * allocation.
     486                 :            :          */
     487                 :          0 :         down_read(&EXT4_I(inode)->i_data_sem);
     488                 :          0 :         ext4_set_inode_state(inode, EXT4_STATE_EXT_MIGRATE);
     489                 :          0 :         up_read((&EXT4_I(inode)->i_data_sem));
     490                 :            : 
     491                 :          0 :         handle = ext4_journal_start(inode, EXT4_HT_MIGRATE, 1);
     492         [ #  # ]:          0 :         if (IS_ERR(handle)) {
     493                 :            :                 /*
     494                 :            :                  * It is impossible to update on-disk structures without
     495                 :            :                  * a handle, so just rollback in-core changes and live other
     496                 :            :                  * work to orphan_list_cleanup()
     497                 :            :                  */
     498                 :          0 :                 ext4_orphan_del(NULL, tmp_inode);
     499                 :          0 :                 retval = PTR_ERR(handle);
     500                 :          0 :                 goto out_tmp_inode;
     501                 :            :         }
     502                 :            : 
     503                 :          0 :         ei = EXT4_I(inode);
     504                 :          0 :         i_data = ei->i_data;
     505                 :          0 :         memset(&lb, 0, sizeof(lb));
     506                 :            : 
     507                 :            :         /* 32 bit block address 4 bytes */
     508                 :          0 :         max_entries = inode->i_sb->s_blocksize >> 2;
     509         [ #  # ]:          0 :         for (i = 0; i < EXT4_NDIR_BLOCKS; i++) {
     510         [ #  # ]:          0 :                 if (i_data[i]) {
     511                 :          0 :                         retval = update_extent_range(handle, tmp_inode,
     512                 :            :                                                 le32_to_cpu(i_data[i]), &lb);
     513         [ #  # ]:          0 :                         if (retval)
     514                 :          0 :                                 goto err_out;
     515                 :            :                 } else
     516                 :          0 :                         lb.curr_block++;
     517                 :            :         }
     518         [ #  # ]:          0 :         if (i_data[EXT4_IND_BLOCK]) {
     519                 :          0 :                 retval = update_ind_extent_range(handle, tmp_inode,
     520                 :            :                                 le32_to_cpu(i_data[EXT4_IND_BLOCK]), &lb);
     521         [ #  # ]:          0 :                 if (retval)
     522                 :          0 :                         goto err_out;
     523                 :            :         } else
     524                 :          0 :                 lb.curr_block += max_entries;
     525         [ #  # ]:          0 :         if (i_data[EXT4_DIND_BLOCK]) {
     526                 :          0 :                 retval = update_dind_extent_range(handle, tmp_inode,
     527                 :            :                                 le32_to_cpu(i_data[EXT4_DIND_BLOCK]), &lb);
     528         [ #  # ]:          0 :                 if (retval)
     529                 :          0 :                         goto err_out;
     530                 :            :         } else
     531                 :          0 :                 lb.curr_block += max_entries * max_entries;
     532         [ #  # ]:          0 :         if (i_data[EXT4_TIND_BLOCK]) {
     533                 :          0 :                 retval = update_tind_extent_range(handle, tmp_inode,
     534                 :            :                                 le32_to_cpu(i_data[EXT4_TIND_BLOCK]), &lb);
     535         [ #  # ]:          0 :                 if (retval)
     536                 :          0 :                         goto err_out;
     537                 :            :         }
     538                 :            :         /*
     539                 :            :          * Build the last extent
     540                 :            :          */
     541                 :          0 :         retval = finish_range(handle, tmp_inode, &lb);
     542                 :          0 : err_out:
     543         [ #  # ]:          0 :         if (retval)
     544                 :            :                 /*
     545                 :            :                  * Failure case delete the extent information with the
     546                 :            :                  * tmp_inode
     547                 :            :                  */
     548                 :          0 :                 free_ext_block(handle, tmp_inode);
     549                 :            :         else {
     550                 :          0 :                 retval = ext4_ext_swap_inode_data(handle, inode, tmp_inode);
     551         [ #  # ]:          0 :                 if (retval)
     552                 :            :                         /*
     553                 :            :                          * if we fail to swap inode data free the extent
     554                 :            :                          * details of the tmp inode
     555                 :            :                          */
     556                 :          0 :                         free_ext_block(handle, tmp_inode);
     557                 :            :         }
     558                 :            : 
     559                 :            :         /* We mark the tmp_inode dirty via ext4_ext_tree_init. */
     560                 :          0 :         retval = ext4_journal_ensure_credits(handle, 1, 0);
     561         [ #  # ]:          0 :         if (retval < 0)
     562                 :          0 :                 goto out_stop;
     563                 :            :         /*
     564                 :            :          * Mark the tmp_inode as of size zero
     565                 :            :          */
     566                 :          0 :         i_size_write(tmp_inode, 0);
     567                 :            : 
     568                 :            :         /*
     569                 :            :          * set the  i_blocks count to zero
     570                 :            :          * so that the ext4_evict_inode() does the
     571                 :            :          * right job
     572                 :            :          *
     573                 :            :          * We don't need to take the i_lock because
     574                 :            :          * the inode is not visible to user space.
     575                 :            :          */
     576                 :          0 :         tmp_inode->i_blocks = 0;
     577                 :            : 
     578                 :            :         /* Reset the extent details */
     579                 :          0 :         ext4_ext_tree_init(handle, tmp_inode);
     580                 :          0 : out_stop:
     581                 :          0 :         ext4_journal_stop(handle);
     582                 :          0 : out_tmp_inode:
     583                 :          0 :         unlock_new_inode(tmp_inode);
     584                 :          0 :         iput(tmp_inode);
     585                 :          0 : out_unlock:
     586                 :          0 :         percpu_up_write(&sbi->s_writepages_rwsem);
     587                 :          0 :         return retval;
     588                 :            : }
     589                 :            : 
     590                 :            : /*
     591                 :            :  * Migrate a simple extent-based inode to use the i_blocks[] array
     592                 :            :  */
     593                 :          0 : int ext4_ind_migrate(struct inode *inode)
     594                 :            : {
     595                 :          0 :         struct ext4_extent_header       *eh;
     596         [ #  # ]:          0 :         struct ext4_sb_info             *sbi = EXT4_SB(inode->i_sb);
     597                 :          0 :         struct ext4_super_block         *es = sbi->s_es;
     598         [ #  # ]:          0 :         struct ext4_inode_info          *ei = EXT4_I(inode);
     599                 :          0 :         struct ext4_extent              *ex;
     600                 :          0 :         unsigned int                    i, len;
     601                 :          0 :         ext4_lblk_t                     start, end;
     602                 :          0 :         ext4_fsblk_t                    blk;
     603                 :          0 :         handle_t                        *handle;
     604                 :          0 :         int                             ret;
     605                 :            : 
     606   [ #  #  #  # ]:          0 :         if (!ext4_has_feature_extents(inode->i_sb) ||
     607                 :            :             (!ext4_test_inode_flag(inode, EXT4_INODE_EXTENTS)))
     608                 :          0 :                 return -EINVAL;
     609                 :            : 
     610         [ #  # ]:          0 :         if (ext4_has_feature_bigalloc(inode->i_sb))
     611                 :            :                 return -EOPNOTSUPP;
     612                 :            : 
     613                 :            :         /*
     614                 :            :          * In order to get correct extent info, force all delayed allocation
     615                 :            :          * blocks to be allocated, otherwise delayed allocation blocks may not
     616                 :            :          * be reflected and bypass the checks on extent header.
     617                 :            :          */
     618         [ #  # ]:          0 :         if (test_opt(inode->i_sb, DELALLOC))
     619                 :          0 :                 ext4_alloc_da_blocks(inode);
     620                 :            : 
     621                 :          0 :         percpu_down_write(&sbi->s_writepages_rwsem);
     622                 :            : 
     623                 :          0 :         handle = ext4_journal_start(inode, EXT4_HT_MIGRATE, 1);
     624         [ #  # ]:          0 :         if (IS_ERR(handle)) {
     625                 :          0 :                 ret = PTR_ERR(handle);
     626                 :          0 :                 goto out_unlock;
     627                 :            :         }
     628                 :            : 
     629                 :          0 :         down_write(&EXT4_I(inode)->i_data_sem);
     630                 :          0 :         ret = ext4_ext_check_inode(inode);
     631         [ #  # ]:          0 :         if (ret)
     632                 :          0 :                 goto errout;
     633                 :            : 
     634         [ #  # ]:          0 :         eh = ext_inode_hdr(inode);
     635                 :          0 :         ex  = EXT_FIRST_EXTENT(eh);
     636         [ #  # ]:          0 :         if (ext4_blocks_count(es) > EXT4_MAX_BLOCK_FILE_PHYS ||
     637   [ #  #  #  # ]:          0 :             eh->eh_depth != 0 || le16_to_cpu(eh->eh_entries) > 1) {
     638                 :          0 :                 ret = -EOPNOTSUPP;
     639                 :          0 :                 goto errout;
     640                 :            :         }
     641         [ #  # ]:          0 :         if (eh->eh_entries == 0)
     642                 :            :                 blk = len = start = end = 0;
     643                 :            :         else {
     644                 :          0 :                 len = le16_to_cpu(ex->ee_len);
     645         [ #  # ]:          0 :                 blk = ext4_ext_pblock(ex);
     646                 :          0 :                 start = le32_to_cpu(ex->ee_block);
     647                 :          0 :                 end = start + len - 1;
     648         [ #  # ]:          0 :                 if (end >= EXT4_NDIR_BLOCKS) {
     649                 :          0 :                         ret = -EOPNOTSUPP;
     650                 :          0 :                         goto errout;
     651                 :            :                 }
     652                 :            :         }
     653                 :            : 
     654                 :          0 :         ext4_clear_inode_flag(inode, EXT4_INODE_EXTENTS);
     655                 :          0 :         memset(ei->i_data, 0, sizeof(ei->i_data));
     656         [ #  # ]:          0 :         for (i = start; i <= end; i++)
     657                 :          0 :                 ei->i_data[i] = cpu_to_le32(blk++);
     658                 :          0 :         ext4_mark_inode_dirty(handle, inode);
     659                 :          0 : errout:
     660                 :          0 :         ext4_journal_stop(handle);
     661                 :          0 :         up_write(&EXT4_I(inode)->i_data_sem);
     662                 :          0 : out_unlock:
     663                 :          0 :         percpu_up_write(&sbi->s_writepages_rwsem);
     664                 :          0 :         return ret;
     665                 :            : }

Generated by: LCOV version 1.14