Blame view

fs/ext4/ext4_jbd2.c 3.95 KB
8984d137d   Andrew Morton   [PATCH] ext4: uni...
1
2
3
  /*
   * Interface between ext4 and JBD
   */
3dcf54515   Christoph Hellwig   ext4: move header...
4
  #include "ext4_jbd2.h"
8984d137d   Andrew Morton   [PATCH] ext4: uni...
5

d6797d14b   Theodore Ts'o   ext4: move ext4_f...
6
  #include <trace/events/ext4.h>
90c7201b9   Theodore Ts'o   ext4: Pass line n...
7
8
  int __ext4_journal_get_write_access(const char *where, unsigned int line,
  				    handle_t *handle, struct buffer_head *bh)
8984d137d   Andrew Morton   [PATCH] ext4: uni...
9
  {
0390131ba   Frank Mayhar   ext4: Allow ext4 ...
10
11
12
13
14
  	int err = 0;
  
  	if (ext4_handle_valid(handle)) {
  		err = jbd2_journal_get_write_access(handle, bh);
  		if (err)
90c7201b9   Theodore Ts'o   ext4: Pass line n...
15
  			ext4_journal_abort_handle(where, line, __func__, bh,
0390131ba   Frank Mayhar   ext4: Allow ext4 ...
16
17
  						  handle, err);
  	}
8984d137d   Andrew Morton   [PATCH] ext4: uni...
18
19
  	return err;
  }
d6797d14b   Theodore Ts'o   ext4: move ext4_f...
20
21
22
23
24
25
26
27
28
29
30
31
  /*
   * The ext4 forget function must perform a revoke if we are freeing data
   * which has been journaled.  Metadata (eg. indirect blocks) must be
   * revoked in all cases.
   *
   * "bh" may be NULL: a metadata block may have been freed from memory
   * but there may still be a record of it in the journal, and that record
   * still needs to be revoked.
   *
   * If the handle isn't valid we're not journaling, but we still need to
   * call into ext4_journal_revoke() to put the buffer head.
   */
90c7201b9   Theodore Ts'o   ext4: Pass line n...
32
33
34
  int __ext4_forget(const char *where, unsigned int line, handle_t *handle,
  		  int is_metadata, struct inode *inode,
  		  struct buffer_head *bh, ext4_fsblk_t blocknr)
d6797d14b   Theodore Ts'o   ext4: move ext4_f...
35
36
37
38
39
40
41
42
43
44
45
46
47
  {
  	int err;
  
  	might_sleep();
  
  	trace_ext4_forget(inode, is_metadata, blocknr);
  	BUFFER_TRACE(bh, "enter");
  
  	jbd_debug(4, "forgetting bh %p: is_metadata = %d, mode %o, "
  		  "data mode %x
  ",
  		  bh, is_metadata, inode->i_mode,
  		  test_opt(inode->i_sb, DATA_FLAGS));
e4684b3fb   Theodore Ts'o   ext4: fold ext4_j...
48
49
50
51
52
  	/* In the no journal case, we can just do a bforget and return */
  	if (!ext4_handle_valid(handle)) {
  		bforget(bh);
  		return 0;
  	}
d6797d14b   Theodore Ts'o   ext4: move ext4_f...
53
54
55
56
57
58
59
60
61
  	/* Never use the revoke function if we are doing full data
  	 * journaling: there is no need to, and a V1 superblock won't
  	 * support it.  Otherwise, only skip the revoke on un-journaled
  	 * data blocks. */
  
  	if (test_opt(inode->i_sb, DATA_FLAGS) == EXT4_MOUNT_JOURNAL_DATA ||
  	    (!is_metadata && !ext4_should_journal_data(inode))) {
  		if (bh) {
  			BUFFER_TRACE(bh, "call jbd2_journal_forget");
b7e57e7c2   Theodore Ts'o   ext4: fold ext4_j...
62
63
  			err = jbd2_journal_forget(handle, bh);
  			if (err)
90c7201b9   Theodore Ts'o   ext4: Pass line n...
64
65
  				ext4_journal_abort_handle(where, line, __func__,
  							  bh, handle, err);
b7e57e7c2   Theodore Ts'o   ext4: fold ext4_j...
66
  			return err;
d6797d14b   Theodore Ts'o   ext4: move ext4_f...
67
68
69
70
71
72
73
  		}
  		return 0;
  	}
  
  	/*
  	 * data!=journal && (is_metadata || should_journal_data(inode))
  	 */
e4684b3fb   Theodore Ts'o   ext4: fold ext4_j...
74
75
76
  	BUFFER_TRACE(bh, "call jbd2_journal_revoke");
  	err = jbd2_journal_revoke(handle, blocknr, bh);
  	if (err) {
90c7201b9   Theodore Ts'o   ext4: Pass line n...
77
78
  		ext4_journal_abort_handle(where, line, __func__,
  					  bh, handle, err);
c398eda0e   Theodore Ts'o   ext4: Pass line n...
79
80
  		__ext4_abort(inode->i_sb, where, line,
  			   "error %d when attempting revoke", err);
e4684b3fb   Theodore Ts'o   ext4: fold ext4_j...
81
  	}
d6797d14b   Theodore Ts'o   ext4: move ext4_f...
82
83
84
  	BUFFER_TRACE(bh, "exit");
  	return err;
  }
90c7201b9   Theodore Ts'o   ext4: Pass line n...
85
  int __ext4_journal_get_create_access(const char *where, unsigned int line,
8984d137d   Andrew Morton   [PATCH] ext4: uni...
86
87
  				handle_t *handle, struct buffer_head *bh)
  {
0390131ba   Frank Mayhar   ext4: Allow ext4 ...
88
89
90
91
92
  	int err = 0;
  
  	if (ext4_handle_valid(handle)) {
  		err = jbd2_journal_get_create_access(handle, bh);
  		if (err)
90c7201b9   Theodore Ts'o   ext4: Pass line n...
93
94
  			ext4_journal_abort_handle(where, line, __func__,
  						  bh, handle, err);
0390131ba   Frank Mayhar   ext4: Allow ext4 ...
95
  	}
8984d137d   Andrew Morton   [PATCH] ext4: uni...
96
97
  	return err;
  }
90c7201b9   Theodore Ts'o   ext4: Pass line n...
98
99
100
  int __ext4_handle_dirty_metadata(const char *where, unsigned int line,
  				 handle_t *handle, struct inode *inode,
  				 struct buffer_head *bh)
8984d137d   Andrew Morton   [PATCH] ext4: uni...
101
  {
0390131ba   Frank Mayhar   ext4: Allow ext4 ...
102
103
104
105
  	int err = 0;
  
  	if (ext4_handle_valid(handle)) {
  		err = jbd2_journal_dirty_metadata(handle, bh);
9ea7a0df6   Theodore Ts'o   jbd2: add debuggi...
106
107
108
109
110
  		if (err) {
  			/* Errors can only happen if there is a bug */
  			handle->h_err = err;
  			__ext4_journal_stop(where, line, handle);
  		}
0390131ba   Frank Mayhar   ext4: Allow ext4 ...
111
  	} else {
73b50c1c9   Curt Wohlgemuth   ext4: Fix BUG_ON ...
112
  		if (inode)
fe188c0e0   Theodore Ts'o   ext4: Assure that...
113
114
115
  			mark_buffer_dirty_inode(bh, inode);
  		else
  			mark_buffer_dirty(bh);
0390131ba   Frank Mayhar   ext4: Allow ext4 ...
116
117
118
  		if (inode && inode_needs_sync(inode)) {
  			sync_dirty_buffer(bh);
  			if (buffer_req(bh) && !buffer_uptodate(bh)) {
1c13d5c08   Theodore Ts'o   ext4: Save error ...
119
120
121
122
123
  				struct ext4_super_block *es;
  
  				es = EXT4_SB(inode->i_sb)->s_es;
  				es->s_last_error_block =
  					cpu_to_le64(bh->b_blocknr);
c398eda0e   Theodore Ts'o   ext4: Pass line n...
124
125
126
  				ext4_error_inode(inode, where, line,
  						 bh->b_blocknr,
  					"IO error syncing itable block");
0390131ba   Frank Mayhar   ext4: Allow ext4 ...
127
128
129
130
  				err = -EIO;
  			}
  		}
  	}
8984d137d   Andrew Morton   [PATCH] ext4: uni...
131
132
  	return err;
  }
a0375156c   Theodore Ts'o   ext4: Clean up s_...
133

90c7201b9   Theodore Ts'o   ext4: Pass line n...
134
135
  int __ext4_handle_dirty_super(const char *where, unsigned int line,
  			      handle_t *handle, struct super_block *sb)
a0375156c   Theodore Ts'o   ext4: Clean up s_...
136
137
138
139
140
141
142
  {
  	struct buffer_head *bh = EXT4_SB(sb)->s_sbh;
  	int err = 0;
  
  	if (ext4_handle_valid(handle)) {
  		err = jbd2_journal_dirty_metadata(handle, bh);
  		if (err)
90c7201b9   Theodore Ts'o   ext4: Pass line n...
143
144
  			ext4_journal_abort_handle(where, line, __func__,
  						  bh, handle, err);
a0375156c   Theodore Ts'o   ext4: Clean up s_...
145
146
147
148
  	} else
  		sb->s_dirt = 1;
  	return err;
  }