root/fs/ext4/sysfs.c

/* [<][>][^][v][top][bottom][index][help] */

DEFINITIONS

This source file includes following definitions.
  1. session_write_kbytes_show
  2. lifetime_write_kbytes_show
  3. inode_readahead_blks_store
  4. reserved_clusters_store
  5. trigger_test_error
  6. journal_task_show
  7. calc_ptr
  8. __print_tstamp
  9. ext4_attr_show
  10. ext4_attr_store
  11. ext4_sb_release
  12. ext4_register_sysfs
  13. ext4_unregister_sysfs
  14. ext4_init_sysfs
  15. ext4_exit_sysfs

   1 // SPDX-License-Identifier: GPL-2.0
   2 /*
   3  *  linux/fs/ext4/sysfs.c
   4  *
   5  * Copyright (C) 1992, 1993, 1994, 1995
   6  * Remy Card (card@masi.ibp.fr)
   7  * Theodore Ts'o (tytso@mit.edu)
   8  *
   9  */
  10 
  11 #include <linux/time.h>
  12 #include <linux/fs.h>
  13 #include <linux/seq_file.h>
  14 #include <linux/slab.h>
  15 #include <linux/proc_fs.h>
  16 
  17 #include "ext4.h"
  18 #include "ext4_jbd2.h"
  19 
  20 typedef enum {
  21         attr_noop,
  22         attr_delayed_allocation_blocks,
  23         attr_session_write_kbytes,
  24         attr_lifetime_write_kbytes,
  25         attr_reserved_clusters,
  26         attr_inode_readahead,
  27         attr_trigger_test_error,
  28         attr_first_error_time,
  29         attr_last_error_time,
  30         attr_feature,
  31         attr_pointer_ui,
  32         attr_pointer_atomic,
  33         attr_journal_task,
  34 } attr_id_t;
  35 
  36 typedef enum {
  37         ptr_explicit,
  38         ptr_ext4_sb_info_offset,
  39         ptr_ext4_super_block_offset,
  40 } attr_ptr_t;
  41 
  42 static const char proc_dirname[] = "fs/ext4";
  43 static struct proc_dir_entry *ext4_proc_root;
  44 
  45 struct ext4_attr {
  46         struct attribute attr;
  47         short attr_id;
  48         short attr_ptr;
  49         union {
  50                 int offset;
  51                 void *explicit_ptr;
  52         } u;
  53 };
  54 
  55 static ssize_t session_write_kbytes_show(struct ext4_sb_info *sbi, char *buf)
  56 {
  57         struct super_block *sb = sbi->s_buddy_cache->i_sb;
  58 
  59         if (!sb->s_bdev->bd_part)
  60                 return snprintf(buf, PAGE_SIZE, "0\n");
  61         return snprintf(buf, PAGE_SIZE, "%lu\n",
  62                         (part_stat_read(sb->s_bdev->bd_part,
  63                                         sectors[STAT_WRITE]) -
  64                          sbi->s_sectors_written_start) >> 1);
  65 }
  66 
  67 static ssize_t lifetime_write_kbytes_show(struct ext4_sb_info *sbi, char *buf)
  68 {
  69         struct super_block *sb = sbi->s_buddy_cache->i_sb;
  70 
  71         if (!sb->s_bdev->bd_part)
  72                 return snprintf(buf, PAGE_SIZE, "0\n");
  73         return snprintf(buf, PAGE_SIZE, "%llu\n",
  74                         (unsigned long long)(sbi->s_kbytes_written +
  75                         ((part_stat_read(sb->s_bdev->bd_part,
  76                                          sectors[STAT_WRITE]) -
  77                           EXT4_SB(sb)->s_sectors_written_start) >> 1)));
  78 }
  79 
  80 static ssize_t inode_readahead_blks_store(struct ext4_sb_info *sbi,
  81                                           const char *buf, size_t count)
  82 {
  83         unsigned long t;
  84         int ret;
  85 
  86         ret = kstrtoul(skip_spaces(buf), 0, &t);
  87         if (ret)
  88                 return ret;
  89 
  90         if (t && (!is_power_of_2(t) || t > 0x40000000))
  91                 return -EINVAL;
  92 
  93         sbi->s_inode_readahead_blks = t;
  94         return count;
  95 }
  96 
  97 static ssize_t reserved_clusters_store(struct ext4_sb_info *sbi,
  98                                    const char *buf, size_t count)
  99 {
 100         unsigned long long val;
 101         ext4_fsblk_t clusters = (ext4_blocks_count(sbi->s_es) >>
 102                                  sbi->s_cluster_bits);
 103         int ret;
 104 
 105         ret = kstrtoull(skip_spaces(buf), 0, &val);
 106         if (ret || val >= clusters)
 107                 return -EINVAL;
 108 
 109         atomic64_set(&sbi->s_resv_clusters, val);
 110         return count;
 111 }
 112 
 113 static ssize_t trigger_test_error(struct ext4_sb_info *sbi,
 114                                   const char *buf, size_t count)
 115 {
 116         int len = count;
 117 
 118         if (!capable(CAP_SYS_ADMIN))
 119                 return -EPERM;
 120 
 121         if (len && buf[len-1] == '\n')
 122                 len--;
 123 
 124         if (len)
 125                 ext4_error(sbi->s_sb, "%.*s", len, buf);
 126         return count;
 127 }
 128 
 129 static ssize_t journal_task_show(struct ext4_sb_info *sbi, char *buf)
 130 {
 131         if (!sbi->s_journal)
 132                 return snprintf(buf, PAGE_SIZE, "<none>\n");
 133         return snprintf(buf, PAGE_SIZE, "%d\n",
 134                         task_pid_vnr(sbi->s_journal->j_task));
 135 }
 136 
 137 #define EXT4_ATTR(_name,_mode,_id)                                      \
 138 static struct ext4_attr ext4_attr_##_name = {                           \
 139         .attr = {.name = __stringify(_name), .mode = _mode },           \
 140         .attr_id = attr_##_id,                                          \
 141 }
 142 
 143 #define EXT4_ATTR_FUNC(_name,_mode)  EXT4_ATTR(_name,_mode,_name)
 144 
 145 #define EXT4_ATTR_FEATURE(_name)   EXT4_ATTR(_name, 0444, feature)
 146 
 147 #define EXT4_ATTR_OFFSET(_name,_mode,_id,_struct,_elname)       \
 148 static struct ext4_attr ext4_attr_##_name = {                   \
 149         .attr = {.name = __stringify(_name), .mode = _mode },   \
 150         .attr_id = attr_##_id,                                  \
 151         .attr_ptr = ptr_##_struct##_offset,                     \
 152         .u = {                                                  \
 153                 .offset = offsetof(struct _struct, _elname),\
 154         },                                                      \
 155 }
 156 
 157 #define EXT4_RO_ATTR_ES_UI(_name,_elname)                               \
 158         EXT4_ATTR_OFFSET(_name, 0444, pointer_ui, ext4_super_block, _elname)
 159 
 160 #define EXT4_RW_ATTR_SBI_UI(_name,_elname)      \
 161         EXT4_ATTR_OFFSET(_name, 0644, pointer_ui, ext4_sb_info, _elname)
 162 
 163 #define EXT4_ATTR_PTR(_name,_mode,_id,_ptr) \
 164 static struct ext4_attr ext4_attr_##_name = {                   \
 165         .attr = {.name = __stringify(_name), .mode = _mode },   \
 166         .attr_id = attr_##_id,                                  \
 167         .attr_ptr = ptr_explicit,                               \
 168         .u = {                                                  \
 169                 .explicit_ptr = _ptr,                           \
 170         },                                                      \
 171 }
 172 
 173 #define ATTR_LIST(name) &ext4_attr_##name.attr
 174 
 175 EXT4_ATTR_FUNC(delayed_allocation_blocks, 0444);
 176 EXT4_ATTR_FUNC(session_write_kbytes, 0444);
 177 EXT4_ATTR_FUNC(lifetime_write_kbytes, 0444);
 178 EXT4_ATTR_FUNC(reserved_clusters, 0644);
 179 
 180 EXT4_ATTR_OFFSET(inode_readahead_blks, 0644, inode_readahead,
 181                  ext4_sb_info, s_inode_readahead_blks);
 182 EXT4_RW_ATTR_SBI_UI(inode_goal, s_inode_goal);
 183 EXT4_RW_ATTR_SBI_UI(mb_stats, s_mb_stats);
 184 EXT4_RW_ATTR_SBI_UI(mb_max_to_scan, s_mb_max_to_scan);
 185 EXT4_RW_ATTR_SBI_UI(mb_min_to_scan, s_mb_min_to_scan);
 186 EXT4_RW_ATTR_SBI_UI(mb_order2_req, s_mb_order2_reqs);
 187 EXT4_RW_ATTR_SBI_UI(mb_stream_req, s_mb_stream_request);
 188 EXT4_RW_ATTR_SBI_UI(mb_group_prealloc, s_mb_group_prealloc);
 189 EXT4_RW_ATTR_SBI_UI(extent_max_zeroout_kb, s_extent_max_zeroout_kb);
 190 EXT4_ATTR(trigger_fs_error, 0200, trigger_test_error);
 191 EXT4_RW_ATTR_SBI_UI(err_ratelimit_interval_ms, s_err_ratelimit_state.interval);
 192 EXT4_RW_ATTR_SBI_UI(err_ratelimit_burst, s_err_ratelimit_state.burst);
 193 EXT4_RW_ATTR_SBI_UI(warning_ratelimit_interval_ms, s_warning_ratelimit_state.interval);
 194 EXT4_RW_ATTR_SBI_UI(warning_ratelimit_burst, s_warning_ratelimit_state.burst);
 195 EXT4_RW_ATTR_SBI_UI(msg_ratelimit_interval_ms, s_msg_ratelimit_state.interval);
 196 EXT4_RW_ATTR_SBI_UI(msg_ratelimit_burst, s_msg_ratelimit_state.burst);
 197 EXT4_RO_ATTR_ES_UI(errors_count, s_error_count);
 198 EXT4_ATTR(first_error_time, 0444, first_error_time);
 199 EXT4_ATTR(last_error_time, 0444, last_error_time);
 200 EXT4_ATTR(journal_task, 0444, journal_task);
 201 
 202 static unsigned int old_bump_val = 128;
 203 EXT4_ATTR_PTR(max_writeback_mb_bump, 0444, pointer_ui, &old_bump_val);
 204 
 205 static struct attribute *ext4_attrs[] = {
 206         ATTR_LIST(delayed_allocation_blocks),
 207         ATTR_LIST(session_write_kbytes),
 208         ATTR_LIST(lifetime_write_kbytes),
 209         ATTR_LIST(reserved_clusters),
 210         ATTR_LIST(inode_readahead_blks),
 211         ATTR_LIST(inode_goal),
 212         ATTR_LIST(mb_stats),
 213         ATTR_LIST(mb_max_to_scan),
 214         ATTR_LIST(mb_min_to_scan),
 215         ATTR_LIST(mb_order2_req),
 216         ATTR_LIST(mb_stream_req),
 217         ATTR_LIST(mb_group_prealloc),
 218         ATTR_LIST(max_writeback_mb_bump),
 219         ATTR_LIST(extent_max_zeroout_kb),
 220         ATTR_LIST(trigger_fs_error),
 221         ATTR_LIST(err_ratelimit_interval_ms),
 222         ATTR_LIST(err_ratelimit_burst),
 223         ATTR_LIST(warning_ratelimit_interval_ms),
 224         ATTR_LIST(warning_ratelimit_burst),
 225         ATTR_LIST(msg_ratelimit_interval_ms),
 226         ATTR_LIST(msg_ratelimit_burst),
 227         ATTR_LIST(errors_count),
 228         ATTR_LIST(first_error_time),
 229         ATTR_LIST(last_error_time),
 230         ATTR_LIST(journal_task),
 231         NULL,
 232 };
 233 ATTRIBUTE_GROUPS(ext4);
 234 
 235 /* Features this copy of ext4 supports */
 236 EXT4_ATTR_FEATURE(lazy_itable_init);
 237 EXT4_ATTR_FEATURE(batched_discard);
 238 EXT4_ATTR_FEATURE(meta_bg_resize);
 239 #ifdef CONFIG_FS_ENCRYPTION
 240 EXT4_ATTR_FEATURE(encryption);
 241 #endif
 242 #ifdef CONFIG_UNICODE
 243 EXT4_ATTR_FEATURE(casefold);
 244 #endif
 245 #ifdef CONFIG_FS_VERITY
 246 EXT4_ATTR_FEATURE(verity);
 247 #endif
 248 EXT4_ATTR_FEATURE(metadata_csum_seed);
 249 
 250 static struct attribute *ext4_feat_attrs[] = {
 251         ATTR_LIST(lazy_itable_init),
 252         ATTR_LIST(batched_discard),
 253         ATTR_LIST(meta_bg_resize),
 254 #ifdef CONFIG_FS_ENCRYPTION
 255         ATTR_LIST(encryption),
 256 #endif
 257 #ifdef CONFIG_UNICODE
 258         ATTR_LIST(casefold),
 259 #endif
 260 #ifdef CONFIG_FS_VERITY
 261         ATTR_LIST(verity),
 262 #endif
 263         ATTR_LIST(metadata_csum_seed),
 264         NULL,
 265 };
 266 ATTRIBUTE_GROUPS(ext4_feat);
 267 
 268 static void *calc_ptr(struct ext4_attr *a, struct ext4_sb_info *sbi)
 269 {
 270         switch (a->attr_ptr) {
 271         case ptr_explicit:
 272                 return a->u.explicit_ptr;
 273         case ptr_ext4_sb_info_offset:
 274                 return (void *) (((char *) sbi) + a->u.offset);
 275         case ptr_ext4_super_block_offset:
 276                 return (void *) (((char *) sbi->s_es) + a->u.offset);
 277         }
 278         return NULL;
 279 }
 280 
 281 static ssize_t __print_tstamp(char *buf, __le32 lo, __u8 hi)
 282 {
 283         return snprintf(buf, PAGE_SIZE, "%lld",
 284                         ((time64_t)hi << 32) + le32_to_cpu(lo));
 285 }
 286 
 287 #define print_tstamp(buf, es, tstamp) \
 288         __print_tstamp(buf, (es)->tstamp, (es)->tstamp ## _hi)
 289 
 290 static ssize_t ext4_attr_show(struct kobject *kobj,
 291                               struct attribute *attr, char *buf)
 292 {
 293         struct ext4_sb_info *sbi = container_of(kobj, struct ext4_sb_info,
 294                                                 s_kobj);
 295         struct ext4_attr *a = container_of(attr, struct ext4_attr, attr);
 296         void *ptr = calc_ptr(a, sbi);
 297 
 298         switch (a->attr_id) {
 299         case attr_delayed_allocation_blocks:
 300                 return snprintf(buf, PAGE_SIZE, "%llu\n",
 301                                 (s64) EXT4_C2B(sbi,
 302                        percpu_counter_sum(&sbi->s_dirtyclusters_counter)));
 303         case attr_session_write_kbytes:
 304                 return session_write_kbytes_show(sbi, buf);
 305         case attr_lifetime_write_kbytes:
 306                 return lifetime_write_kbytes_show(sbi, buf);
 307         case attr_reserved_clusters:
 308                 return snprintf(buf, PAGE_SIZE, "%llu\n",
 309                                 (unsigned long long)
 310                                 atomic64_read(&sbi->s_resv_clusters));
 311         case attr_inode_readahead:
 312         case attr_pointer_ui:
 313                 if (!ptr)
 314                         return 0;
 315                 if (a->attr_ptr == ptr_ext4_super_block_offset)
 316                         return snprintf(buf, PAGE_SIZE, "%u\n",
 317                                         le32_to_cpup(ptr));
 318                 else
 319                         return snprintf(buf, PAGE_SIZE, "%u\n",
 320                                         *((unsigned int *) ptr));
 321         case attr_pointer_atomic:
 322                 if (!ptr)
 323                         return 0;
 324                 return snprintf(buf, PAGE_SIZE, "%d\n",
 325                                 atomic_read((atomic_t *) ptr));
 326         case attr_feature:
 327                 return snprintf(buf, PAGE_SIZE, "supported\n");
 328         case attr_first_error_time:
 329                 return print_tstamp(buf, sbi->s_es, s_first_error_time);
 330         case attr_last_error_time:
 331                 return print_tstamp(buf, sbi->s_es, s_last_error_time);
 332         case attr_journal_task:
 333                 return journal_task_show(sbi, buf);
 334         }
 335 
 336         return 0;
 337 }
 338 
 339 static ssize_t ext4_attr_store(struct kobject *kobj,
 340                                struct attribute *attr,
 341                                const char *buf, size_t len)
 342 {
 343         struct ext4_sb_info *sbi = container_of(kobj, struct ext4_sb_info,
 344                                                 s_kobj);
 345         struct ext4_attr *a = container_of(attr, struct ext4_attr, attr);
 346         void *ptr = calc_ptr(a, sbi);
 347         unsigned long t;
 348         int ret;
 349 
 350         switch (a->attr_id) {
 351         case attr_reserved_clusters:
 352                 return reserved_clusters_store(sbi, buf, len);
 353         case attr_pointer_ui:
 354                 if (!ptr)
 355                         return 0;
 356                 ret = kstrtoul(skip_spaces(buf), 0, &t);
 357                 if (ret)
 358                         return ret;
 359                 if (a->attr_ptr == ptr_ext4_super_block_offset)
 360                         *((__le32 *) ptr) = cpu_to_le32(t);
 361                 else
 362                         *((unsigned int *) ptr) = t;
 363                 return len;
 364         case attr_inode_readahead:
 365                 return inode_readahead_blks_store(sbi, buf, len);
 366         case attr_trigger_test_error:
 367                 return trigger_test_error(sbi, buf, len);
 368         }
 369         return 0;
 370 }
 371 
 372 static void ext4_sb_release(struct kobject *kobj)
 373 {
 374         struct ext4_sb_info *sbi = container_of(kobj, struct ext4_sb_info,
 375                                                 s_kobj);
 376         complete(&sbi->s_kobj_unregister);
 377 }
 378 
 379 static const struct sysfs_ops ext4_attr_ops = {
 380         .show   = ext4_attr_show,
 381         .store  = ext4_attr_store,
 382 };
 383 
 384 static struct kobj_type ext4_sb_ktype = {
 385         .default_groups = ext4_groups,
 386         .sysfs_ops      = &ext4_attr_ops,
 387         .release        = ext4_sb_release,
 388 };
 389 
 390 static struct kobj_type ext4_feat_ktype = {
 391         .default_groups = ext4_feat_groups,
 392         .sysfs_ops      = &ext4_attr_ops,
 393         .release        = (void (*)(struct kobject *))kfree,
 394 };
 395 
 396 static struct kobject *ext4_root;
 397 
 398 static struct kobject *ext4_feat;
 399 
 400 int ext4_register_sysfs(struct super_block *sb)
 401 {
 402         struct ext4_sb_info *sbi = EXT4_SB(sb);
 403         int err;
 404 
 405         init_completion(&sbi->s_kobj_unregister);
 406         err = kobject_init_and_add(&sbi->s_kobj, &ext4_sb_ktype, ext4_root,
 407                                    "%s", sb->s_id);
 408         if (err) {
 409                 kobject_put(&sbi->s_kobj);
 410                 wait_for_completion(&sbi->s_kobj_unregister);
 411                 return err;
 412         }
 413 
 414         if (ext4_proc_root)
 415                 sbi->s_proc = proc_mkdir(sb->s_id, ext4_proc_root);
 416         if (sbi->s_proc) {
 417                 proc_create_single_data("options", S_IRUGO, sbi->s_proc,
 418                                 ext4_seq_options_show, sb);
 419                 proc_create_single_data("es_shrinker_info", S_IRUGO,
 420                                 sbi->s_proc, ext4_seq_es_shrinker_info_show,
 421                                 sb);
 422                 proc_create_seq_data("mb_groups", S_IRUGO, sbi->s_proc,
 423                                 &ext4_mb_seq_groups_ops, sb);
 424         }
 425         return 0;
 426 }
 427 
 428 void ext4_unregister_sysfs(struct super_block *sb)
 429 {
 430         struct ext4_sb_info *sbi = EXT4_SB(sb);
 431 
 432         if (sbi->s_proc)
 433                 remove_proc_subtree(sb->s_id, ext4_proc_root);
 434         kobject_del(&sbi->s_kobj);
 435 }
 436 
 437 int __init ext4_init_sysfs(void)
 438 {
 439         int ret;
 440 
 441         ext4_root = kobject_create_and_add("ext4", fs_kobj);
 442         if (!ext4_root)
 443                 return -ENOMEM;
 444 
 445         ext4_feat = kzalloc(sizeof(*ext4_feat), GFP_KERNEL);
 446         if (!ext4_feat) {
 447                 ret = -ENOMEM;
 448                 goto root_err;
 449         }
 450 
 451         ret = kobject_init_and_add(ext4_feat, &ext4_feat_ktype,
 452                                    ext4_root, "features");
 453         if (ret)
 454                 goto feat_err;
 455 
 456         ext4_proc_root = proc_mkdir(proc_dirname, NULL);
 457         return ret;
 458 
 459 feat_err:
 460         kobject_put(ext4_feat);
 461         ext4_feat = NULL;
 462 root_err:
 463         kobject_put(ext4_root);
 464         ext4_root = NULL;
 465         return ret;
 466 }
 467 
 468 void ext4_exit_sysfs(void)
 469 {
 470         kobject_put(ext4_feat);
 471         ext4_feat = NULL;
 472         kobject_put(ext4_root);
 473         ext4_root = NULL;
 474         remove_proc_entry(proc_dirname, NULL);
 475         ext4_proc_root = NULL;
 476 }
 477 

/* [<][>][^][v][top][bottom][index][help] */