|
@@ -258,6 +258,7 @@ static void init_once(void *foo)
|
|
static int parse_options(struct super_block *sb, char *options)
|
|
static int parse_options(struct super_block *sb, char *options)
|
|
{
|
|
{
|
|
struct f2fs_sb_info *sbi = F2FS_SB(sb);
|
|
struct f2fs_sb_info *sbi = F2FS_SB(sb);
|
|
|
|
+ struct request_queue *q;
|
|
substring_t args[MAX_OPT_ARGS];
|
|
substring_t args[MAX_OPT_ARGS];
|
|
char *p, *name;
|
|
char *p, *name;
|
|
int arg = 0;
|
|
int arg = 0;
|
|
@@ -302,7 +303,14 @@ static int parse_options(struct super_block *sb, char *options)
|
|
return -EINVAL;
|
|
return -EINVAL;
|
|
break;
|
|
break;
|
|
case Opt_discard:
|
|
case Opt_discard:
|
|
- set_opt(sbi, DISCARD);
|
|
|
|
|
|
+ q = bdev_get_queue(sb->s_bdev);
|
|
|
|
+ if (blk_queue_discard(q)) {
|
|
|
|
+ set_opt(sbi, DISCARD);
|
|
|
|
+ } else {
|
|
|
|
+ f2fs_msg(sb, KERN_WARNING,
|
|
|
|
+ "mounting with \"discard\" option, but "
|
|
|
|
+ "the device does not support discard");
|
|
|
|
+ }
|
|
break;
|
|
break;
|
|
case Opt_noheap:
|
|
case Opt_noheap:
|
|
set_opt(sbi, NOHEAP);
|
|
set_opt(sbi, NOHEAP);
|
|
@@ -1235,16 +1243,6 @@ try_onemore:
|
|
proc_create_data("segment_info", S_IRUGO, sbi->s_proc,
|
|
proc_create_data("segment_info", S_IRUGO, sbi->s_proc,
|
|
&f2fs_seq_segment_info_fops, sb);
|
|
&f2fs_seq_segment_info_fops, sb);
|
|
|
|
|
|
- if (test_opt(sbi, DISCARD)) {
|
|
|
|
- struct request_queue *q = bdev_get_queue(sb->s_bdev);
|
|
|
|
- if (!blk_queue_discard(q)) {
|
|
|
|
- f2fs_msg(sb, KERN_WARNING,
|
|
|
|
- "mounting with \"discard\" option, but "
|
|
|
|
- "the device does not support discard");
|
|
|
|
- clear_opt(sbi, DISCARD);
|
|
|
|
- }
|
|
|
|
- }
|
|
|
|
-
|
|
|
|
sbi->s_kobj.kset = f2fs_kset;
|
|
sbi->s_kobj.kset = f2fs_kset;
|
|
init_completion(&sbi->s_kobj_unregister);
|
|
init_completion(&sbi->s_kobj_unregister);
|
|
err = kobject_init_and_add(&sbi->s_kobj, &f2fs_ktype, NULL,
|
|
err = kobject_init_and_add(&sbi->s_kobj, &f2fs_ktype, NULL,
|