diff options
-rw-r--r-- | fs/ext4/ext4_jbd2.h | 56 | ||||
-rw-r--r-- | fs/ext4/inode.c | 36 |
2 files changed, 51 insertions, 41 deletions
diff --git a/fs/ext4/ext4_jbd2.h b/fs/ext4/ext4_jbd2.h index 5802fa1dab18..95af6f878501 100644 --- a/fs/ext4/ext4_jbd2.h +++ b/fs/ext4/ext4_jbd2.h | |||
@@ -261,43 +261,45 @@ static inline void ext4_update_inode_fsync_trans(handle_t *handle, | |||
261 | /* super.c */ | 261 | /* super.c */ |
262 | int ext4_force_commit(struct super_block *sb); | 262 | int ext4_force_commit(struct super_block *sb); |
263 | 263 | ||
264 | static inline int ext4_should_journal_data(struct inode *inode) | 264 | /* |
265 | * Ext4 inode journal modes | ||
266 | */ | ||
267 | #define EXT4_INODE_JOURNAL_DATA_MODE 0x01 /* journal data mode */ | ||
268 | #define EXT4_INODE_ORDERED_DATA_MODE 0x02 /* ordered data mode */ | ||
269 | #define EXT4_INODE_WRITEBACK_DATA_MODE 0x04 /* writeback data mode */ | ||
270 | |||
271 | static inline int ext4_inode_journal_mode(struct inode *inode) | ||
265 | { | 272 | { |
266 | if (EXT4_JOURNAL(inode) == NULL) | 273 | if (EXT4_JOURNAL(inode) == NULL) |
267 | return 0; | 274 | return EXT4_INODE_WRITEBACK_DATA_MODE; /* writeback */ |
268 | if (!S_ISREG(inode->i_mode)) | 275 | /* We do not support data journalling with delayed allocation */ |
269 | return 1; | 276 | if (!S_ISREG(inode->i_mode) || |
270 | if (test_opt(inode->i_sb, DATA_FLAGS) == EXT4_MOUNT_JOURNAL_DATA) | 277 | test_opt(inode->i_sb, DATA_FLAGS) == EXT4_MOUNT_JOURNAL_DATA) |
271 | return 1; | 278 | return EXT4_INODE_JOURNAL_DATA_MODE; /* journal data */ |
272 | if (ext4_test_inode_flag(inode, EXT4_INODE_JOURNAL_DATA)) | 279 | if (ext4_test_inode_flag(inode, EXT4_INODE_JOURNAL_DATA) && |
273 | return 1; | 280 | !test_opt(inode->i_sb, DELALLOC)) |
274 | return 0; | 281 | return EXT4_INODE_JOURNAL_DATA_MODE; /* journal data */ |
282 | if (test_opt(inode->i_sb, DATA_FLAGS) == EXT4_MOUNT_ORDERED_DATA) | ||
283 | return EXT4_INODE_ORDERED_DATA_MODE; /* ordered */ | ||
284 | if (test_opt(inode->i_sb, DATA_FLAGS) == EXT4_MOUNT_WRITEBACK_DATA) | ||
285 | return EXT4_INODE_WRITEBACK_DATA_MODE; /* writeback */ | ||
286 | else | ||
287 | BUG(); | ||
288 | } | ||
289 | |||
290 | static inline int ext4_should_journal_data(struct inode *inode) | ||
291 | { | ||
292 | return ext4_inode_journal_mode(inode) & EXT4_INODE_JOURNAL_DATA_MODE; | ||
275 | } | 293 | } |
276 | 294 | ||
277 | static inline int ext4_should_order_data(struct inode *inode) | 295 | static inline int ext4_should_order_data(struct inode *inode) |
278 | { | 296 | { |
279 | if (EXT4_JOURNAL(inode) == NULL) | 297 | return ext4_inode_journal_mode(inode) & EXT4_INODE_ORDERED_DATA_MODE; |
280 | return 0; | ||
281 | if (!S_ISREG(inode->i_mode)) | ||
282 | return 0; | ||
283 | if (ext4_test_inode_flag(inode, EXT4_INODE_JOURNAL_DATA)) | ||
284 | return 0; | ||
285 | if (test_opt(inode->i_sb, DATA_FLAGS) == EXT4_MOUNT_ORDERED_DATA) | ||
286 | return 1; | ||
287 | return 0; | ||
288 | } | 298 | } |
289 | 299 | ||
290 | static inline int ext4_should_writeback_data(struct inode *inode) | 300 | static inline int ext4_should_writeback_data(struct inode *inode) |
291 | { | 301 | { |
292 | if (EXT4_JOURNAL(inode) == NULL) | 302 | return ext4_inode_journal_mode(inode) & EXT4_INODE_WRITEBACK_DATA_MODE; |
293 | return 1; | ||
294 | if (!S_ISREG(inode->i_mode)) | ||
295 | return 0; | ||
296 | if (ext4_test_inode_flag(inode, EXT4_INODE_JOURNAL_DATA)) | ||
297 | return 0; | ||
298 | if (test_opt(inode->i_sb, DATA_FLAGS) == EXT4_MOUNT_WRITEBACK_DATA) | ||
299 | return 1; | ||
300 | return 0; | ||
301 | } | 303 | } |
302 | 304 | ||
303 | /* | 305 | /* |
diff --git a/fs/ext4/inode.c b/fs/ext4/inode.c index feaa82fe629d..a58812ef5ea3 100644 --- a/fs/ext4/inode.c +++ b/fs/ext4/inode.c | |||
@@ -2482,13 +2482,14 @@ static int ext4_da_write_end(struct file *file, | |||
2482 | int write_mode = (int)(unsigned long)fsdata; | 2482 | int write_mode = (int)(unsigned long)fsdata; |
2483 | 2483 | ||
2484 | if (write_mode == FALL_BACK_TO_NONDELALLOC) { | 2484 | if (write_mode == FALL_BACK_TO_NONDELALLOC) { |
2485 | if (ext4_should_order_data(inode)) { | 2485 | switch (ext4_inode_journal_mode(inode)) { |
2486 | case EXT4_INODE_ORDERED_DATA_MODE: | ||
2486 | return ext4_ordered_write_end(file, mapping, pos, | 2487 | return ext4_ordered_write_end(file, mapping, pos, |
2487 | len, copied, page, fsdata); | 2488 | len, copied, page, fsdata); |
2488 | } else if (ext4_should_writeback_data(inode)) { | 2489 | case EXT4_INODE_WRITEBACK_DATA_MODE: |
2489 | return ext4_writeback_write_end(file, mapping, pos, | 2490 | return ext4_writeback_write_end(file, mapping, pos, |
2490 | len, copied, page, fsdata); | 2491 | len, copied, page, fsdata); |
2491 | } else { | 2492 | default: |
2492 | BUG(); | 2493 | BUG(); |
2493 | } | 2494 | } |
2494 | } | 2495 | } |
@@ -3086,18 +3087,25 @@ static const struct address_space_operations ext4_da_aops = { | |||
3086 | 3087 | ||
3087 | void ext4_set_aops(struct inode *inode) | 3088 | void ext4_set_aops(struct inode *inode) |
3088 | { | 3089 | { |
3089 | if (ext4_should_order_data(inode) && | 3090 | switch (ext4_inode_journal_mode(inode)) { |
3090 | test_opt(inode->i_sb, DELALLOC)) | 3091 | case EXT4_INODE_ORDERED_DATA_MODE: |
3091 | inode->i_mapping->a_ops = &ext4_da_aops; | 3092 | if (test_opt(inode->i_sb, DELALLOC)) |
3092 | else if (ext4_should_order_data(inode)) | 3093 | inode->i_mapping->a_ops = &ext4_da_aops; |
3093 | inode->i_mapping->a_ops = &ext4_ordered_aops; | 3094 | else |
3094 | else if (ext4_should_writeback_data(inode) && | 3095 | inode->i_mapping->a_ops = &ext4_ordered_aops; |
3095 | test_opt(inode->i_sb, DELALLOC)) | 3096 | break; |
3096 | inode->i_mapping->a_ops = &ext4_da_aops; | 3097 | case EXT4_INODE_WRITEBACK_DATA_MODE: |
3097 | else if (ext4_should_writeback_data(inode)) | 3098 | if (test_opt(inode->i_sb, DELALLOC)) |
3098 | inode->i_mapping->a_ops = &ext4_writeback_aops; | 3099 | inode->i_mapping->a_ops = &ext4_da_aops; |
3099 | else | 3100 | else |
3101 | inode->i_mapping->a_ops = &ext4_writeback_aops; | ||
3102 | break; | ||
3103 | case EXT4_INODE_JOURNAL_DATA_MODE: | ||
3100 | inode->i_mapping->a_ops = &ext4_journalled_aops; | 3104 | inode->i_mapping->a_ops = &ext4_journalled_aops; |
3105 | break; | ||
3106 | default: | ||
3107 | BUG(); | ||
3108 | } | ||
3101 | } | 3109 | } |
3102 | 3110 | ||
3103 | 3111 | ||