aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorAlexey Dobriyan <adobriyan@gmail.com>2008-09-14 10:21:33 -0400
committerTheodore Ts'o <tytso@mit.edu>2008-09-14 10:21:33 -0400
commit899fc1a4cf404747de2666534d508804597ee22f (patch)
tree4d3079f33198272fe0dfc6a08fe63dad659a374e
parentc62a11fd9555007b1caab83b5bcbb443a43e32bb (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.c16
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
2807err_out: 2813err_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;
2822err_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:
2821static int ext4_mb_destroy_per_dev_proc(struct super_block *sb) 2828static 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);