|
|
@@ -1356,6 +1356,10 @@ static int journal_reset(journal_t *journal)
|
|
|
return jbd2_journal_start_thread(journal);
|
|
|
}
|
|
|
|
|
|
+/*
|
|
|
+ * This function expects that the caller will have locked the journal
|
|
|
+ * buffer head, and will return with it unlocked
|
|
|
+ */
|
|
|
static int jbd2_write_superblock(journal_t *journal, int write_flags)
|
|
|
{
|
|
|
struct buffer_head *bh = journal->j_sb_buffer;
|
|
|
@@ -1365,7 +1369,6 @@ static int jbd2_write_superblock(journal_t *journal, int write_flags)
|
|
|
trace_jbd2_write_superblock(journal, write_flags);
|
|
|
if (!(journal->j_flags & JBD2_BARRIER))
|
|
|
write_flags &= ~(REQ_FUA | REQ_PREFLUSH);
|
|
|
- lock_buffer(bh);
|
|
|
if (buffer_write_io_error(bh)) {
|
|
|
/*
|
|
|
* Oh, dear. A previous attempt to write the journal
|
|
|
@@ -1424,6 +1427,7 @@ int jbd2_journal_update_sb_log_tail(journal_t *journal, tid_t tail_tid,
|
|
|
jbd_debug(1, "JBD2: updating superblock (start %lu, seq %u)\n",
|
|
|
tail_block, tail_tid);
|
|
|
|
|
|
+ lock_buffer(journal->j_sb_buffer);
|
|
|
sb->s_sequence = cpu_to_be32(tail_tid);
|
|
|
sb->s_start = cpu_to_be32(tail_block);
|
|
|
|
|
|
@@ -1454,18 +1458,17 @@ static void jbd2_mark_journal_empty(journal_t *journal, int write_op)
|
|
|
journal_superblock_t *sb = journal->j_superblock;
|
|
|
|
|
|
BUG_ON(!mutex_is_locked(&journal->j_checkpoint_mutex));
|
|
|
- read_lock(&journal->j_state_lock);
|
|
|
- /* Is it already empty? */
|
|
|
- if (sb->s_start == 0) {
|
|
|
- read_unlock(&journal->j_state_lock);
|
|
|
+ lock_buffer(journal->j_sb_buffer);
|
|
|
+ if (sb->s_start == 0) { /* Is it already empty? */
|
|
|
+ unlock_buffer(journal->j_sb_buffer);
|
|
|
return;
|
|
|
}
|
|
|
+
|
|
|
jbd_debug(1, "JBD2: Marking journal as empty (seq %d)\n",
|
|
|
journal->j_tail_sequence);
|
|
|
|
|
|
sb->s_sequence = cpu_to_be32(journal->j_tail_sequence);
|
|
|
sb->s_start = cpu_to_be32(0);
|
|
|
- read_unlock(&journal->j_state_lock);
|
|
|
|
|
|
jbd2_write_superblock(journal, write_op);
|
|
|
|
|
|
@@ -1488,9 +1491,8 @@ void jbd2_journal_update_sb_errno(journal_t *journal)
|
|
|
journal_superblock_t *sb = journal->j_superblock;
|
|
|
int errcode;
|
|
|
|
|
|
- read_lock(&journal->j_state_lock);
|
|
|
+ lock_buffer(journal->j_sb_buffer);
|
|
|
errcode = journal->j_errno;
|
|
|
- read_unlock(&journal->j_state_lock);
|
|
|
if (errcode == -ESHUTDOWN)
|
|
|
errcode = 0;
|
|
|
jbd_debug(1, "JBD2: updating superblock error (errno %d)\n", errcode);
|
|
|
@@ -1894,28 +1896,27 @@ int jbd2_journal_set_features (journal_t *journal, unsigned long compat,
|
|
|
|
|
|
sb = journal->j_superblock;
|
|
|
|
|
|
+ /* Load the checksum driver if necessary */
|
|
|
+ if ((journal->j_chksum_driver == NULL) &&
|
|
|
+ INCOMPAT_FEATURE_ON(JBD2_FEATURE_INCOMPAT_CSUM_V3)) {
|
|
|
+ journal->j_chksum_driver = crypto_alloc_shash("crc32c", 0, 0);
|
|
|
+ if (IS_ERR(journal->j_chksum_driver)) {
|
|
|
+ printk(KERN_ERR "JBD2: Cannot load crc32c driver.\n");
|
|
|
+ journal->j_chksum_driver = NULL;
|
|
|
+ return 0;
|
|
|
+ }
|
|
|
+ /* Precompute checksum seed for all metadata */
|
|
|
+ journal->j_csum_seed = jbd2_chksum(journal, ~0, sb->s_uuid,
|
|
|
+ sizeof(sb->s_uuid));
|
|
|
+ }
|
|
|
+
|
|
|
+ lock_buffer(journal->j_sb_buffer);
|
|
|
+
|
|
|
/* If enabling v3 checksums, update superblock */
|
|
|
if (INCOMPAT_FEATURE_ON(JBD2_FEATURE_INCOMPAT_CSUM_V3)) {
|
|
|
sb->s_checksum_type = JBD2_CRC32C_CHKSUM;
|
|
|
sb->s_feature_compat &=
|
|
|
~cpu_to_be32(JBD2_FEATURE_COMPAT_CHECKSUM);
|
|
|
-
|
|
|
- /* Load the checksum driver */
|
|
|
- if (journal->j_chksum_driver == NULL) {
|
|
|
- journal->j_chksum_driver = crypto_alloc_shash("crc32c",
|
|
|
- 0, 0);
|
|
|
- if (IS_ERR(journal->j_chksum_driver)) {
|
|
|
- printk(KERN_ERR "JBD2: Cannot load crc32c "
|
|
|
- "driver.\n");
|
|
|
- journal->j_chksum_driver = NULL;
|
|
|
- return 0;
|
|
|
- }
|
|
|
-
|
|
|
- /* Precompute checksum seed for all metadata */
|
|
|
- journal->j_csum_seed = jbd2_chksum(journal, ~0,
|
|
|
- sb->s_uuid,
|
|
|
- sizeof(sb->s_uuid));
|
|
|
- }
|
|
|
}
|
|
|
|
|
|
/* If enabling v1 checksums, downgrade superblock */
|
|
|
@@ -1927,6 +1928,7 @@ int jbd2_journal_set_features (journal_t *journal, unsigned long compat,
|
|
|
sb->s_feature_compat |= cpu_to_be32(compat);
|
|
|
sb->s_feature_ro_compat |= cpu_to_be32(ro);
|
|
|
sb->s_feature_incompat |= cpu_to_be32(incompat);
|
|
|
+ unlock_buffer(journal->j_sb_buffer);
|
|
|
|
|
|
return 1;
|
|
|
#undef COMPAT_FEATURE_ON
|