|
@@ -2473,6 +2473,23 @@ static ssize_t sbi_ui_store(struct ext4_attr *a,
|
|
|
return count;
|
|
|
}
|
|
|
|
|
|
+static ssize_t trigger_test_error(struct ext4_attr *a,
|
|
|
+ struct ext4_sb_info *sbi,
|
|
|
+ const char *buf, size_t count)
|
|
|
+{
|
|
|
+ int len = count;
|
|
|
+
|
|
|
+ if (!capable(CAP_SYS_ADMIN))
|
|
|
+ return -EPERM;
|
|
|
+
|
|
|
+ if (len && buf[len-1] == '\n')
|
|
|
+ len--;
|
|
|
+
|
|
|
+ if (len)
|
|
|
+ ext4_error(sbi->s_sb, "%.*s", len, buf);
|
|
|
+ return count;
|
|
|
+}
|
|
|
+
|
|
|
#define EXT4_ATTR_OFFSET(_name,_mode,_show,_store,_elname) \
|
|
|
static struct ext4_attr ext4_attr_##_name = { \
|
|
|
.attr = {.name = __stringify(_name), .mode = _mode }, \
|
|
@@ -2503,6 +2520,7 @@ EXT4_RW_ATTR_SBI_UI(mb_order2_req, s_mb_order2_reqs);
|
|
|
EXT4_RW_ATTR_SBI_UI(mb_stream_req, s_mb_stream_request);
|
|
|
EXT4_RW_ATTR_SBI_UI(mb_group_prealloc, s_mb_group_prealloc);
|
|
|
EXT4_RW_ATTR_SBI_UI(max_writeback_mb_bump, s_max_writeback_mb_bump);
|
|
|
+EXT4_ATTR(trigger_fs_error, 0200, NULL, trigger_test_error);
|
|
|
|
|
|
static struct attribute *ext4_attrs[] = {
|
|
|
ATTR_LIST(delayed_allocation_blocks),
|
|
@@ -2517,6 +2535,7 @@ static struct attribute *ext4_attrs[] = {
|
|
|
ATTR_LIST(mb_stream_req),
|
|
|
ATTR_LIST(mb_group_prealloc),
|
|
|
ATTR_LIST(max_writeback_mb_bump),
|
|
|
+ ATTR_LIST(trigger_fs_error),
|
|
|
NULL,
|
|
|
};
|
|
|
|
|
@@ -3087,6 +3106,7 @@ static int ext4_fill_super(struct super_block *sb, void *data, int silent)
|
|
|
goto out_free_orig;
|
|
|
}
|
|
|
sb->s_fs_info = sbi;
|
|
|
+ sbi->s_sb = sb;
|
|
|
sbi->s_mount_opt = 0;
|
|
|
sbi->s_resuid = EXT4_DEF_RESUID;
|
|
|
sbi->s_resgid = EXT4_DEF_RESGID;
|