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(¤t->fs->umask, 0);
54
55 filp = filp_open(path, flags, mode);
56
57 if (flags & O_CREAT)
58 (void) xchg(¤t->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