diff options
author | Linus Torvalds <torvalds@linux-foundation.org> | 2009-06-18 17:07:46 -0400 |
---|---|---|
committer | Linus Torvalds <torvalds@linux-foundation.org> | 2009-06-18 17:07:46 -0400 |
commit | 0732f87761dbe417cb6e084b712d07e879e876ef (patch) | |
tree | afed6ca0368fd3e121fd4f43b11e32aa1e5139c0 /fs/jbd2 | |
parent | 15fc204afc6feb915c400159546f646eca8ba1d9 (diff) | |
parent | 536fc240e7147858255bdb08e7a999a3351a9fb4 (diff) |
Merge branch 'for_linus' of git://git.kernel.org/pub/scm/linux/kernel/git/tytso/ext4
* 'for_linus' of git://git.kernel.org/pub/scm/linux/kernel/git/tytso/ext4:
jbd2: clean up jbd2_journal_try_to_free_buffers()
ext4: Don't update ctime for non-extent-mapped inodes
ext4: Fix up whitespace issues in fs/ext4/inode.c
ext4: Fix 64-bit block type problem on 32-bit platforms
ext4: teach the inode allocator to use a goal inode number
ext4: Use a hash of the topdir directory name for the Orlov parent group
ext4: document the "abort" mount option
ext4: move the abort flag from s_mount_opts to s_mount_flags
ext4: update the s_last_mounted field in the superblock
ext4: change s_mount_opt to be an unsigned int
ext4: online defrag -- Add EXT4_IOC_MOVE_EXT ioctl
ext4: avoid unnecessary spinlock in critical POSIX ACL path
ext3: avoid unnecessary spinlock in critical POSIX ACL path
ext4: convert instrumentation from markers to tracepoints
jbd2: convert instrumentation from markers to tracepoints
Diffstat (limited to 'fs/jbd2')
-rw-r--r-- | fs/jbd2/checkpoint.c | 5 | ||||
-rw-r--r-- | fs/jbd2/commit.c | 13 | ||||
-rw-r--r-- | fs/jbd2/journal.c | 69 | ||||
-rw-r--r-- | fs/jbd2/transaction.c | 49 |
4 files changed, 78 insertions, 58 deletions
diff --git a/fs/jbd2/checkpoint.c b/fs/jbd2/checkpoint.c index 17159cacbd9e..5d70b3e6d49b 100644 --- a/fs/jbd2/checkpoint.c +++ b/fs/jbd2/checkpoint.c | |||
@@ -20,9 +20,9 @@ | |||
20 | #include <linux/time.h> | 20 | #include <linux/time.h> |
21 | #include <linux/fs.h> | 21 | #include <linux/fs.h> |
22 | #include <linux/jbd2.h> | 22 | #include <linux/jbd2.h> |
23 | #include <linux/marker.h> | ||
24 | #include <linux/errno.h> | 23 | #include <linux/errno.h> |
25 | #include <linux/slab.h> | 24 | #include <linux/slab.h> |
25 | #include <trace/events/jbd2.h> | ||
26 | 26 | ||
27 | /* | 27 | /* |
28 | * Unlink a buffer from a transaction checkpoint list. | 28 | * Unlink a buffer from a transaction checkpoint list. |
@@ -358,8 +358,7 @@ int jbd2_log_do_checkpoint(journal_t *journal) | |||
358 | * journal straight away. | 358 | * journal straight away. |
359 | */ | 359 | */ |
360 | result = jbd2_cleanup_journal_tail(journal); | 360 | result = jbd2_cleanup_journal_tail(journal); |
361 | trace_mark(jbd2_checkpoint, "dev %s need_checkpoint %d", | 361 | trace_jbd2_checkpoint(journal, result); |
362 | journal->j_devname, result); | ||
363 | jbd_debug(1, "cleanup_journal_tail returned %d\n", result); | 362 | jbd_debug(1, "cleanup_journal_tail returned %d\n", result); |
364 | if (result <= 0) | 363 | if (result <= 0) |
365 | return result; | 364 | return result; |
diff --git a/fs/jbd2/commit.c b/fs/jbd2/commit.c index 0b7d3b8226fd..7b4088b2364d 100644 --- a/fs/jbd2/commit.c +++ b/fs/jbd2/commit.c | |||
@@ -16,7 +16,6 @@ | |||
16 | #include <linux/time.h> | 16 | #include <linux/time.h> |
17 | #include <linux/fs.h> | 17 | #include <linux/fs.h> |
18 | #include <linux/jbd2.h> | 18 | #include <linux/jbd2.h> |
19 | #include <linux/marker.h> | ||
20 | #include <linux/errno.h> | 19 | #include <linux/errno.h> |
21 | #include <linux/slab.h> | 20 | #include <linux/slab.h> |
22 | #include <linux/mm.h> | 21 | #include <linux/mm.h> |
@@ -26,6 +25,7 @@ | |||
26 | #include <linux/writeback.h> | 25 | #include <linux/writeback.h> |
27 | #include <linux/backing-dev.h> | 26 | #include <linux/backing-dev.h> |
28 | #include <linux/bio.h> | 27 | #include <linux/bio.h> |
28 | #include <trace/events/jbd2.h> | ||
29 | 29 | ||
30 | /* | 30 | /* |
31 | * Default IO end handler for temporary BJ_IO buffer_heads. | 31 | * Default IO end handler for temporary BJ_IO buffer_heads. |
@@ -253,6 +253,7 @@ static int journal_submit_data_buffers(journal_t *journal, | |||
253 | * block allocation with delalloc. We need to write | 253 | * block allocation with delalloc. We need to write |
254 | * only allocated blocks here. | 254 | * only allocated blocks here. |
255 | */ | 255 | */ |
256 | trace_jbd2_submit_inode_data(jinode->i_vfs_inode); | ||
256 | err = journal_submit_inode_data_buffers(mapping); | 257 | err = journal_submit_inode_data_buffers(mapping); |
257 | if (!ret) | 258 | if (!ret) |
258 | ret = err; | 259 | ret = err; |
@@ -394,8 +395,7 @@ void jbd2_journal_commit_transaction(journal_t *journal) | |||
394 | commit_transaction = journal->j_running_transaction; | 395 | commit_transaction = journal->j_running_transaction; |
395 | J_ASSERT(commit_transaction->t_state == T_RUNNING); | 396 | J_ASSERT(commit_transaction->t_state == T_RUNNING); |
396 | 397 | ||
397 | trace_mark(jbd2_start_commit, "dev %s transaction %d", | 398 | trace_jbd2_start_commit(journal, commit_transaction); |
398 | journal->j_devname, commit_transaction->t_tid); | ||
399 | jbd_debug(1, "JBD: starting commit of transaction %d\n", | 399 | jbd_debug(1, "JBD: starting commit of transaction %d\n", |
400 | commit_transaction->t_tid); | 400 | commit_transaction->t_tid); |
401 | 401 | ||
@@ -409,6 +409,7 @@ void jbd2_journal_commit_transaction(journal_t *journal) | |||
409 | */ | 409 | */ |
410 | if (commit_transaction->t_synchronous_commit) | 410 | if (commit_transaction->t_synchronous_commit) |
411 | write_op = WRITE_SYNC_PLUG; | 411 | write_op = WRITE_SYNC_PLUG; |
412 | trace_jbd2_commit_locking(journal, commit_transaction); | ||
412 | stats.u.run.rs_wait = commit_transaction->t_max_wait; | 413 | stats.u.run.rs_wait = commit_transaction->t_max_wait; |
413 | stats.u.run.rs_locked = jiffies; | 414 | stats.u.run.rs_locked = jiffies; |
414 | stats.u.run.rs_running = jbd2_time_diff(commit_transaction->t_start, | 415 | stats.u.run.rs_running = jbd2_time_diff(commit_transaction->t_start, |
@@ -484,6 +485,7 @@ void jbd2_journal_commit_transaction(journal_t *journal) | |||
484 | */ | 485 | */ |
485 | jbd2_journal_switch_revoke_table(journal); | 486 | jbd2_journal_switch_revoke_table(journal); |
486 | 487 | ||
488 | trace_jbd2_commit_flushing(journal, commit_transaction); | ||
487 | stats.u.run.rs_flushing = jiffies; | 489 | stats.u.run.rs_flushing = jiffies; |
488 | stats.u.run.rs_locked = jbd2_time_diff(stats.u.run.rs_locked, | 490 | stats.u.run.rs_locked = jbd2_time_diff(stats.u.run.rs_locked, |
489 | stats.u.run.rs_flushing); | 491 | stats.u.run.rs_flushing); |
@@ -520,6 +522,7 @@ void jbd2_journal_commit_transaction(journal_t *journal) | |||
520 | commit_transaction->t_state = T_COMMIT; | 522 | commit_transaction->t_state = T_COMMIT; |
521 | spin_unlock(&journal->j_state_lock); | 523 | spin_unlock(&journal->j_state_lock); |
522 | 524 | ||
525 | trace_jbd2_commit_logging(journal, commit_transaction); | ||
523 | stats.u.run.rs_logging = jiffies; | 526 | stats.u.run.rs_logging = jiffies; |
524 | stats.u.run.rs_flushing = jbd2_time_diff(stats.u.run.rs_flushing, | 527 | stats.u.run.rs_flushing = jbd2_time_diff(stats.u.run.rs_flushing, |
525 | stats.u.run.rs_logging); | 528 | stats.u.run.rs_logging); |
@@ -1054,9 +1057,7 @@ restart_loop: | |||
1054 | if (journal->j_commit_callback) | 1057 | if (journal->j_commit_callback) |
1055 | journal->j_commit_callback(journal, commit_transaction); | 1058 | journal->j_commit_callback(journal, commit_transaction); |
1056 | 1059 | ||
1057 | trace_mark(jbd2_end_commit, "dev %s transaction %d head %d", | 1060 | trace_jbd2_end_commit(journal, commit_transaction); |
1058 | journal->j_devname, commit_transaction->t_tid, | ||
1059 | journal->j_tail_sequence); | ||
1060 | jbd_debug(1, "JBD: commit %d complete, head %d\n", | 1061 | jbd_debug(1, "JBD: commit %d complete, head %d\n", |
1061 | journal->j_commit_sequence, journal->j_tail_sequence); | 1062 | journal->j_commit_sequence, journal->j_tail_sequence); |
1062 | if (to_free) | 1063 | if (to_free) |
diff --git a/fs/jbd2/journal.c b/fs/jbd2/journal.c index 62be7d294ec2..18bfd5dab642 100644 --- a/fs/jbd2/journal.c +++ b/fs/jbd2/journal.c | |||
@@ -38,6 +38,10 @@ | |||
38 | #include <linux/debugfs.h> | 38 | #include <linux/debugfs.h> |
39 | #include <linux/seq_file.h> | 39 | #include <linux/seq_file.h> |
40 | #include <linux/math64.h> | 40 | #include <linux/math64.h> |
41 | #include <linux/hash.h> | ||
42 | |||
43 | #define CREATE_TRACE_POINTS | ||
44 | #include <trace/events/jbd2.h> | ||
41 | 45 | ||
42 | #include <asm/uaccess.h> | 46 | #include <asm/uaccess.h> |
43 | #include <asm/page.h> | 47 | #include <asm/page.h> |
@@ -2377,6 +2381,71 @@ static void __exit journal_exit(void) | |||
2377 | jbd2_journal_destroy_caches(); | 2381 | jbd2_journal_destroy_caches(); |
2378 | } | 2382 | } |
2379 | 2383 | ||
2384 | /* | ||
2385 | * jbd2_dev_to_name is a utility function used by the jbd2 and ext4 | ||
2386 | * tracing infrastructure to map a dev_t to a device name. | ||
2387 | * | ||
2388 | * The caller should use rcu_read_lock() in order to make sure the | ||
2389 | * device name stays valid until its done with it. We use | ||
2390 | * rcu_read_lock() as well to make sure we're safe in case the caller | ||
2391 | * gets sloppy, and because rcu_read_lock() is cheap and can be safely | ||
2392 | * nested. | ||
2393 | */ | ||
2394 | struct devname_cache { | ||
2395 | struct rcu_head rcu; | ||
2396 | dev_t device; | ||
2397 | char devname[BDEVNAME_SIZE]; | ||
2398 | }; | ||
2399 | #define CACHE_SIZE_BITS 6 | ||
2400 | static struct devname_cache *devcache[1 << CACHE_SIZE_BITS]; | ||
2401 | static DEFINE_SPINLOCK(devname_cache_lock); | ||
2402 | |||
2403 | static void free_devcache(struct rcu_head *rcu) | ||
2404 | { | ||
2405 | kfree(rcu); | ||
2406 | } | ||
2407 | |||
2408 | const char *jbd2_dev_to_name(dev_t device) | ||
2409 | { | ||
2410 | int i = hash_32(device, CACHE_SIZE_BITS); | ||
2411 | char *ret; | ||
2412 | struct block_device *bd; | ||
2413 | |||
2414 | rcu_read_lock(); | ||
2415 | if (devcache[i] && devcache[i]->device == device) { | ||
2416 | ret = devcache[i]->devname; | ||
2417 | rcu_read_unlock(); | ||
2418 | return ret; | ||
2419 | } | ||
2420 | rcu_read_unlock(); | ||
2421 | |||
2422 | spin_lock(&devname_cache_lock); | ||
2423 | if (devcache[i]) { | ||
2424 | if (devcache[i]->device == device) { | ||
2425 | ret = devcache[i]->devname; | ||
2426 | spin_unlock(&devname_cache_lock); | ||
2427 | return ret; | ||
2428 | } | ||
2429 | call_rcu(&devcache[i]->rcu, free_devcache); | ||
2430 | } | ||
2431 | devcache[i] = kmalloc(sizeof(struct devname_cache), GFP_KERNEL); | ||
2432 | if (!devcache[i]) { | ||
2433 | spin_unlock(&devname_cache_lock); | ||
2434 | return "NODEV-ALLOCFAILURE"; /* Something non-NULL */ | ||
2435 | } | ||
2436 | devcache[i]->device = device; | ||
2437 | bd = bdget(device); | ||
2438 | if (bd) { | ||
2439 | bdevname(bd, devcache[i]->devname); | ||
2440 | bdput(bd); | ||
2441 | } else | ||
2442 | __bdevname(device, devcache[i]->devname); | ||
2443 | ret = devcache[i]->devname; | ||
2444 | spin_unlock(&devname_cache_lock); | ||
2445 | return ret; | ||
2446 | } | ||
2447 | EXPORT_SYMBOL(jbd2_dev_to_name); | ||
2448 | |||
2380 | MODULE_LICENSE("GPL"); | 2449 | MODULE_LICENSE("GPL"); |
2381 | module_init(journal_init); | 2450 | module_init(journal_init); |
2382 | module_exit(journal_exit); | 2451 | module_exit(journal_exit); |
diff --git a/fs/jbd2/transaction.c b/fs/jbd2/transaction.c index 996ffda06bf3..494501edba6b 100644 --- a/fs/jbd2/transaction.c +++ b/fs/jbd2/transaction.c | |||
@@ -1547,36 +1547,6 @@ out: | |||
1547 | return; | 1547 | return; |
1548 | } | 1548 | } |
1549 | 1549 | ||
1550 | /* | ||
1551 | * jbd2_journal_try_to_free_buffers() could race with | ||
1552 | * jbd2_journal_commit_transaction(). The later might still hold the | ||
1553 | * reference count to the buffers when inspecting them on | ||
1554 | * t_syncdata_list or t_locked_list. | ||
1555 | * | ||
1556 | * jbd2_journal_try_to_free_buffers() will call this function to | ||
1557 | * wait for the current transaction to finish syncing data buffers, before | ||
1558 | * try to free that buffer. | ||
1559 | * | ||
1560 | * Called with journal->j_state_lock hold. | ||
1561 | */ | ||
1562 | static void jbd2_journal_wait_for_transaction_sync_data(journal_t *journal) | ||
1563 | { | ||
1564 | transaction_t *transaction; | ||
1565 | tid_t tid; | ||
1566 | |||
1567 | spin_lock(&journal->j_state_lock); | ||
1568 | transaction = journal->j_committing_transaction; | ||
1569 | |||
1570 | if (!transaction) { | ||
1571 | spin_unlock(&journal->j_state_lock); | ||
1572 | return; | ||
1573 | } | ||
1574 | |||
1575 | tid = transaction->t_tid; | ||
1576 | spin_unlock(&journal->j_state_lock); | ||
1577 | jbd2_log_wait_commit(journal, tid); | ||
1578 | } | ||
1579 | |||
1580 | /** | 1550 | /** |
1581 | * int jbd2_journal_try_to_free_buffers() - try to free page buffers. | 1551 | * int jbd2_journal_try_to_free_buffers() - try to free page buffers. |
1582 | * @journal: journal for operation | 1552 | * @journal: journal for operation |
@@ -1649,25 +1619,6 @@ int jbd2_journal_try_to_free_buffers(journal_t *journal, | |||
1649 | 1619 | ||
1650 | ret = try_to_free_buffers(page); | 1620 | ret = try_to_free_buffers(page); |
1651 | 1621 | ||
1652 | /* | ||
1653 | * There are a number of places where jbd2_journal_try_to_free_buffers() | ||
1654 | * could race with jbd2_journal_commit_transaction(), the later still | ||
1655 | * holds the reference to the buffers to free while processing them. | ||
1656 | * try_to_free_buffers() failed to free those buffers. Some of the | ||
1657 | * caller of releasepage() request page buffers to be dropped, otherwise | ||
1658 | * treat the fail-to-free as errors (such as generic_file_direct_IO()) | ||
1659 | * | ||
1660 | * So, if the caller of try_to_release_page() wants the synchronous | ||
1661 | * behaviour(i.e make sure buffers are dropped upon return), | ||
1662 | * let's wait for the current transaction to finish flush of | ||
1663 | * dirty data buffers, then try to free those buffers again, | ||
1664 | * with the journal locked. | ||
1665 | */ | ||
1666 | if (ret == 0 && (gfp_mask & __GFP_WAIT) && (gfp_mask & __GFP_FS)) { | ||
1667 | jbd2_journal_wait_for_transaction_sync_data(journal); | ||
1668 | ret = try_to_free_buffers(page); | ||
1669 | } | ||
1670 | |||
1671 | busy: | 1622 | busy: |
1672 | return ret; | 1623 | return ret; |
1673 | } | 1624 | } |