1 | // SPDX-License-Identifier: GPL-2.0 |
2 | /* |
3 | * linux/fs/nfs/file.c |
4 | * |
5 | * Copyright (C) 1992 Rick Sladkey |
6 | */ |
7 | #include <linux/fs.h> |
8 | #include <linux/file.h> |
9 | #include <linux/falloc.h> |
10 | #include <linux/mount.h> |
11 | #include <linux/nfs_fs.h> |
12 | #include <linux/nfs_ssc.h> |
13 | #include "delegation.h" |
14 | #include "internal.h" |
15 | #include "iostat.h" |
16 | #include "fscache.h" |
17 | #include "pnfs.h" |
18 | |
19 | #include "nfstrace.h" |
20 | |
21 | #ifdef CONFIG_NFS_V4_2 |
22 | #include "nfs42.h" |
23 | #endif |
24 | |
25 | #define NFSDBG_FACILITY NFSDBG_FILE |
26 | |
27 | static int |
28 | nfs4_file_open(struct inode *inode, struct file *filp) |
29 | { |
30 | struct nfs_open_context *ctx; |
31 | struct dentry *dentry = file_dentry(file: filp); |
32 | struct dentry *parent = NULL; |
33 | struct inode *dir; |
34 | unsigned openflags = filp->f_flags; |
35 | struct iattr attr; |
36 | int err; |
37 | |
38 | /* |
39 | * If no cached dentry exists or if it's negative, NFSv4 handled the |
40 | * opens in ->lookup() or ->create(). |
41 | * |
42 | * We only get this far for a cached positive dentry. We skipped |
43 | * revalidation, so handle it here by dropping the dentry and returning |
44 | * -EOPENSTALE. The VFS will retry the lookup/create/open. |
45 | */ |
46 | |
47 | dprintk("NFS: open file(%pd2)\n" , dentry); |
48 | |
49 | err = nfs_check_flags(openflags); |
50 | if (err) |
51 | return err; |
52 | |
53 | /* We can't create new files here */ |
54 | openflags &= ~(O_CREAT|O_EXCL); |
55 | |
56 | parent = dget_parent(dentry); |
57 | dir = d_inode(dentry: parent); |
58 | |
59 | ctx = alloc_nfs_open_context(dentry: file_dentry(file: filp), |
60 | f_mode: flags_to_mode(flags: openflags), filp); |
61 | err = PTR_ERR(ptr: ctx); |
62 | if (IS_ERR(ptr: ctx)) |
63 | goto out; |
64 | |
65 | attr.ia_valid = ATTR_OPEN; |
66 | if (openflags & O_TRUNC) { |
67 | attr.ia_valid |= ATTR_SIZE; |
68 | attr.ia_size = 0; |
69 | filemap_write_and_wait(mapping: inode->i_mapping); |
70 | } |
71 | |
72 | inode = NFS_PROTO(inode: dir)->open_context(dir, ctx, openflags, &attr, NULL); |
73 | if (IS_ERR(ptr: inode)) { |
74 | err = PTR_ERR(ptr: inode); |
75 | switch (err) { |
76 | default: |
77 | goto out_put_ctx; |
78 | case -ENOENT: |
79 | case -ESTALE: |
80 | case -EISDIR: |
81 | case -ENOTDIR: |
82 | case -ELOOP: |
83 | goto out_drop; |
84 | } |
85 | } |
86 | if (inode != d_inode(dentry)) |
87 | goto out_drop; |
88 | |
89 | nfs_file_set_open_context(filp, ctx); |
90 | nfs_fscache_open_file(inode, filp); |
91 | err = 0; |
92 | filp->f_mode |= FMODE_CAN_ODIRECT; |
93 | |
94 | out_put_ctx: |
95 | put_nfs_open_context(ctx); |
96 | out: |
97 | dput(parent); |
98 | return err; |
99 | |
100 | out_drop: |
101 | d_drop(dentry); |
102 | err = -EOPENSTALE; |
103 | goto out_put_ctx; |
104 | } |
105 | |
106 | /* |
107 | * Flush all dirty pages, and check for write errors. |
108 | */ |
109 | static int |
110 | nfs4_file_flush(struct file *file, fl_owner_t id) |
111 | { |
112 | struct inode *inode = file_inode(f: file); |
113 | errseq_t since; |
114 | |
115 | dprintk("NFS: flush(%pD2)\n" , file); |
116 | |
117 | nfs_inc_stats(inode, stat: NFSIOS_VFSFLUSH); |
118 | if ((file->f_mode & FMODE_WRITE) == 0) |
119 | return 0; |
120 | |
121 | /* |
122 | * If we're holding a write delegation, then check if we're required |
123 | * to flush the i/o on close. If not, then just start the i/o now. |
124 | */ |
125 | if (!nfs4_delegation_flush_on_close(inode)) |
126 | return filemap_fdatawrite(file->f_mapping); |
127 | |
128 | /* Flush writes to the server and return any errors */ |
129 | since = filemap_sample_wb_err(mapping: file->f_mapping); |
130 | nfs_wb_all(inode); |
131 | return filemap_check_wb_err(mapping: file->f_mapping, since); |
132 | } |
133 | |
134 | #ifdef CONFIG_NFS_V4_2 |
135 | static ssize_t __nfs4_copy_file_range(struct file *file_in, loff_t pos_in, |
136 | struct file *file_out, loff_t pos_out, |
137 | size_t count, unsigned int flags) |
138 | { |
139 | struct nfs42_copy_notify_res *cn_resp = NULL; |
140 | struct nl4_server *nss = NULL; |
141 | nfs4_stateid *cnrs = NULL; |
142 | ssize_t ret; |
143 | bool sync = false; |
144 | |
145 | /* Only offload copy if superblock is the same */ |
146 | if (file_in->f_op != &nfs4_file_operations) |
147 | return -EXDEV; |
148 | if (!nfs_server_capable(inode: file_inode(f: file_out), NFS_CAP_COPY) || |
149 | !nfs_server_capable(inode: file_inode(f: file_in), NFS_CAP_COPY)) |
150 | return -EOPNOTSUPP; |
151 | if (file_inode(f: file_in) == file_inode(f: file_out)) |
152 | return -EOPNOTSUPP; |
153 | /* if the copy size if smaller than 2 RPC payloads, make it |
154 | * synchronous |
155 | */ |
156 | if (count <= 2 * NFS_SERVER(inode: file_inode(f: file_in))->rsize) |
157 | sync = true; |
158 | retry: |
159 | if (!nfs42_files_from_same_server(in: file_in, out: file_out)) { |
160 | /* |
161 | * for inter copy, if copy size is too small |
162 | * then fallback to generic copy. |
163 | */ |
164 | if (sync) |
165 | return -EOPNOTSUPP; |
166 | cn_resp = kzalloc(size: sizeof(struct nfs42_copy_notify_res), |
167 | GFP_KERNEL); |
168 | if (unlikely(cn_resp == NULL)) |
169 | return -ENOMEM; |
170 | |
171 | ret = nfs42_proc_copy_notify(file_in, file_out, cn_resp); |
172 | if (ret) { |
173 | ret = -EOPNOTSUPP; |
174 | goto out; |
175 | } |
176 | nss = &cn_resp->cnr_src; |
177 | cnrs = &cn_resp->cnr_stateid; |
178 | } |
179 | ret = nfs42_proc_copy(file_in, pos_in, file_out, pos_out, count, |
180 | nss, cnrs, sync); |
181 | out: |
182 | kfree(objp: cn_resp); |
183 | |
184 | if (ret == -EAGAIN) |
185 | goto retry; |
186 | return ret; |
187 | } |
188 | |
189 | static ssize_t nfs4_copy_file_range(struct file *file_in, loff_t pos_in, |
190 | struct file *file_out, loff_t pos_out, |
191 | size_t count, unsigned int flags) |
192 | { |
193 | ssize_t ret; |
194 | |
195 | ret = __nfs4_copy_file_range(file_in, pos_in, file_out, pos_out, count, |
196 | flags); |
197 | if (ret == -EOPNOTSUPP || ret == -EXDEV) |
198 | ret = generic_copy_file_range(file_in, pos_in, file_out, |
199 | pos_out, len: count, flags); |
200 | return ret; |
201 | } |
202 | |
203 | static loff_t nfs4_file_llseek(struct file *filep, loff_t offset, int whence) |
204 | { |
205 | loff_t ret; |
206 | |
207 | switch (whence) { |
208 | case SEEK_HOLE: |
209 | case SEEK_DATA: |
210 | ret = nfs42_proc_llseek(filep, offset, whence); |
211 | if (ret != -EOPNOTSUPP) |
212 | return ret; |
213 | fallthrough; |
214 | default: |
215 | return nfs_file_llseek(filep, offset, whence); |
216 | } |
217 | } |
218 | |
219 | static long nfs42_fallocate(struct file *filep, int mode, loff_t offset, loff_t len) |
220 | { |
221 | struct inode *inode = file_inode(f: filep); |
222 | long ret; |
223 | |
224 | if (!S_ISREG(inode->i_mode)) |
225 | return -EOPNOTSUPP; |
226 | |
227 | if ((mode != 0) && (mode != (FALLOC_FL_PUNCH_HOLE | FALLOC_FL_KEEP_SIZE))) |
228 | return -EOPNOTSUPP; |
229 | |
230 | ret = inode_newsize_ok(inode, offset: offset + len); |
231 | if (ret < 0) |
232 | return ret; |
233 | |
234 | if (mode & FALLOC_FL_PUNCH_HOLE) |
235 | return nfs42_proc_deallocate(filep, offset, len); |
236 | return nfs42_proc_allocate(filep, offset, len); |
237 | } |
238 | |
239 | static loff_t nfs42_remap_file_range(struct file *src_file, loff_t src_off, |
240 | struct file *dst_file, loff_t dst_off, loff_t count, |
241 | unsigned int remap_flags) |
242 | { |
243 | struct inode *dst_inode = file_inode(f: dst_file); |
244 | struct nfs_server *server = NFS_SERVER(inode: dst_inode); |
245 | struct inode *src_inode = file_inode(f: src_file); |
246 | unsigned int bs = server->clone_blksize; |
247 | bool same_inode = false; |
248 | int ret; |
249 | |
250 | /* NFS does not support deduplication. */ |
251 | if (remap_flags & REMAP_FILE_DEDUP) |
252 | return -EOPNOTSUPP; |
253 | |
254 | if (remap_flags & ~REMAP_FILE_ADVISORY) |
255 | return -EINVAL; |
256 | |
257 | if (IS_SWAPFILE(dst_inode) || IS_SWAPFILE(src_inode)) |
258 | return -ETXTBSY; |
259 | |
260 | /* check alignment w.r.t. clone_blksize */ |
261 | ret = -EINVAL; |
262 | if (bs) { |
263 | if (!IS_ALIGNED(src_off, bs) || !IS_ALIGNED(dst_off, bs)) |
264 | goto out; |
265 | if (!IS_ALIGNED(count, bs) && i_size_read(inode: src_inode) != (src_off + count)) |
266 | goto out; |
267 | } |
268 | |
269 | if (src_inode == dst_inode) |
270 | same_inode = true; |
271 | |
272 | /* XXX: do we lock at all? what if server needs CB_RECALL_LAYOUT? */ |
273 | if (same_inode) { |
274 | inode_lock(inode: src_inode); |
275 | } else if (dst_inode < src_inode) { |
276 | inode_lock_nested(inode: dst_inode, subclass: I_MUTEX_PARENT); |
277 | inode_lock_nested(inode: src_inode, subclass: I_MUTEX_CHILD); |
278 | } else { |
279 | inode_lock_nested(inode: src_inode, subclass: I_MUTEX_PARENT); |
280 | inode_lock_nested(inode: dst_inode, subclass: I_MUTEX_CHILD); |
281 | } |
282 | |
283 | /* flush all pending writes on both src and dst so that server |
284 | * has the latest data */ |
285 | ret = nfs_sync_inode(inode: src_inode); |
286 | if (ret) |
287 | goto out_unlock; |
288 | ret = nfs_sync_inode(inode: dst_inode); |
289 | if (ret) |
290 | goto out_unlock; |
291 | |
292 | ret = nfs42_proc_clone(src_file, dst_file, src_off, dst_off, count); |
293 | |
294 | /* truncate inode page cache of the dst range so that future reads can fetch |
295 | * new data from server */ |
296 | if (!ret) |
297 | truncate_inode_pages_range(&dst_inode->i_data, lstart: dst_off, lend: dst_off + count - 1); |
298 | |
299 | out_unlock: |
300 | if (same_inode) { |
301 | inode_unlock(inode: src_inode); |
302 | } else if (dst_inode < src_inode) { |
303 | inode_unlock(inode: src_inode); |
304 | inode_unlock(inode: dst_inode); |
305 | } else { |
306 | inode_unlock(inode: dst_inode); |
307 | inode_unlock(inode: src_inode); |
308 | } |
309 | out: |
310 | return ret < 0 ? ret : count; |
311 | } |
312 | |
313 | static int read_name_gen = 1; |
314 | #define SSC_READ_NAME_BODY "ssc_read_%d" |
315 | |
316 | static struct file *__nfs42_ssc_open(struct vfsmount *ss_mnt, |
317 | struct nfs_fh *src_fh, nfs4_stateid *stateid) |
318 | { |
319 | struct nfs_fattr *fattr = nfs_alloc_fattr(); |
320 | struct file *filep, *res; |
321 | struct nfs_server *server; |
322 | struct inode *r_ino = NULL; |
323 | struct nfs_open_context *ctx; |
324 | struct nfs4_state_owner *sp; |
325 | char *read_name = NULL; |
326 | int len, status = 0; |
327 | |
328 | server = NFS_SB(s: ss_mnt->mnt_sb); |
329 | |
330 | if (!fattr) |
331 | return ERR_PTR(error: -ENOMEM); |
332 | |
333 | status = nfs4_proc_getattr(server, fhandle: src_fh, fattr, NULL); |
334 | if (status < 0) { |
335 | res = ERR_PTR(error: status); |
336 | goto out; |
337 | } |
338 | |
339 | if (!S_ISREG(fattr->mode)) { |
340 | res = ERR_PTR(error: -EBADF); |
341 | goto out; |
342 | } |
343 | |
344 | res = ERR_PTR(error: -ENOMEM); |
345 | len = strlen(SSC_READ_NAME_BODY) + 16; |
346 | read_name = kzalloc(size: len, GFP_KERNEL); |
347 | if (read_name == NULL) |
348 | goto out; |
349 | snprintf(buf: read_name, size: len, SSC_READ_NAME_BODY, read_name_gen++); |
350 | |
351 | r_ino = nfs_fhget(ss_mnt->mnt_sb, src_fh, fattr); |
352 | if (IS_ERR(ptr: r_ino)) { |
353 | res = ERR_CAST(ptr: r_ino); |
354 | goto out_free_name; |
355 | } |
356 | |
357 | filep = alloc_file_pseudo(r_ino, ss_mnt, read_name, O_RDONLY, |
358 | r_ino->i_fop); |
359 | if (IS_ERR(ptr: filep)) { |
360 | res = ERR_CAST(ptr: filep); |
361 | iput(r_ino); |
362 | goto out_free_name; |
363 | } |
364 | |
365 | ctx = alloc_nfs_open_context(dentry: filep->f_path.dentry, |
366 | f_mode: flags_to_mode(flags: filep->f_flags), filp: filep); |
367 | if (IS_ERR(ptr: ctx)) { |
368 | res = ERR_CAST(ptr: ctx); |
369 | goto out_filep; |
370 | } |
371 | |
372 | res = ERR_PTR(error: -EINVAL); |
373 | sp = nfs4_get_state_owner(server, ctx->cred, GFP_KERNEL); |
374 | if (sp == NULL) |
375 | goto out_ctx; |
376 | |
377 | ctx->state = nfs4_get_open_state(r_ino, sp); |
378 | if (ctx->state == NULL) |
379 | goto out_stateowner; |
380 | |
381 | set_bit(nr: NFS_SRV_SSC_COPY_STATE, addr: &ctx->state->flags); |
382 | memcpy(&ctx->state->open_stateid.other, &stateid->other, |
383 | NFS4_STATEID_OTHER_SIZE); |
384 | update_open_stateid(state: ctx->state, open_stateid: stateid, NULL, fmode: filep->f_mode); |
385 | set_bit(nr: NFS_OPEN_STATE, addr: &ctx->state->flags); |
386 | |
387 | nfs_file_set_open_context(filp: filep, ctx); |
388 | put_nfs_open_context(ctx); |
389 | |
390 | file_ra_state_init(ra: &filep->f_ra, mapping: filep->f_mapping->host->i_mapping); |
391 | res = filep; |
392 | out_free_name: |
393 | kfree(objp: read_name); |
394 | out: |
395 | nfs_free_fattr(fattr); |
396 | return res; |
397 | out_stateowner: |
398 | nfs4_put_state_owner(sp); |
399 | out_ctx: |
400 | put_nfs_open_context(ctx); |
401 | out_filep: |
402 | fput(filep); |
403 | goto out_free_name; |
404 | } |
405 | |
406 | static void __nfs42_ssc_close(struct file *filep) |
407 | { |
408 | struct nfs_open_context *ctx = nfs_file_open_context(filp: filep); |
409 | |
410 | ctx->state->flags = 0; |
411 | } |
412 | |
413 | static const struct nfs4_ssc_client_ops nfs4_ssc_clnt_ops_tbl = { |
414 | .sco_open = __nfs42_ssc_open, |
415 | .sco_close = __nfs42_ssc_close, |
416 | }; |
417 | |
418 | /** |
419 | * nfs42_ssc_register_ops - Wrapper to register NFS_V4 ops in nfs_common |
420 | * |
421 | * Return values: |
422 | * None |
423 | */ |
424 | void nfs42_ssc_register_ops(void) |
425 | { |
426 | nfs42_ssc_register(ops: &nfs4_ssc_clnt_ops_tbl); |
427 | } |
428 | |
429 | /** |
430 | * nfs42_ssc_unregister_ops - wrapper to un-register NFS_V4 ops in nfs_common |
431 | * |
432 | * Return values: |
433 | * None. |
434 | */ |
435 | void nfs42_ssc_unregister_ops(void) |
436 | { |
437 | nfs42_ssc_unregister(ops: &nfs4_ssc_clnt_ops_tbl); |
438 | } |
439 | #endif /* CONFIG_NFS_V4_2 */ |
440 | |
441 | static int nfs4_setlease(struct file *file, int arg, struct file_lock **lease, |
442 | void **priv) |
443 | { |
444 | return nfs4_proc_setlease(file, arg, lease, priv); |
445 | } |
446 | |
447 | const struct file_operations nfs4_file_operations = { |
448 | .read_iter = nfs_file_read, |
449 | .write_iter = nfs_file_write, |
450 | .mmap = nfs_file_mmap, |
451 | .open = nfs4_file_open, |
452 | .flush = nfs4_file_flush, |
453 | .release = nfs_file_release, |
454 | .fsync = nfs_file_fsync, |
455 | .lock = nfs_lock, |
456 | .flock = nfs_flock, |
457 | .splice_read = nfs_file_splice_read, |
458 | .splice_write = iter_file_splice_write, |
459 | .check_flags = nfs_check_flags, |
460 | .setlease = nfs4_setlease, |
461 | #ifdef CONFIG_NFS_V4_2 |
462 | .copy_file_range = nfs4_copy_file_range, |
463 | .llseek = nfs4_file_llseek, |
464 | .fallocate = nfs42_fallocate, |
465 | .remap_file_range = nfs42_remap_file_range, |
466 | #else |
467 | .llseek = nfs_file_llseek, |
468 | #endif |
469 | }; |
470 | |