1#![recursion_limit="100"]
2#[macro_use]
3extern crate nom;
4
5use std::error;
6use std::fmt;
7use std::fs::File;
8use std::io;
9use std::io::prelude::*;
10use std::str::FromStr;
11
12use self::nom::{le_u8, is_digit, space, newline};
13
14#[cfg(test)]
15mod tests {
16 use nom;
17
18 #[test]
19 fn it_parses_a_u32() {
20 let input = b"12345";
21 let result = super::take_u32(input);
22 match result {
23 nom::IResult::Done(_, f) => assert_eq!(f, 12345u32),
24 _ => unreachable!(),
25 }
26 }
27
28 #[test]
29 fn it_parses_a_u32_with_whitespace() {
30 let input = b"12345 ";
31 let result = super::take_u32(input);
32 match result {
33 nom::IResult::Done(_, f) => assert_eq!(f, 12345u32),
34 _ => unreachable!(),
35 }
36
37 }
38
39 #[test]
40 fn it_parses_extent_allocation() {
41 let example_output = b"extent_alloc 4260849 125170297 4618726 131131897";
42 match super::extent_alloc(example_output) {
43 nom::IResult::Done(_, result) => {
44 assert_eq!(result.allocated_extents, 4260849);
45 assert_eq!(result.freed_blocks, 131131897);
46 }
47 _ => unreachable!(),
48 }
49 }
50
51 #[test]
52 fn it_parses_allocation_btree() {
53 let example_output = b"abt 29491162 337391304 11257328 11133039";
54 match super::abt(example_output) {
55 nom::IResult::Done(_, result) => {
56 assert_eq!(result.inserts, 11257328);
57 }
58 _ => unreachable!(),
59 }
60 }
61
62 #[test]
63 fn it_parses_block_mapping() {
64 let example_output = b"blk_map 381213360 115456141 10903633 69612322 7448401 507596777 0";
65 match super::blk_map(example_output) {
66 nom::IResult::Done(_, result) => {
67 assert_eq!(result.list_delete, 7448401);
68 }
69 _ => unreachable!(),
70 }
71 }
72
73 #[test]
74 fn it_parses_block_map_btree() {
75 let example_output = b"bmbt 771328 6236258 602114 86646";
76 match super::bmbt(example_output) {
77 nom::IResult::Done(_, result) => {
78 assert_eq!(result.deletes, 86646);
79 }
80 _ => unreachable!(),
81 }
82 }
83
84 #[test]
85 fn it_parses_directory_operations() {
86 let example_output = b"dir 21253907 6921870 6969079 779205554";
87 match super::dir(example_output) {
88 nom::IResult::Done(_, result) => {
89 assert_eq!(result.lookups, 21253907);
90 }
91 _ => unreachable!(),
92 }
93 }
94
95 #[test]
96 fn it_parses_transactions() {
97 let example_output = b"trans 126946406 38184616 6342392";
98 match super::trans(example_output) {
99 nom::IResult::Done(_, result) => {
100 assert_eq!(result.waited, 126946406);
101 }
102 _ => unreachable!(),
103 }
104 }
105
106 #[test]
107 fn it_parses_inode_operations() {
108 let example_output = b"ig 17754368 2019571 102 15734797 0 15672217 3962470";
109 match super::ig(example_output) {
110 nom::IResult::Done(_, result) => {
111 assert_eq!(result.cache_lookups, 17754368);
112 }
113 _ => unreachable!(),
114 }
115 }
116
117 #[test]
118 fn it_parses_log_operations() {
119 let example_output = b"log 129491915 3992515264 458018 153771989 127040250";
120 match super::log(example_output) {
121 nom::IResult::Done(_, result) => {
122 assert_eq!(result.log_writes, 129491915);
123 }
124 _ => unreachable!(),
125 }
126 }
127
128 #[test]
129 fn it_parses_tail_pushing_stats() {
130 let example_output = b"push_ail 171473415 0 6896837 3324292 8069877 65884 1289485 0 22535 7337";
131 match super::push_ail(example_output) {
132 nom::IResult::Done(_, result) => {
133 assert_eq!(result.logspace, 171473415);
134 }
135 _ => unreachable!(),
136 }
137 }
138
139 #[test]
140 fn it_parses_io_map_write_convert() {
141 let example_output = b"xstrat 4140059 0";
142 match super::xstrat(example_output) {
143 nom::IResult::Done(_, result) => {
144 assert_eq!(result.quick, 4140059);
145 }
146 _ => unreachable!(),
147 }
148 }
149
150 #[test]
151 fn it_parses_read_write_stats() {
152 let example_output = b"rw 1595677950 1046884251";
153 match super::rw(example_output) {
154 nom::IResult::Done(_, result) => {
155 assert_eq!(result.write, 1595677950);
156 }
157 _ => unreachable!(),
158 }
159 }
160
161 #[test]
162 fn it_parses_attribute_operations() {
163 let example_output = b"attr 194724197 0 7 0";
164 match super::attr(example_output) {
165 nom::IResult::Done(_, result) => {
166 assert_eq!(result.get, 194724197);
167 }
168 _ => unreachable!(),
169 }
170 }
171
172 #[test]
173 fn it_parses_inode_clustering() {
174 let example_output = b"icluster 20772185 2488203 13909520";
175 match super::icluster(example_output) {
176 nom::IResult::Done(_, result) => {
177 assert_eq!(result.count, 20772185);
178 }
179 _ => unreachable!(),
180 }
181 }
182
183 #[test]
184 fn it_parses_vnode_statistics() {
185 let example_output = b"vnodes 62578 15959666 0 0 15897088 15897088 15897088 0";
186 match super::vnodes(example_output) {
187 nom::IResult::Done(_, result) => {
188 assert_eq!(result.active, 62578);
189 }
190 _ => unreachable!(),
191 }
192 }
193
194 #[test]
195 fn it_parses_buf_statistics() {
196 let example_output = b"buf 2090581631 1972536890 118044776 225145 9486625 0 0 2000152616 809762";
197 match super::buf(example_output) {
198 nom::IResult::Done(_, result) => {
199 assert_eq!(result.get, 2090581631);
200 }
201 _ => unreachable!(),
202 }
203 }
204
205 #[test]
206 fn it_parses_extended_precision_counters() {
207 let example_output = b"xpc 6908312903680 67735504884757 19760115252482";
208 match super::xpc(example_output) {
209 nom::IResult::Done(_, result) => {
210 assert_eq!(result.xstrat_bytes, 6908312903680);
211 }
212 _ => unreachable!(),
213 }
214 }
215
216 #[test]
217 fn it_parses_debug() {
218 let example_output = b"debug 0";
219 match super::debug(example_output) {
220 nom::IResult::Done(_, result) => {
221 assert_eq!(result, false);
222 }
223 _ => unreachable!(),
224 }
225 }
226
227 #[test]
228 fn it_parses_example() {
229 let example_output = b"extent_alloc 4260849 125170297 4618726 131131897
230abt 29491162 337391304 11257328 11133039
231blk_map 381213360 115456141 10903633 69612322 7448401 507596777 0
232bmbt 771328 6236258 602114 86646
233dir 21253907 6921870 6969079 779205554
234trans 126946406 38184616 6342392
235ig 17754368 2019571 102 15734797 0 15672217 3962470
236log 129491915 3992515264 458018 153771989 127040250
237push_ail 171473415 0 6896837 3324292 8069877 65884 1289485 0 22535 7337
238xstrat 4140059 0
239rw 1595677950 1046884251
240attr 194724197 0 7 0
241icluster 20772185 2488203 13909520
242vnodes 62578 15959666 0 0 15897088 15897088 15897088 0
243buf 2090581631 1972536890 118044776 225145 9486625 0 0 2000152616 809762
244xpc 6908312903680 67735504884757 19760115252482
245debug 0";
246 let result = super::parse(example_output).unwrap();
247
248 assert_eq!(result.extent_allocation.freed_extents, 4618726);
249 assert_eq!(result.allocation_btree.lookups, 29491162);
250 assert_eq!(result.block_mapping.unmap, 10903633);
251 assert_eq!(result.block_map_btree.inserts, 602114);
252 assert_eq!(result.directory_operations.get_dents, 779205554);
253 assert_eq!(result.transactions.empty, 6342392);
254 assert_eq!(result.inode_operations.inode_attr_changes, 3962470);
255 assert_eq!(result.log_operations.force_sleep, 127040250);
256 assert_eq!(result.tail_pushing_stats.push_ail_flush, 7337);
257 assert_eq!(result.io_map_write_convert.split, 0);
258 assert_eq!(result.read_write_stats.read, 1046884251);
259 assert_eq!(result.attribute_operations.list, 0);
260 assert_eq!(result.inode_clustering.flushinode, 13909520);
261 assert_eq!(result.vnode_statistics.free, 0);
262 assert_eq!(result.buf_statistics.get_read, 809762);
263 assert_eq!(result.extended_precision_counters.read_bytes, 19760115252482);
264 assert_eq!(result.debug, false);
265 }
266
267 #[test]
268 fn it_parses_newer_version_with_extra_fields() {
269 let example_output = b"extent_alloc 0 0 0 0
270abt 0 0 0 0
271blk_map 0 0 0 0 0 0 0
272bmbt 0 0 0 0
273dir 0 0 0 0
274trans 0 0 0
275ig 0 0 0 0 0 0 0
276log 0 0 0 0 0
277push_ail 0 0 0 0 0 0 0 0 0 0
278xstrat 0 0
279rw 0 0
280attr 0 0 0 0
281icluster 0 0 0
282vnodes 0 0 0 0 0 0 0 0
283buf 0 0 0 0 0 0 0 0 0
284abtb2 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
285abtc2 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
286bmbt2 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
287ibt2 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
288fibt2 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
289qm 0 0 0 0 0 0 0 0
290xpc 0 0 0
291debug 0
292";
293 let result = super::parse(example_output).unwrap();
294 assert_eq!(result.extent_allocation.freed_extents, 0);
295 assert_eq!(result.allocation_btree.lookups, 0);
296 assert_eq!(result.block_mapping.unmap, 0);
297 assert_eq!(result.block_map_btree.inserts, 0);
298 assert_eq!(result.directory_operations.get_dents, 0);
299 assert_eq!(result.transactions.empty, 0);
300 assert_eq!(result.inode_operations.inode_attr_changes, 0);
301 assert_eq!(result.log_operations.force_sleep, 0);
302 assert_eq!(result.tail_pushing_stats.push_ail_flush, 0);
303 assert_eq!(result.io_map_write_convert.split, 0);
304 assert_eq!(result.read_write_stats.read, 0);
305 assert_eq!(result.attribute_operations.list, 0);
306 assert_eq!(result.inode_clustering.flushinode, 0);
307 assert_eq!(result.vnode_statistics.free, 0);
308 assert_eq!(result.buf_statistics.get_read, 0);
309 assert_eq!(result.extended_precision_counters.read_bytes, 0);
310 assert_eq!(result.debug, false);
311 }
312}
313
314pub struct XfsStat {
315 pub extent_allocation: ExtentAllocation,
316 pub allocation_btree: AllocationBTree,
317 pub block_mapping: BlockMapping,
318 pub block_map_btree: BlockMapBTree,
319 pub directory_operations: DirectoryOperations,
320 pub transactions: Transactions,
321 pub inode_operations: InodeOperations,
322 pub log_operations: LogOperations,
323 pub tail_pushing_stats: TailPushingStats,
324 pub io_map_write_convert: IoMapWriteConvert,
325 pub read_write_stats: ReadWriteStats,
326 pub attribute_operations: AttributeOperations,
327 pub inode_clustering: InodeClustering,
328 pub vnode_statistics: VnodeStatistics,
329 pub buf_statistics: BufStatistics,
330 pub extended_precision_counters: ExtendedPrecisionCounters,
331 pub debug: bool,
332}
333
334pub struct ExtentAllocation {
335 pub allocated_extents: u32,
337 pub allocated_blocks: u32,
339 pub freed_extents: u32,
341 pub freed_blocks: u32,
343}
344
345pub struct AllocationBTree {
346 pub lookups: u32,
348 pub compares: u32,
350 pub inserts: u32,
352 pub deletes: u32,
354}
355
356pub struct BlockMapping {
357 pub map_read: u32,
359 pub map_write: u32,
361 pub unmap: u32,
363 pub list_insert: u32,
365 pub list_delete: u32,
367 pub list_lookup: u32,
369 pub list_compare: u32,
371}
372
373pub struct BlockMapBTree {
374 pub lookups: u32,
376 pub compares: u32,
378 pub inserts: u32,
380 pub deletes: u32,
382}
383
384pub struct DirectoryOperations {
385 pub lookups: u32,
391 pub creates: u32,
393 pub removes: u32,
395 pub get_dents: u32,
397}
398
399pub struct Transactions {
400 pub waited: u32,
402 pub async: u32,
404 pub empty: u32,
406}
407
408pub struct InodeOperations {
409 pub cache_lookups: u32,
411 pub cache_hits: u32,
413 pub cache_recycle: u32,
415 pub cache_missed: u32,
417 pub cache_dup: u32,
419 pub cache_reclaime: u32,
421 pub inode_attr_changes: u32,
423}
424
425pub struct LogOperations {
426 pub log_writes: u32,
428 pub log_blocks: u32,
430 pub noiclogs: u32,
432 pub log_forced: u32,
434 pub force_sleep: u32,
436}
437
438pub struct TailPushingStats {
439 pub logspace: u32,
441 pub sleep_logspace: u32,
443 pub push_ails: u32,
445 pub push_ail_success: u32,
447 pub push_ail_pushbuf: u32,
449 pub push_ail_pinned: u32,
451 pub push_ail_locked: u32,
453 pub push_ail_flushing: u32,
455 pub push_ail_restarts: u32,
457 pub push_ail_flush: u32,
459}
460
461pub struct IoMapWriteConvert {
462 pub quick: u32,
464 pub split: u32,
466}
467
468pub struct ReadWriteStats {
469 pub write: u32,
471 pub read: u32,
473}
474
475pub struct AttributeOperations {
476 pub get: u32,
478 pub set: u32,
480 pub remove: u32,
482 pub list: u32,
484}
485
486pub struct InodeClustering {
487 pub count: u32,
489 pub flushcnt: u32,
491 pub flushinode: u32,
493}
494
495pub struct VnodeStatistics {
496 pub active: u32,
498 pub alloc: u32,
500 pub get: u32,
502 pub hold: u32,
504 pub rele: u32,
506 pub reclaim: u32,
508 pub remove: u32,
510 pub free: u32,
512}
513
514pub struct BufStatistics {
515 pub get: u32,
516 pub create: u32,
517 pub get_locked: u32,
518 pub get_locked_waited: u32,
519 pub busy_locked: u32,
520 pub miss_locked: u32,
521 pub page_retries: u32,
522 pub page_found: u32,
523 pub get_read: u32,
524}
525
526pub struct ExtendedPrecisionCounters {
527 pub xstrat_bytes: u64,
529 pub write_bytes: u64,
531 pub read_bytes: u64,
533}
534
535#[derive(Debug)]
536pub enum XfsError {
537 Io(io::Error),
539 Incomplete,
541 Parse,
543}
544
545impl fmt::Display for XfsError {
546 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
547 match *self {
548 XfsError::Io(ref err) => write!(f, "IO error: {}", err),
551 XfsError::Incomplete => write!(f, "Not enough data for XFS parse"),
552 XfsError::Parse => write!(f, "Parse error"),
553 }
554 }
555}
556
557impl error::Error for XfsError {
558 fn description(&self) -> &str {
559 match *self {
562 XfsError::Io(ref err) => err.description(),
563 XfsError::Incomplete => "There is not enough data for parsing",
564 XfsError::Parse => "There was an error parsing",
565 }
566 }
567
568 fn cause(&self) -> Option<&error::Error> {
569 match *self {
570 XfsError::Io(ref err) => Some(err),
575 XfsError::Incomplete => None,
576 XfsError::Parse => None,
577 }
578 }
579}
580
581impl From<io::Error> for XfsError {
582 fn from(err: io::Error) -> XfsError {
583 XfsError::Io(err)
584 }
585}
586
587pub fn parse(input: &[u8]) -> Result<XfsStat, XfsError> {
588 match xfs_stat(input) {
589 nom::IResult::Done(_, stat) => Ok(stat),
590 nom::IResult::Error(_) => {
591 Err(XfsError::Parse)
592 },
593 nom::IResult::Incomplete(_) => {
594 Err(XfsError::Incomplete)
595 },
596 }
598}
599
600pub fn read() -> Result<String, XfsError> {
601 let mut f = try!(File::open("/proc/fs/xfs/stat"));
602 let mut s = String::new();
603 try!(f.read_to_string(&mut s));
604 Ok(s)
605}
606
607pub fn get() -> Result<XfsStat, XfsError> {
608 let contents = try!(read());
609 parse((&contents[..]).as_bytes())
610}
611
612named!(xfs_stat <XfsStat>,
613 chain!(
614 extent_alloc: extent_alloc ~
615 newline ~
616 abt: abt ~
617 newline ~
618 blk_map: blk_map ~
619 newline ~
620 block_map_btree: bmbt ~
621 newline ~
622 directory_operations: dir ~
623 newline ~
624 transactions: trans ~
625 newline ~
626 inode_operations: ig ~
627 newline ~
628 log_operations: log ~
629 newline ~
630 tail_pushing_stats: push_ail ~
631 newline ~
632 io_map_write_convert: xstrat ~
633 newline ~
634 read_write_stats: rw ~
635 newline ~
636 attribute_operations: attr ~
637 newline ~
638 inode_clustering: icluster ~
639 newline ~
640 vnode_statistics: vnodes ~
641 newline ~
642 buf_statistics: buf ~
643 newline ~
644 extended_precision_counters: xpc ~
645 newline ~
646 dbg: debug,
647 || {
648 XfsStat {
649 extent_allocation: extent_alloc,
650 allocation_btree: abt,
651 block_mapping: blk_map,
652 block_map_btree: block_map_btree,
653 directory_operations: directory_operations,
654 transactions: transactions,
655 inode_operations: inode_operations,
656 log_operations:log_operations,
657 tail_pushing_stats: tail_pushing_stats,
658 io_map_write_convert: io_map_write_convert,
659 read_write_stats: read_write_stats,
660 attribute_operations: attribute_operations,
661 inode_clustering: inode_clustering,
662 vnode_statistics: vnode_statistics,
663 buf_statistics: buf_statistics,
664 extended_precision_counters: extended_precision_counters,
665 debug: dbg,
666 }
667 }
668 )
669);
670
671named!(debug <bool>,
672 chain!(
673 tag!("debug") ~
674 space ~
675 dbg: le_u8,
676 || {
677 if dbg == 1 {
678 true
679 } else {
680 false
681 }
682 }
683 )
684);
685
686named!(take_u32 <u32>,
687 chain!(
688 uint_slice: take_while!(is_digit) ~
689 opt!(space),
690 || {
691 let int_str = String::from_utf8_lossy(uint_slice);
692 u32::from_str(&int_str[..]).unwrap()
693 }
694 )
695);
696
697named!(take_u64 <u64>,
698 chain!(
699 uint_slice: take_while!(is_digit) ~
700 opt!(space),
701 || {
702 let int_str = String::from_utf8_lossy(uint_slice);
703 u64::from_str(&int_str[..]).unwrap()
704 }
705 )
706);
707
708
709named!(extent_alloc <ExtentAllocation>,
710 chain!(
711 tag!("extent_alloc") ~
712 space ~
713 allocx: take_u32 ~
714 allocb: take_u32 ~
715 freex: take_u32 ~
716 freeb: take_u32,
717 || {
718 ExtentAllocation {
719 allocated_extents: allocx,
720 allocated_blocks: allocb,
721 freed_extents: freex,
722 freed_blocks: freeb,
723 }
724 }
725 )
726);
727
728named!(abt <AllocationBTree>,
729 chain!(
730 tag!("abt") ~
731 space ~
732 lookups: take_u32 ~
733 compares: take_u32 ~
734 inserts: take_u32 ~
735 deletes: take_u32,
736 || {
737 AllocationBTree {
738 lookups: lookups,
739 compares: compares,
740 inserts: inserts,
741 deletes: deletes,
742 }
743 }
744 )
745);
746
747named!(blk_map <BlockMapping>,
748 chain!(
749 tag!("blk_map") ~
750 space ~
751 map_read: take_u32 ~
752 map_write: take_u32 ~
753 unmap: take_u32 ~
754 list_insert: take_u32 ~
755 list_delete: take_u32 ~
756 list_lookup: take_u32 ~
757 list_compare: take_u32,
758 ||{
759 BlockMapping {
760 map_read: map_read,
761 map_write: map_write,
762 unmap: unmap,
763 list_insert: list_insert,
764 list_delete: list_delete,
765 list_lookup: list_lookup,
766 list_compare: list_compare,
767 }
768 }
769 )
770);
771
772named!(bmbt <BlockMapBTree>,
773 chain!(
774 tag!("bmbt") ~
775 space ~
776 lookup: take_u32 ~
777 compare: take_u32 ~
778 insrec: take_u32 ~
779 delrec: take_u32,
780 || {
781 BlockMapBTree {
782 lookups: lookup,
783 compares: compare,
784 inserts: insrec,
785 deletes: delrec,
786 }
787 }
788 )
789);
790
791named!(dir <DirectoryOperations>,
792 chain!(
793 tag!("dir") ~
794 space ~
795 lookups: take_u32 ~
796 creates: take_u32 ~
797 removes: take_u32 ~
798 get_dents: take_u32,
799 || {
800 DirectoryOperations {
801 lookups: lookups,
802 creates: creates,
803 removes: removes,
804 get_dents: get_dents,
805 }
806 }
807 )
808);
809
810named!(trans <Transactions>,
811 chain!(
812 tag!("trans") ~
813 space ~
814 waited: take_u32 ~
815 async: take_u32 ~
816 empty: take_u32,
817 ||{
818 Transactions {
819 waited: waited,
820 async: async,
821 empty: empty,
822 }
823 }
824 )
825);
826
827named!(ig <InodeOperations>,
828 chain!(
829 tag!("ig") ~
830 space ~
831 cache_lookups: take_u32 ~
832 cache_hits: take_u32 ~
833 cache_recycle: take_u32 ~
834 cache_missed: take_u32 ~
835 cache_dup: take_u32 ~
836 cache_reclaime: take_u32 ~
837 inode_attr_changes: take_u32,
838 || {
839 InodeOperations {
840 cache_lookups: cache_lookups,
841 cache_hits: cache_hits,
842 cache_recycle: cache_recycle,
843 cache_missed: cache_missed,
844 cache_dup: cache_dup,
845 cache_reclaime: cache_reclaime,
846 inode_attr_changes: inode_attr_changes,
847 }
848 }
849 )
850);
851
852named!(log <LogOperations>,
853 chain!(
854 tag!("log") ~
855 space ~
856 log_writes: take_u32 ~
857 log_blocks: take_u32 ~
858 noiclogs: take_u32 ~
859 log_forced: take_u32 ~
860 force_sleep: take_u32,
861 || {
862 LogOperations {
863 log_writes: log_writes,
864 log_blocks: log_blocks,
865 noiclogs: noiclogs,
866 log_forced: log_forced,
867 force_sleep: force_sleep,
868 }
869 }
870 )
871);
872
873named!(push_ail <TailPushingStats>,
874 chain!(
875 tag!("push_ail") ~
876 space ~
877 logspace: take_u32 ~
878 sleep_logspace: take_u32 ~
879 push_ails: take_u32 ~
880 push_ail_success: take_u32 ~
881 push_ail_pushbuf: take_u32 ~
882 push_ail_pinned: take_u32 ~
883 push_ail_locked: take_u32 ~
884 push_ail_flushing: take_u32 ~
885 push_ail_restarts: take_u32 ~
886 push_ail_flush: take_u32,
887 || {
888 TailPushingStats {
889 logspace: logspace,
890 sleep_logspace: sleep_logspace,
891 push_ails: push_ails,
892 push_ail_success: push_ail_success,
893 push_ail_pushbuf: push_ail_pushbuf,
894 push_ail_pinned: push_ail_pinned,
895 push_ail_locked: push_ail_locked,
896 push_ail_flushing: push_ail_flushing,
897 push_ail_restarts: push_ail_restarts,
898 push_ail_flush: push_ail_flush,
899 }
900 }
901 )
902);
903
904named!(xstrat <IoMapWriteConvert>,
905 chain!(
906 tag!("xstrat") ~
907 space ~
908 quick: take_u32 ~
909 split: take_u32,
910 || {
911 IoMapWriteConvert {
912 quick: quick,
913 split: split,
914 }
915 }
916 )
917);
918
919named!(rw <ReadWriteStats>,
920 chain!(
921 tag!("rw") ~
922 space ~
923 write: take_u32 ~
924 read: take_u32,
925 || {
926 ReadWriteStats {
927 write: write,
928 read: read,
929 }
930 }
931 )
932);
933
934named!(attr <AttributeOperations>,
935 chain!(
936 tag!("attr") ~
937 space ~
938 get: take_u32 ~
939 set: take_u32 ~
940 remove: take_u32 ~
941 list: take_u32,
942 || {
943 AttributeOperations {
944 get: get,
945 set: set,
946 remove: remove,
947 list: list,
948 }
949 }
950 )
951);
952
953named!(icluster <InodeClustering>,
954 chain!(
955 tag!("icluster") ~
956 space ~
957 count: take_u32 ~
958 flushcnt: take_u32 ~
959 flushinode: take_u32,
960 || {
961 InodeClustering {
962 count: count,
963 flushcnt: flushcnt,
964 flushinode: flushinode,
965 }
966 }
967 )
968);
969
970named!(vnodes <VnodeStatistics>,
971 chain!(
972 tag!("vnodes") ~
973 space ~
974 active: take_u32 ~
975 alloc: take_u32 ~
976 get: take_u32 ~
977 hold: take_u32 ~
978 rele: take_u32 ~
979 reclaim: take_u32 ~
980 remove: take_u32 ~
981 free: take_u32,
982 || {
983 VnodeStatistics {
984 active: active,
985 alloc: alloc,
986 get: get,
987 hold: hold,
988 rele: rele,
989 reclaim: reclaim,
990 remove: remove,
991 free: free,
992 }
993
994 }
995 )
996);
997
998named!(buf <BufStatistics>,
999 chain!(
1000 tag!("buf") ~
1001 space ~
1002 get: take_u32 ~
1003 create: take_u32 ~
1004 get_locked: take_u32 ~
1005 get_locked_waited: take_u32 ~
1006 busy_locked: take_u32 ~
1007 miss_locked: take_u32 ~
1008 page_retries: take_u32 ~
1009 page_found: take_u32 ~
1010 get_read: take_u32,
1011 || {
1012 BufStatistics {
1013 get: get,
1014 create: create,
1015 get_locked: get_locked,
1016 get_locked_waited: get_locked_waited,
1017 busy_locked: busy_locked,
1018 miss_locked: miss_locked,
1019 page_retries: page_retries,
1020 page_found: page_found,
1021 get_read: get_read,
1022 }
1023
1024 }
1025 )
1026);
1027
1028named!(xpc <ExtendedPrecisionCounters>,
1029 chain!(
1030 take_until!("xpc") ~
1031 tag!("xpc") ~
1032 space ~
1033 xstrat_bytes: take_u64 ~
1034 write_bytes: take_u64 ~
1035 read_bytes: take_u64,
1036 ||{
1037 ExtendedPrecisionCounters {
1038 xstrat_bytes: xstrat_bytes,
1039 write_bytes: write_bytes,
1040 read_bytes: read_bytes,
1041 }
1042 }
1043 )
1044);