summaryrefslogtreecommitdiffstats
path: root/include
diff options
context:
space:
mode:
Diffstat (limited to 'include')
-rw-r--r--include/linux/buffer_head.h3
-rw-r--r--include/linux/fs.h2
-rw-r--r--include/linux/jbd.h28
-rw-r--r--include/linux/jbd2.h175
-rw-r--r--include/linux/jbd_common.h26
-rw-r--r--include/linux/mm.h3
-rw-r--r--include/trace/events/ext3.h12
-rw-r--r--include/trace/events/ext4.h304
8 files changed, 364 insertions, 189 deletions
diff --git a/include/linux/buffer_head.h b/include/linux/buffer_head.h
index 9e52b0626b39..f5a3b838ddb0 100644
--- a/include/linux/buffer_head.h
+++ b/include/linux/buffer_head.h
@@ -198,7 +198,8 @@ extern int buffer_heads_over_limit;
* Generic address_space_operations implementations for buffer_head-backed
* address_spaces.
*/
-void block_invalidatepage(struct page *page, unsigned long offset);
+void block_invalidatepage(struct page *page, unsigned int offset,
+ unsigned int length);
int block_write_full_page(struct page *page, get_block_t *get_block,
struct writeback_control *wbc);
int block_write_full_page_endio(struct page *page, get_block_t *get_block,
diff --git a/include/linux/fs.h b/include/linux/fs.h
index 7c30e3a62baf..f8a5240541b7 100644
--- a/include/linux/fs.h
+++ b/include/linux/fs.h
@@ -364,7 +364,7 @@ struct address_space_operations {
/* Unfortunately this kludge is needed for FIBMAP. Don't use it */
sector_t (*bmap)(struct address_space *, sector_t);
- void (*invalidatepage) (struct page *, unsigned long);
+ void (*invalidatepage) (struct page *, unsigned int, unsigned int);
int (*releasepage) (struct page *, gfp_t);
void (*freepage)(struct page *);
ssize_t (*direct_IO)(int, struct kiocb *, const struct iovec *iov,
diff --git a/include/linux/jbd.h b/include/linux/jbd.h
index 7e0b622503c4..8685d1be12c7 100644
--- a/include/linux/jbd.h
+++ b/include/linux/jbd.h
@@ -27,7 +27,6 @@
#include <linux/buffer_head.h>
#include <linux/journal-head.h>
#include <linux/stddef.h>
-#include <linux/bit_spinlock.h>
#include <linux/mutex.h>
#include <linux/timer.h>
#include <linux/lockdep.h>
@@ -244,6 +243,31 @@ typedef struct journal_superblock_s
#include <linux/fs.h>
#include <linux/sched.h>
+
+enum jbd_state_bits {
+ BH_JBD /* Has an attached ext3 journal_head */
+ = BH_PrivateStart,
+ BH_JWrite, /* Being written to log (@@@ DEBUGGING) */
+ BH_Freed, /* Has been freed (truncated) */
+ BH_Revoked, /* Has been revoked from the log */
+ BH_RevokeValid, /* Revoked flag is valid */
+ BH_JBDDirty, /* Is dirty but journaled */
+ BH_State, /* Pins most journal_head state */
+ BH_JournalHead, /* Pins bh->b_private and jh->b_bh */
+ BH_Unshadow, /* Dummy bit, for BJ_Shadow wakeup filtering */
+ BH_JBDPrivateStart, /* First bit available for private use by FS */
+};
+
+BUFFER_FNS(JBD, jbd)
+BUFFER_FNS(JWrite, jwrite)
+BUFFER_FNS(JBDDirty, jbddirty)
+TAS_BUFFER_FNS(JBDDirty, jbddirty)
+BUFFER_FNS(Revoked, revoked)
+TAS_BUFFER_FNS(Revoked, revoked)
+BUFFER_FNS(RevokeValid, revokevalid)
+TAS_BUFFER_FNS(RevokeValid, revokevalid)
+BUFFER_FNS(Freed, freed)
+
#include <linux/jbd_common.h>
#define J_ASSERT(assert) BUG_ON(!(assert))
@@ -840,7 +864,7 @@ extern void journal_release_buffer (handle_t *, struct buffer_head *);
extern int journal_forget (handle_t *, struct buffer_head *);
extern void journal_sync_buffer (struct buffer_head *);
extern void journal_invalidatepage(journal_t *,
- struct page *, unsigned long);
+ struct page *, unsigned int, unsigned int);
extern int journal_try_to_free_buffers(journal_t *, struct page *, gfp_t);
extern int journal_stop(handle_t *);
extern int journal_flush (journal_t *);
diff --git a/include/linux/jbd2.h b/include/linux/jbd2.h
index 6e051f472edb..d5b50a19463c 100644
--- a/include/linux/jbd2.h
+++ b/include/linux/jbd2.h
@@ -26,7 +26,6 @@
#include <linux/buffer_head.h>
#include <linux/journal-head.h>
#include <linux/stddef.h>
-#include <linux/bit_spinlock.h>
#include <linux/mutex.h>
#include <linux/timer.h>
#include <linux/slab.h>
@@ -57,17 +56,13 @@
*/
#define JBD2_EXPENSIVE_CHECKING
extern ushort jbd2_journal_enable_debug;
+void __jbd2_debug(int level, const char *file, const char *func,
+ unsigned int line, const char *fmt, ...);
-#define jbd_debug(n, f, a...) \
- do { \
- if ((n) <= jbd2_journal_enable_debug) { \
- printk (KERN_DEBUG "(%s, %d): %s: ", \
- __FILE__, __LINE__, __func__); \
- printk (f, ## a); \
- } \
- } while (0)
+#define jbd_debug(n, fmt, a...) \
+ __jbd2_debug((n), __FILE__, __func__, __LINE__, (fmt), ##a)
#else
-#define jbd_debug(f, a...) /**/
+#define jbd_debug(n, fmt, a...) /**/
#endif
extern void *jbd2_alloc(size_t size, gfp_t flags);
@@ -302,6 +297,34 @@ typedef struct journal_superblock_s
#include <linux/fs.h>
#include <linux/sched.h>
+
+enum jbd_state_bits {
+ BH_JBD /* Has an attached ext3 journal_head */
+ = BH_PrivateStart,
+ BH_JWrite, /* Being written to log (@@@ DEBUGGING) */
+ BH_Freed, /* Has been freed (truncated) */
+ BH_Revoked, /* Has been revoked from the log */
+ BH_RevokeValid, /* Revoked flag is valid */
+ BH_JBDDirty, /* Is dirty but journaled */
+ BH_State, /* Pins most journal_head state */
+ BH_JournalHead, /* Pins bh->b_private and jh->b_bh */
+ BH_Shadow, /* IO on shadow buffer is running */
+ BH_Verified, /* Metadata block has been verified ok */
+ BH_JBDPrivateStart, /* First bit available for private use by FS */
+};
+
+BUFFER_FNS(JBD, jbd)
+BUFFER_FNS(JWrite, jwrite)
+BUFFER_FNS(JBDDirty, jbddirty)
+TAS_BUFFER_FNS(JBDDirty, jbddirty)
+BUFFER_FNS(Revoked, revoked)
+TAS_BUFFER_FNS(Revoked, revoked)
+BUFFER_FNS(RevokeValid, revokevalid)
+TAS_BUFFER_FNS(RevokeValid, revokevalid)
+BUFFER_FNS(Freed, freed)
+BUFFER_FNS(Shadow, shadow)
+BUFFER_FNS(Verified, verified)
+
#include <linux/jbd_common.h>
#define J_ASSERT(assert) BUG_ON(!(assert))
@@ -382,8 +405,15 @@ struct jbd2_revoke_table_s;
struct jbd2_journal_handle
{
- /* Which compound transaction is this update a part of? */
- transaction_t *h_transaction;
+ union {
+ /* Which compound transaction is this update a part of? */
+ transaction_t *h_transaction;
+ /* Which journal handle belongs to - used iff h_reserved set */
+ journal_t *h_journal;
+ };
+
+ /* Handle reserved for finishing the logical operation */
+ handle_t *h_rsv_handle;
/* Number of remaining buffers we are allowed to dirty: */
int h_buffer_credits;
@@ -398,6 +428,7 @@ struct jbd2_journal_handle
/* Flags [no locking] */
unsigned int h_sync: 1; /* sync-on-close */
unsigned int h_jdata: 1; /* force data journaling */
+ unsigned int h_reserved: 1; /* handle with reserved credits */
unsigned int h_aborted: 1; /* fatal error on handle */
unsigned int h_type: 8; /* for handle statistics */
unsigned int h_line_no: 16; /* for handle statistics */
@@ -524,12 +555,6 @@ struct transaction_s
struct journal_head *t_checkpoint_io_list;
/*
- * Doubly-linked circular list of temporary buffers currently undergoing
- * IO in the log [j_list_lock]
- */
- struct journal_head *t_iobuf_list;
-
- /*
* Doubly-linked circular list of metadata buffers being shadowed by log
* IO. The IO buffers on the iobuf list and the shadow buffers on this
* list match each other one for one at all times. [j_list_lock]
@@ -537,12 +562,6 @@ struct transaction_s
struct journal_head *t_shadow_list;
/*
- * Doubly-linked circular list of control buffers being written to the
- * log. [j_list_lock]
- */
- struct journal_head *t_log_list;
-
- /*
* List of inodes whose data we've modified in data=ordered mode.
* [j_list_lock]
*/
@@ -671,11 +690,10 @@ jbd2_time_diff(unsigned long start, unsigned long end)
* waiting for checkpointing
* @j_wait_transaction_locked: Wait queue for waiting for a locked transaction
* to start committing, or for a barrier lock to be released
- * @j_wait_logspace: Wait queue for waiting for checkpointing to complete
* @j_wait_done_commit: Wait queue for waiting for commit to complete
- * @j_wait_checkpoint: Wait queue to trigger checkpointing
* @j_wait_commit: Wait queue to trigger commit
* @j_wait_updates: Wait queue to wait for updates to complete
+ * @j_wait_reserved: Wait queue to wait for reserved buffer credits to drop
* @j_checkpoint_mutex: Mutex for locking against concurrent checkpoints
* @j_head: Journal head - identifies the first unused block in the journal
* @j_tail: Journal tail - identifies the oldest still-used block in the
@@ -689,6 +707,7 @@ jbd2_time_diff(unsigned long start, unsigned long end)
* journal
* @j_fs_dev: Device which holds the client fs. For internal journal this will
* be equal to j_dev
+ * @j_reserved_credits: Number of buffers reserved from the running transaction
* @j_maxlen: Total maximum capacity of the journal region on disk.
* @j_list_lock: Protects the buffer lists and internal buffer state.
* @j_inode: Optional inode where we store the journal. If present, all journal
@@ -778,21 +797,18 @@ struct journal_s
*/
wait_queue_head_t j_wait_transaction_locked;
- /* Wait queue for waiting for checkpointing to complete */
- wait_queue_head_t j_wait_logspace;
-
/* Wait queue for waiting for commit to complete */
wait_queue_head_t j_wait_done_commit;
- /* Wait queue to trigger checkpointing */
- wait_queue_head_t j_wait_checkpoint;
-
/* Wait queue to trigger commit */
wait_queue_head_t j_wait_commit;
/* Wait queue to wait for updates to complete */
wait_queue_head_t j_wait_updates;
+ /* Wait queue to wait for reserved buffer credits to drop */
+ wait_queue_head_t j_wait_reserved;
+
/* Semaphore for locking against concurrent checkpoints */
struct mutex j_checkpoint_mutex;
@@ -847,6 +863,9 @@ struct journal_s
/* Total maximum capacity of the journal region on disk. */
unsigned int j_maxlen;
+ /* Number of buffers reserved from the running transaction */
+ atomic_t j_reserved_credits;
+
/*
* Protects the buffer lists and internal buffer state.
*/
@@ -991,9 +1010,17 @@ extern void __jbd2_journal_file_buffer(struct journal_head *, transaction_t *, i
extern void __journal_free_buffer(struct journal_head *bh);
extern void jbd2_journal_file_buffer(struct journal_head *, transaction_t *, int);
extern void __journal_clean_data_list(transaction_t *transaction);
+static inline void jbd2_file_log_bh(struct list_head *head, struct buffer_head *bh)
+{
+ list_add_tail(&bh->b_assoc_buffers, head);
+}
+static inline void jbd2_unfile_log_bh(struct buffer_head *bh)
+{
+ list_del_init(&bh->b_assoc_buffers);
+}
/* Log buffer allocation */
-extern struct journal_head * jbd2_journal_get_descriptor_buffer(journal_t *);
+struct buffer_head *jbd2_journal_get_descriptor_buffer(journal_t *journal);
int jbd2_journal_next_log_block(journal_t *, unsigned long long *);
int jbd2_journal_get_log_tail(journal_t *journal, tid_t *tid,
unsigned long *block);
@@ -1039,11 +1066,10 @@ extern void jbd2_buffer_abort_trigger(struct journal_head *jh,
struct jbd2_buffer_trigger_type *triggers);
/* Buffer IO */
-extern int
-jbd2_journal_write_metadata_buffer(transaction_t *transaction,
- struct journal_head *jh_in,
- struct journal_head **jh_out,
- unsigned long long blocknr);
+extern int jbd2_journal_write_metadata_buffer(transaction_t *transaction,
+ struct journal_head *jh_in,
+ struct buffer_head **bh_out,
+ sector_t blocknr);
/* Transaction locking */
extern void __wait_on_journal (journal_t *);
@@ -1076,10 +1102,14 @@ static inline handle_t *journal_current_handle(void)
*/
extern handle_t *jbd2_journal_start(journal_t *, int nblocks);
-extern handle_t *jbd2__journal_start(journal_t *, int nblocks, gfp_t gfp_mask,
- unsigned int type, unsigned int line_no);
+extern handle_t *jbd2__journal_start(journal_t *, int blocks, int rsv_blocks,
+ gfp_t gfp_mask, unsigned int type,
+ unsigned int line_no);
extern int jbd2_journal_restart(handle_t *, int nblocks);
extern int jbd2__journal_restart(handle_t *, int nblocks, gfp_t gfp_mask);
+extern int jbd2_journal_start_reserved(handle_t *handle,
+ unsigned int type, unsigned int line_no);
+extern void jbd2_journal_free_reserved(handle_t *handle);
extern int jbd2_journal_extend (handle_t *, int nblocks);
extern int jbd2_journal_get_write_access(handle_t *, struct buffer_head *);
extern int jbd2_journal_get_create_access (handle_t *, struct buffer_head *);
@@ -1090,7 +1120,7 @@ extern int jbd2_journal_dirty_metadata (handle_t *, struct buffer_head *);
extern int jbd2_journal_forget (handle_t *, struct buffer_head *);
extern void journal_sync_buffer (struct buffer_head *);
extern int jbd2_journal_invalidatepage(journal_t *,
- struct page *, unsigned long);
+ struct page *, unsigned int, unsigned int);
extern int jbd2_journal_try_to_free_buffers(journal_t *, struct page *, gfp_t);
extern int jbd2_journal_stop(handle_t *);
extern int jbd2_journal_flush (journal_t *);
@@ -1125,6 +1155,7 @@ extern void jbd2_journal_ack_err (journal_t *);
extern int jbd2_journal_clear_err (journal_t *);
extern int jbd2_journal_bmap(journal_t *, unsigned long, unsigned long long *);
extern int jbd2_journal_force_commit(journal_t *);
+extern int jbd2_journal_force_commit_nested(journal_t *);
extern int jbd2_journal_file_inode(handle_t *handle, struct jbd2_inode *inode);
extern int jbd2_journal_begin_ordered_truncate(journal_t *journal,
struct jbd2_inode *inode, loff_t new_size);
@@ -1178,8 +1209,10 @@ extern int jbd2_journal_init_revoke_caches(void);
extern void jbd2_journal_destroy_revoke(journal_t *);
extern int jbd2_journal_revoke (handle_t *, unsigned long long, struct buffer_head *);
extern int jbd2_journal_cancel_revoke(handle_t *, struct journal_head *);
-extern void jbd2_journal_write_revoke_records(journal_t *,
- transaction_t *, int);
+extern void jbd2_journal_write_revoke_records(journal_t *journal,
+ transaction_t *transaction,
+ struct list_head *log_bufs,
+ int write_op);
/* Recovery revoke support */
extern int jbd2_journal_set_revoke(journal_t *, unsigned long long, tid_t);
@@ -1195,11 +1228,9 @@ extern void jbd2_clear_buffer_revoked_flags(journal_t *journal);
* transitions on demand.
*/
-int __jbd2_log_space_left(journal_t *); /* Called with journal locked */
int jbd2_log_start_commit(journal_t *journal, tid_t tid);
int __jbd2_log_start_commit(journal_t *journal, tid_t tid);
int jbd2_journal_start_commit(journal_t *journal, tid_t *tid);
-int jbd2_journal_force_commit_nested(journal_t *journal);
int jbd2_log_wait_commit(journal_t *journal, tid_t tid);
int jbd2_complete_transaction(journal_t *journal, tid_t tid);
int jbd2_log_do_checkpoint(journal_t *journal);
@@ -1235,7 +1266,7 @@ static inline int is_journal_aborted(journal_t *journal)
static inline int is_handle_aborted(handle_t *handle)
{
- if (handle->h_aborted)
+ if (handle->h_aborted || !handle->h_transaction)
return 1;
return is_journal_aborted(handle->h_transaction->t_journal);
}
@@ -1266,16 +1297,37 @@ extern int jbd2_journal_blocks_per_page(struct inode *inode);
extern size_t journal_tag_bytes(journal_t *journal);
/*
+ * We reserve t_outstanding_credits >> JBD2_CONTROL_BLOCKS_SHIFT for
+ * transaction control blocks.
+ */
+#define JBD2_CONTROL_BLOCKS_SHIFT 5
+
+/*
* Return the minimum number of blocks which must be free in the journal
* before a new transaction may be started. Must be called under j_state_lock.
*/
-static inline int jbd_space_needed(journal_t *journal)
+static inline int jbd2_space_needed(journal_t *journal)
{
int nblocks = journal->j_max_transaction_buffers;
- if (journal->j_committing_transaction)
- nblocks += atomic_read(&journal->j_committing_transaction->
- t_outstanding_credits);
- return nblocks;
+ return nblocks + (nblocks >> JBD2_CONTROL_BLOCKS_SHIFT);
+}
+
+/*
+ * Return number of free blocks in the log. Must be called under j_state_lock.
+ */
+static inline unsigned long jbd2_log_space_left(journal_t *journal)
+{
+ /* Allow for rounding errors */
+ unsigned long free = journal->j_free - 32;
+
+ if (journal->j_committing_transaction) {
+ unsigned long committing = atomic_read(&journal->
+ j_committing_transaction->t_outstanding_credits);
+
+ /* Transaction + control blocks */
+ free -= committing + (committing >> JBD2_CONTROL_BLOCKS_SHIFT);
+ }
+ return free;
}
/*
@@ -1286,11 +1338,9 @@ static inline int jbd_space_needed(journal_t *journal)
#define BJ_None 0 /* Not journaled */
#define BJ_Metadata 1 /* Normal journaled metadata */
#define BJ_Forget 2 /* Buffer superseded by this transaction */
-#define BJ_IO 3 /* Buffer is for temporary IO use */
-#define BJ_Shadow 4 /* Buffer contents being shadowed to the log */
-#define BJ_LogCtl 5 /* Buffer contains log descriptors */
-#define BJ_Reserved 6 /* Buffer is reserved for access by journal */
-#define BJ_Types 7
+#define BJ_Shadow 3 /* Buffer contents being shadowed to the log */
+#define BJ_Reserved 4 /* Buffer is reserved for access by journal */
+#define BJ_Types 5
extern int jbd_blocks_per_page(struct inode *inode);
@@ -1319,6 +1369,19 @@ static inline u32 jbd2_chksum(journal_t *journal, u32 crc,
return *(u32 *)desc.ctx;
}
+/* Return most recent uncommitted transaction */
+static inline tid_t jbd2_get_latest_transaction(journal_t *journal)
+{
+ tid_t tid;
+
+ read_lock(&journal->j_state_lock);
+ tid = journal->j_commit_request;
+ if (journal->j_running_transaction)
+ tid = journal->j_running_transaction->t_tid;
+ read_unlock(&journal->j_state_lock);
+ return tid;
+}
+
#ifdef __KERNEL__
#define buffer_trace_init(bh) do {} while (0)
diff --git a/include/linux/jbd_common.h b/include/linux/jbd_common.h
index 6133679bc4c0..3dc53432355f 100644
--- a/include/linux/jbd_common.h
+++ b/include/linux/jbd_common.h
@@ -1,31 +1,7 @@
#ifndef _LINUX_JBD_STATE_H
#define _LINUX_JBD_STATE_H
-enum jbd_state_bits {
- BH_JBD /* Has an attached ext3 journal_head */
- = BH_PrivateStart,
- BH_JWrite, /* Being written to log (@@@ DEBUGGING) */
- BH_Freed, /* Has been freed (truncated) */
- BH_Revoked, /* Has been revoked from the log */
- BH_RevokeValid, /* Revoked flag is valid */
- BH_JBDDirty, /* Is dirty but journaled */
- BH_State, /* Pins most journal_head state */
- BH_JournalHead, /* Pins bh->b_private and jh->b_bh */
- BH_Unshadow, /* Dummy bit, for BJ_Shadow wakeup filtering */
- BH_Verified, /* Metadata block has been verified ok */
- BH_JBDPrivateStart, /* First bit available for private use by FS */
-};
-
-BUFFER_FNS(JBD, jbd)
-BUFFER_FNS(JWrite, jwrite)
-BUFFER_FNS(JBDDirty, jbddirty)
-TAS_BUFFER_FNS(JBDDirty, jbddirty)
-BUFFER_FNS(Revoked, revoked)
-TAS_BUFFER_FNS(Revoked, revoked)
-BUFFER_FNS(RevokeValid, revokevalid)
-TAS_BUFFER_FNS(RevokeValid, revokevalid)
-BUFFER_FNS(Freed, freed)
-BUFFER_FNS(Verified, verified)
+#include <linux/bit_spinlock.h>
static inline struct buffer_head *jh2bh(struct journal_head *jh)
{
diff --git a/include/linux/mm.h b/include/linux/mm.h
index e0c8528a41a4..66d881f1d576 100644
--- a/include/linux/mm.h
+++ b/include/linux/mm.h
@@ -1041,7 +1041,8 @@ int get_kernel_page(unsigned long start, int write, struct page **pages);
struct page *get_dump_page(unsigned long addr);
extern int try_to_release_page(struct page * page, gfp_t gfp_mask);
-extern void do_invalidatepage(struct page *page, unsigned long offset);
+extern void do_invalidatepage(struct page *page, unsigned int offset,
+ unsigned int length);
int __set_page_dirty_nobuffers(struct page *page);
int __set_page_dirty_no_writeback(struct page *page);
diff --git a/include/trace/events/ext3.h b/include/trace/events/ext3.h
index 15d11a39be47..6797b9de90ed 100644
--- a/include/trace/events/ext3.h
+++ b/include/trace/events/ext3.h
@@ -290,13 +290,14 @@ DEFINE_EVENT(ext3__page_op, ext3_releasepage,
);
TRACE_EVENT(ext3_invalidatepage,
- TP_PROTO(struct page *page, unsigned long offset),
+ TP_PROTO(struct page *page, unsigned int offset, unsigned int length),
- TP_ARGS(page, offset),
+ TP_ARGS(page, offset, length),
TP_STRUCT__entry(
__field( pgoff_t, index )
- __field( unsigned long, offset )
+ __field( unsigned int, offset )
+ __field( unsigned int, length )
__field( ino_t, ino )
__field( dev_t, dev )
@@ -305,14 +306,15 @@ TRACE_EVENT(ext3_invalidatepage,
TP_fast_assign(
__entry->index = page->index;
__entry->offset = offset;
+ __entry->length = length;
__entry->ino = page->mapping->host->i_ino;
__entry->dev = page->mapping->host->i_sb->s_dev;
),
- TP_printk("dev %d,%d ino %lu page_index %lu offset %lu",
+ TP_printk("dev %d,%d ino %lu page_index %lu offset %u length %u",
MAJOR(__entry->dev), MINOR(__entry->dev),
(unsigned long) __entry->ino,
- __entry->index, __entry->offset)
+ __entry->index, __entry->offset, __entry->length)
);
TRACE_EVENT(ext3_discard_blocks,
diff --git a/include/trace/events/ext4.h b/include/trace/events/ext4.h
index 8ee15b97cd38..2068db241f22 100644
--- a/include/trace/events/ext4.h
+++ b/include/trace/events/ext4.h
@@ -19,6 +19,57 @@ struct extent_status;
#define EXT4_I(inode) (container_of(inode, struct ext4_inode_info, vfs_inode))
+#define show_mballoc_flags(flags) __print_flags(flags, "|", \
+ { EXT4_MB_HINT_MERGE, "HINT_MERGE" }, \
+ { EXT4_MB_HINT_RESERVED, "HINT_RESV" }, \
+ { EXT4_MB_HINT_METADATA, "HINT_MDATA" }, \
+ { EXT4_MB_HINT_FIRST, "HINT_FIRST" }, \
+ { EXT4_MB_HINT_BEST, "HINT_BEST" }, \
+ { EXT4_MB_HINT_DATA, "HINT_DATA" }, \
+ { EXT4_MB_HINT_NOPREALLOC, "HINT_NOPREALLOC" }, \
+ { EXT4_MB_HINT_GROUP_ALLOC, "HINT_GRP_ALLOC" }, \
+ { EXT4_MB_HINT_GOAL_ONLY, "HINT_GOAL_ONLY" }, \
+ { EXT4_MB_HINT_TRY_GOAL, "HINT_TRY_GOAL" }, \
+ { EXT4_MB_DELALLOC_RESERVED, "DELALLOC_RESV" }, \
+ { EXT4_MB_STREAM_ALLOC, "STREAM_ALLOC" }, \
+ { EXT4_MB_USE_ROOT_BLOCKS, "USE_ROOT_BLKS" }, \
+ { EXT4_MB_USE_RESERVED, "USE_RESV" })
+
+#define show_map_flags(flags) __print_flags(flags, "|", \
+ { EXT4_GET_BLOCKS_CREATE, "CREATE" }, \
+ { EXT4_GET_BLOCKS_UNINIT_EXT, "UNINIT" }, \
+ { EXT4_GET_BLOCKS_DELALLOC_RESERVE, "DELALLOC" }, \
+ { EXT4_GET_BLOCKS_PRE_IO, "PRE_IO" }, \
+ { EXT4_GET_BLOCKS_CONVERT, "CONVERT" }, \
+ { EXT4_GET_BLOCKS_METADATA_NOFAIL, "METADATA_NOFAIL" }, \
+ { EXT4_GET_BLOCKS_NO_NORMALIZE, "NO_NORMALIZE" }, \
+ { EXT4_GET_BLOCKS_KEEP_SIZE, "KEEP_SIZE" }, \
+ { EXT4_GET_BLOCKS_NO_LOCK, "NO_LOCK" }, \
+ { EXT4_GET_BLOCKS_NO_PUT_HOLE, "NO_PUT_HOLE" })
+
+#define show_mflags(flags) __print_flags(flags, "", \
+ { EXT4_MAP_NEW, "N" }, \
+ { EXT4_MAP_MAPPED, "M" }, \
+ { EXT4_MAP_UNWRITTEN, "U" }, \
+ { EXT4_MAP_BOUNDARY, "B" }, \
+ { EXT4_MAP_UNINIT, "u" }, \
+ { EXT4_MAP_FROM_CLUSTER, "C" })
+
+#define show_free_flags(flags) __print_flags(flags, "|", \
+ { EXT4_FREE_BLOCKS_METADATA, "METADATA" }, \
+ { EXT4_FREE_BLOCKS_FORGET, "FORGET" }, \
+ { EXT4_FREE_BLOCKS_VALIDATED, "VALIDATED" }, \
+ { EXT4_FREE_BLOCKS_NO_QUOT_UPDATE, "NO_QUOTA" }, \
+ { EXT4_FREE_BLOCKS_NOFREE_FIRST_CLUSTER,"1ST_CLUSTER" },\
+ { EXT4_FREE_BLOCKS_NOFREE_LAST_CLUSTER, "LAST_CLUSTER" })
+
+#define show_extent_status(status) __print_flags(status, "", \
+ { (1 << 3), "W" }, \
+ { (1 << 2), "U" }, \
+ { (1 << 1), "D" }, \
+ { (1 << 0), "H" })
+
+
TRACE_EVENT(ext4_free_inode,
TP_PROTO(struct inode *inode),
@@ -281,7 +332,7 @@ DEFINE_EVENT(ext4__write_end, ext4_da_write_end,
TP_ARGS(inode, pos, len, copied)
);
-TRACE_EVENT(ext4_da_writepages,
+TRACE_EVENT(ext4_writepages,
TP_PROTO(struct inode *inode, struct writeback_control *wbc),
TP_ARGS(inode, wbc),
@@ -324,46 +375,62 @@ TRACE_EVENT(ext4_da_writepages,
);
TRACE_EVENT(ext4_da_write_pages,
- TP_PROTO(struct inode *inode, struct mpage_da_data *mpd),
+ TP_PROTO(struct inode *inode, pgoff_t first_page,
+ struct writeback_control *wbc),
- TP_ARGS(inode, mpd),
+ TP_ARGS(inode, first_page, wbc),
TP_STRUCT__entry(
__field( dev_t, dev )
__field( ino_t, ino )
- __field( __u64, b_blocknr )
- __field( __u32, b_size )
- __field( __u32, b_state )
- __field( unsigned long, first_page )
- __field( int, io_done )
- __field( int, pages_written )
- __field( int, sync_mode )
+ __field( pgoff_t, first_page )
+ __field( long, nr_to_write )
+ __field( int, sync_mode )
),
TP_fast_assign(
__entry->dev = inode->i_sb->s_dev;
__entry->ino = inode->i_ino;
- __entry->b_blocknr = mpd->b_blocknr;
- __entry->b_size = mpd->b_size;
- __entry->b_state = mpd->b_state;
- __entry->first_page = mpd->first_page;
- __entry->io_done = mpd->io_done;
- __entry->pages_written = mpd->pages_written;
- __entry->sync_mode = mpd->wbc->sync_mode;
+ __entry->first_page = first_page;
+ __entry->nr_to_write = wbc->nr_to_write;
+ __entry->sync_mode = wbc->sync_mode;
),
- TP_printk("dev %d,%d ino %lu b_blocknr %llu b_size %u b_state 0x%04x "
- "first_page %lu io_done %d pages_written %d sync_mode %d",
+ TP_printk("dev %d,%d ino %lu first_page %lu nr_to_write %ld "
+ "sync_mode %d",
MAJOR(__entry->dev), MINOR(__entry->dev),
- (unsigned long) __entry->ino,
- __entry->b_blocknr, __entry->b_size,
- __entry->b_state, __entry->first_page,
- __entry->io_done, __entry->pages_written,
- __entry->sync_mode
- )
+ (unsigned long) __entry->ino, __entry->first_page,
+ __entry->nr_to_write, __entry->sync_mode)
);
-TRACE_EVENT(ext4_da_writepages_result,
+TRACE_EVENT(ext4_da_write_pages_extent,
+ TP_PROTO(struct inode *inode, struct ext4_map_blocks *map),
+
+ TP_ARGS(inode, map),
+
+ TP_STRUCT__entry(
+ __field( dev_t, dev )
+ __field( ino_t, ino )
+ __field( __u64, lblk )
+ __field( __u32, len )
+ __field( __u32, flags )
+ ),
+
+ TP_fast_assign(
+ __entry->dev = inode->i_sb->s_dev;
+ __entry->ino = inode->i_ino;
+ __entry->lblk = map->m_lblk;
+ __entry->len = map->m_len;
+ __entry->flags = map->m_flags;
+ ),
+
+ TP_printk("dev %d,%d ino %lu lblk %llu len %u flags %s",
+ MAJOR(__entry->dev), MINOR(__entry->dev),
+ (unsigned long) __entry->ino, __entry->lblk, __entry->len,
+ show_mflags(__entry->flags))
+);
+
+TRACE_EVENT(ext4_writepages_result,
TP_PROTO(struct inode *inode, struct writeback_control *wbc,
int ret, int pages_written),
@@ -444,16 +511,16 @@ DEFINE_EVENT(ext4__page_op, ext4_releasepage,
);
DECLARE_EVENT_CLASS(ext4_invalidatepage_op,
- TP_PROTO(struct page *page, unsigned long offset),
+ TP_PROTO(struct page *page, unsigned int offset, unsigned int length),
- TP_ARGS(page, offset),
+ TP_ARGS(page, offset, length),
TP_STRUCT__entry(
__field( dev_t, dev )
__field( ino_t, ino )
__field( pgoff_t, index )
- __field( unsigned long, offset )
-
+ __field( unsigned int, offset )
+ __field( unsigned int, length )
),
TP_fast_assign(
@@ -461,24 +528,26 @@ DECLARE_EVENT_CLASS(ext4_invalidatepage_op,
__entry->ino = page->mapping->host->i_ino;
__entry->index = page->index;
__entry->offset = offset;
+ __entry->length = length;
),
- TP_printk("dev %d,%d ino %lu page_index %lu offset %lu",
+ TP_printk("dev %d,%d ino %lu page_index %lu offset %u length %u",
MAJOR(__entry->dev), MINOR(__entry->dev),
(unsigned long) __entry->ino,
- (unsigned long) __entry->index, __entry->offset)
+ (unsigned long) __entry->index,
+ __entry->offset, __entry->length)
);
DEFINE_EVENT(ext4_invalidatepage_op, ext4_invalidatepage,
- TP_PROTO(struct page *page, unsigned long offset),
+ TP_PROTO(struct page *page, unsigned int offset, unsigned int length),
- TP_ARGS(page, offset)
+ TP_ARGS(page, offset, length)
);
DEFINE_EVENT(ext4_invalidatepage_op, ext4_journalled_invalidatepage,
- TP_PROTO(struct page *page, unsigned long offset),
+ TP_PROTO(struct page *page, unsigned int offset, unsigned int length),
- TP_ARGS(page, offset)
+ TP_ARGS(page, offset, length)
);
TRACE_EVENT(ext4_discard_blocks,
@@ -673,10 +742,10 @@ TRACE_EVENT(ext4_request_blocks,
__entry->flags = ar->flags;
),
- TP_printk("dev %d,%d ino %lu flags %u len %u lblk %u goal %llu "
+ TP_printk("dev %d,%d ino %lu flags %s len %u lblk %u goal %llu "
"lleft %u lright %u pleft %llu pright %llu ",
MAJOR(__entry->dev), MINOR(__entry->dev),
- (unsigned long) __entry->ino, __entry->flags,
+ (unsigned long) __entry->ino, show_mballoc_flags(__entry->flags),
__entry->len, __entry->logical, __entry->goal,
__entry->lleft, __entry->lright, __entry->pleft,
__entry->pright)
@@ -715,10 +784,10 @@ TRACE_EVENT(ext4_allocate_blocks,
__entry->flags = ar->flags;
),
- TP_printk("dev %d,%d ino %lu flags %u len %u block %llu lblk %u "
+ TP_printk("dev %d,%d ino %lu flags %s len %u block %llu lblk %u "
"goal %llu lleft %u lright %u pleft %llu pright %llu",
MAJOR(__entry->dev), MINOR(__entry->dev),
- (unsigned long) __entry->ino, __entry->flags,
+ (unsigned long) __entry->ino, show_mballoc_flags(__entry->flags),
__entry->len, __entry->block, __entry->logical,
__entry->goal, __entry->lleft, __entry->lright,
__entry->pleft, __entry->pright)
@@ -748,11 +817,11 @@ TRACE_EVENT(ext4_free_blocks,
__entry->mode = inode->i_mode;
),
- TP_printk("dev %d,%d ino %lu mode 0%o block %llu count %lu flags %d",
+ TP_printk("dev %d,%d ino %lu mode 0%o block %llu count %lu flags %s",
MAJOR(__entry->dev), MINOR(__entry->dev),
(unsigned long) __entry->ino,
__entry->mode, __entry->block, __entry->count,
- __entry->flags)
+ show_free_flags(__entry->flags))
);
TRACE_EVENT(ext4_sync_file_enter,
@@ -903,7 +972,7 @@ TRACE_EVENT(ext4_mballoc_alloc,
),
TP_printk("dev %d,%d inode %lu orig %u/%d/%u@%u goal %u/%d/%u@%u "
- "result %u/%d/%u@%u blks %u grps %u cr %u flags 0x%04x "
+ "result %u/%d/%u@%u blks %u grps %u cr %u flags %s "
"tail %u broken %u",
MAJOR(__entry->dev), MINOR(__entry->dev),
(unsigned long) __entry->ino,
@@ -914,7 +983,7 @@ TRACE_EVENT(ext4_mballoc_alloc,
__entry->result_group, __entry->result_start,
__entry->result_len, __entry->result_logical,
__entry->found, __entry->groups, __entry->cr,
- __entry->flags, __entry->tail,
+ show_mballoc_flags(__entry->flags), __entry->tail,
__entry->buddy ? 1 << __entry->buddy : 0)
);
@@ -1528,10 +1597,10 @@ DECLARE_EVENT_CLASS(ext4__map_blocks_enter,
__entry->flags = flags;
),
- TP_printk("dev %d,%d ino %lu lblk %u len %u flags %u",
+ TP_printk("dev %d,%d ino %lu lblk %u len %u flags %s",
MAJOR(__entry->dev), MINOR(__entry->dev),
(unsigned long) __entry->ino,
- __entry->lblk, __entry->len, __entry->flags)
+ __entry->lblk, __entry->len, show_map_flags(__entry->flags))
);
DEFINE_EVENT(ext4__map_blocks_enter, ext4_ext_map_blocks_enter,
@@ -1549,47 +1618,53 @@ DEFINE_EVENT(ext4__map_blocks_enter, ext4_ind_map_blocks_enter,
);
DECLARE_EVENT_CLASS(ext4__map_blocks_exit,
- TP_PROTO(struct inode *inode, struct ext4_map_blocks *map, int ret),
+ TP_PROTO(struct inode *inode, unsigned flags, struct ext4_map_blocks *map,
+ int ret),
- TP_ARGS(inode, map, ret),
+ TP_ARGS(inode, flags, map, ret),
TP_STRUCT__entry(
__field( dev_t, dev )
__field( ino_t, ino )
+ __field( unsigned int, flags )
__field( ext4_fsblk_t, pblk )
__field( ext4_lblk_t, lblk )
__field( unsigned int, len )
- __field( unsigned int, flags )
+ __field( unsigned int, mflags )
__field( int, ret )
),
TP_fast_assign(
__entry->dev = inode->i_sb->s_dev;
__entry->ino = inode->i_ino;
+ __entry->flags = flags;
__entry->pblk = map->m_pblk;
__entry->lblk = map->m_lblk;
__entry->len = map->m_len;
- __entry->flags = map->m_flags;
+ __entry->mflags = map->m_flags;
__entry->ret = ret;
),
- TP_printk("dev %d,%d ino %lu lblk %u pblk %llu len %u flags %x ret %d",
+ TP_printk("dev %d,%d ino %lu flags %s lblk %u pblk %llu len %u "
+ "mflags %s ret %d",
MAJOR(__entry->dev), MINOR(__entry->dev),
(unsigned long) __entry->ino,
- __entry->lblk, __entry->pblk,
- __entry->len, __entry->flags, __entry->ret)
+ show_map_flags(__entry->flags), __entry->lblk, __entry->pblk,
+ __entry->len, show_mflags(__entry->mflags), __entry->ret)
);
DEFINE_EVENT(ext4__map_blocks_exit, ext4_ext_map_blocks_exit,
- TP_PROTO(struct inode *inode, struct ext4_map_blocks *map, int ret),
+ TP_PROTO(struct inode *inode, unsigned flags,
+ struct ext4_map_blocks *map, int ret),
- TP_ARGS(inode, map, ret)
+ TP_ARGS(inode, flags, map, ret)
);
DEFINE_EVENT(ext4__map_blocks_exit, ext4_ind_map_blocks_exit,
- TP_PROTO(struct inode *inode, struct ext4_map_blocks *map, int ret),
+ TP_PROTO(struct inode *inode, unsigned flags,
+ struct ext4_map_blocks *map, int ret),
- TP_ARGS(inode, map, ret)
+ TP_ARGS(inode, flags, map, ret)
);
TRACE_EVENT(ext4_ext_load_extent,
@@ -1638,25 +1713,50 @@ TRACE_EVENT(ext4_load_inode,
);
TRACE_EVENT(ext4_journal_start,
- TP_PROTO(struct super_block *sb, int nblocks, unsigned long IP),
+ TP_PROTO(struct super_block *sb, int blocks, int rsv_blocks,
+ unsigned long IP),
- TP_ARGS(sb, nblocks, IP),
+ TP_ARGS(sb, blocks, rsv_blocks, IP),
TP_STRUCT__entry(
__field( dev_t, dev )
__field(unsigned long, ip )
- __field( int, nblocks )
+ __field( int, blocks )
+ __field( int, rsv_blocks )
),
TP_fast_assign(
- __entry->dev = sb->s_dev;
- __entry->ip = IP;
- __entry->nblocks = nblocks;
+ __entry->dev = sb->s_dev;
+ __entry->ip = IP;
+ __entry->blocks = blocks;
+ __entry->rsv_blocks = rsv_blocks;
),
- TP_printk("dev %d,%d nblocks %d caller %pF",
+ TP_printk("dev %d,%d blocks, %d rsv_blocks, %d caller %pF",
MAJOR(__entry->dev), MINOR(__entry->dev),
- __entry->nblocks, (void *)__entry->ip)
+ __entry->blocks, __entry->rsv_blocks, (void *)__entry->ip)
+);
+
+TRACE_EVENT(ext4_journal_start_reserved,
+ TP_PROTO(struct super_block *sb, int blocks, unsigned long IP),
+
+ TP_ARGS(sb, blocks, IP),
+
+ TP_STRUCT__entry(
+ __field( dev_t, dev )
+ __field(unsigned long, ip )
+ __field( int, blocks )
+ ),
+
+ TP_fast_assign(
+ __entry->dev = sb->s_dev;
+ __entry->ip = IP;
+ __entry->blocks = blocks;
+ ),
+
+ TP_printk("dev %d,%d blocks, %d caller %pF",
+ MAJOR(__entry->dev), MINOR(__entry->dev),
+ __entry->blocks, (void *)__entry->ip)
);
DECLARE_EVENT_CLASS(ext4__trim,
@@ -1736,12 +1836,12 @@ TRACE_EVENT(ext4_ext_handle_uninitialized_extents,
__entry-