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