linux/fs/ext4/move_extent.c
<<
>>
Prefs
   1/*
   2 * Copyright (c) 2008,2009 NEC Software Tohoku, Ltd.
   3 * Written by Takashi Sato <t-sato@yk.jp.nec.com>
   4 *            Akira Fujita <a-fujita@rs.jp.nec.com>
   5 *
   6 * This program is free software; you can redistribute it and/or modify it
   7 * under the terms of version 2.1 of the GNU Lesser General Public License
   8 * as published by the Free Software Foundation.
   9 *
  10 * This program is distributed in the hope that it will be useful,
  11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
  12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  13 * GNU General Public License for more details.
  14 */
  15
  16#include <linux/fs.h>
  17#include <linux/quotaops.h>
  18#include <linux/slab.h>
  19#include "ext4_jbd2.h"
  20#include "ext4.h"
  21#include "ext4_extents.h"
  22
  23/**
  24 * get_ext_path - Find an extent path for designated logical block number.
  25 *
  26 * @inode:      an inode which is searched
  27 * @lblock:     logical block number to find an extent path
  28 * @path:       pointer to an extent path pointer (for output)
  29 *
  30 * ext4_find_extent wrapper. Return 0 on success, or a negative error value
  31 * on failure.
  32 */
  33static inline int
  34get_ext_path(struct inode *inode, ext4_lblk_t lblock,
  35                struct ext4_ext_path **ppath)
  36{
  37        struct ext4_ext_path *path;
  38
  39        path = ext4_find_extent(inode, lblock, ppath, EXT4_EX_NOCACHE);
  40        if (IS_ERR(path))
  41                return PTR_ERR(path);
  42        if (path[ext_depth(inode)].p_ext == NULL) {
  43                ext4_ext_drop_refs(path);
  44                kfree(path);
  45                *ppath = NULL;
  46                return -ENODATA;
  47        }
  48        *ppath = path;
  49        return 0;
  50}
  51
  52/**
  53 * ext4_double_down_write_data_sem - Acquire two inodes' write lock
  54 *                                   of i_data_sem
  55 *
  56 * Acquire write lock of i_data_sem of the two inodes
  57 */
  58void
  59ext4_double_down_write_data_sem(struct inode *first, struct inode *second)
  60{
  61        if (first < second) {
  62                down_write(&EXT4_I(first)->i_data_sem);
  63                down_write_nested(&EXT4_I(second)->i_data_sem, SINGLE_DEPTH_NESTING);
  64        } else {
  65                down_write(&EXT4_I(second)->i_data_sem);
  66                down_write_nested(&EXT4_I(first)->i_data_sem, SINGLE_DEPTH_NESTING);
  67
  68        }
  69}
  70
  71/**
  72 * ext4_double_up_write_data_sem - Release two inodes' write lock of i_data_sem
  73 *
  74 * @orig_inode:         original inode structure to be released its lock first
  75 * @donor_inode:        donor inode structure to be released its lock second
  76 * Release write lock of i_data_sem of two inodes (orig and donor).
  77 */
  78void
  79ext4_double_up_write_data_sem(struct inode *orig_inode,
  80                              struct inode *donor_inode)
  81{
  82        up_write(&EXT4_I(orig_inode)->i_data_sem);
  83        up_write(&EXT4_I(donor_inode)->i_data_sem);
  84}
  85
  86/**
  87 * mext_check_coverage - Check that all extents in range has the same type
  88 *
  89 * @inode:              inode in question
  90 * @from:               block offset of inode
  91 * @count:              block count to be checked
  92 * @unwritten:          extents expected to be unwritten
  93 * @err:                pointer to save error value
  94 *
  95 * Return 1 if all extents in range has expected type, and zero otherwise.
  96 */
  97static int
  98mext_check_coverage(struct inode *inode, ext4_lblk_t from, ext4_lblk_t count,
  99                    int unwritten, int *err)
 100{
 101        struct ext4_ext_path *path = NULL;
 102        struct ext4_extent *ext;
 103        int ret = 0;
 104        ext4_lblk_t last = from + count;
 105        while (from < last) {
 106                *err = get_ext_path(inode, from, &path);
 107                if (*err)
 108                        goto out;
 109                ext = path[ext_depth(inode)].p_ext;
 110                if (unwritten != ext4_ext_is_unwritten(ext))
 111                        goto out;
 112                from += ext4_ext_get_actual_len(ext);
 113                ext4_ext_drop_refs(path);
 114        }
 115        ret = 1;
 116out:
 117        ext4_ext_drop_refs(path);
 118        kfree(path);
 119        return ret;
 120}
 121
 122/**
 123 * mext_page_double_lock - Grab and lock pages on both @inode1 and @inode2
 124 *
 125 * @inode1:     the inode structure
 126 * @inode2:     the inode structure
 127 * @index1:     page index
 128 * @index2:     page index
 129 * @page:       result page vector
 130 *
 131 * Grab two locked pages for inode's by inode order
 132 */
 133static int
 134mext_page_double_lock(struct inode *inode1, struct inode *inode2,
 135                      pgoff_t index1, pgoff_t index2, struct page *page[2])
 136{
 137        struct address_space *mapping[2];
 138        unsigned fl = AOP_FLAG_NOFS;
 139
 140        BUG_ON(!inode1 || !inode2);
 141        if (inode1 < inode2) {
 142                mapping[0] = inode1->i_mapping;
 143                mapping[1] = inode2->i_mapping;
 144        } else {
 145                pgoff_t tmp = index1;
 146                index1 = index2;
 147                index2 = tmp;
 148                mapping[0] = inode2->i_mapping;
 149                mapping[1] = inode1->i_mapping;
 150        }
 151
 152        page[0] = grab_cache_page_write_begin(mapping[0], index1, fl);
 153        if (!page[0])
 154                return -ENOMEM;
 155
 156        page[1] = grab_cache_page_write_begin(mapping[1], index2, fl);
 157        if (!page[1]) {
 158                unlock_page(page[0]);
 159                page_cache_release(page[0]);
 160                return -ENOMEM;
 161        }
 162        /*
 163         * grab_cache_page_write_begin() may not wait on page's writeback if
 164         * BDI not demand that. But it is reasonable to be very conservative
 165         * here and explicitly wait on page's writeback
 166         */
 167        wait_on_page_writeback(page[0]);
 168        wait_on_page_writeback(page[1]);
 169        if (inode1 > inode2) {
 170                struct page *tmp;
 171                tmp = page[0];
 172                page[0] = page[1];
 173                page[1] = tmp;
 174        }
 175        return 0;
 176}
 177
 178/* Force page buffers uptodate w/o dropping page's lock */
 179static int
 180mext_page_mkuptodate(struct page *page, unsigned from, unsigned to)
 181{
 182        struct inode *inode = page->mapping->host;
 183        sector_t block;
 184        struct buffer_head *bh, *head, *arr[MAX_BUF_PER_PAGE];
 185        unsigned int blocksize, block_start, block_end;
 186        int i, err,  nr = 0, partial = 0;
 187        BUG_ON(!PageLocked(page));
 188        BUG_ON(PageWriteback(page));
 189
 190        if (PageUptodate(page))
 191                return 0;
 192
 193        blocksize = 1 << inode->i_blkbits;
 194        if (!page_has_buffers(page))
 195                create_empty_buffers(page, blocksize, 0);
 196
 197        head = page_buffers(page);
 198        block = (sector_t)page->index << (PAGE_CACHE_SHIFT - inode->i_blkbits);
 199        for (bh = head, block_start = 0; bh != head || !block_start;
 200             block++, block_start = block_end, bh = bh->b_this_page) {
 201                block_end = block_start + blocksize;
 202                if (block_end <= from || block_start >= to) {
 203                        if (!buffer_uptodate(bh))
 204                                partial = 1;
 205                        continue;
 206                }
 207                if (buffer_uptodate(bh))
 208                        continue;
 209                if (!buffer_mapped(bh)) {
 210                        err = ext4_get_block(inode, block, bh, 0);
 211                        if (err) {
 212                                SetPageError(page);
 213                                return err;
 214                        }
 215                        if (!buffer_mapped(bh)) {
 216                                zero_user(page, block_start, blocksize);
 217                                set_buffer_uptodate(bh);
 218                                continue;
 219                        }
 220                }
 221                BUG_ON(nr >= MAX_BUF_PER_PAGE);
 222                arr[nr++] = bh;
 223        }
 224        /* No io required */
 225        if (!nr)
 226                goto out;
 227
 228        for (i = 0; i < nr; i++) {
 229                bh = arr[i];
 230                if (!bh_uptodate_or_lock(bh)) {
 231                        err = bh_submit_read(bh);
 232                        if (err)
 233                                return err;
 234                }
 235        }
 236out:
 237        if (!partial)
 238                SetPageUptodate(page);
 239        return 0;
 240}
 241
 242/**
 243 * move_extent_per_page - Move extent data per page
 244 *
 245 * @o_filp:                     file structure of original file
 246 * @donor_inode:                donor inode
 247 * @orig_page_offset:           page index on original file
 248 * @donor_page_offset:          page index on donor file
 249 * @data_offset_in_page:        block index where data swapping starts
 250 * @block_len_in_page:          the number of blocks to be swapped
 251 * @unwritten:                  orig extent is unwritten or not
 252 * @err:                        pointer to save return value
 253 *
 254 * Save the data in original inode blocks and replace original inode extents
 255 * with donor inode extents by calling ext4_swap_extents().
 256 * Finally, write out the saved data in new original inode blocks. Return
 257 * replaced block count.
 258 */
 259static int
 260move_extent_per_page(struct file *o_filp, struct inode *donor_inode,
 261                     pgoff_t orig_page_offset, pgoff_t donor_page_offset,
 262                     int data_offset_in_page,
 263                     int block_len_in_page, int unwritten, int *err)
 264{
 265        struct inode *orig_inode = file_inode(o_filp);
 266        struct page *pagep[2] = {NULL, NULL};
 267        handle_t *handle;
 268        ext4_lblk_t orig_blk_offset, donor_blk_offset;
 269        unsigned long blocksize = orig_inode->i_sb->s_blocksize;
 270        unsigned int tmp_data_size, data_size, replaced_size;
 271        int err2, jblocks, retries = 0;
 272        int replaced_count = 0;
 273        int from = data_offset_in_page << orig_inode->i_blkbits;
 274        int blocks_per_page = PAGE_CACHE_SIZE >> orig_inode->i_blkbits;
 275        struct super_block *sb = orig_inode->i_sb;
 276
 277        /*
 278         * It needs twice the amount of ordinary journal buffers because
 279         * inode and donor_inode may change each different metadata blocks.
 280         */
 281again:
 282        *err = 0;
 283        jblocks = ext4_writepage_trans_blocks(orig_inode) * 2;
 284        handle = ext4_journal_start(orig_inode, EXT4_HT_MOVE_EXTENTS, jblocks);
 285        if (IS_ERR(handle)) {
 286                *err = PTR_ERR(handle);
 287                return 0;
 288        }
 289
 290        orig_blk_offset = orig_page_offset * blocks_per_page +
 291                data_offset_in_page;
 292
 293        donor_blk_offset = donor_page_offset * blocks_per_page +
 294                data_offset_in_page;
 295
 296        /* Calculate data_size */
 297        if ((orig_blk_offset + block_len_in_page - 1) ==
 298            ((orig_inode->i_size - 1) >> orig_inode->i_blkbits)) {
 299                /* Replace the last block */
 300                tmp_data_size = orig_inode->i_size & (blocksize - 1);
 301                /*
 302                 * If data_size equal zero, it shows data_size is multiples of
 303                 * blocksize. So we set appropriate value.
 304                 */
 305                if (tmp_data_size == 0)
 306                        tmp_data_size = blocksize;
 307
 308                data_size = tmp_data_size +
 309                        ((block_len_in_page - 1) << orig_inode->i_blkbits);
 310        } else
 311                data_size = block_len_in_page << orig_inode->i_blkbits;
 312
 313        replaced_size = data_size;
 314
 315        *err = mext_page_double_lock(orig_inode, donor_inode, orig_page_offset,
 316                                     donor_page_offset, pagep);
 317        if (unlikely(*err < 0))
 318                goto stop_journal;
 319        /*
 320         * If orig extent was unwritten it can become initialized
 321         * at any time after i_data_sem was dropped, in order to
 322         * serialize with delalloc we have recheck extent while we
 323         * hold page's lock, if it is still the case data copy is not
 324         * necessary, just swap data blocks between orig and donor.
 325         */
 326        if (unwritten) {
 327                ext4_double_down_write_data_sem(orig_inode, donor_inode);
 328                /* If any of extents in range became initialized we have to
 329                 * fallback to data copying */
 330                unwritten = mext_check_coverage(orig_inode, orig_blk_offset,
 331                                                block_len_in_page, 1, err);
 332                if (*err)
 333                        goto drop_data_sem;
 334
 335                unwritten &= mext_check_coverage(donor_inode, donor_blk_offset,
 336                                                 block_len_in_page, 1, err);
 337                if (*err)
 338                        goto drop_data_sem;
 339
 340                if (!unwritten) {
 341                        ext4_double_up_write_data_sem(orig_inode, donor_inode);
 342                        goto data_copy;
 343                }
 344                if ((page_has_private(pagep[0]) &&
 345                     !try_to_release_page(pagep[0], 0)) ||
 346                    (page_has_private(pagep[1]) &&
 347                     !try_to_release_page(pagep[1], 0))) {
 348                        *err = -EBUSY;
 349                        goto drop_data_sem;
 350                }
 351                replaced_count = ext4_swap_extents(handle, orig_inode,
 352                                                   donor_inode, orig_blk_offset,
 353                                                   donor_blk_offset,
 354                                                   block_len_in_page, 1, err);
 355        drop_data_sem:
 356                ext4_double_up_write_data_sem(orig_inode, donor_inode);
 357                goto unlock_pages;
 358        }
 359data_copy:
 360        *err = mext_page_mkuptodate(pagep[0], from, from + replaced_size);
 361        if (*err)
 362                goto unlock_pages;
 363
 364        /* At this point all buffers in range are uptodate, old mapping layout
 365         * is no longer required, try to drop it now. */
 366        if ((page_has_private(pagep[0]) && !try_to_release_page(pagep[0], 0)) ||
 367            (page_has_private(pagep[1]) && !try_to_release_page(pagep[1], 0))) {
 368                *err = -EBUSY;
 369                goto unlock_pages;
 370        }
 371        ext4_double_down_write_data_sem(orig_inode, donor_inode);
 372        replaced_count = ext4_swap_extents(handle, orig_inode, donor_inode,
 373                                               orig_blk_offset, donor_blk_offset,
 374                                           block_len_in_page, 1, err);
 375        ext4_double_up_write_data_sem(orig_inode, donor_inode);
 376        if (*err) {
 377                if (replaced_count) {
 378                        block_len_in_page = replaced_count;
 379                        replaced_size =
 380                                block_len_in_page << orig_inode->i_blkbits;
 381                } else
 382                        goto unlock_pages;
 383        }
 384        /* Perform all necessary steps similar write_begin()/write_end()
 385         * but keeping in mind that i_size will not change */
 386        *err = __block_write_begin(pagep[0], from, replaced_size,
 387                                   ext4_get_block);
 388        if (!*err)
 389                *err = block_commit_write(pagep[0], from, from + replaced_size);
 390
 391        if (unlikely(*err < 0))
 392                goto repair_branches;
 393
 394        /* Even in case of data=writeback it is reasonable to pin
 395         * inode to transaction, to prevent unexpected data loss */
 396        *err = ext4_jbd2_file_inode(handle, orig_inode);
 397
 398unlock_pages:
 399        unlock_page(pagep[0]);
 400        page_cache_release(pagep[0]);
 401        unlock_page(pagep[1]);
 402        page_cache_release(pagep[1]);
 403stop_journal:
 404        ext4_journal_stop(handle);
 405        if (*err == -ENOSPC &&
 406            ext4_should_retry_alloc(sb, &retries))
 407                goto again;
 408        /* Buffer was busy because probably is pinned to journal transaction,
 409         * force transaction commit may help to free it. */
 410        if (*err == -EBUSY && retries++ < 4 && EXT4_SB(sb)->s_journal &&
 411            jbd2_journal_force_commit_nested(EXT4_SB(sb)->s_journal))
 412                goto again;
 413        return replaced_count;
 414
 415repair_branches:
 416        /*
 417         * This should never ever happen!
 418         * Extents are swapped already, but we are not able to copy data.
 419         * Try to swap extents to it's original places
 420         */
 421        ext4_double_down_write_data_sem(orig_inode, donor_inode);
 422        replaced_count = ext4_swap_extents(handle, donor_inode, orig_inode,
 423                                               orig_blk_offset, donor_blk_offset,
 424                                           block_len_in_page, 0, &err2);
 425        ext4_double_up_write_data_sem(orig_inode, donor_inode);
 426        if (replaced_count != block_len_in_page) {
 427                EXT4_ERROR_INODE_BLOCK(orig_inode, (sector_t)(orig_blk_offset),
 428                                       "Unable to copy data block,"
 429                                       " data will be lost.");
 430                *err = -EIO;
 431        }
 432        replaced_count = 0;
 433        goto unlock_pages;
 434}
 435
 436/**
 437 * mext_check_arguments - Check whether move extent can be done
 438 *
 439 * @orig_inode:         original inode
 440 * @donor_inode:        donor inode
 441 * @orig_start:         logical start offset in block for orig
 442 * @donor_start:        logical start offset in block for donor
 443 * @len:                the number of blocks to be moved
 444 *
 445 * Check the arguments of ext4_move_extents() whether the files can be
 446 * exchanged with each other.
 447 * Return 0 on success, or a negative error value on failure.
 448 */
 449static int
 450mext_check_arguments(struct inode *orig_inode,
 451                     struct inode *donor_inode, __u64 orig_start,
 452                     __u64 donor_start, __u64 *len)
 453{
 454        __u64 orig_eof, donor_eof;
 455        unsigned int blkbits = orig_inode->i_blkbits;
 456        unsigned int blocksize = 1 << blkbits;
 457
 458        orig_eof = (i_size_read(orig_inode) + blocksize - 1) >> blkbits;
 459        donor_eof = (i_size_read(donor_inode) + blocksize - 1) >> blkbits;
 460
 461
 462        if (donor_inode->i_mode & (S_ISUID|S_ISGID)) {
 463                ext4_debug("ext4 move extent: suid or sgid is set"
 464                           " to donor file [ino:orig %lu, donor %lu]\n",
 465                           orig_inode->i_ino, donor_inode->i_ino);
 466                return -EINVAL;
 467        }
 468
 469        if (IS_IMMUTABLE(donor_inode) || IS_APPEND(donor_inode))
 470                return -EPERM;
 471
 472        /* Ext4 move extent does not support swapfile */
 473        if (IS_SWAPFILE(orig_inode) || IS_SWAPFILE(donor_inode)) {
 474                ext4_debug("ext4 move extent: The argument files should "
 475                        "not be swapfile [ino:orig %lu, donor %lu]\n",
 476                        orig_inode->i_ino, donor_inode->i_ino);
 477                return -EBUSY;
 478        }
 479
 480        /* Ext4 move extent supports only extent based file */
 481        if (!(ext4_test_inode_flag(orig_inode, EXT4_INODE_EXTENTS))) {
 482                ext4_debug("ext4 move extent: orig file is not extents "
 483                        "based file [ino:orig %lu]\n", orig_inode->i_ino);
 484                return -EOPNOTSUPP;
 485        } else if (!(ext4_test_inode_flag(donor_inode, EXT4_INODE_EXTENTS))) {
 486                ext4_debug("ext4 move extent: donor file is not extents "
 487                        "based file [ino:donor %lu]\n", donor_inode->i_ino);
 488                return -EOPNOTSUPP;
 489        }
 490
 491        if ((!orig_inode->i_size) || (!donor_inode->i_size)) {
 492                ext4_debug("ext4 move extent: File size is 0 byte\n");
 493                return -EINVAL;
 494        }
 495
 496        /* Start offset should be same */
 497        if ((orig_start & ~(PAGE_MASK >> orig_inode->i_blkbits)) !=
 498            (donor_start & ~(PAGE_MASK >> orig_inode->i_blkbits))) {
 499                ext4_debug("ext4 move extent: orig and donor's start "
 500                        "offset are not alligned [ino:orig %lu, donor %lu]\n",
 501                        orig_inode->i_ino, donor_inode->i_ino);
 502                return -EINVAL;
 503        }
 504
 505        if ((orig_start >= EXT_MAX_BLOCKS) ||
 506            (donor_start >= EXT_MAX_BLOCKS) ||
 507            (*len > EXT_MAX_BLOCKS) ||
 508            (donor_start + *len >= EXT_MAX_BLOCKS) ||
 509            (orig_start + *len >= EXT_MAX_BLOCKS))  {
 510                ext4_debug("ext4 move extent: Can't handle over [%u] blocks "
 511                        "[ino:orig %lu, donor %lu]\n", EXT_MAX_BLOCKS,
 512                        orig_inode->i_ino, donor_inode->i_ino);
 513                return -EINVAL;
 514        }
 515        if (orig_eof < orig_start + *len - 1)
 516                *len = orig_eof - orig_start;
 517        if (donor_eof < donor_start + *len - 1)
 518                *len = donor_eof - donor_start;
 519        if (!*len) {
 520                ext4_debug("ext4 move extent: len should not be 0 "
 521                        "[ino:orig %lu, donor %lu]\n", orig_inode->i_ino,
 522                        donor_inode->i_ino);
 523                return -EINVAL;
 524        }
 525
 526        return 0;
 527}
 528
 529/**
 530 * ext4_move_extents - Exchange the specified range of a file
 531 *
 532 * @o_filp:             file structure of the original file
 533 * @d_filp:             file structure of the donor file
 534 * @orig_blk:           start offset in block for orig
 535 * @donor_blk:          start offset in block for donor
 536 * @len:                the number of blocks to be moved
 537 * @moved_len:          moved block length
 538 *
 539 * This function returns 0 and moved block length is set in moved_len
 540 * if succeed, otherwise returns error value.
 541 *
 542 */
 543int
 544ext4_move_extents(struct file *o_filp, struct file *d_filp, __u64 orig_blk,
 545                  __u64 donor_blk, __u64 len, __u64 *moved_len)
 546{
 547        struct inode *orig_inode = file_inode(o_filp);
 548        struct inode *donor_inode = file_inode(d_filp);
 549        struct ext4_ext_path *path = NULL;
 550        int blocks_per_page = PAGE_CACHE_SIZE >> orig_inode->i_blkbits;
 551        ext4_lblk_t o_end, o_start = orig_blk;
 552        ext4_lblk_t d_start = donor_blk;
 553        int ret;
 554
 555        if (orig_inode->i_sb != donor_inode->i_sb) {
 556                ext4_debug("ext4 move extent: The argument files "
 557                        "should be in same FS [ino:orig %lu, donor %lu]\n",
 558                        orig_inode->i_ino, donor_inode->i_ino);
 559                return -EINVAL;
 560        }
 561
 562        /* orig and donor should be different inodes */
 563        if (orig_inode == donor_inode) {
 564                ext4_debug("ext4 move extent: The argument files should not "
 565                        "be same inode [ino:orig %lu, donor %lu]\n",
 566                        orig_inode->i_ino, donor_inode->i_ino);
 567                return -EINVAL;
 568        }
 569
 570        /* Regular file check */
 571        if (!S_ISREG(orig_inode->i_mode) || !S_ISREG(donor_inode->i_mode)) {
 572                ext4_debug("ext4 move extent: The argument files should be "
 573                        "regular file [ino:orig %lu, donor %lu]\n",
 574                        orig_inode->i_ino, donor_inode->i_ino);
 575                return -EINVAL;
 576        }
 577        /* TODO: This is non obvious task to swap blocks for inodes with full
 578           jornaling enabled */
 579        if (ext4_should_journal_data(orig_inode) ||
 580            ext4_should_journal_data(donor_inode)) {
 581                return -EINVAL;
 582        }
 583        /* Protect orig and donor inodes against a truncate */
 584        lock_two_nondirectories(orig_inode, donor_inode);
 585
 586        /* Wait for all existing dio workers */
 587        ext4_inode_block_unlocked_dio(orig_inode);
 588        ext4_inode_block_unlocked_dio(donor_inode);
 589        inode_dio_wait(orig_inode);
 590        inode_dio_wait(donor_inode);
 591
 592        /* Protect extent tree against block allocations via delalloc */
 593        ext4_double_down_write_data_sem(orig_inode, donor_inode);
 594        /* Check the filesystem environment whether move_extent can be done */
 595        ret = mext_check_arguments(orig_inode, donor_inode, orig_blk,
 596                                    donor_blk, &len);
 597        if (ret)
 598                goto out;
 599        o_end = o_start + len;
 600
 601        while (o_start < o_end) {
 602                struct ext4_extent *ex;
 603                ext4_lblk_t cur_blk, next_blk;
 604                pgoff_t orig_page_index, donor_page_index;
 605                int offset_in_page;
 606                int unwritten, cur_len;
 607
 608                ret = get_ext_path(orig_inode, o_start, &path);
 609                if (ret)
 610                        goto out;
 611                ex = path[path->p_depth].p_ext;
 612                next_blk = ext4_ext_next_allocated_block(path);
 613                cur_blk = le32_to_cpu(ex->ee_block);
 614                cur_len = ext4_ext_get_actual_len(ex);
 615                /* Check hole before the start pos */
 616                if (cur_blk + cur_len - 1 < o_start) {
 617                        if (next_blk == EXT_MAX_BLOCKS) {
 618                                o_start = o_end;
 619                                ret = -ENODATA;
 620                                goto out;
 621                        }
 622                        d_start += next_blk - o_start;
 623                        o_start = next_blk;
 624                        continue;
 625                /* Check hole after the start pos */
 626                } else if (cur_blk > o_start) {
 627                        /* Skip hole */
 628                        d_start += cur_blk - o_start;
 629                        o_start = cur_blk;
 630                        /* Extent inside requested range ?*/
 631                        if (cur_blk >= o_end)
 632                                goto out;
 633                } else { /* in_range(o_start, o_blk, o_len) */
 634                        cur_len += cur_blk - o_start;
 635                }
 636                unwritten = ext4_ext_is_unwritten(ex);
 637                if (o_end - o_start < cur_len)
 638                        cur_len = o_end - o_start;
 639
 640                orig_page_index = o_start >> (PAGE_CACHE_SHIFT -
 641                                               orig_inode->i_blkbits);
 642                donor_page_index = d_start >> (PAGE_CACHE_SHIFT -
 643                                               donor_inode->i_blkbits);
 644                offset_in_page = o_start % blocks_per_page;
 645                if (cur_len > blocks_per_page- offset_in_page)
 646                        cur_len = blocks_per_page - offset_in_page;
 647                /*
 648                 * Up semaphore to avoid following problems:
 649                 * a. transaction deadlock among ext4_journal_start,
 650                 *    ->write_begin via pagefault, and jbd2_journal_commit
 651                 * b. racing with ->readpage, ->write_begin, and ext4_get_block
 652                 *    in move_extent_per_page
 653                 */
 654                ext4_double_up_write_data_sem(orig_inode, donor_inode);
 655                /* Swap original branches with new branches */
 656                move_extent_per_page(o_filp, donor_inode,
 657                                     orig_page_index, donor_page_index,
 658                                     offset_in_page, cur_len,
 659                                     unwritten, &ret);
 660                ext4_double_down_write_data_sem(orig_inode, donor_inode);
 661                if (ret < 0)
 662                        break;
 663                o_start += cur_len;
 664                d_start += cur_len;
 665        }
 666        *moved_len = o_start - orig_blk;
 667        if (*moved_len > len)
 668                *moved_len = len;
 669
 670out:
 671        if (*moved_len) {
 672                ext4_discard_preallocations(orig_inode);
 673                ext4_discard_preallocations(donor_inode);
 674        }
 675
 676        ext4_ext_drop_refs(path);
 677        kfree(path);
 678        ext4_double_up_write_data_sem(orig_inode, donor_inode);
 679        ext4_inode_resume_unlocked_dio(orig_inode);
 680        ext4_inode_resume_unlocked_dio(donor_inode);
 681        unlock_two_nondirectories(orig_inode, donor_inode);
 682
 683        return ret;
 684}
 685