forked from Deadpoolmine/HUNTER-File-System
-
Notifications
You must be signed in to change notification settings - Fork 0
/
sysfs.c
180 lines (153 loc) · 4.96 KB
/
sysfs.c
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
/*
* BRIEF DESCRIPTION
*
* Proc fs operations
*
* Copyright 2023-2024 Regents of the University of Harbin Institute of Technology, Shenzhen
* Computer science and technology, Yanqi Pan <[email protected]>
* Copyright 2012-2013 Intel Corporation
* Copyright 2009-2011 Marco Stornelli <[email protected]>
* Copyright 2003 Sony Corporation
* Copyright 2003 Matsushita Electric Industrial Co., Ltd.
* 2003-2004 (c) MontaVista Software, Inc. , Steve Longerbeam
*
* This program is free software; you can redistribute it and/or modify it
*
* This file is licensed under the terms of the GNU General Public
* License version 2. This program is licensed "as is" without any
* warranty of any kind, whether express or implied.
*/
#include "hunter.h"
#include "inode.h"
const char *proc_dirname = "fs/HUNTER";
struct proc_dir_entry *hk_proc_root;
// TODO: Modify these functions
/* ====================== Statistics ======================== */
static int hk_seq_timing_show(struct seq_file *seq, void *v)
{
int i;
hk_get_timing_stats();
seq_puts(seq, "=========== HUNTER kernel timing stats ===========\n");
for (i = 0; i < TIMING_NUM; i++) {
/* Title */
if (Timingstring[i][0] == '=') {
seq_printf(seq, "\n%s\n\n", Timingstring[i]);
continue;
}
if (measure_timing || Timingstats[i]) {
seq_printf(seq, "%s: count %llu, timing %llu, average %llu\n",
Timingstring[i],
Countstats[i],
Timingstats[i],
Countstats[i] ?
Timingstats[i] / Countstats[i] : 0);
} else {
seq_printf(seq, "%s: count %llu\n",
Timingstring[i],
Countstats[i]);
}
}
seq_puts(seq, "\n");
return 0;
}
static int hk_seq_timing_open(struct inode *inode, struct file *file)
{
return single_open(file, hk_seq_timing_show, PDE_DATA(inode));
}
ssize_t hk_seq_clear_stats(struct file *filp, const char __user *buf,
size_t len, loff_t *ppos)
{
struct address_space *mapping = filp->f_mapping;
struct inode *inode = mapping->host;
struct super_block *sb = PDE_DATA(inode);
hk_clear_stats(sb);
return len;
}
static const struct file_operations hk_seq_timing_fops = {
.owner = THIS_MODULE,
.open = hk_seq_timing_open,
.read = seq_read,
.write = hk_seq_clear_stats,
.llseek = seq_lseek,
.release = single_release,
};
static int hk_seq_IO_show(struct seq_file *seq, void *v)
{
struct super_block *sb = seq->private;
struct hk_sb_info *sbi = HK_SB(sb);
struct free_list *free_list;
unsigned long alloc_log_count = 0;
unsigned long alloc_log_pages = 0;
unsigned long alloc_data_count = 0;
unsigned long alloc_data_pages = 0;
unsigned long free_log_count = 0;
unsigned long freed_log_pages = 0;
unsigned long free_data_count = 0;
unsigned long freed_data_pages = 0;
int i;
hk_get_timing_stats();
hk_get_IO_stats();
seq_puts(seq, "============ HK allocation stats ============\n\n");
seq_printf(seq, "alloc log count %lu, allocated log pages %lu\n"
"alloc data count %lu, allocated data pages %lu\n"
"free log count %lu, freed log pages %lu\n"
"free data count %lu, freed data pages %lu\n",
alloc_log_count, alloc_log_pages,
alloc_data_count, alloc_data_pages,
free_log_count, freed_log_pages,
free_data_count, freed_data_pages);
seq_puts(seq, "\n");
seq_puts(seq, "================ HK I/O stats ================\n\n");
seq_printf(seq, "Read %llu, bytes %llu, average %llu\n",
Countstats[dax_read_t], IOstats[read_bytes],
Countstats[dax_read_t] ?
IOstats[read_bytes] / Countstats[dax_read_t] : 0);
seq_printf(seq, "COW write %llu, bytes %llu, average %llu, write breaks %llu, average %llu\n",
Countstats[do_cow_write_t], IOstats[cow_write_bytes],
Countstats[do_cow_write_t] ?
IOstats[cow_write_bytes] / Countstats[do_cow_write_t] : 0,
IOstats[cow_write_breaks], Countstats[do_cow_write_t] ?
IOstats[cow_write_breaks] / Countstats[do_cow_write_t]
: 0);
seq_printf(seq, "fsync %llu, fdatasync %llu\n",
Countstats[fsync_t], IOstats[fdatasync]);
seq_puts(seq, "\n");
seq_puts(seq, "\n");
return 0;
}
static int hk_seq_IO_open(struct inode *inode, struct file *file)
{
return single_open(file, hk_seq_IO_show, PDE_DATA(inode));
}
static const struct file_operations hk_seq_IO_fops = {
.owner = THIS_MODULE,
.open = hk_seq_IO_open,
.read = seq_read,
.write = hk_seq_clear_stats,
.llseek = seq_lseek,
.release = single_release,
};
/* ====================== Setup/teardown======================== */
void hk_sysfs_init(struct super_block *sb)
{
struct hk_sb_info *sbi = HK_SB(sb);
if (hk_proc_root)
sbi->s_proc = proc_mkdir(sbi->s_bdev->bd_disk->disk_name,
hk_proc_root);
if (sbi->s_proc) {
proc_create_data("timing_stats", 0444, sbi->s_proc,
&hk_seq_timing_fops, sb);
proc_create_data("IO_stats", 0444, sbi->s_proc,
&hk_seq_IO_fops, sb);
}
}
void hk_sysfs_exit(struct super_block *sb)
{
struct hk_sb_info *sbi = HK_SB(sb);
if (sbi->s_proc) {
remove_proc_entry("timing_stats", sbi->s_proc);
remove_proc_entry("IO_stats", sbi->s_proc);
remove_proc_entry(sbi->s_bdev->bd_disk->disk_name,
hk_proc_root);
}
}