aboutsummaryrefslogtreecommitdiffstats
path: root/fs/jbd2/journal.c
diff options
context:
space:
mode:
Diffstat (limited to 'fs/jbd2/journal.c')
-rw-r--r--fs/jbd2/journal.c77
1 files changed, 73 insertions, 4 deletions
diff --git a/fs/jbd2/journal.c b/fs/jbd2/journal.c
index 58144102bf25..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>
@@ -1781,7 +1785,7 @@ int jbd2_journal_wipe(journal_t *journal, int write)
1781 * Journal abort has very specific semantics, which we describe 1785 * Journal abort has very specific semantics, which we describe
1782 * for journal abort. 1786 * for journal abort.
1783 * 1787 *
1784 * Two internal function, which provide abort to te jbd layer 1788 * Two internal functions, which provide abort to the jbd layer
1785 * itself are here. 1789 * itself are here.
1786 */ 1790 */
1787 1791
@@ -1879,7 +1883,7 @@ void jbd2_journal_abort(journal_t *journal, int errno)
1879 * int jbd2_journal_errno () - returns the journal's error state. 1883 * int jbd2_journal_errno () - returns the journal's error state.
1880 * @journal: journal to examine. 1884 * @journal: journal to examine.
1881 * 1885 *
1882 * This is the errno numbet set with jbd2_journal_abort(), the last 1886 * This is the errno number set with jbd2_journal_abort(), the last
1883 * time the journal was mounted - if the journal was stopped 1887 * time the journal was mounted - if the journal was stopped
1884 * without calling abort this will be 0. 1888 * without calling abort this will be 0.
1885 * 1889 *
@@ -1903,7 +1907,7 @@ int jbd2_journal_errno(journal_t *journal)
1903 * int jbd2_journal_clear_err () - clears the journal's error state 1907 * int jbd2_journal_clear_err () - clears the journal's error state
1904 * @journal: journal to act on. 1908 * @journal: journal to act on.
1905 * 1909 *
1906 * An error must be cleared or Acked to take a FS out of readonly 1910 * An error must be cleared or acked to take a FS out of readonly
1907 * mode. 1911 * mode.
1908 */ 1912 */
1909int jbd2_journal_clear_err(journal_t *journal) 1913int jbd2_journal_clear_err(journal_t *journal)
@@ -1923,7 +1927,7 @@ int jbd2_journal_clear_err(journal_t *journal)
1923 * void jbd2_journal_ack_err() - Ack journal err. 1927 * void jbd2_journal_ack_err() - Ack journal err.
1924 * @journal: journal to act on. 1928 * @journal: journal to act on.
1925 * 1929 *
1926 * An error must be cleared or Acked to take a FS out of readonly 1930 * An error must be cleared or acked to take a FS out of readonly
1927 * mode. 1931 * mode.
1928 */ 1932 */
1929void jbd2_journal_ack_err(journal_t *journal) 1933void jbd2_journal_ack_err(journal_t *journal)
@@ -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 */
2394struct devname_cache {
2395 struct rcu_head rcu;
2396 dev_t device;
2397 char devname[BDEVNAME_SIZE];
2398};
2399#define CACHE_SIZE_BITS 6
2400static struct devname_cache *devcache[1 << CACHE_SIZE_BITS];
2401static DEFINE_SPINLOCK(devname_cache_lock);
2402
2403static void free_devcache(struct rcu_head *rcu)
2404{
2405 kfree(rcu);
2406}
2407
2408const 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}
2447EXPORT_SYMBOL(jbd2_dev_to_name);
2448
2380MODULE_LICENSE("GPL"); 2449MODULE_LICENSE("GPL");
2381module_init(journal_init); 2450module_init(journal_init);
2382module_exit(journal_exit); 2451module_exit(journal_exit);