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
zfs_file_open(const char * path,int flags,int mode,zfs_file_t ** fpp)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
zfs_file_close(zfs_file_t * fp)67 zfs_file_close(zfs_file_t *fp)
68 {
69 	filp_close(fp, 0);
70 }
71 
72 static ssize_t
zfs_file_write_impl(zfs_file_t * fp,const void * buf,size_t count,loff_t * off)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
zfs_file_write(zfs_file_t * fp,const void * buf,size_t count,ssize_t * resid)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
zfs_file_pwrite(zfs_file_t * fp,const void * buf,size_t count,loff_t off,ssize_t * resid)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
zfs_file_read_impl(zfs_file_t * fp,void * buf,size_t count,loff_t * off)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
zfs_file_read(zfs_file_t * fp,void * buf,size_t count,ssize_t * resid)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
zfs_file_pread(zfs_file_t * fp,void * buf,size_t count,loff_t off,ssize_t * resid)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
zfs_file_seek(zfs_file_t * fp,loff_t * offp,int whence)245 zfs_file_seek(zfs_file_t *fp, loff_t *offp, int whence)
246 {
247 	loff_t rc;
248 
249 	if (*offp < 0)
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
zfs_file_getattr(zfs_file_t * filp,zfs_file_attr_t * zfattr)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 #elif defined(HAVE_3ARGS_VFS_GETATTR)
283 	rc = vfs_getattr(filp->f_path.mnt, filp->f_dentry, &stat);
284 #else
285 #error "No available vfs_getattr()"
286 #endif
287 	if (rc)
288 		return (-rc);
289 
290 	zfattr->zfa_size = stat.size;
291 	zfattr->zfa_mode = stat.mode;
292 
293 	return (0);
294 }
295 
296 /*
297  * Sync file to disk
298  *
299  * filp - file pointer
300  * flags - O_SYNC and or O_DSYNC
301  *
302  * Returns 0 on success or error code of underlying sync call on failure.
303  */
304 int
zfs_file_fsync(zfs_file_t * filp,int flags)305 zfs_file_fsync(zfs_file_t *filp, int flags)
306 {
307 	int datasync = 0;
308 	int error;
309 	int fstrans;
310 
311 	if (flags & O_DSYNC)
312 		datasync = 1;
313 
314 	/*
315 	 * May enter XFS which generates a warning when PF_FSTRANS is set.
316 	 * To avoid this the flag is cleared over vfs_sync() and then reset.
317 	 */
318 	fstrans = __spl_pf_fstrans_check();
319 	if (fstrans)
320 		current->flags &= ~(__SPL_PF_FSTRANS);
321 
322 	error = -vfs_fsync(filp, datasync);
323 
324 	if (fstrans)
325 		current->flags |= __SPL_PF_FSTRANS;
326 
327 	return (error);
328 }
329 
330 /*
331  * fallocate - allocate or free space on disk
332  *
333  * fp - file pointer
334  * mode (non-standard options for hole punching etc)
335  * offset - offset to start allocating or freeing from
336  * len - length to free / allocate
337  *
338  * OPTIONAL
339  */
340 int
zfs_file_fallocate(zfs_file_t * fp,int mode,loff_t offset,loff_t len)341 zfs_file_fallocate(zfs_file_t *fp, int mode, loff_t offset, loff_t len)
342 {
343 	/*
344 	 * May enter XFS which generates a warning when PF_FSTRANS is set.
345 	 * To avoid this the flag is cleared over vfs_sync() and then reset.
346 	 */
347 	int fstrans = __spl_pf_fstrans_check();
348 	if (fstrans)
349 		current->flags &= ~(__SPL_PF_FSTRANS);
350 
351 	/*
352 	 * When supported by the underlying file system preferentially
353 	 * use the fallocate() callback to preallocate the space.
354 	 */
355 	int error = EOPNOTSUPP;
356 	if (fp->f_op->fallocate)
357 		error = fp->f_op->fallocate(fp, mode, offset, len);
358 
359 	if (fstrans)
360 		current->flags |= __SPL_PF_FSTRANS;
361 
362 	return (error);
363 }
364 
365 /*
366  * Request current file pointer offset
367  *
368  * fp - pointer to file
369  *
370  * Returns current file offset.
371  */
372 loff_t
zfs_file_off(zfs_file_t * fp)373 zfs_file_off(zfs_file_t *fp)
374 {
375 	return (fp->f_pos);
376 }
377 
378 /*
379  * Request file pointer private data
380  *
381  * fp - pointer to file
382  *
383  * Returns pointer to file private data.
384  */
385 void *
zfs_file_private(zfs_file_t * fp)386 zfs_file_private(zfs_file_t *fp)
387 {
388 	return (fp->private_data);
389 }
390 
391 /*
392  * unlink file
393  *
394  * path - fully qualified file path
395  *
396  * Returns 0 on success.
397  *
398  * OPTIONAL
399  */
400 int
zfs_file_unlink(const char * path)401 zfs_file_unlink(const char *path)
402 {
403 	return (EOPNOTSUPP);
404 }
405 
406 /*
407  * Get reference to file pointer
408  *
409  * fd - input file descriptor
410  *
411  * Returns pointer to file struct or NULL
412  */
413 zfs_file_t *
zfs_file_get(int fd)414 zfs_file_get(int fd)
415 {
416 	return (fget(fd));
417 }
418 
419 /*
420  * Drop reference to file pointer
421  *
422  * fp - input file struct pointer
423  */
424 void
zfs_file_put(zfs_file_t * fp)425 zfs_file_put(zfs_file_t *fp)
426 {
427 	fput(fp);
428 }
429