Line data Source code
1 : // SPDX-License-Identifier: GPL-2.0-only
2 : /*
3 : * Copyright (C) 2017 Red Hat, Inc.
4 : */
5 :
6 : #include <linux/cred.h>
7 : #include <linux/file.h>
8 : #include <linux/mount.h>
9 : #include <linux/xattr.h>
10 : #include <linux/uio.h>
11 : #include <linux/uaccess.h>
12 : #include <linux/splice.h>
13 : #include <linux/security.h>
14 : #include <linux/mm.h>
15 : #include <linux/fs.h>
16 : #include "overlayfs.h"
17 :
18 : struct ovl_aio_req {
19 : struct kiocb iocb;
20 : struct kiocb *orig_iocb;
21 : struct fd fd;
22 : };
23 :
24 : static struct kmem_cache *ovl_aio_request_cachep;
25 :
26 : static char ovl_whatisit(struct inode *inode, struct inode *realinode)
27 : {
28 : if (realinode != ovl_inode_upper(inode))
29 : return 'l';
30 : if (ovl_has_upperdata(inode))
31 : return 'u';
32 : else
33 : return 'm';
34 : }
35 :
36 : /* No atime modificaton nor notify on underlying */
37 : #define OVL_OPEN_FLAGS (O_NOATIME | FMODE_NONOTIFY)
38 :
39 39 : static struct file *ovl_open_realfile(const struct file *file,
40 : struct inode *realinode)
41 : {
42 39 : struct inode *inode = file_inode(file);
43 39 : struct file *realfile;
44 39 : const struct cred *old_cred;
45 39 : int flags = file->f_flags | OVL_OPEN_FLAGS;
46 39 : int acc_mode = ACC_MODE(flags);
47 39 : int err;
48 :
49 39 : if (flags & O_APPEND)
50 0 : acc_mode |= MAY_APPEND;
51 :
52 39 : old_cred = ovl_override_creds(inode->i_sb);
53 39 : err = inode_permission(&init_user_ns, realinode, MAY_OPEN | acc_mode);
54 39 : if (err) {
55 0 : realfile = ERR_PTR(err);
56 : } else {
57 39 : if (!inode_owner_or_capable(&init_user_ns, realinode))
58 0 : flags &= ~O_NOATIME;
59 :
60 39 : realfile = open_with_fake_path(&file->f_path, flags, realinode,
61 39 : current_cred());
62 : }
63 39 : revert_creds(old_cred);
64 :
65 39 : pr_debug("open(%p[%pD2/%c], 0%o) -> (%p, 0%o)\n",
66 : file, file, ovl_whatisit(inode, realinode), file->f_flags,
67 : realfile, IS_ERR(realfile) ? 0 : realfile->f_flags);
68 :
69 39 : return realfile;
70 : }
71 :
72 : #define OVL_SETFL_MASK (O_APPEND | O_NONBLOCK | O_NDELAY | O_DIRECT)
73 :
74 0 : static int ovl_change_flags(struct file *file, unsigned int flags)
75 : {
76 0 : struct inode *inode = file_inode(file);
77 0 : int err;
78 :
79 0 : flags &= OVL_SETFL_MASK;
80 :
81 0 : if (((flags ^ file->f_flags) & O_APPEND) && IS_APPEND(inode))
82 : return -EPERM;
83 :
84 0 : if (flags & O_DIRECT) {
85 0 : if (!file->f_mapping->a_ops ||
86 0 : !file->f_mapping->a_ops->direct_IO)
87 : return -EINVAL;
88 : }
89 :
90 0 : if (file->f_op->check_flags) {
91 0 : err = file->f_op->check_flags(flags);
92 0 : if (err)
93 : return err;
94 : }
95 :
96 0 : spin_lock(&file->f_lock);
97 0 : file->f_flags = (file->f_flags & ~OVL_SETFL_MASK) | flags;
98 0 : spin_unlock(&file->f_lock);
99 :
100 0 : return 0;
101 : }
102 :
103 0 : static int ovl_real_fdget_meta(const struct file *file, struct fd *real,
104 : bool allow_meta)
105 : {
106 0 : struct inode *inode = file_inode(file);
107 0 : struct inode *realinode;
108 :
109 0 : real->flags = 0;
110 0 : real->file = file->private_data;
111 :
112 0 : if (allow_meta)
113 0 : realinode = ovl_inode_real(inode);
114 : else
115 0 : realinode = ovl_inode_realdata(inode);
116 :
117 : /* Has it been copied up since we'd opened it? */
118 0 : if (unlikely(file_inode(real->file) != realinode)) {
119 0 : real->flags = FDPUT_FPUT;
120 0 : real->file = ovl_open_realfile(file, realinode);
121 :
122 0 : return PTR_ERR_OR_ZERO(real->file);
123 : }
124 :
125 : /* Did the flags change since open? */
126 0 : if (unlikely((file->f_flags ^ real->file->f_flags) & ~OVL_OPEN_FLAGS))
127 0 : return ovl_change_flags(real->file, file->f_flags);
128 :
129 : return 0;
130 : }
131 :
132 0 : static int ovl_real_fdget(const struct file *file, struct fd *real)
133 : {
134 0 : if (d_is_dir(file_dentry(file))) {
135 0 : real->flags = 0;
136 0 : real->file = ovl_dir_real_file(file, false);
137 :
138 0 : return PTR_ERR_OR_ZERO(real->file);
139 : }
140 :
141 0 : return ovl_real_fdget_meta(file, real, false);
142 : }
143 :
144 39 : static int ovl_open(struct inode *inode, struct file *file)
145 : {
146 39 : struct file *realfile;
147 39 : int err;
148 :
149 39 : err = ovl_maybe_copy_up(file_dentry(file), file->f_flags);
150 39 : if (err)
151 : return err;
152 :
153 : /* No longer need these flags, so don't pass them on to underlying fs */
154 39 : file->f_flags &= ~(O_CREAT | O_EXCL | O_NOCTTY | O_TRUNC);
155 :
156 39 : realfile = ovl_open_realfile(file, ovl_inode_realdata(inode));
157 39 : if (IS_ERR(realfile))
158 0 : return PTR_ERR(realfile);
159 :
160 39 : file->private_data = realfile;
161 :
162 39 : return 0;
163 : }
164 :
165 39 : static int ovl_release(struct inode *inode, struct file *file)
166 : {
167 39 : fput(file->private_data);
168 :
169 39 : return 0;
170 : }
171 :
172 0 : static loff_t ovl_llseek(struct file *file, loff_t offset, int whence)
173 : {
174 0 : struct inode *inode = file_inode(file);
175 0 : struct fd real;
176 0 : const struct cred *old_cred;
177 0 : loff_t ret;
178 :
179 : /*
180 : * The two special cases below do not need to involve real fs,
181 : * so we can optimizing concurrent callers.
182 : */
183 0 : if (offset == 0) {
184 0 : if (whence == SEEK_CUR)
185 0 : return file->f_pos;
186 :
187 0 : if (whence == SEEK_SET)
188 0 : return vfs_setpos(file, 0, 0);
189 : }
190 :
191 0 : ret = ovl_real_fdget(file, &real);
192 0 : if (ret)
193 : return ret;
194 :
195 : /*
196 : * Overlay file f_pos is the master copy that is preserved
197 : * through copy up and modified on read/write, but only real
198 : * fs knows how to SEEK_HOLE/SEEK_DATA and real fs may impose
199 : * limitations that are more strict than ->s_maxbytes for specific
200 : * files, so we use the real file to perform seeks.
201 : */
202 0 : ovl_inode_lock(inode);
203 0 : real.file->f_pos = file->f_pos;
204 :
205 0 : old_cred = ovl_override_creds(inode->i_sb);
206 0 : ret = vfs_llseek(real.file, offset, whence);
207 0 : revert_creds(old_cred);
208 :
209 0 : file->f_pos = real.file->f_pos;
210 0 : ovl_inode_unlock(inode);
211 :
212 0 : fdput(real);
213 :
214 0 : return ret;
215 : }
216 :
217 0 : static void ovl_file_accessed(struct file *file)
218 : {
219 0 : struct inode *inode, *upperinode;
220 :
221 0 : if (file->f_flags & O_NOATIME)
222 : return;
223 :
224 0 : inode = file_inode(file);
225 0 : upperinode = ovl_inode_upper(inode);
226 :
227 0 : if (!upperinode)
228 : return;
229 :
230 0 : if ((!timespec64_equal(&inode->i_mtime, &upperinode->i_mtime) ||
231 0 : !timespec64_equal(&inode->i_ctime, &upperinode->i_ctime))) {
232 0 : inode->i_mtime = upperinode->i_mtime;
233 0 : inode->i_ctime = upperinode->i_ctime;
234 : }
235 :
236 0 : touch_atime(&file->f_path);
237 : }
238 :
239 0 : static rwf_t ovl_iocb_to_rwf(int ifl)
240 : {
241 0 : rwf_t flags = 0;
242 :
243 0 : if (ifl & IOCB_NOWAIT)
244 0 : flags |= RWF_NOWAIT;
245 0 : if (ifl & IOCB_HIPRI)
246 0 : flags |= RWF_HIPRI;
247 0 : if (ifl & IOCB_DSYNC)
248 0 : flags |= RWF_DSYNC;
249 0 : if (ifl & IOCB_SYNC)
250 0 : flags |= RWF_SYNC;
251 :
252 0 : return flags;
253 : }
254 :
255 0 : static void ovl_aio_cleanup_handler(struct ovl_aio_req *aio_req)
256 : {
257 0 : struct kiocb *iocb = &aio_req->iocb;
258 0 : struct kiocb *orig_iocb = aio_req->orig_iocb;
259 :
260 0 : if (iocb->ki_flags & IOCB_WRITE) {
261 0 : struct inode *inode = file_inode(orig_iocb->ki_filp);
262 :
263 : /* Actually acquired in ovl_write_iter() */
264 0 : __sb_writers_acquired(file_inode(iocb->ki_filp)->i_sb,
265 : SB_FREEZE_WRITE);
266 0 : file_end_write(iocb->ki_filp);
267 0 : ovl_copyattr(ovl_inode_real(inode), inode);
268 : }
269 :
270 0 : orig_iocb->ki_pos = iocb->ki_pos;
271 0 : fdput(aio_req->fd);
272 0 : kmem_cache_free(ovl_aio_request_cachep, aio_req);
273 0 : }
274 :
275 0 : static void ovl_aio_rw_complete(struct kiocb *iocb, long res, long res2)
276 : {
277 0 : struct ovl_aio_req *aio_req = container_of(iocb,
278 : struct ovl_aio_req, iocb);
279 0 : struct kiocb *orig_iocb = aio_req->orig_iocb;
280 :
281 0 : ovl_aio_cleanup_handler(aio_req);
282 0 : orig_iocb->ki_complete(orig_iocb, res, res2);
283 0 : }
284 :
285 0 : static ssize_t ovl_read_iter(struct kiocb *iocb, struct iov_iter *iter)
286 : {
287 0 : struct file *file = iocb->ki_filp;
288 0 : struct fd real;
289 0 : const struct cred *old_cred;
290 0 : ssize_t ret;
291 :
292 0 : if (!iov_iter_count(iter))
293 : return 0;
294 :
295 0 : ret = ovl_real_fdget(file, &real);
296 0 : if (ret)
297 : return ret;
298 :
299 0 : old_cred = ovl_override_creds(file_inode(file)->i_sb);
300 0 : if (is_sync_kiocb(iocb)) {
301 0 : ret = vfs_iter_read(real.file, iter, &iocb->ki_pos,
302 : ovl_iocb_to_rwf(iocb->ki_flags));
303 : } else {
304 0 : struct ovl_aio_req *aio_req;
305 :
306 0 : ret = -ENOMEM;
307 0 : aio_req = kmem_cache_zalloc(ovl_aio_request_cachep, GFP_KERNEL);
308 0 : if (!aio_req)
309 0 : goto out;
310 :
311 0 : aio_req->fd = real;
312 0 : real.flags = 0;
313 0 : aio_req->orig_iocb = iocb;
314 0 : kiocb_clone(&aio_req->iocb, iocb, real.file);
315 0 : aio_req->iocb.ki_complete = ovl_aio_rw_complete;
316 0 : ret = vfs_iocb_iter_read(real.file, &aio_req->iocb, iter);
317 0 : if (ret != -EIOCBQUEUED)
318 0 : ovl_aio_cleanup_handler(aio_req);
319 : }
320 0 : out:
321 0 : revert_creds(old_cred);
322 0 : ovl_file_accessed(file);
323 :
324 0 : fdput(real);
325 :
326 0 : return ret;
327 : }
328 :
329 0 : static ssize_t ovl_write_iter(struct kiocb *iocb, struct iov_iter *iter)
330 : {
331 0 : struct file *file = iocb->ki_filp;
332 0 : struct inode *inode = file_inode(file);
333 0 : struct fd real;
334 0 : const struct cred *old_cred;
335 0 : ssize_t ret;
336 0 : int ifl = iocb->ki_flags;
337 :
338 0 : if (!iov_iter_count(iter))
339 : return 0;
340 :
341 0 : inode_lock(inode);
342 : /* Update mode */
343 0 : ovl_copyattr(ovl_inode_real(inode), inode);
344 0 : ret = file_remove_privs(file);
345 0 : if (ret)
346 0 : goto out_unlock;
347 :
348 0 : ret = ovl_real_fdget(file, &real);
349 0 : if (ret)
350 0 : goto out_unlock;
351 :
352 0 : if (!ovl_should_sync(OVL_FS(inode->i_sb)))
353 0 : ifl &= ~(IOCB_DSYNC | IOCB_SYNC);
354 :
355 0 : old_cred = ovl_override_creds(file_inode(file)->i_sb);
356 0 : if (is_sync_kiocb(iocb)) {
357 0 : file_start_write(real.file);
358 0 : ret = vfs_iter_write(real.file, iter, &iocb->ki_pos,
359 : ovl_iocb_to_rwf(ifl));
360 0 : file_end_write(real.file);
361 : /* Update size */
362 0 : ovl_copyattr(ovl_inode_real(inode), inode);
363 : } else {
364 0 : struct ovl_aio_req *aio_req;
365 :
366 0 : ret = -ENOMEM;
367 0 : aio_req = kmem_cache_zalloc(ovl_aio_request_cachep, GFP_KERNEL);
368 0 : if (!aio_req)
369 0 : goto out;
370 :
371 0 : file_start_write(real.file);
372 : /* Pacify lockdep, same trick as done in aio_write() */
373 0 : __sb_writers_release(file_inode(real.file)->i_sb,
374 : SB_FREEZE_WRITE);
375 0 : aio_req->fd = real;
376 0 : real.flags = 0;
377 0 : aio_req->orig_iocb = iocb;
378 0 : kiocb_clone(&aio_req->iocb, iocb, real.file);
379 0 : aio_req->iocb.ki_flags = ifl;
380 0 : aio_req->iocb.ki_complete = ovl_aio_rw_complete;
381 0 : ret = vfs_iocb_iter_write(real.file, &aio_req->iocb, iter);
382 0 : if (ret != -EIOCBQUEUED)
383 0 : ovl_aio_cleanup_handler(aio_req);
384 : }
385 0 : out:
386 0 : revert_creds(old_cred);
387 0 : fdput(real);
388 :
389 0 : out_unlock:
390 0 : inode_unlock(inode);
391 :
392 0 : return ret;
393 : }
394 :
395 0 : static int ovl_fsync(struct file *file, loff_t start, loff_t end, int datasync)
396 : {
397 0 : struct fd real;
398 0 : const struct cred *old_cred;
399 0 : int ret;
400 :
401 0 : ret = ovl_sync_status(OVL_FS(file_inode(file)->i_sb));
402 0 : if (ret <= 0)
403 : return ret;
404 :
405 0 : ret = ovl_real_fdget_meta(file, &real, !datasync);
406 0 : if (ret)
407 : return ret;
408 :
409 : /* Don't sync lower file for fear of receiving EROFS error */
410 0 : if (file_inode(real.file) == ovl_inode_upper(file_inode(file))) {
411 0 : old_cred = ovl_override_creds(file_inode(file)->i_sb);
412 0 : ret = vfs_fsync_range(real.file, start, end, datasync);
413 0 : revert_creds(old_cred);
414 : }
415 :
416 0 : fdput(real);
417 :
418 0 : return ret;
419 : }
420 :
421 0 : static int ovl_mmap(struct file *file, struct vm_area_struct *vma)
422 : {
423 0 : struct file *realfile = file->private_data;
424 0 : const struct cred *old_cred;
425 0 : int ret;
426 :
427 0 : if (!realfile->f_op->mmap)
428 : return -ENODEV;
429 :
430 0 : if (WARN_ON(file != vma->vm_file))
431 : return -EIO;
432 :
433 0 : vma->vm_file = get_file(realfile);
434 :
435 0 : old_cred = ovl_override_creds(file_inode(file)->i_sb);
436 0 : ret = call_mmap(vma->vm_file, vma);
437 0 : revert_creds(old_cred);
438 :
439 0 : if (ret) {
440 : /* Drop reference count from new vm_file value */
441 0 : fput(realfile);
442 : } else {
443 : /* Drop reference count from previous vm_file value */
444 0 : fput(file);
445 : }
446 :
447 0 : ovl_file_accessed(file);
448 :
449 0 : return ret;
450 : }
451 :
452 0 : static long ovl_fallocate(struct file *file, int mode, loff_t offset, loff_t len)
453 : {
454 0 : struct inode *inode = file_inode(file);
455 0 : struct fd real;
456 0 : const struct cred *old_cred;
457 0 : int ret;
458 :
459 0 : ret = ovl_real_fdget(file, &real);
460 0 : if (ret)
461 0 : return ret;
462 :
463 0 : old_cred = ovl_override_creds(file_inode(file)->i_sb);
464 0 : ret = vfs_fallocate(real.file, mode, offset, len);
465 0 : revert_creds(old_cred);
466 :
467 : /* Update size */
468 0 : ovl_copyattr(ovl_inode_real(inode), inode);
469 :
470 0 : fdput(real);
471 :
472 0 : return ret;
473 : }
474 :
475 0 : static int ovl_fadvise(struct file *file, loff_t offset, loff_t len, int advice)
476 : {
477 0 : struct fd real;
478 0 : const struct cred *old_cred;
479 0 : int ret;
480 :
481 0 : ret = ovl_real_fdget(file, &real);
482 0 : if (ret)
483 : return ret;
484 :
485 0 : old_cred = ovl_override_creds(file_inode(file)->i_sb);
486 0 : ret = vfs_fadvise(real.file, offset, len, advice);
487 0 : revert_creds(old_cred);
488 :
489 0 : fdput(real);
490 :
491 0 : return ret;
492 : }
493 :
494 0 : static long ovl_real_ioctl(struct file *file, unsigned int cmd,
495 : unsigned long arg)
496 : {
497 0 : struct fd real;
498 0 : long ret;
499 :
500 0 : ret = ovl_real_fdget(file, &real);
501 0 : if (ret)
502 : return ret;
503 :
504 0 : ret = security_file_ioctl(real.file, cmd, arg);
505 0 : if (!ret) {
506 : /*
507 : * Don't override creds, since we currently can't safely check
508 : * permissions before doing so.
509 : */
510 0 : ret = vfs_ioctl(real.file, cmd, arg);
511 : }
512 :
513 0 : fdput(real);
514 :
515 0 : return ret;
516 : }
517 :
518 0 : static long ovl_ioctl_set_flags(struct file *file, unsigned int cmd,
519 : unsigned long arg)
520 : {
521 0 : long ret;
522 0 : struct inode *inode = file_inode(file);
523 :
524 0 : if (!inode_owner_or_capable(&init_user_ns, inode))
525 : return -EACCES;
526 :
527 0 : ret = mnt_want_write_file(file);
528 0 : if (ret)
529 : return ret;
530 :
531 0 : inode_lock(inode);
532 :
533 : /*
534 : * Prevent copy up if immutable and has no CAP_LINUX_IMMUTABLE
535 : * capability.
536 : */
537 0 : ret = -EPERM;
538 0 : if (!ovl_has_upperdata(inode) && IS_IMMUTABLE(inode) &&
539 0 : !capable(CAP_LINUX_IMMUTABLE))
540 0 : goto unlock;
541 :
542 0 : ret = ovl_maybe_copy_up(file_dentry(file), O_WRONLY);
543 0 : if (ret)
544 0 : goto unlock;
545 :
546 0 : ret = ovl_real_ioctl(file, cmd, arg);
547 :
548 0 : ovl_copyflags(ovl_inode_real(inode), inode);
549 0 : unlock:
550 0 : inode_unlock(inode);
551 :
552 0 : mnt_drop_write_file(file);
553 :
554 0 : return ret;
555 :
556 : }
557 :
558 0 : long ovl_ioctl(struct file *file, unsigned int cmd, unsigned long arg)
559 : {
560 0 : long ret;
561 :
562 0 : switch (cmd) {
563 0 : case FS_IOC_GETFLAGS:
564 : case FS_IOC_FSGETXATTR:
565 0 : ret = ovl_real_ioctl(file, cmd, arg);
566 0 : break;
567 :
568 0 : case FS_IOC_FSSETXATTR:
569 : case FS_IOC_SETFLAGS:
570 0 : ret = ovl_ioctl_set_flags(file, cmd, arg);
571 0 : break;
572 :
573 : default:
574 : ret = -ENOTTY;
575 : }
576 :
577 0 : return ret;
578 : }
579 :
580 : #ifdef CONFIG_COMPAT
581 0 : long ovl_compat_ioctl(struct file *file, unsigned int cmd, unsigned long arg)
582 : {
583 0 : switch (cmd) {
584 : case FS_IOC32_GETFLAGS:
585 : cmd = FS_IOC_GETFLAGS;
586 : break;
587 :
588 0 : case FS_IOC32_SETFLAGS:
589 0 : cmd = FS_IOC_SETFLAGS;
590 0 : break;
591 :
592 : default:
593 : return -ENOIOCTLCMD;
594 : }
595 :
596 0 : return ovl_ioctl(file, cmd, arg);
597 : }
598 : #endif
599 :
600 : enum ovl_copyop {
601 : OVL_COPY,
602 : OVL_CLONE,
603 : OVL_DEDUPE,
604 : };
605 :
606 0 : static loff_t ovl_copyfile(struct file *file_in, loff_t pos_in,
607 : struct file *file_out, loff_t pos_out,
608 : loff_t len, unsigned int flags, enum ovl_copyop op)
609 : {
610 0 : struct inode *inode_out = file_inode(file_out);
611 0 : struct fd real_in, real_out;
612 0 : const struct cred *old_cred;
613 0 : loff_t ret;
614 :
615 0 : ret = ovl_real_fdget(file_out, &real_out);
616 0 : if (ret)
617 : return ret;
618 :
619 0 : ret = ovl_real_fdget(file_in, &real_in);
620 0 : if (ret) {
621 0 : fdput(real_out);
622 0 : return ret;
623 : }
624 :
625 0 : old_cred = ovl_override_creds(file_inode(file_out)->i_sb);
626 0 : switch (op) {
627 0 : case OVL_COPY:
628 0 : ret = vfs_copy_file_range(real_in.file, pos_in,
629 : real_out.file, pos_out, len, flags);
630 0 : break;
631 :
632 0 : case OVL_CLONE:
633 0 : ret = vfs_clone_file_range(real_in.file, pos_in,
634 : real_out.file, pos_out, len, flags);
635 0 : break;
636 :
637 0 : case OVL_DEDUPE:
638 0 : ret = vfs_dedupe_file_range_one(real_in.file, pos_in,
639 : real_out.file, pos_out, len,
640 : flags);
641 0 : break;
642 : }
643 0 : revert_creds(old_cred);
644 :
645 : /* Update size */
646 0 : ovl_copyattr(ovl_inode_real(inode_out), inode_out);
647 :
648 0 : fdput(real_in);
649 0 : fdput(real_out);
650 :
651 0 : return ret;
652 : }
653 :
654 0 : static ssize_t ovl_copy_file_range(struct file *file_in, loff_t pos_in,
655 : struct file *file_out, loff_t pos_out,
656 : size_t len, unsigned int flags)
657 : {
658 0 : return ovl_copyfile(file_in, pos_in, file_out, pos_out, len, flags,
659 : OVL_COPY);
660 : }
661 :
662 0 : static loff_t ovl_remap_file_range(struct file *file_in, loff_t pos_in,
663 : struct file *file_out, loff_t pos_out,
664 : loff_t len, unsigned int remap_flags)
665 : {
666 0 : enum ovl_copyop op;
667 :
668 0 : if (remap_flags & ~(REMAP_FILE_DEDUP | REMAP_FILE_ADVISORY))
669 : return -EINVAL;
670 :
671 0 : if (remap_flags & REMAP_FILE_DEDUP)
672 : op = OVL_DEDUPE;
673 : else
674 : op = OVL_CLONE;
675 :
676 : /*
677 : * Don't copy up because of a dedupe request, this wouldn't make sense
678 : * most of the time (data would be duplicated instead of deduplicated).
679 : */
680 0 : if (op == OVL_DEDUPE &&
681 0 : (!ovl_inode_upper(file_inode(file_in)) ||
682 0 : !ovl_inode_upper(file_inode(file_out))))
683 0 : return -EPERM;
684 :
685 0 : return ovl_copyfile(file_in, pos_in, file_out, pos_out, len,
686 : remap_flags, op);
687 : }
688 :
689 : const struct file_operations ovl_file_operations = {
690 : .open = ovl_open,
691 : .release = ovl_release,
692 : .llseek = ovl_llseek,
693 : .read_iter = ovl_read_iter,
694 : .write_iter = ovl_write_iter,
695 : .fsync = ovl_fsync,
696 : .mmap = ovl_mmap,
697 : .fallocate = ovl_fallocate,
698 : .fadvise = ovl_fadvise,
699 : .unlocked_ioctl = ovl_ioctl,
700 : #ifdef CONFIG_COMPAT
701 : .compat_ioctl = ovl_compat_ioctl,
702 : #endif
703 : .splice_read = generic_file_splice_read,
704 : .splice_write = iter_file_splice_write,
705 :
706 : .copy_file_range = ovl_copy_file_range,
707 : .remap_file_range = ovl_remap_file_range,
708 : };
709 :
710 1 : int __init ovl_aio_request_cache_init(void)
711 : {
712 1 : ovl_aio_request_cachep = kmem_cache_create("ovl_aio_req",
713 : sizeof(struct ovl_aio_req),
714 : 0, SLAB_HWCACHE_ALIGN, NULL);
715 1 : if (!ovl_aio_request_cachep)
716 0 : return -ENOMEM;
717 :
718 : return 0;
719 : }
720 :
721 0 : void ovl_aio_request_cache_destroy(void)
722 : {
723 0 : kmem_cache_destroy(ovl_aio_request_cachep);
724 0 : }
|