cregit-Linux how code gets into the kernel

Release 4.10 fs/nfsd/nfs4xdr.c

Directory: fs/nfsd
/*
 *  Server-side XDR for NFSv4
 *
 *  Copyright (c) 2002 The Regents of the University of Michigan.
 *  All rights reserved.
 *
 *  Kendrick Smith <kmsmith@umich.edu>
 *  Andy Adamson   <andros@umich.edu>
 *
 *  Redistribution and use in source and binary forms, with or without
 *  modification, are permitted provided that the following conditions
 *  are met:
 *
 *  1. Redistributions of source code must retain the above copyright
 *     notice, this list of conditions and the following disclaimer.
 *  2. Redistributions in binary form must reproduce the above copyright
 *     notice, this list of conditions and the following disclaimer in the
 *     documentation and/or other materials provided with the distribution.
 *  3. Neither the name of the University nor the names of its
 *     contributors may be used to endorse or promote products derived
 *     from this software without specific prior written permission.
 *
 *  THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED
 *  WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
 *  MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
 *  DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
 *  FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
 *  CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
 *  SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
 *  BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
 *  LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
 *  NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
 *  SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 */

#include <linux/fs_struct.h>
#include <linux/file.h>
#include <linux/slab.h>
#include <linux/namei.h>
#include <linux/statfs.h>
#include <linux/utsname.h>
#include <linux/pagemap.h>
#include <linux/sunrpc/svcauth_gss.h>

#include "idmap.h"
#include "acl.h"
#include "xdr4.h"
#include "vfs.h"
#include "state.h"
#include "cache.h"
#include "netns.h"
#include "pnfs.h"

#ifdef CONFIG_NFSD_V4_SECURITY_LABEL
#include <linux/security.h>
#endif



#define NFSDDBG_FACILITY		NFSDDBG_XDR


u32 nfsd_suppattrs[3][3] = {
	{NFSD4_SUPPORTED_ATTRS_WORD0,
	 NFSD4_SUPPORTED_ATTRS_WORD1,
	 NFSD4_SUPPORTED_ATTRS_WORD2},

	{NFSD4_1_SUPPORTED_ATTRS_WORD0,
	 NFSD4_1_SUPPORTED_ATTRS_WORD1,
	 NFSD4_1_SUPPORTED_ATTRS_WORD2},

	{NFSD4_1_SUPPORTED_ATTRS_WORD0,
	 NFSD4_1_SUPPORTED_ATTRS_WORD1,
	 NFSD4_2_SUPPORTED_ATTRS_WORD2},
};

/*
 * As per referral draft, the fsid for a referral MUST be different from the fsid of the containing
 * directory in order to indicate to the client that a filesystem boundary is present
 * We use a fixed fsid for a referral
 */

#define NFS4_REFERRAL_FSID_MAJOR	0x8000000ULL

#define NFS4_REFERRAL_FSID_MINOR	0x8000000ULL


static __be32 check_filename(char *str, int len) { int i; if (len == 0) return nfserr_inval; if (isdotent(str, len)) return nfserr_badname; for (i = 0; i < len; i++) if (str[i] == '/') return nfserr_badname; return 0; }

Contributors

PersonTokensPropCommitsCommitProp
neil brownneil brown6295.38%250.00%
j. bruce fieldsj. bruce fields23.08%125.00%
al viroal viro11.54%125.00%
Total65100.00%4100.00%

#define DECODE_HEAD \ __be32 *p; \ __be32 status #define DECODE_TAIL \ status = 0; \ out: \ return status; \ xdr_error: \ dprintk("NFSD: xdr error (%s:%d)\n", \ __FILE__, __LINE__); \ status = nfserr_bad_xdr; \ goto out #define READMEM(x,nbytes) do { \ x = (char *)p; \ p += XDR_QUADLEN(nbytes); \ } while (0) #define SAVEMEM(x,nbytes) do { \ if (!(x = (p==argp->tmp || p == argp->tmpp) ? \ savemem(argp, p, nbytes) : \ (char *)p)) { \ dprintk("NFSD: xdr error (%s:%d)\n", \ __FILE__, __LINE__); \ goto xdr_error; \ } \ p += XDR_QUADLEN(nbytes); \ } while (0) #define COPYMEM(x,nbytes) do { \ memcpy((x), p, nbytes); \ p += XDR_QUADLEN(nbytes); \ } while (0) /* READ_BUF, read_buf(): nbytes must be <= PAGE_SIZE */ #define READ_BUF(nbytes) do { \ if (nbytes <= (u32)((char *)argp->end - (char *)argp->p)) { \ p = argp->p; \ argp->p += XDR_QUADLEN(nbytes); \ } else if (!(p = read_buf(argp, nbytes))) { \ dprintk("NFSD: xdr error (%s:%d)\n", \ __FILE__, __LINE__); \ goto xdr_error; \ } \ } while (0)
static void next_decode_page(struct nfsd4_compoundargs *argp) { argp->p = page_address(argp->pagelist[0]); argp->pagelist++; if (argp->pagelen < PAGE_SIZE) { argp->end = argp->p + (argp->pagelen>>2); argp->pagelen = 0; } else { argp->end = argp->p + (PAGE_SIZE>>2); argp->pagelen -= PAGE_SIZE; } }

Contributors

PersonTokensPropCommitsCommitProp
j. bruce fieldsj. bruce fields85100.00%2100.00%
Total85100.00%2100.00%


static __be32 *read_buf(struct nfsd4_compoundargs *argp, u32 nbytes) { /* We want more bytes than seem to be available. * Maybe we need a new page, maybe we have just run out */ unsigned int avail = (char *)argp->end - (char *)argp->p; __be32 *p; if (avail + argp->pagelen < nbytes) return NULL; if (avail + PAGE_SIZE < nbytes) /* need more than a page !! */ return NULL; /* ok, we can do it with the current plus the next page */ if (nbytes <= sizeof(argp->tmp)) p = argp->tmp; else { kfree(argp->tmpp); p = argp->tmpp = kmalloc(nbytes, GFP_KERNEL); if (!p) return NULL; } /* * The following memcpy is safe because read_buf is always * called with nbytes > avail, and the two cases above both * guarantee p points to at least nbytes bytes. */ memcpy(p, argp->p, avail); next_decode_page(argp); memcpy(((char*)p)+avail, argp->p, (nbytes - avail)); argp->p += XDR_QUADLEN(nbytes - avail); return p; }

Contributors

PersonTokensPropCommitsCommitProp
neil brownneil brown16296.43%350.00%
j. bruce fieldsj. bruce fields42.38%233.33%
al viroal viro21.19%116.67%
Total168100.00%6100.00%


static int zero_clientid(clientid_t *clid) { return (clid->cl_boot == 0) && (clid->cl_id == 0); }

Contributors

PersonTokensPropCommitsCommitProp
andy adamsonandy adamson27100.00%1100.00%
Total27100.00%1100.00%

/** * svcxdr_tmpalloc - allocate memory to be freed after compound processing * @argp: NFSv4 compound argument structure * @p: pointer to be freed (with kfree()) * * Marks @p to be freed when processing the compound operation * described in @argp finishes. */
static void * svcxdr_tmpalloc(struct nfsd4_compoundargs *argp, u32 len) { struct svcxdr_tmpbuf *tb; tb = kmalloc(sizeof(*tb) + len, GFP_KERNEL); if (!tb) return NULL; tb->next = argp->to_free; argp->to_free = tb; return tb->buf; }

Contributors

PersonTokensPropCommitsCommitProp
neil brownneil brown5080.65%150.00%
j. bruce fieldsj. bruce fields1219.35%150.00%
Total62100.00%2100.00%

/* * For xdr strings that need to be passed to other kernel api's * as null-terminated strings. * * Note null-terminating in place usually isn't safe since the * buffer might end on a page boundary. */
static char * svcxdr_dupstr(struct nfsd4_compoundargs *argp, void *buf, u32 len) { char *p = svcxdr_tmpalloc(argp, len + 1); if (!p) return NULL; memcpy(p, buf, len); p[len] = '\0'; return p; }

Contributors

PersonTokensPropCommitsCommitProp
j. bruce fieldsj. bruce fields2847.46%342.86%
neil brownneil brown2745.76%228.57%
eric sesterhenneric sesterhenn23.39%114.29%
thomas meyerthomas meyer23.39%114.29%
Total59100.00%7100.00%

/** * savemem - duplicate a chunk of memory for later processing * @argp: NFSv4 compound argument structure to be freed with * @p: pointer to be duplicated * @nbytes: length to be duplicated * * Returns a pointer to a copy of @nbytes bytes of memory at @p * that are preserved until processing of the NFSv4 compound * operation described by @argp finishes. */
static char *savemem(struct nfsd4_compoundargs *argp, __be32 *p, int nbytes) { void *ret; ret = svcxdr_tmpalloc(argp, nbytes); if (!ret) return NULL; memcpy(ret, p, nbytes); return ret; }

Contributors

PersonTokensPropCommitsCommitProp
neil brownneil brown3771.15%350.00%
j. bruce fieldsj. bruce fields1223.08%116.67%
thomas meyerthomas meyer23.85%116.67%
al viroal viro11.92%116.67%
Total52100.00%6100.00%

/* * We require the high 32 bits of 'seconds' to be 0, and * we ignore all 32 bits of 'nseconds'. */
static __be32 nfsd4_decode_time(struct nfsd4_compoundargs *argp, struct timespec *tv) { DECODE_HEAD; u64 sec; READ_BUF(12); p = xdr_decode_hyper(p, &sec); tv->tv_sec = sec; tv->tv_nsec = be32_to_cpup(p++); if (tv->tv_nsec >= (u32)1000000000) return nfserr_inval; DECODE_TAIL; }

Contributors

PersonTokensPropCommitsCommitProp
christoph hellwigchristoph hellwig68100.00%1100.00%
Total68100.00%1100.00%


static __be32 nfsd4_decode_bitmap(struct nfsd4_compoundargs *argp, u32 *bmval) { u32 bmlen; DECODE_HEAD; bmval[0] = 0; bmval[1] = 0; bmval[2] = 0; READ_BUF(4); bmlen = be32_to_cpup(p++); if (bmlen > 1000) goto xdr_error; READ_BUF(bmlen << 2); if (bmlen > 0) bmval[0] = be32_to_cpup(p++); if (bmlen > 1) bmval[1] = be32_to_cpup(p++); if (bmlen > 2) bmval[2] = be32_to_cpup(p++); DECODE_TAIL; }

Contributors

PersonTokensPropCommitsCommitProp
neil brownneil brown8367.48%125.00%
j. bruce fieldsj. bruce fields2016.26%125.00%
andy adamsonandy adamson1915.45%125.00%
al viroal viro10.81%125.00%
Total123100.00%4100.00%


static __be32 nfsd4_decode_fattr(struct nfsd4_compoundargs *argp, u32 *bmval, struct iattr *iattr, struct nfs4_acl **acl, struct xdr_netobj *label, int *umask) { int expected_len, len = 0; u32 dummy32; char *buf; DECODE_HEAD; iattr->ia_valid = 0; if ((status = nfsd4_decode_bitmap(argp, bmval))) return status; if (bmval[0] & ~NFSD_WRITEABLE_ATTRS_WORD0 || bmval[1] & ~NFSD_WRITEABLE_ATTRS_WORD1 || bmval[2] & ~NFSD_WRITEABLE_ATTRS_WORD2) { if (nfsd_attrs_supported(argp->minorversion, bmval)) return nfserr_inval; return nfserr_attrnotsupp; } READ_BUF(4); expected_len = be32_to_cpup(p++); if (bmval[0] & FATTR4_WORD0_SIZE) { READ_BUF(8); len += 8; p = xdr_decode_hyper(p, &iattr->ia_size); iattr->ia_valid |= ATTR_SIZE; } if (bmval[0] & FATTR4_WORD0_ACL) { u32 nace; struct nfs4_ace *ace; READ_BUF(4); len += 4; nace = be32_to_cpup(p++); if (nace > NFS4_ACL_MAX) return nfserr_fbig; *acl = svcxdr_tmpalloc(argp, nfs4_acl_bytes(nace)); if (*acl == NULL) return nfserr_jukebox; (*acl)->naces = nace; for (ace = (*acl)->aces; ace < (*acl)->aces + nace; ace++) { READ_BUF(16); len += 16; ace->type = be32_to_cpup(p++); ace->flag = be32_to_cpup(p++); ace->access_mask = be32_to_cpup(p++); dummy32 = be32_to_cpup(p++); READ_BUF(dummy32); len += XDR_QUADLEN(dummy32) << 2; READMEM(buf, dummy32); ace->whotype = nfs4_acl_get_whotype(buf, dummy32); status = nfs_ok; if (ace->whotype != NFS4_ACL_WHO_NAMED) ; else if (ace->flag & NFS4_ACE_IDENTIFIER_GROUP) status = nfsd_map_name_to_gid(argp->rqstp, buf, dummy32, &ace->who_gid); else status = nfsd_map_name_to_uid(argp->rqstp, buf, dummy32, &ace->who_uid); if (status) return status; } } else *acl = NULL; if (bmval[1] & FATTR4_WORD1_MODE) { READ_BUF(4); len += 4; iattr->ia_mode = be32_to_cpup(p++); iattr->ia_mode &= (S_IFMT | S_IALLUGO); iattr->ia_valid |= ATTR_MODE; } if (bmval[1] & FATTR4_WORD1_OWNER) { READ_BUF(4); len += 4; dummy32 = be32_to_cpup(p++); READ_BUF(dummy32); len += (XDR_QUADLEN(dummy32) << 2); READMEM(buf, dummy32); if ((status = nfsd_map_name_to_uid(argp->rqstp, buf, dummy32, &iattr->ia_uid))) return status; iattr->ia_valid |= ATTR_UID; } if (bmval[1] & FATTR4_WORD1_OWNER_GROUP) { READ_BUF(4); len += 4; dummy32 = be32_to_cpup(p++); READ_BUF(dummy32); len += (XDR_QUADLEN(dummy32) << 2); READMEM(buf, dummy32); if ((status = nfsd_map_name_to_gid(argp->rqstp, buf, dummy32, &iattr->ia_gid))) return status; iattr->ia_valid |= ATTR_GID; } if (bmval[1] & FATTR4_WORD1_TIME_ACCESS_SET) { READ_BUF(4); len += 4; dummy32 = be32_to_cpup(p++); switch (dummy32) { case NFS4_SET_TO_CLIENT_TIME: len += 12; status = nfsd4_decode_time(argp, &iattr->ia_atime); if (status) return status; iattr->ia_valid |= (ATTR_ATIME | ATTR_ATIME_SET); break; case NFS4_SET_TO_SERVER_TIME: iattr->ia_valid |= ATTR_ATIME; break; default: goto xdr_error; } } if (bmval[1] & FATTR4_WORD1_TIME_MODIFY_SET) { READ_BUF(4); len += 4; dummy32 = be32_to_cpup(p++); switch (dummy32) { case NFS4_SET_TO_CLIENT_TIME: len += 12; status = nfsd4_decode_time(argp, &iattr->ia_mtime); if (status) return status; iattr->ia_valid |= (ATTR_MTIME | ATTR_MTIME_SET); break; case NFS4_SET_TO_SERVER_TIME: iattr->ia_valid |= ATTR_MTIME; break; default: goto xdr_error; } } label->len = 0; #ifdef CONFIG_NFSD_V4_SECURITY_LABEL if (bmval[2] & FATTR4_WORD2_SECURITY_LABEL) { READ_BUF(4); len += 4; dummy32 = be32_to_cpup(p++); /* lfs: we don't use it */ READ_BUF(4); len += 4; dummy32 = be32_to_cpup(p++); /* pi: we don't use it either */ READ_BUF(4); len += 4; dummy32 = be32_to_cpup(p++); READ_BUF(dummy32); if (dummy32 > NFS4_MAXLABELLEN) return nfserr_badlabel; len += (XDR_QUADLEN(dummy32) << 2); READMEM(buf, dummy32); label->len = dummy32; label->data = svcxdr_dupstr(argp, buf, dummy32); if (!label->data) return nfserr_jukebox; } #endif if (bmval[2] & FATTR4_WORD2_MODE_UMASK) { if (!umask) goto xdr_error; READ_BUF(8); len += 8; dummy32 = be32_to_cpup(p++); iattr->ia_mode = dummy32 & (S_IFMT | S_IALLUGO); dummy32 = be32_to_cpup(p++); *umask = dummy32 & S_IRWXUGO; iattr->ia_valid |= ATTR_MODE; } if (len != expected_len) goto xdr_error; DECODE_TAIL; }

Contributors

PersonTokensPropCommitsCommitProp
neil brownneil brown60158.92%416.00%
j. bruce fieldsj. bruce fields19318.92%1144.00%
david quigleydavid quigley12011.76%14.00%
andreas gruenbacherandreas gruenbacher737.16%14.00%
andrew mortonandrew morton100.98%14.00%
christoph hellwigchristoph hellwig100.98%14.00%
kinglong meekinglong mee40.39%28.00%
andi kleenandi kleen30.29%14.00%
eric w. biedermaneric w. biederman30.29%14.00%
yu zhiguoyu zhiguo20.20%14.00%
al viroal viro10.10%14.00%
Total1020100.00%25100.00%


static __be32 nfsd4_decode_stateid(struct nfsd4_compoundargs *argp, stateid_t *sid) { DECODE_HEAD; READ_BUF(sizeof(stateid_t)); sid->si_generation = be32_to_cpup(p++); COPYMEM(&sid->si_opaque, sizeof(stateid_opaque_t)); DECODE_TAIL; }

Contributors

PersonTokensPropCommitsCommitProp
benny halevybenny halevy4386.00%125.00%
j. bruce fieldsj. bruce fields510.00%125.00%
al viroal viro12.00%125.00%
neil brownneil brown12.00%125.00%
Total50100.00%4100.00%


static __be32 nfsd4_decode_access(struct nfsd4_compoundargs *argp, struct nfsd4_access *access) { DECODE_HEAD; READ_BUF(4); access->ac_req_access = be32_to_cpup(p++); DECODE_TAIL; }

Contributors

PersonTokensPropCommitsCommitProp
neil brownneil brown2880.00%133.33%
j. bruce fieldsj. bruce fields514.29%133.33%
benny halevybenny halevy25.71%133.33%
Total35100.00%3100.00%


static __be32 nfsd4_decode_cb_sec(struct nfsd4_compoundargs *argp, struct nfsd4_cb_sec *cbs) { DECODE_HEAD; u32 dummy, uid, gid; char *machine_name; int i; int nr_secflavs; /* callback_sec_params4 */ READ_BUF(4); nr_secflavs = be32_to_cpup(p++); if (nr_secflavs) cbs->flavor = (u32)(-1); else /* Is this legal? Be generous, take it to mean AUTH_NONE: */ cbs->flavor = 0; for (i = 0; i < nr_secflavs; ++i) { READ_BUF(4); dummy = be32_to_cpup(p++); switch (dummy) { case RPC_AUTH_NULL: /* Nothing to read */ if (cbs->flavor == (u32)(-1)) cbs->flavor = RPC_AUTH_NULL; break; case RPC_AUTH_UNIX: READ_BUF(8); /* stamp */ dummy = be32_to_cpup(p++); /* machine name */ dummy = be32_to_cpup(p++); READ_BUF(dummy); SAVEMEM(machine_name, dummy); /* uid, gid */ READ_BUF(8); uid = be32_to_cpup(p++); gid = be32_to_cpup(p++); /* more gids */ READ_BUF(4); dummy = be32_to_cpup(p++); READ_BUF(dummy * 4); if (cbs->flavor == (u32)(-1)) { kuid_t kuid = make_kuid(&init_user_ns, uid); kgid_t kgid = make_kgid(&init_user_ns, gid); if (uid_valid(kuid) && gid_valid(kgid)) { cbs->uid = kuid; cbs->gid = kgid; cbs->flavor = RPC_AUTH_UNIX; } else { dprintk("RPC_AUTH_UNIX with invalid" "uid or gid ignoring!\n"); } } break; case RPC_AUTH_GSS: dprintk("RPC_AUTH_GSS callback secflavor " "not supported!\n"); READ_BUF(8); /* gcbp_service */ dummy = be32_to_cpup(p++); /* gcbp_handle_from_server */ dummy = be32_to_cpup(p++); READ_BUF(dummy); p += XDR_QUADLEN(dummy); /* gcbp_handle_from_client */ READ_BUF(4); dummy = be32_to_cpup(p++); READ_BUF(dummy); break; default: dprintk("Illegal callback secflavor\n"); return nfserr_inval; } } DECODE_TAIL; }

Contributors

PersonTokensPropCommitsCommitProp
j. bruce fieldsj. bruce fields32187.23%480.00%
eric w. biedermaneric w. biederman4712.77%120.00%
Total368100.00%5100.00%


static __be32 nfsd4_decode_backchannel_ctl(struct nfsd4_compoundargs *argp, struct nfsd4_backchannel_ctl *bc) { DECODE_HEAD; READ_BUF(4); bc->bc_cb_program = be32_to_cpup(p++); nfsd4_decode_cb_sec(argp, &bc->bc_cb_sec); DECODE_TAIL; }

Contributors

PersonTokensPropCommitsCommitProp
j. bruce fieldsj. bruce fields45100.00%2100.00%
Total45100.00%2100.00%


static __be32 nfsd4_decode_bind_conn_to_session(struct nfsd4_compoundargs *argp, struct nfsd4_bind_conn_to_session *bcts) { DECODE_HEAD; READ_BUF(NFS4_MAX_SESSIONID_LEN + 8); COPYMEM(bcts->sessionid.data, NFS4_MAX_SESSIONID_LEN); bcts->dir = be32_to_cpup(p++); /* XXX: skipping ctsa_use_conn_in_rdma_mode. Perhaps Tom Tucker * could help us figure out we should be using it. */ DECODE_TAIL; }

Contributors

PersonTokensPropCommitsCommitProp
j. bruce fieldsj. bruce fields4897.96%266.67%
bryan schumakerbryan schumaker12.04%133.33%
Total49100.00%3100.00%


static __be32 nfsd4_decode_close(struct nfsd4_compoundargs *argp, struct nfsd4_close *close) { DECODE_HEAD; READ_BUF(4); close->cl_seqid = be32_to_cpup(p++); return nfsd4_decode_stateid(argp, &close->cl_stateid); DECODE_TAIL; }

Contributors

PersonTokensPropCommitsCommitProp
neil brownneil brown3576.09%125.00%
j. bruce fieldsj. bruce fields510.87%125.00%
benny halevybenny halevy510.87%125.00%
al viroal viro12.17%125.00%
Total46100.00%4100.00%


static __be32 nfsd4_decode_commit(struct nfsd4_compoundargs *argp, struct nfsd4_commit *commit) { DECODE_HEAD; READ_BUF(12); p = xdr_decode_hyper(p, &commit->co_offset); commit->co_count = be32_to_cpup(p++); DECODE_TAIL; }

Contributors

PersonTokensPropCommitsCommitProp
neil brownneil brown3574.47%125.00%
j. bruce fieldsj. bruce fields1123.40%250.00%
al viroal viro12.13%125.00%
Total47100.00%4100.00%


static __be32 nfsd4_decode_create(struct nfsd4_compoundargs *argp, struct nfsd4_create *create) { DECODE_HEAD; READ_BUF(4); create->cr_type = be32_to_cpup(p++); switch (create->cr_type) { case NF4LNK: READ_BUF(4); create->cr_datalen = be32_to_cpup(p++); READ_BUF(create->cr_datalen); create->cr_data = svcxdr_dupstr(argp, p, create->cr_datalen); if (!create->cr_data) return nfserr_jukebox; break; case NF4BLK: case NF4CHR: READ_BUF(8); create->cr_specdata1 = be32_to_cpup(p++); create->cr_specdata2 = be32_to_cpup(p++); break; case NF4SOCK: case NF4FIFO: case NF4DIR: default: break; } READ_BUF(4); create->cr_namelen = be32_to_cpup(p++); READ_BUF(create->cr_namelen); SAVEMEM(create->cr_name, create->cr_namelen); if ((status = check_filename(create->cr_name, create->cr_namelen))) return status; status = nfsd4_decode_fattr(argp, create->cr_bmval, &create->cr_iattr, &create->cr_acl, &create->cr_label, &current->fs->umask); if (status) goto out; DECODE_TAIL; }

Contributors

PersonTokensPropCommitsCommitProp
neil brownneil brown16170.00%433.33%
j. bruce fieldsj. bruce fields5222.61%433.33%
andreas gruenbacherandreas gruenbacher73.04%18.33%
david quigleydavid quigley52.17%18.33%
benny halevybenny halevy41.74%18.33%
al viroal viro10.43%18.33%
Total230100.00%12100.00%


static inline __be32 nfsd4_decode_delegreturn(struct nfsd4_compoundargs *argp, struct nfsd4_delegreturn *dr) { return nfsd4_decode_stateid(argp, &dr->dr_stateid); }

Contributors

PersonTokensPropCommitsCommitProp
neil brownneil brown2278.57%250.00%
benny halevybenny halevy517.86%125.00%
al viroal viro13.57%125.00%
Total28100.00%4100.00%


static inline __be32 nfsd4_decode_getattr(struct nfsd4_compoundargs *argp, struct nfsd4_getattr *getattr) { return nfsd4_decode_bitmap(argp, getattr->ga_bmval); }

Contributors

PersonTokensPropCommitsCommitProp
neil brownneil brown2696.30%266.67%
al viroal viro13.70%133.33%
Total27100.00%3100.00%


static __be32 nfsd4_decode_link(struct nfsd4_compoundargs *argp, struct nfsd4_link *link) { DECODE_HEAD; READ_BUF(4); link->li_namelen = be32_to_cpup(p++); READ_BUF(link->