aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorPeter Zijlstra <a.p.zijlstra@chello.nl>2007-10-17 02:25:45 -0400
committerLinus Torvalds <torvalds@woody.linux-foundation.org>2007-10-17 11:42:44 -0400
commit833f4077bf7c2dcff6e31526e03ec2ad91c88581 (patch)
tree80916540be846267342c3e5e4a6255c2c18b44d5
parentbf1d89c81352f6eca72d0c10cfee3dba29ef5efb (diff)
lib: percpu_counter_init error handling
alloc_percpu can fail, propagate that error. Signed-off-by: Peter Zijlstra <a.p.zijlstra@chello.nl> Signed-off-by: Andrew Morton <akpm@linux-foundation.org> Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
-rw-r--r--fs/ext2/super.c15
-rw-r--r--fs/ext3/super.c21
-rw-r--r--fs/ext4/super.c21
-rw-r--r--include/linux/percpu_counter.h5
-rw-r--r--lib/percpu_counter.c8
5 files changed, 52 insertions, 18 deletions
diff --git a/fs/ext2/super.c b/fs/ext2/super.c
index 639a32c3c9c1..2690e460f2ef 100644
--- a/fs/ext2/super.c
+++ b/fs/ext2/super.c
@@ -653,6 +653,7 @@ static int ext2_fill_super(struct super_block *sb, void *data, int silent)
653 int db_count; 653 int db_count;
654 int i, j; 654 int i, j;
655 __le32 features; 655 __le32 features;
656 int err;
656 657
657 sbi = kzalloc(sizeof(*sbi), GFP_KERNEL); 658 sbi = kzalloc(sizeof(*sbi), GFP_KERNEL);
658 if (!sbi) 659 if (!sbi)
@@ -906,12 +907,20 @@ static int ext2_fill_super(struct super_block *sb, void *data, int silent)
906 get_random_bytes(&sbi->s_next_generation, sizeof(u32)); 907 get_random_bytes(&sbi->s_next_generation, sizeof(u32));
907 spin_lock_init(&sbi->s_next_gen_lock); 908 spin_lock_init(&sbi->s_next_gen_lock);
908 909
909 percpu_counter_init(&sbi->s_freeblocks_counter, 910 err = percpu_counter_init(&sbi->s_freeblocks_counter,
910 ext2_count_free_blocks(sb)); 911 ext2_count_free_blocks(sb));
911 percpu_counter_init(&sbi->s_freeinodes_counter, 912 if (!err) {
913 err = percpu_counter_init(&sbi->s_freeinodes_counter,
912 ext2_count_free_inodes(sb)); 914 ext2_count_free_inodes(sb));
913 percpu_counter_init(&sbi->s_dirs_counter, 915 }
916 if (!err) {
917 err = percpu_counter_init(&sbi->s_dirs_counter,
914 ext2_count_dirs(sb)); 918 ext2_count_dirs(sb));
919 }
920 if (err) {
921 printk(KERN_ERR "EXT2-fs: insufficient memory\n");
922 goto failed_mount3;
923 }
915 /* 924 /*
916 * set up enough so that it can read an inode 925 * set up enough so that it can read an inode
917 */ 926 */
diff --git a/fs/ext3/super.c b/fs/ext3/super.c
index c5a52c9775a0..ac5c6b0ecd64 100644
--- a/fs/ext3/super.c
+++ b/fs/ext3/super.c
@@ -1416,6 +1416,7 @@ static int ext3_fill_super (struct super_block *sb, void *data, int silent)
1416 int i; 1416 int i;
1417 int needs_recovery; 1417 int needs_recovery;
1418 __le32 features; 1418 __le32 features;
1419 int err;
1419 1420
1420 sbi = kzalloc(sizeof(*sbi), GFP_KERNEL); 1421 sbi = kzalloc(sizeof(*sbi), GFP_KERNEL);
1421 if (!sbi) 1422 if (!sbi)
@@ -1675,12 +1676,20 @@ static int ext3_fill_super (struct super_block *sb, void *data, int silent)
1675 get_random_bytes(&sbi->s_next_generation, sizeof(u32)); 1676 get_random_bytes(&sbi->s_next_generation, sizeof(u32));
1676 spin_lock_init(&sbi->s_next_gen_lock); 1677 spin_lock_init(&sbi->s_next_gen_lock);
1677 1678
1678 percpu_counter_init(&sbi->s_freeblocks_counter, 1679 err = percpu_counter_init(&sbi->s_freeblocks_counter,
1679 ext3_count_free_blocks(sb)); 1680 ext3_count_free_blocks(sb));
1680 percpu_counter_init(&sbi->s_freeinodes_counter, 1681 if (!err) {
1681 ext3_count_free_inodes(sb)); 1682 err = percpu_counter_init(&sbi->s_freeinodes_counter,
1682 percpu_counter_init(&sbi->s_dirs_counter, 1683 ext3_count_free_inodes(sb));
1683 ext3_count_dirs(sb)); 1684 }
1685 if (!err) {
1686 err = percpu_counter_init(&sbi->s_dirs_counter,
1687 ext3_count_dirs(sb));
1688 }
1689 if (err) {
1690 printk(KERN_ERR "EXT3-fs: insufficient memory\n");
1691 goto failed_mount3;
1692 }
1684 1693
1685 /* per fileystem reservation list head & lock */ 1694 /* per fileystem reservation list head & lock */
1686 spin_lock_init(&sbi->s_rsv_window_lock); 1695 spin_lock_init(&sbi->s_rsv_window_lock);
diff --git a/fs/ext4/super.c b/fs/ext4/super.c
index 1814d4b8ff1f..157c64c9a4e7 100644
--- a/fs/ext4/super.c
+++ b/fs/ext4/super.c
@@ -1479,6 +1479,7 @@ static int ext4_fill_super (struct super_block *sb, void *data, int silent)
1479 int needs_recovery; 1479 int needs_recovery;
1480 __le32 features; 1480 __le32 features;
1481 __u64 blocks_count; 1481 __u64 blocks_count;
1482 int err;
1482 1483
1483 sbi = kzalloc(sizeof(*sbi), GFP_KERNEL); 1484 sbi = kzalloc(sizeof(*sbi), GFP_KERNEL);
1484 if (!sbi) 1485 if (!sbi)
@@ -1759,12 +1760,20 @@ static int ext4_fill_super (struct super_block *sb, void *data, int silent)
1759 get_random_bytes(&sbi->s_next_generation, sizeof(u32)); 1760 get_random_bytes(&sbi->s_next_generation, sizeof(u32));
1760 spin_lock_init(&sbi->s_next_gen_lock); 1761 spin_lock_init(&sbi->s_next_gen_lock);
1761 1762
1762 percpu_counter_init(&sbi->s_freeblocks_counter, 1763 err = percpu_counter_init(&sbi->s_freeblocks_counter,
1763 ext4_count_free_blocks(sb)); 1764 ext4_count_free_blocks(sb));
1764 percpu_counter_init(&sbi->s_freeinodes_counter, 1765 if (!err) {
1765 ext4_count_free_inodes(sb)); 1766 err = percpu_counter_init(&sbi->s_freeinodes_counter,
1766 percpu_counter_init(&sbi->s_dirs_counter, 1767 ext4_count_free_inodes(sb));
1767 ext4_count_dirs(sb)); 1768 }
1769 if (!err) {
1770 err = percpu_counter_init(&sbi->s_dirs_counter,
1771 ext4_count_dirs(sb));
1772 }
1773 if (err) {
1774 printk(KERN_ERR "EXT4-fs: insufficient memory\n");
1775 goto failed_mount3;
1776 }
1768 1777
1769 /* per fileystem reservation list head & lock */ 1778 /* per fileystem reservation list head & lock */
1770 spin_lock_init(&sbi->s_rsv_window_lock); 1779 spin_lock_init(&sbi->s_rsv_window_lock);
diff --git a/include/linux/percpu_counter.h b/include/linux/percpu_counter.h
index 21e054595bcb..f7ecd38d7e9c 100644
--- a/include/linux/percpu_counter.h
+++ b/include/linux/percpu_counter.h
@@ -30,7 +30,7 @@ struct percpu_counter {
30#define FBC_BATCH (NR_CPUS*4) 30#define FBC_BATCH (NR_CPUS*4)
31#endif 31#endif
32 32
33void percpu_counter_init(struct percpu_counter *fbc, s64 amount); 33int percpu_counter_init(struct percpu_counter *fbc, s64 amount);
34void percpu_counter_destroy(struct percpu_counter *fbc); 34void percpu_counter_destroy(struct percpu_counter *fbc);
35void percpu_counter_set(struct percpu_counter *fbc, s64 amount); 35void percpu_counter_set(struct percpu_counter *fbc, s64 amount);
36void __percpu_counter_add(struct percpu_counter *fbc, s64 amount, s32 batch); 36void __percpu_counter_add(struct percpu_counter *fbc, s64 amount, s32 batch);
@@ -78,9 +78,10 @@ struct percpu_counter {
78 s64 count; 78 s64 count;
79}; 79};
80 80
81static inline void percpu_counter_init(struct percpu_counter *fbc, s64 amount) 81static inline int percpu_counter_init(struct percpu_counter *fbc, s64 amount)
82{ 82{
83 fbc->count = amount; 83 fbc->count = amount;
84 return 0;
84} 85}
85 86
86static inline void percpu_counter_destroy(struct percpu_counter *fbc) 87static inline void percpu_counter_destroy(struct percpu_counter *fbc)
diff --git a/lib/percpu_counter.c b/lib/percpu_counter.c
index 3b0ed80c1efd..3a59d84b2d1e 100644
--- a/lib/percpu_counter.c
+++ b/lib/percpu_counter.c
@@ -68,21 +68,27 @@ s64 __percpu_counter_sum(struct percpu_counter *fbc)
68} 68}
69EXPORT_SYMBOL(__percpu_counter_sum); 69EXPORT_SYMBOL(__percpu_counter_sum);
70 70
71void percpu_counter_init(struct percpu_counter *fbc, s64 amount) 71int percpu_counter_init(struct percpu_counter *fbc, s64 amount)
72{ 72{
73 spin_lock_init(&fbc->lock); 73 spin_lock_init(&fbc->lock);
74 fbc->count = amount; 74 fbc->count = amount;
75 fbc->counters = alloc_percpu(s32); 75 fbc->counters = alloc_percpu(s32);
76 if (!fbc->counters)
77 return -ENOMEM;
76#ifdef CONFIG_HOTPLUG_CPU 78#ifdef CONFIG_HOTPLUG_CPU
77 mutex_lock(&percpu_counters_lock); 79 mutex_lock(&percpu_counters_lock);
78 list_add(&fbc->list, &percpu_counters); 80 list_add(&fbc->list, &percpu_counters);
79 mutex_unlock(&percpu_counters_lock); 81 mutex_unlock(&percpu_counters_lock);
80#endif 82#endif
83 return 0;
81} 84}
82EXPORT_SYMBOL(percpu_counter_init); 85EXPORT_SYMBOL(percpu_counter_init);
83 86
84void percpu_counter_destroy(struct percpu_counter *fbc) 87void percpu_counter_destroy(struct percpu_counter *fbc)
85{ 88{
89 if (!fbc->counters)
90 return;
91
86 free_percpu(fbc->counters); 92 free_percpu(fbc->counters);
87#ifdef CONFIG_HOTPLUG_CPU 93#ifdef CONFIG_HOTPLUG_CPU
88 mutex_lock(&percpu_counters_lock); 94 mutex_lock(&percpu_counters_lock);