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-5.11-3' of git://git.linux-nfs.org/projects/trondmy/linux-nfs

Pull NFS client fixes from Trond Myklebust:

- SUNRPC: Handle 0 length opaque XDR object data properly

- Fix a layout segment leak in pnfs_layout_process()

- pNFS/NFSv4: Update the layout barrier when we schedule a layoutreturn

- pNFS/NFSv4: Improve rejection of out-of-order layouts

- pNFS/NFSv4: Try to return invalid layout in pnfs_layout_process()

* tag 'nfs-for-5.11-3' of git://git.linux-nfs.org/projects/trondmy/linux-nfs:
SUNRPC: Handle 0 length opaque XDR object data properly
SUNRPC: Move simple_get_bytes and simple_get_netobj into private header
pNFS/NFSv4: Improve rejection of out-of-order layouts
pNFS/NFSv4: Update the layout barrier when we schedule a layoutreturn
pNFS/NFSv4: Try to return invalid layout in pnfs_layout_process()
pNFS/NFSv4: Fix a layout segment leak in pnfs_layout_process()

+93 -85
+44 -25
fs/nfs/pnfs.c
··· 324 324 return NULL; 325 325 } 326 326 327 + /* 328 + * Compare 2 layout stateid sequence ids, to see which is newer, 329 + * taking into account wraparound issues. 330 + */ 331 + static bool pnfs_seqid_is_newer(u32 s1, u32 s2) 332 + { 333 + return (s32)(s1 - s2) > 0; 334 + } 335 + 336 + static void pnfs_barrier_update(struct pnfs_layout_hdr *lo, u32 newseq) 337 + { 338 + if (pnfs_seqid_is_newer(newseq, lo->plh_barrier)) 339 + lo->plh_barrier = newseq; 340 + } 341 + 327 342 static void 328 343 pnfs_set_plh_return_info(struct pnfs_layout_hdr *lo, enum pnfs_iomode iomode, 329 344 u32 seq) ··· 350 335 if (seq != 0) { 351 336 WARN_ON_ONCE(lo->plh_return_seq != 0 && lo->plh_return_seq != seq); 352 337 lo->plh_return_seq = seq; 338 + pnfs_barrier_update(lo, seq); 353 339 } 354 340 } 355 341 ··· 653 637 rv = 1; 654 638 } 655 639 return rv; 656 - } 657 - 658 - /* 659 - * Compare 2 layout stateid sequence ids, to see which is newer, 660 - * taking into account wraparound issues. 661 - */ 662 - static bool pnfs_seqid_is_newer(u32 s1, u32 s2) 663 - { 664 - return (s32)(s1 - s2) > 0; 665 640 } 666 641 667 642 static bool ··· 991 984 new_barrier = be32_to_cpu(new->seqid); 992 985 else if (new_barrier == 0) 993 986 return; 994 - if (pnfs_seqid_is_newer(new_barrier, lo->plh_barrier)) 995 - lo->plh_barrier = new_barrier; 987 + pnfs_barrier_update(lo, new_barrier); 996 988 } 997 989 998 990 static bool ··· 1000 994 { 1001 995 u32 seqid = be32_to_cpu(stateid->seqid); 1002 996 1003 - return !pnfs_seqid_is_newer(seqid, lo->plh_barrier); 997 + return !pnfs_seqid_is_newer(seqid, lo->plh_barrier) && lo->plh_barrier; 1004 998 } 1005 999 1006 1000 /* lget is set to 1 if called from inside send_layoutget call chain */ ··· 1189 1183 return false; 1190 1184 set_bit(NFS_LAYOUT_RETURN, &lo->plh_flags); 1191 1185 pnfs_get_layout_hdr(lo); 1186 + nfs4_stateid_copy(stateid, &lo->plh_stateid); 1187 + *cred = get_cred(lo->plh_lc_cred); 1192 1188 if (test_bit(NFS_LAYOUT_RETURN_REQUESTED, &lo->plh_flags)) { 1193 - nfs4_stateid_copy(stateid, &lo->plh_stateid); 1194 - *cred = get_cred(lo->plh_lc_cred); 1195 1189 if (lo->plh_return_seq != 0) 1196 1190 stateid->seqid = cpu_to_be32(lo->plh_return_seq); 1197 1191 if (iomode != NULL) 1198 1192 *iomode = lo->plh_return_iomode; 1199 1193 pnfs_clear_layoutreturn_info(lo); 1200 - return true; 1201 - } 1202 - nfs4_stateid_copy(stateid, &lo->plh_stateid); 1203 - *cred = get_cred(lo->plh_lc_cred); 1204 - if (iomode != NULL) 1194 + } else if (iomode != NULL) 1205 1195 *iomode = IOMODE_ANY; 1196 + pnfs_barrier_update(lo, be32_to_cpu(stateid->seqid)); 1206 1197 return true; 1207 1198 } 1208 1199 ··· 1912 1909 wake_up_var(&lo->plh_outstanding); 1913 1910 } 1914 1911 1912 + static bool pnfs_is_first_layoutget(struct pnfs_layout_hdr *lo) 1913 + { 1914 + return test_bit(NFS_LAYOUT_FIRST_LAYOUTGET, &lo->plh_flags); 1915 + } 1916 + 1915 1917 static void pnfs_clear_first_layoutget(struct pnfs_layout_hdr *lo) 1916 1918 { 1917 1919 unsigned long *bitlock = &lo->plh_flags; ··· 2391 2383 goto out_forget; 2392 2384 } 2393 2385 2394 - if (!pnfs_layout_is_valid(lo)) { 2395 - /* We have a completely new layout */ 2396 - pnfs_set_layout_stateid(lo, &res->stateid, lgp->cred, true); 2397 - } else if (nfs4_stateid_match_other(&lo->plh_stateid, &res->stateid)) { 2386 + if (nfs4_stateid_match_other(&lo->plh_stateid, &res->stateid)) { 2398 2387 /* existing state ID, make sure the sequence number matches. */ 2399 2388 if (pnfs_layout_stateid_blocked(lo, &res->stateid)) { 2389 + if (!pnfs_layout_is_valid(lo) && 2390 + pnfs_is_first_layoutget(lo)) 2391 + lo->plh_barrier = 0; 2400 2392 dprintk("%s forget reply due to sequence\n", __func__); 2401 2393 goto out_forget; 2402 2394 } 2403 2395 pnfs_set_layout_stateid(lo, &res->stateid, lgp->cred, false); 2404 - } else { 2396 + } else if (pnfs_layout_is_valid(lo)) { 2405 2397 /* 2406 2398 * We got an entirely new state ID. Mark all segments for the 2407 2399 * inode invalid, and retry the layoutget 2408 2400 */ 2409 - pnfs_mark_layout_stateid_invalid(lo, &free_me); 2401 + struct pnfs_layout_range range = { 2402 + .iomode = IOMODE_ANY, 2403 + .length = NFS4_MAX_UINT64, 2404 + }; 2405 + pnfs_set_plh_return_info(lo, IOMODE_ANY, 0); 2406 + pnfs_mark_matching_lsegs_return(lo, &lo->plh_return_segs, 2407 + &range, 0); 2410 2408 goto out_forget; 2409 + } else { 2410 + /* We have a completely new layout */ 2411 + if (!pnfs_is_first_layoutget(lo)) 2412 + goto out_forget; 2413 + pnfs_set_layout_stateid(lo, &res->stateid, lgp->cred, true); 2411 2414 } 2412 2415 2413 2416 pnfs_get_lseg(lseg);
+1 -2
include/linux/sunrpc/xdr.h
··· 25 25 #define XDR_QUADLEN(l) (((l) + 3) >> 2) 26 26 27 27 /* 28 - * Generic opaque `network object.' At the kernel level, this type 29 - * is used only by lockd. 28 + * Generic opaque `network object.' 30 29 */ 31 30 #define XDR_MAX_NETOBJ 1024 32 31 struct xdr_netobj {
+1 -29
net/sunrpc/auth_gss/auth_gss.c
··· 29 29 #include <linux/uaccess.h> 30 30 #include <linux/hashtable.h> 31 31 32 + #include "auth_gss_internal.h" 32 33 #include "../netns.h" 33 34 34 35 #include <trace/events/rpcgss.h> ··· 124 123 set_bit(RPCAUTH_CRED_UPTODATE, &cred->cr_flags); 125 124 smp_mb__before_atomic(); 126 125 clear_bit(RPCAUTH_CRED_NEW, &cred->cr_flags); 127 - } 128 - 129 - static const void * 130 - simple_get_bytes(const void *p, const void *end, void *res, size_t len) 131 - { 132 - const void *q = (const void *)((const char *)p + len); 133 - if (unlikely(q > end || q < p)) 134 - return ERR_PTR(-EFAULT); 135 - memcpy(res, p, len); 136 - return q; 137 - } 138 - 139 - static inline const void * 140 - simple_get_netobj(const void *p, const void *end, struct xdr_netobj *dest) 141 - { 142 - const void *q; 143 - unsigned int len; 144 - 145 - p = simple_get_bytes(p, end, &len, sizeof(len)); 146 - if (IS_ERR(p)) 147 - return p; 148 - q = (const void *)((const char *)p + len); 149 - if (unlikely(q > end || q < p)) 150 - return ERR_PTR(-EFAULT); 151 - dest->data = kmemdup(p, len, GFP_NOFS); 152 - if (unlikely(dest->data == NULL)) 153 - return ERR_PTR(-ENOMEM); 154 - dest->len = len; 155 - return q; 156 126 } 157 127 158 128 static struct gss_cl_ctx *
+45
net/sunrpc/auth_gss/auth_gss_internal.h
··· 1 + // SPDX-License-Identifier: BSD-3-Clause 2 + /* 3 + * linux/net/sunrpc/auth_gss/auth_gss_internal.h 4 + * 5 + * Internal definitions for RPCSEC_GSS client authentication 6 + * 7 + * Copyright (c) 2000 The Regents of the University of Michigan. 8 + * All rights reserved. 9 + * 10 + */ 11 + #include <linux/err.h> 12 + #include <linux/string.h> 13 + #include <linux/sunrpc/xdr.h> 14 + 15 + static inline const void * 16 + simple_get_bytes(const void *p, const void *end, void *res, size_t len) 17 + { 18 + const void *q = (const void *)((const char *)p + len); 19 + if (unlikely(q > end || q < p)) 20 + return ERR_PTR(-EFAULT); 21 + memcpy(res, p, len); 22 + return q; 23 + } 24 + 25 + static inline const void * 26 + simple_get_netobj(const void *p, const void *end, struct xdr_netobj *dest) 27 + { 28 + const void *q; 29 + unsigned int len; 30 + 31 + p = simple_get_bytes(p, end, &len, sizeof(len)); 32 + if (IS_ERR(p)) 33 + return p; 34 + q = (const void *)((const char *)p + len); 35 + if (unlikely(q > end || q < p)) 36 + return ERR_PTR(-EFAULT); 37 + if (len) { 38 + dest->data = kmemdup(p, len, GFP_NOFS); 39 + if (unlikely(dest->data == NULL)) 40 + return ERR_PTR(-ENOMEM); 41 + } else 42 + dest->data = NULL; 43 + dest->len = len; 44 + return q; 45 + }
+2 -29
net/sunrpc/auth_gss/gss_krb5_mech.c
··· 21 21 #include <linux/sunrpc/xdr.h> 22 22 #include <linux/sunrpc/gss_krb5_enctypes.h> 23 23 24 + #include "auth_gss_internal.h" 25 + 24 26 #if IS_ENABLED(CONFIG_SUNRPC_DEBUG) 25 27 # define RPCDBG_FACILITY RPCDBG_AUTH 26 28 #endif ··· 143 141 if (supported_gss_krb5_enctypes[i].etype == etype) 144 142 return &supported_gss_krb5_enctypes[i]; 145 143 return NULL; 146 - } 147 - 148 - static const void * 149 - simple_get_bytes(const void *p, const void *end, void *res, int len) 150 - { 151 - const void *q = (const void *)((const char *)p + len); 152 - if (unlikely(q > end || q < p)) 153 - return ERR_PTR(-EFAULT); 154 - memcpy(res, p, len); 155 - return q; 156 - } 157 - 158 - static const void * 159 - simple_get_netobj(const void *p, const void *end, struct xdr_netobj *res) 160 - { 161 - const void *q; 162 - unsigned int len; 163 - 164 - p = simple_get_bytes(p, end, &len, sizeof(len)); 165 - if (IS_ERR(p)) 166 - return p; 167 - q = (const void *)((const char *)p + len); 168 - if (unlikely(q > end || q < p)) 169 - return ERR_PTR(-EFAULT); 170 - res->data = kmemdup(p, len, GFP_NOFS); 171 - if (unlikely(res->data == NULL)) 172 - return ERR_PTR(-ENOMEM); 173 - res->len = len; 174 - return q; 175 144 } 176 145 177 146 static inline const void *