Linux Audio

Check our new training course

Loading...
v3.5.6
  1/*
  2 * Interface between ext4 and JBD
  3 */
  4
  5#include "ext4_jbd2.h"
  6
  7#include <trace/events/ext4.h>
  8
  9int __ext4_journal_get_write_access(const char *where, unsigned int line,
 10				    handle_t *handle, struct buffer_head *bh)
 11{
 12	int err = 0;
 13
 14	if (ext4_handle_valid(handle)) {
 15		err = jbd2_journal_get_write_access(handle, bh);
 16		if (err)
 17			ext4_journal_abort_handle(where, line, __func__, bh,
 18						  handle, err);
 19	}
 20	return err;
 21}
 22
 23/*
 24 * The ext4 forget function must perform a revoke if we are freeing data
 25 * which has been journaled.  Metadata (eg. indirect blocks) must be
 26 * revoked in all cases.
 27 *
 28 * "bh" may be NULL: a metadata block may have been freed from memory
 29 * but there may still be a record of it in the journal, and that record
 30 * still needs to be revoked.
 31 *
 32 * If the handle isn't valid we're not journaling, but we still need to
 33 * call into ext4_journal_revoke() to put the buffer head.
 34 */
 35int __ext4_forget(const char *where, unsigned int line, handle_t *handle,
 36		  int is_metadata, struct inode *inode,
 37		  struct buffer_head *bh, ext4_fsblk_t blocknr)
 38{
 39	int err;
 40
 41	might_sleep();
 42
 43	trace_ext4_forget(inode, is_metadata, blocknr);
 44	BUFFER_TRACE(bh, "enter");
 45
 46	jbd_debug(4, "forgetting bh %p: is_metadata = %d, mode %o, "
 47		  "data mode %x\n",
 48		  bh, is_metadata, inode->i_mode,
 49		  test_opt(inode->i_sb, DATA_FLAGS));
 50
 51	/* In the no journal case, we can just do a bforget and return */
 52	if (!ext4_handle_valid(handle)) {
 53		bforget(bh);
 54		return 0;
 55	}
 56
 57	/* Never use the revoke function if we are doing full data
 58	 * journaling: there is no need to, and a V1 superblock won't
 59	 * support it.  Otherwise, only skip the revoke on un-journaled
 60	 * data blocks. */
 61
 62	if (test_opt(inode->i_sb, DATA_FLAGS) == EXT4_MOUNT_JOURNAL_DATA ||
 63	    (!is_metadata && !ext4_should_journal_data(inode))) {
 64		if (bh) {
 65			BUFFER_TRACE(bh, "call jbd2_journal_forget");
 66			err = jbd2_journal_forget(handle, bh);
 67			if (err)
 68				ext4_journal_abort_handle(where, line, __func__,
 69							  bh, handle, err);
 70			return err;
 71		}
 72		return 0;
 73	}
 74
 75	/*
 76	 * data!=journal && (is_metadata || should_journal_data(inode))
 77	 */
 78	BUFFER_TRACE(bh, "call jbd2_journal_revoke");
 79	err = jbd2_journal_revoke(handle, blocknr, bh);
 80	if (err) {
 81		ext4_journal_abort_handle(where, line, __func__,
 82					  bh, handle, err);
 83		__ext4_abort(inode->i_sb, where, line,
 84			   "error %d when attempting revoke", err);
 85	}
 86	BUFFER_TRACE(bh, "exit");
 87	return err;
 88}
 89
 90int __ext4_journal_get_create_access(const char *where, unsigned int line,
 91				handle_t *handle, struct buffer_head *bh)
 92{
 93	int err = 0;
 94
 95	if (ext4_handle_valid(handle)) {
 96		err = jbd2_journal_get_create_access(handle, bh);
 97		if (err)
 98			ext4_journal_abort_handle(where, line, __func__,
 99						  bh, handle, err);
100	}
101	return err;
102}
103
104int __ext4_handle_dirty_metadata(const char *where, unsigned int line,
105				 handle_t *handle, struct inode *inode,
106				 struct buffer_head *bh)
107{
108	int err = 0;
109
110	if (ext4_handle_valid(handle)) {
111		err = jbd2_journal_dirty_metadata(handle, bh);
112		if (err) {
113			/* Errors can only happen if there is a bug */
114			handle->h_err = err;
115			__ext4_journal_stop(where, line, handle);
116		}
117	} else {
118		if (inode)
119			mark_buffer_dirty_inode(bh, inode);
120		else
121			mark_buffer_dirty(bh);
122		if (inode && inode_needs_sync(inode)) {
123			sync_dirty_buffer(bh);
124			if (buffer_req(bh) && !buffer_uptodate(bh)) {
125				struct ext4_super_block *es;
126
127				es = EXT4_SB(inode->i_sb)->s_es;
128				es->s_last_error_block =
129					cpu_to_le64(bh->b_blocknr);
130				ext4_error_inode(inode, where, line,
131						 bh->b_blocknr,
132					"IO error syncing itable block");
133				err = -EIO;
134			}
135		}
136	}
137	return err;
138}
139
140int __ext4_handle_dirty_super(const char *where, unsigned int line,
141			      handle_t *handle, struct super_block *sb,
142			      int now)
143{
144	struct buffer_head *bh = EXT4_SB(sb)->s_sbh;
145	int err = 0;
146
147	if (ext4_handle_valid(handle)) {
148		ext4_superblock_csum_set(sb,
149				(struct ext4_super_block *)bh->b_data);
150		err = jbd2_journal_dirty_metadata(handle, bh);
151		if (err)
152			ext4_journal_abort_handle(where, line, __func__,
153						  bh, handle, err);
154	} else if (now) {
155		ext4_superblock_csum_set(sb,
156				(struct ext4_super_block *)bh->b_data);
157		mark_buffer_dirty(bh);
158	} else
159		sb->s_dirt = 1;
160	return err;
161}
v3.1
  1/*
  2 * Interface between ext4 and JBD
  3 */
  4
  5#include "ext4_jbd2.h"
  6
  7#include <trace/events/ext4.h>
  8
  9int __ext4_journal_get_write_access(const char *where, unsigned int line,
 10				    handle_t *handle, struct buffer_head *bh)
 11{
 12	int err = 0;
 13
 14	if (ext4_handle_valid(handle)) {
 15		err = jbd2_journal_get_write_access(handle, bh);
 16		if (err)
 17			ext4_journal_abort_handle(where, line, __func__, bh,
 18						  handle, err);
 19	}
 20	return err;
 21}
 22
 23/*
 24 * The ext4 forget function must perform a revoke if we are freeing data
 25 * which has been journaled.  Metadata (eg. indirect blocks) must be
 26 * revoked in all cases.
 27 *
 28 * "bh" may be NULL: a metadata block may have been freed from memory
 29 * but there may still be a record of it in the journal, and that record
 30 * still needs to be revoked.
 31 *
 32 * If the handle isn't valid we're not journaling, but we still need to
 33 * call into ext4_journal_revoke() to put the buffer head.
 34 */
 35int __ext4_forget(const char *where, unsigned int line, handle_t *handle,
 36		  int is_metadata, struct inode *inode,
 37		  struct buffer_head *bh, ext4_fsblk_t blocknr)
 38{
 39	int err;
 40
 41	might_sleep();
 42
 43	trace_ext4_forget(inode, is_metadata, blocknr);
 44	BUFFER_TRACE(bh, "enter");
 45
 46	jbd_debug(4, "forgetting bh %p: is_metadata = %d, mode %o, "
 47		  "data mode %x\n",
 48		  bh, is_metadata, inode->i_mode,
 49		  test_opt(inode->i_sb, DATA_FLAGS));
 50
 51	/* In the no journal case, we can just do a bforget and return */
 52	if (!ext4_handle_valid(handle)) {
 53		bforget(bh);
 54		return 0;
 55	}
 56
 57	/* Never use the revoke function if we are doing full data
 58	 * journaling: there is no need to, and a V1 superblock won't
 59	 * support it.  Otherwise, only skip the revoke on un-journaled
 60	 * data blocks. */
 61
 62	if (test_opt(inode->i_sb, DATA_FLAGS) == EXT4_MOUNT_JOURNAL_DATA ||
 63	    (!is_metadata && !ext4_should_journal_data(inode))) {
 64		if (bh) {
 65			BUFFER_TRACE(bh, "call jbd2_journal_forget");
 66			err = jbd2_journal_forget(handle, bh);
 67			if (err)
 68				ext4_journal_abort_handle(where, line, __func__,
 69							  bh, handle, err);
 70			return err;
 71		}
 72		return 0;
 73	}
 74
 75	/*
 76	 * data!=journal && (is_metadata || should_journal_data(inode))
 77	 */
 78	BUFFER_TRACE(bh, "call jbd2_journal_revoke");
 79	err = jbd2_journal_revoke(handle, blocknr, bh);
 80	if (err) {
 81		ext4_journal_abort_handle(where, line, __func__,
 82					  bh, handle, err);
 83		__ext4_abort(inode->i_sb, where, line,
 84			   "error %d when attempting revoke", err);
 85	}
 86	BUFFER_TRACE(bh, "exit");
 87	return err;
 88}
 89
 90int __ext4_journal_get_create_access(const char *where, unsigned int line,
 91				handle_t *handle, struct buffer_head *bh)
 92{
 93	int err = 0;
 94
 95	if (ext4_handle_valid(handle)) {
 96		err = jbd2_journal_get_create_access(handle, bh);
 97		if (err)
 98			ext4_journal_abort_handle(where, line, __func__,
 99						  bh, handle, err);
100	}
101	return err;
102}
103
104int __ext4_handle_dirty_metadata(const char *where, unsigned int line,
105				 handle_t *handle, struct inode *inode,
106				 struct buffer_head *bh)
107{
108	int err = 0;
109
110	if (ext4_handle_valid(handle)) {
111		err = jbd2_journal_dirty_metadata(handle, bh);
112		if (err)
113			ext4_journal_abort_handle(where, line, __func__,
114						  bh, handle, err);
 
 
115	} else {
116		if (inode)
117			mark_buffer_dirty_inode(bh, inode);
118		else
119			mark_buffer_dirty(bh);
120		if (inode && inode_needs_sync(inode)) {
121			sync_dirty_buffer(bh);
122			if (buffer_req(bh) && !buffer_uptodate(bh)) {
123				struct ext4_super_block *es;
124
125				es = EXT4_SB(inode->i_sb)->s_es;
126				es->s_last_error_block =
127					cpu_to_le64(bh->b_blocknr);
128				ext4_error_inode(inode, where, line,
129						 bh->b_blocknr,
130					"IO error syncing itable block");
131				err = -EIO;
132			}
133		}
134	}
135	return err;
136}
137
138int __ext4_handle_dirty_super(const char *where, unsigned int line,
139			      handle_t *handle, struct super_block *sb)
 
140{
141	struct buffer_head *bh = EXT4_SB(sb)->s_sbh;
142	int err = 0;
143
144	if (ext4_handle_valid(handle)) {
 
 
145		err = jbd2_journal_dirty_metadata(handle, bh);
146		if (err)
147			ext4_journal_abort_handle(where, line, __func__,
148						  bh, handle, err);
 
 
 
 
149	} else
150		sb->s_dirt = 1;
151	return err;
152}