aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--Documentation/ABI/testing/sysfs-fs-nilfs290
-rw-r--r--fs/nilfs2/sysfs.c270
-rw-r--r--fs/nilfs2/sysfs.h16
3 files changed, 376 insertions, 0 deletions
diff --git a/Documentation/ABI/testing/sysfs-fs-nilfs2 b/Documentation/ABI/testing/sysfs-fs-nilfs2
index e9b4c61aa88a..c9952f4071e7 100644
--- a/Documentation/ABI/testing/sysfs-fs-nilfs2
+++ b/Documentation/ABI/testing/sysfs-fs-nilfs2
@@ -89,3 +89,93 @@ Contact: "Vyacheslav Dubeyko" <slava@dubeyko.com>
89Description: 89Description:
90 Describe attributes of /sys/fs/nilfs2/<device>/superblock 90 Describe attributes of /sys/fs/nilfs2/<device>/superblock
91 group. 91 group.
92
93What: /sys/fs/nilfs2/<device>/segctor/last_pseg_block
94Date: April 2014
95Contact: "Vyacheslav Dubeyko" <slava@dubeyko.com>
96Description:
97 Show start block number of the latest segment.
98
99What: /sys/fs/nilfs2/<device>/segctor/last_seg_sequence
100Date: April 2014
101Contact: "Vyacheslav Dubeyko" <slava@dubeyko.com>
102Description:
103 Show sequence value of the latest segment.
104
105What: /sys/fs/nilfs2/<device>/segctor/last_seg_checkpoint
106Date: April 2014
107Contact: "Vyacheslav Dubeyko" <slava@dubeyko.com>
108Description:
109 Show checkpoint number of the latest segment.
110
111What: /sys/fs/nilfs2/<device>/segctor/current_seg_sequence
112Date: April 2014
113Contact: "Vyacheslav Dubeyko" <slava@dubeyko.com>
114Description:
115 Show segment sequence counter.
116
117What: /sys/fs/nilfs2/<device>/segctor/current_last_full_seg
118Date: April 2014
119Contact: "Vyacheslav Dubeyko" <slava@dubeyko.com>
120Description:
121 Show index number of the latest full segment.
122
123What: /sys/fs/nilfs2/<device>/segctor/next_full_seg
124Date: April 2014
125Contact: "Vyacheslav Dubeyko" <slava@dubeyko.com>
126Description:
127 Show index number of the full segment index
128 to be used next.
129
130What: /sys/fs/nilfs2/<device>/segctor/next_pseg_offset
131Date: April 2014
132Contact: "Vyacheslav Dubeyko" <slava@dubeyko.com>
133Description:
134 Show offset of next partial segment in the current
135 full segment.
136
137What: /sys/fs/nilfs2/<device>/segctor/next_checkpoint
138Date: April 2014
139Contact: "Vyacheslav Dubeyko" <slava@dubeyko.com>
140Description:
141 Show next checkpoint number.
142
143What: /sys/fs/nilfs2/<device>/segctor/last_seg_write_time
144Date: April 2014
145Contact: "Vyacheslav Dubeyko" <slava@dubeyko.com>
146Description:
147 Show write time of the last segment in
148 human-readable format.
149
150What: /sys/fs/nilfs2/<device>/segctor/last_seg_write_time_secs
151Date: April 2014
152Contact: "Vyacheslav Dubeyko" <slava@dubeyko.com>
153Description:
154 Show write time of the last segment in seconds.
155
156What: /sys/fs/nilfs2/<device>/segctor/last_nongc_write_time
157Date: April 2014
158Contact: "Vyacheslav Dubeyko" <slava@dubeyko.com>
159Description:
160 Show write time of the last segment not for cleaner
161 operation in human-readable format.
162
163What: /sys/fs/nilfs2/<device>/segctor/last_nongc_write_time_secs
164Date: April 2014
165Contact: "Vyacheslav Dubeyko" <slava@dubeyko.com>
166Description:
167 Show write time of the last segment not for cleaner
168 operation in seconds.
169
170What: /sys/fs/nilfs2/<device>/segctor/dirty_data_blocks_count
171Date: April 2014
172Contact: "Vyacheslav Dubeyko" <slava@dubeyko.com>
173Description:
174 Show number of dirty data blocks.
175
176What: /sys/fs/nilfs2/<device>/segctor/README
177Date: April 2014
178Contact: "Vyacheslav Dubeyko" <slava@dubeyko.com>
179Description:
180 Describe attributes of /sys/fs/nilfs2/<device>/segctor
181 group.
diff --git a/fs/nilfs2/sysfs.c b/fs/nilfs2/sysfs.c
index 239f239da8ae..61454a859e81 100644
--- a/fs/nilfs2/sysfs.c
+++ b/fs/nilfs2/sysfs.c
@@ -112,6 +112,268 @@ void nilfs_sysfs_delete_##name##_group(struct the_nilfs *nilfs) \
112} 112}
113 113
114/************************************************************************ 114/************************************************************************
115 * NILFS segctor attrs *
116 ************************************************************************/
117
118static ssize_t
119nilfs_segctor_last_pseg_block_show(struct nilfs_segctor_attr *attr,
120 struct the_nilfs *nilfs,
121 char *buf)
122{
123 sector_t last_pseg;
124
125 spin_lock(&nilfs->ns_last_segment_lock);
126 last_pseg = nilfs->ns_last_pseg;
127 spin_unlock(&nilfs->ns_last_segment_lock);
128
129 return snprintf(buf, PAGE_SIZE, "%llu\n",
130 (unsigned long long)last_pseg);
131}
132
133static ssize_t
134nilfs_segctor_last_seg_sequence_show(struct nilfs_segctor_attr *attr,
135 struct the_nilfs *nilfs,
136 char *buf)
137{
138 u64 last_seq;
139
140 spin_lock(&nilfs->ns_last_segment_lock);
141 last_seq = nilfs->ns_last_seq;
142 spin_unlock(&nilfs->ns_last_segment_lock);
143
144 return snprintf(buf, PAGE_SIZE, "%llu\n", last_seq);
145}
146
147static ssize_t
148nilfs_segctor_last_seg_checkpoint_show(struct nilfs_segctor_attr *attr,
149 struct the_nilfs *nilfs,
150 char *buf)
151{
152 __u64 last_cno;
153
154 spin_lock(&nilfs->ns_last_segment_lock);
155 last_cno = nilfs->ns_last_cno;
156 spin_unlock(&nilfs->ns_last_segment_lock);
157
158 return snprintf(buf, PAGE_SIZE, "%llu\n", last_cno);
159}
160
161static ssize_t
162nilfs_segctor_current_seg_sequence_show(struct nilfs_segctor_attr *attr,
163 struct the_nilfs *nilfs,
164 char *buf)
165{
166 u64 seg_seq;
167
168 down_read(&nilfs->ns_sem);
169 seg_seq = nilfs->ns_seg_seq;
170 up_read(&nilfs->ns_sem);
171
172 return snprintf(buf, PAGE_SIZE, "%llu\n", seg_seq);
173}
174
175static ssize_t
176nilfs_segctor_current_last_full_seg_show(struct nilfs_segctor_attr *attr,
177 struct the_nilfs *nilfs,
178 char *buf)
179{
180 __u64 segnum;
181
182 down_read(&nilfs->ns_sem);
183 segnum = nilfs->ns_segnum;
184 up_read(&nilfs->ns_sem);
185
186 return snprintf(buf, PAGE_SIZE, "%llu\n", segnum);
187}
188
189static ssize_t
190nilfs_segctor_next_full_seg_show(struct nilfs_segctor_attr *attr,
191 struct the_nilfs *nilfs,
192 char *buf)
193{
194 __u64 nextnum;
195
196 down_read(&nilfs->ns_sem);
197 nextnum = nilfs->ns_nextnum;
198 up_read(&nilfs->ns_sem);
199
200 return snprintf(buf, PAGE_SIZE, "%llu\n", nextnum);
201}
202
203static ssize_t
204nilfs_segctor_next_pseg_offset_show(struct nilfs_segctor_attr *attr,
205 struct the_nilfs *nilfs,
206 char *buf)
207{
208 unsigned long pseg_offset;
209
210 down_read(&nilfs->ns_sem);
211 pseg_offset = nilfs->ns_pseg_offset;
212 up_read(&nilfs->ns_sem);
213
214 return snprintf(buf, PAGE_SIZE, "%lu\n", pseg_offset);
215}
216
217static ssize_t
218nilfs_segctor_next_checkpoint_show(struct nilfs_segctor_attr *attr,
219 struct the_nilfs *nilfs,
220 char *buf)
221{
222 __u64 cno;
223
224 down_read(&nilfs->ns_sem);
225 cno = nilfs->ns_cno;
226 up_read(&nilfs->ns_sem);
227
228 return snprintf(buf, PAGE_SIZE, "%llu\n", cno);
229}
230
231static ssize_t
232nilfs_segctor_last_seg_write_time_show(struct nilfs_segctor_attr *attr,
233 struct the_nilfs *nilfs,
234 char *buf)
235{
236 time_t ctime;
237
238 down_read(&nilfs->ns_sem);
239 ctime = nilfs->ns_ctime;
240 up_read(&nilfs->ns_sem);
241
242 return NILFS_SHOW_TIME(ctime, buf);
243}
244
245static ssize_t
246nilfs_segctor_last_seg_write_time_secs_show(struct nilfs_segctor_attr *attr,
247 struct the_nilfs *nilfs,
248 char *buf)
249{
250 time_t ctime;
251
252 down_read(&nilfs->ns_sem);
253 ctime = nilfs->ns_ctime;
254 up_read(&nilfs->ns_sem);
255
256 return snprintf(buf, PAGE_SIZE, "%llu\n", (unsigned long long)ctime);
257}
258
259static ssize_t
260nilfs_segctor_last_nongc_write_time_show(struct nilfs_segctor_attr *attr,
261 struct the_nilfs *nilfs,
262 char *buf)
263{
264 time_t nongc_ctime;
265
266 down_read(&nilfs->ns_sem);
267 nongc_ctime = nilfs->ns_nongc_ctime;
268 up_read(&nilfs->ns_sem);
269
270 return NILFS_SHOW_TIME(nongc_ctime, buf);
271}
272
273static ssize_t
274nilfs_segctor_last_nongc_write_time_secs_show(struct nilfs_segctor_attr *attr,
275 struct the_nilfs *nilfs,
276 char *buf)
277{
278 time_t nongc_ctime;
279
280 down_read(&nilfs->ns_sem);
281 nongc_ctime = nilfs->ns_nongc_ctime;
282 up_read(&nilfs->ns_sem);
283
284 return snprintf(buf, PAGE_SIZE, "%llu\n",
285 (unsigned long long)nongc_ctime);
286}
287
288static ssize_t
289nilfs_segctor_dirty_data_blocks_count_show(struct nilfs_segctor_attr *attr,
290 struct the_nilfs *nilfs,
291 char *buf)
292{
293 u32 ndirtyblks;
294
295 down_read(&nilfs->ns_sem);
296 ndirtyblks = atomic_read(&nilfs->ns_ndirtyblks);
297 up_read(&nilfs->ns_sem);
298
299 return snprintf(buf, PAGE_SIZE, "%u\n", ndirtyblks);
300}
301
302static const char segctor_readme_str[] =
303 "The segctor group contains attributes that describe\n"
304 "segctor thread activity details.\n\n"
305 "(1) last_pseg_block\n"
306 "\tshow start block number of the latest segment.\n\n"
307 "(2) last_seg_sequence\n"
308 "\tshow sequence value of the latest segment.\n\n"
309 "(3) last_seg_checkpoint\n"
310 "\tshow checkpoint number of the latest segment.\n\n"
311 "(4) current_seg_sequence\n\tshow segment sequence counter.\n\n"
312 "(5) current_last_full_seg\n"
313 "\tshow index number of the latest full segment.\n\n"
314 "(6) next_full_seg\n"
315 "\tshow index number of the full segment index to be used next.\n\n"
316 "(7) next_pseg_offset\n"
317 "\tshow offset of next partial segment in the current full segment.\n\n"
318 "(8) next_checkpoint\n\tshow next checkpoint number.\n\n"
319 "(9) last_seg_write_time\n"
320 "\tshow write time of the last segment in human-readable format.\n\n"
321 "(10) last_seg_write_time_secs\n"
322 "\tshow write time of the last segment in seconds.\n\n"
323 "(11) last_nongc_write_time\n"
324 "\tshow write time of the last segment not for cleaner operation "
325 "in human-readable format.\n\n"
326 "(12) last_nongc_write_time_secs\n"
327 "\tshow write time of the last segment not for cleaner operation "
328 "in seconds.\n\n"
329 "(13) dirty_data_blocks_count\n"
330 "\tshow number of dirty data blocks.\n\n";
331
332static ssize_t
333nilfs_segctor_README_show(struct nilfs_segctor_attr *attr,
334 struct the_nilfs *nilfs, char *buf)
335{
336 return snprintf(buf, PAGE_SIZE, segctor_readme_str);
337}
338
339NILFS_SEGCTOR_RO_ATTR(last_pseg_block);
340NILFS_SEGCTOR_RO_ATTR(last_seg_sequence);
341NILFS_SEGCTOR_RO_ATTR(last_seg_checkpoint);
342NILFS_SEGCTOR_RO_ATTR(current_seg_sequence);
343NILFS_SEGCTOR_RO_ATTR(current_last_full_seg);
344NILFS_SEGCTOR_RO_ATTR(next_full_seg);
345NILFS_SEGCTOR_RO_ATTR(next_pseg_offset);
346NILFS_SEGCTOR_RO_ATTR(next_checkpoint);
347NILFS_SEGCTOR_RO_ATTR(last_seg_write_time);
348NILFS_SEGCTOR_RO_ATTR(last_seg_write_time_secs);
349NILFS_SEGCTOR_RO_ATTR(last_nongc_write_time);
350NILFS_SEGCTOR_RO_ATTR(last_nongc_write_time_secs);
351NILFS_SEGCTOR_RO_ATTR(dirty_data_blocks_count);
352NILFS_SEGCTOR_RO_ATTR(README);
353
354static struct attribute *nilfs_segctor_attrs[] = {
355 NILFS_SEGCTOR_ATTR_LIST(last_pseg_block),
356 NILFS_SEGCTOR_ATTR_LIST(last_seg_sequence),
357 NILFS_SEGCTOR_ATTR_LIST(last_seg_checkpoint),
358 NILFS_SEGCTOR_ATTR_LIST(current_seg_sequence),
359 NILFS_SEGCTOR_ATTR_LIST(current_last_full_seg),
360 NILFS_SEGCTOR_ATTR_LIST(next_full_seg),
361 NILFS_SEGCTOR_ATTR_LIST(next_pseg_offset),
362 NILFS_SEGCTOR_ATTR_LIST(next_checkpoint),
363 NILFS_SEGCTOR_ATTR_LIST(last_seg_write_time),
364 NILFS_SEGCTOR_ATTR_LIST(last_seg_write_time_secs),
365 NILFS_SEGCTOR_ATTR_LIST(last_nongc_write_time),
366 NILFS_SEGCTOR_ATTR_LIST(last_nongc_write_time_secs),
367 NILFS_SEGCTOR_ATTR_LIST(dirty_data_blocks_count),
368 NILFS_SEGCTOR_ATTR_LIST(README),
369 NULL,
370};
371
372NILFS_DEV_INT_GROUP_OPS(segctor, dev);
373NILFS_DEV_INT_GROUP_TYPE(segctor, dev);
374NILFS_DEV_INT_GROUP_FNS(segctor, dev);
375
376/************************************************************************
115 * NILFS superblock attrs * 377 * NILFS superblock attrs *
116 ************************************************************************/ 378 ************************************************************************/
117 379
@@ -406,8 +668,15 @@ int nilfs_sysfs_create_device_group(struct super_block *sb)
406 if (err) 668 if (err)
407 goto cleanup_dev_kobject; 669 goto cleanup_dev_kobject;
408 670
671 err = nilfs_sysfs_create_segctor_group(nilfs);
672 if (err)
673 goto delete_superblock_group;
674
409 return 0; 675 return 0;
410 676
677delete_superblock_group:
678 nilfs_sysfs_delete_superblock_group(nilfs);
679
411cleanup_dev_kobject: 680cleanup_dev_kobject:
412 kobject_del(&nilfs->ns_dev_kobj); 681 kobject_del(&nilfs->ns_dev_kobj);
413 682
@@ -421,6 +690,7 @@ failed_create_device_group:
421void nilfs_sysfs_delete_device_group(struct the_nilfs *nilfs) 690void nilfs_sysfs_delete_device_group(struct the_nilfs *nilfs)
422{ 691{
423 nilfs_sysfs_delete_superblock_group(nilfs); 692 nilfs_sysfs_delete_superblock_group(nilfs);
693 nilfs_sysfs_delete_segctor_group(nilfs);
424 kobject_del(&nilfs->ns_dev_kobj); 694 kobject_del(&nilfs->ns_dev_kobj);
425 kfree(nilfs->ns_dev_subgroups); 695 kfree(nilfs->ns_dev_subgroups);
426} 696}
diff --git a/fs/nilfs2/sysfs.h b/fs/nilfs2/sysfs.h
index 1d76af59238c..ad4d5bcc16f5 100644
--- a/fs/nilfs2/sysfs.h
+++ b/fs/nilfs2/sysfs.h
@@ -28,11 +28,17 @@
28 * struct nilfs_sysfs_dev_subgroups - device subgroup kernel objects 28 * struct nilfs_sysfs_dev_subgroups - device subgroup kernel objects
29 * @sg_superblock_kobj: /sys/fs/<nilfs>/<device>/superblock 29 * @sg_superblock_kobj: /sys/fs/<nilfs>/<device>/superblock
30 * @sg_superblock_kobj_unregister: completion state 30 * @sg_superblock_kobj_unregister: completion state
31 * @sg_segctor_kobj: /sys/fs/<nilfs>/<device>/segctor
32 * @sg_segctor_kobj_unregister: completion state
31 */ 33 */
32struct nilfs_sysfs_dev_subgroups { 34struct nilfs_sysfs_dev_subgroups {
33 /* /sys/fs/<nilfs>/<device>/superblock */ 35 /* /sys/fs/<nilfs>/<device>/superblock */
34 struct kobject sg_superblock_kobj; 36 struct kobject sg_superblock_kobj;
35 struct completion sg_superblock_kobj_unregister; 37 struct completion sg_superblock_kobj_unregister;
38
39 /* /sys/fs/<nilfs>/<device>/segctor */
40 struct kobject sg_segctor_kobj;
41 struct completion sg_segctor_kobj_unregister;
36}; 42};
37 43
38#define NILFS_COMMON_ATTR_STRUCT(name) \ 44#define NILFS_COMMON_ATTR_STRUCT(name) \
@@ -57,6 +63,7 @@ struct nilfs_##name##_attr { \
57 63
58NILFS_DEV_ATTR_STRUCT(dev); 64NILFS_DEV_ATTR_STRUCT(dev);
59NILFS_DEV_ATTR_STRUCT(superblock); 65NILFS_DEV_ATTR_STRUCT(superblock);
66NILFS_DEV_ATTR_STRUCT(segctor);
60 67
61#define NILFS_ATTR(type, name, mode, show, store) \ 68#define NILFS_ATTR(type, name, mode, show, store) \
62 static struct nilfs_##type##_attr nilfs_##type##_attr_##name = \ 69 static struct nilfs_##type##_attr nilfs_##type##_attr_##name = \
@@ -90,11 +97,20 @@ NILFS_DEV_ATTR_STRUCT(superblock);
90#define NILFS_SUPERBLOCK_RW_ATTR(name) \ 97#define NILFS_SUPERBLOCK_RW_ATTR(name) \
91 NILFS_RW_ATTR(superblock, name) 98 NILFS_RW_ATTR(superblock, name)
92 99
100#define NILFS_SEGCTOR_INFO_ATTR(name) \
101 NILFS_INFO_ATTR(segctor, name)
102#define NILFS_SEGCTOR_RO_ATTR(name) \
103 NILFS_RO_ATTR(segctor, name)
104#define NILFS_SEGCTOR_RW_ATTR(name) \
105 NILFS_RW_ATTR(segctor, name)
106
93#define NILFS_FEATURE_ATTR_LIST(name) \ 107#define NILFS_FEATURE_ATTR_LIST(name) \
94 (&nilfs_feature_attr_##name.attr) 108 (&nilfs_feature_attr_##name.attr)
95#define NILFS_DEV_ATTR_LIST(name) \ 109#define NILFS_DEV_ATTR_LIST(name) \
96 (&nilfs_dev_attr_##name.attr) 110 (&nilfs_dev_attr_##name.attr)
97#define NILFS_SUPERBLOCK_ATTR_LIST(name) \ 111#define NILFS_SUPERBLOCK_ATTR_LIST(name) \
98 (&nilfs_superblock_attr_##name.attr) 112 (&nilfs_superblock_attr_##name.attr)
113#define NILFS_SEGCTOR_ATTR_LIST(name) \
114 (&nilfs_segctor_attr_##name.attr)
99 115
100#endif /* _NILFS_SYSFS_H */ 116#endif /* _NILFS_SYSFS_H */