aboutsummaryrefslogtreecommitdiffstats
path: root/fs/btrfs/super.c
diff options
context:
space:
mode:
Diffstat (limited to 'fs/btrfs/super.c')
-rw-r--r--fs/btrfs/super.c125
1 files changed, 71 insertions, 54 deletions
diff --git a/fs/btrfs/super.c b/fs/btrfs/super.c
index f267718cbd1..96eb9fef7bd 100644
--- a/fs/btrfs/super.c
+++ b/fs/btrfs/super.c
@@ -188,7 +188,8 @@ void btrfs_printk(struct btrfs_fs_info *fs_info, const char *fmt, ...)
188 va_start(args, fmt); 188 va_start(args, fmt);
189 189
190 if (fmt[0] == '<' && isdigit(fmt[1]) && fmt[2] == '>') { 190 if (fmt[0] == '<' && isdigit(fmt[1]) && fmt[2] == '>') {
191 strncpy(lvl, fmt, 3); 191 memcpy(lvl, fmt, 3);
192 lvl[3] = '\0';
192 fmt += 3; 193 fmt += 3;
193 type = logtypes[fmt[1] - '0']; 194 type = logtypes[fmt[1] - '0'];
194 } else 195 } else
@@ -435,11 +436,8 @@ int btrfs_parse_options(struct btrfs_root *root, char *options)
435 case Opt_thread_pool: 436 case Opt_thread_pool:
436 intarg = 0; 437 intarg = 0;
437 match_int(&args[0], &intarg); 438 match_int(&args[0], &intarg);
438 if (intarg) { 439 if (intarg)
439 info->thread_pool_size = intarg; 440 info->thread_pool_size = intarg;
440 printk(KERN_INFO "btrfs: thread pool %d\n",
441 info->thread_pool_size);
442 }
443 break; 441 break;
444 case Opt_max_inline: 442 case Opt_max_inline:
445 num = match_strdup(&args[0]); 443 num = match_strdup(&args[0]);
@@ -755,7 +753,6 @@ static int btrfs_fill_super(struct super_block *sb,
755 void *data, int silent) 753 void *data, int silent)
756{ 754{
757 struct inode *inode; 755 struct inode *inode;
758 struct dentry *root_dentry;
759 struct btrfs_fs_info *fs_info = btrfs_sb(sb); 756 struct btrfs_fs_info *fs_info = btrfs_sb(sb);
760 struct btrfs_key key; 757 struct btrfs_key key;
761 int err; 758 int err;
@@ -770,7 +767,7 @@ static int btrfs_fill_super(struct super_block *sb,
770#ifdef CONFIG_BTRFS_FS_POSIX_ACL 767#ifdef CONFIG_BTRFS_FS_POSIX_ACL
771 sb->s_flags |= MS_POSIXACL; 768 sb->s_flags |= MS_POSIXACL;
772#endif 769#endif
773 770 sb->s_flags |= MS_I_VERSION;
774 err = open_ctree(sb, fs_devices, (char *)data); 771 err = open_ctree(sb, fs_devices, (char *)data);
775 if (err) { 772 if (err) {
776 printk("btrfs: open_ctree failed\n"); 773 printk("btrfs: open_ctree failed\n");
@@ -786,15 +783,12 @@ static int btrfs_fill_super(struct super_block *sb,
786 goto fail_close; 783 goto fail_close;
787 } 784 }
788 785
789 root_dentry = d_alloc_root(inode); 786 sb->s_root = d_make_root(inode);
790 if (!root_dentry) { 787 if (!sb->s_root) {
791 iput(inode);
792 err = -ENOMEM; 788 err = -ENOMEM;
793 goto fail_close; 789 goto fail_close;
794 } 790 }
795 791
796 sb->s_root = root_dentry;
797
798 save_mount_options(sb, data); 792 save_mount_options(sb, data);
799 cleancache_init_fs(sb); 793 cleancache_init_fs(sb);
800 sb->s_flags |= MS_ACTIVE; 794 sb->s_flags |= MS_ACTIVE;
@@ -929,63 +923,48 @@ static inline int is_subvolume_inode(struct inode *inode)
929 */ 923 */
930static char *setup_root_args(char *args) 924static char *setup_root_args(char *args)
931{ 925{
932 unsigned copied = 0; 926 unsigned len = strlen(args) + 2 + 1;
933 unsigned len = strlen(args) + 2; 927 char *src, *dst, *buf;
934 char *pos;
935 char *ret;
936 928
937 /* 929 /*
938 * We need the same args as before, but minus 930 * We need the same args as before, but with this substitution:
939 * 931 * s!subvol=[^,]+!subvolid=0!
940 * subvol=a
941 *
942 * and add
943 * 932 *
944 * subvolid=0 933 * Since the replacement string is up to 2 bytes longer than the
945 * 934 * original, allocate strlen(args) + 2 + 1 bytes.
946 * which is a difference of 2 characters, so we allocate strlen(args) +
947 * 2 characters.
948 */ 935 */
949 ret = kzalloc(len * sizeof(char), GFP_NOFS);
950 if (!ret)
951 return NULL;
952 pos = strstr(args, "subvol=");
953 936
937 src = strstr(args, "subvol=");
954 /* This shouldn't happen, but just in case.. */ 938 /* This shouldn't happen, but just in case.. */
955 if (!pos) { 939 if (!src)
956 kfree(ret); 940 return NULL;
941
942 buf = dst = kmalloc(len, GFP_NOFS);
943 if (!buf)
957 return NULL; 944 return NULL;
958 }
959 945
960 /* 946 /*
961 * The subvol=<> arg is not at the front of the string, copy everybody 947 * If the subvol= arg is not at the start of the string,
962 * up to that into ret. 948 * copy whatever precedes it into buf.
963 */ 949 */
964 if (pos != args) { 950 if (src != args) {
965 *pos = '\0'; 951 *src++ = '\0';
966 strcpy(ret, args); 952 strcpy(buf, args);
967 copied += strlen(args); 953 dst += strlen(args);
968 pos++;
969 } 954 }
970 955
971 strncpy(ret + copied, "subvolid=0", len - copied); 956 strcpy(dst, "subvolid=0");
972 957 dst += strlen("subvolid=0");
973 /* Length of subvolid=0 */
974 copied += 10;
975 958
976 /* 959 /*
977 * If there is no , after the subvol= option then we know there's no 960 * If there is a "," after the original subvol=... string,
978 * other options and we can just return. 961 * copy that suffix into our buffer. Otherwise, we're done.
979 */ 962 */
980 pos = strchr(pos, ','); 963 src = strchr(src, ',');
981 if (!pos) 964 if (src)
982 return ret; 965 strcpy(dst, src);
983
984 /* Copy the rest of the arguments into our buffer */
985 strncpy(ret + copied, pos, len - copied);
986 copied += strlen(pos);
987 966
988 return ret; 967 return buf;
989} 968}
990 969
991static struct dentry *mount_subvol(const char *subvol_name, int flags, 970static struct dentry *mount_subvol(const char *subvol_name, int flags,
@@ -1122,6 +1101,40 @@ error_fs_info:
1122 return ERR_PTR(error); 1101 return ERR_PTR(error);
1123} 1102}
1124 1103
1104static void btrfs_set_max_workers(struct btrfs_workers *workers, int new_limit)
1105{
1106 spin_lock_irq(&workers->lock);
1107 workers->max_workers = new_limit;
1108 spin_unlock_irq(&workers->lock);
1109}
1110
1111static void btrfs_resize_thread_pool(struct btrfs_fs_info *fs_info,
1112 int new_pool_size, int old_pool_size)
1113{
1114 if (new_pool_size == old_pool_size)
1115 return;
1116
1117 fs_info->thread_pool_size = new_pool_size;
1118
1119 printk(KERN_INFO "btrfs: resize thread pool %d -> %d\n",
1120 old_pool_size, new_pool_size);
1121
1122 btrfs_set_max_workers(&fs_info->generic_worker, new_pool_size);
1123 btrfs_set_max_workers(&fs_info->workers, new_pool_size);
1124 btrfs_set_max_workers(&fs_info->delalloc_workers, new_pool_size);
1125 btrfs_set_max_workers(&fs_info->submit_workers, new_pool_size);
1126 btrfs_set_max_workers(&fs_info->caching_workers, new_pool_size);
1127 btrfs_set_max_workers(&fs_info->fixup_workers, new_pool_size);
1128 btrfs_set_max_workers(&fs_info->endio_workers, new_pool_size);
1129 btrfs_set_max_workers(&fs_info->endio_meta_workers, new_pool_size);
1130 btrfs_set_max_workers(&fs_info->endio_meta_write_workers, new_pool_size);
1131 btrfs_set_max_workers(&fs_info->endio_write_workers, new_pool_size);
1132 btrfs_set_max_workers(&fs_info->endio_freespace_worker, new_pool_size);
1133 btrfs_set_max_workers(&fs_info->delayed_workers, new_pool_size);
1134 btrfs_set_max_workers(&fs_info->readahead_workers, new_pool_size);
1135 btrfs_set_max_workers(&fs_info->scrub_workers, new_pool_size);
1136}
1137
1125static int btrfs_remount(struct super_block *sb, int *flags, char *data) 1138static int btrfs_remount(struct super_block *sb, int *flags, char *data)
1126{ 1139{
1127 struct btrfs_fs_info *fs_info = btrfs_sb(sb); 1140 struct btrfs_fs_info *fs_info = btrfs_sb(sb);
@@ -1141,6 +1154,9 @@ static int btrfs_remount(struct super_block *sb, int *flags, char *data)
1141 goto restore; 1154 goto restore;
1142 } 1155 }
1143 1156
1157 btrfs_resize_thread_pool(fs_info,
1158 fs_info->thread_pool_size, old_thread_pool_size);
1159
1144 if ((*flags & MS_RDONLY) == (sb->s_flags & MS_RDONLY)) 1160 if ((*flags & MS_RDONLY) == (sb->s_flags & MS_RDONLY))
1145 return 0; 1161 return 0;
1146 1162
@@ -1184,7 +1200,8 @@ restore:
1184 fs_info->compress_type = old_compress_type; 1200 fs_info->compress_type = old_compress_type;
1185 fs_info->max_inline = old_max_inline; 1201 fs_info->max_inline = old_max_inline;
1186 fs_info->alloc_start = old_alloc_start; 1202 fs_info->alloc_start = old_alloc_start;
1187 fs_info->thread_pool_size = old_thread_pool_size; 1203 btrfs_resize_thread_pool(fs_info,
1204 old_thread_pool_size, fs_info->thread_pool_size);
1188 fs_info->metadata_ratio = old_metadata_ratio; 1205 fs_info->metadata_ratio = old_metadata_ratio;
1189 return ret; 1206 return ret;
1190} 1207}