diff options
author | Tao Ma <boyu.mt@taobao.com> | 2012-12-10 14:05:57 -0500 |
---|---|---|
committer | Theodore Ts'o <tytso@mit.edu> | 2012-12-10 14:05:57 -0500 |
commit | 3fdcfb668fd78ec92d9bc2daddf1d41e2a8a30bb (patch) | |
tree | 7f6a45d4815824132c0d70906e04a937a2a222bf /fs/ext4/inode.c | |
parent | f19d5870cbf72d4cb2a8e1f749dff97af99b071e (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/ext4/inode.c')
-rw-r--r-- | fs/ext4/inode.c | 69 |
1 files changed, 49 insertions, 20 deletions
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); |
1949 | out: | 1977 | out: |
1978 | brelse(inode_bh); | ||
1950 | return ret; | 1979 | return ret; |
1951 | } | 1980 | } |
1952 | 1981 | ||