root/fs/nilfs2/sysfs.c

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

DEFINITIONS

This source file includes following definitions.
  1. nilfs_snapshot_inodes_count_show
  2. nilfs_snapshot_blocks_count_show
  3. nilfs_snapshot_README_show
  4. nilfs_snapshot_attr_show
  5. nilfs_snapshot_attr_store
  6. nilfs_snapshot_attr_release
  7. nilfs_sysfs_create_snapshot_group
  8. nilfs_sysfs_delete_snapshot_group
  9. nilfs_mounted_snapshots_README_show
  10. nilfs_checkpoints_checkpoints_number_show
  11. nilfs_checkpoints_snapshots_number_show
  12. nilfs_checkpoints_last_seg_checkpoint_show
  13. nilfs_checkpoints_next_checkpoint_show
  14. nilfs_checkpoints_README_show
  15. nilfs_segments_segments_number_show
  16. nilfs_segments_blocks_per_segment_show
  17. nilfs_segments_clean_segments_show
  18. nilfs_segments_dirty_segments_show
  19. nilfs_segments_README_show
  20. nilfs_segctor_last_pseg_block_show
  21. nilfs_segctor_last_seg_sequence_show
  22. nilfs_segctor_last_seg_checkpoint_show
  23. nilfs_segctor_current_seg_sequence_show
  24. nilfs_segctor_current_last_full_seg_show
  25. nilfs_segctor_next_full_seg_show
  26. nilfs_segctor_next_pseg_offset_show
  27. nilfs_segctor_next_checkpoint_show
  28. nilfs_segctor_last_seg_write_time_show
  29. nilfs_segctor_last_seg_write_time_secs_show
  30. nilfs_segctor_last_nongc_write_time_show
  31. nilfs_segctor_last_nongc_write_time_secs_show
  32. nilfs_segctor_dirty_data_blocks_count_show
  33. nilfs_segctor_README_show
  34. nilfs_superblock_sb_write_time_show
  35. nilfs_superblock_sb_write_time_secs_show
  36. nilfs_superblock_sb_write_count_show
  37. nilfs_superblock_sb_update_frequency_show
  38. nilfs_superblock_sb_update_frequency_store
  39. nilfs_superblock_README_show
  40. nilfs_dev_revision_show
  41. nilfs_dev_blocksize_show
  42. nilfs_dev_device_size_show
  43. nilfs_dev_free_blocks_show
  44. nilfs_dev_uuid_show
  45. nilfs_dev_volume_name_show
  46. nilfs_dev_README_show
  47. nilfs_dev_attr_show
  48. nilfs_dev_attr_store
  49. nilfs_dev_attr_release
  50. nilfs_sysfs_create_device_group
  51. nilfs_sysfs_delete_device_group
  52. nilfs_feature_revision_show
  53. nilfs_feature_README_show
  54. nilfs_sysfs_init
  55. nilfs_sysfs_exit

   1 // SPDX-License-Identifier: GPL-2.0+
   2 /*
   3  * sysfs.c - sysfs support implementation.
   4  *
   5  * Copyright (C) 2005-2014 Nippon Telegraph and Telephone Corporation.
   6  * Copyright (C) 2014 HGST, Inc., a Western Digital Company.
   7  *
   8  * Written by Vyacheslav Dubeyko <Vyacheslav.Dubeyko@hgst.com>
   9  */
  10 
  11 #include <linux/kobject.h>
  12 
  13 #include "nilfs.h"
  14 #include "mdt.h"
  15 #include "sufile.h"
  16 #include "cpfile.h"
  17 #include "sysfs.h"
  18 
  19 /* /sys/fs/<nilfs>/ */
  20 static struct kset *nilfs_kset;
  21 
  22 #define NILFS_SHOW_TIME(time_t_val, buf) ({ \
  23                 struct tm res; \
  24                 int count = 0; \
  25                 time64_to_tm(time_t_val, 0, &res); \
  26                 res.tm_year += 1900; \
  27                 res.tm_mon += 1; \
  28                 count = scnprintf(buf, PAGE_SIZE, \
  29                                     "%ld-%.2d-%.2d %.2d:%.2d:%.2d\n", \
  30                                     res.tm_year, res.tm_mon, res.tm_mday, \
  31                                     res.tm_hour, res.tm_min, res.tm_sec);\
  32                 count; \
  33 })
  34 
  35 #define NILFS_DEV_INT_GROUP_OPS(name, parent_name) \
  36 static ssize_t nilfs_##name##_attr_show(struct kobject *kobj, \
  37                                         struct attribute *attr, char *buf) \
  38 { \
  39         struct the_nilfs *nilfs = container_of(kobj->parent, \
  40                                                 struct the_nilfs, \
  41                                                 ns_##parent_name##_kobj); \
  42         struct nilfs_##name##_attr *a = container_of(attr, \
  43                                                 struct nilfs_##name##_attr, \
  44                                                 attr); \
  45         return a->show ? a->show(a, nilfs, buf) : 0; \
  46 } \
  47 static ssize_t nilfs_##name##_attr_store(struct kobject *kobj, \
  48                                          struct attribute *attr, \
  49                                          const char *buf, size_t len) \
  50 { \
  51         struct the_nilfs *nilfs = container_of(kobj->parent, \
  52                                                 struct the_nilfs, \
  53                                                 ns_##parent_name##_kobj); \
  54         struct nilfs_##name##_attr *a = container_of(attr, \
  55                                                 struct nilfs_##name##_attr, \
  56                                                 attr); \
  57         return a->store ? a->store(a, nilfs, buf, len) : 0; \
  58 } \
  59 static const struct sysfs_ops nilfs_##name##_attr_ops = { \
  60         .show   = nilfs_##name##_attr_show, \
  61         .store  = nilfs_##name##_attr_store, \
  62 }
  63 
  64 #define NILFS_DEV_INT_GROUP_TYPE(name, parent_name) \
  65 static void nilfs_##name##_attr_release(struct kobject *kobj) \
  66 { \
  67         struct nilfs_sysfs_##parent_name##_subgroups *subgroups; \
  68         struct the_nilfs *nilfs = container_of(kobj->parent, \
  69                                                 struct the_nilfs, \
  70                                                 ns_##parent_name##_kobj); \
  71         subgroups = nilfs->ns_##parent_name##_subgroups; \
  72         complete(&subgroups->sg_##name##_kobj_unregister); \
  73 } \
  74 static struct kobj_type nilfs_##name##_ktype = { \
  75         .default_attrs  = nilfs_##name##_attrs, \
  76         .sysfs_ops      = &nilfs_##name##_attr_ops, \
  77         .release        = nilfs_##name##_attr_release, \
  78 }
  79 
  80 #define NILFS_DEV_INT_GROUP_FNS(name, parent_name) \
  81 static int nilfs_sysfs_create_##name##_group(struct the_nilfs *nilfs) \
  82 { \
  83         struct kobject *parent; \
  84         struct kobject *kobj; \
  85         struct completion *kobj_unregister; \
  86         struct nilfs_sysfs_##parent_name##_subgroups *subgroups; \
  87         int err; \
  88         subgroups = nilfs->ns_##parent_name##_subgroups; \
  89         kobj = &subgroups->sg_##name##_kobj; \
  90         kobj_unregister = &subgroups->sg_##name##_kobj_unregister; \
  91         parent = &nilfs->ns_##parent_name##_kobj; \
  92         kobj->kset = nilfs_kset; \
  93         init_completion(kobj_unregister); \
  94         err = kobject_init_and_add(kobj, &nilfs_##name##_ktype, parent, \
  95                                     #name); \
  96         if (err) \
  97                 return err; \
  98         return 0; \
  99 } \
 100 static void nilfs_sysfs_delete_##name##_group(struct the_nilfs *nilfs) \
 101 { \
 102         kobject_del(&nilfs->ns_##parent_name##_subgroups->sg_##name##_kobj); \
 103 }
 104 
 105 /************************************************************************
 106  *                        NILFS snapshot attrs                          *
 107  ************************************************************************/
 108 
 109 static ssize_t
 110 nilfs_snapshot_inodes_count_show(struct nilfs_snapshot_attr *attr,
 111                                  struct nilfs_root *root, char *buf)
 112 {
 113         return snprintf(buf, PAGE_SIZE, "%llu\n",
 114                         (unsigned long long)atomic64_read(&root->inodes_count));
 115 }
 116 
 117 static ssize_t
 118 nilfs_snapshot_blocks_count_show(struct nilfs_snapshot_attr *attr,
 119                                  struct nilfs_root *root, char *buf)
 120 {
 121         return snprintf(buf, PAGE_SIZE, "%llu\n",
 122                         (unsigned long long)atomic64_read(&root->blocks_count));
 123 }
 124 
 125 static const char snapshot_readme_str[] =
 126         "The group contains details about mounted snapshot.\n\n"
 127         "(1) inodes_count\n\tshow number of inodes for snapshot.\n\n"
 128         "(2) blocks_count\n\tshow number of blocks for snapshot.\n\n";
 129 
 130 static ssize_t
 131 nilfs_snapshot_README_show(struct nilfs_snapshot_attr *attr,
 132                             struct nilfs_root *root, char *buf)
 133 {
 134         return snprintf(buf, PAGE_SIZE, snapshot_readme_str);
 135 }
 136 
 137 NILFS_SNAPSHOT_RO_ATTR(inodes_count);
 138 NILFS_SNAPSHOT_RO_ATTR(blocks_count);
 139 NILFS_SNAPSHOT_RO_ATTR(README);
 140 
 141 static struct attribute *nilfs_snapshot_attrs[] = {
 142         NILFS_SNAPSHOT_ATTR_LIST(inodes_count),
 143         NILFS_SNAPSHOT_ATTR_LIST(blocks_count),
 144         NILFS_SNAPSHOT_ATTR_LIST(README),
 145         NULL,
 146 };
 147 
 148 static ssize_t nilfs_snapshot_attr_show(struct kobject *kobj,
 149                                         struct attribute *attr, char *buf)
 150 {
 151         struct nilfs_root *root =
 152                         container_of(kobj, struct nilfs_root, snapshot_kobj);
 153         struct nilfs_snapshot_attr *a =
 154                         container_of(attr, struct nilfs_snapshot_attr, attr);
 155 
 156         return a->show ? a->show(a, root, buf) : 0;
 157 }
 158 
 159 static ssize_t nilfs_snapshot_attr_store(struct kobject *kobj,
 160                                          struct attribute *attr,
 161                                          const char *buf, size_t len)
 162 {
 163         struct nilfs_root *root =
 164                         container_of(kobj, struct nilfs_root, snapshot_kobj);
 165         struct nilfs_snapshot_attr *a =
 166                         container_of(attr, struct nilfs_snapshot_attr, attr);
 167 
 168         return a->store ? a->store(a, root, buf, len) : 0;
 169 }
 170 
 171 static void nilfs_snapshot_attr_release(struct kobject *kobj)
 172 {
 173         struct nilfs_root *root = container_of(kobj, struct nilfs_root,
 174                                                 snapshot_kobj);
 175         complete(&root->snapshot_kobj_unregister);
 176 }
 177 
 178 static const struct sysfs_ops nilfs_snapshot_attr_ops = {
 179         .show   = nilfs_snapshot_attr_show,
 180         .store  = nilfs_snapshot_attr_store,
 181 };
 182 
 183 static struct kobj_type nilfs_snapshot_ktype = {
 184         .default_attrs  = nilfs_snapshot_attrs,
 185         .sysfs_ops      = &nilfs_snapshot_attr_ops,
 186         .release        = nilfs_snapshot_attr_release,
 187 };
 188 
 189 int nilfs_sysfs_create_snapshot_group(struct nilfs_root *root)
 190 {
 191         struct the_nilfs *nilfs;
 192         struct kobject *parent;
 193         int err;
 194 
 195         nilfs = root->nilfs;
 196         parent = &nilfs->ns_dev_subgroups->sg_mounted_snapshots_kobj;
 197         root->snapshot_kobj.kset = nilfs_kset;
 198         init_completion(&root->snapshot_kobj_unregister);
 199 
 200         if (root->cno == NILFS_CPTREE_CURRENT_CNO) {
 201                 err = kobject_init_and_add(&root->snapshot_kobj,
 202                                             &nilfs_snapshot_ktype,
 203                                             &nilfs->ns_dev_kobj,
 204                                             "current_checkpoint");
 205         } else {
 206                 err = kobject_init_and_add(&root->snapshot_kobj,
 207                                             &nilfs_snapshot_ktype,
 208                                             parent,
 209                                             "%llu", root->cno);
 210         }
 211 
 212         if (err)
 213                 return err;
 214 
 215         return 0;
 216 }
 217 
 218 void nilfs_sysfs_delete_snapshot_group(struct nilfs_root *root)
 219 {
 220         kobject_del(&root->snapshot_kobj);
 221 }
 222 
 223 /************************************************************************
 224  *                    NILFS mounted snapshots attrs                     *
 225  ************************************************************************/
 226 
 227 static const char mounted_snapshots_readme_str[] =
 228         "The mounted_snapshots group contains group for\n"
 229         "every mounted snapshot.\n";
 230 
 231 static ssize_t
 232 nilfs_mounted_snapshots_README_show(struct nilfs_mounted_snapshots_attr *attr,
 233                                     struct the_nilfs *nilfs, char *buf)
 234 {
 235         return snprintf(buf, PAGE_SIZE, mounted_snapshots_readme_str);
 236 }
 237 
 238 NILFS_MOUNTED_SNAPSHOTS_RO_ATTR(README);
 239 
 240 static struct attribute *nilfs_mounted_snapshots_attrs[] = {
 241         NILFS_MOUNTED_SNAPSHOTS_ATTR_LIST(README),
 242         NULL,
 243 };
 244 
 245 NILFS_DEV_INT_GROUP_OPS(mounted_snapshots, dev);
 246 NILFS_DEV_INT_GROUP_TYPE(mounted_snapshots, dev);
 247 NILFS_DEV_INT_GROUP_FNS(mounted_snapshots, dev);
 248 
 249 /************************************************************************
 250  *                      NILFS checkpoints attrs                         *
 251  ************************************************************************/
 252 
 253 static ssize_t
 254 nilfs_checkpoints_checkpoints_number_show(struct nilfs_checkpoints_attr *attr,
 255                                             struct the_nilfs *nilfs,
 256                                             char *buf)
 257 {
 258         __u64 ncheckpoints;
 259         struct nilfs_cpstat cpstat;
 260         int err;
 261 
 262         down_read(&nilfs->ns_segctor_sem);
 263         err = nilfs_cpfile_get_stat(nilfs->ns_cpfile, &cpstat);
 264         up_read(&nilfs->ns_segctor_sem);
 265         if (err < 0) {
 266                 nilfs_msg(nilfs->ns_sb, KERN_ERR,
 267                           "unable to get checkpoint stat: err=%d", err);
 268                 return err;
 269         }
 270 
 271         ncheckpoints = cpstat.cs_ncps;
 272 
 273         return snprintf(buf, PAGE_SIZE, "%llu\n", ncheckpoints);
 274 }
 275 
 276 static ssize_t
 277 nilfs_checkpoints_snapshots_number_show(struct nilfs_checkpoints_attr *attr,
 278                                         struct the_nilfs *nilfs,
 279                                         char *buf)
 280 {
 281         __u64 nsnapshots;
 282         struct nilfs_cpstat cpstat;
 283         int err;
 284 
 285         down_read(&nilfs->ns_segctor_sem);
 286         err = nilfs_cpfile_get_stat(nilfs->ns_cpfile, &cpstat);
 287         up_read(&nilfs->ns_segctor_sem);
 288         if (err < 0) {
 289                 nilfs_msg(nilfs->ns_sb, KERN_ERR,
 290                           "unable to get checkpoint stat: err=%d", err);
 291                 return err;
 292         }
 293 
 294         nsnapshots = cpstat.cs_nsss;
 295 
 296         return snprintf(buf, PAGE_SIZE, "%llu\n", nsnapshots);
 297 }
 298 
 299 static ssize_t
 300 nilfs_checkpoints_last_seg_checkpoint_show(struct nilfs_checkpoints_attr *attr,
 301                                             struct the_nilfs *nilfs,
 302                                             char *buf)
 303 {
 304         __u64 last_cno;
 305 
 306         spin_lock(&nilfs->ns_last_segment_lock);
 307         last_cno = nilfs->ns_last_cno;
 308         spin_unlock(&nilfs->ns_last_segment_lock);
 309 
 310         return snprintf(buf, PAGE_SIZE, "%llu\n", last_cno);
 311 }
 312 
 313 static ssize_t
 314 nilfs_checkpoints_next_checkpoint_show(struct nilfs_checkpoints_attr *attr,
 315                                         struct the_nilfs *nilfs,
 316                                         char *buf)
 317 {
 318         __u64 cno;
 319 
 320         down_read(&nilfs->ns_segctor_sem);
 321         cno = nilfs->ns_cno;
 322         up_read(&nilfs->ns_segctor_sem);
 323 
 324         return snprintf(buf, PAGE_SIZE, "%llu\n", cno);
 325 }
 326 
 327 static const char checkpoints_readme_str[] =
 328         "The checkpoints group contains attributes that describe\n"
 329         "details about volume's checkpoints.\n\n"
 330         "(1) checkpoints_number\n\tshow number of checkpoints on volume.\n\n"
 331         "(2) snapshots_number\n\tshow number of snapshots on volume.\n\n"
 332         "(3) last_seg_checkpoint\n"
 333         "\tshow checkpoint number of the latest segment.\n\n"
 334         "(4) next_checkpoint\n\tshow next checkpoint number.\n\n";
 335 
 336 static ssize_t
 337 nilfs_checkpoints_README_show(struct nilfs_checkpoints_attr *attr,
 338                                 struct the_nilfs *nilfs, char *buf)
 339 {
 340         return snprintf(buf, PAGE_SIZE, checkpoints_readme_str);
 341 }
 342 
 343 NILFS_CHECKPOINTS_RO_ATTR(checkpoints_number);
 344 NILFS_CHECKPOINTS_RO_ATTR(snapshots_number);
 345 NILFS_CHECKPOINTS_RO_ATTR(last_seg_checkpoint);
 346 NILFS_CHECKPOINTS_RO_ATTR(next_checkpoint);
 347 NILFS_CHECKPOINTS_RO_ATTR(README);
 348 
 349 static struct attribute *nilfs_checkpoints_attrs[] = {
 350         NILFS_CHECKPOINTS_ATTR_LIST(checkpoints_number),
 351         NILFS_CHECKPOINTS_ATTR_LIST(snapshots_number),
 352         NILFS_CHECKPOINTS_ATTR_LIST(last_seg_checkpoint),
 353         NILFS_CHECKPOINTS_ATTR_LIST(next_checkpoint),
 354         NILFS_CHECKPOINTS_ATTR_LIST(README),
 355         NULL,
 356 };
 357 
 358 NILFS_DEV_INT_GROUP_OPS(checkpoints, dev);
 359 NILFS_DEV_INT_GROUP_TYPE(checkpoints, dev);
 360 NILFS_DEV_INT_GROUP_FNS(checkpoints, dev);
 361 
 362 /************************************************************************
 363  *                        NILFS segments attrs                          *
 364  ************************************************************************/
 365 
 366 static ssize_t
 367 nilfs_segments_segments_number_show(struct nilfs_segments_attr *attr,
 368                                      struct the_nilfs *nilfs,
 369                                      char *buf)
 370 {
 371         return snprintf(buf, PAGE_SIZE, "%lu\n", nilfs->ns_nsegments);
 372 }
 373 
 374 static ssize_t
 375 nilfs_segments_blocks_per_segment_show(struct nilfs_segments_attr *attr,
 376                                         struct the_nilfs *nilfs,
 377                                         char *buf)
 378 {
 379         return snprintf(buf, PAGE_SIZE, "%lu\n", nilfs->ns_blocks_per_segment);
 380 }
 381 
 382 static ssize_t
 383 nilfs_segments_clean_segments_show(struct nilfs_segments_attr *attr,
 384                                     struct the_nilfs *nilfs,
 385                                     char *buf)
 386 {
 387         unsigned long ncleansegs;
 388 
 389         down_read(&NILFS_MDT(nilfs->ns_dat)->mi_sem);
 390         ncleansegs = nilfs_sufile_get_ncleansegs(nilfs->ns_sufile);
 391         up_read(&NILFS_MDT(nilfs->ns_dat)->mi_sem);
 392 
 393         return snprintf(buf, PAGE_SIZE, "%lu\n", ncleansegs);
 394 }
 395 
 396 static ssize_t
 397 nilfs_segments_dirty_segments_show(struct nilfs_segments_attr *attr,
 398                                     struct the_nilfs *nilfs,
 399                                     char *buf)
 400 {
 401         struct nilfs_sustat sustat;
 402         int err;
 403 
 404         down_read(&nilfs->ns_segctor_sem);
 405         err = nilfs_sufile_get_stat(nilfs->ns_sufile, &sustat);
 406         up_read(&nilfs->ns_segctor_sem);
 407         if (err < 0) {
 408                 nilfs_msg(nilfs->ns_sb, KERN_ERR,
 409                           "unable to get segment stat: err=%d", err);
 410                 return err;
 411         }
 412 
 413         return snprintf(buf, PAGE_SIZE, "%llu\n", sustat.ss_ndirtysegs);
 414 }
 415 
 416 static const char segments_readme_str[] =
 417         "The segments group contains attributes that describe\n"
 418         "details about volume's segments.\n\n"
 419         "(1) segments_number\n\tshow number of segments on volume.\n\n"
 420         "(2) blocks_per_segment\n\tshow number of blocks in segment.\n\n"
 421         "(3) clean_segments\n\tshow count of clean segments.\n\n"
 422         "(4) dirty_segments\n\tshow count of dirty segments.\n\n";
 423 
 424 static ssize_t
 425 nilfs_segments_README_show(struct nilfs_segments_attr *attr,
 426                             struct the_nilfs *nilfs,
 427                             char *buf)
 428 {
 429         return snprintf(buf, PAGE_SIZE, segments_readme_str);
 430 }
 431 
 432 NILFS_SEGMENTS_RO_ATTR(segments_number);
 433 NILFS_SEGMENTS_RO_ATTR(blocks_per_segment);
 434 NILFS_SEGMENTS_RO_ATTR(clean_segments);
 435 NILFS_SEGMENTS_RO_ATTR(dirty_segments);
 436 NILFS_SEGMENTS_RO_ATTR(README);
 437 
 438 static struct attribute *nilfs_segments_attrs[] = {
 439         NILFS_SEGMENTS_ATTR_LIST(segments_number),
 440         NILFS_SEGMENTS_ATTR_LIST(blocks_per_segment),
 441         NILFS_SEGMENTS_ATTR_LIST(clean_segments),
 442         NILFS_SEGMENTS_ATTR_LIST(dirty_segments),
 443         NILFS_SEGMENTS_ATTR_LIST(README),
 444         NULL,
 445 };
 446 
 447 NILFS_DEV_INT_GROUP_OPS(segments, dev);
 448 NILFS_DEV_INT_GROUP_TYPE(segments, dev);
 449 NILFS_DEV_INT_GROUP_FNS(segments, dev);
 450 
 451 /************************************************************************
 452  *                        NILFS segctor attrs                           *
 453  ************************************************************************/
 454 
 455 static ssize_t
 456 nilfs_segctor_last_pseg_block_show(struct nilfs_segctor_attr *attr,
 457                                     struct the_nilfs *nilfs,
 458                                     char *buf)
 459 {
 460         sector_t last_pseg;
 461 
 462         spin_lock(&nilfs->ns_last_segment_lock);
 463         last_pseg = nilfs->ns_last_pseg;
 464         spin_unlock(&nilfs->ns_last_segment_lock);
 465 
 466         return snprintf(buf, PAGE_SIZE, "%llu\n",
 467                         (unsigned long long)last_pseg);
 468 }
 469 
 470 static ssize_t
 471 nilfs_segctor_last_seg_sequence_show(struct nilfs_segctor_attr *attr,
 472                                         struct the_nilfs *nilfs,
 473                                         char *buf)
 474 {
 475         u64 last_seq;
 476 
 477         spin_lock(&nilfs->ns_last_segment_lock);
 478         last_seq = nilfs->ns_last_seq;
 479         spin_unlock(&nilfs->ns_last_segment_lock);
 480 
 481         return snprintf(buf, PAGE_SIZE, "%llu\n", last_seq);
 482 }
 483 
 484 static ssize_t
 485 nilfs_segctor_last_seg_checkpoint_show(struct nilfs_segctor_attr *attr,
 486                                         struct the_nilfs *nilfs,
 487                                         char *buf)
 488 {
 489         __u64 last_cno;
 490 
 491         spin_lock(&nilfs->ns_last_segment_lock);
 492         last_cno = nilfs->ns_last_cno;
 493         spin_unlock(&nilfs->ns_last_segment_lock);
 494 
 495         return snprintf(buf, PAGE_SIZE, "%llu\n", last_cno);
 496 }
 497 
 498 static ssize_t
 499 nilfs_segctor_current_seg_sequence_show(struct nilfs_segctor_attr *attr,
 500                                         struct the_nilfs *nilfs,
 501                                         char *buf)
 502 {
 503         u64 seg_seq;
 504 
 505         down_read(&nilfs->ns_segctor_sem);
 506         seg_seq = nilfs->ns_seg_seq;
 507         up_read(&nilfs->ns_segctor_sem);
 508 
 509         return snprintf(buf, PAGE_SIZE, "%llu\n", seg_seq);
 510 }
 511 
 512 static ssize_t
 513 nilfs_segctor_current_last_full_seg_show(struct nilfs_segctor_attr *attr,
 514                                          struct the_nilfs *nilfs,
 515                                          char *buf)
 516 {
 517         __u64 segnum;
 518 
 519         down_read(&nilfs->ns_segctor_sem);
 520         segnum = nilfs->ns_segnum;
 521         up_read(&nilfs->ns_segctor_sem);
 522 
 523         return snprintf(buf, PAGE_SIZE, "%llu\n", segnum);
 524 }
 525 
 526 static ssize_t
 527 nilfs_segctor_next_full_seg_show(struct nilfs_segctor_attr *attr,
 528                                  struct the_nilfs *nilfs,
 529                                  char *buf)
 530 {
 531         __u64 nextnum;
 532 
 533         down_read(&nilfs->ns_segctor_sem);
 534         nextnum = nilfs->ns_nextnum;
 535         up_read(&nilfs->ns_segctor_sem);
 536 
 537         return snprintf(buf, PAGE_SIZE, "%llu\n", nextnum);
 538 }
 539 
 540 static ssize_t
 541 nilfs_segctor_next_pseg_offset_show(struct nilfs_segctor_attr *attr,
 542                                         struct the_nilfs *nilfs,
 543                                         char *buf)
 544 {
 545         unsigned long pseg_offset;
 546 
 547         down_read(&nilfs->ns_segctor_sem);
 548         pseg_offset = nilfs->ns_pseg_offset;
 549         up_read(&nilfs->ns_segctor_sem);
 550 
 551         return snprintf(buf, PAGE_SIZE, "%lu\n", pseg_offset);
 552 }
 553 
 554 static ssize_t
 555 nilfs_segctor_next_checkpoint_show(struct nilfs_segctor_attr *attr,
 556                                         struct the_nilfs *nilfs,
 557                                         char *buf)
 558 {
 559         __u64 cno;
 560 
 561         down_read(&nilfs->ns_segctor_sem);
 562         cno = nilfs->ns_cno;
 563         up_read(&nilfs->ns_segctor_sem);
 564 
 565         return snprintf(buf, PAGE_SIZE, "%llu\n", cno);
 566 }
 567 
 568 static ssize_t
 569 nilfs_segctor_last_seg_write_time_show(struct nilfs_segctor_attr *attr,
 570                                         struct the_nilfs *nilfs,
 571                                         char *buf)
 572 {
 573         time64_t ctime;
 574 
 575         down_read(&nilfs->ns_segctor_sem);
 576         ctime = nilfs->ns_ctime;
 577         up_read(&nilfs->ns_segctor_sem);
 578 
 579         return NILFS_SHOW_TIME(ctime, buf);
 580 }
 581 
 582 static ssize_t
 583 nilfs_segctor_last_seg_write_time_secs_show(struct nilfs_segctor_attr *attr,
 584                                             struct the_nilfs *nilfs,
 585                                             char *buf)
 586 {
 587         time64_t ctime;
 588 
 589         down_read(&nilfs->ns_segctor_sem);
 590         ctime = nilfs->ns_ctime;
 591         up_read(&nilfs->ns_segctor_sem);
 592 
 593         return snprintf(buf, PAGE_SIZE, "%llu\n", ctime);
 594 }
 595 
 596 static ssize_t
 597 nilfs_segctor_last_nongc_write_time_show(struct nilfs_segctor_attr *attr,
 598                                          struct the_nilfs *nilfs,
 599                                          char *buf)
 600 {
 601         time64_t nongc_ctime;
 602 
 603         down_read(&nilfs->ns_segctor_sem);
 604         nongc_ctime = nilfs->ns_nongc_ctime;
 605         up_read(&nilfs->ns_segctor_sem);
 606 
 607         return NILFS_SHOW_TIME(nongc_ctime, buf);
 608 }
 609 
 610 static ssize_t
 611 nilfs_segctor_last_nongc_write_time_secs_show(struct nilfs_segctor_attr *attr,
 612                                                 struct the_nilfs *nilfs,
 613                                                 char *buf)
 614 {
 615         time64_t nongc_ctime;
 616 
 617         down_read(&nilfs->ns_segctor_sem);
 618         nongc_ctime = nilfs->ns_nongc_ctime;
 619         up_read(&nilfs->ns_segctor_sem);
 620 
 621         return snprintf(buf, PAGE_SIZE, "%llu\n", nongc_ctime);
 622 }
 623 
 624 static ssize_t
 625 nilfs_segctor_dirty_data_blocks_count_show(struct nilfs_segctor_attr *attr,
 626                                             struct the_nilfs *nilfs,
 627                                             char *buf)
 628 {
 629         u32 ndirtyblks;
 630 
 631         down_read(&nilfs->ns_segctor_sem);
 632         ndirtyblks = atomic_read(&nilfs->ns_ndirtyblks);
 633         up_read(&nilfs->ns_segctor_sem);
 634 
 635         return snprintf(buf, PAGE_SIZE, "%u\n", ndirtyblks);
 636 }
 637 
 638 static const char segctor_readme_str[] =
 639         "The segctor group contains attributes that describe\n"
 640         "segctor thread activity details.\n\n"
 641         "(1) last_pseg_block\n"
 642         "\tshow start block number of the latest segment.\n\n"
 643         "(2) last_seg_sequence\n"
 644         "\tshow sequence value of the latest segment.\n\n"
 645         "(3) last_seg_checkpoint\n"
 646         "\tshow checkpoint number of the latest segment.\n\n"
 647         "(4) current_seg_sequence\n\tshow segment sequence counter.\n\n"
 648         "(5) current_last_full_seg\n"
 649         "\tshow index number of the latest full segment.\n\n"
 650         "(6) next_full_seg\n"
 651         "\tshow index number of the full segment index to be used next.\n\n"
 652         "(7) next_pseg_offset\n"
 653         "\tshow offset of next partial segment in the current full segment.\n\n"
 654         "(8) next_checkpoint\n\tshow next checkpoint number.\n\n"
 655         "(9) last_seg_write_time\n"
 656         "\tshow write time of the last segment in human-readable format.\n\n"
 657         "(10) last_seg_write_time_secs\n"
 658         "\tshow write time of the last segment in seconds.\n\n"
 659         "(11) last_nongc_write_time\n"
 660         "\tshow write time of the last segment not for cleaner operation "
 661         "in human-readable format.\n\n"
 662         "(12) last_nongc_write_time_secs\n"
 663         "\tshow write time of the last segment not for cleaner operation "
 664         "in seconds.\n\n"
 665         "(13) dirty_data_blocks_count\n"
 666         "\tshow number of dirty data blocks.\n\n";
 667 
 668 static ssize_t
 669 nilfs_segctor_README_show(struct nilfs_segctor_attr *attr,
 670                           struct the_nilfs *nilfs, char *buf)
 671 {
 672         return snprintf(buf, PAGE_SIZE, segctor_readme_str);
 673 }
 674 
 675 NILFS_SEGCTOR_RO_ATTR(last_pseg_block);
 676 NILFS_SEGCTOR_RO_ATTR(last_seg_sequence);
 677 NILFS_SEGCTOR_RO_ATTR(last_seg_checkpoint);
 678 NILFS_SEGCTOR_RO_ATTR(current_seg_sequence);
 679 NILFS_SEGCTOR_RO_ATTR(current_last_full_seg);
 680 NILFS_SEGCTOR_RO_ATTR(next_full_seg);
 681 NILFS_SEGCTOR_RO_ATTR(next_pseg_offset);
 682 NILFS_SEGCTOR_RO_ATTR(next_checkpoint);
 683 NILFS_SEGCTOR_RO_ATTR(last_seg_write_time);
 684 NILFS_SEGCTOR_RO_ATTR(last_seg_write_time_secs);
 685 NILFS_SEGCTOR_RO_ATTR(last_nongc_write_time);
 686 NILFS_SEGCTOR_RO_ATTR(last_nongc_write_time_secs);
 687 NILFS_SEGCTOR_RO_ATTR(dirty_data_blocks_count);
 688 NILFS_SEGCTOR_RO_ATTR(README);
 689 
 690 static struct attribute *nilfs_segctor_attrs[] = {
 691         NILFS_SEGCTOR_ATTR_LIST(last_pseg_block),
 692         NILFS_SEGCTOR_ATTR_LIST(last_seg_sequence),
 693         NILFS_SEGCTOR_ATTR_LIST(last_seg_checkpoint),
 694         NILFS_SEGCTOR_ATTR_LIST(current_seg_sequence),
 695         NILFS_SEGCTOR_ATTR_LIST(current_last_full_seg),
 696         NILFS_SEGCTOR_ATTR_LIST(next_full_seg),
 697         NILFS_SEGCTOR_ATTR_LIST(next_pseg_offset),
 698         NILFS_SEGCTOR_ATTR_LIST(next_checkpoint),
 699         NILFS_SEGCTOR_ATTR_LIST(last_seg_write_time),
 700         NILFS_SEGCTOR_ATTR_LIST(last_seg_write_time_secs),
 701         NILFS_SEGCTOR_ATTR_LIST(last_nongc_write_time),
 702         NILFS_SEGCTOR_ATTR_LIST(last_nongc_write_time_secs),
 703         NILFS_SEGCTOR_ATTR_LIST(dirty_data_blocks_count),
 704         NILFS_SEGCTOR_ATTR_LIST(README),
 705         NULL,
 706 };
 707 
 708 NILFS_DEV_INT_GROUP_OPS(segctor, dev);
 709 NILFS_DEV_INT_GROUP_TYPE(segctor, dev);
 710 NILFS_DEV_INT_GROUP_FNS(segctor, dev);
 711 
 712 /************************************************************************
 713  *                        NILFS superblock attrs                        *
 714  ************************************************************************/
 715 
 716 static ssize_t
 717 nilfs_superblock_sb_write_time_show(struct nilfs_superblock_attr *attr,
 718                                      struct the_nilfs *nilfs,
 719                                      char *buf)
 720 {
 721         time64_t sbwtime;
 722 
 723         down_read(&nilfs->ns_sem);
 724         sbwtime = nilfs->ns_sbwtime;
 725         up_read(&nilfs->ns_sem);
 726 
 727         return NILFS_SHOW_TIME(sbwtime, buf);
 728 }
 729 
 730 static ssize_t
 731 nilfs_superblock_sb_write_time_secs_show(struct nilfs_superblock_attr *attr,
 732                                          struct the_nilfs *nilfs,
 733                                          char *buf)
 734 {
 735         time64_t sbwtime;
 736 
 737         down_read(&nilfs->ns_sem);
 738         sbwtime = nilfs->ns_sbwtime;
 739         up_read(&nilfs->ns_sem);
 740 
 741         return snprintf(buf, PAGE_SIZE, "%llu\n", sbwtime);
 742 }
 743 
 744 static ssize_t
 745 nilfs_superblock_sb_write_count_show(struct nilfs_superblock_attr *attr,
 746                                       struct the_nilfs *nilfs,
 747                                       char *buf)
 748 {
 749         unsigned int sbwcount;
 750 
 751         down_read(&nilfs->ns_sem);
 752         sbwcount = nilfs->ns_sbwcount;
 753         up_read(&nilfs->ns_sem);
 754 
 755         return snprintf(buf, PAGE_SIZE, "%u\n", sbwcount);
 756 }
 757 
 758 static ssize_t
 759 nilfs_superblock_sb_update_frequency_show(struct nilfs_superblock_attr *attr,
 760                                             struct the_nilfs *nilfs,
 761                                             char *buf)
 762 {
 763         unsigned int sb_update_freq;
 764 
 765         down_read(&nilfs->ns_sem);
 766         sb_update_freq = nilfs->ns_sb_update_freq;
 767         up_read(&nilfs->ns_sem);
 768 
 769         return snprintf(buf, PAGE_SIZE, "%u\n", sb_update_freq);
 770 }
 771 
 772 static ssize_t
 773 nilfs_superblock_sb_update_frequency_store(struct nilfs_superblock_attr *attr,
 774                                             struct the_nilfs *nilfs,
 775                                             const char *buf, size_t count)
 776 {
 777         unsigned int val;
 778         int err;
 779 
 780         err = kstrtouint(skip_spaces(buf), 0, &val);
 781         if (err) {
 782                 nilfs_msg(nilfs->ns_sb, KERN_ERR,
 783                           "unable to convert string: err=%d", err);
 784                 return err;
 785         }
 786 
 787         if (val < NILFS_SB_FREQ) {
 788                 val = NILFS_SB_FREQ;
 789                 nilfs_msg(nilfs->ns_sb, KERN_WARNING,
 790                           "superblock update frequency cannot be lesser than 10 seconds");
 791         }
 792 
 793         down_write(&nilfs->ns_sem);
 794         nilfs->ns_sb_update_freq = val;
 795         up_write(&nilfs->ns_sem);
 796 
 797         return count;
 798 }
 799 
 800 static const char sb_readme_str[] =
 801         "The superblock group contains attributes that describe\n"
 802         "superblock's details.\n\n"
 803         "(1) sb_write_time\n\tshow previous write time of super block "
 804         "in human-readable format.\n\n"
 805         "(2) sb_write_time_secs\n\tshow previous write time of super block "
 806         "in seconds.\n\n"
 807         "(3) sb_write_count\n\tshow write count of super block.\n\n"
 808         "(4) sb_update_frequency\n"
 809         "\tshow/set interval of periodical update of superblock (in seconds).\n\n"
 810         "\tYou can set preferable frequency of superblock update by command:\n\n"
 811         "\t'echo <val> > /sys/fs/<nilfs>/<dev>/superblock/sb_update_frequency'\n";
 812 
 813 static ssize_t
 814 nilfs_superblock_README_show(struct nilfs_superblock_attr *attr,
 815                                 struct the_nilfs *nilfs, char *buf)
 816 {
 817         return snprintf(buf, PAGE_SIZE, sb_readme_str);
 818 }
 819 
 820 NILFS_SUPERBLOCK_RO_ATTR(sb_write_time);
 821 NILFS_SUPERBLOCK_RO_ATTR(sb_write_time_secs);
 822 NILFS_SUPERBLOCK_RO_ATTR(sb_write_count);
 823 NILFS_SUPERBLOCK_RW_ATTR(sb_update_frequency);
 824 NILFS_SUPERBLOCK_RO_ATTR(README);
 825 
 826 static struct attribute *nilfs_superblock_attrs[] = {
 827         NILFS_SUPERBLOCK_ATTR_LIST(sb_write_time),
 828         NILFS_SUPERBLOCK_ATTR_LIST(sb_write_time_secs),
 829         NILFS_SUPERBLOCK_ATTR_LIST(sb_write_count),
 830         NILFS_SUPERBLOCK_ATTR_LIST(sb_update_frequency),
 831         NILFS_SUPERBLOCK_ATTR_LIST(README),
 832         NULL,
 833 };
 834 
 835 NILFS_DEV_INT_GROUP_OPS(superblock, dev);
 836 NILFS_DEV_INT_GROUP_TYPE(superblock, dev);
 837 NILFS_DEV_INT_GROUP_FNS(superblock, dev);
 838 
 839 /************************************************************************
 840  *                        NILFS device attrs                            *
 841  ************************************************************************/
 842 
 843 static
 844 ssize_t nilfs_dev_revision_show(struct nilfs_dev_attr *attr,
 845                                 struct the_nilfs *nilfs,
 846                                 char *buf)
 847 {
 848         struct nilfs_super_block **sbp = nilfs->ns_sbp;
 849         u32 major = le32_to_cpu(sbp[0]->s_rev_level);
 850         u16 minor = le16_to_cpu(sbp[0]->s_minor_rev_level);
 851 
 852         return snprintf(buf, PAGE_SIZE, "%d.%d\n", major, minor);
 853 }
 854 
 855 static
 856 ssize_t nilfs_dev_blocksize_show(struct nilfs_dev_attr *attr,
 857                                  struct the_nilfs *nilfs,
 858                                  char *buf)
 859 {
 860         return snprintf(buf, PAGE_SIZE, "%u\n", nilfs->ns_blocksize);
 861 }
 862 
 863 static
 864 ssize_t nilfs_dev_device_size_show(struct nilfs_dev_attr *attr,
 865                                     struct the_nilfs *nilfs,
 866                                     char *buf)
 867 {
 868         struct nilfs_super_block **sbp = nilfs->ns_sbp;
 869         u64 dev_size = le64_to_cpu(sbp[0]->s_dev_size);
 870 
 871         return snprintf(buf, PAGE_SIZE, "%llu\n", dev_size);
 872 }
 873 
 874 static
 875 ssize_t nilfs_dev_free_blocks_show(struct nilfs_dev_attr *attr,
 876                                    struct the_nilfs *nilfs,
 877                                    char *buf)
 878 {
 879         sector_t free_blocks = 0;
 880 
 881         nilfs_count_free_blocks(nilfs, &free_blocks);
 882         return snprintf(buf, PAGE_SIZE, "%llu\n",
 883                         (unsigned long long)free_blocks);
 884 }
 885 
 886 static
 887 ssize_t nilfs_dev_uuid_show(struct nilfs_dev_attr *attr,
 888                             struct the_nilfs *nilfs,
 889                             char *buf)
 890 {
 891         struct nilfs_super_block **sbp = nilfs->ns_sbp;
 892 
 893         return snprintf(buf, PAGE_SIZE, "%pUb\n", sbp[0]->s_uuid);
 894 }
 895 
 896 static
 897 ssize_t nilfs_dev_volume_name_show(struct nilfs_dev_attr *attr,
 898                                     struct the_nilfs *nilfs,
 899                                     char *buf)
 900 {
 901         struct nilfs_super_block **sbp = nilfs->ns_sbp;
 902 
 903         return scnprintf(buf, sizeof(sbp[0]->s_volume_name), "%s\n",
 904                          sbp[0]->s_volume_name);
 905 }
 906 
 907 static const char dev_readme_str[] =
 908         "The <device> group contains attributes that describe file system\n"
 909         "partition's details.\n\n"
 910         "(1) revision\n\tshow NILFS file system revision.\n\n"
 911         "(2) blocksize\n\tshow volume block size in bytes.\n\n"
 912         "(3) device_size\n\tshow volume size in bytes.\n\n"
 913         "(4) free_blocks\n\tshow count of free blocks on volume.\n\n"
 914         "(5) uuid\n\tshow volume's UUID.\n\n"
 915         "(6) volume_name\n\tshow volume's name.\n\n";
 916 
 917 static ssize_t nilfs_dev_README_show(struct nilfs_dev_attr *attr,
 918                                      struct the_nilfs *nilfs,
 919                                      char *buf)
 920 {
 921         return snprintf(buf, PAGE_SIZE, dev_readme_str);
 922 }
 923 
 924 NILFS_DEV_RO_ATTR(revision);
 925 NILFS_DEV_RO_ATTR(blocksize);
 926 NILFS_DEV_RO_ATTR(device_size);
 927 NILFS_DEV_RO_ATTR(free_blocks);
 928 NILFS_DEV_RO_ATTR(uuid);
 929 NILFS_DEV_RO_ATTR(volume_name);
 930 NILFS_DEV_RO_ATTR(README);
 931 
 932 static struct attribute *nilfs_dev_attrs[] = {
 933         NILFS_DEV_ATTR_LIST(revision),
 934         NILFS_DEV_ATTR_LIST(blocksize),
 935         NILFS_DEV_ATTR_LIST(device_size),
 936         NILFS_DEV_ATTR_LIST(free_blocks),
 937         NILFS_DEV_ATTR_LIST(uuid),
 938         NILFS_DEV_ATTR_LIST(volume_name),
 939         NILFS_DEV_ATTR_LIST(README),
 940         NULL,
 941 };
 942 
 943 static ssize_t nilfs_dev_attr_show(struct kobject *kobj,
 944                                     struct attribute *attr, char *buf)
 945 {
 946         struct the_nilfs *nilfs = container_of(kobj, struct the_nilfs,
 947                                                 ns_dev_kobj);
 948         struct nilfs_dev_attr *a = container_of(attr, struct nilfs_dev_attr,
 949                                                 attr);
 950 
 951         return a->show ? a->show(a, nilfs, buf) : 0;
 952 }
 953 
 954 static ssize_t nilfs_dev_attr_store(struct kobject *kobj,
 955                                     struct attribute *attr,
 956                                     const char *buf, size_t len)
 957 {
 958         struct the_nilfs *nilfs = container_of(kobj, struct the_nilfs,
 959                                                 ns_dev_kobj);
 960         struct nilfs_dev_attr *a = container_of(attr, struct nilfs_dev_attr,
 961                                                 attr);
 962 
 963         return a->store ? a->store(a, nilfs, buf, len) : 0;
 964 }
 965 
 966 static void nilfs_dev_attr_release(struct kobject *kobj)
 967 {
 968         struct the_nilfs *nilfs = container_of(kobj, struct the_nilfs,
 969                                                 ns_dev_kobj);
 970         complete(&nilfs->ns_dev_kobj_unregister);
 971 }
 972 
 973 static const struct sysfs_ops nilfs_dev_attr_ops = {
 974         .show   = nilfs_dev_attr_show,
 975         .store  = nilfs_dev_attr_store,
 976 };
 977 
 978 static struct kobj_type nilfs_dev_ktype = {
 979         .default_attrs  = nilfs_dev_attrs,
 980         .sysfs_ops      = &nilfs_dev_attr_ops,
 981         .release        = nilfs_dev_attr_release,
 982 };
 983 
 984 int nilfs_sysfs_create_device_group(struct super_block *sb)
 985 {
 986         struct the_nilfs *nilfs = sb->s_fs_info;
 987         size_t devgrp_size = sizeof(struct nilfs_sysfs_dev_subgroups);
 988         int err;
 989 
 990         nilfs->ns_dev_subgroups = kzalloc(devgrp_size, GFP_KERNEL);
 991         if (unlikely(!nilfs->ns_dev_subgroups)) {
 992                 err = -ENOMEM;
 993                 nilfs_msg(sb, KERN_ERR,
 994                           "unable to allocate memory for device group");
 995                 goto failed_create_device_group;
 996         }
 997 
 998         nilfs->ns_dev_kobj.kset = nilfs_kset;
 999         init_completion(&nilfs->ns_dev_kobj_unregister);
1000         err = kobject_init_and_add(&nilfs->ns_dev_kobj, &nilfs_dev_ktype, NULL,
1001                                     "%s", sb->s_id);
1002         if (err)
1003                 goto free_dev_subgroups;
1004 
1005         err = nilfs_sysfs_create_mounted_snapshots_group(nilfs);
1006         if (err)
1007                 goto cleanup_dev_kobject;
1008 
1009         err = nilfs_sysfs_create_checkpoints_group(nilfs);
1010         if (err)
1011                 goto delete_mounted_snapshots_group;
1012 
1013         err = nilfs_sysfs_create_segments_group(nilfs);
1014         if (err)
1015                 goto delete_checkpoints_group;
1016 
1017         err = nilfs_sysfs_create_superblock_group(nilfs);
1018         if (err)
1019                 goto delete_segments_group;
1020 
1021         err = nilfs_sysfs_create_segctor_group(nilfs);
1022         if (err)
1023                 goto delete_superblock_group;
1024 
1025         return 0;
1026 
1027 delete_superblock_group:
1028         nilfs_sysfs_delete_superblock_group(nilfs);
1029 
1030 delete_segments_group:
1031         nilfs_sysfs_delete_segments_group(nilfs);
1032 
1033 delete_checkpoints_group:
1034         nilfs_sysfs_delete_checkpoints_group(nilfs);
1035 
1036 delete_mounted_snapshots_group:
1037         nilfs_sysfs_delete_mounted_snapshots_group(nilfs);
1038 
1039 cleanup_dev_kobject:
1040         kobject_del(&nilfs->ns_dev_kobj);
1041 
1042 free_dev_subgroups:
1043         kfree(nilfs->ns_dev_subgroups);
1044 
1045 failed_create_device_group:
1046         return err;
1047 }
1048 
1049 void nilfs_sysfs_delete_device_group(struct the_nilfs *nilfs)
1050 {
1051         nilfs_sysfs_delete_mounted_snapshots_group(nilfs);
1052         nilfs_sysfs_delete_checkpoints_group(nilfs);
1053         nilfs_sysfs_delete_segments_group(nilfs);
1054         nilfs_sysfs_delete_superblock_group(nilfs);
1055         nilfs_sysfs_delete_segctor_group(nilfs);
1056         kobject_del(&nilfs->ns_dev_kobj);
1057         kfree(nilfs->ns_dev_subgroups);
1058 }
1059 
1060 /************************************************************************
1061  *                        NILFS feature attrs                           *
1062  ************************************************************************/
1063 
1064 static ssize_t nilfs_feature_revision_show(struct kobject *kobj,
1065                                             struct attribute *attr, char *buf)
1066 {
1067         return snprintf(buf, PAGE_SIZE, "%d.%d\n",
1068                         NILFS_CURRENT_REV, NILFS_MINOR_REV);
1069 }
1070 
1071 static const char features_readme_str[] =
1072         "The features group contains attributes that describe NILFS file\n"
1073         "system driver features.\n\n"
1074         "(1) revision\n\tshow current revision of NILFS file system driver.\n";
1075 
1076 static ssize_t nilfs_feature_README_show(struct kobject *kobj,
1077                                          struct attribute *attr,
1078                                          char *buf)
1079 {
1080         return snprintf(buf, PAGE_SIZE, features_readme_str);
1081 }
1082 
1083 NILFS_FEATURE_RO_ATTR(revision);
1084 NILFS_FEATURE_RO_ATTR(README);
1085 
1086 static struct attribute *nilfs_feature_attrs[] = {
1087         NILFS_FEATURE_ATTR_LIST(revision),
1088         NILFS_FEATURE_ATTR_LIST(README),
1089         NULL,
1090 };
1091 
1092 static const struct attribute_group nilfs_feature_attr_group = {
1093         .name = "features",
1094         .attrs = nilfs_feature_attrs,
1095 };
1096 
1097 int __init nilfs_sysfs_init(void)
1098 {
1099         int err;
1100 
1101         nilfs_kset = kset_create_and_add(NILFS_ROOT_GROUP_NAME, NULL, fs_kobj);
1102         if (!nilfs_kset) {
1103                 err = -ENOMEM;
1104                 nilfs_msg(NULL, KERN_ERR,
1105                           "unable to create sysfs entry: err=%d", err);
1106                 goto failed_sysfs_init;
1107         }
1108 
1109         err = sysfs_create_group(&nilfs_kset->kobj, &nilfs_feature_attr_group);
1110         if (unlikely(err)) {
1111                 nilfs_msg(NULL, KERN_ERR,
1112                           "unable to create feature group: err=%d", err);
1113                 goto cleanup_sysfs_init;
1114         }
1115 
1116         return 0;
1117 
1118 cleanup_sysfs_init:
1119         kset_unregister(nilfs_kset);
1120 
1121 failed_sysfs_init:
1122         return err;
1123 }
1124 
1125 void nilfs_sysfs_exit(void)
1126 {
1127         sysfs_remove_group(&nilfs_kset->kobj, &nilfs_feature_attr_group);
1128         kset_unregister(nilfs_kset);
1129 }

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