xref: /freebsd/sys/contrib/openzfs/module/os/linux/zfs/zfs_file_os.c (revision df58e8b1506f241670be86a560fb6e8432043aee)
1 // SPDX-License-Identifier: CDDL-1.0
2 /*
3  * CDDL HEADER START
4  *
5  * The contents of this file are subject to the terms of the
6  * Common Development and Distribution License (the "License").
7  * You may not use this file except in compliance with the License.
8  *
9  * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
10  * or https://opensource.org/licenses/CDDL-1.0.
11  * See the License for the specific language governing permissions
12  * and limitations under the License.
13  *
14  * When distributing Covered Code, include this CDDL HEADER in each
15  * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
16  * If applicable, add the following below this CDDL HEADER, with the
17  * fields enclosed by brackets "[]" replaced with your own identifying
18  * information: Portions Copyright [yyyy] [name of copyright owner]
19  *
20  * CDDL HEADER END
21  */
22 
23 #include <sys/zfs_context.h>
24 #include <sys/zfs_file.h>
25 #include <sys/stat.h>
26 #include <sys/file.h>
27 #include <linux/falloc.h>
28 #include <linux/fs.h>
29 #include <linux/uaccess.h>
30 #ifdef HAVE_FDTABLE_HEADER
31 #include <linux/fdtable.h>
32 #endif
33 
34 /*
35  * Open file
36  *
37  * path - fully qualified path to file
38  * flags - file attributes O_READ / O_WRITE / O_EXCL
39  * fpp - pointer to return file pointer
40  *
41  * Returns 0 on success underlying error on failure.
42  */
43 int
zfs_file_open(const char * path,int flags,int mode,zfs_file_t ** fpp)44 zfs_file_open(const char *path, int flags, int mode, zfs_file_t **fpp)
45 {
46 	struct file *filp;
47 	int saved_umask;
48 
49 	if (!(flags & O_CREAT) && (flags & O_WRONLY))
50 		flags |= O_EXCL;
51 
52 	if (flags & O_CREAT)
53 		saved_umask = xchg(&current->fs->umask, 0);
54 
55 	filp = filp_open(path, flags, mode);
56 
57 	if (flags & O_CREAT)
58 		(void) xchg(&current->fs->umask, saved_umask);
59 
60 	if (IS_ERR(filp))
61 		return (-PTR_ERR(filp));
62 
63 	*fpp = filp;
64 	return (0);
65 }
66 
67 void
zfs_file_close(zfs_file_t * fp)68 zfs_file_close(zfs_file_t *fp)
69 {
70 	filp_close(fp, 0);
71 }
72 
73 /*
74  * Stateful write - use os internal file pointer to determine where to
75  * write and update on successful completion.
76  *
77  * fp -  pointer to file (pipe, socket, etc) to write to
78  * buf - buffer to write
79  * count - # of bytes to write
80  * resid -  pointer to count of unwritten bytes  (if short write)
81  *
82  * Returns 0 on success errno on failure.
83  */
84 int
zfs_file_write(zfs_file_t * fp,const void * buf,size_t count,ssize_t * resid)85 zfs_file_write(zfs_file_t *fp, const void *buf, size_t count, ssize_t *resid)
86 {
87 	loff_t off = fp->f_pos;
88 	ssize_t rc;
89 
90 	rc = kernel_write(fp, buf, count, &off);
91 	if (rc < 0)
92 		return (-rc);
93 
94 	fp->f_pos = off;
95 
96 	if (resid) {
97 		*resid = count - rc;
98 	} else if (rc != count) {
99 		return (EIO);
100 	}
101 
102 	return (0);
103 }
104 
105 /*
106  * Stateless write - os internal file pointer is not updated.
107  *
108  * fp -  pointer to file (pipe, socket, etc) to write to
109  * buf - buffer to write
110  * count - # of bytes to write
111  * off - file offset to write to (only valid for seekable types)
112  * resid -  pointer to count of unwritten bytes
113  *
114  * Returns 0 on success errno on failure.
115  */
116 int
zfs_file_pwrite(zfs_file_t * fp,const void * buf,size_t count,loff_t off,ssize_t * resid)117 zfs_file_pwrite(zfs_file_t *fp, const void *buf, size_t count, loff_t off,
118     ssize_t *resid)
119 {
120 	ssize_t rc;
121 
122 	rc  = kernel_write(fp, buf, count, &off);
123 	if (rc < 0)
124 		return (-rc);
125 
126 	if (resid) {
127 		*resid = count - rc;
128 	} else if (rc != count) {
129 		return (EIO);
130 	}
131 
132 	return (0);
133 }
134 
135 /*
136  * Stateful read - use os internal file pointer to determine where to
137  * read and update on successful completion.
138  *
139  * fp -  pointer to file (pipe, socket, etc) to read from
140  * buf - buffer to write
141  * count - # of bytes to read
142  * resid -  pointer to count of unread bytes (if short read)
143  *
144  * Returns 0 on success errno on failure.
145  */
146 int
zfs_file_read(zfs_file_t * fp,void * buf,size_t count,ssize_t * resid)147 zfs_file_read(zfs_file_t *fp, void *buf, size_t count, ssize_t *resid)
148 {
149 	loff_t off = fp->f_pos;
150 	ssize_t rc;
151 
152 	rc = kernel_read(fp, buf, count, &off);
153 	if (rc < 0)
154 		return (-rc);
155 
156 	fp->f_pos = off;
157 
158 	if (resid) {
159 		*resid = count - rc;
160 	} else if (rc != count) {
161 		return (EIO);
162 	}
163 
164 	return (0);
165 }
166 
167 /*
168  * Stateless read - os internal file pointer is not updated.
169  *
170  * fp -  pointer to file (pipe, socket, etc) to read from
171  * buf - buffer to write
172  * count - # of bytes to write
173  * off - file offset to read from (only valid for seekable types)
174  * resid -  pointer to count of unwritten bytes (if short write)
175  *
176  * Returns 0 on success errno on failure.
177  */
178 int
zfs_file_pread(zfs_file_t * fp,void * buf,size_t count,loff_t off,ssize_t * resid)179 zfs_file_pread(zfs_file_t *fp, void *buf, size_t count, loff_t off,
180     ssize_t *resid)
181 {
182 	ssize_t rc;
183 
184 	rc = kernel_read(fp, buf, count, &off);
185 	if (rc < 0)
186 		return (-rc);
187 
188 	if (resid) {
189 		*resid = count - rc;
190 	} else if (rc != count) {
191 		return (EIO);
192 	}
193 
194 	return (0);
195 }
196 
197 /*
198  * lseek - set / get file pointer
199  *
200  * fp -  pointer to file (pipe, socket, etc) to read from
201  * offp - value to seek to, returns current value plus passed offset
202  * whence - see man pages for standard lseek whence values
203  *
204  * Returns 0 on success errno on failure (ESPIPE for non seekable types)
205  */
206 int
zfs_file_seek(zfs_file_t * fp,loff_t * offp,int whence)207 zfs_file_seek(zfs_file_t *fp, loff_t *offp, int whence)
208 {
209 	loff_t rc;
210 
211 	if (*offp < 0)
212 		return (EINVAL);
213 
214 	rc = vfs_llseek(fp, *offp, whence);
215 	if (rc < 0)
216 		return (-rc);
217 
218 	*offp = rc;
219 
220 	return (0);
221 }
222 
223 /*
224  * Get file attributes
225  *
226  * filp - file pointer
227  * zfattr - pointer to file attr structure
228  *
229  * Currently only used for fetching size and file mode.
230  *
231  * Returns 0 on success or error code of underlying getattr call on failure.
232  */
233 int
zfs_file_getattr(zfs_file_t * filp,zfs_file_attr_t * zfattr)234 zfs_file_getattr(zfs_file_t *filp, zfs_file_attr_t *zfattr)
235 {
236 	struct kstat stat;
237 	int rc;
238 
239 	rc = vfs_getattr(&filp->f_path, &stat, STATX_BASIC_STATS,
240 	    AT_STATX_SYNC_AS_STAT);
241 	if (rc)
242 		return (-rc);
243 
244 	zfattr->zfa_size = stat.size;
245 	zfattr->zfa_mode = stat.mode;
246 
247 	return (0);
248 }
249 
250 /*
251  * Sync file to disk
252  *
253  * filp - file pointer
254  * flags - O_SYNC and or O_DSYNC
255  *
256  * Returns 0 on success or error code of underlying sync call on failure.
257  */
258 int
zfs_file_fsync(zfs_file_t * filp,int flags)259 zfs_file_fsync(zfs_file_t *filp, int flags)
260 {
261 	int datasync = 0;
262 	int error;
263 
264 	if (flags & O_DSYNC)
265 		datasync = 1;
266 
267 	error = -vfs_fsync(filp, datasync);
268 
269 	return (error);
270 }
271 
272 /*
273  * deallocate - zero and/or deallocate file storage
274  *
275  * fp - file pointer
276  * offset - offset to start zeroing or deallocating
277  * len - length to zero or deallocate
278  */
279 int
zfs_file_deallocate(zfs_file_t * fp,loff_t offset,loff_t len)280 zfs_file_deallocate(zfs_file_t *fp, loff_t offset, loff_t len)
281 {
282 	/*
283 	 * When supported by the underlying file system preferentially
284 	 * use the fallocate() callback to preallocate the space.
285 	 */
286 	int error = EOPNOTSUPP;
287 	if (fp->f_op->fallocate)
288 		error = -fp->f_op->fallocate(fp,
289 		    FALLOC_FL_PUNCH_HOLE | FALLOC_FL_KEEP_SIZE, offset, len);
290 
291 	if (error)
292 		return (SET_ERROR(error));
293 
294 	return (0);
295 }
296 
297 /*
298  * Request current file pointer offset
299  *
300  * fp - pointer to file
301  *
302  * Returns current file offset.
303  */
304 loff_t
zfs_file_off(zfs_file_t * fp)305 zfs_file_off(zfs_file_t *fp)
306 {
307 	return (fp->f_pos);
308 }
309 
310 /*
311  * Request file pointer private data
312  *
313  * fp - pointer to file
314  *
315  * Returns pointer to file private data.
316  */
317 void *
zfs_file_private(zfs_file_t * fp)318 zfs_file_private(zfs_file_t *fp)
319 {
320 	return (fp->private_data);
321 }
322 
323 /*
324  * unlink file
325  *
326  * path - fully qualified file path
327  *
328  * Returns 0 on success.
329  *
330  * OPTIONAL
331  */
332 int
zfs_file_unlink(const char * path)333 zfs_file_unlink(const char *path)
334 {
335 	return (EOPNOTSUPP);
336 }
337 
338 /*
339  * Get reference to file pointer
340  *
341  * fd - input file descriptor
342  *
343  * Returns pointer to file struct or NULL
344  */
345 zfs_file_t *
zfs_file_get(int fd)346 zfs_file_get(int fd)
347 {
348 	return (fget(fd));
349 }
350 
351 /*
352  * Drop reference to file pointer
353  *
354  * fp - input file struct pointer
355  */
356 void
zfs_file_put(zfs_file_t * fp)357 zfs_file_put(zfs_file_t *fp)
358 {
359 	fput(fp);
360 }
361