[Devel] [PATCH rh7 v3] ext4: add generic uevent infrastructure
Konstantin Khorenko
khorenko at virtuozzo.com
Tue Jun 20 19:49:58 MSK 2017
Kirill, Andrey, what is about Dima's comment?
> +int ext4_send_uevent(struct super_block *sb, enum ext4_event_type action)
> +{
> + int ret;
> + struct kobj_uevent_env *env;
> + const u8 *uuid = sb->s_uuid;
> + enum kobject_action kaction = KOBJ_CHANGE;
> +
> + env = kzalloc(sizeof(struct kobj_uevent_env), GFP_KERNEL);
Please change GFP_KERNEL to GFP_NOFS otherwise it may deadlock.
--
Best regards,
Konstantin Khorenko,
Virtuozzo Linux Kernel Team
On 06/16/2017 10:46 AM, Dmitry Monakhov wrote:
> Andrey Ryabinin <aryabinin at virtuozzo.com> writes:
>
>> From: Dmitry Monakhov <dmonakhov at openvz.org>
>>
>> *Purpose:
>> It is reasonable to annaunce fs related events via uevent infrastructure.
>> This patch implement only ext4'th part, but IMHO this should be usefull for
>> any generic filesystem.
>>
>> Example: Runtime fs-error is pure async event. Currently there is no good
>> way to handle this situation and inform user-space about this.
>>
>> *Implementation:
>> Add uevent infrastructure similar to dm uevent
>> FS_ACTION = {MOUNT|UMOUNT|REMOUNT|ERROR|FREEZE|UNFREEZE}
>> FS_UUID
>> FS_NAME
>> FS_TYPE
>>
>> Signed-off-by: Dmitry Monakhov <dmonakhov at openvz.org>
> Only one note about mem allocation context, see below. Otherwise looks good.
>>
>> https://jira.sw.ru/browse/PSBM-66618
>> Signed-off-by: Andrey Ryabinin <aryabinin at virtuozzo.com>
>> ---
>> Changes since v2:
>> - Report error event only once per superblock
>>
>> fs/ext4/ext4.h | 11 ++++++++
>> fs/ext4/super.c | 88 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++-
>> 2 files changed, 98 insertions(+), 1 deletion(-)
>>
>> diff --git a/fs/ext4/ext4.h b/fs/ext4/ext4.h
>> index 1cd964870da3..ce60718c7143 100644
>> --- a/fs/ext4/ext4.h
>> +++ b/fs/ext4/ext4.h
>> @@ -1356,6 +1356,8 @@ struct ext4_sb_info {
>> /* Precomputed FS UUID checksum for seeding other checksums */
>> __u32 s_csum_seed;
>>
>> + bool s_err_event_sent;
>> +
>> /* Reclaim extents from extent status tree */
>> struct shrinker s_es_shrinker;
>> struct list_head s_es_lru;
>> @@ -2758,6 +2760,15 @@ extern int ext4_check_blockref(const char *, unsigned int,
>> struct ext4_ext_path;
>> struct ext4_extent;
>>
>> +enum ext4_event_type {
>> + EXT4_UA_MOUNT,
>> + EXT4_UA_UMOUNT,
>> + EXT4_UA_REMOUNT,
>> + EXT4_UA_ERROR,
>> + EXT4_UA_FREEZE,
>> + EXT4_UA_UNFREEZE,
>> +};
>> +
>> /*
>> * Maximum number of logical blocks in a file; ext4_extent's ee_block is
>> * __le32.
>> diff --git a/fs/ext4/super.c b/fs/ext4/super.c
>> index ee065861b62a..088313b6333f 100644
>> --- a/fs/ext4/super.c
>> +++ b/fs/ext4/super.c
>> @@ -301,6 +301,79 @@ void ext4_itable_unused_set(struct super_block *sb,
>> bg->bg_itable_unused_hi = cpu_to_le16(count >> 16);
>> }
>>
>> +static int ext4_uuid_valid(const u8 *uuid)
>> +{
>> + int i;
>> +
>> + for (i = 0; i < 16; i++) {
>> + if (uuid[i])
>> + return 1;
>> + }
>> + return 0;
>> +}
>> +
>> +/**
>> + * ext4_send_uevent - prepare and send uevent
>> + *
>> + * @sb: super_block
>> + * @action: action type
>> + *
>> + */
>> +int ext4_send_uevent(struct super_block *sb, enum ext4_event_type action)
>> +{
>> + int ret;
>> + struct kobj_uevent_env *env;
>> + const u8 *uuid = sb->s_uuid;
>> + enum kobject_action kaction = KOBJ_CHANGE;
>> +
>> + env = kzalloc(sizeof(struct kobj_uevent_env), GFP_KERNEL);
> Please change GFP_KERNEL to GFP_NOFS otherwise it may deadlock.
>> + if (!env)
>> + return -ENOMEM;
>> +
>> + ret = add_uevent_var(env, "FS_TYPE=%s", sb->s_type->name);
>> + if (ret)
>> + goto out;
>> + ret = add_uevent_var(env, "FS_NAME=%s", sb->s_id);
>> + if (ret)
>> + goto out;
>> +
>> + if (ext4_uuid_valid(uuid)) {
>> + ret = add_uevent_var(env, "UUID=%pUB", uuid);
>> + if (ret)
>> + goto out;
>> + }
>> +
>> + switch (action) {
>> + case EXT4_UA_MOUNT:
>> + kaction = KOBJ_ONLINE;
>> + ret = add_uevent_var(env, "FS_ACTION=%s", "MOUNT");
>> + break;
>> + case EXT4_UA_UMOUNT:
>> + kaction = KOBJ_OFFLINE;
>> + ret = add_uevent_var(env, "FS_ACTION=%s", "UMOUNT");
>> + break;
>> + case EXT4_UA_REMOUNT:
>> + ret = add_uevent_var(env, "FS_ACTION=%s", "REMOUNT");
>> + break;
>> + case EXT4_UA_ERROR:
>> + ret = add_uevent_var(env, "FS_ACTION=%s", "ERROR");
>> + break;
>> + case EXT4_UA_FREEZE:
>> + ret = add_uevent_var(env, "FS_ACTION=%s", "FREEZE");
>> + break;
>> + case EXT4_UA_UNFREEZE:
>> + ret = add_uevent_var(env, "FS_ACTION=%s", "UNFREEZE");
>> + break;
>> + default:
>> + ret = -EINVAL;
>> + }
>> + if (ret)
>> + goto out;
>> + ret = kobject_uevent_env(&(EXT4_SB(sb)->s_kobj), kaction, env->envp);
>> +out:
>> + kfree(env);
>> + return ret;
>> +}
>>
>> static void __save_error_info(struct super_block *sb, const char *func,
>> unsigned int line)
>> @@ -389,6 +462,9 @@ static void ext4_journal_commit_callback(journal_t *journal, transaction_t *txn)
>>
>> static void ext4_handle_error(struct super_block *sb)
>> {
>> + if (!xchg(&EXT4_SB(sb)->s_err_event_sent, 1))
>> + ext4_send_uevent(sb, EXT4_UA_ERROR);
>> +
>> if (sb->s_flags & MS_RDONLY)
>> return;
>>
>> @@ -780,6 +856,7 @@ static void ext4_put_super(struct super_block *sb)
>> struct ext4_super_block *es = sbi->s_es;
>> int i, err;
>>
>> + ext4_send_uevent(sb, EXT4_UA_UMOUNT);
>> ext4_unregister_li_request(sb);
>> dquot_disable(sb, -1, DQUOT_USAGE_ENABLED | DQUOT_LIMITS_ENABLED);
>>
>> @@ -4463,6 +4540,7 @@ no_journal:
>> ratelimit_state_init(&sbi->s_warning_ratelimit_state, 5 * HZ, 10);
>> ratelimit_state_init(&sbi->s_msg_ratelimit_state, 5 * HZ, 10);
>>
>> + ext4_send_uevent(sb, EXT4_UA_MOUNT);
>> kfree(orig_data);
>> return 0;
>>
>> @@ -5011,8 +5089,10 @@ static int ext4_freeze(struct super_block *sb)
>> int error = 0;
>> journal_t *journal;
>>
>> - if (sb->s_flags & MS_RDONLY)
>> + if (sb->s_flags & MS_RDONLY) {
>> + ext4_send_uevent(sb, EXT4_UA_FREEZE);
>> return 0;
>> + }
>>
>> journal = EXT4_SB(sb)->s_journal;
>>
>> @@ -5033,6 +5113,9 @@ static int ext4_freeze(struct super_block *sb)
>> out:
>> /* we rely on upper layer to stop further updates */
>> jbd2_journal_unlock_updates(EXT4_SB(sb)->s_journal);
>> + if (!error)
>> + ext4_send_uevent(sb, EXT4_UA_FREEZE);
>> +
>> return error;
>> }
>>
>> @@ -5042,6 +5125,8 @@ out:
>> */
>> static int ext4_unfreeze(struct super_block *sb)
>> {
>> + ext4_send_uevent(sb, EXT4_UA_UNFREEZE);
>> +
>> if (sb->s_flags & MS_RDONLY)
>> return 0;
>>
>> @@ -5287,6 +5372,7 @@ static int ext4_remount(struct super_block *sb, int *flags, char *data)
>>
>> *flags = (*flags & ~MS_LAZYTIME) | (sb->s_flags & MS_LAZYTIME);
>> ext4_msg(sb, KERN_INFO, "re-mounted. Opts: %s", orig_data);
>> + ext4_send_uevent(sb, EXT4_UA_REMOUNT);
>> kfree(orig_data);
>> return 0;
>>
>> --
>> 2.13.0
> _______________________________________________
> Devel mailing list
> Devel at openvz.org
> https://lists.openvz.org/mailman/listinfo/devel
> .
>
More information about the Devel
mailing list