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