diff options
Diffstat (limited to 'fs/ext4/inode.c')
-rw-r--r-- | fs/ext4/inode.c | 107 |
1 files changed, 79 insertions, 28 deletions
diff --git a/fs/ext4/inode.c b/fs/ext4/inode.c index c33fcb4f8533..e3d425eeab4a 100644 --- a/fs/ext4/inode.c +++ b/fs/ext4/inode.c | |||
@@ -72,10 +72,9 @@ static __u32 ext4_inode_csum(struct inode *inode, struct ext4_inode *raw, | |||
72 | csum = ext4_chksum(sbi, csum, (__u8 *)&dummy_csum, | 72 | csum = ext4_chksum(sbi, csum, (__u8 *)&dummy_csum, |
73 | csum_size); | 73 | csum_size); |
74 | offset += csum_size; | 74 | offset += csum_size; |
75 | csum = ext4_chksum(sbi, csum, (__u8 *)raw + offset, | ||
76 | EXT4_INODE_SIZE(inode->i_sb) - | ||
77 | offset); | ||
78 | } | 75 | } |
76 | csum = ext4_chksum(sbi, csum, (__u8 *)raw + offset, | ||
77 | EXT4_INODE_SIZE(inode->i_sb) - offset); | ||
79 | } | 78 | } |
80 | 79 | ||
81 | return csum; | 80 | return csum; |
@@ -1017,8 +1016,16 @@ static int ext4_write_begin(struct file *file, struct address_space *mapping, | |||
1017 | pgoff_t index; | 1016 | pgoff_t index; |
1018 | unsigned from, to; | 1017 | unsigned from, to; |
1019 | 1018 | ||
1020 | trace_android_fs_datawrite_start(inode, pos, len, | 1019 | if (trace_android_fs_datawrite_start_enabled()) { |
1021 | current->pid, current->comm); | 1020 | char *path, pathbuf[MAX_TRACE_PATHBUF_LEN]; |
1021 | |||
1022 | path = android_fstrace_get_pathname(pathbuf, | ||
1023 | MAX_TRACE_PATHBUF_LEN, | ||
1024 | inode); | ||
1025 | trace_android_fs_datawrite_start(inode, pos, len, | ||
1026 | current->pid, path, | ||
1027 | current->comm); | ||
1028 | } | ||
1022 | trace_ext4_write_begin(inode, pos, len, flags); | 1029 | trace_ext4_write_begin(inode, pos, len, flags); |
1023 | /* | 1030 | /* |
1024 | * Reserve one block more for addition to orphan list in case | 1031 | * Reserve one block more for addition to orphan list in case |
@@ -1169,8 +1176,11 @@ static int ext4_write_end(struct file *file, | |||
1169 | if (ext4_has_inline_data(inode)) { | 1176 | if (ext4_has_inline_data(inode)) { |
1170 | ret = ext4_write_inline_data_end(inode, pos, len, | 1177 | ret = ext4_write_inline_data_end(inode, pos, len, |
1171 | copied, page); | 1178 | copied, page); |
1172 | if (ret < 0) | 1179 | if (ret < 0) { |
1180 | unlock_page(page); | ||
1181 | put_page(page); | ||
1173 | goto errout; | 1182 | goto errout; |
1183 | } | ||
1174 | copied = ret; | 1184 | copied = ret; |
1175 | } else | 1185 | } else |
1176 | copied = block_write_end(file, mapping, pos, | 1186 | copied = block_write_end(file, mapping, pos, |
@@ -1224,7 +1234,9 @@ errout: | |||
1224 | * set the buffer to be dirty, since in data=journalled mode we need | 1234 | * set the buffer to be dirty, since in data=journalled mode we need |
1225 | * to call ext4_handle_dirty_metadata() instead. | 1235 | * to call ext4_handle_dirty_metadata() instead. |
1226 | */ | 1236 | */ |
1227 | static void zero_new_buffers(struct page *page, unsigned from, unsigned to) | 1237 | static void ext4_journalled_zero_new_buffers(handle_t *handle, |
1238 | struct page *page, | ||
1239 | unsigned from, unsigned to) | ||
1228 | { | 1240 | { |
1229 | unsigned int block_start = 0, block_end; | 1241 | unsigned int block_start = 0, block_end; |
1230 | struct buffer_head *head, *bh; | 1242 | struct buffer_head *head, *bh; |
@@ -1241,7 +1253,7 @@ static void zero_new_buffers(struct page *page, unsigned from, unsigned to) | |||
1241 | size = min(to, block_end) - start; | 1253 | size = min(to, block_end) - start; |
1242 | 1254 | ||
1243 | zero_user(page, start, size); | 1255 | zero_user(page, start, size); |
1244 | set_buffer_uptodate(bh); | 1256 | write_end_fn(handle, bh); |
1245 | } | 1257 | } |
1246 | clear_buffer_new(bh); | 1258 | clear_buffer_new(bh); |
1247 | } | 1259 | } |
@@ -1271,18 +1283,25 @@ static int ext4_journalled_write_end(struct file *file, | |||
1271 | 1283 | ||
1272 | BUG_ON(!ext4_handle_valid(handle)); | 1284 | BUG_ON(!ext4_handle_valid(handle)); |
1273 | 1285 | ||
1274 | if (ext4_has_inline_data(inode)) | 1286 | if (ext4_has_inline_data(inode)) { |
1275 | copied = ext4_write_inline_data_end(inode, pos, len, | 1287 | ret = ext4_write_inline_data_end(inode, pos, len, |
1276 | copied, page); | 1288 | copied, page); |
1277 | else { | 1289 | if (ret < 0) { |
1278 | if (copied < len) { | 1290 | unlock_page(page); |
1279 | if (!PageUptodate(page)) | 1291 | put_page(page); |
1280 | copied = 0; | 1292 | goto errout; |
1281 | zero_new_buffers(page, from+copied, to); | ||
1282 | } | 1293 | } |
1283 | 1294 | copied = ret; | |
1295 | } else if (unlikely(copied < len) && !PageUptodate(page)) { | ||
1296 | copied = 0; | ||
1297 | ext4_journalled_zero_new_buffers(handle, page, from, to); | ||
1298 | } else { | ||
1299 | if (unlikely(copied < len)) | ||
1300 | ext4_journalled_zero_new_buffers(handle, page, | ||
1301 | from + copied, to); | ||
1284 | ret = ext4_walk_page_buffers(handle, page_buffers(page), from, | 1302 | ret = ext4_walk_page_buffers(handle, page_buffers(page), from, |
1285 | to, &partial, write_end_fn); | 1303 | from + copied, &partial, |
1304 | write_end_fn); | ||
1286 | if (!partial) | 1305 | if (!partial) |
1287 | SetPageUptodate(page); | 1306 | SetPageUptodate(page); |
1288 | } | 1307 | } |
@@ -1308,6 +1327,7 @@ static int ext4_journalled_write_end(struct file *file, | |||
1308 | */ | 1327 | */ |
1309 | ext4_orphan_add(handle, inode); | 1328 | ext4_orphan_add(handle, inode); |
1310 | 1329 | ||
1330 | errout: | ||
1311 | ret2 = ext4_journal_stop(handle); | 1331 | ret2 = ext4_journal_stop(handle); |
1312 | if (!ret) | 1332 | if (!ret) |
1313 | ret = ret2; | 1333 | ret = ret2; |
@@ -2037,7 +2057,7 @@ static int mpage_process_page_bufs(struct mpage_da_data *mpd, | |||
2037 | { | 2057 | { |
2038 | struct inode *inode = mpd->inode; | 2058 | struct inode *inode = mpd->inode; |
2039 | int err; | 2059 | int err; |
2040 | ext4_lblk_t blocks = (i_size_read(inode) + (1 << inode->i_blkbits) - 1) | 2060 | ext4_lblk_t blocks = (i_size_read(inode) + i_blocksize(inode) - 1) |
2041 | >> inode->i_blkbits; | 2061 | >> inode->i_blkbits; |
2042 | 2062 | ||
2043 | do { | 2063 | do { |
@@ -2732,8 +2752,16 @@ static int ext4_da_write_begin(struct file *file, struct address_space *mapping, | |||
2732 | len, flags, pagep, fsdata); | 2752 | len, flags, pagep, fsdata); |
2733 | } | 2753 | } |
2734 | *fsdata = (void *)0; | 2754 | *fsdata = (void *)0; |
2735 | trace_android_fs_datawrite_start(inode, pos, len, | 2755 | if (trace_android_fs_datawrite_start_enabled()) { |
2736 | current->pid, current->comm); | 2756 | char *path, pathbuf[MAX_TRACE_PATHBUF_LEN]; |
2757 | |||
2758 | path = android_fstrace_get_pathname(pathbuf, | ||
2759 | MAX_TRACE_PATHBUF_LEN, | ||
2760 | inode); | ||
2761 | trace_android_fs_datawrite_start(inode, pos, len, | ||
2762 | current->pid, | ||
2763 | path, current->comm); | ||
2764 | } | ||
2737 | trace_ext4_da_write_begin(inode, pos, len, flags); | 2765 | trace_ext4_da_write_begin(inode, pos, len, flags); |
2738 | 2766 | ||
2739 | if (ext4_test_inode_state(inode, EXT4_STATE_MAY_INLINE_DATA)) { | 2767 | if (ext4_test_inode_state(inode, EXT4_STATE_MAY_INLINE_DATA)) { |
@@ -3342,16 +3370,27 @@ static ssize_t ext4_direct_IO(struct kiocb *iocb, struct iov_iter *iter, | |||
3342 | return 0; | 3370 | return 0; |
3343 | 3371 | ||
3344 | if (trace_android_fs_dataread_start_enabled() && | 3372 | if (trace_android_fs_dataread_start_enabled() && |
3345 | (iov_iter_rw(iter) == READ)) | 3373 | (iov_iter_rw(iter) == READ)) { |
3374 | char *path, pathbuf[MAX_TRACE_PATHBUF_LEN]; | ||
3375 | |||
3376 | path = android_fstrace_get_pathname(pathbuf, | ||
3377 | MAX_TRACE_PATHBUF_LEN, | ||
3378 | inode); | ||
3346 | trace_android_fs_dataread_start(inode, offset, count, | 3379 | trace_android_fs_dataread_start(inode, offset, count, |
3347 | current->pid, | 3380 | current->pid, path, |
3348 | current->comm); | 3381 | current->comm); |
3382 | } | ||
3349 | if (trace_android_fs_datawrite_start_enabled() && | 3383 | if (trace_android_fs_datawrite_start_enabled() && |
3350 | (iov_iter_rw(iter) == WRITE)) | 3384 | (iov_iter_rw(iter) == WRITE)) { |
3385 | char *path, pathbuf[MAX_TRACE_PATHBUF_LEN]; | ||
3386 | |||
3387 | path = android_fstrace_get_pathname(pathbuf, | ||
3388 | MAX_TRACE_PATHBUF_LEN, | ||
3389 | inode); | ||
3351 | trace_android_fs_datawrite_start(inode, offset, count, | 3390 | trace_android_fs_datawrite_start(inode, offset, count, |
3352 | current->pid, | 3391 | current->pid, path, |
3353 | current->comm); | 3392 | current->comm); |
3354 | 3393 | } | |
3355 | trace_ext4_direct_IO_enter(inode, offset, count, iov_iter_rw(iter)); | 3394 | trace_ext4_direct_IO_enter(inode, offset, count, iov_iter_rw(iter)); |
3356 | if (ext4_test_inode_flag(inode, EXT4_INODE_EXTENTS)) | 3395 | if (ext4_test_inode_flag(inode, EXT4_INODE_EXTENTS)) |
3357 | ret = ext4_ext_direct_IO(iocb, iter, offset); | 3396 | ret = ext4_ext_direct_IO(iocb, iter, offset); |
@@ -3587,6 +3626,10 @@ static int ext4_block_truncate_page(handle_t *handle, | |||
3587 | unsigned blocksize; | 3626 | unsigned blocksize; |
3588 | struct inode *inode = mapping->host; | 3627 | struct inode *inode = mapping->host; |
3589 | 3628 | ||
3629 | /* If we are processing an encrypted inode during orphan list handling */ | ||
3630 | if (ext4_encrypted_inode(inode) && !ext4_has_encryption_key(inode)) | ||
3631 | return 0; | ||
3632 | |||
3590 | blocksize = inode->i_sb->s_blocksize; | 3633 | blocksize = inode->i_sb->s_blocksize; |
3591 | length = blocksize - (offset & (blocksize - 1)); | 3634 | length = blocksize - (offset & (blocksize - 1)); |
3592 | 3635 | ||
@@ -3804,6 +3847,8 @@ int ext4_punch_hole(struct inode *inode, loff_t offset, loff_t length) | |||
3804 | 3847 | ||
3805 | inode->i_mtime = inode->i_ctime = ext4_current_time(inode); | 3848 | inode->i_mtime = inode->i_ctime = ext4_current_time(inode); |
3806 | ext4_mark_inode_dirty(handle, inode); | 3849 | ext4_mark_inode_dirty(handle, inode); |
3850 | if (ret >= 0) | ||
3851 | ext4_update_inode_fsync_trans(handle, inode, 1); | ||
3807 | out_stop: | 3852 | out_stop: |
3808 | ext4_journal_stop(handle); | 3853 | ext4_journal_stop(handle); |
3809 | out_dio: | 3854 | out_dio: |
@@ -5173,8 +5218,9 @@ static int ext4_expand_extra_isize(struct inode *inode, | |||
5173 | /* No extended attributes present */ | 5218 | /* No extended attributes present */ |
5174 | if (!ext4_test_inode_state(inode, EXT4_STATE_XATTR) || | 5219 | if (!ext4_test_inode_state(inode, EXT4_STATE_XATTR) || |
5175 | header->h_magic != cpu_to_le32(EXT4_XATTR_MAGIC)) { | 5220 | header->h_magic != cpu_to_le32(EXT4_XATTR_MAGIC)) { |
5176 | memset((void *)raw_inode + EXT4_GOOD_OLD_INODE_SIZE, 0, | 5221 | memset((void *)raw_inode + EXT4_GOOD_OLD_INODE_SIZE + |
5177 | new_extra_isize); | 5222 | EXT4_I(inode)->i_extra_isize, 0, |
5223 | new_extra_isize - EXT4_I(inode)->i_extra_isize); | ||
5178 | EXT4_I(inode)->i_extra_isize = new_extra_isize; | 5224 | EXT4_I(inode)->i_extra_isize = new_extra_isize; |
5179 | return 0; | 5225 | return 0; |
5180 | } | 5226 | } |
@@ -5404,6 +5450,11 @@ int ext4_page_mkwrite(struct vm_area_struct *vma, struct vm_fault *vmf) | |||
5404 | file_update_time(vma->vm_file); | 5450 | file_update_time(vma->vm_file); |
5405 | 5451 | ||
5406 | down_read(&EXT4_I(inode)->i_mmap_sem); | 5452 | down_read(&EXT4_I(inode)->i_mmap_sem); |
5453 | |||
5454 | ret = ext4_convert_inline_data(inode); | ||
5455 | if (ret) | ||
5456 | goto out_ret; | ||
5457 | |||
5407 | /* Delalloc case is easy... */ | 5458 | /* Delalloc case is easy... */ |
5408 | if (test_opt(inode->i_sb, DELALLOC) && | 5459 | if (test_opt(inode->i_sb, DELALLOC) && |
5409 | !ext4_should_journal_data(inode) && | 5460 | !ext4_should_journal_data(inode) && |