6
6
#include <linux/kernel.h> /* min */
7
7
#include <linux/module.h>
8
8
#include <linux/printk.h> /* printk */
9
- #include <linux/string.h> /* strcpy */
9
+ #include <linux/slab.h> /* kvzalloc, kvrealloc, kvfree */
10
+ #include <linux/string.h> /* memset */
10
11
#include <linux/uaccess.h> /* copy_from_user, copy_to_user */
11
12
#include <linux/rwsem.h>
12
13
#include <uapi/linux/stat.h> /* S_IRUSR */
@@ -43,7 +44,7 @@ int dyn_arr_reserve(dyn_arr_t *a, size_t off, size_t len);
43
44
int dyn_arr_reserve (dyn_arr_t * a , size_t off , size_t len )
44
45
{
45
46
size_t new_used , new_size ;
46
-
47
+
47
48
new_used = off + len ;
48
49
if (new_used > a -> _size ) {
49
50
new_size = new_used * 2 ;
@@ -99,10 +100,12 @@ static ssize_t read(struct file *filp, char __user *buf, size_t len, loff_t *off
99
100
ret = min (len , data .used - (size_t )* off );
100
101
if (copy_to_user (buf , data .buf + * off , ret )) {
101
102
ret = - EFAULT ;
103
+ goto out ;
102
104
} else {
103
105
* off += ret ;
104
106
}
105
107
}
108
+ out :
106
109
up_read (& rwsem );
107
110
if (log ) pr_info ("read ret:=%lld\n" , (long long )ret );
108
111
return ret ;
@@ -114,15 +117,21 @@ static ssize_t write(struct file *filp, const char __user *buf, size_t len, loff
114
117
115
118
if (log ) pr_info ("write len=%zu off=%lld\n" , len , (long long )* off );
116
119
down_write (& rwsem );
117
- dyn_arr_reserve (& data , * off , len );
120
+ ret = dyn_arr_reserve (& data , * off , len );
121
+ if (ret ) {
122
+ ret = - ENOSPC ;
123
+ goto out ;
124
+ }
118
125
if (copy_from_user (data .buf + * off , buf , len )) {
119
126
ret = - EFAULT ;
127
+ goto out ;
120
128
} else {
121
129
ret = len ;
122
130
* off += ret ;
123
131
}
124
- up_write ( & rwsem );
132
+ out :
125
133
if (log ) pr_info ("write ret:=%lld\n" , (long long )ret );
134
+ up_write (& rwsem );
126
135
return ret ;
127
136
}
128
137
@@ -168,7 +177,7 @@ static const struct file_operations fops = {
168
177
static int myinit (void )
169
178
{
170
179
int ret ;
171
-
180
+
172
181
ret = dyn_arr_init (& data , 1 );
173
182
if (ret )
174
183
return ret ;
0 commit comments