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

NFSD: Implement CB_SEQUENCE referring call lists

The slot index number of the current COMPOUND has, until now, not
been needed outside of nfsd4_sequence(). But to record the tuple
that represents a referring call, the slot number will be needed
when processing subsequent operations in the COMPOUND.

Refactor the code that allocates a new struct nfsd4_slot to ensure
that the new sl_index field is always correctly initialized.

Reviewed-by: Jeff Layton <jlayton@kernel.org>
Signed-off-by: Chuck Lever <chuck.lever@oracle.com>

Chuck Lever 281ae67c 4f3c8d8c

+22 -17
+21 -17
fs/nfsd/nfs4state.c
··· 1987 1987 return ret; 1988 1988 } 1989 1989 1990 - /* 1991 - * We don't actually need to cache the rpc and session headers, so we 1992 - * can allocate a little less for each slot: 1993 - */ 1994 - static inline u32 slot_bytes(struct nfsd4_channel_attrs *ca) 1990 + static struct nfsd4_slot *nfsd4_alloc_slot(struct nfsd4_channel_attrs *fattrs, 1991 + int index, gfp_t gfp) 1995 1992 { 1996 - u32 size; 1993 + struct nfsd4_slot *slot; 1994 + size_t size; 1997 1995 1998 - if (ca->maxresp_cached < NFSD_MIN_HDR_SEQ_SZ) 1999 - size = 0; 2000 - else 2001 - size = ca->maxresp_cached - NFSD_MIN_HDR_SEQ_SZ; 2002 - return size + sizeof(struct nfsd4_slot); 1996 + /* 1997 + * The RPC and NFS session headers are never saved in 1998 + * the slot reply cache buffer. 1999 + */ 2000 + size = fattrs->maxresp_cached < NFSD_MIN_HDR_SEQ_SZ ? 2001 + 0 : fattrs->maxresp_cached - NFSD_MIN_HDR_SEQ_SZ; 2002 + 2003 + slot = kzalloc(struct_size(slot, sl_data, size), gfp); 2004 + if (!slot) 2005 + return NULL; 2006 + slot->sl_index = index; 2007 + return slot; 2003 2008 } 2004 2009 2005 2010 static struct nfsd4_session *alloc_session(struct nfsd4_channel_attrs *fattrs, 2006 2011 struct nfsd4_channel_attrs *battrs) 2007 2012 { 2008 2013 int numslots = fattrs->maxreqs; 2009 - int slotsize = slot_bytes(fattrs); 2010 2014 struct nfsd4_session *new; 2011 2015 struct nfsd4_slot *slot; 2012 2016 int i; ··· 2019 2015 if (!new) 2020 2016 return NULL; 2021 2017 xa_init(&new->se_slots); 2022 - /* allocate each struct nfsd4_slot and data cache in one piece */ 2023 - slot = kzalloc(slotsize, GFP_KERNEL); 2018 + 2019 + slot = nfsd4_alloc_slot(fattrs, 0, GFP_KERNEL); 2024 2020 if (!slot || xa_is_err(xa_store(&new->se_slots, 0, slot, GFP_KERNEL))) 2025 2021 goto out_free; 2026 2022 2027 2023 for (i = 1; i < numslots; i++) { 2028 2024 const gfp_t gfp = GFP_KERNEL | __GFP_NORETRY | __GFP_NOWARN; 2029 - slot = kzalloc(slotsize, gfp); 2025 + slot = nfsd4_alloc_slot(fattrs, i, gfp); 2030 2026 if (!slot) 2031 2027 break; 2032 2028 if (xa_is_err(xa_store(&new->se_slots, i, slot, gfp))) { ··· 4442 4438 * spinlock, and only succeeds if there is 4443 4439 * plenty of memory. 4444 4440 */ 4445 - slot = kzalloc(slot_bytes(&session->se_fchannel), 4446 - GFP_NOWAIT); 4441 + slot = nfsd4_alloc_slot(&session->se_fchannel, s, 4442 + GFP_NOWAIT); 4447 4443 prev_slot = xa_load(&session->se_slots, s); 4448 4444 if (xa_is_value(prev_slot) && slot) { 4449 4445 slot->sl_seqid = xa_to_value(prev_slot);
+1
fs/nfsd/state.h
··· 278 278 u32 sl_seqid; 279 279 __be32 sl_status; 280 280 struct svc_cred sl_cred; 281 + u32 sl_index; 281 282 u32 sl_datalen; 282 283 u16 sl_opcnt; 283 284 u16 sl_generation;