diff options
author | Alexey Dobriyan <adobriyan@gmail.com> | 2008-09-14 10:21:33 -0400 |
---|---|---|
committer | Theodore Ts'o <tytso@mit.edu> | 2008-09-14 10:21:33 -0400 |
commit | 899fc1a4cf404747de2666534d508804597ee22f (patch) | |
tree | 4d3079f33198272fe0dfc6a08fe63dad659a374e | |
parent | c62a11fd9555007b1caab83b5bcbb443a43e32bb (diff) |
ext4: fix #11321: create /proc/ext4/*/stats more carefully
ext4 creates per-suberblock directory in /proc/ext4/ . Name used as
basis is taken from bdevname, which, surprise, can contain slash.
However, proc while allowing to use proc_create("a/b", parent) form of
PDE creation, assumes that parent/a was already created.
bdevname in question is 'cciss/c0d0p9', directory is not created and all
this stuff goes directly into /proc (which is real bug).
Warning comes when _second_ partition is mounted.
http://bugzilla.kernel.org/show_bug.cgi?id=11321
Signed-off-by: Alexey Dobriyan <adobriyan@gmail.com>
Signed-off-by: "Theodore Ts'o" <tytso@mit.edu>
-rw-r--r-- | fs/ext4/mballoc.c | 16 |
1 files changed, 13 insertions, 3 deletions
diff --git a/fs/ext4/mballoc.c b/fs/ext4/mballoc.c index 585c25950184..9122271e3d65 100644 --- a/fs/ext4/mballoc.c +++ b/fs/ext4/mballoc.c | |||
@@ -2786,14 +2786,20 @@ static int ext4_mb_init_per_dev_proc(struct super_block *sb) | |||
2786 | mode_t mode = S_IFREG | S_IRUGO | S_IWUSR; | 2786 | mode_t mode = S_IFREG | S_IRUGO | S_IWUSR; |
2787 | struct ext4_sb_info *sbi = EXT4_SB(sb); | 2787 | struct ext4_sb_info *sbi = EXT4_SB(sb); |
2788 | struct proc_dir_entry *proc; | 2788 | struct proc_dir_entry *proc; |
2789 | char devname[64]; | 2789 | char devname[BDEVNAME_SIZE], *p; |
2790 | 2790 | ||
2791 | if (proc_root_ext4 == NULL) { | 2791 | if (proc_root_ext4 == NULL) { |
2792 | sbi->s_mb_proc = NULL; | 2792 | sbi->s_mb_proc = NULL; |
2793 | return -EINVAL; | 2793 | return -EINVAL; |
2794 | } | 2794 | } |
2795 | bdevname(sb->s_bdev, devname); | 2795 | bdevname(sb->s_bdev, devname); |
2796 | p = devname; | ||
2797 | while ((p = strchr(p, '/'))) | ||
2798 | *p = '!'; | ||
2799 | |||
2796 | sbi->s_mb_proc = proc_mkdir(devname, proc_root_ext4); | 2800 | sbi->s_mb_proc = proc_mkdir(devname, proc_root_ext4); |
2801 | if (!sbi->s_mb_proc) | ||
2802 | goto err_create_dir; | ||
2797 | 2803 | ||
2798 | MB_PROC_HANDLER(EXT4_MB_STATS_NAME, stats); | 2804 | MB_PROC_HANDLER(EXT4_MB_STATS_NAME, stats); |
2799 | MB_PROC_HANDLER(EXT4_MB_MAX_TO_SCAN_NAME, max_to_scan); | 2805 | MB_PROC_HANDLER(EXT4_MB_MAX_TO_SCAN_NAME, max_to_scan); |
@@ -2805,7 +2811,6 @@ static int ext4_mb_init_per_dev_proc(struct super_block *sb) | |||
2805 | return 0; | 2811 | return 0; |
2806 | 2812 | ||
2807 | err_out: | 2813 | err_out: |
2808 | printk(KERN_ERR "EXT4-fs: Unable to create %s\n", devname); | ||
2809 | remove_proc_entry(EXT4_MB_GROUP_PREALLOC, sbi->s_mb_proc); | 2814 | remove_proc_entry(EXT4_MB_GROUP_PREALLOC, sbi->s_mb_proc); |
2810 | remove_proc_entry(EXT4_MB_STREAM_REQ, sbi->s_mb_proc); | 2815 | remove_proc_entry(EXT4_MB_STREAM_REQ, sbi->s_mb_proc); |
2811 | remove_proc_entry(EXT4_MB_ORDER2_REQ, sbi->s_mb_proc); | 2816 | remove_proc_entry(EXT4_MB_ORDER2_REQ, sbi->s_mb_proc); |
@@ -2814,6 +2819,8 @@ err_out: | |||
2814 | remove_proc_entry(EXT4_MB_STATS_NAME, sbi->s_mb_proc); | 2819 | remove_proc_entry(EXT4_MB_STATS_NAME, sbi->s_mb_proc); |
2815 | remove_proc_entry(devname, proc_root_ext4); | 2820 | remove_proc_entry(devname, proc_root_ext4); |
2816 | sbi->s_mb_proc = NULL; | 2821 | sbi->s_mb_proc = NULL; |
2822 | err_create_dir: | ||
2823 | printk(KERN_ERR "EXT4-fs: Unable to create %s\n", devname); | ||
2817 | 2824 | ||
2818 | return -ENOMEM; | 2825 | return -ENOMEM; |
2819 | } | 2826 | } |
@@ -2821,12 +2828,15 @@ err_out: | |||
2821 | static int ext4_mb_destroy_per_dev_proc(struct super_block *sb) | 2828 | static int ext4_mb_destroy_per_dev_proc(struct super_block *sb) |
2822 | { | 2829 | { |
2823 | struct ext4_sb_info *sbi = EXT4_SB(sb); | 2830 | struct ext4_sb_info *sbi = EXT4_SB(sb); |
2824 | char devname[64]; | 2831 | char devname[BDEVNAME_SIZE], *p; |
2825 | 2832 | ||
2826 | if (sbi->s_mb_proc == NULL) | 2833 | if (sbi->s_mb_proc == NULL) |
2827 | return -EINVAL; | 2834 | return -EINVAL; |
2828 | 2835 | ||
2829 | bdevname(sb->s_bdev, devname); | 2836 | bdevname(sb->s_bdev, devname); |
2837 | p = devname; | ||
2838 | while ((p = strchr(p, '/'))) | ||
2839 | *p = '!'; | ||
2830 | remove_proc_entry(EXT4_MB_GROUP_PREALLOC, sbi->s_mb_proc); | 2840 | remove_proc_entry(EXT4_MB_GROUP_PREALLOC, sbi->s_mb_proc); |
2831 | remove_proc_entry(EXT4_MB_STREAM_REQ, sbi->s_mb_proc); | 2841 | remove_proc_entry(EXT4_MB_STREAM_REQ, sbi->s_mb_proc); |
2832 | remove_proc_entry(EXT4_MB_ORDER2_REQ, sbi->s_mb_proc); | 2842 | remove_proc_entry(EXT4_MB_ORDER2_REQ, sbi->s_mb_proc); |