diff options
author | Jan Kara <jack@suse.cz> | 2013-06-04 12:37:50 -0400 |
---|---|---|
committer | Theodore Ts'o <tytso@mit.edu> | 2013-06-04 12:37:50 -0400 |
commit | 5fe2fe895a9a6b857e2f3a7fc5b8f080b03fd55f (patch) | |
tree | 4413bc3674762e6f8accef300c5ea07f76911336 /fs/ext4 | |
parent | 8f7d89f36829b9061a14f9040cda1372f264c4fe (diff) |
ext4: provide wrappers for transaction reservation calls
Reviewed-by: Zheng Liu <wenqing.lz@taobao.com>
Signed-off-by: Jan Kara <jack@suse.cz>
Signed-off-by: "Theodore Ts'o" <tytso@mit.edu>
Diffstat (limited to 'fs/ext4')
-rw-r--r-- | fs/ext4/ext4_jbd2.c | 58 | ||||
-rw-r--r-- | fs/ext4/ext4_jbd2.h | 26 | ||||
-rw-r--r-- | fs/ext4/ialloc.c | 3 |
3 files changed, 70 insertions, 17 deletions
diff --git a/fs/ext4/ext4_jbd2.c b/fs/ext4/ext4_jbd2.c index bd25e782ec6b..72a3600aedbd 100644 --- a/fs/ext4/ext4_jbd2.c +++ b/fs/ext4/ext4_jbd2.c | |||
@@ -38,31 +38,43 @@ static void ext4_put_nojournal(handle_t *handle) | |||
38 | /* | 38 | /* |
39 | * Wrappers for jbd2_journal_start/end. | 39 | * Wrappers for jbd2_journal_start/end. |
40 | */ | 40 | */ |
41 | handle_t *__ext4_journal_start_sb(struct super_block *sb, unsigned int line, | 41 | static int ext4_journal_check_start(struct super_block *sb) |
42 | int type, int nblocks) | ||
43 | { | 42 | { |
44 | journal_t *journal; | 43 | journal_t *journal; |
45 | 44 | ||
46 | might_sleep(); | 45 | might_sleep(); |
47 | |||
48 | trace_ext4_journal_start(sb, nblocks, _RET_IP_); | ||
49 | if (sb->s_flags & MS_RDONLY) | 46 | if (sb->s_flags & MS_RDONLY) |
50 | return ERR_PTR(-EROFS); | 47 | return -EROFS; |
51 | |||
52 | WARN_ON(sb->s_writers.frozen == SB_FREEZE_COMPLETE); | 48 | WARN_ON(sb->s_writers.frozen == SB_FREEZE_COMPLETE); |
53 | journal = EXT4_SB(sb)->s_journal; | 49 | journal = EXT4_SB(sb)->s_journal; |
54 | if (!journal) | ||
55 | return ext4_get_nojournal(); | ||
56 | /* | 50 | /* |
57 | * Special case here: if the journal has aborted behind our | 51 | * Special case here: if the journal has aborted behind our |
58 | * backs (eg. EIO in the commit thread), then we still need to | 52 | * backs (eg. EIO in the commit thread), then we still need to |
59 | * take the FS itself readonly cleanly. | 53 | * take the FS itself readonly cleanly. |
60 | */ | 54 | */ |
61 | if (is_journal_aborted(journal)) { | 55 | if (journal && is_journal_aborted(journal)) { |
62 | ext4_abort(sb, "Detected aborted journal"); | 56 | ext4_abort(sb, "Detected aborted journal"); |
63 | return ERR_PTR(-EROFS); | 57 | return -EROFS; |
64 | } | 58 | } |
65 | return jbd2__journal_start(journal, nblocks, 0, GFP_NOFS, type, line); | 59 | return 0; |
60 | } | ||
61 | |||
62 | handle_t *__ext4_journal_start_sb(struct super_block *sb, unsigned int line, | ||
63 | int type, int blocks, int rsv_blocks) | ||
64 | { | ||
65 | journal_t *journal; | ||
66 | int err; | ||
67 | |||
68 | trace_ext4_journal_start(sb, blocks, rsv_blocks, _RET_IP_); | ||
69 | err = ext4_journal_check_start(sb); | ||
70 | if (err < 0) | ||
71 | return ERR_PTR(err); | ||
72 | |||
73 | journal = EXT4_SB(sb)->s_journal; | ||
74 | if (!journal) | ||
75 | return ext4_get_nojournal(); | ||
76 | return jbd2__journal_start(journal, blocks, rsv_blocks, GFP_NOFS, | ||
77 | type, line); | ||
66 | } | 78 | } |
67 | 79 | ||
68 | int __ext4_journal_stop(const char *where, unsigned int line, handle_t *handle) | 80 | int __ext4_journal_stop(const char *where, unsigned int line, handle_t *handle) |
@@ -86,6 +98,30 @@ int __ext4_journal_stop(const char *where, unsigned int line, handle_t *handle) | |||
86 | return err; | 98 | return err; |
87 | } | 99 | } |
88 | 100 | ||
101 | handle_t *__ext4_journal_start_reserved(handle_t *handle, unsigned int line, | ||
102 | int type) | ||
103 | { | ||
104 | struct super_block *sb; | ||
105 | int err; | ||
106 | |||
107 | if (!ext4_handle_valid(handle)) | ||
108 | return ext4_get_nojournal(); | ||
109 | |||
110 | sb = handle->h_journal->j_private; | ||
111 | trace_ext4_journal_start_reserved(sb, handle->h_buffer_credits, | ||
112 | _RET_IP_); | ||
113 | err = ext4_journal_check_start(sb); | ||
114 | if (err < 0) { | ||
115 | jbd2_journal_free_reserved(handle); | ||
116 | return ERR_PTR(err); | ||
117 | } | ||
118 | |||
119 | err = jbd2_journal_start_reserved(handle, type, line); | ||
120 | if (err < 0) | ||
121 | return ERR_PTR(err); | ||
122 | return handle; | ||
123 | } | ||
124 | |||
89 | void ext4_journal_abort_handle(const char *caller, unsigned int line, | 125 | void ext4_journal_abort_handle(const char *caller, unsigned int line, |
90 | const char *err_fn, struct buffer_head *bh, | 126 | const char *err_fn, struct buffer_head *bh, |
91 | handle_t *handle, int err) | 127 | handle_t *handle, int err) |
diff --git a/fs/ext4/ext4_jbd2.h b/fs/ext4/ext4_jbd2.h index c8c6885406db..fdd865eb1879 100644 --- a/fs/ext4/ext4_jbd2.h +++ b/fs/ext4/ext4_jbd2.h | |||
@@ -265,7 +265,7 @@ int __ext4_handle_dirty_super(const char *where, unsigned int line, | |||
265 | __ext4_handle_dirty_super(__func__, __LINE__, (handle), (sb)) | 265 | __ext4_handle_dirty_super(__func__, __LINE__, (handle), (sb)) |
266 | 266 | ||
267 | handle_t *__ext4_journal_start_sb(struct super_block *sb, unsigned int line, | 267 | handle_t *__ext4_journal_start_sb(struct super_block *sb, unsigned int line, |
268 | int type, int nblocks); | 268 | int type, int blocks, int rsv_blocks); |
269 | int __ext4_journal_stop(const char *where, unsigned int line, handle_t *handle); | 269 | int __ext4_journal_stop(const char *where, unsigned int line, handle_t *handle); |
270 | 270 | ||
271 | #define EXT4_NOJOURNAL_MAX_REF_COUNT ((unsigned long) 4096) | 271 | #define EXT4_NOJOURNAL_MAX_REF_COUNT ((unsigned long) 4096) |
@@ -300,21 +300,37 @@ static inline int ext4_handle_has_enough_credits(handle_t *handle, int needed) | |||
300 | } | 300 | } |
301 | 301 | ||
302 | #define ext4_journal_start_sb(sb, type, nblocks) \ | 302 | #define ext4_journal_start_sb(sb, type, nblocks) \ |
303 | __ext4_journal_start_sb((sb), __LINE__, (type), (nblocks)) | 303 | __ext4_journal_start_sb((sb), __LINE__, (type), (nblocks), 0) |
304 | 304 | ||
305 | #define ext4_journal_start(inode, type, nblocks) \ | 305 | #define ext4_journal_start(inode, type, nblocks) \ |
306 | __ext4_journal_start((inode), __LINE__, (type), (nblocks)) | 306 | __ext4_journal_start((inode), __LINE__, (type), (nblocks), 0) |
307 | |||
308 | #define ext4_journal_start_with_reserve(inode, type, blocks, rsv_blocks) \ | ||
309 | __ext4_journal_start((inode), __LINE__, (type), (blocks), (rsv_blocks)) | ||
307 | 310 | ||
308 | static inline handle_t *__ext4_journal_start(struct inode *inode, | 311 | static inline handle_t *__ext4_journal_start(struct inode *inode, |
309 | unsigned int line, int type, | 312 | unsigned int line, int type, |
310 | int nblocks) | 313 | int blocks, int rsv_blocks) |
311 | { | 314 | { |
312 | return __ext4_journal_start_sb(inode->i_sb, line, type, nblocks); | 315 | return __ext4_journal_start_sb(inode->i_sb, line, type, blocks, |
316 | rsv_blocks); | ||
313 | } | 317 | } |
314 | 318 | ||
315 | #define ext4_journal_stop(handle) \ | 319 | #define ext4_journal_stop(handle) \ |
316 | __ext4_journal_stop(__func__, __LINE__, (handle)) | 320 | __ext4_journal_stop(__func__, __LINE__, (handle)) |
317 | 321 | ||
322 | #define ext4_journal_start_reserve(handle, type) \ | ||
323 | __ext4_journal_start_reserved((handle), __LINE__, (type)) | ||
324 | |||
325 | handle_t *__ext4_journal_start_reserved(handle_t *handle, unsigned int line, | ||
326 | int type); | ||
327 | |||
328 | static inline void ext4_journal_free_reserved(handle_t *handle) | ||
329 | { | ||
330 | if (ext4_handle_valid(handle)) | ||
331 | jbd2_journal_free_reserved(handle); | ||
332 | } | ||
333 | |||
318 | static inline handle_t *ext4_journal_current_handle(void) | 334 | static inline handle_t *ext4_journal_current_handle(void) |
319 | { | 335 | { |
320 | return journal_current_handle(); | 336 | return journal_current_handle(); |
diff --git a/fs/ext4/ialloc.c b/fs/ext4/ialloc.c index 00a818d67b54..f03598c6ffd3 100644 --- a/fs/ext4/ialloc.c +++ b/fs/ext4/ialloc.c | |||
@@ -747,7 +747,8 @@ repeat_in_this_group: | |||
747 | if (!handle) { | 747 | if (!handle) { |
748 | BUG_ON(nblocks <= 0); | 748 | BUG_ON(nblocks <= 0); |
749 | handle = __ext4_journal_start_sb(dir->i_sb, line_no, | 749 | handle = __ext4_journal_start_sb(dir->i_sb, line_no, |
750 | handle_type, nblocks); | 750 | handle_type, nblocks, |
751 | 0); | ||
751 | if (IS_ERR(handle)) { | 752 | if (IS_ERR(handle)) { |
752 | err = PTR_ERR(handle); | 753 | err = PTR_ERR(handle); |
753 | ext4_std_error(sb, err); | 754 | ext4_std_error(sb, err); |