diff options
| author | Linus Torvalds <torvalds@woody.linux-foundation.org> | 2007-10-12 18:04:00 -0400 |
|---|---|---|
| committer | Linus Torvalds <torvalds@woody.linux-foundation.org> | 2007-10-12 18:04:00 -0400 |
| commit | a6e3d7dba92e19acffaa36aad962741a762aa8c5 (patch) | |
| tree | 4170e6cfe524b3714f35aba07890073ae8ae75c5 /fs/ocfs2/aops.c | |
| parent | 42f04b6d4c8c69ccffc10863418c5b5f100a8554 (diff) | |
| parent | e7b34019606ab1dd06196635e931b0c302799228 (diff) | |
Merge branch 'upstream-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/mfasheh/ocfs2
* 'upstream-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/mfasheh/ocfs2: (23 commits)
ocfs2: Optionally return filldir errors
ocfs2: Write support for directories with inline data
ocfs2: Read support for directories with inline data
ocfs2: Write support for inline data
ocfs2: Read support for inline data
ocfs2: Structure updates for inline data
ocfs2: Cleanup dirent size check
ocfs2: Rename cleanups
ocfs2: Provide convenience function for ino lookup
ocfs2: Implement ocfs2_empty_dir() as a caller of ocfs2_dir_foreach()
ocfs2: Remove open coded readdir()
ocfs2: Pass raw u64 to filldir
ocfs2: Abstract out core dir listing functionality
ocfs2: Move directory manipulation code into dir.c
ocfs2: Small refactor of truncate zeroing code
ocfs2: move nonsparse hole-filling into ocfs2_write_begin()
ocfs2: Sync ocfs2_fs.h with ocfs2-tools
[PATCH] fs/ocfs2/: removed unneeded initial value and function's return value
ocfs2: Implement show_options()
ocfs2: Clear slot map when umounting a local volume
...
Diffstat (limited to 'fs/ocfs2/aops.c')
| -rw-r--r-- | fs/ocfs2/aops.c | 309 |
1 files changed, 293 insertions, 16 deletions
diff --git a/fs/ocfs2/aops.c b/fs/ocfs2/aops.c index f37f25c931f5..34d10452c56d 100644 --- a/fs/ocfs2/aops.c +++ b/fs/ocfs2/aops.c | |||
| @@ -206,9 +206,70 @@ bail: | |||
| 206 | return err; | 206 | return err; |
| 207 | } | 207 | } |
| 208 | 208 | ||
| 209 | int ocfs2_read_inline_data(struct inode *inode, struct page *page, | ||
| 210 | struct buffer_head *di_bh) | ||
| 211 | { | ||
| 212 | void *kaddr; | ||
| 213 | unsigned int size; | ||
| 214 | struct ocfs2_dinode *di = (struct ocfs2_dinode *)di_bh->b_data; | ||
| 215 | |||
| 216 | if (!(le16_to_cpu(di->i_dyn_features) & OCFS2_INLINE_DATA_FL)) { | ||
| 217 | ocfs2_error(inode->i_sb, "Inode %llu lost inline data flag", | ||
| 218 | (unsigned long long)OCFS2_I(inode)->ip_blkno); | ||
| 219 | return -EROFS; | ||
| 220 | } | ||
| 221 | |||
| 222 | size = i_size_read(inode); | ||
| 223 | |||
| 224 | if (size > PAGE_CACHE_SIZE || | ||
| 225 | size > ocfs2_max_inline_data(inode->i_sb)) { | ||
| 226 | ocfs2_error(inode->i_sb, | ||
| 227 | "Inode %llu has with inline data has bad size: %u", | ||
| 228 | (unsigned long long)OCFS2_I(inode)->ip_blkno, size); | ||
| 229 | return -EROFS; | ||
| 230 | } | ||
| 231 | |||
| 232 | kaddr = kmap_atomic(page, KM_USER0); | ||
| 233 | if (size) | ||
| 234 | memcpy(kaddr, di->id2.i_data.id_data, size); | ||
| 235 | /* Clear the remaining part of the page */ | ||
| 236 | memset(kaddr + size, 0, PAGE_CACHE_SIZE - size); | ||
| 237 | flush_dcache_page(page); | ||
| 238 | kunmap_atomic(kaddr, KM_USER0); | ||
| 239 | |||
| 240 | SetPageUptodate(page); | ||
| 241 | |||
| 242 | return 0; | ||
| 243 | } | ||
| 244 | |||
| 245 | static int ocfs2_readpage_inline(struct inode *inode, struct page *page) | ||
| 246 | { | ||
| 247 | int ret; | ||
| 248 | struct buffer_head *di_bh = NULL; | ||
| 249 | struct ocfs2_super *osb = OCFS2_SB(inode->i_sb); | ||
| 250 | |||
| 251 | BUG_ON(!PageLocked(page)); | ||
| 252 | BUG_ON(!OCFS2_I(inode)->ip_dyn_features & OCFS2_INLINE_DATA_FL); | ||
| 253 | |||
| 254 | ret = ocfs2_read_block(osb, OCFS2_I(inode)->ip_blkno, &di_bh, | ||
| 255 | OCFS2_BH_CACHED, inode); | ||
| 256 | if (ret) { | ||
| 257 | mlog_errno(ret); | ||
| 258 | goto out; | ||
| 259 | } | ||
| 260 | |||
| 261 | ret = ocfs2_read_inline_data(inode, page, di_bh); | ||
| 262 | out: | ||
| 263 | unlock_page(page); | ||
| 264 | |||
| 265 | brelse(di_bh); | ||
| 266 | return ret; | ||
| 267 | } | ||
| 268 | |||
| 209 | static int ocfs2_readpage(struct file *file, struct page *page) | 269 | static int ocfs2_readpage(struct file *file, struct page *page) |
| 210 | { | 270 | { |
| 211 | struct inode *inode = page->mapping->host; | 271 | struct inode *inode = page->mapping->host; |
| 272 | struct ocfs2_inode_info *oi = OCFS2_I(inode); | ||
| 212 | loff_t start = (loff_t)page->index << PAGE_CACHE_SHIFT; | 273 | loff_t start = (loff_t)page->index << PAGE_CACHE_SHIFT; |
| 213 | int ret, unlock = 1; | 274 | int ret, unlock = 1; |
| 214 | 275 | ||
| @@ -222,7 +283,7 @@ static int ocfs2_readpage(struct file *file, struct page *page) | |||
| 222 | goto out; | 283 | goto out; |
| 223 | } | 284 | } |
| 224 | 285 | ||
| 225 | if (down_read_trylock(&OCFS2_I(inode)->ip_alloc_sem) == 0) { | 286 | if (down_read_trylock(&oi->ip_alloc_sem) == 0) { |
| 226 | ret = AOP_TRUNCATED_PAGE; | 287 | ret = AOP_TRUNCATED_PAGE; |
| 227 | goto out_meta_unlock; | 288 | goto out_meta_unlock; |
| 228 | } | 289 | } |
| @@ -252,7 +313,10 @@ static int ocfs2_readpage(struct file *file, struct page *page) | |||
| 252 | goto out_alloc; | 313 | goto out_alloc; |
| 253 | } | 314 | } |
| 254 | 315 | ||
| 255 | ret = block_read_full_page(page, ocfs2_get_block); | 316 | if (oi->ip_dyn_features & OCFS2_INLINE_DATA_FL) |
| 317 | ret = ocfs2_readpage_inline(inode, page); | ||
| 318 | else | ||
| 319 | ret = block_read_full_page(page, ocfs2_get_block); | ||
| 256 | unlock = 0; | 320 | unlock = 0; |
| 257 | 321 | ||
| 258 | ocfs2_data_unlock(inode, 0); | 322 | ocfs2_data_unlock(inode, 0); |
| @@ -301,12 +365,8 @@ int ocfs2_prepare_write_nolock(struct inode *inode, struct page *page, | |||
| 301 | { | 365 | { |
| 302 | int ret; | 366 | int ret; |
| 303 | 367 | ||
| 304 | down_read(&OCFS2_I(inode)->ip_alloc_sem); | ||
| 305 | |||
| 306 | ret = block_prepare_write(page, from, to, ocfs2_get_block); | 368 | ret = block_prepare_write(page, from, to, ocfs2_get_block); |
| 307 | 369 | ||
| 308 | up_read(&OCFS2_I(inode)->ip_alloc_sem); | ||
| 309 | |||
| 310 | return ret; | 370 | return ret; |
| 311 | } | 371 | } |
| 312 | 372 | ||
| @@ -401,7 +461,9 @@ static sector_t ocfs2_bmap(struct address_space *mapping, sector_t block) | |||
| 401 | down_read(&OCFS2_I(inode)->ip_alloc_sem); | 461 | down_read(&OCFS2_I(inode)->ip_alloc_sem); |
| 402 | } | 462 | } |
| 403 | 463 | ||
| 404 | err = ocfs2_extent_map_get_blocks(inode, block, &p_blkno, NULL, NULL); | 464 | if (!(OCFS2_I(inode)->ip_dyn_features & OCFS2_INLINE_DATA_FL)) |
| 465 | err = ocfs2_extent_map_get_blocks(inode, block, &p_blkno, NULL, | ||
| 466 | NULL); | ||
| 405 | 467 | ||
| 406 | if (!INODE_JOURNAL(inode)) { | 468 | if (!INODE_JOURNAL(inode)) { |
| 407 | up_read(&OCFS2_I(inode)->ip_alloc_sem); | 469 | up_read(&OCFS2_I(inode)->ip_alloc_sem); |
| @@ -415,7 +477,6 @@ static sector_t ocfs2_bmap(struct address_space *mapping, sector_t block) | |||
| 415 | goto bail; | 477 | goto bail; |
| 416 | } | 478 | } |
| 417 | 479 | ||
| 418 | |||
| 419 | bail: | 480 | bail: |
| 420 | status = err ? 0 : p_blkno; | 481 | status = err ? 0 : p_blkno; |
| 421 | 482 | ||
| @@ -570,6 +631,13 @@ static ssize_t ocfs2_direct_IO(int rw, | |||
| 570 | 631 | ||
| 571 | mlog_entry_void(); | 632 | mlog_entry_void(); |
| 572 | 633 | ||
| 634 | /* | ||
| 635 | * Fallback to buffered I/O if we see an inode without | ||
| 636 | * extents. | ||
| 637 | */ | ||
| 638 | if (OCFS2_I(inode)->ip_dyn_features & OCFS2_INLINE_DATA_FL) | ||
| 639 | return 0; | ||
| 640 | |||
| 573 | if (!ocfs2_sparse_alloc(OCFS2_SB(inode->i_sb))) { | 641 | if (!ocfs2_sparse_alloc(OCFS2_SB(inode->i_sb))) { |
| 574 | /* | 642 | /* |
| 575 | * We get PR data locks even for O_DIRECT. This | 643 | * We get PR data locks even for O_DIRECT. This |
| @@ -834,18 +902,22 @@ struct ocfs2_write_ctxt { | |||
| 834 | struct ocfs2_cached_dealloc_ctxt w_dealloc; | 902 | struct ocfs2_cached_dealloc_ctxt w_dealloc; |
| 835 | }; | 903 | }; |
| 836 | 904 | ||
| 837 | static void ocfs2_free_write_ctxt(struct ocfs2_write_ctxt *wc) | 905 | void ocfs2_unlock_and_free_pages(struct page **pages, int num_pages) |
| 838 | { | 906 | { |
| 839 | int i; | 907 | int i; |
| 840 | 908 | ||
| 841 | for(i = 0; i < wc->w_num_pages; i++) { | 909 | for(i = 0; i < num_pages; i++) { |
| 842 | if (wc->w_pages[i] == NULL) | 910 | if (pages[i]) { |
| 843 | continue; | 911 | unlock_page(pages[i]); |
| 844 | 912 | mark_page_accessed(pages[i]); | |
| 845 | unlock_page(wc->w_pages[i]); | 913 | page_cache_release(pages[i]); |
| 846 | mark_page_accessed(wc->w_pages[i]); | 914 | } |
| 847 | page_cache_release(wc->w_pages[i]); | ||
| 848 | } | 915 | } |
| 916 | } | ||
| 917 | |||
| 918 | static void ocfs2_free_write_ctxt(struct ocfs2_write_ctxt *wc) | ||
| 919 | { | ||
| 920 | ocfs2_unlock_and_free_pages(wc->w_pages, wc->w_num_pages); | ||
| 849 | 921 | ||
| 850 | brelse(wc->w_di_bh); | 922 | brelse(wc->w_di_bh); |
| 851 | kfree(wc); | 923 | kfree(wc); |
| @@ -1360,6 +1432,160 @@ out: | |||
| 1360 | return ret; | 1432 | return ret; |
| 1361 | } | 1433 | } |
| 1362 | 1434 | ||
| 1435 | static int ocfs2_write_begin_inline(struct address_space *mapping, | ||
| 1436 | struct inode *inode, | ||
| 1437 | struct ocfs2_write_ctxt *wc) | ||
| 1438 | { | ||
| 1439 | int ret; | ||
| 1440 | struct ocfs2_super *osb = OCFS2_SB(inode->i_sb); | ||
| 1441 | struct page *page; | ||
| 1442 | handle_t *handle; | ||
| 1443 | struct ocfs2_dinode *di = (struct ocfs2_dinode *)wc->w_di_bh->b_data; | ||
| 1444 | |||
| 1445 | page = find_or_create_page(mapping, 0, GFP_NOFS); | ||
| 1446 | if (!page) { | ||
| 1447 | ret = -ENOMEM; | ||
| 1448 | mlog_errno(ret); | ||
| 1449 | goto out; | ||
| 1450 | } | ||
| 1451 | /* | ||
| 1452 | * If we don't set w_num_pages then this page won't get unlocked | ||
| 1453 | * and freed on cleanup of the write context. | ||
| 1454 | */ | ||
| 1455 | wc->w_pages[0] = wc->w_target_page = page; | ||
| 1456 | wc->w_num_pages = 1; | ||
| 1457 | |||
| 1458 | handle = ocfs2_start_trans(osb, OCFS2_INODE_UPDATE_CREDITS); | ||
| 1459 | if (IS_ERR(handle)) { | ||
| 1460 | ret = PTR_ERR(handle); | ||
| 1461 | mlog_errno(ret); | ||
| 1462 | goto out; | ||
| 1463 | } | ||
| 1464 | |||
| 1465 | ret = ocfs2_journal_access(handle, inode, wc->w_di_bh, | ||
| 1466 | OCFS2_JOURNAL_ACCESS_WRITE); | ||
| 1467 | if (ret) { | ||
| 1468 | ocfs2_commit_trans(osb, handle); | ||
| 1469 | |||
| 1470 | mlog_errno(ret); | ||
| 1471 | goto out; | ||
| 1472 | } | ||
| 1473 | |||
| 1474 | if (!(OCFS2_I(inode)->ip_dyn_features & OCFS2_INLINE_DATA_FL)) | ||
| 1475 | ocfs2_set_inode_data_inline(inode, di); | ||
| 1476 | |||
| 1477 | if (!PageUptodate(page)) { | ||
| 1478 | ret = ocfs2_read_inline_data(inode, page, wc->w_di_bh); | ||
| 1479 | if (ret) { | ||
| 1480 | ocfs2_commit_trans(osb, handle); | ||
| 1481 | |||
| 1482 | goto out; | ||
| 1483 | } | ||
| 1484 | } | ||
| 1485 | |||
| 1486 | wc->w_handle = handle; | ||
| 1487 | out: | ||
| 1488 | return ret; | ||
| 1489 | } | ||
| 1490 | |||
| 1491 | int ocfs2_size_fits_inline_data(struct buffer_head *di_bh, u64 new_size) | ||
| 1492 | { | ||
| 1493 | struct ocfs2_dinode *di = (struct ocfs2_dinode *)di_bh->b_data; | ||
| 1494 | |||
| 1495 | if (new_size < le16_to_cpu(di->id2.i_data.id_count)) | ||
| 1496 | return 1; | ||
| 1497 | return 0; | ||
| 1498 | } | ||
| 1499 | |||
| 1500 | static int ocfs2_try_to_write_inline_data(struct address_space *mapping, | ||
| 1501 | struct inode *inode, loff_t pos, | ||
| 1502 | unsigned len, struct page *mmap_page, | ||
| 1503 | struct ocfs2_write_ctxt *wc) | ||
| 1504 | { | ||
| 1505 | int ret, written = 0; | ||
| 1506 | loff_t end = pos + len; | ||
| 1507 | struct ocfs2_inode_info *oi = OCFS2_I(inode); | ||
| 1508 | |||
| 1509 | mlog(0, "Inode %llu, write of %u bytes at off %llu. features: 0x%x\n", | ||
| 1510 | (unsigned long long)oi->ip_blkno, len, (unsigned long long)pos, | ||
| 1511 | oi->ip_dyn_features); | ||
| 1512 | |||
| 1513 | /* | ||
| 1514 | * Handle inodes which already have inline data 1st. | ||
| 1515 | */ | ||
| 1516 | if (oi->ip_dyn_features & OCFS2_INLINE_DATA_FL) { | ||
| 1517 | if (mmap_page == NULL && | ||
| 1518 | ocfs2_size_fits_inline_data(wc->w_di_bh, end)) | ||
| 1519 | goto do_inline_write; | ||
| 1520 | |||
| 1521 | /* | ||
| 1522 | * The write won't fit - we have to give this inode an | ||
| 1523 | * inline extent list now. | ||
| 1524 | */ | ||
| 1525 | ret = ocfs2_convert_inline_data_to_extents(inode, wc->w_di_bh); | ||
| 1526 | if (ret) | ||
| 1527 | mlog_errno(ret); | ||
| 1528 | goto out; | ||
| 1529 | } | ||
| 1530 | |||
| 1531 | /* | ||
| 1532 | * Check whether the inode can accept inline data. | ||
| 1533 | */ | ||
| 1534 | if (oi->ip_clusters != 0 || i_size_read(inode) != 0) | ||
| 1535 | return 0; | ||
| 1536 | |||
| 1537 | /* | ||
| 1538 | * Check whether the write can fit. | ||
| 1539 | */ | ||
| 1540 | if (mmap_page || end > ocfs2_max_inline_data(inode->i_sb)) | ||
| 1541 | return 0; | ||
| 1542 | |||
| 1543 | do_inline_write: | ||
| 1544 | ret = ocfs2_write_begin_inline(mapping, inode, wc); | ||
| 1545 | if (ret) { | ||
| 1546 | mlog_errno(ret); | ||
| 1547 | goto out; | ||
| 1548 | } | ||
| 1549 | |||
| 1550 | /* | ||
| 1551 | * This signals to the caller that the data can be written | ||
| 1552 | * inline. | ||
| 1553 | */ | ||
| 1554 | written = 1; | ||
| 1555 | out: | ||
| 1556 | return written ? written : ret; | ||
| 1557 | } | ||
| 1558 | |||
| 1559 | /* | ||
| 1560 | * This function only does anything for file systems which can't | ||
| 1561 | * handle sparse files. | ||
| 1562 | * | ||
| 1563 | * What we want to do here is fill in any hole between the current end | ||
| 1564 | * of allocation and the end of our write. That way the rest of the | ||
| 1565 | * write path can treat it as an non-allocating write, which has no | ||
| 1566 | * special case code for sparse/nonsparse files. | ||
| 1567 | */ | ||
| 1568 | static int ocfs2_expand_nonsparse_inode(struct inode *inode, loff_t pos, | ||
| 1569 | unsigned len, | ||
| 1570 | struct ocfs2_write_ctxt *wc) | ||
| 1571 | { | ||
| 1572 | int ret; | ||
| 1573 | struct ocfs2_super *osb = OCFS2_SB(inode->i_sb); | ||
| 1574 | loff_t newsize = pos + len; | ||
| 1575 | |||
| 1576 | if (ocfs2_sparse_alloc(osb)) | ||
| 1577 | return 0; | ||
| 1578 | |||
| 1579 | if (newsize <= i_size_read(inode)) | ||
| 1580 | return 0; | ||
| 1581 | |||
| 1582 | ret = ocfs2_extend_no_holes(inode, newsize, newsize - len); | ||
| 1583 | if (ret) | ||
| 1584 | mlog_errno(ret); | ||
| 1585 | |||
| 1586 | return ret; | ||
| 1587 | } | ||
| 1588 | |||
| 1363 | int ocfs2_write_begin_nolock(struct address_space *mapping, | 1589 | int ocfs2_write_begin_nolock(struct address_space *mapping, |
| 1364 | loff_t pos, unsigned len, unsigned flags, | 1590 | loff_t pos, unsigned len, unsigned flags, |
| 1365 | struct page **pagep, void **fsdata, | 1591 | struct page **pagep, void **fsdata, |
| @@ -1381,6 +1607,25 @@ int ocfs2_write_begin_nolock(struct address_space *mapping, | |||
| 1381 | return ret; | 1607 | return ret; |
| 1382 | } | 1608 | } |
| 1383 | 1609 | ||
| 1610 | if (ocfs2_supports_inline_data(osb)) { | ||
| 1611 | ret = ocfs2_try_to_write_inline_data(mapping, inode, pos, len, | ||
| 1612 | mmap_page, wc); | ||
| 1613 | if (ret == 1) { | ||
| 1614 | ret = 0; | ||
| 1615 | goto success; | ||
| 1616 | } | ||
| 1617 | if (ret < 0) { | ||
| 1618 | mlog_errno(ret); | ||
| 1619 | goto out; | ||
| 1620 | } | ||
| 1621 | } | ||
| 1622 | |||
| 1623 | ret = ocfs2_expand_nonsparse_inode(inode, pos, len, wc); | ||
| 1624 | if (ret) { | ||
| 1625 | mlog_errno(ret); | ||
| 1626 | goto out; | ||
| 1627 | } | ||
| 1628 | |||
| 1384 | ret = ocfs2_populate_write_desc(inode, wc, &clusters_to_alloc, | 1629 | ret = ocfs2_populate_write_desc(inode, wc, &clusters_to_alloc, |
| 1385 | &extents_to_split); | 1630 | &extents_to_split); |
| 1386 | if (ret) { | 1631 | if (ret) { |
| @@ -1462,6 +1707,7 @@ int ocfs2_write_begin_nolock(struct address_space *mapping, | |||
| 1462 | if (meta_ac) | 1707 | if (meta_ac) |
| 1463 | ocfs2_free_alloc_context(meta_ac); | 1708 | ocfs2_free_alloc_context(meta_ac); |
| 1464 | 1709 | ||
| 1710 | success: | ||
| 1465 | *pagep = wc->w_target_page; | 1711 | *pagep = wc->w_target_page; |
| 1466 | *fsdata = wc; | 1712 | *fsdata = wc; |
| 1467 | return 0; | 1713 | return 0; |
| @@ -1529,6 +1775,31 @@ out_fail: | |||
| 1529 | return ret; | 1775 | return ret; |
| 1530 | } | 1776 | } |
| 1531 | 1777 | ||
| 1778 | static void ocfs2_write_end_inline(struct inode *inode, loff_t pos, | ||
| 1779 | unsigned len, unsigned *copied, | ||
| 1780 | struct ocfs2_dinode *di, | ||
| 1781 | struct ocfs2_write_ctxt *wc) | ||
| 1782 | { | ||
| 1783 | void *kaddr; | ||
| 1784 | |||
| 1785 | if (unlikely(*copied < len)) { | ||
| 1786 | if (!PageUptodate(wc->w_target_page)) { | ||
| 1787 | *copied = 0; | ||
| 1788 | return; | ||
| 1789 | } | ||
| 1790 | } | ||
| 1791 | |||
| 1792 | kaddr = kmap_atomic(wc->w_target_page, KM_USER0); | ||
| 1793 | memcpy(di->id2.i_data.id_data + pos, kaddr + pos, *copied); | ||
| 1794 | kunmap_atomic(kaddr, KM_USER0); | ||
| 1795 | |||
| 1796 | mlog(0, "Data written to inode at offset %llu. " | ||
| 1797 | "id_count = %u, copied = %u, i_dyn_features = 0x%x\n", | ||
| 1798 | (unsigned long long)pos, *copied, | ||
| 1799 | le16_to_cpu(di->id2.i_data.id_count), | ||
| 1800 | le16_to_cpu(di->i_dyn_features)); | ||
| 1801 | } | ||
| 1802 | |||
| 1532 | int ocfs2_write_end_nolock(struct address_space *mapping, | 1803 | int ocfs2_write_end_nolock(struct address_space *mapping, |
| 1533 | loff_t pos, unsigned len, unsigned copied, | 1804 | loff_t pos, unsigned len, unsigned copied, |
| 1534 | struct page *page, void *fsdata) | 1805 | struct page *page, void *fsdata) |
| @@ -1542,6 +1813,11 @@ int ocfs2_write_end_nolock(struct address_space *mapping, | |||
| 1542 | handle_t *handle = wc->w_handle; | 1813 | handle_t *handle = wc->w_handle; |
| 1543 | struct page *tmppage; | 1814 | struct page *tmppage; |
| 1544 | 1815 | ||
| 1816 | if (OCFS2_I(inode)->ip_dyn_features & OCFS2_INLINE_DATA_FL) { | ||
| 1817 | ocfs2_write_end_inline(inode, pos, len, &copied, di, wc); | ||
| 1818 | goto out_write_size; | ||
| 1819 | } | ||
| 1820 | |||
| 1545 | if (unlikely(copied < len)) { | 1821 | if (unlikely(copied < len)) { |
| 1546 | if (!PageUptodate(wc->w_target_page)) | 1822 | if (!PageUptodate(wc->w_target_page)) |
| 1547 | copied = 0; | 1823 | copied = 0; |
| @@ -1579,6 +1855,7 @@ int ocfs2_write_end_nolock(struct address_space *mapping, | |||
| 1579 | block_commit_write(tmppage, from, to); | 1855 | block_commit_write(tmppage, from, to); |
| 1580 | } | 1856 | } |
| 1581 | 1857 | ||
| 1858 | out_write_size: | ||
| 1582 | pos += copied; | 1859 | pos += copied; |
| 1583 | if (pos > inode->i_size) { | 1860 | if (pos > inode->i_size) { |
| 1584 | i_size_write(inode, pos); | 1861 | i_size_write(inode, pos); |
