|
@@ -1124,16 +1124,21 @@ static int ext4_journalled_write_end(struct file *file,
|
|
|
|
|
|
BUG_ON(!ext4_handle_valid(handle));
|
|
|
|
|
|
- if (copied < len) {
|
|
|
- if (!PageUptodate(page))
|
|
|
- copied = 0;
|
|
|
- page_zero_new_buffers(page, from+copied, to);
|
|
|
- }
|
|
|
+ if (ext4_has_inline_data(inode))
|
|
|
+ copied = ext4_write_inline_data_end(inode, pos, len,
|
|
|
+ copied, page);
|
|
|
+ else {
|
|
|
+ if (copied < len) {
|
|
|
+ if (!PageUptodate(page))
|
|
|
+ copied = 0;
|
|
|
+ page_zero_new_buffers(page, from+copied, to);
|
|
|
+ }
|
|
|
|
|
|
- ret = ext4_walk_page_buffers(handle, page_buffers(page), from,
|
|
|
- to, &partial, write_end_fn);
|
|
|
- if (!partial)
|
|
|
- SetPageUptodate(page);
|
|
|
+ ret = ext4_walk_page_buffers(handle, page_buffers(page), from,
|
|
|
+ to, &partial, write_end_fn);
|
|
|
+ if (!partial)
|
|
|
+ SetPageUptodate(page);
|
|
|
+ }
|
|
|
new_i_size = pos + copied;
|
|
|
if (new_i_size > inode->i_size)
|
|
|
i_size_write(inode, pos+copied);
|
|
@@ -1911,15 +1916,29 @@ static int __ext4_journalled_writepage(struct page *page,
|
|
|
{
|
|
|
struct address_space *mapping = page->mapping;
|
|
|
struct inode *inode = mapping->host;
|
|
|
- struct buffer_head *page_bufs;
|
|
|
+ struct buffer_head *page_bufs = NULL;
|
|
|
handle_t *handle = NULL;
|
|
|
- int ret = 0;
|
|
|
- int err;
|
|
|
+ int ret = 0, err = 0;
|
|
|
+ int inline_data = ext4_has_inline_data(inode);
|
|
|
+ struct buffer_head *inode_bh = NULL;
|
|
|
|
|
|
ClearPageChecked(page);
|
|
|
- page_bufs = page_buffers(page);
|
|
|
- BUG_ON(!page_bufs);
|
|
|
- ext4_walk_page_buffers(handle, page_bufs, 0, len, NULL, bget_one);
|
|
|
+
|
|
|
+ if (inline_data) {
|
|
|
+ BUG_ON(page->index != 0);
|
|
|
+ BUG_ON(len > ext4_get_max_inline_size(inode));
|
|
|
+ inode_bh = ext4_journalled_write_inline_data(inode, len, page);
|
|
|
+ if (inode_bh == NULL)
|
|
|
+ goto out;
|
|
|
+ } else {
|
|
|
+ page_bufs = page_buffers(page);
|
|
|
+ if (!page_bufs) {
|
|
|
+ BUG();
|
|
|
+ goto out;
|
|
|
+ }
|
|
|
+ ext4_walk_page_buffers(handle, page_bufs, 0, len,
|
|
|
+ NULL, bget_one);
|
|
|
+ }
|
|
|
/* As soon as we unlock the page, it can go away, but we have
|
|
|
* references to buffers so we are safe */
|
|
|
unlock_page(page);
|
|
@@ -1932,11 +1951,18 @@ static int __ext4_journalled_writepage(struct page *page,
|
|
|
|
|
|
BUG_ON(!ext4_handle_valid(handle));
|
|
|
|
|
|
- ret = ext4_walk_page_buffers(handle, page_bufs, 0, len, NULL,
|
|
|
- do_journal_get_write_access);
|
|
|
+ if (inline_data) {
|
|
|
+ ret = ext4_journal_get_write_access(handle, inode_bh);
|
|
|
|
|
|
- err = ext4_walk_page_buffers(handle, page_bufs, 0, len, NULL,
|
|
|
- write_end_fn);
|
|
|
+ err = ext4_handle_dirty_metadata(handle, inode, inode_bh);
|
|
|
+
|
|
|
+ } else {
|
|
|
+ ret = ext4_walk_page_buffers(handle, page_bufs, 0, len, NULL,
|
|
|
+ do_journal_get_write_access);
|
|
|
+
|
|
|
+ err = ext4_walk_page_buffers(handle, page_bufs, 0, len, NULL,
|
|
|
+ write_end_fn);
|
|
|
+ }
|
|
|
if (ret == 0)
|
|
|
ret = err;
|
|
|
EXT4_I(inode)->i_datasync_tid = handle->h_transaction->t_tid;
|
|
@@ -1944,9 +1970,12 @@ static int __ext4_journalled_writepage(struct page *page,
|
|
|
if (!ret)
|
|
|
ret = err;
|
|
|
|
|
|
- ext4_walk_page_buffers(handle, page_bufs, 0, len, NULL, bput_one);
|
|
|
+ if (!ext4_has_inline_data(inode))
|
|
|
+ ext4_walk_page_buffers(handle, page_bufs, 0, len,
|
|
|
+ NULL, bput_one);
|
|
|
ext4_set_inode_state(inode, EXT4_STATE_JDATA);
|
|
|
out:
|
|
|
+ brelse(inode_bh);
|
|
|
return ret;
|
|
|
}
|
|
|
|