Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux
1
fork

Configure Feed

Select the types of activity you want to include in your feed.

Merge tag 'nfs-for-6.10-1' of git://git.linux-nfs.org/projects/trondmy/linux-nfs

Pull NFS client updates from Trond Myklebust:
"Stable fixes:
- nfs: fix undefined behavior in nfs_block_bits()
- NFSv4.2: Fix READ_PLUS when server doesn't support OP_READ_PLUS

Bugfixes:
- Fix mixing of the lock/nolock and local_lock mount options
- NFSv4: Fixup smatch warning for ambiguous return
- NFSv3: Fix remount when using the legacy binary mount api
- SUNRPC: Fix the handling of expired RPCSEC_GSS contexts
- SUNRPC: fix the NFSACL RPC retries when soft mounts are enabled
- rpcrdma: fix handling for RDMA_CM_EVENT_DEVICE_REMOVAL

Features and cleanups:
- NFSv3: Use the atomic_open API to fix open(O_CREAT|O_TRUNC)
- pNFS/filelayout: S layout segment range in LAYOUTGET
- pNFS: rework pnfs_generic_pg_check_layout to check IO range
- NFSv2: Turn off enabling of NFS v2 by default"

* tag 'nfs-for-6.10-1' of git://git.linux-nfs.org/projects/trondmy/linux-nfs:
nfs: fix undefined behavior in nfs_block_bits()
pNFS: rework pnfs_generic_pg_check_layout to check IO range
pNFS/filelayout: check layout segment range
pNFS/filelayout: fixup pNfs allocation modes
rpcrdma: fix handling for RDMA_CM_EVENT_DEVICE_REMOVAL
NFS: Don't enable NFS v2 by default
NFS: Fix READ_PLUS when server doesn't support OP_READ_PLUS
sunrpc: fix NFSACL RPC retry on soft mount
SUNRPC: fix handling expired GSS context
nfs: keep server info for remounts
NFSv4: Fixup smatch warning for ambiguous return
NFS: make sure lock/nolock overriding local_lock mount option
NFS: add atomic_open for NFSv3 to handle O_TRUNC correctly.
pNFS/filelayout: Specify the layout segment range in LAYOUTGET
pNFS/filelayout: Remove the whole file layout requirement

+129 -68
+2 -2
fs/nfs/Kconfig
··· 33 33 config NFS_V2 34 34 tristate "NFS client support for NFS version 2" 35 35 depends on NFS_FS 36 - default y 36 + default n 37 37 help 38 38 This option enables support for version 2 of the NFS protocol 39 39 (RFC 1094) in the kernel's NFS client. 40 40 41 - If unsure, say Y. 41 + If unsure, say N. 42 42 43 43 config NFS_V3 44 44 tristate "NFS client support for NFS version 3"
+51 -3
fs/nfs/dir.c
··· 56 56 static int nfs_fsync_dir(struct file *, loff_t, loff_t, int); 57 57 static loff_t nfs_llseek_dir(struct file *, loff_t, int); 58 58 static void nfs_readdir_clear_array(struct folio *); 59 + static int nfs_do_create(struct inode *dir, struct dentry *dentry, 60 + umode_t mode, int open_flags); 59 61 60 62 const struct file_operations nfs_dir_operations = { 61 63 .llseek = nfs_llseek_dir, ··· 2245 2243 2246 2244 #endif /* CONFIG_NFSV4 */ 2247 2245 2246 + int nfs_atomic_open_v23(struct inode *dir, struct dentry *dentry, 2247 + struct file *file, unsigned int open_flags, 2248 + umode_t mode) 2249 + { 2250 + 2251 + /* Same as look+open from lookup_open(), but with different O_TRUNC 2252 + * handling. 2253 + */ 2254 + int error = 0; 2255 + 2256 + if (open_flags & O_CREAT) { 2257 + file->f_mode |= FMODE_CREATED; 2258 + error = nfs_do_create(dir, dentry, mode, open_flags); 2259 + if (error) 2260 + return error; 2261 + return finish_open(file, dentry, NULL); 2262 + } else if (d_in_lookup(dentry)) { 2263 + /* The only flags nfs_lookup considers are 2264 + * LOOKUP_EXCL and LOOKUP_RENAME_TARGET, and 2265 + * we want those to be zero so the lookup isn't skipped. 2266 + */ 2267 + struct dentry *res = nfs_lookup(dir, dentry, 0); 2268 + 2269 + d_lookup_done(dentry); 2270 + if (unlikely(res)) { 2271 + if (IS_ERR(res)) 2272 + return PTR_ERR(res); 2273 + return finish_no_open(file, res); 2274 + } 2275 + } 2276 + return finish_no_open(file, NULL); 2277 + 2278 + } 2279 + EXPORT_SYMBOL_GPL(nfs_atomic_open_v23); 2280 + 2248 2281 struct dentry * 2249 2282 nfs_add_or_obtain(struct dentry *dentry, struct nfs_fh *fhandle, 2250 2283 struct nfs_fattr *fattr) ··· 2340 2303 * that the operation succeeded on the server, but an error in the 2341 2304 * reply path made it appear to have failed. 2342 2305 */ 2343 - int nfs_create(struct mnt_idmap *idmap, struct inode *dir, 2344 - struct dentry *dentry, umode_t mode, bool excl) 2306 + static int nfs_do_create(struct inode *dir, struct dentry *dentry, 2307 + umode_t mode, int open_flags) 2345 2308 { 2346 2309 struct iattr attr; 2347 - int open_flags = excl ? O_CREAT | O_EXCL : O_CREAT; 2348 2310 int error; 2311 + 2312 + open_flags |= O_CREAT; 2349 2313 2350 2314 dfprintk(VFS, "NFS: create(%s/%lu), %pd\n", 2351 2315 dir->i_sb->s_id, dir->i_ino, dentry); 2352 2316 2353 2317 attr.ia_mode = mode; 2354 2318 attr.ia_valid = ATTR_MODE; 2319 + if (open_flags & O_TRUNC) { 2320 + attr.ia_size = 0; 2321 + attr.ia_valid |= ATTR_SIZE; 2322 + } 2355 2323 2356 2324 trace_nfs_create_enter(dir, dentry, open_flags); 2357 2325 error = NFS_PROTO(dir)->create(dir, dentry, &attr, open_flags); ··· 2367 2325 out_err: 2368 2326 d_drop(dentry); 2369 2327 return error; 2328 + } 2329 + 2330 + int nfs_create(struct mnt_idmap *idmap, struct inode *dir, 2331 + struct dentry *dentry, umode_t mode, bool excl) 2332 + { 2333 + return nfs_do_create(dir, dentry, mode, excl ? O_EXCL : 0); 2370 2334 } 2371 2335 EXPORT_SYMBOL_GPL(nfs_create); 2372 2336
+8 -16
fs/nfs/filelayout/filelayout.c
··· 605 605 606 606 dprintk("--> %s\n", __func__); 607 607 608 - /* FIXME: remove this check when layout segment support is added */ 609 - if (lgr->range.offset != 0 || 610 - lgr->range.length != NFS4_MAX_UINT64) { 611 - dprintk("%s Only whole file layouts supported. Use MDS i/o\n", 612 - __func__); 613 - goto out; 614 - } 615 - 616 608 if (fl->pattern_offset > lgr->range.offset) { 617 609 dprintk("%s pattern_offset %lld too large\n", 618 610 __func__, fl->pattern_offset); ··· 867 875 filelayout_pg_init_read(struct nfs_pageio_descriptor *pgio, 868 876 struct nfs_page *req) 869 877 { 870 - pnfs_generic_pg_check_layout(pgio); 878 + pnfs_generic_pg_check_layout(pgio, req); 871 879 if (!pgio->pg_lseg) { 872 880 pgio->pg_lseg = fl_pnfs_update_layout(pgio->pg_inode, 873 881 nfs_req_openctx(req), 874 - 0, 875 - NFS4_MAX_UINT64, 882 + req_offset(req), 883 + req->wb_bytes, 876 884 IOMODE_READ, 877 885 false, 878 - GFP_KERNEL); 886 + nfs_io_gfp_mask()); 879 887 if (IS_ERR(pgio->pg_lseg)) { 880 888 pgio->pg_error = PTR_ERR(pgio->pg_lseg); 881 889 pgio->pg_lseg = NULL; ··· 891 899 filelayout_pg_init_write(struct nfs_pageio_descriptor *pgio, 892 900 struct nfs_page *req) 893 901 { 894 - pnfs_generic_pg_check_layout(pgio); 902 + pnfs_generic_pg_check_layout(pgio, req); 895 903 if (!pgio->pg_lseg) { 896 904 pgio->pg_lseg = fl_pnfs_update_layout(pgio->pg_inode, 897 905 nfs_req_openctx(req), 898 - 0, 899 - NFS4_MAX_UINT64, 906 + req_offset(req), 907 + req->wb_bytes, 900 908 IOMODE_RW, 901 909 false, 902 - GFP_NOFS); 910 + nfs_io_gfp_mask()); 903 911 if (IS_ERR(pgio->pg_lseg)) { 904 912 pgio->pg_error = PTR_ERR(pgio->pg_lseg); 905 913 pgio->pg_lseg = NULL;
+2 -10
fs/nfs/flexfilelayout/flexfilelayout.c
··· 823 823 } 824 824 825 825 static void 826 - ff_layout_pg_check_layout(struct nfs_pageio_descriptor *pgio, 827 - struct nfs_page *req) 828 - { 829 - pnfs_generic_pg_check_layout(pgio); 830 - pnfs_generic_pg_check_range(pgio, req); 831 - } 832 - 833 - static void 834 826 ff_layout_pg_init_read(struct nfs_pageio_descriptor *pgio, 835 827 struct nfs_page *req) 836 828 { ··· 832 840 u32 ds_idx; 833 841 834 842 retry: 835 - ff_layout_pg_check_layout(pgio, req); 843 + pnfs_generic_pg_check_layout(pgio, req); 836 844 /* Use full layout for now */ 837 845 if (!pgio->pg_lseg) { 838 846 ff_layout_pg_get_read(pgio, req, false); ··· 887 895 u32 i; 888 896 889 897 retry: 890 - ff_layout_pg_check_layout(pgio, req); 898 + pnfs_generic_pg_check_layout(pgio, req); 891 899 if (!pgio->pg_lseg) { 892 900 pgio->pg_lseg = 893 901 pnfs_update_layout(pgio->pg_inode, nfs_req_openctx(req),
+8 -3
fs/nfs/fs_context.c
··· 600 600 break; 601 601 case Opt_lock: 602 602 if (result.negated) { 603 + ctx->lock_status = NFS_LOCK_NOLOCK; 603 604 ctx->flags |= NFS_MOUNT_NONLM; 604 605 ctx->flags |= (NFS_MOUNT_LOCAL_FLOCK | NFS_MOUNT_LOCAL_FCNTL); 605 606 } else { 607 + ctx->lock_status = NFS_LOCK_LOCK; 606 608 ctx->flags &= ~NFS_MOUNT_NONLM; 607 609 ctx->flags &= ~(NFS_MOUNT_LOCAL_FLOCK | NFS_MOUNT_LOCAL_FCNTL); 608 610 } ··· 1114 1112 ctx->acdirmax = data->acdirmax; 1115 1113 ctx->need_mount = false; 1116 1114 1117 - memcpy(sap, &data->addr, sizeof(data->addr)); 1118 - ctx->nfs_server.addrlen = sizeof(data->addr); 1119 - ctx->nfs_server.port = ntohs(data->addr.sin_port); 1115 + if (!is_remount_fc(fc)) { 1116 + memcpy(sap, &data->addr, sizeof(data->addr)); 1117 + ctx->nfs_server.addrlen = sizeof(data->addr); 1118 + ctx->nfs_server.port = ntohs(data->addr.sin_port); 1119 + } 1120 + 1120 1121 if (sap->ss_family != AF_INET || 1121 1122 !nfs_verify_server_address(sap)) 1122 1123 goto out_no_address;
+9 -2
fs/nfs/internal.h
··· 112 112 unsigned short protofamily; 113 113 unsigned short mountfamily; 114 114 bool has_sec_mnt_opts; 115 + int lock_status; 115 116 116 117 struct { 117 118 union { ··· 152 151 struct nfs_fattr *fattr; 153 152 unsigned int inherited_bsize; 154 153 } clone_data; 154 + }; 155 + 156 + enum nfs_lock_status { 157 + NFS_LOCK_NOT_SET = 0, 158 + NFS_LOCK_LOCK = 1, 159 + NFS_LOCK_NOLOCK = 2, 155 160 }; 156 161 157 162 #define nfs_errorf(fc, fmt, ...) ((fc)->log.log ? \ ··· 717 710 if ((bsize & (bsize - 1)) || nrbitsp) { 718 711 unsigned char nrbits; 719 712 720 - for (nrbits = 31; nrbits && !(bsize & (1 << nrbits)); nrbits--) 713 + for (nrbits = 31; nrbits && !(bsize & (1UL << nrbits)); nrbits--) 721 714 ; 722 - bsize = 1 << nrbits; 715 + bsize = 1UL << nrbits; 723 716 if (nrbitsp) 724 717 *nrbitsp = nrbits; 725 718 }
+1
fs/nfs/nfs3proc.c
··· 986 986 987 987 static const struct inode_operations nfs3_dir_inode_operations = { 988 988 .create = nfs_create, 989 + .atomic_open = nfs_atomic_open_v23, 989 990 .lookup = nfs_lookup, 990 991 .link = nfs_link, 991 992 .unlink = nfs_unlink,
+1 -1
fs/nfs/nfs4proc.c
··· 5456 5456 struct rpc_message *msg = &task->tk_msg; 5457 5457 5458 5458 if (msg->rpc_proc == &nfs4_procedures[NFSPROC4_CLNT_READ_PLUS] && 5459 - server->caps & NFS_CAP_READ_PLUS && task->tk_status == -ENOTSUPP) { 5459 + task->tk_status == -ENOTSUPP) { 5460 5460 server->caps &= ~NFS_CAP_READ_PLUS; 5461 5461 msg->rpc_proc = &nfs4_procedures[NFSPROC4_CLNT_READ]; 5462 5462 rpc_restart_call_prepare(task);
+5 -7
fs/nfs/nfs4state.c
··· 2116 2116 { 2117 2117 struct nfs_client *clp = server->nfs_client; 2118 2118 struct nfs4_fs_locations *locations = NULL; 2119 + struct nfs_fattr *fattr; 2119 2120 struct inode *inode; 2120 2121 struct page *page; 2121 2122 int status, result; ··· 2126 2125 (unsigned long long)server->fsid.minor, 2127 2126 clp->cl_hostname); 2128 2127 2129 - result = 0; 2130 2128 page = alloc_page(GFP_KERNEL); 2131 2129 locations = kmalloc(sizeof(struct nfs4_fs_locations), GFP_KERNEL); 2132 - if (page == NULL || locations == NULL) { 2130 + fattr = nfs_alloc_fattr(); 2131 + if (page == NULL || locations == NULL || fattr == NULL) { 2133 2132 dprintk("<-- %s: no memory\n", __func__); 2134 - goto out; 2135 - } 2136 - locations->fattr = nfs_alloc_fattr(); 2137 - if (locations->fattr == NULL) { 2138 - dprintk("<-- %s: no memory\n", __func__); 2133 + result = 0; 2139 2134 goto out; 2140 2135 } 2141 2136 2137 + locations->fattr = fattr; 2142 2138 inode = d_inode(server->super->s_root); 2143 2139 result = nfs4_proc_get_locations(server, NFS_FH(inode), locations, 2144 2140 page, cred);
+9 -20
fs/nfs/pnfs.c
··· 2705 2705 &range); 2706 2706 } 2707 2707 2708 + /* Check if we have we have a valid layout but if there isn't an intersection 2709 + * between the request and the pgio->pg_lseg, put this pgio->pg_lseg away. 2710 + */ 2708 2711 void 2709 - pnfs_generic_pg_check_layout(struct nfs_pageio_descriptor *pgio) 2712 + pnfs_generic_pg_check_layout(struct nfs_pageio_descriptor *pgio, 2713 + struct nfs_page *req) 2710 2714 { 2711 2715 if (pgio->pg_lseg == NULL || 2712 - test_bit(NFS_LSEG_VALID, &pgio->pg_lseg->pls_flags)) 2716 + (test_bit(NFS_LSEG_VALID, &pgio->pg_lseg->pls_flags) && 2717 + pnfs_lseg_request_intersecting(pgio->pg_lseg, req))) 2713 2718 return; 2714 2719 pnfs_put_lseg(pgio->pg_lseg); 2715 2720 pgio->pg_lseg = NULL; 2716 2721 } 2717 2722 EXPORT_SYMBOL_GPL(pnfs_generic_pg_check_layout); 2718 2723 2719 - /* 2720 - * Check for any intersection between the request and the pgio->pg_lseg, 2721 - * and if none, put this pgio->pg_lseg away. 2722 - */ 2723 - void 2724 - pnfs_generic_pg_check_range(struct nfs_pageio_descriptor *pgio, struct nfs_page *req) 2725 - { 2726 - if (pgio->pg_lseg && !pnfs_lseg_request_intersecting(pgio->pg_lseg, req)) { 2727 - pnfs_put_lseg(pgio->pg_lseg); 2728 - pgio->pg_lseg = NULL; 2729 - } 2730 - } 2731 - EXPORT_SYMBOL_GPL(pnfs_generic_pg_check_range); 2732 - 2733 2724 void 2734 2725 pnfs_generic_pg_init_read(struct nfs_pageio_descriptor *pgio, struct nfs_page *req) 2735 2726 { 2736 2727 u64 rd_size; 2737 2728 2738 - pnfs_generic_pg_check_layout(pgio); 2739 - pnfs_generic_pg_check_range(pgio, req); 2729 + pnfs_generic_pg_check_layout(pgio, req); 2740 2730 if (pgio->pg_lseg == NULL) { 2741 2731 if (pgio->pg_dreq == NULL) 2742 2732 rd_size = i_size_read(pgio->pg_inode) - req_offset(req); ··· 2756 2766 pnfs_generic_pg_init_write(struct nfs_pageio_descriptor *pgio, 2757 2767 struct nfs_page *req, u64 wb_size) 2758 2768 { 2759 - pnfs_generic_pg_check_layout(pgio); 2760 - pnfs_generic_pg_check_range(pgio, req); 2769 + pnfs_generic_pg_check_layout(pgio, req); 2761 2770 if (pgio->pg_lseg == NULL) { 2762 2771 pgio->pg_lseg = 2763 2772 pnfs_update_layout(pgio->pg_inode, nfs_req_openctx(req),
+1 -2
fs/nfs/pnfs.h
··· 257 257 258 258 void set_pnfs_layoutdriver(struct nfs_server *, const struct nfs_fh *, struct nfs_fsinfo *); 259 259 void unset_pnfs_layoutdriver(struct nfs_server *); 260 - void pnfs_generic_pg_check_layout(struct nfs_pageio_descriptor *pgio); 261 - void pnfs_generic_pg_check_range(struct nfs_pageio_descriptor *pgio, struct nfs_page *req); 260 + void pnfs_generic_pg_check_layout(struct nfs_pageio_descriptor *pgio, struct nfs_page *req); 262 261 void pnfs_generic_pg_init_read(struct nfs_pageio_descriptor *, struct nfs_page *); 263 262 int pnfs_generic_pg_readpages(struct nfs_pageio_descriptor *desc); 264 263 void pnfs_generic_pg_init_write(struct nfs_pageio_descriptor *pgio,
+1
fs/nfs/proc.c
··· 695 695 static const struct inode_operations nfs_dir_inode_operations = { 696 696 .create = nfs_create, 697 697 .lookup = nfs_lookup, 698 + .atomic_open = nfs_atomic_open_v23, 698 699 .link = nfs_link, 699 700 .unlink = nfs_unlink, 700 701 .symlink = nfs_symlink,
+10
fs/nfs/super.c
··· 901 901 rpc_authflavor_t authlist[NFS_MAX_SECFLAVORS]; 902 902 unsigned int authlist_len = ARRAY_SIZE(authlist); 903 903 904 + /* make sure 'nolock'/'lock' override the 'local_lock' mount option */ 905 + if (ctx->lock_status) { 906 + if (ctx->lock_status == NFS_LOCK_NOLOCK) { 907 + ctx->flags |= NFS_MOUNT_NONLM; 908 + ctx->flags |= (NFS_MOUNT_LOCAL_FLOCK | NFS_MOUNT_LOCAL_FCNTL); 909 + } else { 910 + ctx->flags &= ~NFS_MOUNT_NONLM; 911 + ctx->flags &= ~(NFS_MOUNT_LOCAL_FLOCK | NFS_MOUNT_LOCAL_FCNTL); 912 + } 913 + } 904 914 status = nfs_request_mount(fc, ctx->mntfh, authlist, &authlist_len); 905 915 if (status) 906 916 return ERR_PTR(status);
+3
include/linux/nfs_fs.h
··· 561 561 extern void nfs_access_zap_cache(struct inode *inode); 562 562 extern int nfs_access_get_cached(struct inode *inode, const struct cred *cred, 563 563 u32 *mask, bool may_block); 564 + extern int nfs_atomic_open_v23(struct inode *dir, struct dentry *dentry, 565 + struct file *file, unsigned int open_flags, 566 + umode_t mode); 564 567 565 568 /* 566 569 * linux/fs/nfs/symlink.c
+13 -1
net/sunrpc/clnt.c
··· 1071 1071 .authflavor = old->cl_auth->au_flavor, 1072 1072 .cred = old->cl_cred, 1073 1073 .stats = old->cl_stats, 1074 + .timeout = old->cl_timeout, 1074 1075 }; 1075 1076 struct rpc_clnt *clnt; 1076 1077 int err; ··· 2699 2698 goto out_msg_denied; 2700 2699 2701 2700 error = rpcauth_checkverf(task, xdr); 2702 - if (error) 2701 + if (error) { 2702 + struct rpc_cred *cred = task->tk_rqstp->rq_cred; 2703 + 2704 + if (!test_bit(RPCAUTH_CRED_UPTODATE, &cred->cr_flags)) { 2705 + rpcauth_invalcred(task); 2706 + if (!task->tk_cred_retry) 2707 + goto out_err; 2708 + task->tk_cred_retry--; 2709 + trace_rpc__stale_creds(task); 2710 + return -EKEYREJECTED; 2711 + } 2703 2712 goto out_verifier; 2713 + } 2704 2714 2705 2715 p = xdr_inline_decode(xdr, sizeof(*p)); 2706 2716 if (!p)
+5 -1
net/sunrpc/xprtrdma/verbs.c
··· 244 244 case RDMA_CM_EVENT_DEVICE_REMOVAL: 245 245 pr_info("rpcrdma: removing device %s for %pISpc\n", 246 246 ep->re_id->device->name, sap); 247 - fallthrough; 247 + switch (xchg(&ep->re_connect_status, -ENODEV)) { 248 + case 0: goto wake_connect_worker; 249 + case 1: goto disconnected; 250 + } 251 + return 0; 248 252 case RDMA_CM_EVENT_ADDR_CHANGE: 249 253 ep->re_connect_status = -ENODEV; 250 254 goto disconnected;