Commit 3fdcfb668fd78ec92d9bc2daddf1d41e2a8a30bb

Authored by Tao Ma
Committed by Theodore Ts'o
1 parent f19d5870cb

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>

Showing 3 changed files with 85 additions and 20 deletions Side-by-side Diff

... ... @@ -747,6 +747,30 @@
747 747 return copied;
748 748 }
749 749  
  750 +struct buffer_head *
  751 +ext4_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  
751 775 int ext4_destroy_inline_data(handle_t *handle, struct inode *inode)
752 776 {
... ... @@ -1124,16 +1124,21 @@
1124 1124  
1125 1125 BUG_ON(!ext4_handle_valid(handle));
1126 1126  
1127   - if (copied < len) {
1128   - if (!PageUptodate(page))
1129   - copied = 0;
1130   - page_zero_new_buffers(page, from+copied, to);
1131   - }
  1127 + if (ext4_has_inline_data(inode))
  1128 + copied = ext4_write_inline_data_end(inode, pos, len,
  1129 + copied, page);
  1130 + else {
  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,
1134   - to, &partial, write_end_fn);
1135   - if (!partial)
1136   - SetPageUptodate(page);
  1137 + ret = ext4_walk_page_buffers(handle, page_buffers(page), from,
  1138 + to, &partial, write_end_fn);
  1139 + if (!partial)
  1140 + SetPageUptodate(page);
  1141 + }
1137 1142 new_i_size = pos + copied;
1138 1143 if (new_i_size > inode->i_size)
1139 1144 i_size_write(inode, pos+copied);
1140 1145  
1141 1146  
... ... @@ -1911,15 +1916,29 @@
1911 1916 {
1912 1917 struct address_space *mapping = page->mapping;
1913 1918 struct inode *inode = mapping->host;
1914   - struct buffer_head *page_bufs;
  1919 + struct buffer_head *page_bufs = NULL;
1915 1920 handle_t *handle = NULL;
1916   - int ret = 0;
1917   - int err;
  1921 + int ret = 0, err = 0;
  1922 + int inline_data = ext4_has_inline_data(inode);
  1923 + struct buffer_head *inode_bh = NULL;
1918 1924  
1919 1925 ClearPageChecked(page);
1920   - page_bufs = page_buffers(page);
1921   - BUG_ON(!page_bufs);
1922   - ext4_walk_page_buffers(handle, page_bufs, 0, len, NULL, bget_one);
  1926 +
  1927 + if (inline_data) {
  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 1942 /* As soon as we unlock the page, it can go away, but we have
1924 1943 * references to buffers so we are safe */
1925 1944 unlock_page(page);
1926 1945  
... ... @@ -1932,11 +1951,18 @@
1932 1951  
1933 1952 BUG_ON(!ext4_handle_valid(handle));
1934 1953  
1935   - ret = ext4_walk_page_buffers(handle, page_bufs, 0, len, NULL,
1936   - do_journal_get_write_access);
  1954 + if (inline_data) {
  1955 + ret = ext4_journal_get_write_access(handle, inode_bh);
1937 1956  
1938   - err = ext4_walk_page_buffers(handle, page_bufs, 0, len, NULL,
1939   - write_end_fn);
  1957 + err = ext4_handle_dirty_metadata(handle, inode, inode_bh);
  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 1966 if (ret == 0)
1941 1967 ret = err;
1942 1968 EXT4_I(inode)->i_datasync_tid = handle->h_transaction->t_tid;
1943 1969  
... ... @@ -1944,9 +1970,12 @@
1944 1970 if (!ret)
1945 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 1976 ext4_set_inode_state(inode, EXT4_STATE_JDATA);
1949 1977 out:
  1978 + brelse(inode_bh);
1950 1979 return ret;
1951 1980 }
1952 1981  
... ... @@ -150,6 +150,10 @@
150 150 loff_t pos, unsigned len,
151 151 unsigned copied,
152 152 struct page *page);
  153 +extern struct buffer_head *
  154 +ext4_journalled_write_inline_data(struct inode *inode,
  155 + unsigned len,
  156 + struct page *page);
153 157 # else /* CONFIG_EXT4_FS_XATTR */
154 158  
155 159 static inline int
... ... @@ -287,6 +291,14 @@
287 291 struct page *page)
288 292 {
289 293 return 0;
  294 +}
  295 +
  296 +static inline struct buffer_head *
  297 +ext4_journalled_write_inline_data(struct inode *inode,
  298 + unsigned len,
  299 + struct page *page)
  300 +{
  301 + return NULL;
290 302 }
291 303 # endif /* CONFIG_EXT4_FS_XATTR */
292 304