aboutsummaryrefslogtreecommitdiffstats
path: root/fs
diff options
context:
space:
mode:
authorTao Ma <boyu.mt@taobao.com>2012-12-10 14:05:57 -0500
committerTheodore Ts'o <tytso@mit.edu>2012-12-10 14:05:57 -0500
commit3fdcfb668fd78ec92d9bc2daddf1d41e2a8a30bb (patch)
tree7f6a45d4815824132c0d70906e04a937a2a222bf /fs
parentf19d5870cbf72d4cb2a8e1f749dff97af99b071e (diff)
ext4: add journalled write support for inline data
Signed-off-by: Tao Ma <boyu.mt@taobao.com> Signed-off-by: "Theodore Ts'o" <tytso@mit.edu>
Diffstat (limited to 'fs')
-rw-r--r--fs/ext4/inline.c24
-rw-r--r--fs/ext4/inode.c69
-rw-r--r--fs/ext4/xattr.h12
3 files changed, 85 insertions, 20 deletions
diff --git a/fs/ext4/inline.c b/fs/ext4/inline.c
index 320ff6fe5d8c..01274b1e7d40 100644
--- a/fs/ext4/inline.c
+++ b/fs/ext4/inline.c
@@ -747,6 +747,30 @@ out:
747 return copied; 747 return copied;
748} 748}
749 749
750struct buffer_head *
751ext4_journalled_write_inline_data(struct inode *inode,
752 unsigned len,
753 struct page *page)
754{
755 int ret;
756 void *kaddr;
757 struct ext4_iloc iloc;
758
759 ret = ext4_get_inode_loc(inode, &iloc);
760 if (ret) {
761 ext4_std_error(inode->i_sb, ret);
762 return NULL;
763 }
764
765 down_write(&EXT4_I(inode)->xattr_sem);
766 kaddr = kmap_atomic(page);
767 ext4_write_inline_data(inode, &iloc, kaddr, 0, len);
768 kunmap_atomic(kaddr);
769 up_write(&EXT4_I(inode)->xattr_sem);
770
771 return iloc.bh;
772}
773
750 774
751int ext4_destroy_inline_data(handle_t *handle, struct inode *inode) 775int ext4_destroy_inline_data(handle_t *handle, struct inode *inode)
752{ 776{
diff --git a/fs/ext4/inode.c b/fs/ext4/inode.c
index 70c8d5f323f0..5c91622cfe01 100644
--- a/fs/ext4/inode.c
+++ b/fs/ext4/inode.c
@@ -1124,16 +1124,21 @@ static int ext4_journalled_write_end(struct file *file,
1124 1124
1125 BUG_ON(!ext4_handle_valid(handle)); 1125 BUG_ON(!ext4_handle_valid(handle));
1126 1126
1127 if (copied < len) { 1127 if (ext4_has_inline_data(inode))
1128 if (!PageUptodate(page)) 1128 copied = ext4_write_inline_data_end(inode, pos, len,
1129 copied = 0; 1129 copied, page);
1130 page_zero_new_buffers(page, from+copied, to); 1130 else {
1131 } 1131 if (copied < len) {
1132 if (!PageUptodate(page))
1133 copied = 0;
1134 page_zero_new_buffers(page, from+copied, to);
1135 }
1132 1136
1133 ret = ext4_walk_page_buffers(handle, page_buffers(page), from, 1137 ret = ext4_walk_page_buffers(handle, page_buffers(page), from,
1134 to, &partial, write_end_fn); 1138 to, &partial, write_end_fn);
1135 if (!partial) 1139 if (!partial)
1136 SetPageUptodate(page); 1140 SetPageUptodate(page);
1141 }
1137 new_i_size = pos + copied; 1142 new_i_size = pos + copied;
1138 if (new_i_size > inode->i_size) 1143 if (new_i_size > inode->i_size)
1139 i_size_write(inode, pos+copied); 1144 i_size_write(inode, pos+copied);
@@ -1911,15 +1916,29 @@ static int __ext4_journalled_writepage(struct page *page,
1911{ 1916{
1912 struct address_space *mapping = page->mapping; 1917 struct address_space *mapping = page->mapping;
1913 struct inode *inode = mapping->host; 1918 struct inode *inode = mapping->host;
1914 struct buffer_head *page_bufs; 1919 struct buffer_head *page_bufs = NULL;
1915 handle_t *handle = NULL; 1920 handle_t *handle = NULL;
1916 int ret = 0; 1921 int ret = 0, err = 0;
1917 int err; 1922 int inline_data = ext4_has_inline_data(inode);
1923 struct buffer_head *inode_bh = NULL;
1918 1924
1919 ClearPageChecked(page); 1925 ClearPageChecked(page);
1920 page_bufs = page_buffers(page); 1926
1921 BUG_ON(!page_bufs); 1927 if (inline_data) {
1922 ext4_walk_page_buffers(handle, page_bufs, 0, len, NULL, bget_one); 1928 BUG_ON(page->index != 0);
1929 BUG_ON(len > ext4_get_max_inline_size(inode));
1930 inode_bh = ext4_journalled_write_inline_data(inode, len, page);
1931 if (inode_bh == NULL)
1932 goto out;
1933 } else {
1934 page_bufs = page_buffers(page);
1935 if (!page_bufs) {
1936 BUG();
1937 goto out;
1938 }
1939 ext4_walk_page_buffers(handle, page_bufs, 0, len,
1940 NULL, bget_one);
1941 }
1923 /* As soon as we unlock the page, it can go away, but we have 1942 /* As soon as we unlock the page, it can go away, but we have
1924 * references to buffers so we are safe */ 1943 * references to buffers so we are safe */
1925 unlock_page(page); 1944 unlock_page(page);
@@ -1932,11 +1951,18 @@ static int __ext4_journalled_writepage(struct page *page,
1932 1951
1933 BUG_ON(!ext4_handle_valid(handle)); 1952 BUG_ON(!ext4_handle_valid(handle));
1934 1953
1935 ret = ext4_walk_page_buffers(handle, page_bufs, 0, len, NULL, 1954 if (inline_data) {
1936 do_journal_get_write_access); 1955 ret = ext4_journal_get_write_access(handle, inode_bh);
1937 1956
1938 err = ext4_walk_page_buffers(handle, page_bufs, 0, len, NULL, 1957 err = ext4_handle_dirty_metadata(handle, inode, inode_bh);
1939 write_end_fn); 1958
1959 } else {
1960 ret = ext4_walk_page_buffers(handle, page_bufs, 0, len, NULL,
1961 do_journal_get_write_access);
1962
1963 err = ext4_walk_page_buffers(handle, page_bufs, 0, len, NULL,
1964 write_end_fn);
1965 }
1940 if (ret == 0) 1966 if (ret == 0)
1941 ret = err; 1967 ret = err;
1942 EXT4_I(inode)->i_datasync_tid = handle->h_transaction->t_tid; 1968 EXT4_I(inode)->i_datasync_tid = handle->h_transaction->t_tid;
@@ -1944,9 +1970,12 @@ static int __ext4_journalled_writepage(struct page *page,
1944 if (!ret) 1970 if (!ret)
1945 ret = err; 1971 ret = err;
1946 1972
1947 ext4_walk_page_buffers(handle, page_bufs, 0, len, NULL, bput_one); 1973 if (!ext4_has_inline_data(inode))
1974 ext4_walk_page_buffers(handle, page_bufs, 0, len,
1975 NULL, bput_one);
1948 ext4_set_inode_state(inode, EXT4_STATE_JDATA); 1976 ext4_set_inode_state(inode, EXT4_STATE_JDATA);
1949out: 1977out:
1978 brelse(inode_bh);
1950 return ret; 1979 return ret;
1951} 1980}
1952 1981
diff --git a/fs/ext4/xattr.h b/fs/ext4/xattr.h
index db5672206238..7095ac13fbc2 100644
--- a/fs/ext4/xattr.h
+++ b/fs/ext4/xattr.h
@@ -150,6 +150,10 @@ extern int ext4_write_inline_data_end(struct inode *inode,
150 loff_t pos, unsigned len, 150 loff_t pos, unsigned len,
151 unsigned copied, 151 unsigned copied,
152 struct page *page); 152 struct page *page);
153extern struct buffer_head *
154ext4_journalled_write_inline_data(struct inode *inode,
155 unsigned len,
156 struct page *page);
153# else /* CONFIG_EXT4_FS_XATTR */ 157# else /* CONFIG_EXT4_FS_XATTR */
154 158
155static inline int 159static inline int
@@ -288,6 +292,14 @@ static inline int ext4_write_inline_data_end(struct inode *inode,
288{ 292{
289 return 0; 293 return 0;
290} 294}
295
296static inline struct buffer_head *
297ext4_journalled_write_inline_data(struct inode *inode,
298 unsigned len,
299 struct page *page)
300{
301 return NULL;
302}
291# endif /* CONFIG_EXT4_FS_XATTR */ 303# endif /* CONFIG_EXT4_FS_XATTR */
292 304
293#ifdef CONFIG_EXT4_FS_SECURITY 305#ifdef CONFIG_EXT4_FS_SECURITY