xref: /openbmc/linux/fs/coda/file.c (revision c900529f3d9161bfde5cca0754f83b4d3c3e0220)
1b2441318SGreg Kroah-Hartman // SPDX-License-Identifier: GPL-2.0
21da177e4SLinus Torvalds /*
31da177e4SLinus Torvalds  * File operations for Coda.
41da177e4SLinus Torvalds  * Original version: (C) 1996 Peter Braam
51da177e4SLinus Torvalds  * Rewritten for Linux 2.1: (C) 1997 Carnegie Mellon University
61da177e4SLinus Torvalds  *
71da177e4SLinus Torvalds  * Carnegie Mellon encourages users of this code to contribute improvements
81da177e4SLinus Torvalds  * to the Coda project. Contact Peter Braam <coda@cs.cmu.edu>.
91da177e4SLinus Torvalds  */
101da177e4SLinus Torvalds 
111077c285SXiyu Yang #include <linux/refcount.h>
121da177e4SLinus Torvalds #include <linux/types.h>
131da177e4SLinus Torvalds #include <linux/kernel.h>
141da177e4SLinus Torvalds #include <linux/time.h>
151da177e4SLinus Torvalds #include <linux/file.h>
161da177e4SLinus Torvalds #include <linux/fs.h>
17cbcc268bSMatthew Wilcox (Oracle) #include <linux/pagemap.h>
181da177e4SLinus Torvalds #include <linux/stat.h>
197596b27dSRandy Dunlap #include <linux/cred.h>
201da177e4SLinus Torvalds #include <linux/errno.h>
21b5ce1d83SYoshihisa Abe #include <linux/spinlock.h>
221da177e4SLinus Torvalds #include <linux/string.h>
235a0e3ad6STejun Heo #include <linux/slab.h>
24834b46c3SFabian Frederick #include <linux/uaccess.h>
25a9fba24cSPedro Cuadra #include <linux/uio.h>
26a1be2935SDavid Howells #include <linux/splice.h>
271da177e4SLinus Torvalds 
281da177e4SLinus Torvalds #include <linux/coda.h>
298fc8b9dfSDavid Howells #include "coda_psdev.h"
3031a203dfSAl Viro #include "coda_linux.h"
31c98d8cfbSAdrian Bunk #include "coda_int.h"
32c98d8cfbSAdrian Bunk 
337fa0a1daSJan Harkes struct coda_vm_ops {
341077c285SXiyu Yang 	refcount_t refcnt;
357fa0a1daSJan Harkes 	struct file *coda_file;
367fa0a1daSJan Harkes 	const struct vm_operations_struct *host_vm_ops;
377fa0a1daSJan Harkes 	struct vm_operations_struct vm_ops;
387fa0a1daSJan Harkes };
397fa0a1daSJan Harkes 
401da177e4SLinus Torvalds static ssize_t
coda_file_read_iter(struct kiocb * iocb,struct iov_iter * to)41c12c49e7SAl Viro coda_file_read_iter(struct kiocb *iocb, struct iov_iter *to)
421da177e4SLinus Torvalds {
43c12c49e7SAl Viro 	struct file *coda_file = iocb->ki_filp;
44a9fba24cSPedro Cuadra 	struct inode *coda_inode = file_inode(coda_file);
455bb44810SFabian Frederick 	struct coda_file_info *cfi = coda_ftoc(coda_file);
46a9fba24cSPedro Cuadra 	loff_t ki_pos = iocb->ki_pos;
47a9fba24cSPedro Cuadra 	size_t count = iov_iter_count(to);
48a9fba24cSPedro Cuadra 	ssize_t ret;
491da177e4SLinus Torvalds 
50a9fba24cSPedro Cuadra 	ret = venus_access_intent(coda_inode->i_sb, coda_i2f(coda_inode),
51a9fba24cSPedro Cuadra 				  &cfi->cfi_access_intent,
52a9fba24cSPedro Cuadra 				  count, ki_pos, CODA_ACCESS_TYPE_READ);
53a9fba24cSPedro Cuadra 	if (ret)
54a9fba24cSPedro Cuadra 		goto finish_read;
55a9fba24cSPedro Cuadra 
56a9fba24cSPedro Cuadra 	ret = vfs_iter_read(cfi->cfi_container, to, &iocb->ki_pos, 0);
57a9fba24cSPedro Cuadra 
58a9fba24cSPedro Cuadra finish_read:
59a9fba24cSPedro Cuadra 	venus_access_intent(coda_inode->i_sb, coda_i2f(coda_inode),
60a9fba24cSPedro Cuadra 			    &cfi->cfi_access_intent,
61a9fba24cSPedro Cuadra 			    count, ki_pos, CODA_ACCESS_TYPE_READ_FINISH);
62a9fba24cSPedro Cuadra 	return ret;
631da177e4SLinus Torvalds }
641da177e4SLinus Torvalds 
651da177e4SLinus Torvalds static ssize_t
coda_file_write_iter(struct kiocb * iocb,struct iov_iter * to)66c12c49e7SAl Viro coda_file_write_iter(struct kiocb *iocb, struct iov_iter *to)
671da177e4SLinus Torvalds {
68c12c49e7SAl Viro 	struct file *coda_file = iocb->ki_filp;
69c12c49e7SAl Viro 	struct inode *coda_inode = file_inode(coda_file);
705bb44810SFabian Frederick 	struct coda_file_info *cfi = coda_ftoc(coda_file);
71a9fba24cSPedro Cuadra 	struct file *host_file = cfi->cfi_container;
72a9fba24cSPedro Cuadra 	loff_t ki_pos = iocb->ki_pos;
73a9fba24cSPedro Cuadra 	size_t count = iov_iter_count(to);
741da177e4SLinus Torvalds 	ssize_t ret;
751da177e4SLinus Torvalds 
76a9fba24cSPedro Cuadra 	ret = venus_access_intent(coda_inode->i_sb, coda_i2f(coda_inode),
77a9fba24cSPedro Cuadra 				  &cfi->cfi_access_intent,
78a9fba24cSPedro Cuadra 				  count, ki_pos, CODA_ACCESS_TYPE_WRITE);
79a9fba24cSPedro Cuadra 	if (ret)
80a9fba24cSPedro Cuadra 		goto finish_write;
81a9fba24cSPedro Cuadra 
8203d95eb2SAl Viro 	file_start_write(host_file);
835955102cSAl Viro 	inode_lock(coda_inode);
84abbb6589SChristoph Hellwig 	ret = vfs_iter_write(cfi->cfi_container, to, &iocb->ki_pos, 0);
85c12c49e7SAl Viro 	coda_inode->i_size = file_inode(host_file)->i_size;
861da177e4SLinus Torvalds 	coda_inode->i_blocks = (coda_inode->i_size + 511) >> 9;
87*ea9b53d4SJeff Layton 	coda_inode->i_mtime = inode_set_ctime_current(coda_inode);
885955102cSAl Viro 	inode_unlock(coda_inode);
8903d95eb2SAl Viro 	file_end_write(host_file);
90a9fba24cSPedro Cuadra 
91a9fba24cSPedro Cuadra finish_write:
92a9fba24cSPedro Cuadra 	venus_access_intent(coda_inode->i_sb, coda_i2f(coda_inode),
93a9fba24cSPedro Cuadra 			    &cfi->cfi_access_intent,
94a9fba24cSPedro Cuadra 			    count, ki_pos, CODA_ACCESS_TYPE_WRITE_FINISH);
951da177e4SLinus Torvalds 	return ret;
961da177e4SLinus Torvalds }
971da177e4SLinus Torvalds 
98a1be2935SDavid Howells static ssize_t
coda_file_splice_read(struct file * coda_file,loff_t * ppos,struct pipe_inode_info * pipe,size_t len,unsigned int flags)99a1be2935SDavid Howells coda_file_splice_read(struct file *coda_file, loff_t *ppos,
100a1be2935SDavid Howells 		      struct pipe_inode_info *pipe,
101a1be2935SDavid Howells 		      size_t len, unsigned int flags)
102a1be2935SDavid Howells {
103a1be2935SDavid Howells 	struct inode *coda_inode = file_inode(coda_file);
104a1be2935SDavid Howells 	struct coda_file_info *cfi = coda_ftoc(coda_file);
105a1be2935SDavid Howells 	struct file *in = cfi->cfi_container;
106a1be2935SDavid Howells 	loff_t ki_pos = *ppos;
107a1be2935SDavid Howells 	ssize_t ret;
108a1be2935SDavid Howells 
109a1be2935SDavid Howells 	ret = venus_access_intent(coda_inode->i_sb, coda_i2f(coda_inode),
110a1be2935SDavid Howells 				  &cfi->cfi_access_intent,
111a1be2935SDavid Howells 				  len, ki_pos, CODA_ACCESS_TYPE_READ);
112a1be2935SDavid Howells 	if (ret)
113a1be2935SDavid Howells 		goto finish_read;
114a1be2935SDavid Howells 
115a1be2935SDavid Howells 	ret = vfs_splice_read(in, ppos, pipe, len, flags);
116a1be2935SDavid Howells 
117a1be2935SDavid Howells finish_read:
118a1be2935SDavid Howells 	venus_access_intent(coda_inode->i_sb, coda_i2f(coda_inode),
119a1be2935SDavid Howells 			    &cfi->cfi_access_intent,
120a1be2935SDavid Howells 			    len, ki_pos, CODA_ACCESS_TYPE_READ_FINISH);
121a1be2935SDavid Howells 	return ret;
122a1be2935SDavid Howells }
123a1be2935SDavid Howells 
1247fa0a1daSJan Harkes static void
coda_vm_open(struct vm_area_struct * vma)1257fa0a1daSJan Harkes coda_vm_open(struct vm_area_struct *vma)
1267fa0a1daSJan Harkes {
1277fa0a1daSJan Harkes 	struct coda_vm_ops *cvm_ops =
1287fa0a1daSJan Harkes 		container_of(vma->vm_ops, struct coda_vm_ops, vm_ops);
1297fa0a1daSJan Harkes 
1301077c285SXiyu Yang 	refcount_inc(&cvm_ops->refcnt);
1317fa0a1daSJan Harkes 
1327fa0a1daSJan Harkes 	if (cvm_ops->host_vm_ops && cvm_ops->host_vm_ops->open)
1337fa0a1daSJan Harkes 		cvm_ops->host_vm_ops->open(vma);
1347fa0a1daSJan Harkes }
1357fa0a1daSJan Harkes 
1367fa0a1daSJan Harkes static void
coda_vm_close(struct vm_area_struct * vma)1377fa0a1daSJan Harkes coda_vm_close(struct vm_area_struct *vma)
1387fa0a1daSJan Harkes {
1397fa0a1daSJan Harkes 	struct coda_vm_ops *cvm_ops =
1407fa0a1daSJan Harkes 		container_of(vma->vm_ops, struct coda_vm_ops, vm_ops);
1417fa0a1daSJan Harkes 
1427fa0a1daSJan Harkes 	if (cvm_ops->host_vm_ops && cvm_ops->host_vm_ops->close)
1437fa0a1daSJan Harkes 		cvm_ops->host_vm_ops->close(vma);
1447fa0a1daSJan Harkes 
1451077c285SXiyu Yang 	if (refcount_dec_and_test(&cvm_ops->refcnt)) {
1467fa0a1daSJan Harkes 		vma->vm_ops = cvm_ops->host_vm_ops;
1477fa0a1daSJan Harkes 		fput(cvm_ops->coda_file);
1487fa0a1daSJan Harkes 		kfree(cvm_ops);
1497fa0a1daSJan Harkes 	}
1507fa0a1daSJan Harkes }
1517fa0a1daSJan Harkes 
1521da177e4SLinus Torvalds static int
coda_file_mmap(struct file * coda_file,struct vm_area_struct * vma)1531da177e4SLinus Torvalds coda_file_mmap(struct file *coda_file, struct vm_area_struct *vma)
1541da177e4SLinus Torvalds {
155a9fba24cSPedro Cuadra 	struct inode *coda_inode = file_inode(coda_file);
156a9fba24cSPedro Cuadra 	struct coda_file_info *cfi = coda_ftoc(coda_file);
157a9fba24cSPedro Cuadra 	struct file *host_file = cfi->cfi_container;
158a9fba24cSPedro Cuadra 	struct inode *host_inode = file_inode(host_file);
1591da177e4SLinus Torvalds 	struct coda_inode_info *cii;
1607fa0a1daSJan Harkes 	struct coda_vm_ops *cvm_ops;
161a9fba24cSPedro Cuadra 	loff_t ppos;
162a9fba24cSPedro Cuadra 	size_t count;
1637fa0a1daSJan Harkes 	int ret;
1641da177e4SLinus Torvalds 
16572c2d531SAl Viro 	if (!host_file->f_op->mmap)
1661da177e4SLinus Torvalds 		return -ENODEV;
1671da177e4SLinus Torvalds 
1687fa0a1daSJan Harkes 	if (WARN_ON(coda_file != vma->vm_file))
1697fa0a1daSJan Harkes 		return -EIO;
1707fa0a1daSJan Harkes 
171a9fba24cSPedro Cuadra 	count = vma->vm_end - vma->vm_start;
172a9fba24cSPedro Cuadra 	ppos = vma->vm_pgoff * PAGE_SIZE;
173a9fba24cSPedro Cuadra 
174a9fba24cSPedro Cuadra 	ret = venus_access_intent(coda_inode->i_sb, coda_i2f(coda_inode),
175a9fba24cSPedro Cuadra 				  &cfi->cfi_access_intent,
176a9fba24cSPedro Cuadra 				  count, ppos, CODA_ACCESS_TYPE_MMAP);
177a9fba24cSPedro Cuadra 	if (ret)
178a9fba24cSPedro Cuadra 		return ret;
179a9fba24cSPedro Cuadra 
1807fa0a1daSJan Harkes 	cvm_ops = kmalloc(sizeof(struct coda_vm_ops), GFP_KERNEL);
1817fa0a1daSJan Harkes 	if (!cvm_ops)
1827fa0a1daSJan Harkes 		return -ENOMEM;
1837fa0a1daSJan Harkes 
184b5ce1d83SYoshihisa Abe 	cii = ITOC(coda_inode);
185b5ce1d83SYoshihisa Abe 	spin_lock(&cii->c_lock);
1861da177e4SLinus Torvalds 	coda_file->f_mapping = host_file->f_mapping;
1871da177e4SLinus Torvalds 	if (coda_inode->i_mapping == &coda_inode->i_data)
1881da177e4SLinus Torvalds 		coda_inode->i_mapping = host_inode->i_mapping;
1891da177e4SLinus Torvalds 
1901da177e4SLinus Torvalds 	/* only allow additional mmaps as long as userspace isn't changing
1911da177e4SLinus Torvalds 	 * the container file on us! */
192b5ce1d83SYoshihisa Abe 	else if (coda_inode->i_mapping != host_inode->i_mapping) {
193b5ce1d83SYoshihisa Abe 		spin_unlock(&cii->c_lock);
1947fa0a1daSJan Harkes 		kfree(cvm_ops);
1951da177e4SLinus Torvalds 		return -EBUSY;
196b5ce1d83SYoshihisa Abe 	}
1971da177e4SLinus Torvalds 
1981da177e4SLinus Torvalds 	/* keep track of how often the coda_inode/host_file has been mmapped */
1991da177e4SLinus Torvalds 	cii->c_mapcount++;
2001da177e4SLinus Torvalds 	cfi->cfi_mapcount++;
201b5ce1d83SYoshihisa Abe 	spin_unlock(&cii->c_lock);
2021da177e4SLinus Torvalds 
2037fa0a1daSJan Harkes 	vma->vm_file = get_file(host_file);
2047fa0a1daSJan Harkes 	ret = call_mmap(vma->vm_file, vma);
2057fa0a1daSJan Harkes 
2067fa0a1daSJan Harkes 	if (ret) {
2079da29c7fSChristian König 		/* if call_mmap fails, our caller will put host_file so we
2089da29c7fSChristian König 		 * should drop the reference to the coda_file that we got.
2097fa0a1daSJan Harkes 		 */
2109da29c7fSChristian König 		fput(coda_file);
2117fa0a1daSJan Harkes 		kfree(cvm_ops);
2127fa0a1daSJan Harkes 	} else {
2137fa0a1daSJan Harkes 		/* here we add redirects for the open/close vm_operations */
2147fa0a1daSJan Harkes 		cvm_ops->host_vm_ops = vma->vm_ops;
2157fa0a1daSJan Harkes 		if (vma->vm_ops)
2167fa0a1daSJan Harkes 			cvm_ops->vm_ops = *vma->vm_ops;
2177fa0a1daSJan Harkes 
2187fa0a1daSJan Harkes 		cvm_ops->vm_ops.open = coda_vm_open;
2197fa0a1daSJan Harkes 		cvm_ops->vm_ops.close = coda_vm_close;
2207fa0a1daSJan Harkes 		cvm_ops->coda_file = coda_file;
2211077c285SXiyu Yang 		refcount_set(&cvm_ops->refcnt, 1);
2227fa0a1daSJan Harkes 
2237fa0a1daSJan Harkes 		vma->vm_ops = &cvm_ops->vm_ops;
2247fa0a1daSJan Harkes 	}
2257fa0a1daSJan Harkes 	return ret;
2261da177e4SLinus Torvalds }
2271da177e4SLinus Torvalds 
coda_open(struct inode * coda_inode,struct file * coda_file)2281da177e4SLinus Torvalds int coda_open(struct inode *coda_inode, struct file *coda_file)
2291da177e4SLinus Torvalds {
2301da177e4SLinus Torvalds 	struct file *host_file = NULL;
2311da177e4SLinus Torvalds 	int error;
2321da177e4SLinus Torvalds 	unsigned short flags = coda_file->f_flags & (~O_EXCL);
2331da177e4SLinus Torvalds 	unsigned short coda_flags = coda_flags_to_cflags(flags);
2341da177e4SLinus Torvalds 	struct coda_file_info *cfi;
2351da177e4SLinus Torvalds 
2361da177e4SLinus Torvalds 	cfi = kmalloc(sizeof(struct coda_file_info), GFP_KERNEL);
2376ecbc4e1SJosh Triplett 	if (!cfi)
2381da177e4SLinus Torvalds 		return -ENOMEM;
2391da177e4SLinus Torvalds 
2401da177e4SLinus Torvalds 	error = venus_open(coda_inode->i_sb, coda_i2f(coda_inode), coda_flags,
2411da177e4SLinus Torvalds 			   &host_file);
24238c2e437SJan Harkes 	if (!host_file)
24338c2e437SJan Harkes 		error = -EIO;
24438c2e437SJan Harkes 
24538c2e437SJan Harkes 	if (error) {
2461da177e4SLinus Torvalds 		kfree(cfi);
2471da177e4SLinus Torvalds 		return error;
2481da177e4SLinus Torvalds 	}
2491da177e4SLinus Torvalds 
2501da177e4SLinus Torvalds 	host_file->f_flags |= coda_file->f_flags & (O_APPEND | O_SYNC);
2511da177e4SLinus Torvalds 
2521da177e4SLinus Torvalds 	cfi->cfi_magic = CODA_MAGIC;
2531da177e4SLinus Torvalds 	cfi->cfi_mapcount = 0;
2541da177e4SLinus Torvalds 	cfi->cfi_container = host_file;
255a9fba24cSPedro Cuadra 	/* assume access intents are supported unless we hear otherwise */
256a9fba24cSPedro Cuadra 	cfi->cfi_access_intent = true;
2571da177e4SLinus Torvalds 
2581da177e4SLinus Torvalds 	BUG_ON(coda_file->private_data != NULL);
2591da177e4SLinus Torvalds 	coda_file->private_data = cfi;
2601da177e4SLinus Torvalds 	return 0;
2611da177e4SLinus Torvalds }
2621da177e4SLinus Torvalds 
coda_release(struct inode * coda_inode,struct file * coda_file)2631da177e4SLinus Torvalds int coda_release(struct inode *coda_inode, struct file *coda_file)
2641da177e4SLinus Torvalds {
2651da177e4SLinus Torvalds 	unsigned short flags = (coda_file->f_flags) & (~O_EXCL);
2661da177e4SLinus Torvalds 	unsigned short coda_flags = coda_flags_to_cflags(flags);
2671da177e4SLinus Torvalds 	struct coda_file_info *cfi;
2681da177e4SLinus Torvalds 	struct coda_inode_info *cii;
2691da177e4SLinus Torvalds 	struct inode *host_inode;
2701da177e4SLinus Torvalds 
2715bb44810SFabian Frederick 	cfi = coda_ftoc(coda_file);
2721da177e4SLinus Torvalds 
273b1deb685SAlex Shi 	venus_close(coda_inode->i_sb, coda_i2f(coda_inode),
274d76b0d9bSDavid Howells 			  coda_flags, coda_file->f_cred->fsuid);
2751da177e4SLinus Torvalds 
276496ad9aaSAl Viro 	host_inode = file_inode(cfi->cfi_container);
2771da177e4SLinus Torvalds 	cii = ITOC(coda_inode);
2781da177e4SLinus Torvalds 
2791da177e4SLinus Torvalds 	/* did we mmap this file? */
280b5ce1d83SYoshihisa Abe 	spin_lock(&cii->c_lock);
2811da177e4SLinus Torvalds 	if (coda_inode->i_mapping == &host_inode->i_data) {
2821da177e4SLinus Torvalds 		cii->c_mapcount -= cfi->cfi_mapcount;
2831da177e4SLinus Torvalds 		if (!cii->c_mapcount)
2841da177e4SLinus Torvalds 			coda_inode->i_mapping = &coda_inode->i_data;
2851da177e4SLinus Torvalds 	}
286b5ce1d83SYoshihisa Abe 	spin_unlock(&cii->c_lock);
2871da177e4SLinus Torvalds 
2881da177e4SLinus Torvalds 	fput(cfi->cfi_container);
2891da177e4SLinus Torvalds 	kfree(coda_file->private_data);
2901da177e4SLinus Torvalds 	coda_file->private_data = NULL;
2911da177e4SLinus Torvalds 
292d3fec424SJan Harkes 	/* VFS fput ignores the return value from file_operations->release, so
293d3fec424SJan Harkes 	 * there is no use returning an error here */
294d3fec424SJan Harkes 	return 0;
2951da177e4SLinus Torvalds }
2961da177e4SLinus Torvalds 
coda_fsync(struct file * coda_file,loff_t start,loff_t end,int datasync)29702c24a82SJosef Bacik int coda_fsync(struct file *coda_file, loff_t start, loff_t end, int datasync)
2981da177e4SLinus Torvalds {
2991da177e4SLinus Torvalds 	struct file *host_file;
300496ad9aaSAl Viro 	struct inode *coda_inode = file_inode(coda_file);
3011da177e4SLinus Torvalds 	struct coda_file_info *cfi;
302f7cc02b8SYoshihisa Abe 	int err;
3031da177e4SLinus Torvalds 
3041da177e4SLinus Torvalds 	if (!(S_ISREG(coda_inode->i_mode) || S_ISDIR(coda_inode->i_mode) ||
3051da177e4SLinus Torvalds 	      S_ISLNK(coda_inode->i_mode)))
3061da177e4SLinus Torvalds 		return -EINVAL;
3071da177e4SLinus Torvalds 
30802c24a82SJosef Bacik 	err = filemap_write_and_wait_range(coda_inode->i_mapping, start, end);
30902c24a82SJosef Bacik 	if (err)
31002c24a82SJosef Bacik 		return err;
3115955102cSAl Viro 	inode_lock(coda_inode);
31202c24a82SJosef Bacik 
3135bb44810SFabian Frederick 	cfi = coda_ftoc(coda_file);
3141da177e4SLinus Torvalds 	host_file = cfi->cfi_container;
3151da177e4SLinus Torvalds 
3168018ab05SChristoph Hellwig 	err = vfs_fsync(host_file, datasync);
317f7cc02b8SYoshihisa Abe 	if (!err && !datasync)
3181da177e4SLinus Torvalds 		err = venus_fsync(coda_inode->i_sb, coda_i2f(coda_inode));
3195955102cSAl Viro 	inode_unlock(coda_inode);
3201da177e4SLinus Torvalds 
3211da177e4SLinus Torvalds 	return err;
3221da177e4SLinus Torvalds }
3231da177e4SLinus Torvalds 
3244b6f5d20SArjan van de Ven const struct file_operations coda_file_operations = {
3251da177e4SLinus Torvalds 	.llseek		= generic_file_llseek,
326c12c49e7SAl Viro 	.read_iter	= coda_file_read_iter,
327c12c49e7SAl Viro 	.write_iter	= coda_file_write_iter,
3281da177e4SLinus Torvalds 	.mmap		= coda_file_mmap,
3291da177e4SLinus Torvalds 	.open		= coda_open,
3301da177e4SLinus Torvalds 	.release	= coda_release,
3311da177e4SLinus Torvalds 	.fsync		= coda_fsync,
332a1be2935SDavid Howells 	.splice_read	= coda_file_splice_read,
3331da177e4SLinus Torvalds };
334