Branch data Line data Source code
1 : : // SPDX-License-Identifier: GPL-2.0
2 : : /*
3 : : * linux/fs/read_write.c
4 : : *
5 : : * Copyright (C) 1991, 1992 Linus Torvalds
6 : : */
7 : :
8 : : #include <linux/slab.h>
9 : : #include <linux/stat.h>
10 : : #include <linux/sched/xacct.h>
11 : : #include <linux/fcntl.h>
12 : : #include <linux/file.h>
13 : : #include <linux/uio.h>
14 : : #include <linux/fsnotify.h>
15 : : #include <linux/security.h>
16 : : #include <linux/export.h>
17 : : #include <linux/syscalls.h>
18 : : #include <linux/pagemap.h>
19 : : #include <linux/splice.h>
20 : : #include <linux/compat.h>
21 : : #include <linux/mount.h>
22 : : #include <linux/fs.h>
23 : : #include "internal.h"
24 : :
25 : : #include <linux/uaccess.h>
26 : : #include <asm/unistd.h>
27 : :
28 : : const struct file_operations generic_ro_fops = {
29 : : .llseek = generic_file_llseek,
30 : : .read_iter = generic_file_read_iter,
31 : : .mmap = generic_file_readonly_mmap,
32 : : .splice_read = generic_file_splice_read,
33 : : };
34 : :
35 : : EXPORT_SYMBOL(generic_ro_fops);
36 : :
37 : 0 : static inline bool unsigned_offsets(struct file *file)
38 : : {
39 : 0 : return file->f_mode & FMODE_UNSIGNED_OFFSET;
40 : : }
41 : :
42 : : /**
43 : : * vfs_setpos - update the file offset for lseek
44 : : * @file: file structure in question
45 : : * @offset: file offset to seek to
46 : : * @maxsize: maximum file size
47 : : *
48 : : * This is a low-level filesystem helper for updating the file offset to
49 : : * the value specified by @offset if the given offset is valid and it is
50 : : * not equal to the current file offset.
51 : : *
52 : : * Return the specified offset on success and -EINVAL on invalid offset.
53 : : */
54 : 4980 : loff_t vfs_setpos(struct file *file, loff_t offset, loff_t maxsize)
55 : : {
56 [ # # # # : 0 : if (offset < 0 && !unsigned_offsets(file))
# # # # ]
57 : : return -EINVAL;
58 [ + - + - : 4980 : if (offset > maxsize)
- - ]
59 : : return -EINVAL;
60 : :
61 [ + - + + : 4980 : if (offset != file->f_pos) {
- - ]
62 : 4530 : file->f_pos = offset;
63 : 4530 : file->f_version = 0;
64 : : }
65 : : return offset;
66 : : }
67 : : EXPORT_SYMBOL(vfs_setpos);
68 : :
69 : : /**
70 : : * generic_file_llseek_size - generic llseek implementation for regular files
71 : : * @file: file structure to seek on
72 : : * @offset: file offset to seek to
73 : : * @whence: type of seek
74 : : * @size: max size of this file in file system
75 : : * @eof: offset used for SEEK_END position
76 : : *
77 : : * This is a variant of generic_file_llseek that allows passing in a custom
78 : : * maximum file size and a custom EOF position, for e.g. hashed directories
79 : : *
80 : : * Synchronization:
81 : : * SEEK_SET and SEEK_END are unsynchronized (but atomic on 64bit platforms)
82 : : * SEEK_CUR is synchronized against other SEEK_CURs, but not read/writes.
83 : : * read/writes behave like SEEK_SET against seeks.
84 : : */
85 : : loff_t
86 : 16740 : generic_file_llseek_size(struct file *file, loff_t offset, int whence,
87 : : loff_t maxsize, loff_t eof)
88 : : {
89 [ + + - - : 16740 : switch (whence) {
+ ]
90 : 30 : case SEEK_END:
91 : 30 : offset += eof;
92 : 30 : break;
93 : 12240 : case SEEK_CUR:
94 : : /*
95 : : * Here we special-case the lseek(fd, 0, SEEK_CUR)
96 : : * position-querying operation. Avoid rewriting the "same"
97 : : * f_pos value back to the file because a concurrent read(),
98 : : * write() or lseek() might have altered it
99 : : */
100 [ + + ]: 12240 : if (offset == 0)
101 : 11760 : return file->f_pos;
102 : : /*
103 : : * f_lock protects against read/modify/write race with other
104 : : * SEEK_CURs. Note that parallel writes and reads behave
105 : : * like SEEK_SET.
106 : : */
107 : 480 : spin_lock(&file->f_lock);
108 [ - + ]: 480 : offset = vfs_setpos(file, file->f_pos + offset, maxsize);
109 : 480 : spin_unlock(&file->f_lock);
110 : 480 : return offset;
111 : 0 : case SEEK_DATA:
112 : : /*
113 : : * In the generic case the entire file is data, so as long as
114 : : * offset isn't at the end of the file then the offset is data.
115 : : */
116 [ # # ]: 0 : if ((unsigned long long)offset >= eof)
117 : : return -ENXIO;
118 : : break;
119 : 0 : case SEEK_HOLE:
120 : : /*
121 : : * There is a virtual hole at the end of the file, so as long as
122 : : * offset isn't i_size or larger, return i_size.
123 : : */
124 [ # # ]: 0 : if ((unsigned long long)offset >= eof)
125 : : return -ENXIO;
126 : : offset = eof;
127 : : break;
128 : : }
129 : :
130 [ - + ]: 4500 : return vfs_setpos(file, offset, maxsize);
131 : : }
132 : : EXPORT_SYMBOL(generic_file_llseek_size);
133 : :
134 : : /**
135 : : * generic_file_llseek - generic llseek implementation for regular files
136 : : * @file: file structure to seek on
137 : : * @offset: file offset to seek to
138 : : * @whence: type of seek
139 : : *
140 : : * This is a generic implemenation of ->llseek useable for all normal local
141 : : * filesystems. It just updates the file offset to the value specified by
142 : : * @offset and @whence.
143 : : */
144 : 0 : loff_t generic_file_llseek(struct file *file, loff_t offset, int whence)
145 : : {
146 : 0 : struct inode *inode = file->f_mapping->host;
147 : :
148 : 0 : return generic_file_llseek_size(file, offset, whence,
149 : 0 : inode->i_sb->s_maxbytes,
150 : : i_size_read(inode));
151 : : }
152 : : EXPORT_SYMBOL(generic_file_llseek);
153 : :
154 : : /**
155 : : * fixed_size_llseek - llseek implementation for fixed-sized devices
156 : : * @file: file structure to seek on
157 : : * @offset: file offset to seek to
158 : : * @whence: type of seek
159 : : * @size: size of the file
160 : : *
161 : : */
162 : 3960 : loff_t fixed_size_llseek(struct file *file, loff_t offset, int whence, loff_t size)
163 : : {
164 [ + - ]: 3960 : switch (whence) {
165 : 3960 : case SEEK_SET: case SEEK_CUR: case SEEK_END:
166 : 3960 : return generic_file_llseek_size(file, offset, whence,
167 : : size, size);
168 : : default:
169 : : return -EINVAL;
170 : : }
171 : : }
172 : : EXPORT_SYMBOL(fixed_size_llseek);
173 : :
174 : : /**
175 : : * no_seek_end_llseek - llseek implementation for fixed-sized devices
176 : : * @file: file structure to seek on
177 : : * @offset: file offset to seek to
178 : : * @whence: type of seek
179 : : *
180 : : */
181 : 0 : loff_t no_seek_end_llseek(struct file *file, loff_t offset, int whence)
182 : : {
183 [ # # ]: 0 : switch (whence) {
184 : 0 : case SEEK_SET: case SEEK_CUR:
185 : 0 : return generic_file_llseek_size(file, offset, whence,
186 : : OFFSET_MAX, 0);
187 : : default:
188 : : return -EINVAL;
189 : : }
190 : : }
191 : : EXPORT_SYMBOL(no_seek_end_llseek);
192 : :
193 : : /**
194 : : * no_seek_end_llseek_size - llseek implementation for fixed-sized devices
195 : : * @file: file structure to seek on
196 : : * @offset: file offset to seek to
197 : : * @whence: type of seek
198 : : * @size: maximal offset allowed
199 : : *
200 : : */
201 : 0 : loff_t no_seek_end_llseek_size(struct file *file, loff_t offset, int whence, loff_t size)
202 : : {
203 [ # # ]: 0 : switch (whence) {
204 : 0 : case SEEK_SET: case SEEK_CUR:
205 : 0 : return generic_file_llseek_size(file, offset, whence,
206 : : size, 0);
207 : : default:
208 : : return -EINVAL;
209 : : }
210 : : }
211 : : EXPORT_SYMBOL(no_seek_end_llseek_size);
212 : :
213 : : /**
214 : : * noop_llseek - No Operation Performed llseek implementation
215 : : * @file: file structure to seek on
216 : : * @offset: file offset to seek to
217 : : * @whence: type of seek
218 : : *
219 : : * This is an implementation of ->llseek useable for the rare special case when
220 : : * userspace expects the seek to succeed but the (device) file is actually not
221 : : * able to perform the seek. In this case you use noop_llseek() instead of
222 : : * falling back to the default implementation of ->llseek.
223 : : */
224 : 0 : loff_t noop_llseek(struct file *file, loff_t offset, int whence)
225 : : {
226 : 0 : return file->f_pos;
227 : : }
228 : : EXPORT_SYMBOL(noop_llseek);
229 : :
230 : 846 : loff_t no_llseek(struct file *file, loff_t offset, int whence)
231 : : {
232 : 846 : return -ESPIPE;
233 : : }
234 : : EXPORT_SYMBOL(no_llseek);
235 : :
236 : 30 : loff_t default_llseek(struct file *file, loff_t offset, int whence)
237 : : {
238 : 30 : struct inode *inode = file_inode(file);
239 : 30 : loff_t retval;
240 : :
241 : 30 : inode_lock(inode);
242 [ - - - - : 30 : switch (whence) {
+ ]
243 : 0 : case SEEK_END:
244 : 0 : offset += i_size_read(inode);
245 : 0 : break;
246 : 0 : case SEEK_CUR:
247 [ # # ]: 0 : if (offset == 0) {
248 : 0 : retval = file->f_pos;
249 : 0 : goto out;
250 : : }
251 : 0 : offset += file->f_pos;
252 : 0 : break;
253 : 0 : case SEEK_DATA:
254 : : /*
255 : : * In the generic case the entire file is data, so as
256 : : * long as offset isn't at the end of the file then the
257 : : * offset is data.
258 : : */
259 [ # # ]: 0 : if (offset >= inode->i_size) {
260 : 0 : retval = -ENXIO;
261 : 0 : goto out;
262 : : }
263 : : break;
264 : 0 : case SEEK_HOLE:
265 : : /*
266 : : * There is a virtual hole at the end of the file, so
267 : : * as long as offset isn't i_size or larger, return
268 : : * i_size.
269 : : */
270 [ # # ]: 0 : if (offset >= inode->i_size) {
271 : 0 : retval = -ENXIO;
272 : 0 : goto out;
273 : : }
274 : : offset = inode->i_size;
275 : : break;
276 : : }
277 : 30 : retval = -EINVAL;
278 [ - + - - ]: 30 : if (offset >= 0 || unsigned_offsets(file)) {
279 [ + - ]: 30 : if (offset != file->f_pos) {
280 : 30 : file->f_pos = offset;
281 : 30 : file->f_version = 0;
282 : : }
283 : : retval = offset;
284 : : }
285 : 0 : out:
286 : 30 : inode_unlock(inode);
287 : 30 : return retval;
288 : : }
289 : : EXPORT_SYMBOL(default_llseek);
290 : :
291 : 18966 : loff_t vfs_llseek(struct file *file, loff_t offset, int whence)
292 : : {
293 : 18966 : loff_t (*fn)(struct file *, loff_t, int);
294 : :
295 : 18966 : fn = no_llseek;
296 [ # # ]: 0 : if (file->f_mode & FMODE_LSEEK) {
297 [ - - + - : 18120 : if (file->f_op->llseek)
- - ]
298 : 18120 : fn = file->f_op->llseek;
299 : : }
300 : 0 : return fn(file, offset, whence);
301 : : }
302 : : EXPORT_SYMBOL(vfs_llseek);
303 : :
304 : 18966 : off_t ksys_lseek(unsigned int fd, off_t offset, unsigned int whence)
305 : : {
306 : 18966 : off_t retval;
307 : 18966 : struct fd f = fdget_pos(fd);
308 [ + - ]: 18966 : if (!f.file)
309 : : return -EBADF;
310 : :
311 : 18966 : retval = -EINVAL;
312 [ + - ]: 18966 : if (whence <= SEEK_MAX) {
313 [ + + ]: 18966 : loff_t res = vfs_llseek(f.file, offset, whence);
314 : 18966 : retval = res;
315 : 18966 : if (res != (loff_t)retval)
316 : : retval = -EOVERFLOW; /* LFS: should only happen on 32 bit platforms */
317 : : }
318 : 18966 : fdput_pos(f);
319 : 18966 : return retval;
320 : : }
321 : :
322 : 37932 : SYSCALL_DEFINE3(lseek, unsigned int, fd, off_t, offset, unsigned int, whence)
323 : : {
324 : 18966 : return ksys_lseek(fd, offset, whence);
325 : : }
326 : :
327 : : #ifdef CONFIG_COMPAT
328 : 0 : COMPAT_SYSCALL_DEFINE3(lseek, unsigned int, fd, compat_off_t, offset, unsigned int, whence)
329 : : {
330 : 0 : return ksys_lseek(fd, offset, whence);
331 : : }
332 : : #endif
333 : :
334 : : #if !defined(CONFIG_64BIT) || defined(CONFIG_COMPAT)
335 : 0 : SYSCALL_DEFINE5(llseek, unsigned int, fd, unsigned long, offset_high,
336 : : unsigned long, offset_low, loff_t __user *, result,
337 : : unsigned int, whence)
338 : : {
339 : 0 : int retval;
340 : 0 : struct fd f = fdget_pos(fd);
341 : 0 : loff_t offset;
342 : :
343 [ # # ]: 0 : if (!f.file)
344 : : return -EBADF;
345 : :
346 : 0 : retval = -EINVAL;
347 [ # # ]: 0 : if (whence > SEEK_MAX)
348 : 0 : goto out_putf;
349 : :
350 [ # # ]: 0 : offset = vfs_llseek(f.file, ((loff_t) offset_high << 32) | offset_low,
351 : : whence);
352 : :
353 : 0 : retval = (int)offset;
354 [ # # ]: 0 : if (offset >= 0) {
355 : 0 : retval = -EFAULT;
356 [ # # ]: 0 : if (!copy_to_user(result, &offset, sizeof(offset)))
357 : 0 : retval = 0;
358 : : }
359 : 0 : out_putf:
360 : 0 : fdput_pos(f);
361 : 0 : return retval;
362 : : }
363 : : #endif
364 : :
365 : 639111 : int rw_verify_area(int read_write, struct file *file, const loff_t *ppos, size_t count)
366 : : {
367 : 639111 : struct inode *inode;
368 : 639111 : int retval = -EINVAL;
369 : :
370 [ + - ]: 639111 : inode = file_inode(file);
371 [ + - ]: 639111 : if (unlikely((ssize_t) count < 0))
372 : : return retval;
373 : :
374 : : /*
375 : : * ranged mandatory locking does not apply to streams - it makes sense
376 : : * only for files where position has a meaning.
377 : : */
378 [ + + ]: 639111 : if (ppos) {
379 : 439418 : loff_t pos = *ppos;
380 : :
381 [ - + ]: 439418 : if (unlikely(pos < 0)) {
382 [ # # ]: 0 : if (!unsigned_offsets(file))
383 : : return retval;
384 [ # # ]: 0 : if (count >= -pos) /* both values are in 0..LLONG_MAX */
385 : : return -EOVERFLOW;
386 [ - + ]: 439418 : } else if (unlikely((loff_t) (pos + count) < 0)) {
387 [ # # ]: 0 : if (!unsigned_offsets(file))
388 : : return retval;
389 : : }
390 : :
391 [ + + - + ]: 443648 : if (unlikely(inode->i_flctx && mandatory_lock(inode))) {
392 : 0 : retval = locks_mandatory_area(inode, file, pos, pos + count - 1,
393 : : read_write == READ ? F_RDLCK : F_WRLCK);
394 [ # # ]: 0 : if (retval < 0)
395 : : return retval;
396 : : }
397 : : }
398 : :
399 [ + + ]: 701306 : return security_file_permission(file,
400 : : read_write == READ ? MAY_READ : MAY_WRITE);
401 : : }
402 : :
403 : 434633 : static ssize_t new_sync_read(struct file *filp, char __user *buf, size_t len, loff_t *ppos)
404 : : {
405 : 434633 : struct iovec iov = { .iov_base = buf, .iov_len = len };
406 : 434633 : struct kiocb kiocb;
407 : 434633 : struct iov_iter iter;
408 : 434633 : ssize_t ret;
409 : :
410 : 434633 : init_sync_kiocb(&kiocb, filp);
411 [ + + ]: 434633 : kiocb.ki_pos = (ppos ? *ppos : 0);
412 : 434633 : iov_iter_init(&iter, READ, &iov, 1, len);
413 : :
414 : 434633 : ret = call_read_iter(filp, &kiocb, &iter);
415 [ - + ]: 434633 : BUG_ON(ret == -EIOCBQUEUED);
416 [ + + ]: 434633 : if (ppos)
417 : 252604 : *ppos = kiocb.ki_pos;
418 : 434633 : return ret;
419 : : }
420 : :
421 : 576556 : ssize_t __vfs_read(struct file *file, char __user *buf, size_t count,
422 : : loff_t *pos)
423 : : {
424 [ + + ]: 576556 : if (file->f_op->read)
425 : 141923 : return file->f_op->read(file, buf, count, pos);
426 [ + - ]: 434633 : else if (file->f_op->read_iter)
427 : 434633 : return new_sync_read(file, buf, count, pos);
428 : : else
429 : : return -EINVAL;
430 : : }
431 : :
432 : 134646 : ssize_t kernel_read(struct file *file, void *buf, size_t count, loff_t *pos)
433 : : {
434 : 134646 : mm_segment_t old_fs;
435 : 134646 : ssize_t result;
436 : :
437 : 134646 : old_fs = get_fs();
438 : 134646 : set_fs(KERNEL_DS);
439 : : /* The cast to a user pointer is valid due to the set_fs() */
440 : 134646 : result = vfs_read(file, (void __user *)buf, count, pos);
441 : 134646 : set_fs(old_fs);
442 : 134646 : return result;
443 : : }
444 : : EXPORT_SYMBOL(kernel_read);
445 : :
446 : 576556 : ssize_t vfs_read(struct file *file, char __user *buf, size_t count, loff_t *pos)
447 : : {
448 : 576556 : ssize_t ret;
449 : :
450 [ + - ]: 576556 : if (!(file->f_mode & FMODE_READ))
451 : : return -EBADF;
452 [ + - ]: 576556 : if (!(file->f_mode & FMODE_CAN_READ))
453 : : return -EINVAL;
454 [ - + + - ]: 1153112 : if (unlikely(!access_ok(buf, count)))
455 : : return -EFAULT;
456 : :
457 : 576556 : ret = rw_verify_area(READ, file, pos, count);
458 [ + - ]: 576556 : if (!ret) {
459 : 576556 : if (count > MAX_RW_COUNT)
460 : : count = MAX_RW_COUNT;
461 : 576556 : ret = __vfs_read(file, buf, count, pos);
462 [ + + ]: 576526 : if (ret > 0) {
463 : 326299 : fsnotify_access(file);
464 : 326299 : add_rchar(current, ret);
465 : : }
466 : 576526 : inc_syscr(current);
467 : : }
468 : :
469 : : return ret;
470 : : }
471 : :
472 : 35953 : static ssize_t new_sync_write(struct file *filp, const char __user *buf, size_t len, loff_t *ppos)
473 : : {
474 : 35953 : struct iovec iov = { .iov_base = (void __user *)buf, .iov_len = len };
475 : 35953 : struct kiocb kiocb;
476 : 35953 : struct iov_iter iter;
477 : 35953 : ssize_t ret;
478 : :
479 : 35953 : init_sync_kiocb(&kiocb, filp);
480 [ + + ]: 35953 : kiocb.ki_pos = (ppos ? *ppos : 0);
481 : 35953 : iov_iter_init(&iter, WRITE, &iov, 1, len);
482 : :
483 : 35953 : ret = call_write_iter(filp, &kiocb, &iter);
484 [ - + ]: 35953 : BUG_ON(ret == -EIOCBQUEUED);
485 [ + + ]: 35953 : if (ret > 0 && ppos)
486 : 18331 : *ppos = kiocb.ki_pos;
487 : 35953 : return ret;
488 : : }
489 : :
490 : 57253 : static ssize_t __vfs_write(struct file *file, const char __user *p,
491 : : size_t count, loff_t *pos)
492 : : {
493 [ + + ]: 57253 : if (file->f_op->write)
494 : 21300 : return file->f_op->write(file, p, count, pos);
495 [ + - ]: 35953 : else if (file->f_op->write_iter)
496 : 35953 : return new_sync_write(file, p, count, pos);
497 : : else
498 : : return -EINVAL;
499 : : }
500 : :
501 : 0 : ssize_t __kernel_write(struct file *file, const void *buf, size_t count, loff_t *pos)
502 : : {
503 : 0 : mm_segment_t old_fs;
504 : 0 : const char __user *p;
505 : 0 : ssize_t ret;
506 : :
507 [ # # ]: 0 : if (!(file->f_mode & FMODE_CAN_WRITE))
508 : : return -EINVAL;
509 : :
510 : 0 : old_fs = get_fs();
511 : 0 : set_fs(KERNEL_DS);
512 : 0 : p = (__force const char __user *)buf;
513 : 0 : if (count > MAX_RW_COUNT)
514 : : count = MAX_RW_COUNT;
515 : 0 : ret = __vfs_write(file, p, count, pos);
516 : 0 : set_fs(old_fs);
517 [ # # ]: 0 : if (ret > 0) {
518 : 0 : fsnotify_modify(file);
519 : 0 : add_wchar(current, ret);
520 : : }
521 : 0 : inc_syscw(current);
522 : 0 : return ret;
523 : : }
524 : : EXPORT_SYMBOL(__kernel_write);
525 : :
526 : 0 : ssize_t kernel_write(struct file *file, const void *buf, size_t count,
527 : : loff_t *pos)
528 : : {
529 : 0 : mm_segment_t old_fs;
530 : 0 : ssize_t res;
531 : :
532 : 0 : old_fs = get_fs();
533 : 0 : set_fs(KERNEL_DS);
534 : : /* The cast to a user pointer is valid due to the set_fs() */
535 : 0 : res = vfs_write(file, (__force const char __user *)buf, count, pos);
536 : 0 : set_fs(old_fs);
537 : :
538 : 0 : return res;
539 : : }
540 : : EXPORT_SYMBOL(kernel_write);
541 : :
542 : 57253 : ssize_t vfs_write(struct file *file, const char __user *buf, size_t count, loff_t *pos)
543 : : {
544 : 57253 : ssize_t ret;
545 : :
546 [ + - ]: 57253 : if (!(file->f_mode & FMODE_WRITE))
547 : : return -EBADF;
548 [ + - ]: 57253 : if (!(file->f_mode & FMODE_CAN_WRITE))
549 : : return -EINVAL;
550 [ - + + - ]: 114506 : if (unlikely(!access_ok(buf, count)))
551 : : return -EFAULT;
552 : :
553 : 57253 : ret = rw_verify_area(WRITE, file, pos, count);
554 [ + - ]: 57253 : if (!ret) {
555 : 57253 : if (count > MAX_RW_COUNT)
556 : : count = MAX_RW_COUNT;
557 : 57253 : file_start_write(file);
558 : 57253 : ret = __vfs_write(file, buf, count, pos);
559 [ + + ]: 57253 : if (ret > 0) {
560 : 40885 : fsnotify_modify(file);
561 : 40885 : add_wchar(current, ret);
562 : : }
563 [ + + ]: 57253 : inc_syscw(current);
564 [ + + ]: 57253 : file_end_write(file);
565 : : }
566 : :
567 : : return ret;
568 : : }
569 : :
570 : : /* file_ppos returns &file->f_pos or NULL if file is stream */
571 : 503595 : static inline loff_t *file_ppos(struct file *file)
572 : : {
573 : 807497 : return file->f_mode & FMODE_STREAM ? NULL : &file->f_pos;
574 : : }
575 : :
576 : 441910 : ssize_t ksys_read(unsigned int fd, char __user *buf, size_t count)
577 : : {
578 : 441910 : struct fd f = fdget_pos(fd);
579 : 441910 : ssize_t ret = -EBADF;
580 : :
581 [ + - ]: 441910 : if (f.file) {
582 [ + + ]: 441910 : loff_t pos, *ppos = file_ppos(f.file);
583 [ + - ]: 259869 : if (ppos) {
584 : 259869 : pos = *ppos;
585 : 259869 : ppos = &pos;
586 : : }
587 : 441910 : ret = vfs_read(f.file, buf, count, ppos);
588 [ + + ]: 441880 : if (ret >= 0 && ppos)
589 : 255503 : f.file->f_pos = pos;
590 : 441880 : fdput_pos(f);
591 : : }
592 : 441880 : return ret;
593 : : }
594 : :
595 : 883790 : SYSCALL_DEFINE3(read, unsigned int, fd, char __user *, buf, size_t, count)
596 : : {
597 : 441910 : return ksys_read(fd, buf, count);
598 : : }
599 : :
600 : 57223 : ssize_t ksys_write(unsigned int fd, const char __user *buf, size_t count)
601 : : {
602 : 57223 : struct fd f = fdget_pos(fd);
603 : 57223 : ssize_t ret = -EBADF;
604 : :
605 [ + - ]: 57223 : if (f.file) {
606 [ + + ]: 57223 : loff_t pos, *ppos = file_ppos(f.file);
607 [ + - ]: 39601 : if (ppos) {
608 : 39601 : pos = *ppos;
609 : 39601 : ppos = &pos;
610 : : }
611 : 57223 : ret = vfs_write(f.file, buf, count, ppos);
612 [ + + ]: 57223 : if (ret >= 0 && ppos)
613 : 39601 : f.file->f_pos = pos;
614 : 57223 : fdput_pos(f);
615 : : }
616 : :
617 : 57223 : return ret;
618 : : }
619 : :
620 : 114446 : SYSCALL_DEFINE3(write, unsigned int, fd, const char __user *, buf,
621 : : size_t, count)
622 : : {
623 : 57223 : return ksys_write(fd, buf, count);
624 : : }
625 : :
626 : 0 : ssize_t ksys_pread64(unsigned int fd, char __user *buf, size_t count,
627 : : loff_t pos)
628 : : {
629 : 0 : struct fd f;
630 : 0 : ssize_t ret = -EBADF;
631 : :
632 [ # # ]: 0 : if (pos < 0)
633 : : return -EINVAL;
634 : :
635 : 0 : f = fdget(fd);
636 [ # # ]: 0 : if (f.file) {
637 : 0 : ret = -ESPIPE;
638 [ # # ]: 0 : if (f.file->f_mode & FMODE_PREAD)
639 : 0 : ret = vfs_read(f.file, buf, count, &pos);
640 [ # # ]: 0 : fdput(f);
641 : : }
642 : :
643 : : return ret;
644 : : }
645 : :
646 : 0 : SYSCALL_DEFINE4(pread64, unsigned int, fd, char __user *, buf,
647 : : size_t, count, loff_t, pos)
648 : : {
649 : 0 : return ksys_pread64(fd, buf, count, pos);
650 : : }
651 : :
652 : 30 : ssize_t ksys_pwrite64(unsigned int fd, const char __user *buf,
653 : : size_t count, loff_t pos)
654 : : {
655 : 30 : struct fd f;
656 : 30 : ssize_t ret = -EBADF;
657 : :
658 [ + - ]: 30 : if (pos < 0)
659 : : return -EINVAL;
660 : :
661 : 30 : f = fdget(fd);
662 [ + - ]: 30 : if (f.file) {
663 : 30 : ret = -ESPIPE;
664 [ + - ]: 30 : if (f.file->f_mode & FMODE_PWRITE)
665 : 30 : ret = vfs_write(f.file, buf, count, &pos);
666 [ - + ]: 30 : fdput(f);
667 : : }
668 : :
669 : : return ret;
670 : : }
671 : :
672 : 60 : SYSCALL_DEFINE4(pwrite64, unsigned int, fd, const char __user *, buf,
673 : : size_t, count, loff_t, pos)
674 : : {
675 : 30 : return ksys_pwrite64(fd, buf, count, pos);
676 : : }
677 : :
678 : 1894 : static ssize_t do_iter_readv_writev(struct file *filp, struct iov_iter *iter,
679 : : loff_t *ppos, int type, rwf_t flags)
680 : : {
681 : 1894 : struct kiocb kiocb;
682 : 1894 : ssize_t ret;
683 : :
684 : 1894 : init_sync_kiocb(&kiocb, filp);
685 : 1894 : ret = kiocb_set_rw_flags(&kiocb, flags);
686 [ + - ]: 1894 : if (ret)
687 : : return ret;
688 [ + + ]: 1894 : kiocb.ki_pos = (ppos ? *ppos : 0);
689 : :
690 [ - + ]: 1894 : if (type == READ)
691 : 0 : ret = call_read_iter(filp, &kiocb, iter);
692 : : else
693 : 1894 : ret = call_write_iter(filp, &kiocb, iter);
694 [ - + ]: 1894 : BUG_ON(ret == -EIOCBQUEUED);
695 [ + + ]: 1894 : if (ppos)
696 : 1864 : *ppos = kiocb.ki_pos;
697 : : return ret;
698 : : }
699 : :
700 : : /* Do it by hand, with file-ops */
701 : 2688 : static ssize_t do_loop_readv_writev(struct file *filp, struct iov_iter *iter,
702 : : loff_t *ppos, int type, rwf_t flags)
703 : : {
704 : 2688 : ssize_t ret = 0;
705 : :
706 [ + - ]: 2688 : if (flags & ~RWF_HIPRI)
707 : : return -EOPNOTSUPP;
708 : :
709 [ + + ]: 14526 : while (iov_iter_count(iter)) {
710 [ - + ]: 11838 : struct iovec iovec = iov_iter_iovec(iter);
711 : 11838 : ssize_t nr;
712 : :
713 [ - + ]: 11838 : if (type == READ) {
714 : 0 : nr = filp->f_op->read(filp, iovec.iov_base,
715 : : iovec.iov_len, ppos);
716 : : } else {
717 : 11838 : nr = filp->f_op->write(filp, iovec.iov_base,
718 : : iovec.iov_len, ppos);
719 : : }
720 : :
721 [ - + ]: 11838 : if (nr < 0) {
722 [ # # ]: 0 : if (!ret)
723 : 0 : ret = nr;
724 : : break;
725 : : }
726 : 11838 : ret += nr;
727 [ + - ]: 11838 : if (nr != iovec.iov_len)
728 : : break;
729 : 11838 : iov_iter_advance(iter, nr);
730 : : }
731 : :
732 : : return ret;
733 : : }
734 : :
735 : : /**
736 : : * rw_copy_check_uvector() - Copy an array of &struct iovec from userspace
737 : : * into the kernel and check that it is valid.
738 : : *
739 : : * @type: One of %CHECK_IOVEC_ONLY, %READ, or %WRITE.
740 : : * @uvector: Pointer to the userspace array.
741 : : * @nr_segs: Number of elements in userspace array.
742 : : * @fast_segs: Number of elements in @fast_pointer.
743 : : * @fast_pointer: Pointer to (usually small on-stack) kernel array.
744 : : * @ret_pointer: (output parameter) Pointer to a variable that will point to
745 : : * either @fast_pointer, a newly allocated kernel array, or NULL,
746 : : * depending on which array was used.
747 : : *
748 : : * This function copies an array of &struct iovec of @nr_segs from
749 : : * userspace into the kernel and checks that each element is valid (e.g.
750 : : * it does not point to a kernel address or cause overflow by being too
751 : : * large, etc.).
752 : : *
753 : : * As an optimization, the caller may provide a pointer to a small
754 : : * on-stack array in @fast_pointer, typically %UIO_FASTIOV elements long
755 : : * (the size of this array, or 0 if unused, should be given in @fast_segs).
756 : : *
757 : : * @ret_pointer will always point to the array that was used, so the
758 : : * caller must take care not to call kfree() on it e.g. in case the
759 : : * @fast_pointer array was used and it was allocated on the stack.
760 : : *
761 : : * Return: The total number of bytes covered by the iovec array on success
762 : : * or a negative error code on error.
763 : : */
764 : 114582 : ssize_t rw_copy_check_uvector(int type, const struct iovec __user * uvector,
765 : : unsigned long nr_segs, unsigned long fast_segs,
766 : : struct iovec *fast_pointer,
767 : : struct iovec **ret_pointer)
768 : : {
769 : 114582 : unsigned long seg;
770 : 114582 : ssize_t ret;
771 : 114582 : struct iovec *iov = fast_pointer;
772 : :
773 : : /*
774 : : * SuS says "The readv() function *may* fail if the iovcnt argument
775 : : * was less than or equal to 0, or greater than {IOV_MAX}. Linux has
776 : : * traditionally returned zero for zero segments, so...
777 : : */
778 [ - + ]: 114582 : if (nr_segs == 0) {
779 : 0 : ret = 0;
780 : 0 : goto out;
781 : : }
782 : :
783 : : /*
784 : : * First get the "struct iovec" from user memory and
785 : : * verify all the pointers
786 : : */
787 [ - + ]: 114582 : if (nr_segs > UIO_MAXIOV) {
788 : 0 : ret = -EINVAL;
789 : 0 : goto out;
790 : : }
791 [ + + ]: 114582 : if (nr_segs > fast_segs) {
792 : 1088 : iov = kmalloc_array(nr_segs, sizeof(struct iovec), GFP_KERNEL);
793 [ - + ]: 1088 : if (iov == NULL) {
794 : 0 : ret = -ENOMEM;
795 : 0 : goto out;
796 : : }
797 : : }
798 [ - + - + ]: 229164 : if (copy_from_user(iov, uvector, nr_segs*sizeof(*uvector))) {
799 : 0 : ret = -EFAULT;
800 : 0 : goto out;
801 : : }
802 : :
803 : : /*
804 : : * According to the Single Unix Specification we should return EINVAL
805 : : * if an element length is < 0 when cast to ssize_t or if the
806 : : * total length would overflow the ssize_t return value of the
807 : : * system call.
808 : : *
809 : : * Linux caps all read/write calls to MAX_RW_COUNT, and avoids the
810 : : * overflow case.
811 : : */
812 : : ret = 0;
813 [ + + ]: 310880 : for (seg = 0; seg < nr_segs; seg++) {
814 : 196298 : void __user *buf = iov[seg].iov_base;
815 : 196298 : ssize_t len = (ssize_t)iov[seg].iov_len;
816 : :
817 : : /* see if we we're about to use an invalid len or if
818 : : * it's about to overflow ssize_t */
819 [ - + ]: 196298 : if (len < 0) {
820 : 0 : ret = -EINVAL;
821 : 0 : goto out;
822 : : }
823 [ + - ]: 196298 : if (type >= 0
824 [ - + - + ]: 392596 : && unlikely(!access_ok(buf, len))) {
825 : 0 : ret = -EFAULT;
826 : 0 : goto out;
827 : : }
828 [ - + ]: 196298 : if (len > MAX_RW_COUNT - ret) {
829 : 0 : len = MAX_RW_COUNT - ret;
830 : 0 : iov[seg].iov_len = len;
831 : : }
832 : 196298 : ret += len;
833 : : }
834 : 114582 : out:
835 : 114582 : *ret_pointer = iov;
836 : 114582 : return ret;
837 : : }
838 : :
839 : : #ifdef CONFIG_COMPAT
840 : 0 : ssize_t compat_rw_copy_check_uvector(int type,
841 : : const struct compat_iovec __user *uvector, unsigned long nr_segs,
842 : : unsigned long fast_segs, struct iovec *fast_pointer,
843 : : struct iovec **ret_pointer)
844 : : {
845 : 0 : compat_ssize_t tot_len;
846 : 0 : struct iovec *iov = *ret_pointer = fast_pointer;
847 : 0 : ssize_t ret = 0;
848 : 0 : int seg;
849 : :
850 : : /*
851 : : * SuS says "The readv() function *may* fail if the iovcnt argument
852 : : * was less than or equal to 0, or greater than {IOV_MAX}. Linux has
853 : : * traditionally returned zero for zero segments, so...
854 : : */
855 [ # # ]: 0 : if (nr_segs == 0)
856 : 0 : goto out;
857 : :
858 : 0 : ret = -EINVAL;
859 [ # # ]: 0 : if (nr_segs > UIO_MAXIOV)
860 : 0 : goto out;
861 [ # # ]: 0 : if (nr_segs > fast_segs) {
862 : 0 : ret = -ENOMEM;
863 : 0 : iov = kmalloc_array(nr_segs, sizeof(struct iovec), GFP_KERNEL);
864 [ # # ]: 0 : if (iov == NULL)
865 : 0 : goto out;
866 : : }
867 : 0 : *ret_pointer = iov;
868 : :
869 : 0 : ret = -EFAULT;
870 [ # # # # ]: 0 : if (!access_ok(uvector, nr_segs*sizeof(*uvector)))
871 : 0 : goto out;
872 : :
873 : : /*
874 : : * Single unix specification:
875 : : * We should -EINVAL if an element length is not >= 0 and fitting an
876 : : * ssize_t.
877 : : *
878 : : * In Linux, the total length is limited to MAX_RW_COUNT, there is
879 : : * no overflow possibility.
880 : : */
881 : : tot_len = 0;
882 : : ret = -EINVAL;
883 [ # # ]: 0 : for (seg = 0; seg < nr_segs; seg++) {
884 : 0 : compat_uptr_t buf;
885 : 0 : compat_ssize_t len;
886 : :
887 [ # # ]: 0 : if (__get_user(len, &uvector->iov_len) ||
888 [ # # ]: 0 : __get_user(buf, &uvector->iov_base)) {
889 : 0 : ret = -EFAULT;
890 : 0 : goto out;
891 : : }
892 [ # # ]: 0 : if (len < 0) /* size_t not fitting in compat_ssize_t .. */
893 : 0 : goto out;
894 [ # # ]: 0 : if (type >= 0 &&
895 [ # # # # ]: 0 : !access_ok(compat_ptr(buf), len)) {
896 : 0 : ret = -EFAULT;
897 : 0 : goto out;
898 : : }
899 [ # # ]: 0 : if (len > MAX_RW_COUNT - tot_len)
900 : 0 : len = MAX_RW_COUNT - tot_len;
901 : 0 : tot_len += len;
902 : 0 : iov->iov_base = compat_ptr(buf);
903 : 0 : iov->iov_len = (compat_size_t) len;
904 : 0 : uvector++;
905 : 0 : iov++;
906 : : }
907 : 0 : ret = tot_len;
908 : :
909 : 0 : out:
910 : 0 : return ret;
911 : : }
912 : : #endif
913 : :
914 : 0 : static ssize_t do_iter_read(struct file *file, struct iov_iter *iter,
915 : : loff_t *pos, rwf_t flags)
916 : : {
917 : 0 : size_t tot_len;
918 : 0 : ssize_t ret = 0;
919 : :
920 [ # # ]: 0 : if (!(file->f_mode & FMODE_READ))
921 : : return -EBADF;
922 [ # # ]: 0 : if (!(file->f_mode & FMODE_CAN_READ))
923 : : return -EINVAL;
924 : :
925 [ # # ]: 0 : tot_len = iov_iter_count(iter);
926 [ # # ]: 0 : if (!tot_len)
927 : 0 : goto out;
928 : 0 : ret = rw_verify_area(READ, file, pos, tot_len);
929 [ # # ]: 0 : if (ret < 0)
930 : : return ret;
931 : :
932 [ # # ]: 0 : if (file->f_op->read_iter)
933 : 0 : ret = do_iter_readv_writev(file, iter, pos, READ, flags);
934 : : else
935 : 0 : ret = do_loop_readv_writev(file, iter, pos, READ, flags);
936 : 0 : out:
937 [ # # ]: 0 : if (ret >= 0)
938 : 0 : fsnotify_access(file);
939 : : return ret;
940 : : }
941 : :
942 : 0 : ssize_t vfs_iocb_iter_read(struct file *file, struct kiocb *iocb,
943 : : struct iov_iter *iter)
944 : : {
945 : 0 : size_t tot_len;
946 : 0 : ssize_t ret = 0;
947 : :
948 [ # # ]: 0 : if (!file->f_op->read_iter)
949 : : return -EINVAL;
950 [ # # ]: 0 : if (!(file->f_mode & FMODE_READ))
951 : : return -EBADF;
952 [ # # ]: 0 : if (!(file->f_mode & FMODE_CAN_READ))
953 : : return -EINVAL;
954 : :
955 [ # # ]: 0 : tot_len = iov_iter_count(iter);
956 [ # # ]: 0 : if (!tot_len)
957 : 0 : goto out;
958 : 0 : ret = rw_verify_area(READ, file, &iocb->ki_pos, tot_len);
959 [ # # ]: 0 : if (ret < 0)
960 : : return ret;
961 : :
962 : 0 : ret = call_read_iter(file, iocb, iter);
963 : : out:
964 [ # # ]: 0 : if (ret >= 0)
965 : 0 : fsnotify_access(file);
966 : : return ret;
967 : : }
968 : : EXPORT_SYMBOL(vfs_iocb_iter_read);
969 : :
970 : 0 : ssize_t vfs_iter_read(struct file *file, struct iov_iter *iter, loff_t *ppos,
971 : : rwf_t flags)
972 : : {
973 [ # # ]: 0 : if (!file->f_op->read_iter)
974 : : return -EINVAL;
975 : 0 : return do_iter_read(file, iter, ppos, flags);
976 : : }
977 : : EXPORT_SYMBOL(vfs_iter_read);
978 : :
979 : 4582 : static ssize_t do_iter_write(struct file *file, struct iov_iter *iter,
980 : : loff_t *pos, rwf_t flags)
981 : : {
982 : 4582 : size_t tot_len;
983 : 4582 : ssize_t ret = 0;
984 : :
985 [ + - ]: 4582 : if (!(file->f_mode & FMODE_WRITE))
986 : : return -EBADF;
987 [ + - ]: 4582 : if (!(file->f_mode & FMODE_CAN_WRITE))
988 : : return -EINVAL;
989 : :
990 [ + - ]: 4582 : tot_len = iov_iter_count(iter);
991 [ + - ]: 4582 : if (!tot_len)
992 : : return 0;
993 : 4582 : ret = rw_verify_area(WRITE, file, pos, tot_len);
994 [ + - ]: 4582 : if (ret < 0)
995 : : return ret;
996 : :
997 [ + + ]: 4582 : if (file->f_op->write_iter)
998 : 1894 : ret = do_iter_readv_writev(file, iter, pos, WRITE, flags);
999 : : else
1000 : 2688 : ret = do_loop_readv_writev(file, iter, pos, WRITE, flags);
1001 [ + - ]: 4582 : if (ret > 0)
1002 : 4582 : fsnotify_modify(file);
1003 : : return ret;
1004 : : }
1005 : :
1006 : 0 : ssize_t vfs_iocb_iter_write(struct file *file, struct kiocb *iocb,
1007 : : struct iov_iter *iter)
1008 : : {
1009 : 0 : size_t tot_len;
1010 : 0 : ssize_t ret = 0;
1011 : :
1012 [ # # ]: 0 : if (!file->f_op->write_iter)
1013 : : return -EINVAL;
1014 [ # # ]: 0 : if (!(file->f_mode & FMODE_WRITE))
1015 : : return -EBADF;
1016 [ # # ]: 0 : if (!(file->f_mode & FMODE_CAN_WRITE))
1017 : : return -EINVAL;
1018 : :
1019 [ # # ]: 0 : tot_len = iov_iter_count(iter);
1020 [ # # ]: 0 : if (!tot_len)
1021 : : return 0;
1022 : 0 : ret = rw_verify_area(WRITE, file, &iocb->ki_pos, tot_len);
1023 [ # # ]: 0 : if (ret < 0)
1024 : : return ret;
1025 : :
1026 : 0 : ret = call_write_iter(file, iocb, iter);
1027 [ # # ]: 0 : if (ret > 0)
1028 : 0 : fsnotify_modify(file);
1029 : :
1030 : : return ret;
1031 : : }
1032 : : EXPORT_SYMBOL(vfs_iocb_iter_write);
1033 : :
1034 : 120 : ssize_t vfs_iter_write(struct file *file, struct iov_iter *iter, loff_t *ppos,
1035 : : rwf_t flags)
1036 : : {
1037 [ + - ]: 120 : if (!file->f_op->write_iter)
1038 : : return -EINVAL;
1039 : 120 : return do_iter_write(file, iter, ppos, flags);
1040 : : }
1041 : : EXPORT_SYMBOL(vfs_iter_write);
1042 : :
1043 : 0 : ssize_t vfs_readv(struct file *file, const struct iovec __user *vec,
1044 : : unsigned long vlen, loff_t *pos, rwf_t flags)
1045 : : {
1046 : 0 : struct iovec iovstack[UIO_FASTIOV];
1047 : 0 : struct iovec *iov = iovstack;
1048 : 0 : struct iov_iter iter;
1049 : 0 : ssize_t ret;
1050 : :
1051 : 0 : ret = import_iovec(READ, vec, vlen, ARRAY_SIZE(iovstack), &iov, &iter);
1052 [ # # ]: 0 : if (ret >= 0) {
1053 : 0 : ret = do_iter_read(file, &iter, pos, flags);
1054 : 0 : kfree(iov);
1055 : : }
1056 : :
1057 : 0 : return ret;
1058 : : }
1059 : :
1060 : 4462 : static ssize_t vfs_writev(struct file *file, const struct iovec __user *vec,
1061 : : unsigned long vlen, loff_t *pos, rwf_t flags)
1062 : : {
1063 : 4462 : struct iovec iovstack[UIO_FASTIOV];
1064 : 4462 : struct iovec *iov = iovstack;
1065 : 4462 : struct iov_iter iter;
1066 : 4462 : ssize_t ret;
1067 : :
1068 : 4462 : ret = import_iovec(WRITE, vec, vlen, ARRAY_SIZE(iovstack), &iov, &iter);
1069 [ + - ]: 4462 : if (ret >= 0) {
1070 : 4462 : file_start_write(file);
1071 : 4462 : ret = do_iter_write(file, &iter, pos, flags);
1072 [ - + ]: 4462 : file_end_write(file);
1073 : 4462 : kfree(iov);
1074 : : }
1075 : 4462 : return ret;
1076 : : }
1077 : :
1078 : 0 : static ssize_t do_readv(unsigned long fd, const struct iovec __user *vec,
1079 : : unsigned long vlen, rwf_t flags)
1080 : : {
1081 : 0 : struct fd f = fdget_pos(fd);
1082 : 0 : ssize_t ret = -EBADF;
1083 : :
1084 [ # # ]: 0 : if (f.file) {
1085 [ # # ]: 0 : loff_t pos, *ppos = file_ppos(f.file);
1086 [ # # ]: 0 : if (ppos) {
1087 : 0 : pos = *ppos;
1088 : 0 : ppos = &pos;
1089 : : }
1090 : 0 : ret = vfs_readv(f.file, vec, vlen, ppos, flags);
1091 [ # # ]: 0 : if (ret >= 0 && ppos)
1092 : 0 : f.file->f_pos = pos;
1093 : 0 : fdput_pos(f);
1094 : : }
1095 : :
1096 [ # # ]: 0 : if (ret > 0)
1097 : 0 : add_rchar(current, ret);
1098 : 0 : inc_syscr(current);
1099 : 0 : return ret;
1100 : : }
1101 : :
1102 : 4462 : static ssize_t do_writev(unsigned long fd, const struct iovec __user *vec,
1103 : : unsigned long vlen, rwf_t flags)
1104 : : {
1105 : 4462 : struct fd f = fdget_pos(fd);
1106 : 4462 : ssize_t ret = -EBADF;
1107 : :
1108 [ + - ]: 4462 : if (f.file) {
1109 [ + + ]: 4462 : loff_t pos, *ppos = file_ppos(f.file);
1110 [ + - ]: 4432 : if (ppos) {
1111 : 4432 : pos = *ppos;
1112 : 4432 : ppos = &pos;
1113 : : }
1114 : 4462 : ret = vfs_writev(f.file, vec, vlen, ppos, flags);
1115 [ + + ]: 4462 : if (ret >= 0 && ppos)
1116 : 4432 : f.file->f_pos = pos;
1117 : 4462 : fdput_pos(f);
1118 : : }
1119 : :
1120 [ + - ]: 4462 : if (ret > 0)
1121 : 4462 : add_wchar(current, ret);
1122 : 4462 : inc_syscw(current);
1123 : 4462 : return ret;
1124 : : }
1125 : :
1126 : 0 : static inline loff_t pos_from_hilo(unsigned long high, unsigned long low)
1127 : : {
1128 : : #define HALF_LONG_BITS (BITS_PER_LONG / 2)
1129 : 0 : return (((loff_t)high << HALF_LONG_BITS) << HALF_LONG_BITS) | low;
1130 : : }
1131 : :
1132 : 0 : static ssize_t do_preadv(unsigned long fd, const struct iovec __user *vec,
1133 : : unsigned long vlen, loff_t pos, rwf_t flags)
1134 : : {
1135 : 0 : struct fd f;
1136 : 0 : ssize_t ret = -EBADF;
1137 : :
1138 [ # # ]: 0 : if (pos < 0)
1139 : : return -EINVAL;
1140 : :
1141 : 0 : f = fdget(fd);
1142 [ # # ]: 0 : if (f.file) {
1143 : 0 : ret = -ESPIPE;
1144 [ # # ]: 0 : if (f.file->f_mode & FMODE_PREAD)
1145 : 0 : ret = vfs_readv(f.file, vec, vlen, &pos, flags);
1146 [ # # ]: 0 : fdput(f);
1147 : : }
1148 : :
1149 [ # # ]: 0 : if (ret > 0)
1150 : 0 : add_rchar(current, ret);
1151 : 0 : inc_syscr(current);
1152 : 0 : return ret;
1153 : : }
1154 : :
1155 : 0 : static ssize_t do_pwritev(unsigned long fd, const struct iovec __user *vec,
1156 : : unsigned long vlen, loff_t pos, rwf_t flags)
1157 : : {
1158 : 0 : struct fd f;
1159 : 0 : ssize_t ret = -EBADF;
1160 : :
1161 [ # # ]: 0 : if (pos < 0)
1162 : : return -EINVAL;
1163 : :
1164 : 0 : f = fdget(fd);
1165 [ # # ]: 0 : if (f.file) {
1166 : 0 : ret = -ESPIPE;
1167 [ # # ]: 0 : if (f.file->f_mode & FMODE_PWRITE)
1168 : 0 : ret = vfs_writev(f.file, vec, vlen, &pos, flags);
1169 [ # # ]: 0 : fdput(f);
1170 : : }
1171 : :
1172 [ # # ]: 0 : if (ret > 0)
1173 : 0 : add_wchar(current, ret);
1174 : 0 : inc_syscw(current);
1175 : 0 : return ret;
1176 : : }
1177 : :
1178 : 0 : SYSCALL_DEFINE3(readv, unsigned long, fd, const struct iovec __user *, vec,
1179 : : unsigned long, vlen)
1180 : : {
1181 : 0 : return do_readv(fd, vec, vlen, 0);
1182 : : }
1183 : :
1184 : 8924 : SYSCALL_DEFINE3(writev, unsigned long, fd, const struct iovec __user *, vec,
1185 : : unsigned long, vlen)
1186 : : {
1187 : 4462 : return do_writev(fd, vec, vlen, 0);
1188 : : }
1189 : :
1190 : 0 : SYSCALL_DEFINE5(preadv, unsigned long, fd, const struct iovec __user *, vec,
1191 : : unsigned long, vlen, unsigned long, pos_l, unsigned long, pos_h)
1192 : : {
1193 : 0 : loff_t pos = pos_from_hilo(pos_h, pos_l);
1194 : :
1195 : 0 : return do_preadv(fd, vec, vlen, pos, 0);
1196 : : }
1197 : :
1198 : 0 : SYSCALL_DEFINE6(preadv2, unsigned long, fd, const struct iovec __user *, vec,
1199 : : unsigned long, vlen, unsigned long, pos_l, unsigned long, pos_h,
1200 : : rwf_t, flags)
1201 : : {
1202 : : loff_t pos = pos_from_hilo(pos_h, pos_l);
1203 : :
1204 : : if (pos == -1)
1205 : : return do_readv(fd, vec, vlen, flags);
1206 : :
1207 : : return do_preadv(fd, vec, vlen, pos, flags);
1208 : : }
1209 : :
1210 : 0 : SYSCALL_DEFINE5(pwritev, unsigned long, fd, const struct iovec __user *, vec,
1211 : : unsigned long, vlen, unsigned long, pos_l, unsigned long, pos_h)
1212 : : {
1213 : 0 : loff_t pos = pos_from_hilo(pos_h, pos_l);
1214 : :
1215 : 0 : return do_pwritev(fd, vec, vlen, pos, 0);
1216 : : }
1217 : :
1218 : 0 : SYSCALL_DEFINE6(pwritev2, unsigned long, fd, const struct iovec __user *, vec,
1219 : : unsigned long, vlen, unsigned long, pos_l, unsigned long, pos_h,
1220 : : rwf_t, flags)
1221 : : {
1222 : : loff_t pos = pos_from_hilo(pos_h, pos_l);
1223 : :
1224 : : if (pos == -1)
1225 : : return do_writev(fd, vec, vlen, flags);
1226 : :
1227 : : return do_pwritev(fd, vec, vlen, pos, flags);
1228 : : }
1229 : :
1230 : : #ifdef CONFIG_COMPAT
1231 : 0 : static size_t compat_readv(struct file *file,
1232 : : const struct compat_iovec __user *vec,
1233 : : unsigned long vlen, loff_t *pos, rwf_t flags)
1234 : : {
1235 : 0 : struct iovec iovstack[UIO_FASTIOV];
1236 : 0 : struct iovec *iov = iovstack;
1237 : 0 : struct iov_iter iter;
1238 : 0 : ssize_t ret;
1239 : :
1240 : 0 : ret = compat_import_iovec(READ, vec, vlen, UIO_FASTIOV, &iov, &iter);
1241 [ # # ]: 0 : if (ret >= 0) {
1242 : 0 : ret = do_iter_read(file, &iter, pos, flags);
1243 : 0 : kfree(iov);
1244 : : }
1245 [ # # ]: 0 : if (ret > 0)
1246 : 0 : add_rchar(current, ret);
1247 : 0 : inc_syscr(current);
1248 : 0 : return ret;
1249 : : }
1250 : :
1251 : 0 : static size_t do_compat_readv(compat_ulong_t fd,
1252 : : const struct compat_iovec __user *vec,
1253 : : compat_ulong_t vlen, rwf_t flags)
1254 : : {
1255 : 0 : struct fd f = fdget_pos(fd);
1256 : 0 : ssize_t ret;
1257 : 0 : loff_t pos;
1258 : :
1259 [ # # ]: 0 : if (!f.file)
1260 : : return -EBADF;
1261 : 0 : pos = f.file->f_pos;
1262 : 0 : ret = compat_readv(f.file, vec, vlen, &pos, flags);
1263 [ # # ]: 0 : if (ret >= 0)
1264 : 0 : f.file->f_pos = pos;
1265 : 0 : fdput_pos(f);
1266 : 0 : return ret;
1267 : :
1268 : : }
1269 : :
1270 : 0 : COMPAT_SYSCALL_DEFINE3(readv, compat_ulong_t, fd,
1271 : : const struct compat_iovec __user *,vec,
1272 : : compat_ulong_t, vlen)
1273 : : {
1274 : 0 : return do_compat_readv(fd, vec, vlen, 0);
1275 : : }
1276 : :
1277 : 0 : static long do_compat_preadv64(unsigned long fd,
1278 : : const struct compat_iovec __user *vec,
1279 : : unsigned long vlen, loff_t pos, rwf_t flags)
1280 : : {
1281 : 0 : struct fd f;
1282 : 0 : ssize_t ret;
1283 : :
1284 [ # # ]: 0 : if (pos < 0)
1285 : : return -EINVAL;
1286 : 0 : f = fdget(fd);
1287 [ # # ]: 0 : if (!f.file)
1288 : : return -EBADF;
1289 : 0 : ret = -ESPIPE;
1290 [ # # ]: 0 : if (f.file->f_mode & FMODE_PREAD)
1291 : 0 : ret = compat_readv(f.file, vec, vlen, &pos, flags);
1292 [ # # ]: 0 : fdput(f);
1293 : : return ret;
1294 : : }
1295 : :
1296 : : #ifdef __ARCH_WANT_COMPAT_SYS_PREADV64
1297 : 0 : COMPAT_SYSCALL_DEFINE4(preadv64, unsigned long, fd,
1298 : : const struct compat_iovec __user *,vec,
1299 : : unsigned long, vlen, loff_t, pos)
1300 : : {
1301 : 0 : return do_compat_preadv64(fd, vec, vlen, pos, 0);
1302 : : }
1303 : : #endif
1304 : :
1305 : 0 : COMPAT_SYSCALL_DEFINE5(preadv, compat_ulong_t, fd,
1306 : : const struct compat_iovec __user *,vec,
1307 : : compat_ulong_t, vlen, u32, pos_low, u32, pos_high)
1308 : : {
1309 : 0 : loff_t pos = ((loff_t)pos_high << 32) | pos_low;
1310 : :
1311 : 0 : return do_compat_preadv64(fd, vec, vlen, pos, 0);
1312 : : }
1313 : :
1314 : : #ifdef __ARCH_WANT_COMPAT_SYS_PREADV64V2
1315 : 0 : COMPAT_SYSCALL_DEFINE5(preadv64v2, unsigned long, fd,
1316 : : const struct compat_iovec __user *,vec,
1317 : : unsigned long, vlen, loff_t, pos, rwf_t, flags)
1318 : : {
1319 [ # # ]: 0 : if (pos == -1)
1320 : 0 : return do_compat_readv(fd, vec, vlen, flags);
1321 : :
1322 : 0 : return do_compat_preadv64(fd, vec, vlen, pos, flags);
1323 : : }
1324 : : #endif
1325 : :
1326 : 0 : COMPAT_SYSCALL_DEFINE6(preadv2, compat_ulong_t, fd,
1327 : : const struct compat_iovec __user *,vec,
1328 : : compat_ulong_t, vlen, u32, pos_low, u32, pos_high,
1329 : : rwf_t, flags)
1330 : : {
1331 : 0 : loff_t pos = ((loff_t)pos_high << 32) | pos_low;
1332 : :
1333 [ # # ]: 0 : if (pos == -1)
1334 : 0 : return do_compat_readv(fd, vec, vlen, flags);
1335 : :
1336 : 0 : return do_compat_preadv64(fd, vec, vlen, pos, flags);
1337 : : }
1338 : :
1339 : 0 : static size_t compat_writev(struct file *file,
1340 : : const struct compat_iovec __user *vec,
1341 : : unsigned long vlen, loff_t *pos, rwf_t flags)
1342 : : {
1343 : 0 : struct iovec iovstack[UIO_FASTIOV];
1344 : 0 : struct iovec *iov = iovstack;
1345 : 0 : struct iov_iter iter;
1346 : 0 : ssize_t ret;
1347 : :
1348 : 0 : ret = compat_import_iovec(WRITE, vec, vlen, UIO_FASTIOV, &iov, &iter);
1349 [ # # ]: 0 : if (ret >= 0) {
1350 : 0 : file_start_write(file);
1351 : 0 : ret = do_iter_write(file, &iter, pos, flags);
1352 [ # # ]: 0 : file_end_write(file);
1353 : 0 : kfree(iov);
1354 : : }
1355 [ # # ]: 0 : if (ret > 0)
1356 : 0 : add_wchar(current, ret);
1357 : 0 : inc_syscw(current);
1358 : 0 : return ret;
1359 : : }
1360 : :
1361 : 0 : static size_t do_compat_writev(compat_ulong_t fd,
1362 : : const struct compat_iovec __user* vec,
1363 : : compat_ulong_t vlen, rwf_t flags)
1364 : : {
1365 : 0 : struct fd f = fdget_pos(fd);
1366 : 0 : ssize_t ret;
1367 : 0 : loff_t pos;
1368 : :
1369 [ # # ]: 0 : if (!f.file)
1370 : : return -EBADF;
1371 : 0 : pos = f.file->f_pos;
1372 : 0 : ret = compat_writev(f.file, vec, vlen, &pos, flags);
1373 [ # # ]: 0 : if (ret >= 0)
1374 : 0 : f.file->f_pos = pos;
1375 : 0 : fdput_pos(f);
1376 : 0 : return ret;
1377 : : }
1378 : :
1379 : 0 : COMPAT_SYSCALL_DEFINE3(writev, compat_ulong_t, fd,
1380 : : const struct compat_iovec __user *, vec,
1381 : : compat_ulong_t, vlen)
1382 : : {
1383 : 0 : return do_compat_writev(fd, vec, vlen, 0);
1384 : : }
1385 : :
1386 : 0 : static long do_compat_pwritev64(unsigned long fd,
1387 : : const struct compat_iovec __user *vec,
1388 : : unsigned long vlen, loff_t pos, rwf_t flags)
1389 : : {
1390 : 0 : struct fd f;
1391 : 0 : ssize_t ret;
1392 : :
1393 [ # # ]: 0 : if (pos < 0)
1394 : : return -EINVAL;
1395 : 0 : f = fdget(fd);
1396 [ # # ]: 0 : if (!f.file)
1397 : : return -EBADF;
1398 : 0 : ret = -ESPIPE;
1399 [ # # ]: 0 : if (f.file->f_mode & FMODE_PWRITE)
1400 : 0 : ret = compat_writev(f.file, vec, vlen, &pos, flags);
1401 [ # # ]: 0 : fdput(f);
1402 : : return ret;
1403 : : }
1404 : :
1405 : : #ifdef __ARCH_WANT_COMPAT_SYS_PWRITEV64
1406 : 0 : COMPAT_SYSCALL_DEFINE4(pwritev64, unsigned long, fd,
1407 : : const struct compat_iovec __user *,vec,
1408 : : unsigned long, vlen, loff_t, pos)
1409 : : {
1410 : 0 : return do_compat_pwritev64(fd, vec, vlen, pos, 0);
1411 : : }
1412 : : #endif
1413 : :
1414 : 0 : COMPAT_SYSCALL_DEFINE5(pwritev, compat_ulong_t, fd,
1415 : : const struct compat_iovec __user *,vec,
1416 : : compat_ulong_t, vlen, u32, pos_low, u32, pos_high)
1417 : : {
1418 : 0 : loff_t pos = ((loff_t)pos_high << 32) | pos_low;
1419 : :
1420 : 0 : return do_compat_pwritev64(fd, vec, vlen, pos, 0);
1421 : : }
1422 : :
1423 : : #ifdef __ARCH_WANT_COMPAT_SYS_PWRITEV64V2
1424 : 0 : COMPAT_SYSCALL_DEFINE5(pwritev64v2, unsigned long, fd,
1425 : : const struct compat_iovec __user *,vec,
1426 : : unsigned long, vlen, loff_t, pos, rwf_t, flags)
1427 : : {
1428 [ # # ]: 0 : if (pos == -1)
1429 : 0 : return do_compat_writev(fd, vec, vlen, flags);
1430 : :
1431 : 0 : return do_compat_pwritev64(fd, vec, vlen, pos, flags);
1432 : : }
1433 : : #endif
1434 : :
1435 : 0 : COMPAT_SYSCALL_DEFINE6(pwritev2, compat_ulong_t, fd,
1436 : : const struct compat_iovec __user *,vec,
1437 : : compat_ulong_t, vlen, u32, pos_low, u32, pos_high, rwf_t, flags)
1438 : : {
1439 : 0 : loff_t pos = ((loff_t)pos_high << 32) | pos_low;
1440 : :
1441 [ # # ]: 0 : if (pos == -1)
1442 : 0 : return do_compat_writev(fd, vec, vlen, flags);
1443 : :
1444 : 0 : return do_compat_pwritev64(fd, vec, vlen, pos, flags);
1445 : : }
1446 : :
1447 : : #endif
1448 : :
1449 : 0 : static ssize_t do_sendfile(int out_fd, int in_fd, loff_t *ppos,
1450 : : size_t count, loff_t max)
1451 : : {
1452 : 0 : struct fd in, out;
1453 : 0 : struct inode *in_inode, *out_inode;
1454 : 0 : loff_t pos;
1455 : 0 : loff_t out_pos;
1456 : 0 : ssize_t retval;
1457 : 0 : int fl;
1458 : :
1459 : : /*
1460 : : * Get input file, and verify that it is ok..
1461 : : */
1462 : 0 : retval = -EBADF;
1463 : 0 : in = fdget(in_fd);
1464 [ # # ]: 0 : if (!in.file)
1465 : 0 : goto out;
1466 [ # # ]: 0 : if (!(in.file->f_mode & FMODE_READ))
1467 : 0 : goto fput_in;
1468 : 0 : retval = -ESPIPE;
1469 [ # # ]: 0 : if (!ppos) {
1470 : 0 : pos = in.file->f_pos;
1471 : : } else {
1472 : 0 : pos = *ppos;
1473 [ # # ]: 0 : if (!(in.file->f_mode & FMODE_PREAD))
1474 : 0 : goto fput_in;
1475 : : }
1476 : 0 : retval = rw_verify_area(READ, in.file, &pos, count);
1477 [ # # ]: 0 : if (retval < 0)
1478 : 0 : goto fput_in;
1479 : 0 : if (count > MAX_RW_COUNT)
1480 : : count = MAX_RW_COUNT;
1481 : :
1482 : : /*
1483 : : * Get output file, and verify that it is ok..
1484 : : */
1485 : 0 : retval = -EBADF;
1486 : 0 : out = fdget(out_fd);
1487 [ # # ]: 0 : if (!out.file)
1488 : 0 : goto fput_in;
1489 [ # # ]: 0 : if (!(out.file->f_mode & FMODE_WRITE))
1490 : 0 : goto fput_out;
1491 : 0 : in_inode = file_inode(in.file);
1492 : 0 : out_inode = file_inode(out.file);
1493 : 0 : out_pos = out.file->f_pos;
1494 : 0 : retval = rw_verify_area(WRITE, out.file, &out_pos, count);
1495 [ # # ]: 0 : if (retval < 0)
1496 : 0 : goto fput_out;
1497 : :
1498 [ # # ]: 0 : if (!max)
1499 : 0 : max = min(in_inode->i_sb->s_maxbytes, out_inode->i_sb->s_maxbytes);
1500 : :
1501 [ # # ]: 0 : if (unlikely(pos + count > max)) {
1502 : 0 : retval = -EOVERFLOW;
1503 [ # # ]: 0 : if (pos >= max)
1504 : 0 : goto fput_out;
1505 : 0 : count = max - pos;
1506 : : }
1507 : :
1508 : 0 : fl = 0;
1509 : : #if 0
1510 : : /*
1511 : : * We need to debate whether we can enable this or not. The
1512 : : * man page documents EAGAIN return for the output at least,
1513 : : * and the application is arguably buggy if it doesn't expect
1514 : : * EAGAIN on a non-blocking file descriptor.
1515 : : */
1516 : : if (in.file->f_flags & O_NONBLOCK)
1517 : : fl = SPLICE_F_NONBLOCK;
1518 : : #endif
1519 : 0 : file_start_write(out.file);
1520 : 0 : retval = do_splice_direct(in.file, &pos, out.file, &out_pos, count, fl);
1521 [ # # ]: 0 : file_end_write(out.file);
1522 : :
1523 [ # # ]: 0 : if (retval > 0) {
1524 : 0 : add_rchar(current, retval);
1525 : 0 : add_wchar(current, retval);
1526 : 0 : fsnotify_access(in.file);
1527 : 0 : fsnotify_modify(out.file);
1528 : 0 : out.file->f_pos = out_pos;
1529 [ # # ]: 0 : if (ppos)
1530 : 0 : *ppos = pos;
1531 : : else
1532 : 0 : in.file->f_pos = pos;
1533 : : }
1534 : :
1535 [ # # ]: 0 : inc_syscr(current);
1536 [ # # ]: 0 : inc_syscw(current);
1537 [ # # ]: 0 : if (pos > max)
1538 : 0 : retval = -EOVERFLOW;
1539 : :
1540 : 0 : fput_out:
1541 [ # # ]: 0 : fdput(out);
1542 : 0 : fput_in:
1543 [ # # ]: 0 : fdput(in);
1544 : 0 : out:
1545 : 0 : return retval;
1546 : : }
1547 : :
1548 : 0 : SYSCALL_DEFINE4(sendfile, int, out_fd, int, in_fd, off_t __user *, offset, size_t, count)
1549 : : {
1550 : 0 : loff_t pos;
1551 : 0 : off_t off;
1552 : 0 : ssize_t ret;
1553 : :
1554 [ # # ]: 0 : if (offset) {
1555 [ # # ]: 0 : if (unlikely(get_user(off, offset)))
1556 : : return -EFAULT;
1557 : 0 : pos = off;
1558 : 0 : ret = do_sendfile(out_fd, in_fd, &pos, count, MAX_NON_LFS);
1559 [ # # ]: 0 : if (unlikely(put_user(pos, offset)))
1560 : : return -EFAULT;
1561 : 0 : return ret;
1562 : : }
1563 : :
1564 : 0 : return do_sendfile(out_fd, in_fd, NULL, count, 0);
1565 : : }
1566 : :
1567 : 0 : SYSCALL_DEFINE4(sendfile64, int, out_fd, int, in_fd, loff_t __user *, offset, size_t, count)
1568 : : {
1569 : 0 : loff_t pos;
1570 : 0 : ssize_t ret;
1571 : :
1572 [ # # ]: 0 : if (offset) {
1573 [ # # ]: 0 : if (unlikely(copy_from_user(&pos, offset, sizeof(loff_t))))
1574 : : return -EFAULT;
1575 : 0 : ret = do_sendfile(out_fd, in_fd, &pos, count, 0);
1576 [ # # ]: 0 : if (unlikely(put_user(pos, offset)))
1577 : : return -EFAULT;
1578 : 0 : return ret;
1579 : : }
1580 : :
1581 : 0 : return do_sendfile(out_fd, in_fd, NULL, count, 0);
1582 : : }
1583 : :
1584 : : #ifdef CONFIG_COMPAT
1585 : 0 : COMPAT_SYSCALL_DEFINE4(sendfile, int, out_fd, int, in_fd,
1586 : : compat_off_t __user *, offset, compat_size_t, count)
1587 : : {
1588 : 0 : loff_t pos;
1589 : 0 : off_t off;
1590 : 0 : ssize_t ret;
1591 : :
1592 [ # # ]: 0 : if (offset) {
1593 [ # # ]: 0 : if (unlikely(get_user(off, offset)))
1594 : : return -EFAULT;
1595 : 0 : pos = off;
1596 : 0 : ret = do_sendfile(out_fd, in_fd, &pos, count, MAX_NON_LFS);
1597 [ # # ]: 0 : if (unlikely(put_user(pos, offset)))
1598 : : return -EFAULT;
1599 : 0 : return ret;
1600 : : }
1601 : :
1602 : 0 : return do_sendfile(out_fd, in_fd, NULL, count, 0);
1603 : : }
1604 : :
1605 : 0 : COMPAT_SYSCALL_DEFINE4(sendfile64, int, out_fd, int, in_fd,
1606 : : compat_loff_t __user *, offset, compat_size_t, count)
1607 : : {
1608 : 0 : loff_t pos;
1609 : 0 : ssize_t ret;
1610 : :
1611 [ # # ]: 0 : if (offset) {
1612 [ # # ]: 0 : if (unlikely(copy_from_user(&pos, offset, sizeof(loff_t))))
1613 : : return -EFAULT;
1614 : 0 : ret = do_sendfile(out_fd, in_fd, &pos, count, 0);
1615 [ # # ]: 0 : if (unlikely(put_user(pos, offset)))
1616 : : return -EFAULT;
1617 : 0 : return ret;
1618 : : }
1619 : :
1620 : 0 : return do_sendfile(out_fd, in_fd, NULL, count, 0);
1621 : : }
1622 : : #endif
1623 : :
1624 : : /**
1625 : : * generic_copy_file_range - copy data between two files
1626 : : * @file_in: file structure to read from
1627 : : * @pos_in: file offset to read from
1628 : : * @file_out: file structure to write data to
1629 : : * @pos_out: file offset to write data to
1630 : : * @len: amount of data to copy
1631 : : * @flags: copy flags
1632 : : *
1633 : : * This is a generic filesystem helper to copy data from one file to another.
1634 : : * It has no constraints on the source or destination file owners - the files
1635 : : * can belong to different superblocks and different filesystem types. Short
1636 : : * copies are allowed.
1637 : : *
1638 : : * This should be called from the @file_out filesystem, as per the
1639 : : * ->copy_file_range() method.
1640 : : *
1641 : : * Returns the number of bytes copied or a negative error indicating the
1642 : : * failure.
1643 : : */
1644 : :
1645 : 120 : ssize_t generic_copy_file_range(struct file *file_in, loff_t pos_in,
1646 : : struct file *file_out, loff_t pos_out,
1647 : : size_t len, unsigned int flags)
1648 : : {
1649 : 120 : return do_splice_direct(file_in, &pos_in, file_out, &pos_out,
1650 : 0 : len > MAX_RW_COUNT ? MAX_RW_COUNT : len, 0);
1651 : : }
1652 : : EXPORT_SYMBOL(generic_copy_file_range);
1653 : :
1654 : 120 : static ssize_t do_copy_file_range(struct file *file_in, loff_t pos_in,
1655 : : struct file *file_out, loff_t pos_out,
1656 : : size_t len, unsigned int flags)
1657 : : {
1658 : : /*
1659 : : * Although we now allow filesystems to handle cross sb copy, passing
1660 : : * a file of the wrong filesystem type to filesystem driver can result
1661 : : * in an attempt to dereference the wrong type of ->private_data, so
1662 : : * avoid doing that until we really have a good reason. NFS defines
1663 : : * several different file_system_type structures, but they all end up
1664 : : * using the same ->copy_file_range() function pointer.
1665 : : */
1666 [ - + ]: 120 : if (file_out->f_op->copy_file_range &&
1667 [ # # ]: 0 : file_out->f_op->copy_file_range == file_in->f_op->copy_file_range)
1668 : 0 : return file_out->f_op->copy_file_range(file_in, pos_in,
1669 : : file_out, pos_out,
1670 : : len, flags);
1671 : :
1672 : 120 : return generic_copy_file_range(file_in, pos_in, file_out, pos_out, len,
1673 : : flags);
1674 : : }
1675 : :
1676 : : /*
1677 : : * copy_file_range() differs from regular file read and write in that it
1678 : : * specifically allows return partial success. When it does so is up to
1679 : : * the copy_file_range method.
1680 : : */
1681 : 240 : ssize_t vfs_copy_file_range(struct file *file_in, loff_t pos_in,
1682 : : struct file *file_out, loff_t pos_out,
1683 : : size_t len, unsigned int flags)
1684 : : {
1685 : 240 : ssize_t ret;
1686 : :
1687 [ + - ]: 240 : if (flags != 0)
1688 : : return -EINVAL;
1689 : :
1690 : 240 : ret = generic_copy_file_checks(file_in, pos_in, file_out, pos_out, &len,
1691 : : flags);
1692 [ + - ]: 240 : if (unlikely(ret))
1693 : : return ret;
1694 : :
1695 : 240 : ret = rw_verify_area(READ, file_in, &pos_in, len);
1696 [ + - ]: 240 : if (unlikely(ret))
1697 : : return ret;
1698 : :
1699 : 240 : ret = rw_verify_area(WRITE, file_out, &pos_out, len);
1700 [ + - ]: 240 : if (unlikely(ret))
1701 : : return ret;
1702 : :
1703 [ + + ]: 240 : if (len == 0)
1704 : : return 0;
1705 : :
1706 : 120 : file_start_write(file_out);
1707 : :
1708 : : /*
1709 : : * Try cloning first, this is supported by more file systems, and
1710 : : * more efficient if both clone and copy are supported (e.g. NFS).
1711 : : */
1712 [ - + - - ]: 120 : if (file_in->f_op->remap_file_range &&
1713 [ # # ]: 0 : file_inode(file_in)->i_sb == file_inode(file_out)->i_sb) {
1714 : 0 : loff_t cloned;
1715 : :
1716 : 0 : cloned = file_in->f_op->remap_file_range(file_in, pos_in,
1717 : : file_out, pos_out,
1718 : 0 : min_t(loff_t, MAX_RW_COUNT, len),
1719 : : REMAP_FILE_CAN_SHORTEN);
1720 [ # # ]: 0 : if (cloned > 0) {
1721 : 0 : ret = cloned;
1722 : 0 : goto done;
1723 : : }
1724 : : }
1725 : :
1726 : 120 : ret = do_copy_file_range(file_in, pos_in, file_out, pos_out, len,
1727 : : flags);
1728 [ - + ]: 120 : WARN_ON_ONCE(ret == -EOPNOTSUPP);
1729 : 120 : done:
1730 [ + - ]: 120 : if (ret > 0) {
1731 : 120 : fsnotify_access(file_in);
1732 : 120 : add_rchar(current, ret);
1733 : 120 : fsnotify_modify(file_out);
1734 : 120 : add_wchar(current, ret);
1735 : : }
1736 : :
1737 [ + - ]: 120 : inc_syscr(current);
1738 [ + - ]: 120 : inc_syscw(current);
1739 : :
1740 [ + - ]: 120 : file_end_write(file_out);
1741 : :
1742 : : return ret;
1743 : : }
1744 : : EXPORT_SYMBOL(vfs_copy_file_range);
1745 : :
1746 : 480 : SYSCALL_DEFINE6(copy_file_range, int, fd_in, loff_t __user *, off_in,
1747 : : int, fd_out, loff_t __user *, off_out,
1748 : : size_t, len, unsigned int, flags)
1749 : : {
1750 : 240 : loff_t pos_in;
1751 : 240 : loff_t pos_out;
1752 : 240 : struct fd f_in;
1753 : 240 : struct fd f_out;
1754 : 240 : ssize_t ret = -EBADF;
1755 : :
1756 : 240 : f_in = fdget(fd_in);
1757 [ - + ]: 240 : if (!f_in.file)
1758 : 0 : goto out2;
1759 : :
1760 : 240 : f_out = fdget(fd_out);
1761 [ - + ]: 240 : if (!f_out.file)
1762 : 0 : goto out1;
1763 : :
1764 : 240 : ret = -EFAULT;
1765 [ - + ]: 240 : if (off_in) {
1766 [ # # ]: 0 : if (copy_from_user(&pos_in, off_in, sizeof(loff_t)))
1767 : 0 : goto out;
1768 : : } else {
1769 : 240 : pos_in = f_in.file->f_pos;
1770 : : }
1771 : :
1772 [ - + ]: 240 : if (off_out) {
1773 [ # # ]: 0 : if (copy_from_user(&pos_out, off_out, sizeof(loff_t)))
1774 : 0 : goto out;
1775 : : } else {
1776 : 240 : pos_out = f_out.file->f_pos;
1777 : : }
1778 : :
1779 : 240 : ret = vfs_copy_file_range(f_in.file, pos_in, f_out.file, pos_out, len,
1780 : : flags);
1781 [ + + ]: 240 : if (ret > 0) {
1782 : 120 : pos_in += ret;
1783 : 120 : pos_out += ret;
1784 : :
1785 [ - + ]: 120 : if (off_in) {
1786 [ # # ]: 0 : if (copy_to_user(off_in, &pos_in, sizeof(loff_t)))
1787 : 0 : ret = -EFAULT;
1788 : : } else {
1789 : 120 : f_in.file->f_pos = pos_in;
1790 : : }
1791 : :
1792 [ - + ]: 120 : if (off_out) {
1793 [ # # ]: 0 : if (copy_to_user(off_out, &pos_out, sizeof(loff_t)))
1794 : 0 : ret = -EFAULT;
1795 : : } else {
1796 : 120 : f_out.file->f_pos = pos_out;
1797 : : }
1798 : : }
1799 : :
1800 : 120 : out:
1801 [ - + ]: 240 : fdput(f_out);
1802 : 240 : out1:
1803 [ - + ]: 240 : fdput(f_in);
1804 : 240 : out2:
1805 : 240 : return ret;
1806 : : }
1807 : :
1808 : 0 : static int remap_verify_area(struct file *file, loff_t pos, loff_t len,
1809 : : bool write)
1810 : : {
1811 [ # # ]: 0 : struct inode *inode = file_inode(file);
1812 : :
1813 [ # # ]: 0 : if (unlikely(pos < 0 || len < 0))
1814 : : return -EINVAL;
1815 : :
1816 [ # # ]: 0 : if (unlikely((loff_t) (pos + len) < 0))
1817 : : return -EINVAL;
1818 : :
1819 [ # # # # ]: 0 : if (unlikely(inode->i_flctx && mandatory_lock(inode))) {
1820 [ # # ]: 0 : loff_t end = len ? pos + len - 1 : OFFSET_MAX;
1821 : 0 : int retval;
1822 : :
1823 : 0 : retval = locks_mandatory_area(inode, file, pos, end,
1824 : : write ? F_WRLCK : F_RDLCK);
1825 [ # # ]: 0 : if (retval < 0)
1826 : : return retval;
1827 : : }
1828 : :
1829 [ # # ]: 0 : return security_file_permission(file, write ? MAY_WRITE : MAY_READ);
1830 : : }
1831 : : /*
1832 : : * Ensure that we don't remap a partial EOF block in the middle of something
1833 : : * else. Assume that the offsets have already been checked for block
1834 : : * alignment.
1835 : : *
1836 : : * For clone we only link a partial EOF block above or at the destination file's
1837 : : * EOF. For deduplication we accept a partial EOF block only if it ends at the
1838 : : * destination file's EOF (can not link it into the middle of a file).
1839 : : *
1840 : : * Shorten the request if possible.
1841 : : */
1842 : 0 : static int generic_remap_check_len(struct inode *inode_in,
1843 : : struct inode *inode_out,
1844 : : loff_t pos_out,
1845 : : loff_t *len,
1846 : : unsigned int remap_flags)
1847 : : {
1848 : 0 : u64 blkmask = i_blocksize(inode_in) - 1;
1849 : 0 : loff_t new_len = *len;
1850 : :
1851 [ # # ]: 0 : if ((*len & blkmask) == 0)
1852 : : return 0;
1853 : :
1854 [ # # ]: 0 : if (pos_out + *len < i_size_read(inode_out))
1855 : 0 : new_len &= ~blkmask;
1856 : :
1857 [ # # ]: 0 : if (new_len == *len)
1858 : : return 0;
1859 : :
1860 [ # # ]: 0 : if (remap_flags & REMAP_FILE_CAN_SHORTEN) {
1861 : 0 : *len = new_len;
1862 : 0 : return 0;
1863 : : }
1864 : :
1865 [ # # ]: 0 : return (remap_flags & REMAP_FILE_DEDUP) ? -EBADE : -EINVAL;
1866 : : }
1867 : :
1868 : : /* Read a page's worth of file data into the page cache. */
1869 : : static struct page *vfs_dedupe_get_page(struct inode *inode, loff_t offset)
1870 : : {
1871 : : struct page *page;
1872 : :
1873 : : page = read_mapping_page(inode->i_mapping, offset >> PAGE_SHIFT, NULL);
1874 : : if (IS_ERR(page))
1875 : : return page;
1876 : : if (!PageUptodate(page)) {
1877 : : put_page(page);
1878 : : return ERR_PTR(-EIO);
1879 : : }
1880 : : return page;
1881 : : }
1882 : :
1883 : : /*
1884 : : * Lock two pages, ensuring that we lock in offset order if the pages are from
1885 : : * the same file.
1886 : : */
1887 : 0 : static void vfs_lock_two_pages(struct page *page1, struct page *page2)
1888 : : {
1889 : : /* Always lock in order of increasing index. */
1890 [ # # ]: 0 : if (page1->index > page2->index)
1891 : 0 : swap(page1, page2);
1892 : :
1893 : 0 : lock_page(page1);
1894 [ # # ]: 0 : if (page1 != page2)
1895 : 0 : lock_page(page2);
1896 : 0 : }
1897 : :
1898 : : /* Unlock two pages, being careful not to unlock the same page twice. */
1899 : 0 : static void vfs_unlock_two_pages(struct page *page1, struct page *page2)
1900 : : {
1901 : 0 : unlock_page(page1);
1902 [ # # ]: 0 : if (page1 != page2)
1903 : 0 : unlock_page(page2);
1904 : : }
1905 : :
1906 : : /*
1907 : : * Compare extents of two files to see if they are the same.
1908 : : * Caller must have locked both inodes to prevent write races.
1909 : : */
1910 : 0 : static int vfs_dedupe_file_range_compare(struct inode *src, loff_t srcoff,
1911 : : struct inode *dest, loff_t destoff,
1912 : : loff_t len, bool *is_same)
1913 : : {
1914 : 0 : loff_t src_poff;
1915 : 0 : loff_t dest_poff;
1916 : 0 : void *src_addr;
1917 : 0 : void *dest_addr;
1918 : 0 : struct page *src_page;
1919 : 0 : struct page *dest_page;
1920 : 0 : loff_t cmp_len;
1921 : 0 : bool same;
1922 : 0 : int error;
1923 : :
1924 : 0 : error = -EINVAL;
1925 : 0 : same = true;
1926 [ # # ]: 0 : while (len) {
1927 : 0 : src_poff = srcoff & (PAGE_SIZE - 1);
1928 : 0 : dest_poff = destoff & (PAGE_SIZE - 1);
1929 : 0 : cmp_len = min(PAGE_SIZE - src_poff,
1930 : : PAGE_SIZE - dest_poff);
1931 : 0 : cmp_len = min(cmp_len, len);
1932 [ # # ]: 0 : if (cmp_len <= 0)
1933 : 0 : goto out_error;
1934 : :
1935 : 0 : src_page = vfs_dedupe_get_page(src, srcoff);
1936 [ # # ]: 0 : if (IS_ERR(src_page)) {
1937 : 0 : error = PTR_ERR(src_page);
1938 : 0 : goto out_error;
1939 : : }
1940 : 0 : dest_page = vfs_dedupe_get_page(dest, destoff);
1941 [ # # ]: 0 : if (IS_ERR(dest_page)) {
1942 : 0 : error = PTR_ERR(dest_page);
1943 : 0 : put_page(src_page);
1944 : 0 : goto out_error;
1945 : : }
1946 : :
1947 : 0 : vfs_lock_two_pages(src_page, dest_page);
1948 : :
1949 : : /*
1950 : : * Now that we've locked both pages, make sure they're still
1951 : : * mapped to the file data we're interested in. If not,
1952 : : * someone is invalidating pages on us and we lose.
1953 : : */
1954 [ # # # # ]: 0 : if (!PageUptodate(src_page) || !PageUptodate(dest_page) ||
1955 [ # # ]: 0 : src_page->mapping != src->i_mapping ||
1956 [ # # ]: 0 : dest_page->mapping != dest->i_mapping) {
1957 : 0 : same = false;
1958 : 0 : goto unlock;
1959 : : }
1960 : :
1961 : 0 : src_addr = kmap_atomic(src_page);
1962 : 0 : dest_addr = kmap_atomic(dest_page);
1963 : :
1964 [ # # ]: 0 : flush_dcache_page(src_page);
1965 : 0 : flush_dcache_page(dest_page);
1966 : :
1967 [ # # ]: 0 : if (memcmp(src_addr + src_poff, dest_addr + dest_poff, cmp_len))
1968 : 0 : same = false;
1969 : :
1970 : 0 : kunmap_atomic(dest_addr);
1971 : 0 : kunmap_atomic(src_addr);
1972 : 0 : unlock:
1973 : 0 : vfs_unlock_two_pages(src_page, dest_page);
1974 : 0 : put_page(dest_page);
1975 : 0 : put_page(src_page);
1976 : :
1977 [ # # ]: 0 : if (!same)
1978 : : break;
1979 : :
1980 : 0 : srcoff += cmp_len;
1981 : 0 : destoff += cmp_len;
1982 : 0 : len -= cmp_len;
1983 : : }
1984 : :
1985 : 0 : *is_same = same;
1986 : 0 : return 0;
1987 : :
1988 : : out_error:
1989 : : return error;
1990 : : }
1991 : :
1992 : : /*
1993 : : * Check that the two inodes are eligible for cloning, the ranges make
1994 : : * sense, and then flush all dirty data. Caller must ensure that the
1995 : : * inodes have been locked against any other modifications.
1996 : : *
1997 : : * If there's an error, then the usual negative error code is returned.
1998 : : * Otherwise returns 0 with *len set to the request length.
1999 : : */
2000 : 0 : int generic_remap_file_range_prep(struct file *file_in, loff_t pos_in,
2001 : : struct file *file_out, loff_t pos_out,
2002 : : loff_t *len, unsigned int remap_flags)
2003 : : {
2004 [ # # ]: 0 : struct inode *inode_in = file_inode(file_in);
2005 : 0 : struct inode *inode_out = file_inode(file_out);
2006 : 0 : bool same_inode = (inode_in == inode_out);
2007 : 0 : int ret;
2008 : :
2009 : : /* Don't touch certain kinds of inodes */
2010 [ # # ]: 0 : if (IS_IMMUTABLE(inode_out))
2011 : : return -EPERM;
2012 : :
2013 [ # # # # ]: 0 : if (IS_SWAPFILE(inode_in) || IS_SWAPFILE(inode_out))
2014 : : return -ETXTBSY;
2015 : :
2016 : : /* Don't reflink dirs, pipes, sockets... */
2017 [ # # # # ]: 0 : if (S_ISDIR(inode_in->i_mode) || S_ISDIR(inode_out->i_mode))
2018 : : return -EISDIR;
2019 [ # # # # ]: 0 : if (!S_ISREG(inode_in->i_mode) || !S_ISREG(inode_out->i_mode))
2020 : : return -EINVAL;
2021 : :
2022 : : /* Zero length dedupe exits immediately; reflink goes to EOF. */
2023 [ # # ]: 0 : if (*len == 0) {
2024 [ # # ]: 0 : loff_t isize = i_size_read(inode_in);
2025 : :
2026 [ # # # # ]: 0 : if ((remap_flags & REMAP_FILE_DEDUP) || pos_in == isize)
2027 : : return 0;
2028 [ # # ]: 0 : if (pos_in > isize)
2029 : : return -EINVAL;
2030 : 0 : *len = isize - pos_in;
2031 : 0 : if (*len == 0)
2032 : : return 0;
2033 : : }
2034 : :
2035 : : /* Check that we don't violate system file offset limits. */
2036 : 0 : ret = generic_remap_checks(file_in, pos_in, file_out, pos_out, len,
2037 : : remap_flags);
2038 [ # # ]: 0 : if (ret)
2039 : : return ret;
2040 : :
2041 : : /* Wait for the completion of any pending IOs on both files */
2042 : 0 : inode_dio_wait(inode_in);
2043 [ # # ]: 0 : if (!same_inode)
2044 : 0 : inode_dio_wait(inode_out);
2045 : :
2046 : 0 : ret = filemap_write_and_wait_range(inode_in->i_mapping,
2047 : 0 : pos_in, pos_in + *len - 1);
2048 [ # # ]: 0 : if (ret)
2049 : : return ret;
2050 : :
2051 : 0 : ret = filemap_write_and_wait_range(inode_out->i_mapping,
2052 : 0 : pos_out, pos_out + *len - 1);
2053 [ # # ]: 0 : if (ret)
2054 : : return ret;
2055 : :
2056 : : /*
2057 : : * Check that the extents are the same.
2058 : : */
2059 [ # # ]: 0 : if (remap_flags & REMAP_FILE_DEDUP) {
2060 : 0 : bool is_same = false;
2061 : :
2062 : 0 : ret = vfs_dedupe_file_range_compare(inode_in, pos_in,
2063 : : inode_out, pos_out, *len, &is_same);
2064 [ # # ]: 0 : if (ret)
2065 : 0 : return ret;
2066 [ # # ]: 0 : if (!is_same)
2067 : : return -EBADE;
2068 : : }
2069 : :
2070 [ # # ]: 0 : ret = generic_remap_check_len(inode_in, inode_out, pos_out, len,
2071 : : remap_flags);
2072 : 0 : if (ret)
2073 : 0 : return ret;
2074 : :
2075 : : /* If can't alter the file contents, we're done. */
2076 [ # # ]: 0 : if (!(remap_flags & REMAP_FILE_DEDUP))
2077 : 0 : ret = file_modified(file_out);
2078 : :
2079 : : return ret;
2080 : : }
2081 : : EXPORT_SYMBOL(generic_remap_file_range_prep);
2082 : :
2083 : 120 : loff_t do_clone_file_range(struct file *file_in, loff_t pos_in,
2084 : : struct file *file_out, loff_t pos_out,
2085 : : loff_t len, unsigned int remap_flags)
2086 : : {
2087 : 120 : loff_t ret;
2088 : :
2089 [ - + ]: 120 : WARN_ON_ONCE(remap_flags & REMAP_FILE_DEDUP);
2090 : :
2091 : : /*
2092 : : * FICLONE/FICLONERANGE ioctls enforce that src and dest files are on
2093 : : * the same mount. Practically, they only need to be on the same file
2094 : : * system.
2095 : : */
2096 [ + - ]: 120 : if (file_inode(file_in)->i_sb != file_inode(file_out)->i_sb)
2097 : : return -EXDEV;
2098 : :
2099 : 120 : ret = generic_file_rw_checks(file_in, file_out);
2100 [ + - ]: 120 : if (ret < 0)
2101 : : return ret;
2102 : :
2103 [ - + ]: 120 : if (!file_in->f_op->remap_file_range)
2104 : : return -EOPNOTSUPP;
2105 : :
2106 : 0 : ret = remap_verify_area(file_in, pos_in, len, false);
2107 [ # # ]: 0 : if (ret)
2108 : : return ret;
2109 : :
2110 : 0 : ret = remap_verify_area(file_out, pos_out, len, true);
2111 [ # # ]: 0 : if (ret)
2112 : : return ret;
2113 : :
2114 : 0 : ret = file_in->f_op->remap_file_range(file_in, pos_in,
2115 : : file_out, pos_out, len, remap_flags);
2116 [ # # ]: 0 : if (ret < 0)
2117 : : return ret;
2118 : :
2119 : 0 : fsnotify_access(file_in);
2120 : 0 : fsnotify_modify(file_out);
2121 : 0 : return ret;
2122 : : }
2123 : : EXPORT_SYMBOL(do_clone_file_range);
2124 : :
2125 : 120 : loff_t vfs_clone_file_range(struct file *file_in, loff_t pos_in,
2126 : : struct file *file_out, loff_t pos_out,
2127 : : loff_t len, unsigned int remap_flags)
2128 : : {
2129 : 120 : loff_t ret;
2130 : :
2131 : 120 : file_start_write(file_out);
2132 : 120 : ret = do_clone_file_range(file_in, pos_in, file_out, pos_out, len,
2133 : : remap_flags);
2134 [ + - ]: 120 : file_end_write(file_out);
2135 : :
2136 : 120 : return ret;
2137 : : }
2138 : : EXPORT_SYMBOL(vfs_clone_file_range);
2139 : :
2140 : : /* Check whether we are allowed to dedupe the destination file */
2141 : 0 : static bool allow_file_dedupe(struct file *file)
2142 : : {
2143 [ # # ]: 0 : if (capable(CAP_SYS_ADMIN))
2144 : : return true;
2145 [ # # ]: 0 : if (file->f_mode & FMODE_WRITE)
2146 : : return true;
2147 [ # # ]: 0 : if (uid_eq(current_fsuid(), file_inode(file)->i_uid))
2148 : : return true;
2149 [ # # ]: 0 : if (!inode_permission(file_inode(file), MAY_WRITE))
2150 : 0 : return true;
2151 : : return false;
2152 : : }
2153 : :
2154 : 0 : loff_t vfs_dedupe_file_range_one(struct file *src_file, loff_t src_pos,
2155 : : struct file *dst_file, loff_t dst_pos,
2156 : : loff_t len, unsigned int remap_flags)
2157 : : {
2158 : 0 : loff_t ret;
2159 : :
2160 [ # # ]: 0 : WARN_ON_ONCE(remap_flags & ~(REMAP_FILE_DEDUP |
2161 : : REMAP_FILE_CAN_SHORTEN));
2162 : :
2163 : 0 : ret = mnt_want_write_file(dst_file);
2164 [ # # ]: 0 : if (ret)
2165 : : return ret;
2166 : :
2167 : 0 : ret = remap_verify_area(dst_file, dst_pos, len, true);
2168 [ # # ]: 0 : if (ret < 0)
2169 : 0 : goto out_drop_write;
2170 : :
2171 : 0 : ret = -EPERM;
2172 [ # # ]: 0 : if (!allow_file_dedupe(dst_file))
2173 : 0 : goto out_drop_write;
2174 : :
2175 : 0 : ret = -EXDEV;
2176 [ # # ]: 0 : if (src_file->f_path.mnt != dst_file->f_path.mnt)
2177 : 0 : goto out_drop_write;
2178 : :
2179 : 0 : ret = -EISDIR;
2180 [ # # ]: 0 : if (S_ISDIR(file_inode(dst_file)->i_mode))
2181 : 0 : goto out_drop_write;
2182 : :
2183 : 0 : ret = -EINVAL;
2184 [ # # ]: 0 : if (!dst_file->f_op->remap_file_range)
2185 : 0 : goto out_drop_write;
2186 : :
2187 [ # # ]: 0 : if (len == 0) {
2188 : 0 : ret = 0;
2189 : 0 : goto out_drop_write;
2190 : : }
2191 : :
2192 : 0 : ret = dst_file->f_op->remap_file_range(src_file, src_pos, dst_file,
2193 : : dst_pos, len, remap_flags | REMAP_FILE_DEDUP);
2194 : 0 : out_drop_write:
2195 : 0 : mnt_drop_write_file(dst_file);
2196 : :
2197 : 0 : return ret;
2198 : : }
2199 : : EXPORT_SYMBOL(vfs_dedupe_file_range_one);
2200 : :
2201 : 0 : int vfs_dedupe_file_range(struct file *file, struct file_dedupe_range *same)
2202 : : {
2203 : 0 : struct file_dedupe_range_info *info;
2204 [ # # ]: 0 : struct inode *src = file_inode(file);
2205 : 0 : u64 off;
2206 : 0 : u64 len;
2207 : 0 : int i;
2208 : 0 : int ret;
2209 : 0 : u16 count = same->dest_count;
2210 : 0 : loff_t deduped;
2211 : :
2212 [ # # ]: 0 : if (!(file->f_mode & FMODE_READ))
2213 : : return -EINVAL;
2214 : :
2215 [ # # ]: 0 : if (same->reserved1 || same->reserved2)
2216 : : return -EINVAL;
2217 : :
2218 : 0 : off = same->src_offset;
2219 : 0 : len = same->src_length;
2220 : :
2221 [ # # ]: 0 : if (S_ISDIR(src->i_mode))
2222 : : return -EISDIR;
2223 : :
2224 [ # # ]: 0 : if (!S_ISREG(src->i_mode))
2225 : : return -EINVAL;
2226 : :
2227 [ # # ]: 0 : if (!file->f_op->remap_file_range)
2228 : : return -EOPNOTSUPP;
2229 : :
2230 : 0 : ret = remap_verify_area(file, off, len, false);
2231 [ # # ]: 0 : if (ret < 0)
2232 : : return ret;
2233 : 0 : ret = 0;
2234 : :
2235 [ # # ]: 0 : if (off + len > i_size_read(src))
2236 : : return -EINVAL;
2237 : :
2238 : : /* Arbitrary 1G limit on a single dedupe request, can be raised. */
2239 : 0 : len = min_t(u64, len, 1 << 30);
2240 : :
2241 : : /* pre-format output fields to sane values */
2242 [ # # ]: 0 : for (i = 0; i < count; i++) {
2243 : 0 : same->info[i].bytes_deduped = 0ULL;
2244 : 0 : same->info[i].status = FILE_DEDUPE_RANGE_SAME;
2245 : : }
2246 : :
2247 [ # # ]: 0 : for (i = 0, info = same->info; i < count; i++, info++) {
2248 : 0 : struct fd dst_fd = fdget(info->dest_fd);
2249 : 0 : struct file *dst_file = dst_fd.file;
2250 : :
2251 [ # # ]: 0 : if (!dst_file) {
2252 : 0 : info->status = -EBADF;
2253 : 0 : goto next_loop;
2254 : : }
2255 : :
2256 [ # # ]: 0 : if (info->reserved) {
2257 : 0 : info->status = -EINVAL;
2258 : 0 : goto next_fdput;
2259 : : }
2260 : :
2261 : 0 : deduped = vfs_dedupe_file_range_one(file, off, dst_file,
2262 : 0 : info->dest_offset, len,
2263 : : REMAP_FILE_CAN_SHORTEN);
2264 [ # # ]: 0 : if (deduped == -EBADE)
2265 : 0 : info->status = FILE_DEDUPE_RANGE_DIFFERS;
2266 [ # # ]: 0 : else if (deduped < 0)
2267 : 0 : info->status = deduped;
2268 : : else
2269 : 0 : info->bytes_deduped = len;
2270 : :
2271 : 0 : next_fdput:
2272 [ # # ]: 0 : fdput(dst_fd);
2273 : 0 : next_loop:
2274 [ # # ]: 0 : if (fatal_signal_pending(current))
2275 : : break;
2276 : : }
2277 : : return ret;
2278 : : }
2279 : : EXPORT_SYMBOL(vfs_dedupe_file_range);
|