]> CyberLeo.Net >> Repos - FreeBSD/FreeBSD.git/blob - sys/contrib/openzfs/module/os/linux/zfs/zfs_file_os.c
ZFS: MFV 2.0-rc1-gfd20a8
[FreeBSD/FreeBSD.git] / sys / contrib / openzfs / module / os / linux / zfs / zfs_file_os.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 #include <sys/zfs_context.h>
23 #include <sys/zfs_file.h>
24 #include <sys/stat.h>
25 #include <sys/file.h>
26 #include <linux/falloc.h>
27 #include <linux/fs.h>
28 #include <linux/uaccess.h>
29 #ifdef HAVE_FDTABLE_HEADER
30 #include <linux/fdtable.h>
31 #endif
32
33 /*
34  * Open file
35  *
36  * path - fully qualified path to file
37  * flags - file attributes O_READ / O_WRITE / O_EXCL
38  * fpp - pointer to return file pointer
39  *
40  * Returns 0 on success underlying error on failure.
41  */
42 int
43 zfs_file_open(const char *path, int flags, int mode, zfs_file_t **fpp)
44 {
45         struct file *filp;
46         int saved_umask;
47
48         if (!(flags & O_CREAT) && (flags & O_WRONLY))
49                 flags |= O_EXCL;
50
51         if (flags & O_CREAT)
52                 saved_umask = xchg(&current->fs->umask, 0);
53
54         filp = filp_open(path, flags, mode);
55
56         if (flags & O_CREAT)
57                 (void) xchg(&current->fs->umask, saved_umask);
58
59         if (IS_ERR(filp))
60                 return (-PTR_ERR(filp));
61
62         *fpp = filp;
63         return (0);
64 }
65
66 void
67 zfs_file_close(zfs_file_t *fp)
68 {
69         filp_close(fp, 0);
70 }
71
72 static ssize_t
73 zfs_file_write_impl(zfs_file_t *fp, const void *buf, size_t count, loff_t *off)
74 {
75 #if defined(HAVE_KERNEL_WRITE_PPOS)
76         return (kernel_write(fp, buf, count, off));
77 #else
78         mm_segment_t saved_fs;
79         ssize_t rc;
80
81         saved_fs = get_fs();
82         set_fs(KERNEL_DS);
83
84         rc = vfs_write(fp, (__force const char __user __user *)buf, count, off);
85
86         set_fs(saved_fs);
87
88         return (rc);
89 #endif
90 }
91
92 /*
93  * Stateful write - use os internal file pointer to determine where to
94  * write and update on successful completion.
95  *
96  * fp -  pointer to file (pipe, socket, etc) to write to
97  * buf - buffer to write
98  * count - # of bytes to write
99  * resid -  pointer to count of unwritten bytes  (if short write)
100  *
101  * Returns 0 on success errno on failure.
102  */
103 int
104 zfs_file_write(zfs_file_t *fp, const void *buf, size_t count, ssize_t *resid)
105 {
106         loff_t off = fp->f_pos;
107         ssize_t rc;
108
109         rc = zfs_file_write_impl(fp, buf, count, &off);
110         if (rc < 0)
111                 return (-rc);
112
113         fp->f_pos = off;
114
115         if (resid) {
116                 *resid = count - rc;
117         } else if (rc != count) {
118                 return (EIO);
119         }
120
121         return (0);
122 }
123
124 /*
125  * Stateless write - os internal file pointer is not updated.
126  *
127  * fp -  pointer to file (pipe, socket, etc) to write to
128  * buf - buffer to write
129  * count - # of bytes to write
130  * off - file offset to write to (only valid for seekable types)
131  * resid -  pointer to count of unwritten bytes
132  *
133  * Returns 0 on success errno on failure.
134  */
135 int
136 zfs_file_pwrite(zfs_file_t *fp, const void *buf, size_t count, loff_t off,
137     ssize_t *resid)
138 {
139         ssize_t rc;
140
141         rc  = zfs_file_write_impl(fp, buf, count, &off);
142         if (rc < 0)
143                 return (-rc);
144
145         if (resid) {
146                 *resid = count - rc;
147         } else if (rc != count) {
148                 return (EIO);
149         }
150
151         return (0);
152 }
153
154 static ssize_t
155 zfs_file_read_impl(zfs_file_t *fp, void *buf, size_t count, loff_t *off)
156 {
157 #if defined(HAVE_KERNEL_READ_PPOS)
158         return (kernel_read(fp, buf, count, off));
159 #else
160         mm_segment_t saved_fs;
161         ssize_t rc;
162
163         saved_fs = get_fs();
164         set_fs(KERNEL_DS);
165
166         rc = vfs_read(fp, (void __user *)buf, count, off);
167         set_fs(saved_fs);
168
169         return (rc);
170 #endif
171 }
172
173 /*
174  * Stateful read - use os internal file pointer to determine where to
175  * read and update on successful completion.
176  *
177  * fp -  pointer to file (pipe, socket, etc) to read from
178  * buf - buffer to write
179  * count - # of bytes to read
180  * resid -  pointer to count of unread bytes (if short read)
181  *
182  * Returns 0 on success errno on failure.
183  */
184 int
185 zfs_file_read(zfs_file_t *fp, void *buf, size_t count, ssize_t *resid)
186 {
187         loff_t off = fp->f_pos;
188         ssize_t rc;
189
190         rc = zfs_file_read_impl(fp, buf, count, &off);
191         if (rc < 0)
192                 return (-rc);
193
194         fp->f_pos = off;
195
196         if (resid) {
197                 *resid = count - rc;
198         } else if (rc != count) {
199                 return (EIO);
200         }
201
202         return (0);
203 }
204
205 /*
206  * Stateless read - os internal file pointer is not updated.
207  *
208  * fp -  pointer to file (pipe, socket, etc) to read from
209  * buf - buffer to write
210  * count - # of bytes to write
211  * off - file offset to read from (only valid for seekable types)
212  * resid -  pointer to count of unwritten bytes (if short write)
213  *
214  * Returns 0 on success errno on failure.
215  */
216 int
217 zfs_file_pread(zfs_file_t *fp, void *buf, size_t count, loff_t off,
218     ssize_t *resid)
219 {
220         ssize_t rc;
221
222         rc = zfs_file_read_impl(fp, buf, count, &off);
223         if (rc < 0)
224                 return (-rc);
225
226         if (resid) {
227                 *resid = count - rc;
228         } else if (rc != count) {
229                 return (EIO);
230         }
231
232         return (0);
233 }
234
235 /*
236  * lseek - set / get file pointer
237  *
238  * fp -  pointer to file (pipe, socket, etc) to read from
239  * offp - value to seek to, returns current value plus passed offset
240  * whence - see man pages for standard lseek whence values
241  *
242  * Returns 0 on success errno on failure (ESPIPE for non seekable types)
243  */
244 int
245 zfs_file_seek(zfs_file_t *fp, loff_t *offp, int whence)
246 {
247         loff_t rc;
248
249         if (*offp < 0 || *offp > MAXOFFSET_T)
250                 return (EINVAL);
251
252         rc = vfs_llseek(fp, *offp, whence);
253         if (rc < 0)
254                 return (-rc);
255
256         *offp = rc;
257
258         return (0);
259 }
260
261 /*
262  * Get file attributes
263  *
264  * filp - file pointer
265  * zfattr - pointer to file attr structure
266  *
267  * Currently only used for fetching size and file mode.
268  *
269  * Returns 0 on success or error code of underlying getattr call on failure.
270  */
271 int
272 zfs_file_getattr(zfs_file_t *filp, zfs_file_attr_t *zfattr)
273 {
274         struct kstat stat;
275         int rc;
276
277 #if defined(HAVE_4ARGS_VFS_GETATTR)
278         rc = vfs_getattr(&filp->f_path, &stat, STATX_BASIC_STATS,
279             AT_STATX_SYNC_AS_STAT);
280 #elif defined(HAVE_2ARGS_VFS_GETATTR)
281         rc = vfs_getattr(&filp->f_path, &stat);
282 #else
283         rc = vfs_getattr(filp->f_path.mnt, filp->f_dentry, &stat);
284 #endif
285         if (rc)
286                 return (-rc);
287
288         zfattr->zfa_size = stat.size;
289         zfattr->zfa_mode = stat.mode;
290
291         return (0);
292 }
293
294 /*
295  * Sync file to disk
296  *
297  * filp - file pointer
298  * flags - O_SYNC and or O_DSYNC
299  *
300  * Returns 0 on success or error code of underlying sync call on failure.
301  */
302 int
303 zfs_file_fsync(zfs_file_t *filp, int flags)
304 {
305         int datasync = 0;
306         int error;
307         int fstrans;
308
309         if (flags & O_DSYNC)
310                 datasync = 1;
311
312         /*
313          * May enter XFS which generates a warning when PF_FSTRANS is set.
314          * To avoid this the flag is cleared over vfs_sync() and then reset.
315          */
316         fstrans = __spl_pf_fstrans_check();
317         if (fstrans)
318                 current->flags &= ~(__SPL_PF_FSTRANS);
319
320         error = -vfs_fsync(filp, datasync);
321
322         if (fstrans)
323                 current->flags |= __SPL_PF_FSTRANS;
324
325         return (error);
326 }
327
328 /*
329  * fallocate - allocate or free space on disk
330  *
331  * fp - file pointer
332  * mode (non-standard options for hole punching etc)
333  * offset - offset to start allocating or freeing from
334  * len - length to free / allocate
335  *
336  * OPTIONAL
337  */
338 int
339 zfs_file_fallocate(zfs_file_t *fp, int mode, loff_t offset, loff_t len)
340 {
341         /*
342          * May enter XFS which generates a warning when PF_FSTRANS is set.
343          * To avoid this the flag is cleared over vfs_sync() and then reset.
344          */
345         int fstrans = __spl_pf_fstrans_check();
346         if (fstrans)
347                 current->flags &= ~(__SPL_PF_FSTRANS);
348
349         /*
350          * When supported by the underlying file system preferentially
351          * use the fallocate() callback to preallocate the space.
352          */
353         int error = EOPNOTSUPP;
354         if (fp->f_op->fallocate)
355                 error = fp->f_op->fallocate(fp, mode, offset, len);
356
357         if (fstrans)
358                 current->flags |= __SPL_PF_FSTRANS;
359
360         return (error);
361 }
362
363 /*
364  * Request current file pointer offset
365  *
366  * fp - pointer to file
367  *
368  * Returns current file offset.
369  */
370 loff_t
371 zfs_file_off(zfs_file_t *fp)
372 {
373         return (fp->f_pos);
374 }
375
376 /*
377  * Request file pointer private data
378  *
379  * fp - pointer to file
380  *
381  * Returns pointer to file private data.
382  */
383 void *
384 zfs_file_private(zfs_file_t *fp)
385 {
386         return (fp->private_data);
387 }
388
389 /*
390  * unlink file
391  *
392  * path - fully qualified file path
393  *
394  * Returns 0 on success.
395  *
396  * OPTIONAL
397  */
398 int
399 zfs_file_unlink(const char *path)
400 {
401         return (EOPNOTSUPP);
402 }
403
404 /*
405  * Get reference to file pointer
406  *
407  * fd - input file descriptor
408  * fpp - pointer to file pointer
409  *
410  * Returns 0 on success EBADF on failure.
411  */
412 int
413 zfs_file_get(int fd, zfs_file_t **fpp)
414 {
415         zfs_file_t *fp;
416
417         fp = fget(fd);
418         if (fp == NULL)
419                 return (EBADF);
420
421         *fpp = fp;
422
423         return (0);
424 }
425
426 /*
427  * Drop reference to file pointer
428  *
429  * fd - input file descriptor
430  */
431 void
432 zfs_file_put(int fd)
433 {
434         struct file *fp;
435
436         if ((fp = fget(fd)) != NULL) {
437                 fput(fp);
438                 fput(fp);
439         }
440 }