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.c117
1 files changed, 69 insertions, 48 deletions
diff --git a/fs/btrfs/super.c b/fs/btrfs/super.c
index c5f8fca4195f..96eb9fef7bd2 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]);
@@ -769,7 +767,7 @@ static int btrfs_fill_super(struct super_block *sb,
769#ifdef CONFIG_BTRFS_FS_POSIX_ACL 767#ifdef CONFIG_BTRFS_FS_POSIX_ACL
770 sb->s_flags |= MS_POSIXACL; 768 sb->s_flags |= MS_POSIXACL;
771#endif 769#endif
772 770 sb->s_flags |= MS_I_VERSION;
773 err = open_ctree(sb, fs_devices, (char *)data); 771 err = open_ctree(sb, fs_devices, (char *)data);
774 if (err) { 772 if (err) {
775 printk("btrfs: open_ctree failed\n"); 773 printk("btrfs: open_ctree failed\n");
@@ -925,63 +923,48 @@ static inline int is_subvolume_inode(struct inode *inode)
925 */ 923 */
926static char *setup_root_args(char *args) 924static char *setup_root_args(char *args)
927{ 925{
928 unsigned copied = 0; 926 unsigned len = strlen(args) + 2 + 1;
929 unsigned len = strlen(args) + 2; 927 char *src, *dst, *buf;
930 char *pos;
931 char *ret;
932 928
933 /* 929 /*
934 * We need the same args as before, but minus 930 * We need the same args as before, but with this substitution:
935 * 931 * s!subvol=[^,]+!subvolid=0!
936 * subvol=a
937 *
938 * and add
939 *
940 * subvolid=0
941 * 932 *
942 * which is a difference of 2 characters, so we allocate strlen(args) + 933 * Since the replacement string is up to 2 bytes longer than the
943 * 2 characters. 934 * original, allocate strlen(args) + 2 + 1 bytes.
944 */ 935 */
945 ret = kzalloc(len * sizeof(char), GFP_NOFS);
946 if (!ret)
947 return NULL;
948 pos = strstr(args, "subvol=");
949 936
937 src = strstr(args, "subvol=");
950 /* This shouldn't happen, but just in case.. */ 938 /* This shouldn't happen, but just in case.. */
951 if (!pos) { 939 if (!src)
952 kfree(ret); 940 return NULL;
941
942 buf = dst = kmalloc(len, GFP_NOFS);
943 if (!buf)
953 return NULL; 944 return NULL;
954 }
955 945
956 /* 946 /*
957 * 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,
958 * up to that into ret. 948 * copy whatever precedes it into buf.
959 */ 949 */
960 if (pos != args) { 950 if (src != args) {
961 *pos = '\0'; 951 *src++ = '\0';
962 strcpy(ret, args); 952 strcpy(buf, args);
963 copied += strlen(args); 953 dst += strlen(args);
964 pos++;
965 } 954 }
966 955
967 strncpy(ret + copied, "subvolid=0", len - copied); 956 strcpy(dst, "subvolid=0");
968 957 dst += strlen("subvolid=0");
969 /* Length of subvolid=0 */
970 copied += 10;
971 958
972 /* 959 /*
973 * If there is no , after the subvol= option then we know there's no 960 * If there is a "," after the original subvol=... string,
974 * other options and we can just return. 961 * copy that suffix into our buffer. Otherwise, we're done.
975 */ 962 */
976 pos = strchr(pos, ','); 963 src = strchr(src, ',');
977 if (!pos) 964 if (src)
978 return ret; 965 strcpy(dst, src);
979 966
980 /* Copy the rest of the arguments into our buffer */ 967 return buf;
981 strncpy(ret + copied, pos, len - copied);
982 copied += strlen(pos);
983
984 return ret;
985} 968}
986 969
987static struct dentry *mount_subvol(const char *subvol_name, int flags, 970static struct dentry *mount_subvol(const char *subvol_name, int flags,
@@ -1118,6 +1101,40 @@ error_fs_info:
1118 return ERR_PTR(error); 1101 return ERR_PTR(error);
1119} 1102}
1120 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
1121static int btrfs_remount(struct super_block *sb, int *flags, char *data) 1138static int btrfs_remount(struct super_block *sb, int *flags, char *data)
1122{ 1139{
1123 struct btrfs_fs_info *fs_info = btrfs_sb(sb); 1140 struct btrfs_fs_info *fs_info = btrfs_sb(sb);
@@ -1137,6 +1154,9 @@ static int btrfs_remount(struct super_block *sb, int *flags, char *data)
1137 goto restore; 1154 goto restore;
1138 } 1155 }
1139 1156
1157 btrfs_resize_thread_pool(fs_info,
1158 fs_info->thread_pool_size, old_thread_pool_size);
1159
1140 if ((*flags & MS_RDONLY) == (sb->s_flags & MS_RDONLY)) 1160 if ((*flags & MS_RDONLY) == (sb->s_flags & MS_RDONLY))
1141 return 0; 1161 return 0;
1142 1162
@@ -1180,7 +1200,8 @@ restore:
1180 fs_info->compress_type = old_compress_type; 1200 fs_info->compress_type = old_compress_type;
1181 fs_info->max_inline = old_max_inline; 1201 fs_info->max_inline = old_max_inline;
1182 fs_info->alloc_start = old_alloc_start; 1202 fs_info->alloc_start = old_alloc_start;
1183 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);
1184 fs_info->metadata_ratio = old_metadata_ratio; 1205 fs_info->metadata_ratio = old_metadata_ratio;
1185 return ret; 1206 return ret;
1186} 1207}