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