xref: /freebsd-src/sys/contrib/openzfs/module/os/linux/zfs/zfs_file_os.c (revision 7a7741af18d6c8a804cc643cb7ecda9d730c6aa6)
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 https://opensource.org/licenses/CDDL-1.0.
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 /*
73  * Stateful write - use os internal file pointer to determine where to
74  * write and update on successful completion.
75  *
76  * fp -  pointer to file (pipe, socket, etc) to write to
77  * buf - buffer to write
78  * count - # of bytes to write
79  * resid -  pointer to count of unwritten bytes  (if short write)
80  *
81  * Returns 0 on success errno on failure.
82  */
83 int
84 zfs_file_write(zfs_file_t *fp, const void *buf, size_t count, ssize_t *resid)
85 {
86 	loff_t off = fp->f_pos;
87 	ssize_t rc;
88 
89 	rc = kernel_write(fp, buf, count, &off);
90 	if (rc < 0)
91 		return (-rc);
92 
93 	fp->f_pos = off;
94 
95 	if (resid) {
96 		*resid = count - rc;
97 	} else if (rc != count) {
98 		return (EIO);
99 	}
100 
101 	return (0);
102 }
103 
104 /*
105  * Stateless write - os internal file pointer is not updated.
106  *
107  * fp -  pointer to file (pipe, socket, etc) to write to
108  * buf - buffer to write
109  * count - # of bytes to write
110  * off - file offset to write to (only valid for seekable types)
111  * resid -  pointer to count of unwritten bytes
112  *
113  * Returns 0 on success errno on failure.
114  */
115 int
116 zfs_file_pwrite(zfs_file_t *fp, const void *buf, size_t count, loff_t off,
117     ssize_t *resid)
118 {
119 	ssize_t rc;
120 
121 	rc  = kernel_write(fp, buf, count, &off);
122 	if (rc < 0)
123 		return (-rc);
124 
125 	if (resid) {
126 		*resid = count - rc;
127 	} else if (rc != count) {
128 		return (EIO);
129 	}
130 
131 	return (0);
132 }
133 
134 /*
135  * Stateful read - use os internal file pointer to determine where to
136  * read and update on successful completion.
137  *
138  * fp -  pointer to file (pipe, socket, etc) to read from
139  * buf - buffer to write
140  * count - # of bytes to read
141  * resid -  pointer to count of unread bytes (if short read)
142  *
143  * Returns 0 on success errno on failure.
144  */
145 int
146 zfs_file_read(zfs_file_t *fp, void *buf, size_t count, ssize_t *resid)
147 {
148 	loff_t off = fp->f_pos;
149 	ssize_t rc;
150 
151 	rc = kernel_read(fp, buf, count, &off);
152 	if (rc < 0)
153 		return (-rc);
154 
155 	fp->f_pos = off;
156 
157 	if (resid) {
158 		*resid = count - rc;
159 	} else if (rc != count) {
160 		return (EIO);
161 	}
162 
163 	return (0);
164 }
165 
166 /*
167  * Stateless read - os internal file pointer is not updated.
168  *
169  * fp -  pointer to file (pipe, socket, etc) to read from
170  * buf - buffer to write
171  * count - # of bytes to write
172  * off - file offset to read from (only valid for seekable types)
173  * resid -  pointer to count of unwritten bytes (if short write)
174  *
175  * Returns 0 on success errno on failure.
176  */
177 int
178 zfs_file_pread(zfs_file_t *fp, void *buf, size_t count, loff_t off,
179     ssize_t *resid)
180 {
181 	ssize_t rc;
182 
183 	rc = kernel_read(fp, buf, count, &off);
184 	if (rc < 0)
185 		return (-rc);
186 
187 	if (resid) {
188 		*resid = count - rc;
189 	} else if (rc != count) {
190 		return (EIO);
191 	}
192 
193 	return (0);
194 }
195 
196 /*
197  * lseek - set / get file pointer
198  *
199  * fp -  pointer to file (pipe, socket, etc) to read from
200  * offp - value to seek to, returns current value plus passed offset
201  * whence - see man pages for standard lseek whence values
202  *
203  * Returns 0 on success errno on failure (ESPIPE for non seekable types)
204  */
205 int
206 zfs_file_seek(zfs_file_t *fp, loff_t *offp, int whence)
207 {
208 	loff_t rc;
209 
210 	if (*offp < 0)
211 		return (EINVAL);
212 
213 	rc = vfs_llseek(fp, *offp, whence);
214 	if (rc < 0)
215 		return (-rc);
216 
217 	*offp = rc;
218 
219 	return (0);
220 }
221 
222 /*
223  * Get file attributes
224  *
225  * filp - file pointer
226  * zfattr - pointer to file attr structure
227  *
228  * Currently only used for fetching size and file mode.
229  *
230  * Returns 0 on success or error code of underlying getattr call on failure.
231  */
232 int
233 zfs_file_getattr(zfs_file_t *filp, zfs_file_attr_t *zfattr)
234 {
235 	struct kstat stat;
236 	int rc;
237 
238 	rc = vfs_getattr(&filp->f_path, &stat, STATX_BASIC_STATS,
239 	    AT_STATX_SYNC_AS_STAT);
240 	if (rc)
241 		return (-rc);
242 
243 	zfattr->zfa_size = stat.size;
244 	zfattr->zfa_mode = stat.mode;
245 
246 	return (0);
247 }
248 
249 /*
250  * Sync file to disk
251  *
252  * filp - file pointer
253  * flags - O_SYNC and or O_DSYNC
254  *
255  * Returns 0 on success or error code of underlying sync call on failure.
256  */
257 int
258 zfs_file_fsync(zfs_file_t *filp, int flags)
259 {
260 	int datasync = 0;
261 	int error;
262 	int fstrans;
263 
264 	if (flags & O_DSYNC)
265 		datasync = 1;
266 
267 	/*
268 	 * May enter XFS which generates a warning when PF_FSTRANS is set.
269 	 * To avoid this the flag is cleared over vfs_sync() and then reset.
270 	 */
271 	fstrans = __spl_pf_fstrans_check();
272 	if (fstrans)
273 		current->flags &= ~(__SPL_PF_FSTRANS);
274 
275 	error = -vfs_fsync(filp, datasync);
276 
277 	if (fstrans)
278 		current->flags |= __SPL_PF_FSTRANS;
279 
280 	return (error);
281 }
282 
283 /*
284  * deallocate - zero and/or deallocate file storage
285  *
286  * fp - file pointer
287  * offset - offset to start zeroing or deallocating
288  * len - length to zero or deallocate
289  */
290 int
291 zfs_file_deallocate(zfs_file_t *fp, loff_t offset, loff_t len)
292 {
293 	/*
294 	 * May enter XFS which generates a warning when PF_FSTRANS is set.
295 	 * To avoid this the flag is cleared over vfs_sync() and then reset.
296 	 */
297 	int fstrans = __spl_pf_fstrans_check();
298 	if (fstrans)
299 		current->flags &= ~(__SPL_PF_FSTRANS);
300 
301 	/*
302 	 * When supported by the underlying file system preferentially
303 	 * use the fallocate() callback to preallocate the space.
304 	 */
305 	int error = EOPNOTSUPP;
306 	if (fp->f_op->fallocate)
307 		error = -fp->f_op->fallocate(fp,
308 		    FALLOC_FL_PUNCH_HOLE | FALLOC_FL_KEEP_SIZE, offset, len);
309 
310 	if (fstrans)
311 		current->flags |= __SPL_PF_FSTRANS;
312 
313 	if (error)
314 		return (SET_ERROR(error));
315 
316 	return (0);
317 }
318 
319 /*
320  * Request current file pointer offset
321  *
322  * fp - pointer to file
323  *
324  * Returns current file offset.
325  */
326 loff_t
327 zfs_file_off(zfs_file_t *fp)
328 {
329 	return (fp->f_pos);
330 }
331 
332 /*
333  * Request file pointer private data
334  *
335  * fp - pointer to file
336  *
337  * Returns pointer to file private data.
338  */
339 void *
340 zfs_file_private(zfs_file_t *fp)
341 {
342 	return (fp->private_data);
343 }
344 
345 /*
346  * unlink file
347  *
348  * path - fully qualified file path
349  *
350  * Returns 0 on success.
351  *
352  * OPTIONAL
353  */
354 int
355 zfs_file_unlink(const char *path)
356 {
357 	return (EOPNOTSUPP);
358 }
359 
360 /*
361  * Get reference to file pointer
362  *
363  * fd - input file descriptor
364  *
365  * Returns pointer to file struct or NULL
366  */
367 zfs_file_t *
368 zfs_file_get(int fd)
369 {
370 	return (fget(fd));
371 }
372 
373 /*
374  * Drop reference to file pointer
375  *
376  * fp - input file struct pointer
377  */
378 void
379 zfs_file_put(zfs_file_t *fp)
380 {
381 	fput(fp);
382 }
383