diff options
author | Linus Torvalds <torvalds@linux-foundation.org> | 2009-09-23 12:29:20 -0400 |
---|---|---|
committer | Linus Torvalds <torvalds@linux-foundation.org> | 2009-09-23 12:29:20 -0400 |
commit | b64ada6b23d4a305fb3ca59b79dd38707fc53b69 (patch) | |
tree | 61bc87dc3a2549f54231261aaa544acffcd12281 /fs/ocfs2/aops.c | |
parent | be90a49ca22a95f184d9f32d35b5247b44032849 (diff) | |
parent | b80474b432913f73cce8db001e9fa3104f9b79ee (diff) |
Merge branch 'upstream-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/jlbec/ocfs2
* 'upstream-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/jlbec/ocfs2: (85 commits)
ocfs2: Use buffer IO if we are appending a file.
ocfs2: add spinlock protection when dealing with lockres->purge.
dlmglue.c: add missed mlog lines
ocfs2: __ocfs2_abort() should not enable panic for local mounts
ocfs2: Add ioctl for reflink.
ocfs2: Enable refcount tree support.
ocfs2: Implement ocfs2_reflink.
ocfs2: Add preserve to reflink.
ocfs2: Create reflinked file in orphan dir.
ocfs2: Use proper parameter for some inode operation.
ocfs2: Make transaction extend more efficient.
ocfs2: Don't merge in 1st refcount ops of reflink.
ocfs2: Modify removing xattr process for refcount.
ocfs2: Add reflink support for xattr.
ocfs2: Create an xattr indexed block if needed.
ocfs2: Call refcount tree remove process properly.
ocfs2: Attach xattr clusters to refcount tree.
ocfs2: Abstract ocfs2 xattr tree extend rec iteration process.
ocfs2: Abstract the creation of xattr block.
ocfs2: Remove inode from ocfs2_xattr_bucket_get_name_value.
...
Diffstat (limited to 'fs/ocfs2/aops.c')
-rw-r--r-- | fs/ocfs2/aops.c | 37 |
1 files changed, 31 insertions, 6 deletions
diff --git a/fs/ocfs2/aops.c b/fs/ocfs2/aops.c index 8a1e61545f41..72e76062a900 100644 --- a/fs/ocfs2/aops.c +++ b/fs/ocfs2/aops.c | |||
@@ -44,6 +44,7 @@ | |||
44 | #include "suballoc.h" | 44 | #include "suballoc.h" |
45 | #include "super.h" | 45 | #include "super.h" |
46 | #include "symlink.h" | 46 | #include "symlink.h" |
47 | #include "refcounttree.h" | ||
47 | 48 | ||
48 | #include "buffer_head_io.h" | 49 | #include "buffer_head_io.h" |
49 | 50 | ||
@@ -126,8 +127,8 @@ bail: | |||
126 | return err; | 127 | return err; |
127 | } | 128 | } |
128 | 129 | ||
129 | static int ocfs2_get_block(struct inode *inode, sector_t iblock, | 130 | int ocfs2_get_block(struct inode *inode, sector_t iblock, |
130 | struct buffer_head *bh_result, int create) | 131 | struct buffer_head *bh_result, int create) |
131 | { | 132 | { |
132 | int err = 0; | 133 | int err = 0; |
133 | unsigned int ext_flags; | 134 | unsigned int ext_flags; |
@@ -590,6 +591,8 @@ static int ocfs2_direct_IO_get_blocks(struct inode *inode, sector_t iblock, | |||
590 | goto bail; | 591 | goto bail; |
591 | } | 592 | } |
592 | 593 | ||
594 | /* We should already CoW the refcounted extent. */ | ||
595 | BUG_ON(ext_flags & OCFS2_EXT_REFCOUNTED); | ||
593 | /* | 596 | /* |
594 | * get_more_blocks() expects us to describe a hole by clearing | 597 | * get_more_blocks() expects us to describe a hole by clearing |
595 | * the mapped bit on bh_result(). | 598 | * the mapped bit on bh_result(). |
@@ -687,6 +690,10 @@ static ssize_t ocfs2_direct_IO(int rw, | |||
687 | if (OCFS2_I(inode)->ip_dyn_features & OCFS2_INLINE_DATA_FL) | 690 | if (OCFS2_I(inode)->ip_dyn_features & OCFS2_INLINE_DATA_FL) |
688 | return 0; | 691 | return 0; |
689 | 692 | ||
693 | /* Fallback to buffered I/O if we are appending. */ | ||
694 | if (i_size_read(inode) <= offset) | ||
695 | return 0; | ||
696 | |||
690 | ret = blockdev_direct_IO_no_locking(rw, iocb, inode, | 697 | ret = blockdev_direct_IO_no_locking(rw, iocb, inode, |
691 | inode->i_sb->s_bdev, iov, offset, | 698 | inode->i_sb->s_bdev, iov, offset, |
692 | nr_segs, | 699 | nr_segs, |
@@ -1259,7 +1266,8 @@ static int ocfs2_write_cluster(struct address_space *mapping, | |||
1259 | goto out; | 1266 | goto out; |
1260 | } | 1267 | } |
1261 | } else if (unwritten) { | 1268 | } else if (unwritten) { |
1262 | ocfs2_init_dinode_extent_tree(&et, inode, wc->w_di_bh); | 1269 | ocfs2_init_dinode_extent_tree(&et, INODE_CACHE(inode), |
1270 | wc->w_di_bh); | ||
1263 | ret = ocfs2_mark_extent_written(inode, &et, | 1271 | ret = ocfs2_mark_extent_written(inode, &et, |
1264 | wc->w_handle, cpos, 1, phys, | 1272 | wc->w_handle, cpos, 1, phys, |
1265 | meta_ac, &wc->w_dealloc); | 1273 | meta_ac, &wc->w_dealloc); |
@@ -1448,6 +1456,9 @@ static int ocfs2_populate_write_desc(struct inode *inode, | |||
1448 | goto out; | 1456 | goto out; |
1449 | } | 1457 | } |
1450 | 1458 | ||
1459 | /* We should already CoW the refcountd extent. */ | ||
1460 | BUG_ON(ext_flags & OCFS2_EXT_REFCOUNTED); | ||
1461 | |||
1451 | /* | 1462 | /* |
1452 | * Assume worst case - that we're writing in | 1463 | * Assume worst case - that we're writing in |
1453 | * the middle of the extent. | 1464 | * the middle of the extent. |
@@ -1528,7 +1539,7 @@ static int ocfs2_write_begin_inline(struct address_space *mapping, | |||
1528 | goto out; | 1539 | goto out; |
1529 | } | 1540 | } |
1530 | 1541 | ||
1531 | ret = ocfs2_journal_access_di(handle, inode, wc->w_di_bh, | 1542 | ret = ocfs2_journal_access_di(handle, INODE_CACHE(inode), wc->w_di_bh, |
1532 | OCFS2_JOURNAL_ACCESS_WRITE); | 1543 | OCFS2_JOURNAL_ACCESS_WRITE); |
1533 | if (ret) { | 1544 | if (ret) { |
1534 | ocfs2_commit_trans(osb, handle); | 1545 | ocfs2_commit_trans(osb, handle); |
@@ -1699,6 +1710,19 @@ int ocfs2_write_begin_nolock(struct address_space *mapping, | |||
1699 | goto out; | 1710 | goto out; |
1700 | } | 1711 | } |
1701 | 1712 | ||
1713 | ret = ocfs2_check_range_for_refcount(inode, pos, len); | ||
1714 | if (ret < 0) { | ||
1715 | mlog_errno(ret); | ||
1716 | goto out; | ||
1717 | } else if (ret == 1) { | ||
1718 | ret = ocfs2_refcount_cow(inode, di_bh, | ||
1719 | wc->w_cpos, wc->w_clen, UINT_MAX); | ||
1720 | if (ret) { | ||
1721 | mlog_errno(ret); | ||
1722 | goto out; | ||
1723 | } | ||
1724 | } | ||
1725 | |||
1702 | ret = ocfs2_populate_write_desc(inode, wc, &clusters_to_alloc, | 1726 | ret = ocfs2_populate_write_desc(inode, wc, &clusters_to_alloc, |
1703 | &extents_to_split); | 1727 | &extents_to_split); |
1704 | if (ret) { | 1728 | if (ret) { |
@@ -1726,7 +1750,8 @@ int ocfs2_write_begin_nolock(struct address_space *mapping, | |||
1726 | (long long)i_size_read(inode), le32_to_cpu(di->i_clusters), | 1750 | (long long)i_size_read(inode), le32_to_cpu(di->i_clusters), |
1727 | clusters_to_alloc, extents_to_split); | 1751 | clusters_to_alloc, extents_to_split); |
1728 | 1752 | ||
1729 | ocfs2_init_dinode_extent_tree(&et, inode, wc->w_di_bh); | 1753 | ocfs2_init_dinode_extent_tree(&et, INODE_CACHE(inode), |
1754 | wc->w_di_bh); | ||
1730 | ret = ocfs2_lock_allocators(inode, &et, | 1755 | ret = ocfs2_lock_allocators(inode, &et, |
1731 | clusters_to_alloc, extents_to_split, | 1756 | clusters_to_alloc, extents_to_split, |
1732 | &data_ac, &meta_ac); | 1757 | &data_ac, &meta_ac); |
@@ -1773,7 +1798,7 @@ int ocfs2_write_begin_nolock(struct address_space *mapping, | |||
1773 | * We don't want this to fail in ocfs2_write_end(), so do it | 1798 | * We don't want this to fail in ocfs2_write_end(), so do it |
1774 | * here. | 1799 | * here. |
1775 | */ | 1800 | */ |
1776 | ret = ocfs2_journal_access_di(handle, inode, wc->w_di_bh, | 1801 | ret = ocfs2_journal_access_di(handle, INODE_CACHE(inode), wc->w_di_bh, |
1777 | OCFS2_JOURNAL_ACCESS_WRITE); | 1802 | OCFS2_JOURNAL_ACCESS_WRITE); |
1778 | if (ret) { | 1803 | if (ret) { |
1779 | mlog_errno(ret); | 1804 | mlog_errno(ret); |