Linux Audio

Check our new training course

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