585f971e8dc23abe2dea38d23077cc51d9234798
[zfs.git] / module / zfs / zpl_file.c
1 /*
2  * CDDL HEADER START
3  *
4  * The contents of this file are subject to the terms of the
5  * Common Development and Distribution License (the "License").
6  * You may not use this file except in compliance with the License.
7  *
8  * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
9  * or http://www.opensolaris.org/os/licensing.
10  * See the License for the specific language governing permissions
11  * and limitations under the License.
12  *
13  * When distributing Covered Code, include this CDDL HEADER in each
14  * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
15  * If applicable, add the following below this CDDL HEADER, with the
16  * fields enclosed by brackets "[]" replaced with your own identifying
17  * information: Portions Copyright [yyyy] [name of copyright owner]
18  *
19  * CDDL HEADER END
20  */
21 /*
22  * Copyright (c) 2011, Lawrence Livermore National Security, LLC.
23  */
24
25
26 #include <sys/zfs_vfsops.h>
27 #include <sys/zfs_vnops.h>
28 #include <sys/zfs_znode.h>
29 #include <sys/zpl.h>
30
31
32 static int
33 zpl_readdir(struct file *filp, void *dirent, filldir_t filldir)
34 {
35         struct dentry *dentry = filp->f_path.dentry;
36         cred_t *cr;
37         int error;
38
39         cr = (cred_t *)get_current_cred();
40         error = -zfs_readdir(dentry->d_inode, dirent, filldir,
41             &filp->f_pos, cr);
42         put_cred(cr);
43         ASSERT3S(error, <=, 0);
44
45         return (error);
46 }
47
48 static int
49 zpl_fsync(struct file *filp, struct dentry *dentry, int datasync)
50 {
51         cred_t *cr;
52         int error;
53
54         cr = (cred_t *)get_current_cred();
55         error = -zfs_fsync(filp->f_path.dentry->d_inode, datasync, cr);
56         put_cred(cr);
57         ASSERT3S(error, <=, 0);
58
59         return (error);
60 }
61
62 ssize_t
63 zpl_read_common(struct inode *ip, const char *buf, size_t len, loff_t pos,
64      uio_seg_t segment, int flags, cred_t *cr)
65 {
66         int error;
67         struct iovec iov;
68         uio_t uio;
69
70         iov.iov_base = (void *)buf;
71         iov.iov_len = len;
72
73         uio.uio_iov = &iov;
74         uio.uio_resid = len;
75         uio.uio_iovcnt = 1;
76         uio.uio_loffset = pos;
77         uio.uio_limit = MAXOFFSET_T;
78         uio.uio_segflg = segment;
79
80         error = -zfs_read(ip, &uio, flags, cr);
81         if (error < 0)
82                 return (error);
83
84         return (len - uio.uio_resid);
85 }
86
87 static ssize_t
88 zpl_read(struct file *filp, char __user *buf, size_t len, loff_t *ppos)
89 {
90         cred_t *cr;
91         ssize_t read;
92
93         cr = (cred_t *)get_current_cred();
94         read = zpl_read_common(filp->f_mapping->host, buf, len, *ppos,
95             UIO_USERSPACE, filp->f_flags, cr);
96         put_cred(cr);
97
98         if (read < 0)
99                 return (read);
100
101         *ppos += read;
102         return (read);
103 }
104
105 ssize_t
106 zpl_write_common(struct inode *ip, const char *buf, size_t len, loff_t pos,
107     uio_seg_t segment, int flags, cred_t *cr)
108 {
109         int error;
110         struct iovec iov;
111         uio_t uio;
112
113         iov.iov_base = (void *)buf;
114         iov.iov_len = len;
115
116         uio.uio_iov = &iov;
117         uio.uio_resid = len,
118         uio.uio_iovcnt = 1;
119         uio.uio_loffset = pos;
120         uio.uio_limit = MAXOFFSET_T;
121         uio.uio_segflg = segment;
122
123         error = -zfs_write(ip, &uio, flags, cr);
124         if (error < 0)
125                 return (error);
126
127         return (len - uio.uio_resid);
128 }
129
130 static ssize_t
131 zpl_write(struct file *filp, const char __user *buf, size_t len, loff_t *ppos)
132 {
133         cred_t *cr;
134         ssize_t wrote;
135
136         cr = (cred_t *)get_current_cred();
137         wrote = zpl_write_common(filp->f_mapping->host, buf, len, *ppos,
138             UIO_USERSPACE, filp->f_flags, cr);
139         put_cred(cr);
140
141         if (wrote < 0)
142                 return (wrote);
143
144         *ppos += wrote;
145         return (wrote);
146 }
147
148 /*
149  * It's worth taking a moment to describe how mmap is implemented
150  * for zfs because it differs considerably from other Linux filesystems.
151  * However, this issue is handled the same way under OpenSolaris.
152  *
153  * The issue is that by design zfs bypasses the Linux page cache and
154  * leaves all caching up to the ARC.  This has been shown to work
155  * well for the common read(2)/write(2) case.  However, mmap(2)
156  * is problem because it relies on being tightly integrated with the
157  * page cache.  To handle this we cache mmap'ed files twice, once in
158  * the ARC and a second time in the page cache.  The code is careful
159  * to keep both copies synchronized.
160  *
161  * When a file with an mmap'ed region is written to using write(2)
162  * both the data in the ARC and existing pages in the page cache
163  * are updated.  For a read(2) data will be read first from the page
164  * cache then the ARC if needed.  Neither a write(2) or read(2) will
165  * will ever result in new pages being added to the page cache.
166  *
167  * New pages are added to the page cache only via .readpage() which
168  * is called when the vfs needs to read a page off disk to back the
169  * virtual memory region.  These pages may be modified without
170  * notifying the ARC and will be written out periodically via
171  * .writepage().  This will occur due to either a sync or the usual
172  * page aging behavior.  Note because a read(2) of a mmap'ed file
173  * will always check the page cache first even when the ARC is out
174  * of date correct data will still be returned.
175  *
176  * While this implementation ensures correct behavior it does have
177  * have some drawbacks.  The most obvious of which is that it
178  * increases the required memory footprint when access mmap'ed
179  * files.  It also adds additional complexity to the code keeping
180  * both caches synchronized.
181  *
182  * Longer term it may be possible to cleanly resolve this wart by
183  * mapping page cache pages directly on to the ARC buffers.  The
184  * Linux address space operations are flexible enough to allow
185  * selection of which pages back a particular index.  The trick
186  * would be working out the details of which subsystem is in
187  * charge, the ARC, the page cache, or both.  It may also prove
188  * helpful to move the ARC buffers to a scatter-gather lists
189  * rather than a vmalloc'ed region.
190  */
191 static int
192 zpl_mmap(struct file *filp, struct vm_area_struct *vma)
193 {
194         znode_t *zp = ITOZ(filp->f_mapping->host);
195         int error;
196
197         error = generic_file_mmap(filp, vma);
198         if (error)
199                 return (error);
200
201         mutex_enter(&zp->z_lock);
202         zp->z_is_mapped = 1;
203         mutex_exit(&zp->z_lock);
204
205         return (error);
206 }
207
208 /*
209  * Populate a page with data for the Linux page cache.  This function is
210  * only used to support mmap(2).  There will be an identical copy of the
211  * data in the ARC which is kept up to date via .write() and .writepage().
212  *
213  * Current this function relies on zpl_read_common() and the O_DIRECT
214  * flag to read in a page.  This works but the more correct way is to
215  * update zfs_fillpage() to be Linux friendly and use that interface.
216  */
217 static int
218 zpl_readpage(struct file *filp, struct page *pp)
219 {
220         struct inode *ip;
221         loff_t off, i_size;
222         size_t len, wrote;
223         cred_t *cr;
224         void *pb;
225         int error = 0;
226
227         ASSERT(PageLocked(pp));
228         ip = pp->mapping->host;
229         off = page_offset(pp);
230         i_size = i_size_read(ip);
231         ASSERT3S(off, <, i_size);
232
233         cr = (cred_t *)get_current_cred();
234         len = MIN(PAGE_CACHE_SIZE, i_size - off);
235
236         pb = kmap(pp);
237
238         /* O_DIRECT is passed to bypass the page cache and avoid deadlock. */
239         wrote = zpl_read_common(ip, pb, len, off, UIO_SYSSPACE, O_DIRECT, cr);
240         if (wrote != len)
241                 error = -EIO;
242
243         if (!error && (len < PAGE_CACHE_SIZE))
244                 memset(pb + len, 0, PAGE_CACHE_SIZE - len);
245
246         kunmap(pp);
247         put_cred(cr);
248
249         if (error) {
250                 SetPageError(pp);
251                 ClearPageUptodate(pp);
252         } else {
253                 ClearPageError(pp);
254                 SetPageUptodate(pp);
255                 flush_dcache_page(pp);
256         }
257
258         unlock_page(pp);
259
260         return (error);
261 }
262
263 /*
264  * Write out dirty pages to the ARC, this function is only required to
265  * support mmap(2).  Mapped pages may be dirtied by memory operations
266  * which never call .write().  These dirty pages are kept in sync with
267  * the ARC buffers via this hook.
268  *
269  * Currently this function relies on zpl_write_common() and the O_DIRECT
270  * flag to push out the page.  This works but the more correct way is
271  * to update zfs_putapage() to be Linux friendly and use that interface.
272  */
273 static int
274 zpl_writepage(struct page *pp, struct writeback_control *wbc)
275 {
276         struct inode *ip;
277         loff_t off, i_size;
278         size_t len, read;
279         cred_t *cr;
280         void *pb;
281         int error = 0;
282
283         ASSERT(PageLocked(pp));
284         ip = pp->mapping->host;
285         off = page_offset(pp);
286         i_size = i_size_read(ip);
287
288         cr = (cred_t *)get_current_cred();
289         len = MIN(PAGE_CACHE_SIZE, i_size - off);
290
291         pb = kmap(pp);
292
293         /* O_DIRECT is passed to bypass the page cache and avoid deadlock. */
294         read = zpl_write_common(ip, pb, len, off, UIO_SYSSPACE, O_DIRECT, cr);
295         if (read != len)
296                 error = -EIO;
297
298         kunmap(pp);
299         put_cred(cr);
300
301         if (error) {
302                 SetPageError(pp);
303                 ClearPageUptodate(pp);
304         } else {
305                 ClearPageError(pp);
306                 SetPageUptodate(pp);
307         }
308
309         unlock_page(pp);
310
311         return (error);
312 }
313
314 const struct address_space_operations zpl_address_space_operations = {
315         .readpage       = zpl_readpage,
316         .writepage      = zpl_writepage,
317 };
318
319 const struct file_operations zpl_file_operations = {
320         .open           = generic_file_open,
321         .llseek         = generic_file_llseek,
322         .read           = zpl_read,
323         .write          = zpl_write,
324         .readdir        = zpl_readdir,
325         .mmap           = zpl_mmap,
326         .fsync          = zpl_fsync,
327 };
328
329 const struct file_operations zpl_dir_file_operations = {
330         .llseek         = generic_file_llseek,
331         .read           = generic_read_dir,
332         .readdir        = zpl_readdir,
333         .fsync          = zpl_fsync,
334 };