^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2) * Server-side XDR for NFSv4
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4) * Copyright (c) 2002 The Regents of the University of Michigan.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5) * All rights reserved.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7) * Kendrick Smith <kmsmith@umich.edu>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8) * Andy Adamson <andros@umich.edu>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10) * Redistribution and use in source and binary forms, with or without
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11) * modification, are permitted provided that the following conditions
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12) * are met:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14) * 1. Redistributions of source code must retain the above copyright
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15) * notice, this list of conditions and the following disclaimer.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16) * 2. Redistributions in binary form must reproduce the above copyright
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17) * notice, this list of conditions and the following disclaimer in the
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 18) * documentation and/or other materials provided with the distribution.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 19) * 3. Neither the name of the University nor the names of its
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 20) * contributors may be used to endorse or promote products derived
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 21) * from this software without specific prior written permission.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 22) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 23) * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 24) * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 25) * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 26) * DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 27) * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 28) * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 29) * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 30) * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 31) * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 32) * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 33) * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 34) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 35)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 36) #include <linux/file.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 37) #include <linux/slab.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 38) #include <linux/namei.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 39) #include <linux/statfs.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 40) #include <linux/utsname.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 41) #include <linux/pagemap.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 42) #include <linux/sunrpc/svcauth_gss.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 43) #include <linux/sunrpc/addr.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 44) #include <linux/xattr.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 45) #include <uapi/linux/xattr.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 46)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 47) #include "idmap.h"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 48) #include "acl.h"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 49) #include "xdr4.h"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 50) #include "vfs.h"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 51) #include "state.h"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 52) #include "cache.h"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 53) #include "netns.h"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 54) #include "pnfs.h"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 55) #include "filecache.h"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 56)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 57) #ifdef CONFIG_NFSD_V4_SECURITY_LABEL
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 58) #include <linux/security.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 59) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 60)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 61)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 62) #define NFSDDBG_FACILITY NFSDDBG_XDR
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 63)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 64) const u32 nfsd_suppattrs[3][3] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 65) {NFSD4_SUPPORTED_ATTRS_WORD0,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 66) NFSD4_SUPPORTED_ATTRS_WORD1,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 67) NFSD4_SUPPORTED_ATTRS_WORD2},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 68)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 69) {NFSD4_1_SUPPORTED_ATTRS_WORD0,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 70) NFSD4_1_SUPPORTED_ATTRS_WORD1,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 71) NFSD4_1_SUPPORTED_ATTRS_WORD2},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 72)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 73) {NFSD4_1_SUPPORTED_ATTRS_WORD0,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 74) NFSD4_1_SUPPORTED_ATTRS_WORD1,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 75) NFSD4_2_SUPPORTED_ATTRS_WORD2},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 76) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 77)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 78) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 79) * As per referral draft, the fsid for a referral MUST be different from the fsid of the containing
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 80) * directory in order to indicate to the client that a filesystem boundary is present
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 81) * We use a fixed fsid for a referral
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 82) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 83) #define NFS4_REFERRAL_FSID_MAJOR 0x8000000ULL
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 84) #define NFS4_REFERRAL_FSID_MINOR 0x8000000ULL
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 85)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 86) static __be32
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 87) check_filename(char *str, int len)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 88) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 89) int i;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 90)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 91) if (len == 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 92) return nfserr_inval;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 93) if (isdotent(str, len))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 94) return nfserr_badname;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 95) for (i = 0; i < len; i++)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 96) if (str[i] == '/')
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 97) return nfserr_badname;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 98) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 99) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 100)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 101) #define DECODE_HEAD \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 102) __be32 *p; \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 103) __be32 status
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 104) #define DECODE_TAIL \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 105) status = 0; \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 106) out: \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 107) return status; \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 108) xdr_error: \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 109) dprintk("NFSD: xdr error (%s:%d)\n", \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 110) __FILE__, __LINE__); \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 111) status = nfserr_bad_xdr; \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 112) goto out
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 113)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 114) #define READMEM(x,nbytes) do { \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 115) x = (char *)p; \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 116) p += XDR_QUADLEN(nbytes); \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 117) } while (0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 118) #define SAVEMEM(x,nbytes) do { \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 119) if (!(x = (p==argp->tmp || p == argp->tmpp) ? \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 120) savemem(argp, p, nbytes) : \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 121) (char *)p)) { \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 122) dprintk("NFSD: xdr error (%s:%d)\n", \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 123) __FILE__, __LINE__); \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 124) goto xdr_error; \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 125) } \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 126) p += XDR_QUADLEN(nbytes); \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 127) } while (0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 128) #define COPYMEM(x,nbytes) do { \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 129) memcpy((x), p, nbytes); \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 130) p += XDR_QUADLEN(nbytes); \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 131) } while (0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 132)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 133) /* READ_BUF, read_buf(): nbytes must be <= PAGE_SIZE */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 134) #define READ_BUF(nbytes) do { \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 135) if (nbytes <= (u32)((char *)argp->end - (char *)argp->p)) { \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 136) p = argp->p; \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 137) argp->p += XDR_QUADLEN(nbytes); \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 138) } else if (!(p = read_buf(argp, nbytes))) { \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 139) dprintk("NFSD: xdr error (%s:%d)\n", \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 140) __FILE__, __LINE__); \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 141) goto xdr_error; \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 142) } \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 143) } while (0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 144)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 145) static void next_decode_page(struct nfsd4_compoundargs *argp)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 146) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 147) argp->p = page_address(argp->pagelist[0]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 148) argp->pagelist++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 149) if (argp->pagelen < PAGE_SIZE) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 150) argp->end = argp->p + XDR_QUADLEN(argp->pagelen);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 151) argp->pagelen = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 152) } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 153) argp->end = argp->p + (PAGE_SIZE>>2);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 154) argp->pagelen -= PAGE_SIZE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 155) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 156) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 157)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 158) static __be32 *read_buf(struct nfsd4_compoundargs *argp, u32 nbytes)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 159) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 160) /* We want more bytes than seem to be available.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 161) * Maybe we need a new page, maybe we have just run out
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 162) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 163) unsigned int avail = (char *)argp->end - (char *)argp->p;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 164) __be32 *p;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 165)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 166) if (argp->pagelen == 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 167) struct kvec *vec = &argp->rqstp->rq_arg.tail[0];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 168)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 169) if (!argp->tail) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 170) argp->tail = true;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 171) avail = vec->iov_len;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 172) argp->p = vec->iov_base;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 173) argp->end = vec->iov_base + avail;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 174) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 175)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 176) if (avail < nbytes)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 177) return NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 178)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 179) p = argp->p;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 180) argp->p += XDR_QUADLEN(nbytes);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 181) return p;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 182) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 183)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 184) if (avail + argp->pagelen < nbytes)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 185) return NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 186) if (avail + PAGE_SIZE < nbytes) /* need more than a page !! */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 187) return NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 188) /* ok, we can do it with the current plus the next page */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 189) if (nbytes <= sizeof(argp->tmp))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 190) p = argp->tmp;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 191) else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 192) kfree(argp->tmpp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 193) p = argp->tmpp = kmalloc(nbytes, GFP_KERNEL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 194) if (!p)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 195) return NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 196)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 197) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 198) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 199) * The following memcpy is safe because read_buf is always
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 200) * called with nbytes > avail, and the two cases above both
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 201) * guarantee p points to at least nbytes bytes.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 202) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 203) memcpy(p, argp->p, avail);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 204) next_decode_page(argp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 205) memcpy(((char*)p)+avail, argp->p, (nbytes - avail));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 206) argp->p += XDR_QUADLEN(nbytes - avail);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 207) return p;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 208) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 209)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 210) static unsigned int compoundargs_bytes_left(struct nfsd4_compoundargs *argp)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 211) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 212) unsigned int this = (char *)argp->end - (char *)argp->p;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 213)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 214) return this + argp->pagelen;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 215) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 216)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 217) static int zero_clientid(clientid_t *clid)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 218) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 219) return (clid->cl_boot == 0) && (clid->cl_id == 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 220) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 221)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 222) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 223) * svcxdr_tmpalloc - allocate memory to be freed after compound processing
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 224) * @argp: NFSv4 compound argument structure
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 225) * @len: length of buffer to allocate
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 226) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 227) * Allocates a buffer of size @len to be freed when processing the compound
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 228) * operation described in @argp finishes.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 229) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 230) static void *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 231) svcxdr_tmpalloc(struct nfsd4_compoundargs *argp, u32 len)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 232) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 233) struct svcxdr_tmpbuf *tb;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 234)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 235) tb = kmalloc(sizeof(*tb) + len, GFP_KERNEL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 236) if (!tb)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 237) return NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 238) tb->next = argp->to_free;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 239) argp->to_free = tb;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 240) return tb->buf;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 241) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 242)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 243) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 244) * For xdr strings that need to be passed to other kernel api's
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 245) * as null-terminated strings.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 246) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 247) * Note null-terminating in place usually isn't safe since the
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 248) * buffer might end on a page boundary.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 249) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 250) static char *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 251) svcxdr_dupstr(struct nfsd4_compoundargs *argp, void *buf, u32 len)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 252) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 253) char *p = svcxdr_tmpalloc(argp, len + 1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 254)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 255) if (!p)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 256) return NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 257) memcpy(p, buf, len);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 258) p[len] = '\0';
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 259) return p;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 260) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 261)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 262) static __be32
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 263) svcxdr_construct_vector(struct nfsd4_compoundargs *argp, struct kvec *head,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 264) struct page ***pagelist, u32 buflen)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 265) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 266) int avail;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 267) int len;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 268) int pages;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 269)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 270) /* Sorry .. no magic macros for this.. *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 271) * READ_BUF(write->wr_buflen);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 272) * SAVEMEM(write->wr_buf, write->wr_buflen);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 273) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 274) avail = (char *)argp->end - (char *)argp->p;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 275) if (avail + argp->pagelen < buflen) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 276) dprintk("NFSD: xdr error (%s:%d)\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 277) __FILE__, __LINE__);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 278) return nfserr_bad_xdr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 279) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 280) head->iov_base = argp->p;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 281) head->iov_len = avail;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 282) *pagelist = argp->pagelist;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 283)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 284) len = XDR_QUADLEN(buflen) << 2;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 285) if (len >= avail) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 286) len -= avail;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 287)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 288) pages = len >> PAGE_SHIFT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 289) argp->pagelist += pages;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 290) argp->pagelen -= pages * PAGE_SIZE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 291) len -= pages * PAGE_SIZE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 292)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 293) next_decode_page(argp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 294) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 295) argp->p += XDR_QUADLEN(len);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 296)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 297) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 298) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 299)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 300) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 301) * savemem - duplicate a chunk of memory for later processing
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 302) * @argp: NFSv4 compound argument structure to be freed with
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 303) * @p: pointer to be duplicated
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 304) * @nbytes: length to be duplicated
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 305) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 306) * Returns a pointer to a copy of @nbytes bytes of memory at @p
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 307) * that are preserved until processing of the NFSv4 compound
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 308) * operation described by @argp finishes.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 309) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 310) static char *savemem(struct nfsd4_compoundargs *argp, __be32 *p, int nbytes)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 311) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 312) void *ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 313)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 314) ret = svcxdr_tmpalloc(argp, nbytes);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 315) if (!ret)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 316) return NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 317) memcpy(ret, p, nbytes);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 318) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 319) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 320)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 321) static __be32
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 322) nfsd4_decode_time(struct nfsd4_compoundargs *argp, struct timespec64 *tv)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 323) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 324) DECODE_HEAD;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 325)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 326) READ_BUF(12);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 327) p = xdr_decode_hyper(p, &tv->tv_sec);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 328) tv->tv_nsec = be32_to_cpup(p++);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 329) if (tv->tv_nsec >= (u32)1000000000)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 330) return nfserr_inval;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 331)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 332) DECODE_TAIL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 333) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 334)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 335) static __be32
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 336) nfsd4_decode_bitmap(struct nfsd4_compoundargs *argp, u32 *bmval)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 337) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 338) u32 bmlen;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 339) DECODE_HEAD;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 340)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 341) bmval[0] = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 342) bmval[1] = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 343) bmval[2] = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 344)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 345) READ_BUF(4);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 346) bmlen = be32_to_cpup(p++);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 347) if (bmlen > 1000)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 348) goto xdr_error;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 349)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 350) READ_BUF(bmlen << 2);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 351) if (bmlen > 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 352) bmval[0] = be32_to_cpup(p++);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 353) if (bmlen > 1)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 354) bmval[1] = be32_to_cpup(p++);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 355) if (bmlen > 2)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 356) bmval[2] = be32_to_cpup(p++);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 357)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 358) DECODE_TAIL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 359) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 360)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 361) static __be32
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 362) nfsd4_decode_fattr(struct nfsd4_compoundargs *argp, u32 *bmval,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 363) struct iattr *iattr, struct nfs4_acl **acl,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 364) struct xdr_netobj *label, int *umask)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 365) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 366) int expected_len, len = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 367) u32 dummy32;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 368) char *buf;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 369)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 370) DECODE_HEAD;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 371) iattr->ia_valid = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 372) if ((status = nfsd4_decode_bitmap(argp, bmval)))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 373) return status;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 374)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 375) if (bmval[0] & ~NFSD_WRITEABLE_ATTRS_WORD0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 376) || bmval[1] & ~NFSD_WRITEABLE_ATTRS_WORD1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 377) || bmval[2] & ~NFSD_WRITEABLE_ATTRS_WORD2) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 378) if (nfsd_attrs_supported(argp->minorversion, bmval))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 379) return nfserr_inval;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 380) return nfserr_attrnotsupp;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 381) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 382)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 383) READ_BUF(4);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 384) expected_len = be32_to_cpup(p++);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 385)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 386) if (bmval[0] & FATTR4_WORD0_SIZE) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 387) READ_BUF(8);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 388) len += 8;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 389) p = xdr_decode_hyper(p, &iattr->ia_size);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 390) iattr->ia_valid |= ATTR_SIZE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 391) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 392) if (bmval[0] & FATTR4_WORD0_ACL) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 393) u32 nace;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 394) struct nfs4_ace *ace;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 395)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 396) READ_BUF(4); len += 4;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 397) nace = be32_to_cpup(p++);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 398)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 399) if (nace > compoundargs_bytes_left(argp)/20)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 400) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 401) * Even with 4-byte names there wouldn't be
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 402) * space for that many aces; something fishy is
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 403) * going on:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 404) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 405) return nfserr_fbig;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 406)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 407) *acl = svcxdr_tmpalloc(argp, nfs4_acl_bytes(nace));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 408) if (*acl == NULL)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 409) return nfserr_jukebox;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 410)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 411) (*acl)->naces = nace;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 412) for (ace = (*acl)->aces; ace < (*acl)->aces + nace; ace++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 413) READ_BUF(16); len += 16;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 414) ace->type = be32_to_cpup(p++);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 415) ace->flag = be32_to_cpup(p++);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 416) ace->access_mask = be32_to_cpup(p++);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 417) dummy32 = be32_to_cpup(p++);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 418) READ_BUF(dummy32);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 419) len += XDR_QUADLEN(dummy32) << 2;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 420) READMEM(buf, dummy32);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 421) ace->whotype = nfs4_acl_get_whotype(buf, dummy32);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 422) status = nfs_ok;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 423) if (ace->whotype != NFS4_ACL_WHO_NAMED)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 424) ;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 425) else if (ace->flag & NFS4_ACE_IDENTIFIER_GROUP)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 426) status = nfsd_map_name_to_gid(argp->rqstp,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 427) buf, dummy32, &ace->who_gid);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 428) else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 429) status = nfsd_map_name_to_uid(argp->rqstp,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 430) buf, dummy32, &ace->who_uid);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 431) if (status)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 432) return status;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 433) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 434) } else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 435) *acl = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 436) if (bmval[1] & FATTR4_WORD1_MODE) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 437) READ_BUF(4);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 438) len += 4;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 439) iattr->ia_mode = be32_to_cpup(p++);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 440) iattr->ia_mode &= (S_IFMT | S_IALLUGO);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 441) iattr->ia_valid |= ATTR_MODE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 442) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 443) if (bmval[1] & FATTR4_WORD1_OWNER) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 444) READ_BUF(4);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 445) len += 4;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 446) dummy32 = be32_to_cpup(p++);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 447) READ_BUF(dummy32);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 448) len += (XDR_QUADLEN(dummy32) << 2);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 449) READMEM(buf, dummy32);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 450) if ((status = nfsd_map_name_to_uid(argp->rqstp, buf, dummy32, &iattr->ia_uid)))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 451) return status;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 452) iattr->ia_valid |= ATTR_UID;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 453) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 454) if (bmval[1] & FATTR4_WORD1_OWNER_GROUP) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 455) READ_BUF(4);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 456) len += 4;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 457) dummy32 = be32_to_cpup(p++);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 458) READ_BUF(dummy32);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 459) len += (XDR_QUADLEN(dummy32) << 2);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 460) READMEM(buf, dummy32);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 461) if ((status = nfsd_map_name_to_gid(argp->rqstp, buf, dummy32, &iattr->ia_gid)))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 462) return status;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 463) iattr->ia_valid |= ATTR_GID;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 464) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 465) if (bmval[1] & FATTR4_WORD1_TIME_ACCESS_SET) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 466) READ_BUF(4);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 467) len += 4;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 468) dummy32 = be32_to_cpup(p++);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 469) switch (dummy32) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 470) case NFS4_SET_TO_CLIENT_TIME:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 471) len += 12;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 472) status = nfsd4_decode_time(argp, &iattr->ia_atime);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 473) if (status)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 474) return status;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 475) iattr->ia_valid |= (ATTR_ATIME | ATTR_ATIME_SET);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 476) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 477) case NFS4_SET_TO_SERVER_TIME:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 478) iattr->ia_valid |= ATTR_ATIME;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 479) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 480) default:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 481) goto xdr_error;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 482) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 483) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 484) if (bmval[1] & FATTR4_WORD1_TIME_MODIFY_SET) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 485) READ_BUF(4);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 486) len += 4;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 487) dummy32 = be32_to_cpup(p++);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 488) switch (dummy32) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 489) case NFS4_SET_TO_CLIENT_TIME:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 490) len += 12;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 491) status = nfsd4_decode_time(argp, &iattr->ia_mtime);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 492) if (status)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 493) return status;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 494) iattr->ia_valid |= (ATTR_MTIME | ATTR_MTIME_SET);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 495) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 496) case NFS4_SET_TO_SERVER_TIME:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 497) iattr->ia_valid |= ATTR_MTIME;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 498) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 499) default:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 500) goto xdr_error;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 501) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 502) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 503)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 504) label->len = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 505) if (IS_ENABLED(CONFIG_NFSD_V4_SECURITY_LABEL) &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 506) bmval[2] & FATTR4_WORD2_SECURITY_LABEL) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 507) READ_BUF(4);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 508) len += 4;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 509) dummy32 = be32_to_cpup(p++); /* lfs: we don't use it */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 510) READ_BUF(4);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 511) len += 4;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 512) dummy32 = be32_to_cpup(p++); /* pi: we don't use it either */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 513) READ_BUF(4);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 514) len += 4;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 515) dummy32 = be32_to_cpup(p++);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 516) READ_BUF(dummy32);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 517) if (dummy32 > NFS4_MAXLABELLEN)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 518) return nfserr_badlabel;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 519) len += (XDR_QUADLEN(dummy32) << 2);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 520) READMEM(buf, dummy32);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 521) label->len = dummy32;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 522) label->data = svcxdr_dupstr(argp, buf, dummy32);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 523) if (!label->data)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 524) return nfserr_jukebox;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 525) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 526) if (bmval[2] & FATTR4_WORD2_MODE_UMASK) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 527) if (!umask)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 528) goto xdr_error;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 529) READ_BUF(8);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 530) len += 8;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 531) dummy32 = be32_to_cpup(p++);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 532) iattr->ia_mode = dummy32 & (S_IFMT | S_IALLUGO);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 533) dummy32 = be32_to_cpup(p++);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 534) *umask = dummy32 & S_IRWXUGO;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 535) iattr->ia_valid |= ATTR_MODE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 536) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 537) if (len != expected_len)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 538) goto xdr_error;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 539)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 540) DECODE_TAIL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 541) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 542)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 543) static __be32
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 544) nfsd4_decode_stateid(struct nfsd4_compoundargs *argp, stateid_t *sid)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 545) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 546) DECODE_HEAD;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 547)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 548) READ_BUF(sizeof(stateid_t));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 549) sid->si_generation = be32_to_cpup(p++);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 550) COPYMEM(&sid->si_opaque, sizeof(stateid_opaque_t));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 551)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 552) DECODE_TAIL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 553) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 554)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 555) static __be32
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 556) nfsd4_decode_access(struct nfsd4_compoundargs *argp, struct nfsd4_access *access)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 557) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 558) DECODE_HEAD;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 559)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 560) READ_BUF(4);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 561) access->ac_req_access = be32_to_cpup(p++);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 562)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 563) DECODE_TAIL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 564) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 565)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 566) static __be32 nfsd4_decode_cb_sec(struct nfsd4_compoundargs *argp, struct nfsd4_cb_sec *cbs)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 567) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 568) DECODE_HEAD;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 569) struct user_namespace *userns = nfsd_user_namespace(argp->rqstp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 570) u32 dummy, uid, gid;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 571) char *machine_name;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 572) int i;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 573) int nr_secflavs;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 574)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 575) /* callback_sec_params4 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 576) READ_BUF(4);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 577) nr_secflavs = be32_to_cpup(p++);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 578) if (nr_secflavs)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 579) cbs->flavor = (u32)(-1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 580) else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 581) /* Is this legal? Be generous, take it to mean AUTH_NONE: */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 582) cbs->flavor = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 583) for (i = 0; i < nr_secflavs; ++i) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 584) READ_BUF(4);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 585) dummy = be32_to_cpup(p++);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 586) switch (dummy) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 587) case RPC_AUTH_NULL:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 588) /* Nothing to read */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 589) if (cbs->flavor == (u32)(-1))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 590) cbs->flavor = RPC_AUTH_NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 591) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 592) case RPC_AUTH_UNIX:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 593) READ_BUF(8);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 594) /* stamp */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 595) dummy = be32_to_cpup(p++);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 596)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 597) /* machine name */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 598) dummy = be32_to_cpup(p++);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 599) READ_BUF(dummy);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 600) SAVEMEM(machine_name, dummy);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 601)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 602) /* uid, gid */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 603) READ_BUF(8);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 604) uid = be32_to_cpup(p++);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 605) gid = be32_to_cpup(p++);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 606)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 607) /* more gids */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 608) READ_BUF(4);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 609) dummy = be32_to_cpup(p++);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 610) READ_BUF(dummy * 4);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 611) if (cbs->flavor == (u32)(-1)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 612) kuid_t kuid = make_kuid(userns, uid);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 613) kgid_t kgid = make_kgid(userns, gid);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 614) if (uid_valid(kuid) && gid_valid(kgid)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 615) cbs->uid = kuid;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 616) cbs->gid = kgid;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 617) cbs->flavor = RPC_AUTH_UNIX;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 618) } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 619) dprintk("RPC_AUTH_UNIX with invalid"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 620) "uid or gid ignoring!\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 621) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 622) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 623) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 624) case RPC_AUTH_GSS:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 625) dprintk("RPC_AUTH_GSS callback secflavor "
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 626) "not supported!\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 627) READ_BUF(8);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 628) /* gcbp_service */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 629) dummy = be32_to_cpup(p++);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 630) /* gcbp_handle_from_server */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 631) dummy = be32_to_cpup(p++);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 632) READ_BUF(dummy);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 633) p += XDR_QUADLEN(dummy);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 634) /* gcbp_handle_from_client */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 635) READ_BUF(4);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 636) dummy = be32_to_cpup(p++);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 637) READ_BUF(dummy);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 638) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 639) default:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 640) dprintk("Illegal callback secflavor\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 641) return nfserr_inval;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 642) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 643) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 644) DECODE_TAIL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 645) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 646)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 647) static __be32 nfsd4_decode_backchannel_ctl(struct nfsd4_compoundargs *argp, struct nfsd4_backchannel_ctl *bc)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 648) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 649) DECODE_HEAD;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 650)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 651) READ_BUF(4);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 652) bc->bc_cb_program = be32_to_cpup(p++);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 653) nfsd4_decode_cb_sec(argp, &bc->bc_cb_sec);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 654)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 655) DECODE_TAIL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 656) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 657)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 658) static __be32 nfsd4_decode_bind_conn_to_session(struct nfsd4_compoundargs *argp, struct nfsd4_bind_conn_to_session *bcts)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 659) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 660) DECODE_HEAD;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 661)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 662) READ_BUF(NFS4_MAX_SESSIONID_LEN + 8);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 663) COPYMEM(bcts->sessionid.data, NFS4_MAX_SESSIONID_LEN);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 664) bcts->dir = be32_to_cpup(p++);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 665) /* XXX: skipping ctsa_use_conn_in_rdma_mode. Perhaps Tom Tucker
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 666) * could help us figure out we should be using it. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 667) DECODE_TAIL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 668) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 669)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 670) static __be32
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 671) nfsd4_decode_close(struct nfsd4_compoundargs *argp, struct nfsd4_close *close)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 672) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 673) DECODE_HEAD;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 674)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 675) READ_BUF(4);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 676) close->cl_seqid = be32_to_cpup(p++);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 677) return nfsd4_decode_stateid(argp, &close->cl_stateid);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 678)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 679) DECODE_TAIL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 680) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 681)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 682)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 683) static __be32
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 684) nfsd4_decode_commit(struct nfsd4_compoundargs *argp, struct nfsd4_commit *commit)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 685) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 686) DECODE_HEAD;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 687)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 688) READ_BUF(12);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 689) p = xdr_decode_hyper(p, &commit->co_offset);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 690) commit->co_count = be32_to_cpup(p++);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 691)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 692) DECODE_TAIL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 693) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 694)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 695) static __be32
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 696) nfsd4_decode_create(struct nfsd4_compoundargs *argp, struct nfsd4_create *create)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 697) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 698) DECODE_HEAD;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 699)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 700) READ_BUF(4);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 701) create->cr_type = be32_to_cpup(p++);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 702) switch (create->cr_type) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 703) case NF4LNK:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 704) READ_BUF(4);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 705) create->cr_datalen = be32_to_cpup(p++);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 706) READ_BUF(create->cr_datalen);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 707) create->cr_data = svcxdr_dupstr(argp, p, create->cr_datalen);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 708) if (!create->cr_data)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 709) return nfserr_jukebox;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 710) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 711) case NF4BLK:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 712) case NF4CHR:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 713) READ_BUF(8);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 714) create->cr_specdata1 = be32_to_cpup(p++);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 715) create->cr_specdata2 = be32_to_cpup(p++);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 716) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 717) case NF4SOCK:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 718) case NF4FIFO:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 719) case NF4DIR:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 720) default:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 721) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 722) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 723)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 724) READ_BUF(4);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 725) create->cr_namelen = be32_to_cpup(p++);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 726) READ_BUF(create->cr_namelen);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 727) SAVEMEM(create->cr_name, create->cr_namelen);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 728) if ((status = check_filename(create->cr_name, create->cr_namelen)))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 729) return status;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 730)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 731) status = nfsd4_decode_fattr(argp, create->cr_bmval, &create->cr_iattr,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 732) &create->cr_acl, &create->cr_label,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 733) &create->cr_umask);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 734) if (status)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 735) goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 736)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 737) DECODE_TAIL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 738) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 739)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 740) static inline __be32
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 741) nfsd4_decode_delegreturn(struct nfsd4_compoundargs *argp, struct nfsd4_delegreturn *dr)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 742) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 743) return nfsd4_decode_stateid(argp, &dr->dr_stateid);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 744) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 745)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 746) static inline __be32
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 747) nfsd4_decode_getattr(struct nfsd4_compoundargs *argp, struct nfsd4_getattr *getattr)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 748) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 749) return nfsd4_decode_bitmap(argp, getattr->ga_bmval);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 750) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 751)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 752) static __be32
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 753) nfsd4_decode_link(struct nfsd4_compoundargs *argp, struct nfsd4_link *link)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 754) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 755) DECODE_HEAD;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 756)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 757) READ_BUF(4);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 758) link->li_namelen = be32_to_cpup(p++);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 759) READ_BUF(link->li_namelen);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 760) SAVEMEM(link->li_name, link->li_namelen);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 761) if ((status = check_filename(link->li_name, link->li_namelen)))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 762) return status;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 763)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 764) DECODE_TAIL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 765) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 766)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 767) static __be32
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 768) nfsd4_decode_lock(struct nfsd4_compoundargs *argp, struct nfsd4_lock *lock)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 769) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 770) DECODE_HEAD;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 771)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 772) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 773) * type, reclaim(boolean), offset, length, new_lock_owner(boolean)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 774) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 775) READ_BUF(28);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 776) lock->lk_type = be32_to_cpup(p++);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 777) if ((lock->lk_type < NFS4_READ_LT) || (lock->lk_type > NFS4_WRITEW_LT))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 778) goto xdr_error;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 779) lock->lk_reclaim = be32_to_cpup(p++);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 780) p = xdr_decode_hyper(p, &lock->lk_offset);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 781) p = xdr_decode_hyper(p, &lock->lk_length);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 782) lock->lk_is_new = be32_to_cpup(p++);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 783)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 784) if (lock->lk_is_new) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 785) READ_BUF(4);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 786) lock->lk_new_open_seqid = be32_to_cpup(p++);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 787) status = nfsd4_decode_stateid(argp, &lock->lk_new_open_stateid);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 788) if (status)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 789) return status;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 790) READ_BUF(8 + sizeof(clientid_t));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 791) lock->lk_new_lock_seqid = be32_to_cpup(p++);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 792) COPYMEM(&lock->lk_new_clientid, sizeof(clientid_t));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 793) lock->lk_new_owner.len = be32_to_cpup(p++);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 794) READ_BUF(lock->lk_new_owner.len);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 795) READMEM(lock->lk_new_owner.data, lock->lk_new_owner.len);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 796) } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 797) status = nfsd4_decode_stateid(argp, &lock->lk_old_lock_stateid);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 798) if (status)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 799) return status;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 800) READ_BUF(4);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 801) lock->lk_old_lock_seqid = be32_to_cpup(p++);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 802) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 803)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 804) DECODE_TAIL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 805) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 806)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 807) static __be32
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 808) nfsd4_decode_lockt(struct nfsd4_compoundargs *argp, struct nfsd4_lockt *lockt)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 809) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 810) DECODE_HEAD;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 811)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 812) READ_BUF(32);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 813) lockt->lt_type = be32_to_cpup(p++);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 814) if((lockt->lt_type < NFS4_READ_LT) || (lockt->lt_type > NFS4_WRITEW_LT))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 815) goto xdr_error;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 816) p = xdr_decode_hyper(p, &lockt->lt_offset);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 817) p = xdr_decode_hyper(p, &lockt->lt_length);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 818) COPYMEM(&lockt->lt_clientid, 8);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 819) lockt->lt_owner.len = be32_to_cpup(p++);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 820) READ_BUF(lockt->lt_owner.len);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 821) READMEM(lockt->lt_owner.data, lockt->lt_owner.len);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 822)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 823) DECODE_TAIL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 824) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 825)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 826) static __be32
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 827) nfsd4_decode_locku(struct nfsd4_compoundargs *argp, struct nfsd4_locku *locku)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 828) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 829) DECODE_HEAD;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 830)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 831) READ_BUF(8);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 832) locku->lu_type = be32_to_cpup(p++);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 833) if ((locku->lu_type < NFS4_READ_LT) || (locku->lu_type > NFS4_WRITEW_LT))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 834) goto xdr_error;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 835) locku->lu_seqid = be32_to_cpup(p++);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 836) status = nfsd4_decode_stateid(argp, &locku->lu_stateid);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 837) if (status)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 838) return status;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 839) READ_BUF(16);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 840) p = xdr_decode_hyper(p, &locku->lu_offset);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 841) p = xdr_decode_hyper(p, &locku->lu_length);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 842)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 843) DECODE_TAIL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 844) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 845)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 846) static __be32
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 847) nfsd4_decode_lookup(struct nfsd4_compoundargs *argp, struct nfsd4_lookup *lookup)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 848) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 849) DECODE_HEAD;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 850)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 851) READ_BUF(4);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 852) lookup->lo_len = be32_to_cpup(p++);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 853) READ_BUF(lookup->lo_len);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 854) SAVEMEM(lookup->lo_name, lookup->lo_len);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 855) if ((status = check_filename(lookup->lo_name, lookup->lo_len)))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 856) return status;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 857)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 858) DECODE_TAIL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 859) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 860)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 861) static __be32 nfsd4_decode_share_access(struct nfsd4_compoundargs *argp, u32 *share_access, u32 *deleg_want, u32 *deleg_when)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 862) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 863) __be32 *p;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 864) u32 w;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 865)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 866) READ_BUF(4);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 867) w = be32_to_cpup(p++);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 868) *share_access = w & NFS4_SHARE_ACCESS_MASK;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 869) *deleg_want = w & NFS4_SHARE_WANT_MASK;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 870) if (deleg_when)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 871) *deleg_when = w & NFS4_SHARE_WHEN_MASK;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 872)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 873) switch (w & NFS4_SHARE_ACCESS_MASK) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 874) case NFS4_SHARE_ACCESS_READ:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 875) case NFS4_SHARE_ACCESS_WRITE:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 876) case NFS4_SHARE_ACCESS_BOTH:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 877) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 878) default:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 879) return nfserr_bad_xdr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 880) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 881) w &= ~NFS4_SHARE_ACCESS_MASK;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 882) if (!w)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 883) return nfs_ok;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 884) if (!argp->minorversion)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 885) return nfserr_bad_xdr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 886) switch (w & NFS4_SHARE_WANT_MASK) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 887) case NFS4_SHARE_WANT_NO_PREFERENCE:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 888) case NFS4_SHARE_WANT_READ_DELEG:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 889) case NFS4_SHARE_WANT_WRITE_DELEG:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 890) case NFS4_SHARE_WANT_ANY_DELEG:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 891) case NFS4_SHARE_WANT_NO_DELEG:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 892) case NFS4_SHARE_WANT_CANCEL:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 893) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 894) default:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 895) return nfserr_bad_xdr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 896) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 897) w &= ~NFS4_SHARE_WANT_MASK;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 898) if (!w)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 899) return nfs_ok;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 900)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 901) if (!deleg_when) /* open_downgrade */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 902) return nfserr_inval;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 903) switch (w) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 904) case NFS4_SHARE_SIGNAL_DELEG_WHEN_RESRC_AVAIL:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 905) case NFS4_SHARE_PUSH_DELEG_WHEN_UNCONTENDED:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 906) case (NFS4_SHARE_SIGNAL_DELEG_WHEN_RESRC_AVAIL |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 907) NFS4_SHARE_PUSH_DELEG_WHEN_UNCONTENDED):
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 908) return nfs_ok;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 909) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 910) xdr_error:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 911) return nfserr_bad_xdr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 912) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 913)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 914) static __be32 nfsd4_decode_share_deny(struct nfsd4_compoundargs *argp, u32 *x)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 915) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 916) __be32 *p;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 917)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 918) READ_BUF(4);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 919) *x = be32_to_cpup(p++);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 920) /* Note: unlinke access bits, deny bits may be zero. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 921) if (*x & ~NFS4_SHARE_DENY_BOTH)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 922) return nfserr_bad_xdr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 923) return nfs_ok;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 924) xdr_error:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 925) return nfserr_bad_xdr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 926) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 927)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 928) static __be32 nfsd4_decode_opaque(struct nfsd4_compoundargs *argp, struct xdr_netobj *o)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 929) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 930) __be32 *p;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 931)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 932) READ_BUF(4);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 933) o->len = be32_to_cpup(p++);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 934)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 935) if (o->len == 0 || o->len > NFS4_OPAQUE_LIMIT)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 936) return nfserr_bad_xdr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 937)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 938) READ_BUF(o->len);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 939) SAVEMEM(o->data, o->len);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 940) return nfs_ok;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 941) xdr_error:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 942) return nfserr_bad_xdr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 943) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 944)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 945) static __be32
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 946) nfsd4_decode_open(struct nfsd4_compoundargs *argp, struct nfsd4_open *open)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 947) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 948) DECODE_HEAD;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 949) u32 dummy;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 950)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 951) memset(open->op_bmval, 0, sizeof(open->op_bmval));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 952) open->op_iattr.ia_valid = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 953) open->op_openowner = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 954)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 955) open->op_xdr_error = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 956) /* seqid, share_access, share_deny, clientid, ownerlen */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 957) READ_BUF(4);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 958) open->op_seqid = be32_to_cpup(p++);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 959) /* decode, yet ignore deleg_when until supported */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 960) status = nfsd4_decode_share_access(argp, &open->op_share_access,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 961) &open->op_deleg_want, &dummy);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 962) if (status)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 963) goto xdr_error;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 964) status = nfsd4_decode_share_deny(argp, &open->op_share_deny);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 965) if (status)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 966) goto xdr_error;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 967) READ_BUF(sizeof(clientid_t));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 968) COPYMEM(&open->op_clientid, sizeof(clientid_t));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 969) status = nfsd4_decode_opaque(argp, &open->op_owner);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 970) if (status)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 971) goto xdr_error;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 972) READ_BUF(4);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 973) open->op_create = be32_to_cpup(p++);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 974) switch (open->op_create) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 975) case NFS4_OPEN_NOCREATE:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 976) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 977) case NFS4_OPEN_CREATE:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 978) READ_BUF(4);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 979) open->op_createmode = be32_to_cpup(p++);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 980) switch (open->op_createmode) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 981) case NFS4_CREATE_UNCHECKED:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 982) case NFS4_CREATE_GUARDED:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 983) status = nfsd4_decode_fattr(argp, open->op_bmval,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 984) &open->op_iattr, &open->op_acl, &open->op_label,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 985) &open->op_umask);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 986) if (status)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 987) goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 988) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 989) case NFS4_CREATE_EXCLUSIVE:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 990) READ_BUF(NFS4_VERIFIER_SIZE);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 991) COPYMEM(open->op_verf.data, NFS4_VERIFIER_SIZE);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 992) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 993) case NFS4_CREATE_EXCLUSIVE4_1:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 994) if (argp->minorversion < 1)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 995) goto xdr_error;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 996) READ_BUF(NFS4_VERIFIER_SIZE);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 997) COPYMEM(open->op_verf.data, NFS4_VERIFIER_SIZE);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 998) status = nfsd4_decode_fattr(argp, open->op_bmval,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 999) &open->op_iattr, &open->op_acl, &open->op_label,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1000) &open->op_umask);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1001) if (status)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1002) goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1003) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1004) default:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1005) goto xdr_error;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1006) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1007) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1008) default:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1009) goto xdr_error;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1010) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1011)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1012) /* open_claim */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1013) READ_BUF(4);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1014) open->op_claim_type = be32_to_cpup(p++);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1015) switch (open->op_claim_type) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1016) case NFS4_OPEN_CLAIM_NULL:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1017) case NFS4_OPEN_CLAIM_DELEGATE_PREV:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1018) READ_BUF(4);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1019) open->op_fname.len = be32_to_cpup(p++);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1020) READ_BUF(open->op_fname.len);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1021) SAVEMEM(open->op_fname.data, open->op_fname.len);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1022) if ((status = check_filename(open->op_fname.data, open->op_fname.len)))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1023) return status;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1024) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1025) case NFS4_OPEN_CLAIM_PREVIOUS:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1026) READ_BUF(4);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1027) open->op_delegate_type = be32_to_cpup(p++);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1028) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1029) case NFS4_OPEN_CLAIM_DELEGATE_CUR:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1030) status = nfsd4_decode_stateid(argp, &open->op_delegate_stateid);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1031) if (status)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1032) return status;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1033) READ_BUF(4);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1034) open->op_fname.len = be32_to_cpup(p++);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1035) READ_BUF(open->op_fname.len);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1036) SAVEMEM(open->op_fname.data, open->op_fname.len);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1037) if ((status = check_filename(open->op_fname.data, open->op_fname.len)))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1038) return status;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1039) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1040) case NFS4_OPEN_CLAIM_FH:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1041) case NFS4_OPEN_CLAIM_DELEG_PREV_FH:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1042) if (argp->minorversion < 1)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1043) goto xdr_error;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1044) /* void */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1045) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1046) case NFS4_OPEN_CLAIM_DELEG_CUR_FH:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1047) if (argp->minorversion < 1)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1048) goto xdr_error;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1049) status = nfsd4_decode_stateid(argp, &open->op_delegate_stateid);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1050) if (status)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1051) return status;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1052) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1053) default:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1054) goto xdr_error;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1055) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1056)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1057) DECODE_TAIL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1058) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1059)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1060) static __be32
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1061) nfsd4_decode_open_confirm(struct nfsd4_compoundargs *argp, struct nfsd4_open_confirm *open_conf)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1062) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1063) DECODE_HEAD;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1064)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1065) if (argp->minorversion >= 1)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1066) return nfserr_notsupp;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1067)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1068) status = nfsd4_decode_stateid(argp, &open_conf->oc_req_stateid);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1069) if (status)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1070) return status;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1071) READ_BUF(4);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1072) open_conf->oc_seqid = be32_to_cpup(p++);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1073)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1074) DECODE_TAIL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1075) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1076)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1077) static __be32
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1078) nfsd4_decode_open_downgrade(struct nfsd4_compoundargs *argp, struct nfsd4_open_downgrade *open_down)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1079) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1080) DECODE_HEAD;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1081)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1082) status = nfsd4_decode_stateid(argp, &open_down->od_stateid);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1083) if (status)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1084) return status;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1085) READ_BUF(4);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1086) open_down->od_seqid = be32_to_cpup(p++);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1087) status = nfsd4_decode_share_access(argp, &open_down->od_share_access,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1088) &open_down->od_deleg_want, NULL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1089) if (status)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1090) return status;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1091) status = nfsd4_decode_share_deny(argp, &open_down->od_share_deny);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1092) if (status)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1093) return status;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1094) DECODE_TAIL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1095) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1096)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1097) static __be32
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1098) nfsd4_decode_putfh(struct nfsd4_compoundargs *argp, struct nfsd4_putfh *putfh)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1099) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1100) DECODE_HEAD;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1101)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1102) READ_BUF(4);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1103) putfh->pf_fhlen = be32_to_cpup(p++);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1104) if (putfh->pf_fhlen > NFS4_FHSIZE)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1105) goto xdr_error;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1106) READ_BUF(putfh->pf_fhlen);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1107) SAVEMEM(putfh->pf_fhval, putfh->pf_fhlen);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1108)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1109) DECODE_TAIL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1110) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1111)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1112) static __be32
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1113) nfsd4_decode_putpubfh(struct nfsd4_compoundargs *argp, void *p)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1114) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1115) if (argp->minorversion == 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1116) return nfs_ok;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1117) return nfserr_notsupp;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1118) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1119)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1120) static __be32
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1121) nfsd4_decode_read(struct nfsd4_compoundargs *argp, struct nfsd4_read *read)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1122) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1123) DECODE_HEAD;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1124)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1125) status = nfsd4_decode_stateid(argp, &read->rd_stateid);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1126) if (status)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1127) return status;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1128) READ_BUF(12);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1129) p = xdr_decode_hyper(p, &read->rd_offset);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1130) read->rd_length = be32_to_cpup(p++);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1131)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1132) DECODE_TAIL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1133) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1134)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1135) static __be32
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1136) nfsd4_decode_readdir(struct nfsd4_compoundargs *argp, struct nfsd4_readdir *readdir)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1137) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1138) DECODE_HEAD;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1139)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1140) READ_BUF(24);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1141) p = xdr_decode_hyper(p, &readdir->rd_cookie);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1142) COPYMEM(readdir->rd_verf.data, sizeof(readdir->rd_verf.data));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1143) readdir->rd_dircount = be32_to_cpup(p++);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1144) readdir->rd_maxcount = be32_to_cpup(p++);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1145) if ((status = nfsd4_decode_bitmap(argp, readdir->rd_bmval)))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1146) goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1147)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1148) DECODE_TAIL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1149) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1150)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1151) static __be32
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1152) nfsd4_decode_remove(struct nfsd4_compoundargs *argp, struct nfsd4_remove *remove)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1153) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1154) DECODE_HEAD;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1155)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1156) READ_BUF(4);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1157) remove->rm_namelen = be32_to_cpup(p++);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1158) READ_BUF(remove->rm_namelen);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1159) SAVEMEM(remove->rm_name, remove->rm_namelen);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1160) if ((status = check_filename(remove->rm_name, remove->rm_namelen)))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1161) return status;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1162)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1163) DECODE_TAIL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1164) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1165)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1166) static __be32
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1167) nfsd4_decode_rename(struct nfsd4_compoundargs *argp, struct nfsd4_rename *rename)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1168) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1169) DECODE_HEAD;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1170)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1171) READ_BUF(4);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1172) rename->rn_snamelen = be32_to_cpup(p++);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1173) READ_BUF(rename->rn_snamelen);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1174) SAVEMEM(rename->rn_sname, rename->rn_snamelen);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1175) READ_BUF(4);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1176) rename->rn_tnamelen = be32_to_cpup(p++);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1177) READ_BUF(rename->rn_tnamelen);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1178) SAVEMEM(rename->rn_tname, rename->rn_tnamelen);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1179) if ((status = check_filename(rename->rn_sname, rename->rn_snamelen)))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1180) return status;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1181) if ((status = check_filename(rename->rn_tname, rename->rn_tnamelen)))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1182) return status;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1183)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1184) DECODE_TAIL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1185) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1186)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1187) static __be32
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1188) nfsd4_decode_renew(struct nfsd4_compoundargs *argp, clientid_t *clientid)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1189) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1190) DECODE_HEAD;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1191)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1192) if (argp->minorversion >= 1)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1193) return nfserr_notsupp;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1194)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1195) READ_BUF(sizeof(clientid_t));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1196) COPYMEM(clientid, sizeof(clientid_t));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1197)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1198) DECODE_TAIL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1199) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1200)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1201) static __be32
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1202) nfsd4_decode_secinfo(struct nfsd4_compoundargs *argp,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1203) struct nfsd4_secinfo *secinfo)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1204) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1205) DECODE_HEAD;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1206)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1207) READ_BUF(4);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1208) secinfo->si_namelen = be32_to_cpup(p++);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1209) READ_BUF(secinfo->si_namelen);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1210) SAVEMEM(secinfo->si_name, secinfo->si_namelen);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1211) status = check_filename(secinfo->si_name, secinfo->si_namelen);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1212) if (status)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1213) return status;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1214) DECODE_TAIL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1215) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1216)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1217) static __be32
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1218) nfsd4_decode_secinfo_no_name(struct nfsd4_compoundargs *argp,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1219) struct nfsd4_secinfo_no_name *sin)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1220) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1221) DECODE_HEAD;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1222)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1223) READ_BUF(4);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1224) sin->sin_style = be32_to_cpup(p++);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1225) DECODE_TAIL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1226) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1227)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1228) static __be32
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1229) nfsd4_decode_setattr(struct nfsd4_compoundargs *argp, struct nfsd4_setattr *setattr)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1230) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1231) __be32 status;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1232)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1233) status = nfsd4_decode_stateid(argp, &setattr->sa_stateid);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1234) if (status)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1235) return status;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1236) return nfsd4_decode_fattr(argp, setattr->sa_bmval, &setattr->sa_iattr,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1237) &setattr->sa_acl, &setattr->sa_label, NULL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1238) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1239)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1240) static __be32
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1241) nfsd4_decode_setclientid(struct nfsd4_compoundargs *argp, struct nfsd4_setclientid *setclientid)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1242) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1243) DECODE_HEAD;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1244)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1245) if (argp->minorversion >= 1)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1246) return nfserr_notsupp;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1247)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1248) READ_BUF(NFS4_VERIFIER_SIZE);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1249) COPYMEM(setclientid->se_verf.data, NFS4_VERIFIER_SIZE);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1250)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1251) status = nfsd4_decode_opaque(argp, &setclientid->se_name);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1252) if (status)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1253) return nfserr_bad_xdr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1254) READ_BUF(8);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1255) setclientid->se_callback_prog = be32_to_cpup(p++);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1256) setclientid->se_callback_netid_len = be32_to_cpup(p++);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1257) READ_BUF(setclientid->se_callback_netid_len);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1258) SAVEMEM(setclientid->se_callback_netid_val, setclientid->se_callback_netid_len);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1259) READ_BUF(4);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1260) setclientid->se_callback_addr_len = be32_to_cpup(p++);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1261)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1262) READ_BUF(setclientid->se_callback_addr_len);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1263) SAVEMEM(setclientid->se_callback_addr_val, setclientid->se_callback_addr_len);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1264) READ_BUF(4);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1265) setclientid->se_callback_ident = be32_to_cpup(p++);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1266)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1267) DECODE_TAIL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1268) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1269)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1270) static __be32
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1271) nfsd4_decode_setclientid_confirm(struct nfsd4_compoundargs *argp, struct nfsd4_setclientid_confirm *scd_c)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1272) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1273) DECODE_HEAD;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1274)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1275) if (argp->minorversion >= 1)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1276) return nfserr_notsupp;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1277)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1278) READ_BUF(8 + NFS4_VERIFIER_SIZE);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1279) COPYMEM(&scd_c->sc_clientid, 8);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1280) COPYMEM(&scd_c->sc_confirm, NFS4_VERIFIER_SIZE);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1281)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1282) DECODE_TAIL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1283) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1284)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1285) /* Also used for NVERIFY */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1286) static __be32
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1287) nfsd4_decode_verify(struct nfsd4_compoundargs *argp, struct nfsd4_verify *verify)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1288) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1289) DECODE_HEAD;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1290)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1291) if ((status = nfsd4_decode_bitmap(argp, verify->ve_bmval)))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1292) goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1293)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1294) /* For convenience's sake, we compare raw xdr'd attributes in
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1295) * nfsd4_proc_verify */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1296)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1297) READ_BUF(4);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1298) verify->ve_attrlen = be32_to_cpup(p++);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1299) READ_BUF(verify->ve_attrlen);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1300) SAVEMEM(verify->ve_attrval, verify->ve_attrlen);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1301)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1302) DECODE_TAIL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1303) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1304)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1305) static __be32
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1306) nfsd4_decode_write(struct nfsd4_compoundargs *argp, struct nfsd4_write *write)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1307) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1308) DECODE_HEAD;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1309)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1310) status = nfsd4_decode_stateid(argp, &write->wr_stateid);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1311) if (status)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1312) return status;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1313) READ_BUF(16);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1314) p = xdr_decode_hyper(p, &write->wr_offset);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1315) write->wr_stable_how = be32_to_cpup(p++);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1316) if (write->wr_stable_how > NFS_FILE_SYNC)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1317) goto xdr_error;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1318) write->wr_buflen = be32_to_cpup(p++);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1319)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1320) status = svcxdr_construct_vector(argp, &write->wr_head,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1321) &write->wr_pagelist, write->wr_buflen);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1322) if (status)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1323) return status;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1324)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1325) DECODE_TAIL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1326) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1327)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1328) static __be32
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1329) nfsd4_decode_release_lockowner(struct nfsd4_compoundargs *argp, struct nfsd4_release_lockowner *rlockowner)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1330) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1331) DECODE_HEAD;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1332)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1333) if (argp->minorversion >= 1)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1334) return nfserr_notsupp;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1335)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1336) READ_BUF(12);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1337) COPYMEM(&rlockowner->rl_clientid, sizeof(clientid_t));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1338) rlockowner->rl_owner.len = be32_to_cpup(p++);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1339) READ_BUF(rlockowner->rl_owner.len);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1340) READMEM(rlockowner->rl_owner.data, rlockowner->rl_owner.len);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1341)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1342) if (argp->minorversion && !zero_clientid(&rlockowner->rl_clientid))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1343) return nfserr_inval;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1344) DECODE_TAIL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1345) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1346)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1347) static __be32
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1348) nfsd4_decode_exchange_id(struct nfsd4_compoundargs *argp,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1349) struct nfsd4_exchange_id *exid)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1350) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1351) int dummy, tmp;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1352) DECODE_HEAD;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1353)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1354) READ_BUF(NFS4_VERIFIER_SIZE);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1355) COPYMEM(exid->verifier.data, NFS4_VERIFIER_SIZE);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1356)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1357) status = nfsd4_decode_opaque(argp, &exid->clname);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1358) if (status)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1359) return nfserr_bad_xdr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1360)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1361) READ_BUF(4);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1362) exid->flags = be32_to_cpup(p++);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1363)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1364) /* Ignore state_protect4_a */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1365) READ_BUF(4);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1366) exid->spa_how = be32_to_cpup(p++);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1367) switch (exid->spa_how) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1368) case SP4_NONE:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1369) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1370) case SP4_MACH_CRED:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1371) /* spo_must_enforce */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1372) status = nfsd4_decode_bitmap(argp,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1373) exid->spo_must_enforce);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1374) if (status)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1375) goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1376) /* spo_must_allow */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1377) status = nfsd4_decode_bitmap(argp, exid->spo_must_allow);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1378) if (status)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1379) goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1380) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1381) case SP4_SSV:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1382) /* ssp_ops */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1383) READ_BUF(4);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1384) dummy = be32_to_cpup(p++);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1385) READ_BUF(dummy * 4);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1386) p += dummy;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1387)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1388) READ_BUF(4);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1389) dummy = be32_to_cpup(p++);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1390) READ_BUF(dummy * 4);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1391) p += dummy;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1392)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1393) /* ssp_hash_algs<> */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1394) READ_BUF(4);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1395) tmp = be32_to_cpup(p++);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1396) while (tmp--) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1397) READ_BUF(4);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1398) dummy = be32_to_cpup(p++);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1399) READ_BUF(dummy);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1400) p += XDR_QUADLEN(dummy);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1401) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1402)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1403) /* ssp_encr_algs<> */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1404) READ_BUF(4);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1405) tmp = be32_to_cpup(p++);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1406) while (tmp--) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1407) READ_BUF(4);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1408) dummy = be32_to_cpup(p++);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1409) READ_BUF(dummy);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1410) p += XDR_QUADLEN(dummy);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1411) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1412)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1413) /* ignore ssp_window and ssp_num_gss_handles: */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1414) READ_BUF(8);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1415) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1416) default:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1417) goto xdr_error;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1418) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1419)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1420) READ_BUF(4); /* nfs_impl_id4 array length */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1421) dummy = be32_to_cpup(p++);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1422)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1423) if (dummy > 1)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1424) goto xdr_error;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1425)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1426) if (dummy == 1) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1427) status = nfsd4_decode_opaque(argp, &exid->nii_domain);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1428) if (status)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1429) goto xdr_error;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1430)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1431) /* nii_name */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1432) status = nfsd4_decode_opaque(argp, &exid->nii_name);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1433) if (status)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1434) goto xdr_error;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1435)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1436) /* nii_date */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1437) status = nfsd4_decode_time(argp, &exid->nii_time);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1438) if (status)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1439) goto xdr_error;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1440) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1441) DECODE_TAIL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1442) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1443)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1444) static __be32
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1445) nfsd4_decode_create_session(struct nfsd4_compoundargs *argp,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1446) struct nfsd4_create_session *sess)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1447) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1448) DECODE_HEAD;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1449)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1450) READ_BUF(16);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1451) COPYMEM(&sess->clientid, 8);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1452) sess->seqid = be32_to_cpup(p++);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1453) sess->flags = be32_to_cpup(p++);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1454)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1455) /* Fore channel attrs */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1456) READ_BUF(28);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1457) p++; /* headerpadsz is always 0 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1458) sess->fore_channel.maxreq_sz = be32_to_cpup(p++);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1459) sess->fore_channel.maxresp_sz = be32_to_cpup(p++);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1460) sess->fore_channel.maxresp_cached = be32_to_cpup(p++);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1461) sess->fore_channel.maxops = be32_to_cpup(p++);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1462) sess->fore_channel.maxreqs = be32_to_cpup(p++);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1463) sess->fore_channel.nr_rdma_attrs = be32_to_cpup(p++);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1464) if (sess->fore_channel.nr_rdma_attrs == 1) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1465) READ_BUF(4);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1466) sess->fore_channel.rdma_attrs = be32_to_cpup(p++);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1467) } else if (sess->fore_channel.nr_rdma_attrs > 1) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1468) dprintk("Too many fore channel attr bitmaps!\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1469) goto xdr_error;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1470) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1471)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1472) /* Back channel attrs */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1473) READ_BUF(28);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1474) p++; /* headerpadsz is always 0 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1475) sess->back_channel.maxreq_sz = be32_to_cpup(p++);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1476) sess->back_channel.maxresp_sz = be32_to_cpup(p++);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1477) sess->back_channel.maxresp_cached = be32_to_cpup(p++);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1478) sess->back_channel.maxops = be32_to_cpup(p++);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1479) sess->back_channel.maxreqs = be32_to_cpup(p++);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1480) sess->back_channel.nr_rdma_attrs = be32_to_cpup(p++);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1481) if (sess->back_channel.nr_rdma_attrs == 1) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1482) READ_BUF(4);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1483) sess->back_channel.rdma_attrs = be32_to_cpup(p++);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1484) } else if (sess->back_channel.nr_rdma_attrs > 1) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1485) dprintk("Too many back channel attr bitmaps!\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1486) goto xdr_error;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1487) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1488)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1489) READ_BUF(4);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1490) sess->callback_prog = be32_to_cpup(p++);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1491) nfsd4_decode_cb_sec(argp, &sess->cb_sec);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1492) DECODE_TAIL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1493) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1494)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1495) static __be32
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1496) nfsd4_decode_destroy_session(struct nfsd4_compoundargs *argp,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1497) struct nfsd4_destroy_session *destroy_session)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1498) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1499) DECODE_HEAD;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1500) READ_BUF(NFS4_MAX_SESSIONID_LEN);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1501) COPYMEM(destroy_session->sessionid.data, NFS4_MAX_SESSIONID_LEN);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1502)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1503) DECODE_TAIL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1504) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1505)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1506) static __be32
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1507) nfsd4_decode_free_stateid(struct nfsd4_compoundargs *argp,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1508) struct nfsd4_free_stateid *free_stateid)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1509) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1510) DECODE_HEAD;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1511)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1512) READ_BUF(sizeof(stateid_t));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1513) free_stateid->fr_stateid.si_generation = be32_to_cpup(p++);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1514) COPYMEM(&free_stateid->fr_stateid.si_opaque, sizeof(stateid_opaque_t));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1515)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1516) DECODE_TAIL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1517) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1518)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1519) static __be32
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1520) nfsd4_decode_sequence(struct nfsd4_compoundargs *argp,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1521) struct nfsd4_sequence *seq)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1522) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1523) DECODE_HEAD;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1524)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1525) READ_BUF(NFS4_MAX_SESSIONID_LEN + 16);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1526) COPYMEM(seq->sessionid.data, NFS4_MAX_SESSIONID_LEN);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1527) seq->seqid = be32_to_cpup(p++);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1528) seq->slotid = be32_to_cpup(p++);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1529) seq->maxslots = be32_to_cpup(p++);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1530) seq->cachethis = be32_to_cpup(p++);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1531)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1532) DECODE_TAIL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1533) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1534)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1535) static __be32
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1536) nfsd4_decode_test_stateid(struct nfsd4_compoundargs *argp, struct nfsd4_test_stateid *test_stateid)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1537) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1538) int i;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1539) __be32 *p, status;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1540) struct nfsd4_test_stateid_id *stateid;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1541)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1542) READ_BUF(4);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1543) test_stateid->ts_num_ids = ntohl(*p++);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1544)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1545) INIT_LIST_HEAD(&test_stateid->ts_stateid_list);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1546)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1547) for (i = 0; i < test_stateid->ts_num_ids; i++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1548) stateid = svcxdr_tmpalloc(argp, sizeof(*stateid));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1549) if (!stateid) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1550) status = nfserrno(-ENOMEM);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1551) goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1552) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1553)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1554) INIT_LIST_HEAD(&stateid->ts_id_list);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1555) list_add_tail(&stateid->ts_id_list, &test_stateid->ts_stateid_list);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1556)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1557) status = nfsd4_decode_stateid(argp, &stateid->ts_id_stateid);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1558) if (status)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1559) goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1560) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1561)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1562) status = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1563) out:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1564) return status;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1565) xdr_error:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1566) dprintk("NFSD: xdr error (%s:%d)\n", __FILE__, __LINE__);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1567) status = nfserr_bad_xdr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1568) goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1569) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1570)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1571) static __be32 nfsd4_decode_destroy_clientid(struct nfsd4_compoundargs *argp, struct nfsd4_destroy_clientid *dc)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1572) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1573) DECODE_HEAD;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1574)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1575) READ_BUF(8);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1576) COPYMEM(&dc->clientid, 8);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1577)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1578) DECODE_TAIL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1579) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1580)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1581) static __be32 nfsd4_decode_reclaim_complete(struct nfsd4_compoundargs *argp, struct nfsd4_reclaim_complete *rc)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1582) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1583) DECODE_HEAD;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1584)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1585) READ_BUF(4);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1586) rc->rca_one_fs = be32_to_cpup(p++);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1587)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1588) DECODE_TAIL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1589) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1590)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1591) #ifdef CONFIG_NFSD_PNFS
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1592) static __be32
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1593) nfsd4_decode_getdeviceinfo(struct nfsd4_compoundargs *argp,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1594) struct nfsd4_getdeviceinfo *gdev)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1595) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1596) DECODE_HEAD;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1597) u32 num, i;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1598)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1599) READ_BUF(sizeof(struct nfsd4_deviceid) + 3 * 4);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1600) COPYMEM(&gdev->gd_devid, sizeof(struct nfsd4_deviceid));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1601) gdev->gd_layout_type = be32_to_cpup(p++);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1602) gdev->gd_maxcount = be32_to_cpup(p++);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1603) num = be32_to_cpup(p++);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1604) if (num) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1605) if (num > 1000)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1606) goto xdr_error;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1607) READ_BUF(4 * num);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1608) gdev->gd_notify_types = be32_to_cpup(p++);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1609) for (i = 1; i < num; i++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1610) if (be32_to_cpup(p++)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1611) status = nfserr_inval;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1612) goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1613) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1614) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1615) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1616) DECODE_TAIL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1617) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1618)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1619) static __be32
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1620) nfsd4_decode_layoutget(struct nfsd4_compoundargs *argp,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1621) struct nfsd4_layoutget *lgp)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1622) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1623) DECODE_HEAD;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1624)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1625) READ_BUF(36);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1626) lgp->lg_signal = be32_to_cpup(p++);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1627) lgp->lg_layout_type = be32_to_cpup(p++);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1628) lgp->lg_seg.iomode = be32_to_cpup(p++);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1629) p = xdr_decode_hyper(p, &lgp->lg_seg.offset);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1630) p = xdr_decode_hyper(p, &lgp->lg_seg.length);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1631) p = xdr_decode_hyper(p, &lgp->lg_minlength);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1632)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1633) status = nfsd4_decode_stateid(argp, &lgp->lg_sid);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1634) if (status)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1635) return status;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1636)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1637) READ_BUF(4);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1638) lgp->lg_maxcount = be32_to_cpup(p++);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1639)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1640) DECODE_TAIL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1641) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1642)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1643) static __be32
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1644) nfsd4_decode_layoutcommit(struct nfsd4_compoundargs *argp,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1645) struct nfsd4_layoutcommit *lcp)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1646) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1647) DECODE_HEAD;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1648) u32 timechange;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1649)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1650) READ_BUF(20);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1651) p = xdr_decode_hyper(p, &lcp->lc_seg.offset);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1652) p = xdr_decode_hyper(p, &lcp->lc_seg.length);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1653) lcp->lc_reclaim = be32_to_cpup(p++);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1654)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1655) status = nfsd4_decode_stateid(argp, &lcp->lc_sid);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1656) if (status)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1657) return status;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1658)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1659) READ_BUF(4);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1660) lcp->lc_newoffset = be32_to_cpup(p++);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1661) if (lcp->lc_newoffset) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1662) READ_BUF(8);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1663) p = xdr_decode_hyper(p, &lcp->lc_last_wr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1664) } else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1665) lcp->lc_last_wr = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1666) READ_BUF(4);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1667) timechange = be32_to_cpup(p++);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1668) if (timechange) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1669) status = nfsd4_decode_time(argp, &lcp->lc_mtime);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1670) if (status)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1671) return status;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1672) } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1673) lcp->lc_mtime.tv_nsec = UTIME_NOW;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1674) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1675) READ_BUF(8);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1676) lcp->lc_layout_type = be32_to_cpup(p++);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1677)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1678) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1679) * Save the layout update in XDR format and let the layout driver deal
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1680) * with it later.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1681) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1682) lcp->lc_up_len = be32_to_cpup(p++);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1683) if (lcp->lc_up_len > 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1684) READ_BUF(lcp->lc_up_len);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1685) READMEM(lcp->lc_up_layout, lcp->lc_up_len);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1686) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1687)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1688) DECODE_TAIL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1689) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1690)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1691) static __be32
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1692) nfsd4_decode_layoutreturn(struct nfsd4_compoundargs *argp,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1693) struct nfsd4_layoutreturn *lrp)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1694) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1695) DECODE_HEAD;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1696)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1697) READ_BUF(16);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1698) lrp->lr_reclaim = be32_to_cpup(p++);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1699) lrp->lr_layout_type = be32_to_cpup(p++);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1700) lrp->lr_seg.iomode = be32_to_cpup(p++);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1701) lrp->lr_return_type = be32_to_cpup(p++);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1702) if (lrp->lr_return_type == RETURN_FILE) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1703) READ_BUF(16);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1704) p = xdr_decode_hyper(p, &lrp->lr_seg.offset);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1705) p = xdr_decode_hyper(p, &lrp->lr_seg.length);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1706)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1707) status = nfsd4_decode_stateid(argp, &lrp->lr_sid);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1708) if (status)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1709) return status;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1710)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1711) READ_BUF(4);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1712) lrp->lrf_body_len = be32_to_cpup(p++);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1713) if (lrp->lrf_body_len > 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1714) READ_BUF(lrp->lrf_body_len);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1715) READMEM(lrp->lrf_body, lrp->lrf_body_len);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1716) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1717) } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1718) lrp->lr_seg.offset = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1719) lrp->lr_seg.length = NFS4_MAX_UINT64;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1720) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1721)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1722) DECODE_TAIL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1723) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1724) #endif /* CONFIG_NFSD_PNFS */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1725)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1726) static __be32
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1727) nfsd4_decode_fallocate(struct nfsd4_compoundargs *argp,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1728) struct nfsd4_fallocate *fallocate)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1729) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1730) DECODE_HEAD;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1731)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1732) status = nfsd4_decode_stateid(argp, &fallocate->falloc_stateid);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1733) if (status)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1734) return status;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1735)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1736) READ_BUF(16);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1737) p = xdr_decode_hyper(p, &fallocate->falloc_offset);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1738) xdr_decode_hyper(p, &fallocate->falloc_length);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1739)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1740) DECODE_TAIL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1741) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1742)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1743) static __be32
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1744) nfsd4_decode_clone(struct nfsd4_compoundargs *argp, struct nfsd4_clone *clone)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1745) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1746) DECODE_HEAD;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1747)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1748) status = nfsd4_decode_stateid(argp, &clone->cl_src_stateid);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1749) if (status)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1750) return status;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1751) status = nfsd4_decode_stateid(argp, &clone->cl_dst_stateid);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1752) if (status)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1753) return status;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1754)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1755) READ_BUF(8 + 8 + 8);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1756) p = xdr_decode_hyper(p, &clone->cl_src_pos);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1757) p = xdr_decode_hyper(p, &clone->cl_dst_pos);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1758) p = xdr_decode_hyper(p, &clone->cl_count);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1759) DECODE_TAIL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1760) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1761)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1762) static __be32 nfsd4_decode_nl4_server(struct nfsd4_compoundargs *argp,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1763) struct nl4_server *ns)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1764) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1765) DECODE_HEAD;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1766) struct nfs42_netaddr *naddr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1767)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1768) READ_BUF(4);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1769) ns->nl4_type = be32_to_cpup(p++);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1770)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1771) /* currently support for 1 inter-server source server */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1772) switch (ns->nl4_type) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1773) case NL4_NETADDR:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1774) naddr = &ns->u.nl4_addr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1775)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1776) READ_BUF(4);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1777) naddr->netid_len = be32_to_cpup(p++);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1778) if (naddr->netid_len > RPCBIND_MAXNETIDLEN)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1779) goto xdr_error;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1780)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1781) READ_BUF(naddr->netid_len + 4); /* 4 for uaddr len */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1782) COPYMEM(naddr->netid, naddr->netid_len);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1783)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1784) naddr->addr_len = be32_to_cpup(p++);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1785) if (naddr->addr_len > RPCBIND_MAXUADDRLEN)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1786) goto xdr_error;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1787)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1788) READ_BUF(naddr->addr_len);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1789) COPYMEM(naddr->addr, naddr->addr_len);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1790) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1791) default:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1792) goto xdr_error;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1793) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1794) DECODE_TAIL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1795) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1796)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1797) static __be32
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1798) nfsd4_decode_copy(struct nfsd4_compoundargs *argp, struct nfsd4_copy *copy)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1799) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1800) DECODE_HEAD;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1801) struct nl4_server *ns_dummy;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1802) int i, count;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1803)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1804) status = nfsd4_decode_stateid(argp, ©->cp_src_stateid);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1805) if (status)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1806) return status;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1807) status = nfsd4_decode_stateid(argp, ©->cp_dst_stateid);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1808) if (status)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1809) return status;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1810)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1811) READ_BUF(8 + 8 + 8 + 4 + 4 + 4);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1812) p = xdr_decode_hyper(p, ©->cp_src_pos);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1813) p = xdr_decode_hyper(p, ©->cp_dst_pos);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1814) p = xdr_decode_hyper(p, ©->cp_count);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1815) p++; /* ca_consecutive: we always do consecutive copies */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1816) copy->cp_synchronous = be32_to_cpup(p++);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1817)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1818) count = be32_to_cpup(p++);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1819)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1820) copy->cp_intra = false;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1821) if (count == 0) { /* intra-server copy */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1822) copy->cp_intra = true;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1823) goto intra;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1824) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1825)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1826) /* decode all the supplied server addresses but use first */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1827) status = nfsd4_decode_nl4_server(argp, ©->cp_src);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1828) if (status)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1829) return status;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1830)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1831) ns_dummy = kmalloc(sizeof(struct nl4_server), GFP_KERNEL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1832) if (ns_dummy == NULL)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1833) return nfserrno(-ENOMEM);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1834) for (i = 0; i < count - 1; i++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1835) status = nfsd4_decode_nl4_server(argp, ns_dummy);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1836) if (status) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1837) kfree(ns_dummy);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1838) return status;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1839) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1840) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1841) kfree(ns_dummy);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1842) intra:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1843)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1844) DECODE_TAIL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1845) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1846)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1847) static __be32
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1848) nfsd4_decode_offload_status(struct nfsd4_compoundargs *argp,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1849) struct nfsd4_offload_status *os)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1850) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1851) return nfsd4_decode_stateid(argp, &os->stateid);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1852) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1853)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1854) static __be32
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1855) nfsd4_decode_copy_notify(struct nfsd4_compoundargs *argp,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1856) struct nfsd4_copy_notify *cn)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1857) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1858) __be32 status;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1859)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1860) status = nfsd4_decode_stateid(argp, &cn->cpn_src_stateid);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1861) if (status)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1862) return status;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1863) return nfsd4_decode_nl4_server(argp, &cn->cpn_dst);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1864) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1865)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1866) static __be32
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1867) nfsd4_decode_seek(struct nfsd4_compoundargs *argp, struct nfsd4_seek *seek)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1868) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1869) DECODE_HEAD;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1870)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1871) status = nfsd4_decode_stateid(argp, &seek->seek_stateid);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1872) if (status)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1873) return status;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1874)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1875) READ_BUF(8 + 4);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1876) p = xdr_decode_hyper(p, &seek->seek_offset);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1877) seek->seek_whence = be32_to_cpup(p);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1878)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1879) DECODE_TAIL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1880) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1881)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1882) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1883) * XDR data that is more than PAGE_SIZE in size is normally part of a
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1884) * read or write. However, the size of extended attributes is limited
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1885) * by the maximum request size, and then further limited by the underlying
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1886) * filesystem limits. This can exceed PAGE_SIZE (currently, XATTR_SIZE_MAX
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1887) * is 64k). Since there is no kvec- or page-based interface to xattrs,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1888) * and we're not dealing with contiguous pages, we need to do some copying.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1889) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1890)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1891) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1892) * Decode data into buffer. Uses head and pages constructed by
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1893) * svcxdr_construct_vector.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1894) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1895) static __be32
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1896) nfsd4_vbuf_from_vector(struct nfsd4_compoundargs *argp, struct kvec *head,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1897) struct page **pages, char **bufp, u32 buflen)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1898) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1899) char *tmp, *dp;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1900) u32 len;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1901)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1902) if (buflen <= head->iov_len) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1903) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1904) * We're in luck, the head has enough space. Just return
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1905) * the head, no need for copying.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1906) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1907) *bufp = head->iov_base;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1908) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1909) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1910)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1911) tmp = svcxdr_tmpalloc(argp, buflen);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1912) if (tmp == NULL)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1913) return nfserr_jukebox;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1914)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1915) dp = tmp;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1916) memcpy(dp, head->iov_base, head->iov_len);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1917) buflen -= head->iov_len;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1918) dp += head->iov_len;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1919)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1920) while (buflen > 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1921) len = min_t(u32, buflen, PAGE_SIZE);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1922) memcpy(dp, page_address(*pages), len);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1923)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1924) buflen -= len;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1925) dp += len;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1926) pages++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1927) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1928)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1929) *bufp = tmp;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1930) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1931) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1932)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1933) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1934) * Get a user extended attribute name from the XDR buffer.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1935) * It will not have the "user." prefix, so prepend it.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1936) * Lastly, check for nul characters in the name.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1937) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1938) static __be32
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1939) nfsd4_decode_xattr_name(struct nfsd4_compoundargs *argp, char **namep)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1940) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1941) DECODE_HEAD;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1942) char *name, *sp, *dp;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1943) u32 namelen, cnt;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1944)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1945) READ_BUF(4);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1946) namelen = be32_to_cpup(p++);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1947)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1948) if (namelen > (XATTR_NAME_MAX - XATTR_USER_PREFIX_LEN))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1949) return nfserr_nametoolong;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1950)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1951) if (namelen == 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1952) goto xdr_error;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1953)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1954) READ_BUF(namelen);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1955)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1956) name = svcxdr_tmpalloc(argp, namelen + XATTR_USER_PREFIX_LEN + 1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1957) if (!name)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1958) return nfserr_jukebox;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1959)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1960) memcpy(name, XATTR_USER_PREFIX, XATTR_USER_PREFIX_LEN);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1961)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1962) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1963) * Copy the extended attribute name over while checking for 0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1964) * characters.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1965) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1966) sp = (char *)p;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1967) dp = name + XATTR_USER_PREFIX_LEN;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1968) cnt = namelen;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1969)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1970) while (cnt-- > 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1971) if (*sp == '\0')
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1972) goto xdr_error;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1973) *dp++ = *sp++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1974) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1975) *dp = '\0';
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1976)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1977) *namep = name;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1978)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1979) DECODE_TAIL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1980) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1981)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1982) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1983) * A GETXATTR op request comes without a length specifier. We just set the
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1984) * maximum length for the reply based on XATTR_SIZE_MAX and the maximum
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1985) * channel reply size. nfsd_getxattr will probe the length of the xattr,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1986) * check it against getxa_len, and allocate + return the value.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1987) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1988) static __be32
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1989) nfsd4_decode_getxattr(struct nfsd4_compoundargs *argp,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1990) struct nfsd4_getxattr *getxattr)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1991) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1992) __be32 status;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1993) u32 maxcount;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1994)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1995) status = nfsd4_decode_xattr_name(argp, &getxattr->getxa_name);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1996) if (status)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1997) return status;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1998)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1999) maxcount = svc_max_payload(argp->rqstp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2000) maxcount = min_t(u32, XATTR_SIZE_MAX, maxcount);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2001)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2002) getxattr->getxa_len = maxcount;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2003)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2004) return status;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2005) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2006)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2007) static __be32
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2008) nfsd4_decode_setxattr(struct nfsd4_compoundargs *argp,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2009) struct nfsd4_setxattr *setxattr)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2010) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2011) DECODE_HEAD;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2012) u32 flags, maxcount, size;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2013) struct kvec head;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2014) struct page **pagelist;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2015)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2016) READ_BUF(4);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2017) flags = be32_to_cpup(p++);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2018)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2019) if (flags > SETXATTR4_REPLACE)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2020) return nfserr_inval;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2021) setxattr->setxa_flags = flags;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2022)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2023) status = nfsd4_decode_xattr_name(argp, &setxattr->setxa_name);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2024) if (status)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2025) return status;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2026)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2027) maxcount = svc_max_payload(argp->rqstp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2028) maxcount = min_t(u32, XATTR_SIZE_MAX, maxcount);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2029)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2030) READ_BUF(4);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2031) size = be32_to_cpup(p++);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2032) if (size > maxcount)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2033) return nfserr_xattr2big;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2034)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2035) setxattr->setxa_len = size;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2036) if (size > 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2037) status = svcxdr_construct_vector(argp, &head, &pagelist, size);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2038) if (status)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2039) return status;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2040)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2041) status = nfsd4_vbuf_from_vector(argp, &head, pagelist,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2042) &setxattr->setxa_buf, size);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2043) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2044)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2045) DECODE_TAIL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2046) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2047)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2048) static __be32
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2049) nfsd4_decode_listxattrs(struct nfsd4_compoundargs *argp,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2050) struct nfsd4_listxattrs *listxattrs)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2051) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2052) DECODE_HEAD;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2053) u32 maxcount;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2054)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2055) READ_BUF(12);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2056) p = xdr_decode_hyper(p, &listxattrs->lsxa_cookie);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2057)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2058) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2059) * If the cookie is too large to have even one user.x attribute
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2060) * plus trailing '\0' left in a maximum size buffer, it's invalid.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2061) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2062) if (listxattrs->lsxa_cookie >=
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2063) (XATTR_LIST_MAX / (XATTR_USER_PREFIX_LEN + 2)))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2064) return nfserr_badcookie;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2065)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2066) maxcount = be32_to_cpup(p++);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2067) if (maxcount < 8)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2068) /* Always need at least 2 words (length and one character) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2069) return nfserr_inval;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2070)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2071) maxcount = min(maxcount, svc_max_payload(argp->rqstp));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2072) listxattrs->lsxa_maxcount = maxcount;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2073)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2074) DECODE_TAIL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2075) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2076)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2077) static __be32
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2078) nfsd4_decode_removexattr(struct nfsd4_compoundargs *argp,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2079) struct nfsd4_removexattr *removexattr)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2080) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2081) return nfsd4_decode_xattr_name(argp, &removexattr->rmxa_name);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2082) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2083)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2084) static __be32
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2085) nfsd4_decode_noop(struct nfsd4_compoundargs *argp, void *p)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2086) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2087) return nfs_ok;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2088) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2089)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2090) static __be32
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2091) nfsd4_decode_notsupp(struct nfsd4_compoundargs *argp, void *p)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2092) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2093) return nfserr_notsupp;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2094) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2095)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2096) typedef __be32(*nfsd4_dec)(struct nfsd4_compoundargs *argp, void *);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2097)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2098) static const nfsd4_dec nfsd4_dec_ops[] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2099) [OP_ACCESS] = (nfsd4_dec)nfsd4_decode_access,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2100) [OP_CLOSE] = (nfsd4_dec)nfsd4_decode_close,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2101) [OP_COMMIT] = (nfsd4_dec)nfsd4_decode_commit,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2102) [OP_CREATE] = (nfsd4_dec)nfsd4_decode_create,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2103) [OP_DELEGPURGE] = (nfsd4_dec)nfsd4_decode_notsupp,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2104) [OP_DELEGRETURN] = (nfsd4_dec)nfsd4_decode_delegreturn,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2105) [OP_GETATTR] = (nfsd4_dec)nfsd4_decode_getattr,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2106) [OP_GETFH] = (nfsd4_dec)nfsd4_decode_noop,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2107) [OP_LINK] = (nfsd4_dec)nfsd4_decode_link,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2108) [OP_LOCK] = (nfsd4_dec)nfsd4_decode_lock,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2109) [OP_LOCKT] = (nfsd4_dec)nfsd4_decode_lockt,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2110) [OP_LOCKU] = (nfsd4_dec)nfsd4_decode_locku,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2111) [OP_LOOKUP] = (nfsd4_dec)nfsd4_decode_lookup,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2112) [OP_LOOKUPP] = (nfsd4_dec)nfsd4_decode_noop,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2113) [OP_NVERIFY] = (nfsd4_dec)nfsd4_decode_verify,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2114) [OP_OPEN] = (nfsd4_dec)nfsd4_decode_open,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2115) [OP_OPENATTR] = (nfsd4_dec)nfsd4_decode_notsupp,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2116) [OP_OPEN_CONFIRM] = (nfsd4_dec)nfsd4_decode_open_confirm,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2117) [OP_OPEN_DOWNGRADE] = (nfsd4_dec)nfsd4_decode_open_downgrade,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2118) [OP_PUTFH] = (nfsd4_dec)nfsd4_decode_putfh,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2119) [OP_PUTPUBFH] = (nfsd4_dec)nfsd4_decode_putpubfh,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2120) [OP_PUTROOTFH] = (nfsd4_dec)nfsd4_decode_noop,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2121) [OP_READ] = (nfsd4_dec)nfsd4_decode_read,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2122) [OP_READDIR] = (nfsd4_dec)nfsd4_decode_readdir,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2123) [OP_READLINK] = (nfsd4_dec)nfsd4_decode_noop,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2124) [OP_REMOVE] = (nfsd4_dec)nfsd4_decode_remove,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2125) [OP_RENAME] = (nfsd4_dec)nfsd4_decode_rename,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2126) [OP_RENEW] = (nfsd4_dec)nfsd4_decode_renew,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2127) [OP_RESTOREFH] = (nfsd4_dec)nfsd4_decode_noop,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2128) [OP_SAVEFH] = (nfsd4_dec)nfsd4_decode_noop,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2129) [OP_SECINFO] = (nfsd4_dec)nfsd4_decode_secinfo,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2130) [OP_SETATTR] = (nfsd4_dec)nfsd4_decode_setattr,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2131) [OP_SETCLIENTID] = (nfsd4_dec)nfsd4_decode_setclientid,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2132) [OP_SETCLIENTID_CONFIRM] = (nfsd4_dec)nfsd4_decode_setclientid_confirm,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2133) [OP_VERIFY] = (nfsd4_dec)nfsd4_decode_verify,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2134) [OP_WRITE] = (nfsd4_dec)nfsd4_decode_write,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2135) [OP_RELEASE_LOCKOWNER] = (nfsd4_dec)nfsd4_decode_release_lockowner,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2136)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2137) /* new operations for NFSv4.1 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2138) [OP_BACKCHANNEL_CTL] = (nfsd4_dec)nfsd4_decode_backchannel_ctl,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2139) [OP_BIND_CONN_TO_SESSION]= (nfsd4_dec)nfsd4_decode_bind_conn_to_session,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2140) [OP_EXCHANGE_ID] = (nfsd4_dec)nfsd4_decode_exchange_id,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2141) [OP_CREATE_SESSION] = (nfsd4_dec)nfsd4_decode_create_session,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2142) [OP_DESTROY_SESSION] = (nfsd4_dec)nfsd4_decode_destroy_session,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2143) [OP_FREE_STATEID] = (nfsd4_dec)nfsd4_decode_free_stateid,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2144) [OP_GET_DIR_DELEGATION] = (nfsd4_dec)nfsd4_decode_notsupp,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2145) #ifdef CONFIG_NFSD_PNFS
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2146) [OP_GETDEVICEINFO] = (nfsd4_dec)nfsd4_decode_getdeviceinfo,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2147) [OP_GETDEVICELIST] = (nfsd4_dec)nfsd4_decode_notsupp,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2148) [OP_LAYOUTCOMMIT] = (nfsd4_dec)nfsd4_decode_layoutcommit,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2149) [OP_LAYOUTGET] = (nfsd4_dec)nfsd4_decode_layoutget,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2150) [OP_LAYOUTRETURN] = (nfsd4_dec)nfsd4_decode_layoutreturn,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2151) #else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2152) [OP_GETDEVICEINFO] = (nfsd4_dec)nfsd4_decode_notsupp,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2153) [OP_GETDEVICELIST] = (nfsd4_dec)nfsd4_decode_notsupp,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2154) [OP_LAYOUTCOMMIT] = (nfsd4_dec)nfsd4_decode_notsupp,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2155) [OP_LAYOUTGET] = (nfsd4_dec)nfsd4_decode_notsupp,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2156) [OP_LAYOUTRETURN] = (nfsd4_dec)nfsd4_decode_notsupp,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2157) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2158) [OP_SECINFO_NO_NAME] = (nfsd4_dec)nfsd4_decode_secinfo_no_name,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2159) [OP_SEQUENCE] = (nfsd4_dec)nfsd4_decode_sequence,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2160) [OP_SET_SSV] = (nfsd4_dec)nfsd4_decode_notsupp,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2161) [OP_TEST_STATEID] = (nfsd4_dec)nfsd4_decode_test_stateid,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2162) [OP_WANT_DELEGATION] = (nfsd4_dec)nfsd4_decode_notsupp,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2163) [OP_DESTROY_CLIENTID] = (nfsd4_dec)nfsd4_decode_destroy_clientid,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2164) [OP_RECLAIM_COMPLETE] = (nfsd4_dec)nfsd4_decode_reclaim_complete,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2165)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2166) /* new operations for NFSv4.2 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2167) [OP_ALLOCATE] = (nfsd4_dec)nfsd4_decode_fallocate,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2168) [OP_COPY] = (nfsd4_dec)nfsd4_decode_copy,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2169) [OP_COPY_NOTIFY] = (nfsd4_dec)nfsd4_decode_copy_notify,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2170) [OP_DEALLOCATE] = (nfsd4_dec)nfsd4_decode_fallocate,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2171) [OP_IO_ADVISE] = (nfsd4_dec)nfsd4_decode_notsupp,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2172) [OP_LAYOUTERROR] = (nfsd4_dec)nfsd4_decode_notsupp,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2173) [OP_LAYOUTSTATS] = (nfsd4_dec)nfsd4_decode_notsupp,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2174) [OP_OFFLOAD_CANCEL] = (nfsd4_dec)nfsd4_decode_offload_status,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2175) [OP_OFFLOAD_STATUS] = (nfsd4_dec)nfsd4_decode_offload_status,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2176) [OP_READ_PLUS] = (nfsd4_dec)nfsd4_decode_read,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2177) [OP_SEEK] = (nfsd4_dec)nfsd4_decode_seek,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2178) [OP_WRITE_SAME] = (nfsd4_dec)nfsd4_decode_notsupp,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2179) [OP_CLONE] = (nfsd4_dec)nfsd4_decode_clone,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2180) /* RFC 8276 extended atributes operations */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2181) [OP_GETXATTR] = (nfsd4_dec)nfsd4_decode_getxattr,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2182) [OP_SETXATTR] = (nfsd4_dec)nfsd4_decode_setxattr,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2183) [OP_LISTXATTRS] = (nfsd4_dec)nfsd4_decode_listxattrs,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2184) [OP_REMOVEXATTR] = (nfsd4_dec)nfsd4_decode_removexattr,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2185) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2186)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2187) static inline bool
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2188) nfsd4_opnum_in_range(struct nfsd4_compoundargs *argp, struct nfsd4_op *op)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2189) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2190) if (op->opnum < FIRST_NFS4_OP)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2191) return false;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2192) else if (argp->minorversion == 0 && op->opnum > LAST_NFS40_OP)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2193) return false;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2194) else if (argp->minorversion == 1 && op->opnum > LAST_NFS41_OP)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2195) return false;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2196) else if (argp->minorversion == 2 && op->opnum > LAST_NFS42_OP)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2197) return false;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2198) return true;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2199) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2200)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2201) static __be32
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2202) nfsd4_decode_compound(struct nfsd4_compoundargs *argp)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2203) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2204) DECODE_HEAD;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2205) struct nfsd4_op *op;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2206) bool cachethis = false;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2207) int auth_slack= argp->rqstp->rq_auth_slack;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2208) int max_reply = auth_slack + 8; /* opcnt, status */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2209) int readcount = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2210) int readbytes = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2211) int i;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2212)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2213) READ_BUF(4);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2214) argp->taglen = be32_to_cpup(p++);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2215) READ_BUF(argp->taglen);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2216) SAVEMEM(argp->tag, argp->taglen);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2217) READ_BUF(8);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2218) argp->minorversion = be32_to_cpup(p++);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2219) argp->opcnt = be32_to_cpup(p++);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2220) max_reply += 4 + (XDR_QUADLEN(argp->taglen) << 2);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2221)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2222) if (argp->taglen > NFSD4_MAX_TAGLEN)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2223) goto xdr_error;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2224) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2225) * NFS4ERR_RESOURCE is a more helpful error than GARBAGE_ARGS
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2226) * here, so we return success at the xdr level so that
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2227) * nfsd4_proc can handle this is an NFS-level error.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2228) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2229) if (argp->opcnt > NFSD_MAX_OPS_PER_COMPOUND)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2230) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2231)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2232) if (argp->opcnt > ARRAY_SIZE(argp->iops)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2233) argp->ops = kzalloc(argp->opcnt * sizeof(*argp->ops), GFP_KERNEL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2234) if (!argp->ops) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2235) argp->ops = argp->iops;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2236) dprintk("nfsd: couldn't allocate room for COMPOUND\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2237) goto xdr_error;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2238) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2239) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2240)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2241) if (argp->minorversion > NFSD_SUPPORTED_MINOR_VERSION)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2242) argp->opcnt = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2243)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2244) for (i = 0; i < argp->opcnt; i++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2245) op = &argp->ops[i];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2246) op->replay = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2247)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2248) READ_BUF(4);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2249) op->opnum = be32_to_cpup(p++);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2250)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2251) if (nfsd4_opnum_in_range(argp, op))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2252) op->status = nfsd4_dec_ops[op->opnum](argp, &op->u);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2253) else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2254) op->opnum = OP_ILLEGAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2255) op->status = nfserr_op_illegal;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2256) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2257) op->opdesc = OPDESC(op);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2258) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2259) * We'll try to cache the result in the DRC if any one
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2260) * op in the compound wants to be cached:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2261) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2262) cachethis |= nfsd4_cache_this_op(op);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2263)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2264) if (op->opnum == OP_READ || op->opnum == OP_READ_PLUS) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2265) readcount++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2266) readbytes += nfsd4_max_reply(argp->rqstp, op);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2267) } else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2268) max_reply += nfsd4_max_reply(argp->rqstp, op);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2269) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2270) * OP_LOCK and OP_LOCKT may return a conflicting lock.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2271) * (Special case because it will just skip encoding this
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2272) * if it runs out of xdr buffer space, and it is the only
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2273) * operation that behaves this way.)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2274) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2275) if (op->opnum == OP_LOCK || op->opnum == OP_LOCKT)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2276) max_reply += NFS4_OPAQUE_LIMIT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2277)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2278) if (op->status) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2279) argp->opcnt = i+1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2280) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2281) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2282) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2283) /* Sessions make the DRC unnecessary: */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2284) if (argp->minorversion)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2285) cachethis = false;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2286) svc_reserve(argp->rqstp, max_reply + readbytes);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2287) argp->rqstp->rq_cachetype = cachethis ? RC_REPLBUFF : RC_NOCACHE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2288)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2289) if (readcount > 1 || max_reply > PAGE_SIZE - auth_slack)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2290) clear_bit(RQ_SPLICE_OK, &argp->rqstp->rq_flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2291)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2292) DECODE_TAIL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2293) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2294)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2295) static __be32 *encode_change(__be32 *p, struct kstat *stat, struct inode *inode,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2296) struct svc_export *exp)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2297) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2298) if (exp->ex_flags & NFSEXP_V4ROOT) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2299) *p++ = cpu_to_be32(convert_to_wallclock(exp->cd->flush_time));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2300) *p++ = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2301) } else if (IS_I_VERSION(inode)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2302) p = xdr_encode_hyper(p, nfsd4_change_attribute(stat, inode));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2303) } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2304) *p++ = cpu_to_be32(stat->ctime.tv_sec);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2305) *p++ = cpu_to_be32(stat->ctime.tv_nsec);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2306) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2307) return p;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2308) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2309)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2310) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2311) * ctime (in NFSv4, time_metadata) is not writeable, and the client
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2312) * doesn't really care what resolution could theoretically be stored by
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2313) * the filesystem.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2314) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2315) * The client cares how close together changes can be while still
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2316) * guaranteeing ctime changes. For most filesystems (which have
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2317) * timestamps with nanosecond fields) that is limited by the resolution
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2318) * of the time returned from current_time() (which I'm assuming to be
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2319) * 1/HZ).
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2320) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2321) static __be32 *encode_time_delta(__be32 *p, struct inode *inode)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2322) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2323) struct timespec64 ts;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2324) u32 ns;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2325)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2326) ns = max_t(u32, NSEC_PER_SEC/HZ, inode->i_sb->s_time_gran);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2327) ts = ns_to_timespec64(ns);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2328)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2329) p = xdr_encode_hyper(p, ts.tv_sec);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2330) *p++ = cpu_to_be32(ts.tv_nsec);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2331)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2332) return p;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2333) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2334)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2335) static __be32 *encode_cinfo(__be32 *p, struct nfsd4_change_info *c)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2336) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2337) *p++ = cpu_to_be32(c->atomic);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2338) if (c->change_supported) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2339) p = xdr_encode_hyper(p, c->before_change);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2340) p = xdr_encode_hyper(p, c->after_change);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2341) } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2342) *p++ = cpu_to_be32(c->before_ctime_sec);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2343) *p++ = cpu_to_be32(c->before_ctime_nsec);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2344) *p++ = cpu_to_be32(c->after_ctime_sec);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2345) *p++ = cpu_to_be32(c->after_ctime_nsec);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2346) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2347) return p;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2348) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2349)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2350) /* Encode as an array of strings the string given with components
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2351) * separated @sep, escaped with esc_enter and esc_exit.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2352) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2353) static __be32 nfsd4_encode_components_esc(struct xdr_stream *xdr, char sep,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2354) char *components, char esc_enter,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2355) char esc_exit)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2356) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2357) __be32 *p;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2358) __be32 pathlen;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2359) int pathlen_offset;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2360) int strlen, count=0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2361) char *str, *end, *next;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2362)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2363) dprintk("nfsd4_encode_components(%s)\n", components);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2364)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2365) pathlen_offset = xdr->buf->len;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2366) p = xdr_reserve_space(xdr, 4);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2367) if (!p)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2368) return nfserr_resource;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2369) p++; /* We will fill this in with @count later */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2370)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2371) end = str = components;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2372) while (*end) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2373) bool found_esc = false;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2374)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2375) /* try to parse as esc_start, ..., esc_end, sep */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2376) if (*str == esc_enter) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2377) for (; *end && (*end != esc_exit); end++)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2378) /* find esc_exit or end of string */;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2379) next = end + 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2380) if (*end && (!*next || *next == sep)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2381) str++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2382) found_esc = true;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2383) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2384) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2385)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2386) if (!found_esc)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2387) for (; *end && (*end != sep); end++)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2388) /* find sep or end of string */;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2389)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2390) strlen = end - str;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2391) if (strlen) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2392) p = xdr_reserve_space(xdr, strlen + 4);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2393) if (!p)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2394) return nfserr_resource;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2395) p = xdr_encode_opaque(p, str, strlen);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2396) count++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2397) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2398) else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2399) end++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2400) if (found_esc)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2401) end = next;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2402)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2403) str = end;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2404) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2405) pathlen = htonl(count);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2406) write_bytes_to_xdr_buf(xdr->buf, pathlen_offset, &pathlen, 4);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2407) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2408) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2409)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2410) /* Encode as an array of strings the string given with components
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2411) * separated @sep.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2412) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2413) static __be32 nfsd4_encode_components(struct xdr_stream *xdr, char sep,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2414) char *components)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2415) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2416) return nfsd4_encode_components_esc(xdr, sep, components, 0, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2417) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2418)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2419) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2420) * encode a location element of a fs_locations structure
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2421) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2422) static __be32 nfsd4_encode_fs_location4(struct xdr_stream *xdr,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2423) struct nfsd4_fs_location *location)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2424) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2425) __be32 status;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2426)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2427) status = nfsd4_encode_components_esc(xdr, ':', location->hosts,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2428) '[', ']');
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2429) if (status)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2430) return status;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2431) status = nfsd4_encode_components(xdr, '/', location->path);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2432) if (status)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2433) return status;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2434) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2435) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2436)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2437) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2438) * Encode a path in RFC3530 'pathname4' format
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2439) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2440) static __be32 nfsd4_encode_path(struct xdr_stream *xdr,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2441) const struct path *root,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2442) const struct path *path)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2443) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2444) struct path cur = *path;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2445) __be32 *p;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2446) struct dentry **components = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2447) unsigned int ncomponents = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2448) __be32 err = nfserr_jukebox;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2449)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2450) dprintk("nfsd4_encode_components(");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2451)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2452) path_get(&cur);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2453) /* First walk the path up to the nfsd root, and store the
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2454) * dentries/path components in an array.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2455) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2456) for (;;) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2457) if (path_equal(&cur, root))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2458) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2459) if (cur.dentry == cur.mnt->mnt_root) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2460) if (follow_up(&cur))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2461) continue;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2462) goto out_free;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2463) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2464) if ((ncomponents & 15) == 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2465) struct dentry **new;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2466) new = krealloc(components,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2467) sizeof(*new) * (ncomponents + 16),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2468) GFP_KERNEL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2469) if (!new)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2470) goto out_free;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2471) components = new;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2472) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2473) components[ncomponents++] = cur.dentry;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2474) cur.dentry = dget_parent(cur.dentry);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2475) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2476) err = nfserr_resource;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2477) p = xdr_reserve_space(xdr, 4);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2478) if (!p)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2479) goto out_free;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2480) *p++ = cpu_to_be32(ncomponents);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2481)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2482) while (ncomponents) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2483) struct dentry *dentry = components[ncomponents - 1];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2484) unsigned int len;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2485)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2486) spin_lock(&dentry->d_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2487) len = dentry->d_name.len;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2488) p = xdr_reserve_space(xdr, len + 4);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2489) if (!p) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2490) spin_unlock(&dentry->d_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2491) goto out_free;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2492) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2493) p = xdr_encode_opaque(p, dentry->d_name.name, len);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2494) dprintk("/%pd", dentry);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2495) spin_unlock(&dentry->d_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2496) dput(dentry);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2497) ncomponents--;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2498) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2499)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2500) err = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2501) out_free:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2502) dprintk(")\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2503) while (ncomponents)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2504) dput(components[--ncomponents]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2505) kfree(components);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2506) path_put(&cur);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2507) return err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2508) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2509)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2510) static __be32 nfsd4_encode_fsloc_fsroot(struct xdr_stream *xdr,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2511) struct svc_rqst *rqstp, const struct path *path)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2512) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2513) struct svc_export *exp_ps;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2514) __be32 res;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2515)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2516) exp_ps = rqst_find_fsidzero_export(rqstp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2517) if (IS_ERR(exp_ps))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2518) return nfserrno(PTR_ERR(exp_ps));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2519) res = nfsd4_encode_path(xdr, &exp_ps->ex_path, path);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2520) exp_put(exp_ps);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2521) return res;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2522) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2523)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2524) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2525) * encode a fs_locations structure
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2526) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2527) static __be32 nfsd4_encode_fs_locations(struct xdr_stream *xdr,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2528) struct svc_rqst *rqstp, struct svc_export *exp)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2529) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2530) __be32 status;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2531) int i;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2532) __be32 *p;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2533) struct nfsd4_fs_locations *fslocs = &exp->ex_fslocs;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2534)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2535) status = nfsd4_encode_fsloc_fsroot(xdr, rqstp, &exp->ex_path);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2536) if (status)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2537) return status;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2538) p = xdr_reserve_space(xdr, 4);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2539) if (!p)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2540) return nfserr_resource;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2541) *p++ = cpu_to_be32(fslocs->locations_count);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2542) for (i=0; i<fslocs->locations_count; i++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2543) status = nfsd4_encode_fs_location4(xdr, &fslocs->locations[i]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2544) if (status)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2545) return status;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2546) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2547) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2548) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2549)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2550) static u32 nfs4_file_type(umode_t mode)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2551) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2552) switch (mode & S_IFMT) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2553) case S_IFIFO: return NF4FIFO;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2554) case S_IFCHR: return NF4CHR;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2555) case S_IFDIR: return NF4DIR;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2556) case S_IFBLK: return NF4BLK;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2557) case S_IFLNK: return NF4LNK;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2558) case S_IFREG: return NF4REG;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2559) case S_IFSOCK: return NF4SOCK;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2560) default: return NF4BAD;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2561) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2562) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2563)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2564) static inline __be32
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2565) nfsd4_encode_aclname(struct xdr_stream *xdr, struct svc_rqst *rqstp,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2566) struct nfs4_ace *ace)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2567) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2568) if (ace->whotype != NFS4_ACL_WHO_NAMED)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2569) return nfs4_acl_write_who(xdr, ace->whotype);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2570) else if (ace->flag & NFS4_ACE_IDENTIFIER_GROUP)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2571) return nfsd4_encode_group(xdr, rqstp, ace->who_gid);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2572) else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2573) return nfsd4_encode_user(xdr, rqstp, ace->who_uid);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2574) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2575)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2576) static inline __be32
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2577) nfsd4_encode_layout_types(struct xdr_stream *xdr, u32 layout_types)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2578) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2579) __be32 *p;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2580) unsigned long i = hweight_long(layout_types);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2581)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2582) p = xdr_reserve_space(xdr, 4 + 4 * i);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2583) if (!p)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2584) return nfserr_resource;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2585)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2586) *p++ = cpu_to_be32(i);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2587)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2588) for (i = LAYOUT_NFSV4_1_FILES; i < LAYOUT_TYPE_MAX; ++i)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2589) if (layout_types & (1 << i))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2590) *p++ = cpu_to_be32(i);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2591)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2592) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2593) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2594)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2595) #define WORD0_ABSENT_FS_ATTRS (FATTR4_WORD0_FS_LOCATIONS | FATTR4_WORD0_FSID | \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2596) FATTR4_WORD0_RDATTR_ERROR)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2597) #define WORD1_ABSENT_FS_ATTRS FATTR4_WORD1_MOUNTED_ON_FILEID
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2598) #define WORD2_ABSENT_FS_ATTRS 0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2599)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2600) #ifdef CONFIG_NFSD_V4_SECURITY_LABEL
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2601) static inline __be32
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2602) nfsd4_encode_security_label(struct xdr_stream *xdr, struct svc_rqst *rqstp,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2603) void *context, int len)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2604) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2605) __be32 *p;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2606)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2607) p = xdr_reserve_space(xdr, len + 4 + 4 + 4);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2608) if (!p)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2609) return nfserr_resource;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2610)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2611) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2612) * For now we use a 0 here to indicate the null translation; in
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2613) * the future we may place a call to translation code here.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2614) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2615) *p++ = cpu_to_be32(0); /* lfs */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2616) *p++ = cpu_to_be32(0); /* pi */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2617) p = xdr_encode_opaque(p, context, len);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2618) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2619) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2620) #else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2621) static inline __be32
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2622) nfsd4_encode_security_label(struct xdr_stream *xdr, struct svc_rqst *rqstp,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2623) void *context, int len)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2624) { return 0; }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2625) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2626)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2627) static __be32 fattr_handle_absent_fs(u32 *bmval0, u32 *bmval1, u32 *bmval2, u32 *rdattr_err)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2628) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2629) /* As per referral draft: */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2630) if (*bmval0 & ~WORD0_ABSENT_FS_ATTRS ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2631) *bmval1 & ~WORD1_ABSENT_FS_ATTRS) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2632) if (*bmval0 & FATTR4_WORD0_RDATTR_ERROR ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2633) *bmval0 & FATTR4_WORD0_FS_LOCATIONS)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2634) *rdattr_err = NFSERR_MOVED;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2635) else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2636) return nfserr_moved;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2637) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2638) *bmval0 &= WORD0_ABSENT_FS_ATTRS;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2639) *bmval1 &= WORD1_ABSENT_FS_ATTRS;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2640) *bmval2 &= WORD2_ABSENT_FS_ATTRS;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2641) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2642) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2643)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2644)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2645) static int get_parent_attributes(struct svc_export *exp, struct kstat *stat)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2646) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2647) struct path path = exp->ex_path;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2648) int err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2649)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2650) path_get(&path);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2651) while (follow_up(&path)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2652) if (path.dentry != path.mnt->mnt_root)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2653) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2654) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2655) err = vfs_getattr(&path, stat, STATX_BASIC_STATS, AT_STATX_SYNC_AS_STAT);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2656) path_put(&path);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2657) return err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2658) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2659)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2660) static __be32
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2661) nfsd4_encode_bitmap(struct xdr_stream *xdr, u32 bmval0, u32 bmval1, u32 bmval2)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2662) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2663) __be32 *p;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2664)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2665) if (bmval2) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2666) p = xdr_reserve_space(xdr, 16);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2667) if (!p)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2668) goto out_resource;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2669) *p++ = cpu_to_be32(3);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2670) *p++ = cpu_to_be32(bmval0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2671) *p++ = cpu_to_be32(bmval1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2672) *p++ = cpu_to_be32(bmval2);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2673) } else if (bmval1) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2674) p = xdr_reserve_space(xdr, 12);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2675) if (!p)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2676) goto out_resource;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2677) *p++ = cpu_to_be32(2);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2678) *p++ = cpu_to_be32(bmval0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2679) *p++ = cpu_to_be32(bmval1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2680) } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2681) p = xdr_reserve_space(xdr, 8);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2682) if (!p)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2683) goto out_resource;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2684) *p++ = cpu_to_be32(1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2685) *p++ = cpu_to_be32(bmval0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2686) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2687)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2688) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2689) out_resource:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2690) return nfserr_resource;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2691) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2692)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2693) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2694) * Note: @fhp can be NULL; in this case, we might have to compose the filehandle
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2695) * ourselves.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2696) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2697) static __be32
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2698) nfsd4_encode_fattr(struct xdr_stream *xdr, struct svc_fh *fhp,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2699) struct svc_export *exp,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2700) struct dentry *dentry, u32 *bmval,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2701) struct svc_rqst *rqstp, int ignore_crossmnt)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2702) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2703) u32 bmval0 = bmval[0];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2704) u32 bmval1 = bmval[1];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2705) u32 bmval2 = bmval[2];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2706) struct kstat stat;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2707) struct svc_fh *tempfh = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2708) struct kstatfs statfs;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2709) __be32 *p;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2710) int starting_len = xdr->buf->len;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2711) int attrlen_offset;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2712) __be32 attrlen;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2713) u32 dummy;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2714) u64 dummy64;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2715) u32 rdattr_err = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2716) __be32 status;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2717) int err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2718) struct nfs4_acl *acl = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2719) #ifdef CONFIG_NFSD_V4_SECURITY_LABEL
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2720) void *context = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2721) int contextlen;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2722) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2723) bool contextsupport = false;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2724) struct nfsd4_compoundres *resp = rqstp->rq_resp;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2725) u32 minorversion = resp->cstate.minorversion;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2726) struct path path = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2727) .mnt = exp->ex_path.mnt,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2728) .dentry = dentry,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2729) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2730) struct nfsd_net *nn = net_generic(SVC_NET(rqstp), nfsd_net_id);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2731)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2732) BUG_ON(bmval1 & NFSD_WRITEONLY_ATTRS_WORD1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2733) BUG_ON(!nfsd_attrs_supported(minorversion, bmval));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2734)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2735) if (exp->ex_fslocs.migrated) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2736) status = fattr_handle_absent_fs(&bmval0, &bmval1, &bmval2, &rdattr_err);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2737) if (status)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2738) goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2739) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2740)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2741) err = vfs_getattr(&path, &stat, STATX_BASIC_STATS, AT_STATX_SYNC_AS_STAT);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2742) if (err)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2743) goto out_nfserr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2744) if ((bmval0 & (FATTR4_WORD0_FILES_AVAIL | FATTR4_WORD0_FILES_FREE |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2745) FATTR4_WORD0_FILES_TOTAL | FATTR4_WORD0_MAXNAME)) ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2746) (bmval1 & (FATTR4_WORD1_SPACE_AVAIL | FATTR4_WORD1_SPACE_FREE |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2747) FATTR4_WORD1_SPACE_TOTAL))) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2748) err = vfs_statfs(&path, &statfs);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2749) if (err)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2750) goto out_nfserr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2751) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2752) if ((bmval0 & (FATTR4_WORD0_FILEHANDLE | FATTR4_WORD0_FSID)) && !fhp) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2753) tempfh = kmalloc(sizeof(struct svc_fh), GFP_KERNEL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2754) status = nfserr_jukebox;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2755) if (!tempfh)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2756) goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2757) fh_init(tempfh, NFS4_FHSIZE);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2758) status = fh_compose(tempfh, exp, dentry, NULL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2759) if (status)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2760) goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2761) fhp = tempfh;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2762) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2763) if (bmval0 & FATTR4_WORD0_ACL) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2764) err = nfsd4_get_nfs4_acl(rqstp, dentry, &acl);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2765) if (err == -EOPNOTSUPP)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2766) bmval0 &= ~FATTR4_WORD0_ACL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2767) else if (err == -EINVAL) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2768) status = nfserr_attrnotsupp;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2769) goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2770) } else if (err != 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2771) goto out_nfserr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2772) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2773)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2774) #ifdef CONFIG_NFSD_V4_SECURITY_LABEL
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2775) if ((bmval2 & FATTR4_WORD2_SECURITY_LABEL) ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2776) bmval0 & FATTR4_WORD0_SUPPORTED_ATTRS) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2777) if (exp->ex_flags & NFSEXP_SECURITY_LABEL)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2778) err = security_inode_getsecctx(d_inode(dentry),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2779) &context, &contextlen);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2780) else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2781) err = -EOPNOTSUPP;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2782) contextsupport = (err == 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2783) if (bmval2 & FATTR4_WORD2_SECURITY_LABEL) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2784) if (err == -EOPNOTSUPP)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2785) bmval2 &= ~FATTR4_WORD2_SECURITY_LABEL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2786) else if (err)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2787) goto out_nfserr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2788) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2789) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2790) #endif /* CONFIG_NFSD_V4_SECURITY_LABEL */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2791)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2792) status = nfsd4_encode_bitmap(xdr, bmval0, bmval1, bmval2);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2793) if (status)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2794) goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2795)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2796) attrlen_offset = xdr->buf->len;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2797) p = xdr_reserve_space(xdr, 4);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2798) if (!p)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2799) goto out_resource;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2800) p++; /* to be backfilled later */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2801)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2802) if (bmval0 & FATTR4_WORD0_SUPPORTED_ATTRS) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2803) u32 supp[3];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2804)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2805) memcpy(supp, nfsd_suppattrs[minorversion], sizeof(supp));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2806)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2807) if (!IS_POSIXACL(dentry->d_inode))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2808) supp[0] &= ~FATTR4_WORD0_ACL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2809) if (!contextsupport)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2810) supp[2] &= ~FATTR4_WORD2_SECURITY_LABEL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2811) if (!supp[2]) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2812) p = xdr_reserve_space(xdr, 12);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2813) if (!p)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2814) goto out_resource;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2815) *p++ = cpu_to_be32(2);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2816) *p++ = cpu_to_be32(supp[0]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2817) *p++ = cpu_to_be32(supp[1]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2818) } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2819) p = xdr_reserve_space(xdr, 16);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2820) if (!p)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2821) goto out_resource;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2822) *p++ = cpu_to_be32(3);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2823) *p++ = cpu_to_be32(supp[0]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2824) *p++ = cpu_to_be32(supp[1]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2825) *p++ = cpu_to_be32(supp[2]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2826) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2827) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2828) if (bmval0 & FATTR4_WORD0_TYPE) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2829) p = xdr_reserve_space(xdr, 4);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2830) if (!p)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2831) goto out_resource;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2832) dummy = nfs4_file_type(stat.mode);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2833) if (dummy == NF4BAD) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2834) status = nfserr_serverfault;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2835) goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2836) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2837) *p++ = cpu_to_be32(dummy);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2838) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2839) if (bmval0 & FATTR4_WORD0_FH_EXPIRE_TYPE) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2840) p = xdr_reserve_space(xdr, 4);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2841) if (!p)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2842) goto out_resource;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2843) if (exp->ex_flags & NFSEXP_NOSUBTREECHECK)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2844) *p++ = cpu_to_be32(NFS4_FH_PERSISTENT);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2845) else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2846) *p++ = cpu_to_be32(NFS4_FH_PERSISTENT|
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2847) NFS4_FH_VOL_RENAME);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2848) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2849) if (bmval0 & FATTR4_WORD0_CHANGE) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2850) p = xdr_reserve_space(xdr, 8);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2851) if (!p)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2852) goto out_resource;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2853) p = encode_change(p, &stat, d_inode(dentry), exp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2854) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2855) if (bmval0 & FATTR4_WORD0_SIZE) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2856) p = xdr_reserve_space(xdr, 8);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2857) if (!p)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2858) goto out_resource;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2859) p = xdr_encode_hyper(p, stat.size);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2860) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2861) if (bmval0 & FATTR4_WORD0_LINK_SUPPORT) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2862) p = xdr_reserve_space(xdr, 4);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2863) if (!p)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2864) goto out_resource;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2865) *p++ = cpu_to_be32(1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2866) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2867) if (bmval0 & FATTR4_WORD0_SYMLINK_SUPPORT) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2868) p = xdr_reserve_space(xdr, 4);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2869) if (!p)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2870) goto out_resource;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2871) *p++ = cpu_to_be32(1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2872) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2873) if (bmval0 & FATTR4_WORD0_NAMED_ATTR) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2874) p = xdr_reserve_space(xdr, 4);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2875) if (!p)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2876) goto out_resource;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2877) *p++ = cpu_to_be32(0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2878) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2879) if (bmval0 & FATTR4_WORD0_FSID) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2880) p = xdr_reserve_space(xdr, 16);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2881) if (!p)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2882) goto out_resource;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2883) if (exp->ex_fslocs.migrated) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2884) p = xdr_encode_hyper(p, NFS4_REFERRAL_FSID_MAJOR);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2885) p = xdr_encode_hyper(p, NFS4_REFERRAL_FSID_MINOR);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2886) } else switch(fsid_source(fhp)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2887) case FSIDSOURCE_FSID:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2888) p = xdr_encode_hyper(p, (u64)exp->ex_fsid);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2889) p = xdr_encode_hyper(p, (u64)0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2890) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2891) case FSIDSOURCE_DEV:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2892) *p++ = cpu_to_be32(0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2893) *p++ = cpu_to_be32(MAJOR(stat.dev));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2894) *p++ = cpu_to_be32(0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2895) *p++ = cpu_to_be32(MINOR(stat.dev));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2896) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2897) case FSIDSOURCE_UUID:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2898) p = xdr_encode_opaque_fixed(p, exp->ex_uuid,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2899) EX_UUID_LEN);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2900) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2901) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2902) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2903) if (bmval0 & FATTR4_WORD0_UNIQUE_HANDLES) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2904) p = xdr_reserve_space(xdr, 4);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2905) if (!p)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2906) goto out_resource;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2907) *p++ = cpu_to_be32(0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2908) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2909) if (bmval0 & FATTR4_WORD0_LEASE_TIME) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2910) p = xdr_reserve_space(xdr, 4);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2911) if (!p)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2912) goto out_resource;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2913) *p++ = cpu_to_be32(nn->nfsd4_lease);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2914) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2915) if (bmval0 & FATTR4_WORD0_RDATTR_ERROR) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2916) p = xdr_reserve_space(xdr, 4);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2917) if (!p)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2918) goto out_resource;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2919) *p++ = cpu_to_be32(rdattr_err);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2920) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2921) if (bmval0 & FATTR4_WORD0_ACL) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2922) struct nfs4_ace *ace;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2923)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2924) if (acl == NULL) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2925) p = xdr_reserve_space(xdr, 4);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2926) if (!p)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2927) goto out_resource;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2928)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2929) *p++ = cpu_to_be32(0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2930) goto out_acl;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2931) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2932) p = xdr_reserve_space(xdr, 4);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2933) if (!p)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2934) goto out_resource;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2935) *p++ = cpu_to_be32(acl->naces);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2936)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2937) for (ace = acl->aces; ace < acl->aces + acl->naces; ace++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2938) p = xdr_reserve_space(xdr, 4*3);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2939) if (!p)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2940) goto out_resource;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2941) *p++ = cpu_to_be32(ace->type);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2942) *p++ = cpu_to_be32(ace->flag);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2943) *p++ = cpu_to_be32(ace->access_mask &
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2944) NFS4_ACE_MASK_ALL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2945) status = nfsd4_encode_aclname(xdr, rqstp, ace);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2946) if (status)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2947) goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2948) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2949) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2950) out_acl:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2951) if (bmval0 & FATTR4_WORD0_ACLSUPPORT) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2952) p = xdr_reserve_space(xdr, 4);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2953) if (!p)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2954) goto out_resource;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2955) *p++ = cpu_to_be32(IS_POSIXACL(dentry->d_inode) ?
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2956) ACL4_SUPPORT_ALLOW_ACL|ACL4_SUPPORT_DENY_ACL : 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2957) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2958) if (bmval0 & FATTR4_WORD0_CANSETTIME) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2959) p = xdr_reserve_space(xdr, 4);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2960) if (!p)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2961) goto out_resource;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2962) *p++ = cpu_to_be32(1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2963) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2964) if (bmval0 & FATTR4_WORD0_CASE_INSENSITIVE) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2965) p = xdr_reserve_space(xdr, 4);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2966) if (!p)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2967) goto out_resource;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2968) *p++ = cpu_to_be32(0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2969) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2970) if (bmval0 & FATTR4_WORD0_CASE_PRESERVING) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2971) p = xdr_reserve_space(xdr, 4);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2972) if (!p)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2973) goto out_resource;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2974) *p++ = cpu_to_be32(1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2975) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2976) if (bmval0 & FATTR4_WORD0_CHOWN_RESTRICTED) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2977) p = xdr_reserve_space(xdr, 4);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2978) if (!p)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2979) goto out_resource;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2980) *p++ = cpu_to_be32(1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2981) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2982) if (bmval0 & FATTR4_WORD0_FILEHANDLE) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2983) p = xdr_reserve_space(xdr, fhp->fh_handle.fh_size + 4);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2984) if (!p)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2985) goto out_resource;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2986) p = xdr_encode_opaque(p, &fhp->fh_handle.fh_base,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2987) fhp->fh_handle.fh_size);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2988) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2989) if (bmval0 & FATTR4_WORD0_FILEID) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2990) p = xdr_reserve_space(xdr, 8);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2991) if (!p)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2992) goto out_resource;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2993) p = xdr_encode_hyper(p, stat.ino);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2994) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2995) if (bmval0 & FATTR4_WORD0_FILES_AVAIL) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2996) p = xdr_reserve_space(xdr, 8);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2997) if (!p)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2998) goto out_resource;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2999) p = xdr_encode_hyper(p, (u64) statfs.f_ffree);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3000) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3001) if (bmval0 & FATTR4_WORD0_FILES_FREE) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3002) p = xdr_reserve_space(xdr, 8);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3003) if (!p)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3004) goto out_resource;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3005) p = xdr_encode_hyper(p, (u64) statfs.f_ffree);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3006) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3007) if (bmval0 & FATTR4_WORD0_FILES_TOTAL) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3008) p = xdr_reserve_space(xdr, 8);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3009) if (!p)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3010) goto out_resource;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3011) p = xdr_encode_hyper(p, (u64) statfs.f_files);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3012) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3013) if (bmval0 & FATTR4_WORD0_FS_LOCATIONS) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3014) status = nfsd4_encode_fs_locations(xdr, rqstp, exp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3015) if (status)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3016) goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3017) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3018) if (bmval0 & FATTR4_WORD0_HOMOGENEOUS) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3019) p = xdr_reserve_space(xdr, 4);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3020) if (!p)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3021) goto out_resource;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3022) *p++ = cpu_to_be32(1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3023) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3024) if (bmval0 & FATTR4_WORD0_MAXFILESIZE) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3025) p = xdr_reserve_space(xdr, 8);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3026) if (!p)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3027) goto out_resource;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3028) p = xdr_encode_hyper(p, exp->ex_path.mnt->mnt_sb->s_maxbytes);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3029) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3030) if (bmval0 & FATTR4_WORD0_MAXLINK) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3031) p = xdr_reserve_space(xdr, 4);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3032) if (!p)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3033) goto out_resource;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3034) *p++ = cpu_to_be32(255);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3035) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3036) if (bmval0 & FATTR4_WORD0_MAXNAME) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3037) p = xdr_reserve_space(xdr, 4);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3038) if (!p)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3039) goto out_resource;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3040) *p++ = cpu_to_be32(statfs.f_namelen);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3041) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3042) if (bmval0 & FATTR4_WORD0_MAXREAD) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3043) p = xdr_reserve_space(xdr, 8);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3044) if (!p)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3045) goto out_resource;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3046) p = xdr_encode_hyper(p, (u64) svc_max_payload(rqstp));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3047) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3048) if (bmval0 & FATTR4_WORD0_MAXWRITE) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3049) p = xdr_reserve_space(xdr, 8);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3050) if (!p)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3051) goto out_resource;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3052) p = xdr_encode_hyper(p, (u64) svc_max_payload(rqstp));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3053) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3054) if (bmval1 & FATTR4_WORD1_MODE) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3055) p = xdr_reserve_space(xdr, 4);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3056) if (!p)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3057) goto out_resource;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3058) *p++ = cpu_to_be32(stat.mode & S_IALLUGO);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3059) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3060) if (bmval1 & FATTR4_WORD1_NO_TRUNC) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3061) p = xdr_reserve_space(xdr, 4);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3062) if (!p)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3063) goto out_resource;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3064) *p++ = cpu_to_be32(1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3065) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3066) if (bmval1 & FATTR4_WORD1_NUMLINKS) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3067) p = xdr_reserve_space(xdr, 4);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3068) if (!p)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3069) goto out_resource;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3070) *p++ = cpu_to_be32(stat.nlink);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3071) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3072) if (bmval1 & FATTR4_WORD1_OWNER) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3073) status = nfsd4_encode_user(xdr, rqstp, stat.uid);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3074) if (status)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3075) goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3076) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3077) if (bmval1 & FATTR4_WORD1_OWNER_GROUP) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3078) status = nfsd4_encode_group(xdr, rqstp, stat.gid);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3079) if (status)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3080) goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3081) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3082) if (bmval1 & FATTR4_WORD1_RAWDEV) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3083) p = xdr_reserve_space(xdr, 8);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3084) if (!p)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3085) goto out_resource;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3086) *p++ = cpu_to_be32((u32) MAJOR(stat.rdev));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3087) *p++ = cpu_to_be32((u32) MINOR(stat.rdev));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3088) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3089) if (bmval1 & FATTR4_WORD1_SPACE_AVAIL) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3090) p = xdr_reserve_space(xdr, 8);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3091) if (!p)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3092) goto out_resource;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3093) dummy64 = (u64)statfs.f_bavail * (u64)statfs.f_bsize;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3094) p = xdr_encode_hyper(p, dummy64);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3095) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3096) if (bmval1 & FATTR4_WORD1_SPACE_FREE) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3097) p = xdr_reserve_space(xdr, 8);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3098) if (!p)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3099) goto out_resource;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3100) dummy64 = (u64)statfs.f_bfree * (u64)statfs.f_bsize;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3101) p = xdr_encode_hyper(p, dummy64);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3102) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3103) if (bmval1 & FATTR4_WORD1_SPACE_TOTAL) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3104) p = xdr_reserve_space(xdr, 8);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3105) if (!p)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3106) goto out_resource;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3107) dummy64 = (u64)statfs.f_blocks * (u64)statfs.f_bsize;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3108) p = xdr_encode_hyper(p, dummy64);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3109) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3110) if (bmval1 & FATTR4_WORD1_SPACE_USED) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3111) p = xdr_reserve_space(xdr, 8);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3112) if (!p)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3113) goto out_resource;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3114) dummy64 = (u64)stat.blocks << 9;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3115) p = xdr_encode_hyper(p, dummy64);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3116) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3117) if (bmval1 & FATTR4_WORD1_TIME_ACCESS) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3118) p = xdr_reserve_space(xdr, 12);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3119) if (!p)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3120) goto out_resource;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3121) p = xdr_encode_hyper(p, (s64)stat.atime.tv_sec);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3122) *p++ = cpu_to_be32(stat.atime.tv_nsec);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3123) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3124) if (bmval1 & FATTR4_WORD1_TIME_DELTA) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3125) p = xdr_reserve_space(xdr, 12);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3126) if (!p)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3127) goto out_resource;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3128) p = encode_time_delta(p, d_inode(dentry));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3129) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3130) if (bmval1 & FATTR4_WORD1_TIME_METADATA) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3131) p = xdr_reserve_space(xdr, 12);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3132) if (!p)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3133) goto out_resource;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3134) p = xdr_encode_hyper(p, (s64)stat.ctime.tv_sec);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3135) *p++ = cpu_to_be32(stat.ctime.tv_nsec);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3136) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3137) if (bmval1 & FATTR4_WORD1_TIME_MODIFY) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3138) p = xdr_reserve_space(xdr, 12);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3139) if (!p)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3140) goto out_resource;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3141) p = xdr_encode_hyper(p, (s64)stat.mtime.tv_sec);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3142) *p++ = cpu_to_be32(stat.mtime.tv_nsec);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3143) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3144) if (bmval1 & FATTR4_WORD1_MOUNTED_ON_FILEID) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3145) struct kstat parent_stat;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3146) u64 ino = stat.ino;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3147)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3148) p = xdr_reserve_space(xdr, 8);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3149) if (!p)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3150) goto out_resource;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3151) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3152) * Get parent's attributes if not ignoring crossmount
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3153) * and this is the root of a cross-mounted filesystem.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3154) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3155) if (ignore_crossmnt == 0 &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3156) dentry == exp->ex_path.mnt->mnt_root) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3157) err = get_parent_attributes(exp, &parent_stat);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3158) if (err)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3159) goto out_nfserr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3160) ino = parent_stat.ino;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3161) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3162) p = xdr_encode_hyper(p, ino);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3163) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3164) #ifdef CONFIG_NFSD_PNFS
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3165) if (bmval1 & FATTR4_WORD1_FS_LAYOUT_TYPES) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3166) status = nfsd4_encode_layout_types(xdr, exp->ex_layout_types);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3167) if (status)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3168) goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3169) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3170)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3171) if (bmval2 & FATTR4_WORD2_LAYOUT_TYPES) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3172) status = nfsd4_encode_layout_types(xdr, exp->ex_layout_types);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3173) if (status)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3174) goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3175) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3176)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3177) if (bmval2 & FATTR4_WORD2_LAYOUT_BLKSIZE) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3178) p = xdr_reserve_space(xdr, 4);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3179) if (!p)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3180) goto out_resource;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3181) *p++ = cpu_to_be32(stat.blksize);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3182) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3183) #endif /* CONFIG_NFSD_PNFS */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3184) if (bmval2 & FATTR4_WORD2_SUPPATTR_EXCLCREAT) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3185) u32 supp[3];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3186)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3187) memcpy(supp, nfsd_suppattrs[minorversion], sizeof(supp));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3188) supp[0] &= NFSD_SUPPATTR_EXCLCREAT_WORD0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3189) supp[1] &= NFSD_SUPPATTR_EXCLCREAT_WORD1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3190) supp[2] &= NFSD_SUPPATTR_EXCLCREAT_WORD2;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3191)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3192) status = nfsd4_encode_bitmap(xdr, supp[0], supp[1], supp[2]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3193) if (status)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3194) goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3195) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3196)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3197) if (bmval2 & FATTR4_WORD2_CHANGE_ATTR_TYPE) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3198) p = xdr_reserve_space(xdr, 4);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3199) if (!p)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3200) goto out_resource;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3201) if (IS_I_VERSION(d_inode(dentry)))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3202) *p++ = cpu_to_be32(NFS4_CHANGE_TYPE_IS_MONOTONIC_INCR);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3203) else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3204) *p++ = cpu_to_be32(NFS4_CHANGE_TYPE_IS_TIME_METADATA);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3205) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3206)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3207) #ifdef CONFIG_NFSD_V4_SECURITY_LABEL
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3208) if (bmval2 & FATTR4_WORD2_SECURITY_LABEL) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3209) status = nfsd4_encode_security_label(xdr, rqstp, context,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3210) contextlen);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3211) if (status)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3212) goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3213) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3214) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3215)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3216) if (bmval2 & FATTR4_WORD2_XATTR_SUPPORT) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3217) p = xdr_reserve_space(xdr, 4);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3218) if (!p)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3219) goto out_resource;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3220) err = xattr_supported_namespace(d_inode(dentry),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3221) XATTR_USER_PREFIX);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3222) *p++ = cpu_to_be32(err == 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3223) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3224)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3225) attrlen = htonl(xdr->buf->len - attrlen_offset - 4);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3226) write_bytes_to_xdr_buf(xdr->buf, attrlen_offset, &attrlen, 4);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3227) status = nfs_ok;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3228)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3229) out:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3230) #ifdef CONFIG_NFSD_V4_SECURITY_LABEL
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3231) if (context)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3232) security_release_secctx(context, contextlen);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3233) #endif /* CONFIG_NFSD_V4_SECURITY_LABEL */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3234) kfree(acl);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3235) if (tempfh) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3236) fh_put(tempfh);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3237) kfree(tempfh);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3238) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3239) if (status)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3240) xdr_truncate_encode(xdr, starting_len);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3241) return status;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3242) out_nfserr:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3243) status = nfserrno(err);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3244) goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3245) out_resource:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3246) status = nfserr_resource;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3247) goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3248) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3249)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3250) static void svcxdr_init_encode_from_buffer(struct xdr_stream *xdr,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3251) struct xdr_buf *buf, __be32 *p, int bytes)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3252) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3253) xdr->scratch.iov_len = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3254) memset(buf, 0, sizeof(struct xdr_buf));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3255) buf->head[0].iov_base = p;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3256) buf->head[0].iov_len = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3257) buf->len = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3258) xdr->buf = buf;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3259) xdr->iov = buf->head;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3260) xdr->p = p;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3261) xdr->end = (void *)p + bytes;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3262) buf->buflen = bytes;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3263) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3264)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3265) __be32 nfsd4_encode_fattr_to_buf(__be32 **p, int words,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3266) struct svc_fh *fhp, struct svc_export *exp,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3267) struct dentry *dentry, u32 *bmval,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3268) struct svc_rqst *rqstp, int ignore_crossmnt)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3269) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3270) struct xdr_buf dummy;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3271) struct xdr_stream xdr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3272) __be32 ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3273)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3274) svcxdr_init_encode_from_buffer(&xdr, &dummy, *p, words << 2);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3275) ret = nfsd4_encode_fattr(&xdr, fhp, exp, dentry, bmval, rqstp,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3276) ignore_crossmnt);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3277) *p = xdr.p;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3278) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3279) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3280)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3281) static inline int attributes_need_mount(u32 *bmval)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3282) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3283) if (bmval[0] & ~(FATTR4_WORD0_RDATTR_ERROR | FATTR4_WORD0_LEASE_TIME))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3284) return 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3285) if (bmval[1] & ~FATTR4_WORD1_MOUNTED_ON_FILEID)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3286) return 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3287) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3288) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3289)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3290) static __be32
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3291) nfsd4_encode_dirent_fattr(struct xdr_stream *xdr, struct nfsd4_readdir *cd,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3292) const char *name, int namlen)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3293) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3294) struct svc_export *exp = cd->rd_fhp->fh_export;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3295) struct dentry *dentry;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3296) __be32 nfserr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3297) int ignore_crossmnt = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3298)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3299) dentry = lookup_positive_unlocked(name, cd->rd_fhp->fh_dentry, namlen);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3300) if (IS_ERR(dentry))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3301) return nfserrno(PTR_ERR(dentry));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3302)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3303) exp_get(exp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3304) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3305) * In the case of a mountpoint, the client may be asking for
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3306) * attributes that are only properties of the underlying filesystem
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3307) * as opposed to the cross-mounted file system. In such a case,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3308) * we will not follow the cross mount and will fill the attribtutes
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3309) * directly from the mountpoint dentry.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3310) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3311) if (nfsd_mountpoint(dentry, exp)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3312) int err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3313)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3314) if (!(exp->ex_flags & NFSEXP_V4ROOT)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3315) && !attributes_need_mount(cd->rd_bmval)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3316) ignore_crossmnt = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3317) goto out_encode;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3318) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3319) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3320) * Why the heck aren't we just using nfsd_lookup??
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3321) * Different "."/".." handling? Something else?
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3322) * At least, add a comment here to explain....
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3323) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3324) err = nfsd_cross_mnt(cd->rd_rqstp, &dentry, &exp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3325) if (err) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3326) nfserr = nfserrno(err);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3327) goto out_put;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3328) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3329) nfserr = check_nfsd_access(exp, cd->rd_rqstp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3330) if (nfserr)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3331) goto out_put;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3332)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3333) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3334) out_encode:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3335) nfserr = nfsd4_encode_fattr(xdr, NULL, exp, dentry, cd->rd_bmval,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3336) cd->rd_rqstp, ignore_crossmnt);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3337) out_put:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3338) dput(dentry);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3339) exp_put(exp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3340) return nfserr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3341) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3342)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3343) static __be32 *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3344) nfsd4_encode_rdattr_error(struct xdr_stream *xdr, __be32 nfserr)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3345) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3346) __be32 *p;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3347)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3348) p = xdr_reserve_space(xdr, 20);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3349) if (!p)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3350) return NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3351) *p++ = htonl(2);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3352) *p++ = htonl(FATTR4_WORD0_RDATTR_ERROR); /* bmval0 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3353) *p++ = htonl(0); /* bmval1 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3354)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3355) *p++ = htonl(4); /* attribute length */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3356) *p++ = nfserr; /* no htonl */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3357) return p;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3358) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3359)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3360) static int
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3361) nfsd4_encode_dirent(void *ccdv, const char *name, int namlen,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3362) loff_t offset, u64 ino, unsigned int d_type)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3363) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3364) struct readdir_cd *ccd = ccdv;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3365) struct nfsd4_readdir *cd = container_of(ccd, struct nfsd4_readdir, common);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3366) struct xdr_stream *xdr = cd->xdr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3367) int start_offset = xdr->buf->len;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3368) int cookie_offset;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3369) u32 name_and_cookie;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3370) int entry_bytes;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3371) __be32 nfserr = nfserr_toosmall;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3372) __be64 wire_offset;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3373) __be32 *p;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3374)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3375) /* In nfsv4, "." and ".." never make it onto the wire.. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3376) if (name && isdotent(name, namlen)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3377) cd->common.err = nfs_ok;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3378) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3379) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3380)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3381) if (cd->cookie_offset) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3382) wire_offset = cpu_to_be64(offset);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3383) write_bytes_to_xdr_buf(xdr->buf, cd->cookie_offset,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3384) &wire_offset, 8);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3385) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3386)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3387) p = xdr_reserve_space(xdr, 4);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3388) if (!p)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3389) goto fail;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3390) *p++ = xdr_one; /* mark entry present */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3391) cookie_offset = xdr->buf->len;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3392) p = xdr_reserve_space(xdr, 3*4 + namlen);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3393) if (!p)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3394) goto fail;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3395) p = xdr_encode_hyper(p, NFS_OFFSET_MAX); /* offset of next entry */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3396) p = xdr_encode_array(p, name, namlen); /* name length & name */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3397)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3398) nfserr = nfsd4_encode_dirent_fattr(xdr, cd, name, namlen);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3399) switch (nfserr) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3400) case nfs_ok:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3401) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3402) case nfserr_resource:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3403) nfserr = nfserr_toosmall;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3404) goto fail;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3405) case nfserr_noent:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3406) xdr_truncate_encode(xdr, start_offset);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3407) goto skip_entry;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3408) default:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3409) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3410) * If the client requested the RDATTR_ERROR attribute,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3411) * we stuff the error code into this attribute
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3412) * and continue. If this attribute was not requested,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3413) * then in accordance with the spec, we fail the
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3414) * entire READDIR operation(!)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3415) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3416) if (!(cd->rd_bmval[0] & FATTR4_WORD0_RDATTR_ERROR))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3417) goto fail;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3418) p = nfsd4_encode_rdattr_error(xdr, nfserr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3419) if (p == NULL) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3420) nfserr = nfserr_toosmall;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3421) goto fail;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3422) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3423) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3424) nfserr = nfserr_toosmall;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3425) entry_bytes = xdr->buf->len - start_offset;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3426) if (entry_bytes > cd->rd_maxcount)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3427) goto fail;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3428) cd->rd_maxcount -= entry_bytes;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3429) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3430) * RFC 3530 14.2.24 describes rd_dircount as only a "hint", and
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3431) * notes that it could be zero. If it is zero, then the server
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3432) * should enforce only the rd_maxcount value.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3433) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3434) if (cd->rd_dircount) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3435) name_and_cookie = 4 + 4 * XDR_QUADLEN(namlen) + 8;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3436) if (name_and_cookie > cd->rd_dircount && cd->cookie_offset)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3437) goto fail;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3438) cd->rd_dircount -= min(cd->rd_dircount, name_and_cookie);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3439) if (!cd->rd_dircount)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3440) cd->rd_maxcount = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3441) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3442)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3443) cd->cookie_offset = cookie_offset;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3444) skip_entry:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3445) cd->common.err = nfs_ok;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3446) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3447) fail:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3448) xdr_truncate_encode(xdr, start_offset);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3449) cd->common.err = nfserr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3450) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3451) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3452)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3453) static __be32
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3454) nfsd4_encode_stateid(struct xdr_stream *xdr, stateid_t *sid)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3455) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3456) __be32 *p;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3457)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3458) p = xdr_reserve_space(xdr, sizeof(stateid_t));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3459) if (!p)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3460) return nfserr_resource;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3461) *p++ = cpu_to_be32(sid->si_generation);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3462) p = xdr_encode_opaque_fixed(p, &sid->si_opaque,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3463) sizeof(stateid_opaque_t));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3464) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3465) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3466)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3467) static __be32
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3468) nfsd4_encode_access(struct nfsd4_compoundres *resp, __be32 nfserr, struct nfsd4_access *access)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3469) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3470) struct xdr_stream *xdr = &resp->xdr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3471) __be32 *p;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3472)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3473) p = xdr_reserve_space(xdr, 8);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3474) if (!p)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3475) return nfserr_resource;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3476) *p++ = cpu_to_be32(access->ac_supported);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3477) *p++ = cpu_to_be32(access->ac_resp_access);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3478) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3479) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3480)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3481) static __be32 nfsd4_encode_bind_conn_to_session(struct nfsd4_compoundres *resp, __be32 nfserr, struct nfsd4_bind_conn_to_session *bcts)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3482) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3483) struct xdr_stream *xdr = &resp->xdr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3484) __be32 *p;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3485)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3486) p = xdr_reserve_space(xdr, NFS4_MAX_SESSIONID_LEN + 8);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3487) if (!p)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3488) return nfserr_resource;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3489) p = xdr_encode_opaque_fixed(p, bcts->sessionid.data,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3490) NFS4_MAX_SESSIONID_LEN);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3491) *p++ = cpu_to_be32(bcts->dir);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3492) /* Upshifting from TCP to RDMA is not supported */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3493) *p++ = cpu_to_be32(0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3494) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3495) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3496)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3497) static __be32
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3498) nfsd4_encode_close(struct nfsd4_compoundres *resp, __be32 nfserr, struct nfsd4_close *close)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3499) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3500) struct xdr_stream *xdr = &resp->xdr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3501)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3502) return nfsd4_encode_stateid(xdr, &close->cl_stateid);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3503) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3504)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3505)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3506) static __be32
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3507) nfsd4_encode_commit(struct nfsd4_compoundres *resp, __be32 nfserr, struct nfsd4_commit *commit)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3508) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3509) struct xdr_stream *xdr = &resp->xdr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3510) __be32 *p;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3511)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3512) p = xdr_reserve_space(xdr, NFS4_VERIFIER_SIZE);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3513) if (!p)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3514) return nfserr_resource;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3515) p = xdr_encode_opaque_fixed(p, commit->co_verf.data,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3516) NFS4_VERIFIER_SIZE);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3517) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3518) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3519)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3520) static __be32
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3521) nfsd4_encode_create(struct nfsd4_compoundres *resp, __be32 nfserr, struct nfsd4_create *create)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3522) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3523) struct xdr_stream *xdr = &resp->xdr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3524) __be32 *p;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3525)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3526) p = xdr_reserve_space(xdr, 20);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3527) if (!p)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3528) return nfserr_resource;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3529) encode_cinfo(p, &create->cr_cinfo);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3530) return nfsd4_encode_bitmap(xdr, create->cr_bmval[0],
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3531) create->cr_bmval[1], create->cr_bmval[2]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3532) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3533)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3534) static __be32
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3535) nfsd4_encode_getattr(struct nfsd4_compoundres *resp, __be32 nfserr, struct nfsd4_getattr *getattr)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3536) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3537) struct svc_fh *fhp = getattr->ga_fhp;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3538) struct xdr_stream *xdr = &resp->xdr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3539)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3540) return nfsd4_encode_fattr(xdr, fhp, fhp->fh_export, fhp->fh_dentry,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3541) getattr->ga_bmval, resp->rqstp, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3542) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3543)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3544) static __be32
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3545) nfsd4_encode_getfh(struct nfsd4_compoundres *resp, __be32 nfserr, struct svc_fh **fhpp)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3546) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3547) struct xdr_stream *xdr = &resp->xdr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3548) struct svc_fh *fhp = *fhpp;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3549) unsigned int len;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3550) __be32 *p;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3551)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3552) len = fhp->fh_handle.fh_size;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3553) p = xdr_reserve_space(xdr, len + 4);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3554) if (!p)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3555) return nfserr_resource;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3556) p = xdr_encode_opaque(p, &fhp->fh_handle.fh_base, len);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3557) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3558) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3559)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3560) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3561) * Including all fields other than the name, a LOCK4denied structure requires
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3562) * 8(clientid) + 4(namelen) + 8(offset) + 8(length) + 4(type) = 32 bytes.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3563) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3564) static __be32
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3565) nfsd4_encode_lock_denied(struct xdr_stream *xdr, struct nfsd4_lock_denied *ld)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3566) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3567) struct xdr_netobj *conf = &ld->ld_owner;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3568) __be32 *p;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3569)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3570) again:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3571) p = xdr_reserve_space(xdr, 32 + XDR_LEN(conf->len));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3572) if (!p) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3573) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3574) * Don't fail to return the result just because we can't
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3575) * return the conflicting open:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3576) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3577) if (conf->len) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3578) kfree(conf->data);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3579) conf->len = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3580) conf->data = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3581) goto again;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3582) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3583) return nfserr_resource;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3584) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3585) p = xdr_encode_hyper(p, ld->ld_start);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3586) p = xdr_encode_hyper(p, ld->ld_length);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3587) *p++ = cpu_to_be32(ld->ld_type);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3588) if (conf->len) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3589) p = xdr_encode_opaque_fixed(p, &ld->ld_clientid, 8);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3590) p = xdr_encode_opaque(p, conf->data, conf->len);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3591) kfree(conf->data);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3592) } else { /* non - nfsv4 lock in conflict, no clientid nor owner */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3593) p = xdr_encode_hyper(p, (u64)0); /* clientid */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3594) *p++ = cpu_to_be32(0); /* length of owner name */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3595) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3596) return nfserr_denied;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3597) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3598)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3599) static __be32
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3600) nfsd4_encode_lock(struct nfsd4_compoundres *resp, __be32 nfserr, struct nfsd4_lock *lock)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3601) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3602) struct xdr_stream *xdr = &resp->xdr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3603)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3604) if (!nfserr)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3605) nfserr = nfsd4_encode_stateid(xdr, &lock->lk_resp_stateid);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3606) else if (nfserr == nfserr_denied)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3607) nfserr = nfsd4_encode_lock_denied(xdr, &lock->lk_denied);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3608)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3609) return nfserr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3610) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3611)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3612) static __be32
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3613) nfsd4_encode_lockt(struct nfsd4_compoundres *resp, __be32 nfserr, struct nfsd4_lockt *lockt)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3614) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3615) struct xdr_stream *xdr = &resp->xdr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3616)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3617) if (nfserr == nfserr_denied)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3618) nfsd4_encode_lock_denied(xdr, &lockt->lt_denied);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3619) return nfserr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3620) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3621)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3622) static __be32
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3623) nfsd4_encode_locku(struct nfsd4_compoundres *resp, __be32 nfserr, struct nfsd4_locku *locku)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3624) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3625) struct xdr_stream *xdr = &resp->xdr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3626)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3627) return nfsd4_encode_stateid(xdr, &locku->lu_stateid);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3628) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3629)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3630)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3631) static __be32
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3632) nfsd4_encode_link(struct nfsd4_compoundres *resp, __be32 nfserr, struct nfsd4_link *link)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3633) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3634) struct xdr_stream *xdr = &resp->xdr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3635) __be32 *p;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3636)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3637) p = xdr_reserve_space(xdr, 20);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3638) if (!p)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3639) return nfserr_resource;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3640) p = encode_cinfo(p, &link->li_cinfo);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3641) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3642) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3643)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3644)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3645) static __be32
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3646) nfsd4_encode_open(struct nfsd4_compoundres *resp, __be32 nfserr, struct nfsd4_open *open)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3647) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3648) struct xdr_stream *xdr = &resp->xdr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3649) __be32 *p;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3650)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3651) nfserr = nfsd4_encode_stateid(xdr, &open->op_stateid);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3652) if (nfserr)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3653) return nfserr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3654) p = xdr_reserve_space(xdr, 24);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3655) if (!p)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3656) return nfserr_resource;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3657) p = encode_cinfo(p, &open->op_cinfo);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3658) *p++ = cpu_to_be32(open->op_rflags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3659)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3660) nfserr = nfsd4_encode_bitmap(xdr, open->op_bmval[0], open->op_bmval[1],
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3661) open->op_bmval[2]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3662) if (nfserr)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3663) return nfserr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3664)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3665) p = xdr_reserve_space(xdr, 4);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3666) if (!p)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3667) return nfserr_resource;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3668)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3669) *p++ = cpu_to_be32(open->op_delegate_type);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3670) switch (open->op_delegate_type) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3671) case NFS4_OPEN_DELEGATE_NONE:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3672) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3673) case NFS4_OPEN_DELEGATE_READ:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3674) nfserr = nfsd4_encode_stateid(xdr, &open->op_delegate_stateid);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3675) if (nfserr)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3676) return nfserr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3677) p = xdr_reserve_space(xdr, 20);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3678) if (!p)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3679) return nfserr_resource;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3680) *p++ = cpu_to_be32(open->op_recall);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3681)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3682) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3683) * TODO: ACE's in delegations
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3684) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3685) *p++ = cpu_to_be32(NFS4_ACE_ACCESS_ALLOWED_ACE_TYPE);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3686) *p++ = cpu_to_be32(0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3687) *p++ = cpu_to_be32(0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3688) *p++ = cpu_to_be32(0); /* XXX: is NULL principal ok? */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3689) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3690) case NFS4_OPEN_DELEGATE_WRITE:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3691) nfserr = nfsd4_encode_stateid(xdr, &open->op_delegate_stateid);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3692) if (nfserr)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3693) return nfserr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3694) p = xdr_reserve_space(xdr, 32);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3695) if (!p)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3696) return nfserr_resource;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3697) *p++ = cpu_to_be32(0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3698)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3699) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3700) * TODO: space_limit's in delegations
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3701) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3702) *p++ = cpu_to_be32(NFS4_LIMIT_SIZE);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3703) *p++ = cpu_to_be32(~(u32)0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3704) *p++ = cpu_to_be32(~(u32)0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3705)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3706) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3707) * TODO: ACE's in delegations
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3708) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3709) *p++ = cpu_to_be32(NFS4_ACE_ACCESS_ALLOWED_ACE_TYPE);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3710) *p++ = cpu_to_be32(0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3711) *p++ = cpu_to_be32(0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3712) *p++ = cpu_to_be32(0); /* XXX: is NULL principal ok? */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3713) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3714) case NFS4_OPEN_DELEGATE_NONE_EXT: /* 4.1 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3715) switch (open->op_why_no_deleg) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3716) case WND4_CONTENTION:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3717) case WND4_RESOURCE:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3718) p = xdr_reserve_space(xdr, 8);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3719) if (!p)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3720) return nfserr_resource;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3721) *p++ = cpu_to_be32(open->op_why_no_deleg);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3722) /* deleg signaling not supported yet: */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3723) *p++ = cpu_to_be32(0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3724) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3725) default:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3726) p = xdr_reserve_space(xdr, 4);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3727) if (!p)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3728) return nfserr_resource;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3729) *p++ = cpu_to_be32(open->op_why_no_deleg);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3730) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3731) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3732) default:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3733) BUG();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3734) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3735) /* XXX save filehandle here */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3736) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3737) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3738)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3739) static __be32
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3740) nfsd4_encode_open_confirm(struct nfsd4_compoundres *resp, __be32 nfserr, struct nfsd4_open_confirm *oc)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3741) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3742) struct xdr_stream *xdr = &resp->xdr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3743)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3744) return nfsd4_encode_stateid(xdr, &oc->oc_resp_stateid);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3745) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3746)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3747) static __be32
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3748) nfsd4_encode_open_downgrade(struct nfsd4_compoundres *resp, __be32 nfserr, struct nfsd4_open_downgrade *od)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3749) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3750) struct xdr_stream *xdr = &resp->xdr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3751)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3752) return nfsd4_encode_stateid(xdr, &od->od_stateid);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3753) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3754)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3755) static __be32 nfsd4_encode_splice_read(
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3756) struct nfsd4_compoundres *resp,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3757) struct nfsd4_read *read,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3758) struct file *file, unsigned long maxcount)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3759) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3760) struct xdr_stream *xdr = &resp->xdr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3761) struct xdr_buf *buf = xdr->buf;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3762) u32 eof;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3763) int space_left;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3764) __be32 nfserr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3765) __be32 *p = xdr->p - 2;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3766)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3767) /* Make sure there will be room for padding if needed */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3768) if (xdr->end - xdr->p < 1)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3769) return nfserr_resource;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3770)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3771) nfserr = nfsd_splice_read(read->rd_rqstp, read->rd_fhp,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3772) file, read->rd_offset, &maxcount, &eof);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3773) read->rd_length = maxcount;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3774) if (nfserr) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3775) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3776) * nfsd_splice_actor may have already messed with the
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3777) * page length; reset it so as not to confuse
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3778) * xdr_truncate_encode:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3779) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3780) buf->page_len = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3781) return nfserr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3782) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3783)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3784) *(p++) = htonl(eof);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3785) *(p++) = htonl(maxcount);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3786)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3787) buf->page_len = maxcount;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3788) buf->len += maxcount;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3789) xdr->page_ptr += (buf->page_base + maxcount + PAGE_SIZE - 1)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3790) / PAGE_SIZE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3791)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3792) /* Use rest of head for padding and remaining ops: */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3793) buf->tail[0].iov_base = xdr->p;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3794) buf->tail[0].iov_len = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3795) xdr->iov = buf->tail;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3796) if (maxcount&3) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3797) int pad = 4 - (maxcount&3);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3798)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3799) *(xdr->p++) = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3800)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3801) buf->tail[0].iov_base += maxcount&3;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3802) buf->tail[0].iov_len = pad;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3803) buf->len += pad;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3804) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3805)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3806) space_left = min_t(int, (void *)xdr->end - (void *)xdr->p,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3807) buf->buflen - buf->len);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3808) buf->buflen = buf->len + space_left;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3809) xdr->end = (__be32 *)((void *)xdr->end + space_left);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3810)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3811) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3812) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3813)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3814) static __be32 nfsd4_encode_readv(struct nfsd4_compoundres *resp,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3815) struct nfsd4_read *read,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3816) struct file *file, unsigned long maxcount)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3817) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3818) struct xdr_stream *xdr = &resp->xdr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3819) u32 eof;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3820) int starting_len = xdr->buf->len - 8;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3821) __be32 nfserr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3822) __be32 tmp;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3823) int pad;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3824)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3825) read->rd_vlen = xdr_reserve_space_vec(xdr, resp->rqstp->rq_vec, maxcount);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3826) if (read->rd_vlen < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3827) return nfserr_resource;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3828)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3829) nfserr = nfsd_readv(resp->rqstp, read->rd_fhp, file, read->rd_offset,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3830) resp->rqstp->rq_vec, read->rd_vlen, &maxcount,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3831) &eof);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3832) read->rd_length = maxcount;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3833) if (nfserr)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3834) return nfserr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3835) if (svc_encode_read_payload(resp->rqstp, starting_len + 8, maxcount))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3836) return nfserr_io;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3837) xdr_truncate_encode(xdr, starting_len + 8 + xdr_align_size(maxcount));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3838)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3839) tmp = htonl(eof);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3840) write_bytes_to_xdr_buf(xdr->buf, starting_len , &tmp, 4);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3841) tmp = htonl(maxcount);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3842) write_bytes_to_xdr_buf(xdr->buf, starting_len + 4, &tmp, 4);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3843)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3844) tmp = xdr_zero;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3845) pad = (maxcount&3) ? 4 - (maxcount&3) : 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3846) write_bytes_to_xdr_buf(xdr->buf, starting_len + 8 + maxcount,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3847) &tmp, pad);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3848) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3849)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3850) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3851)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3852) static __be32
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3853) nfsd4_encode_read(struct nfsd4_compoundres *resp, __be32 nfserr,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3854) struct nfsd4_read *read)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3855) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3856) unsigned long maxcount;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3857) struct xdr_stream *xdr = &resp->xdr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3858) struct file *file;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3859) int starting_len = xdr->buf->len;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3860) __be32 *p;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3861)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3862) if (nfserr)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3863) return nfserr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3864) file = read->rd_nf->nf_file;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3865)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3866) p = xdr_reserve_space(xdr, 8); /* eof flag and byte count */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3867) if (!p) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3868) WARN_ON_ONCE(test_bit(RQ_SPLICE_OK, &resp->rqstp->rq_flags));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3869) return nfserr_resource;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3870) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3871) if (resp->xdr.buf->page_len &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3872) test_bit(RQ_SPLICE_OK, &resp->rqstp->rq_flags)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3873) WARN_ON_ONCE(1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3874) return nfserr_resource;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3875) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3876) xdr_commit_encode(xdr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3877)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3878) maxcount = svc_max_payload(resp->rqstp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3879) maxcount = min_t(unsigned long, maxcount,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3880) (xdr->buf->buflen - xdr->buf->len));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3881) maxcount = min_t(unsigned long, maxcount, read->rd_length);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3882)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3883) if (file->f_op->splice_read &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3884) test_bit(RQ_SPLICE_OK, &resp->rqstp->rq_flags))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3885) nfserr = nfsd4_encode_splice_read(resp, read, file, maxcount);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3886) else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3887) nfserr = nfsd4_encode_readv(resp, read, file, maxcount);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3888)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3889) if (nfserr)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3890) xdr_truncate_encode(xdr, starting_len);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3891)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3892) return nfserr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3893) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3894)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3895) static __be32
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3896) nfsd4_encode_readlink(struct nfsd4_compoundres *resp, __be32 nfserr, struct nfsd4_readlink *readlink)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3897) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3898) int maxcount;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3899) __be32 wire_count;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3900) int zero = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3901) struct xdr_stream *xdr = &resp->xdr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3902) int length_offset = xdr->buf->len;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3903) __be32 *p;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3904)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3905) p = xdr_reserve_space(xdr, 4);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3906) if (!p)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3907) return nfserr_resource;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3908) maxcount = PAGE_SIZE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3909)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3910) p = xdr_reserve_space(xdr, maxcount);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3911) if (!p)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3912) return nfserr_resource;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3913) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3914) * XXX: By default, vfs_readlink() will truncate symlinks if they
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3915) * would overflow the buffer. Is this kosher in NFSv4? If not, one
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3916) * easy fix is: if vfs_readlink() precisely fills the buffer, assume
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3917) * that truncation occurred, and return NFS4ERR_RESOURCE.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3918) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3919) nfserr = nfsd_readlink(readlink->rl_rqstp, readlink->rl_fhp,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3920) (char *)p, &maxcount);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3921) if (nfserr == nfserr_isdir)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3922) nfserr = nfserr_inval;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3923) if (nfserr) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3924) xdr_truncate_encode(xdr, length_offset);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3925) return nfserr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3926) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3927)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3928) wire_count = htonl(maxcount);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3929) write_bytes_to_xdr_buf(xdr->buf, length_offset, &wire_count, 4);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3930) xdr_truncate_encode(xdr, length_offset + 4 + ALIGN(maxcount, 4));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3931) if (maxcount & 3)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3932) write_bytes_to_xdr_buf(xdr->buf, length_offset + 4 + maxcount,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3933) &zero, 4 - (maxcount&3));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3934) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3935) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3936)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3937) static __be32
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3938) nfsd4_encode_readdir(struct nfsd4_compoundres *resp, __be32 nfserr, struct nfsd4_readdir *readdir)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3939) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3940) int maxcount;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3941) int bytes_left;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3942) loff_t offset;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3943) __be64 wire_offset;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3944) struct xdr_stream *xdr = &resp->xdr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3945) int starting_len = xdr->buf->len;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3946) __be32 *p;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3947)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3948) p = xdr_reserve_space(xdr, NFS4_VERIFIER_SIZE);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3949) if (!p)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3950) return nfserr_resource;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3951)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3952) /* XXX: Following NFSv3, we ignore the READDIR verifier for now. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3953) *p++ = cpu_to_be32(0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3954) *p++ = cpu_to_be32(0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3955) resp->xdr.buf->head[0].iov_len = ((char *)resp->xdr.p)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3956) - (char *)resp->xdr.buf->head[0].iov_base;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3957)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3958) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3959) * Number of bytes left for directory entries allowing for the
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3960) * final 8 bytes of the readdir and a following failed op:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3961) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3962) bytes_left = xdr->buf->buflen - xdr->buf->len
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3963) - COMPOUND_ERR_SLACK_SPACE - 8;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3964) if (bytes_left < 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3965) nfserr = nfserr_resource;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3966) goto err_no_verf;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3967) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3968) maxcount = svc_max_payload(resp->rqstp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3969) maxcount = min_t(u32, readdir->rd_maxcount, maxcount);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3970) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3971) * Note the rfc defines rd_maxcount as the size of the
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3972) * READDIR4resok structure, which includes the verifier above
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3973) * and the 8 bytes encoded at the end of this function:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3974) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3975) if (maxcount < 16) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3976) nfserr = nfserr_toosmall;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3977) goto err_no_verf;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3978) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3979) maxcount = min_t(int, maxcount-16, bytes_left);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3980)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3981) /* RFC 3530 14.2.24 allows us to ignore dircount when it's 0: */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3982) if (!readdir->rd_dircount)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3983) readdir->rd_dircount = svc_max_payload(resp->rqstp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3984)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3985) readdir->xdr = xdr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3986) readdir->rd_maxcount = maxcount;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3987) readdir->common.err = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3988) readdir->cookie_offset = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3989)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3990) offset = readdir->rd_cookie;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3991) nfserr = nfsd_readdir(readdir->rd_rqstp, readdir->rd_fhp,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3992) &offset,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3993) &readdir->common, nfsd4_encode_dirent);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3994) if (nfserr == nfs_ok &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3995) readdir->common.err == nfserr_toosmall &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3996) xdr->buf->len == starting_len + 8) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3997) /* nothing encoded; which limit did we hit?: */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3998) if (maxcount - 16 < bytes_left)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3999) /* It was the fault of rd_maxcount: */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4000) nfserr = nfserr_toosmall;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4001) else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4002) /* We ran out of buffer space: */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4003) nfserr = nfserr_resource;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4004) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4005) if (nfserr)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4006) goto err_no_verf;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4007)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4008) if (readdir->cookie_offset) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4009) wire_offset = cpu_to_be64(offset);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4010) write_bytes_to_xdr_buf(xdr->buf, readdir->cookie_offset,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4011) &wire_offset, 8);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4012) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4013)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4014) p = xdr_reserve_space(xdr, 8);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4015) if (!p) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4016) WARN_ON_ONCE(1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4017) goto err_no_verf;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4018) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4019) *p++ = 0; /* no more entries */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4020) *p++ = htonl(readdir->common.err == nfserr_eof);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4021)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4022) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4023) err_no_verf:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4024) xdr_truncate_encode(xdr, starting_len);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4025) return nfserr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4026) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4027)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4028) static __be32
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4029) nfsd4_encode_remove(struct nfsd4_compoundres *resp, __be32 nfserr, struct nfsd4_remove *remove)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4030) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4031) struct xdr_stream *xdr = &resp->xdr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4032) __be32 *p;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4033)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4034) p = xdr_reserve_space(xdr, 20);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4035) if (!p)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4036) return nfserr_resource;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4037) p = encode_cinfo(p, &remove->rm_cinfo);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4038) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4039) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4040)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4041) static __be32
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4042) nfsd4_encode_rename(struct nfsd4_compoundres *resp, __be32 nfserr, struct nfsd4_rename *rename)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4043) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4044) struct xdr_stream *xdr = &resp->xdr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4045) __be32 *p;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4046)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4047) p = xdr_reserve_space(xdr, 40);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4048) if (!p)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4049) return nfserr_resource;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4050) p = encode_cinfo(p, &rename->rn_sinfo);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4051) p = encode_cinfo(p, &rename->rn_tinfo);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4052) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4053) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4054)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4055) static __be32
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4056) nfsd4_do_encode_secinfo(struct xdr_stream *xdr, struct svc_export *exp)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4057) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4058) u32 i, nflavs, supported;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4059) struct exp_flavor_info *flavs;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4060) struct exp_flavor_info def_flavs[2];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4061) __be32 *p, *flavorsp;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4062) static bool report = true;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4063)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4064) if (exp->ex_nflavors) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4065) flavs = exp->ex_flavors;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4066) nflavs = exp->ex_nflavors;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4067) } else { /* Handling of some defaults in absence of real secinfo: */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4068) flavs = def_flavs;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4069) if (exp->ex_client->flavour->flavour == RPC_AUTH_UNIX) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4070) nflavs = 2;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4071) flavs[0].pseudoflavor = RPC_AUTH_UNIX;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4072) flavs[1].pseudoflavor = RPC_AUTH_NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4073) } else if (exp->ex_client->flavour->flavour == RPC_AUTH_GSS) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4074) nflavs = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4075) flavs[0].pseudoflavor
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4076) = svcauth_gss_flavor(exp->ex_client);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4077) } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4078) nflavs = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4079) flavs[0].pseudoflavor
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4080) = exp->ex_client->flavour->flavour;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4081) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4082) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4083)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4084) supported = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4085) p = xdr_reserve_space(xdr, 4);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4086) if (!p)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4087) return nfserr_resource;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4088) flavorsp = p++; /* to be backfilled later */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4089)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4090) for (i = 0; i < nflavs; i++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4091) rpc_authflavor_t pf = flavs[i].pseudoflavor;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4092) struct rpcsec_gss_info info;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4093)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4094) if (rpcauth_get_gssinfo(pf, &info) == 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4095) supported++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4096) p = xdr_reserve_space(xdr, 4 + 4 +
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4097) XDR_LEN(info.oid.len) + 4 + 4);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4098) if (!p)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4099) return nfserr_resource;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4100) *p++ = cpu_to_be32(RPC_AUTH_GSS);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4101) p = xdr_encode_opaque(p, info.oid.data, info.oid.len);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4102) *p++ = cpu_to_be32(info.qop);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4103) *p++ = cpu_to_be32(info.service);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4104) } else if (pf < RPC_AUTH_MAXFLAVOR) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4105) supported++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4106) p = xdr_reserve_space(xdr, 4);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4107) if (!p)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4108) return nfserr_resource;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4109) *p++ = cpu_to_be32(pf);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4110) } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4111) if (report)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4112) pr_warn("NFS: SECINFO: security flavor %u "
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4113) "is not supported\n", pf);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4114) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4115) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4116)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4117) if (nflavs != supported)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4118) report = false;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4119) *flavorsp = htonl(supported);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4120) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4121) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4122)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4123) static __be32
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4124) nfsd4_encode_secinfo(struct nfsd4_compoundres *resp, __be32 nfserr,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4125) struct nfsd4_secinfo *secinfo)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4126) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4127) struct xdr_stream *xdr = &resp->xdr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4128)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4129) return nfsd4_do_encode_secinfo(xdr, secinfo->si_exp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4130) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4131)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4132) static __be32
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4133) nfsd4_encode_secinfo_no_name(struct nfsd4_compoundres *resp, __be32 nfserr,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4134) struct nfsd4_secinfo_no_name *secinfo)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4135) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4136) struct xdr_stream *xdr = &resp->xdr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4137)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4138) return nfsd4_do_encode_secinfo(xdr, secinfo->sin_exp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4139) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4140)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4141) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4142) * The SETATTR encode routine is special -- it always encodes a bitmap,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4143) * regardless of the error status.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4144) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4145) static __be32
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4146) nfsd4_encode_setattr(struct nfsd4_compoundres *resp, __be32 nfserr, struct nfsd4_setattr *setattr)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4147) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4148) struct xdr_stream *xdr = &resp->xdr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4149) __be32 *p;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4150)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4151) p = xdr_reserve_space(xdr, 16);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4152) if (!p)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4153) return nfserr_resource;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4154) if (nfserr) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4155) *p++ = cpu_to_be32(3);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4156) *p++ = cpu_to_be32(0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4157) *p++ = cpu_to_be32(0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4158) *p++ = cpu_to_be32(0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4159) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4160) else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4161) *p++ = cpu_to_be32(3);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4162) *p++ = cpu_to_be32(setattr->sa_bmval[0]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4163) *p++ = cpu_to_be32(setattr->sa_bmval[1]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4164) *p++ = cpu_to_be32(setattr->sa_bmval[2]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4165) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4166) return nfserr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4167) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4168)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4169) static __be32
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4170) nfsd4_encode_setclientid(struct nfsd4_compoundres *resp, __be32 nfserr, struct nfsd4_setclientid *scd)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4171) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4172) struct xdr_stream *xdr = &resp->xdr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4173) __be32 *p;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4174)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4175) if (!nfserr) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4176) p = xdr_reserve_space(xdr, 8 + NFS4_VERIFIER_SIZE);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4177) if (!p)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4178) return nfserr_resource;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4179) p = xdr_encode_opaque_fixed(p, &scd->se_clientid, 8);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4180) p = xdr_encode_opaque_fixed(p, &scd->se_confirm,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4181) NFS4_VERIFIER_SIZE);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4182) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4183) else if (nfserr == nfserr_clid_inuse) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4184) p = xdr_reserve_space(xdr, 8);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4185) if (!p)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4186) return nfserr_resource;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4187) *p++ = cpu_to_be32(0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4188) *p++ = cpu_to_be32(0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4189) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4190) return nfserr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4191) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4192)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4193) static __be32
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4194) nfsd4_encode_write(struct nfsd4_compoundres *resp, __be32 nfserr, struct nfsd4_write *write)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4195) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4196) struct xdr_stream *xdr = &resp->xdr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4197) __be32 *p;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4198)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4199) p = xdr_reserve_space(xdr, 16);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4200) if (!p)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4201) return nfserr_resource;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4202) *p++ = cpu_to_be32(write->wr_bytes_written);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4203) *p++ = cpu_to_be32(write->wr_how_written);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4204) p = xdr_encode_opaque_fixed(p, write->wr_verifier.data,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4205) NFS4_VERIFIER_SIZE);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4206) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4207) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4208)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4209) static __be32
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4210) nfsd4_encode_exchange_id(struct nfsd4_compoundres *resp, __be32 nfserr,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4211) struct nfsd4_exchange_id *exid)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4212) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4213) struct xdr_stream *xdr = &resp->xdr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4214) __be32 *p;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4215) char *major_id;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4216) char *server_scope;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4217) int major_id_sz;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4218) int server_scope_sz;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4219) uint64_t minor_id = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4220) struct nfsd_net *nn = net_generic(SVC_NET(resp->rqstp), nfsd_net_id);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4221)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4222) major_id = nn->nfsd_name;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4223) major_id_sz = strlen(nn->nfsd_name);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4224) server_scope = nn->nfsd_name;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4225) server_scope_sz = strlen(nn->nfsd_name);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4226)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4227) p = xdr_reserve_space(xdr,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4228) 8 /* eir_clientid */ +
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4229) 4 /* eir_sequenceid */ +
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4230) 4 /* eir_flags */ +
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4231) 4 /* spr_how */);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4232) if (!p)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4233) return nfserr_resource;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4234)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4235) p = xdr_encode_opaque_fixed(p, &exid->clientid, 8);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4236) *p++ = cpu_to_be32(exid->seqid);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4237) *p++ = cpu_to_be32(exid->flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4238)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4239) *p++ = cpu_to_be32(exid->spa_how);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4240)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4241) switch (exid->spa_how) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4242) case SP4_NONE:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4243) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4244) case SP4_MACH_CRED:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4245) /* spo_must_enforce bitmap: */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4246) nfserr = nfsd4_encode_bitmap(xdr,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4247) exid->spo_must_enforce[0],
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4248) exid->spo_must_enforce[1],
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4249) exid->spo_must_enforce[2]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4250) if (nfserr)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4251) return nfserr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4252) /* spo_must_allow bitmap: */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4253) nfserr = nfsd4_encode_bitmap(xdr,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4254) exid->spo_must_allow[0],
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4255) exid->spo_must_allow[1],
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4256) exid->spo_must_allow[2]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4257) if (nfserr)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4258) return nfserr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4259) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4260) default:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4261) WARN_ON_ONCE(1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4262) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4263)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4264) p = xdr_reserve_space(xdr,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4265) 8 /* so_minor_id */ +
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4266) 4 /* so_major_id.len */ +
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4267) (XDR_QUADLEN(major_id_sz) * 4) +
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4268) 4 /* eir_server_scope.len */ +
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4269) (XDR_QUADLEN(server_scope_sz) * 4) +
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4270) 4 /* eir_server_impl_id.count (0) */);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4271) if (!p)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4272) return nfserr_resource;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4273)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4274) /* The server_owner struct */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4275) p = xdr_encode_hyper(p, minor_id); /* Minor id */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4276) /* major id */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4277) p = xdr_encode_opaque(p, major_id, major_id_sz);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4278)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4279) /* Server scope */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4280) p = xdr_encode_opaque(p, server_scope, server_scope_sz);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4281)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4282) /* Implementation id */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4283) *p++ = cpu_to_be32(0); /* zero length nfs_impl_id4 array */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4284) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4285) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4286)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4287) static __be32
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4288) nfsd4_encode_create_session(struct nfsd4_compoundres *resp, __be32 nfserr,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4289) struct nfsd4_create_session *sess)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4290) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4291) struct xdr_stream *xdr = &resp->xdr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4292) __be32 *p;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4293)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4294) p = xdr_reserve_space(xdr, 24);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4295) if (!p)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4296) return nfserr_resource;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4297) p = xdr_encode_opaque_fixed(p, sess->sessionid.data,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4298) NFS4_MAX_SESSIONID_LEN);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4299) *p++ = cpu_to_be32(sess->seqid);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4300) *p++ = cpu_to_be32(sess->flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4301)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4302) p = xdr_reserve_space(xdr, 28);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4303) if (!p)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4304) return nfserr_resource;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4305) *p++ = cpu_to_be32(0); /* headerpadsz */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4306) *p++ = cpu_to_be32(sess->fore_channel.maxreq_sz);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4307) *p++ = cpu_to_be32(sess->fore_channel.maxresp_sz);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4308) *p++ = cpu_to_be32(sess->fore_channel.maxresp_cached);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4309) *p++ = cpu_to_be32(sess->fore_channel.maxops);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4310) *p++ = cpu_to_be32(sess->fore_channel.maxreqs);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4311) *p++ = cpu_to_be32(sess->fore_channel.nr_rdma_attrs);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4312)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4313) if (sess->fore_channel.nr_rdma_attrs) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4314) p = xdr_reserve_space(xdr, 4);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4315) if (!p)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4316) return nfserr_resource;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4317) *p++ = cpu_to_be32(sess->fore_channel.rdma_attrs);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4318) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4319)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4320) p = xdr_reserve_space(xdr, 28);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4321) if (!p)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4322) return nfserr_resource;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4323) *p++ = cpu_to_be32(0); /* headerpadsz */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4324) *p++ = cpu_to_be32(sess->back_channel.maxreq_sz);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4325) *p++ = cpu_to_be32(sess->back_channel.maxresp_sz);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4326) *p++ = cpu_to_be32(sess->back_channel.maxresp_cached);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4327) *p++ = cpu_to_be32(sess->back_channel.maxops);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4328) *p++ = cpu_to_be32(sess->back_channel.maxreqs);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4329) *p++ = cpu_to_be32(sess->back_channel.nr_rdma_attrs);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4330)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4331) if (sess->back_channel.nr_rdma_attrs) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4332) p = xdr_reserve_space(xdr, 4);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4333) if (!p)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4334) return nfserr_resource;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4335) *p++ = cpu_to_be32(sess->back_channel.rdma_attrs);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4336) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4337) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4338) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4339)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4340) static __be32
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4341) nfsd4_encode_sequence(struct nfsd4_compoundres *resp, __be32 nfserr,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4342) struct nfsd4_sequence *seq)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4343) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4344) struct xdr_stream *xdr = &resp->xdr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4345) __be32 *p;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4346)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4347) p = xdr_reserve_space(xdr, NFS4_MAX_SESSIONID_LEN + 20);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4348) if (!p)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4349) return nfserr_resource;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4350) p = xdr_encode_opaque_fixed(p, seq->sessionid.data,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4351) NFS4_MAX_SESSIONID_LEN);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4352) *p++ = cpu_to_be32(seq->seqid);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4353) *p++ = cpu_to_be32(seq->slotid);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4354) /* Note slotid's are numbered from zero: */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4355) *p++ = cpu_to_be32(seq->maxslots - 1); /* sr_highest_slotid */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4356) *p++ = cpu_to_be32(seq->maxslots - 1); /* sr_target_highest_slotid */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4357) *p++ = cpu_to_be32(seq->status_flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4358)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4359) resp->cstate.data_offset = xdr->buf->len; /* DRC cache data pointer */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4360) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4361) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4362)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4363) static __be32
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4364) nfsd4_encode_test_stateid(struct nfsd4_compoundres *resp, __be32 nfserr,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4365) struct nfsd4_test_stateid *test_stateid)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4366) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4367) struct xdr_stream *xdr = &resp->xdr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4368) struct nfsd4_test_stateid_id *stateid, *next;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4369) __be32 *p;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4370)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4371) p = xdr_reserve_space(xdr, 4 + (4 * test_stateid->ts_num_ids));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4372) if (!p)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4373) return nfserr_resource;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4374) *p++ = htonl(test_stateid->ts_num_ids);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4375)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4376) list_for_each_entry_safe(stateid, next, &test_stateid->ts_stateid_list, ts_id_list) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4377) *p++ = stateid->ts_id_status;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4378) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4379)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4380) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4381) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4382)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4383) #ifdef CONFIG_NFSD_PNFS
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4384) static __be32
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4385) nfsd4_encode_getdeviceinfo(struct nfsd4_compoundres *resp, __be32 nfserr,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4386) struct nfsd4_getdeviceinfo *gdev)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4387) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4388) struct xdr_stream *xdr = &resp->xdr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4389) const struct nfsd4_layout_ops *ops;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4390) u32 starting_len = xdr->buf->len, needed_len;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4391) __be32 *p;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4392)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4393) p = xdr_reserve_space(xdr, 4);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4394) if (!p)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4395) return nfserr_resource;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4396)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4397) *p++ = cpu_to_be32(gdev->gd_layout_type);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4398)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4399) /* If maxcount is 0 then just update notifications */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4400) if (gdev->gd_maxcount != 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4401) ops = nfsd4_layout_ops[gdev->gd_layout_type];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4402) nfserr = ops->encode_getdeviceinfo(xdr, gdev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4403) if (nfserr) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4404) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4405) * We don't bother to burden the layout drivers with
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4406) * enforcing gd_maxcount, just tell the client to
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4407) * come back with a bigger buffer if it's not enough.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4408) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4409) if (xdr->buf->len + 4 > gdev->gd_maxcount)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4410) goto toosmall;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4411) return nfserr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4412) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4413) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4414)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4415) if (gdev->gd_notify_types) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4416) p = xdr_reserve_space(xdr, 4 + 4);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4417) if (!p)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4418) return nfserr_resource;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4419) *p++ = cpu_to_be32(1); /* bitmap length */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4420) *p++ = cpu_to_be32(gdev->gd_notify_types);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4421) } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4422) p = xdr_reserve_space(xdr, 4);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4423) if (!p)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4424) return nfserr_resource;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4425) *p++ = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4426) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4427)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4428) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4429) toosmall:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4430) dprintk("%s: maxcount too small\n", __func__);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4431) needed_len = xdr->buf->len + 4 /* notifications */;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4432) xdr_truncate_encode(xdr, starting_len);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4433) p = xdr_reserve_space(xdr, 4);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4434) if (!p)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4435) return nfserr_resource;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4436) *p++ = cpu_to_be32(needed_len);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4437) return nfserr_toosmall;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4438) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4439)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4440) static __be32
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4441) nfsd4_encode_layoutget(struct nfsd4_compoundres *resp, __be32 nfserr,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4442) struct nfsd4_layoutget *lgp)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4443) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4444) struct xdr_stream *xdr = &resp->xdr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4445) const struct nfsd4_layout_ops *ops;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4446) __be32 *p;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4447)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4448) p = xdr_reserve_space(xdr, 36 + sizeof(stateid_opaque_t));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4449) if (!p)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4450) return nfserr_resource;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4451)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4452) *p++ = cpu_to_be32(1); /* we always set return-on-close */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4453) *p++ = cpu_to_be32(lgp->lg_sid.si_generation);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4454) p = xdr_encode_opaque_fixed(p, &lgp->lg_sid.si_opaque,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4455) sizeof(stateid_opaque_t));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4456)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4457) *p++ = cpu_to_be32(1); /* we always return a single layout */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4458) p = xdr_encode_hyper(p, lgp->lg_seg.offset);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4459) p = xdr_encode_hyper(p, lgp->lg_seg.length);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4460) *p++ = cpu_to_be32(lgp->lg_seg.iomode);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4461) *p++ = cpu_to_be32(lgp->lg_layout_type);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4462)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4463) ops = nfsd4_layout_ops[lgp->lg_layout_type];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4464) return ops->encode_layoutget(xdr, lgp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4465) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4466)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4467) static __be32
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4468) nfsd4_encode_layoutcommit(struct nfsd4_compoundres *resp, __be32 nfserr,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4469) struct nfsd4_layoutcommit *lcp)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4470) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4471) struct xdr_stream *xdr = &resp->xdr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4472) __be32 *p;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4473)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4474) p = xdr_reserve_space(xdr, 4);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4475) if (!p)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4476) return nfserr_resource;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4477) *p++ = cpu_to_be32(lcp->lc_size_chg);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4478) if (lcp->lc_size_chg) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4479) p = xdr_reserve_space(xdr, 8);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4480) if (!p)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4481) return nfserr_resource;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4482) p = xdr_encode_hyper(p, lcp->lc_newsize);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4483) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4484)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4485) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4486) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4487)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4488) static __be32
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4489) nfsd4_encode_layoutreturn(struct nfsd4_compoundres *resp, __be32 nfserr,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4490) struct nfsd4_layoutreturn *lrp)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4491) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4492) struct xdr_stream *xdr = &resp->xdr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4493) __be32 *p;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4494)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4495) p = xdr_reserve_space(xdr, 4);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4496) if (!p)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4497) return nfserr_resource;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4498) *p++ = cpu_to_be32(lrp->lrs_present);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4499) if (lrp->lrs_present)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4500) return nfsd4_encode_stateid(xdr, &lrp->lr_sid);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4501) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4502) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4503) #endif /* CONFIG_NFSD_PNFS */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4504)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4505) static __be32
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4506) nfsd42_encode_write_res(struct nfsd4_compoundres *resp,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4507) struct nfsd42_write_res *write, bool sync)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4508) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4509) __be32 *p;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4510) p = xdr_reserve_space(&resp->xdr, 4);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4511) if (!p)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4512) return nfserr_resource;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4513)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4514) if (sync)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4515) *p++ = cpu_to_be32(0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4516) else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4517) __be32 nfserr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4518) *p++ = cpu_to_be32(1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4519) nfserr = nfsd4_encode_stateid(&resp->xdr, &write->cb_stateid);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4520) if (nfserr)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4521) return nfserr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4522) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4523) p = xdr_reserve_space(&resp->xdr, 8 + 4 + NFS4_VERIFIER_SIZE);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4524) if (!p)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4525) return nfserr_resource;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4526)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4527) p = xdr_encode_hyper(p, write->wr_bytes_written);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4528) *p++ = cpu_to_be32(write->wr_stable_how);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4529) p = xdr_encode_opaque_fixed(p, write->wr_verifier.data,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4530) NFS4_VERIFIER_SIZE);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4531) return nfs_ok;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4532) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4533)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4534) static __be32
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4535) nfsd42_encode_nl4_server(struct nfsd4_compoundres *resp, struct nl4_server *ns)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4536) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4537) struct xdr_stream *xdr = &resp->xdr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4538) struct nfs42_netaddr *addr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4539) __be32 *p;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4540)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4541) p = xdr_reserve_space(xdr, 4);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4542) *p++ = cpu_to_be32(ns->nl4_type);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4543)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4544) switch (ns->nl4_type) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4545) case NL4_NETADDR:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4546) addr = &ns->u.nl4_addr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4547)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4548) /* netid_len, netid, uaddr_len, uaddr (port included
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4549) * in RPCBIND_MAXUADDRLEN)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4550) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4551) p = xdr_reserve_space(xdr,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4552) 4 /* netid len */ +
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4553) (XDR_QUADLEN(addr->netid_len) * 4) +
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4554) 4 /* uaddr len */ +
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4555) (XDR_QUADLEN(addr->addr_len) * 4));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4556) if (!p)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4557) return nfserr_resource;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4558)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4559) *p++ = cpu_to_be32(addr->netid_len);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4560) p = xdr_encode_opaque_fixed(p, addr->netid,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4561) addr->netid_len);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4562) *p++ = cpu_to_be32(addr->addr_len);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4563) p = xdr_encode_opaque_fixed(p, addr->addr,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4564) addr->addr_len);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4565) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4566) default:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4567) WARN_ON_ONCE(ns->nl4_type != NL4_NETADDR);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4568) return nfserr_inval;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4569) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4570)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4571) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4572) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4573)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4574) static __be32
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4575) nfsd4_encode_copy(struct nfsd4_compoundres *resp, __be32 nfserr,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4576) struct nfsd4_copy *copy)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4577) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4578) __be32 *p;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4579)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4580) nfserr = nfsd42_encode_write_res(resp, ©->cp_res,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4581) copy->cp_synchronous);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4582) if (nfserr)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4583) return nfserr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4584)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4585) p = xdr_reserve_space(&resp->xdr, 4 + 4);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4586) *p++ = xdr_one; /* cr_consecutive */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4587) *p++ = cpu_to_be32(copy->cp_synchronous);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4588) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4589) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4590)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4591) static __be32
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4592) nfsd4_encode_offload_status(struct nfsd4_compoundres *resp, __be32 nfserr,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4593) struct nfsd4_offload_status *os)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4594) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4595) struct xdr_stream *xdr = &resp->xdr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4596) __be32 *p;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4597)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4598) p = xdr_reserve_space(xdr, 8 + 4);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4599) if (!p)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4600) return nfserr_resource;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4601) p = xdr_encode_hyper(p, os->count);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4602) *p++ = cpu_to_be32(0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4603) return nfserr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4604) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4605)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4606) static __be32
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4607) nfsd4_encode_read_plus_data(struct nfsd4_compoundres *resp,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4608) struct nfsd4_read *read,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4609) unsigned long *maxcount, u32 *eof,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4610) loff_t *pos)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4611) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4612) struct xdr_stream *xdr = &resp->xdr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4613) struct file *file = read->rd_nf->nf_file;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4614) int starting_len = xdr->buf->len;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4615) loff_t hole_pos;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4616) __be32 nfserr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4617) __be32 *p, tmp;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4618) __be64 tmp64;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4619)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4620) hole_pos = pos ? *pos : vfs_llseek(file, read->rd_offset, SEEK_HOLE);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4621) if (hole_pos > read->rd_offset)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4622) *maxcount = min_t(unsigned long, *maxcount, hole_pos - read->rd_offset);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4623) *maxcount = min_t(unsigned long, *maxcount, (xdr->buf->buflen - xdr->buf->len));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4624)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4625) /* Content type, offset, byte count */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4626) p = xdr_reserve_space(xdr, 4 + 8 + 4);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4627) if (!p)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4628) return nfserr_resource;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4629)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4630) read->rd_vlen = xdr_reserve_space_vec(xdr, resp->rqstp->rq_vec, *maxcount);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4631) if (read->rd_vlen < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4632) return nfserr_resource;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4633)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4634) nfserr = nfsd_readv(resp->rqstp, read->rd_fhp, file, read->rd_offset,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4635) resp->rqstp->rq_vec, read->rd_vlen, maxcount, eof);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4636) if (nfserr)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4637) return nfserr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4638) xdr_truncate_encode(xdr, starting_len + 16 + xdr_align_size(*maxcount));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4639)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4640) tmp = htonl(NFS4_CONTENT_DATA);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4641) write_bytes_to_xdr_buf(xdr->buf, starting_len, &tmp, 4);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4642) tmp64 = cpu_to_be64(read->rd_offset);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4643) write_bytes_to_xdr_buf(xdr->buf, starting_len + 4, &tmp64, 8);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4644) tmp = htonl(*maxcount);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4645) write_bytes_to_xdr_buf(xdr->buf, starting_len + 12, &tmp, 4);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4646)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4647) tmp = xdr_zero;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4648) write_bytes_to_xdr_buf(xdr->buf, starting_len + 16 + *maxcount, &tmp,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4649) xdr_pad_size(*maxcount));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4650) return nfs_ok;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4651) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4652)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4653) static __be32
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4654) nfsd4_encode_read_plus_hole(struct nfsd4_compoundres *resp,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4655) struct nfsd4_read *read,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4656) unsigned long *maxcount, u32 *eof)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4657) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4658) struct file *file = read->rd_nf->nf_file;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4659) loff_t data_pos = vfs_llseek(file, read->rd_offset, SEEK_DATA);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4660) loff_t f_size = i_size_read(file_inode(file));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4661) unsigned long count;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4662) __be32 *p;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4663)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4664) if (data_pos == -ENXIO)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4665) data_pos = f_size;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4666) else if (data_pos <= read->rd_offset || (data_pos < f_size && data_pos % PAGE_SIZE))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4667) return nfsd4_encode_read_plus_data(resp, read, maxcount, eof, &f_size);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4668) count = data_pos - read->rd_offset;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4669)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4670) /* Content type, offset, byte count */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4671) p = xdr_reserve_space(&resp->xdr, 4 + 8 + 8);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4672) if (!p)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4673) return nfserr_resource;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4674)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4675) *p++ = htonl(NFS4_CONTENT_HOLE);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4676) p = xdr_encode_hyper(p, read->rd_offset);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4677) p = xdr_encode_hyper(p, count);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4678)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4679) *eof = (read->rd_offset + count) >= f_size;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4680) *maxcount = min_t(unsigned long, count, *maxcount);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4681) return nfs_ok;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4682) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4683)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4684) static __be32
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4685) nfsd4_encode_read_plus(struct nfsd4_compoundres *resp, __be32 nfserr,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4686) struct nfsd4_read *read)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4687) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4688) unsigned long maxcount, count;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4689) struct xdr_stream *xdr = &resp->xdr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4690) struct file *file;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4691) int starting_len = xdr->buf->len;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4692) int last_segment = xdr->buf->len;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4693) int segments = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4694) __be32 *p, tmp;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4695) bool is_data;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4696) loff_t pos;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4697) u32 eof;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4698)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4699) if (nfserr)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4700) return nfserr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4701) file = read->rd_nf->nf_file;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4702)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4703) /* eof flag, segment count */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4704) p = xdr_reserve_space(xdr, 4 + 4);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4705) if (!p)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4706) return nfserr_resource;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4707) xdr_commit_encode(xdr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4708)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4709) maxcount = svc_max_payload(resp->rqstp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4710) maxcount = min_t(unsigned long, maxcount,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4711) (xdr->buf->buflen - xdr->buf->len));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4712) maxcount = min_t(unsigned long, maxcount, read->rd_length);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4713) count = maxcount;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4714)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4715) eof = read->rd_offset >= i_size_read(file_inode(file));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4716) if (eof)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4717) goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4718)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4719) pos = vfs_llseek(file, read->rd_offset, SEEK_HOLE);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4720) is_data = pos > read->rd_offset;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4721)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4722) while (count > 0 && !eof) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4723) maxcount = count;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4724) if (is_data)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4725) nfserr = nfsd4_encode_read_plus_data(resp, read, &maxcount, &eof,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4726) segments == 0 ? &pos : NULL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4727) else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4728) nfserr = nfsd4_encode_read_plus_hole(resp, read, &maxcount, &eof);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4729) if (nfserr)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4730) goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4731) count -= maxcount;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4732) read->rd_offset += maxcount;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4733) is_data = !is_data;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4734) last_segment = xdr->buf->len;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4735) segments++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4736) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4737)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4738) out:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4739) if (nfserr && segments == 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4740) xdr_truncate_encode(xdr, starting_len);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4741) else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4742) if (nfserr) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4743) xdr_truncate_encode(xdr, last_segment);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4744) nfserr = nfs_ok;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4745) eof = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4746) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4747) tmp = htonl(eof);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4748) write_bytes_to_xdr_buf(xdr->buf, starting_len, &tmp, 4);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4749) tmp = htonl(segments);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4750) write_bytes_to_xdr_buf(xdr->buf, starting_len + 4, &tmp, 4);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4751) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4752)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4753) return nfserr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4754) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4755)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4756) static __be32
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4757) nfsd4_encode_copy_notify(struct nfsd4_compoundres *resp, __be32 nfserr,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4758) struct nfsd4_copy_notify *cn)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4759) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4760) struct xdr_stream *xdr = &resp->xdr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4761) __be32 *p;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4762)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4763) if (nfserr)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4764) return nfserr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4765)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4766) /* 8 sec, 4 nsec */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4767) p = xdr_reserve_space(xdr, 12);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4768) if (!p)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4769) return nfserr_resource;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4770)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4771) /* cnr_lease_time */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4772) p = xdr_encode_hyper(p, cn->cpn_sec);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4773) *p++ = cpu_to_be32(cn->cpn_nsec);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4774)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4775) /* cnr_stateid */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4776) nfserr = nfsd4_encode_stateid(xdr, &cn->cpn_cnr_stateid);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4777) if (nfserr)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4778) return nfserr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4779)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4780) /* cnr_src.nl_nsvr */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4781) p = xdr_reserve_space(xdr, 4);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4782) if (!p)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4783) return nfserr_resource;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4784)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4785) *p++ = cpu_to_be32(1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4786)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4787) return nfsd42_encode_nl4_server(resp, &cn->cpn_src);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4788) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4789)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4790) static __be32
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4791) nfsd4_encode_seek(struct nfsd4_compoundres *resp, __be32 nfserr,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4792) struct nfsd4_seek *seek)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4793) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4794) __be32 *p;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4795)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4796) p = xdr_reserve_space(&resp->xdr, 4 + 8);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4797) *p++ = cpu_to_be32(seek->seek_eof);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4798) p = xdr_encode_hyper(p, seek->seek_pos);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4799)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4800) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4801) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4802)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4803) static __be32
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4804) nfsd4_encode_noop(struct nfsd4_compoundres *resp, __be32 nfserr, void *p)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4805) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4806) return nfserr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4807) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4808)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4809) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4810) * Encode kmalloc-ed buffer in to XDR stream.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4811) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4812) static __be32
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4813) nfsd4_vbuf_to_stream(struct xdr_stream *xdr, char *buf, u32 buflen)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4814) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4815) u32 cplen;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4816) __be32 *p;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4817)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4818) cplen = min_t(unsigned long, buflen,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4819) ((void *)xdr->end - (void *)xdr->p));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4820) p = xdr_reserve_space(xdr, cplen);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4821) if (!p)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4822) return nfserr_resource;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4823)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4824) memcpy(p, buf, cplen);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4825) buf += cplen;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4826) buflen -= cplen;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4827)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4828) while (buflen) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4829) cplen = min_t(u32, buflen, PAGE_SIZE);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4830) p = xdr_reserve_space(xdr, cplen);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4831) if (!p)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4832) return nfserr_resource;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4833)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4834) memcpy(p, buf, cplen);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4835)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4836) if (cplen < PAGE_SIZE) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4837) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4838) * We're done, with a length that wasn't page
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4839) * aligned, so possibly not word aligned. Pad
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4840) * any trailing bytes with 0.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4841) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4842) xdr_encode_opaque_fixed(p, NULL, cplen);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4843) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4844) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4845)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4846) buflen -= PAGE_SIZE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4847) buf += PAGE_SIZE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4848) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4849)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4850) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4851) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4852)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4853) static __be32
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4854) nfsd4_encode_getxattr(struct nfsd4_compoundres *resp, __be32 nfserr,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4855) struct nfsd4_getxattr *getxattr)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4856) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4857) struct xdr_stream *xdr = &resp->xdr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4858) __be32 *p, err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4859)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4860) p = xdr_reserve_space(xdr, 4);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4861) if (!p)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4862) return nfserr_resource;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4863)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4864) *p = cpu_to_be32(getxattr->getxa_len);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4865)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4866) if (getxattr->getxa_len == 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4867) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4868)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4869) err = nfsd4_vbuf_to_stream(xdr, getxattr->getxa_buf,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4870) getxattr->getxa_len);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4871)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4872) kvfree(getxattr->getxa_buf);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4873)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4874) return err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4875) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4876)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4877) static __be32
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4878) nfsd4_encode_setxattr(struct nfsd4_compoundres *resp, __be32 nfserr,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4879) struct nfsd4_setxattr *setxattr)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4880) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4881) struct xdr_stream *xdr = &resp->xdr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4882) __be32 *p;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4883)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4884) p = xdr_reserve_space(xdr, 20);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4885) if (!p)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4886) return nfserr_resource;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4887)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4888) encode_cinfo(p, &setxattr->setxa_cinfo);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4889)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4890) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4891) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4892)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4893) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4894) * See if there are cookie values that can be rejected outright.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4895) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4896) static __be32
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4897) nfsd4_listxattr_validate_cookie(struct nfsd4_listxattrs *listxattrs,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4898) u32 *offsetp)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4899) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4900) u64 cookie = listxattrs->lsxa_cookie;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4901)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4902) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4903) * If the cookie is larger than the maximum number we can fit
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4904) * in either the buffer we just got back from vfs_listxattr, or,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4905) * XDR-encoded, in the return buffer, it's invalid.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4906) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4907) if (cookie > (listxattrs->lsxa_len) / (XATTR_USER_PREFIX_LEN + 2))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4908) return nfserr_badcookie;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4909)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4910) if (cookie > (listxattrs->lsxa_maxcount /
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4911) (XDR_QUADLEN(XATTR_USER_PREFIX_LEN + 2) + 4)))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4912) return nfserr_badcookie;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4913)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4914) *offsetp = (u32)cookie;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4915) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4916) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4917)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4918) static __be32
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4919) nfsd4_encode_listxattrs(struct nfsd4_compoundres *resp, __be32 nfserr,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4920) struct nfsd4_listxattrs *listxattrs)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4921) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4922) struct xdr_stream *xdr = &resp->xdr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4923) u32 cookie_offset, count_offset, eof;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4924) u32 left, xdrleft, slen, count;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4925) u32 xdrlen, offset;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4926) u64 cookie;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4927) char *sp;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4928) __be32 status, tmp;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4929) __be32 *p;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4930) u32 nuser;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4931)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4932) eof = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4933)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4934) status = nfsd4_listxattr_validate_cookie(listxattrs, &offset);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4935) if (status)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4936) goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4937)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4938) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4939) * Reserve space for the cookie and the name array count. Record
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4940) * the offsets to save them later.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4941) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4942) cookie_offset = xdr->buf->len;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4943) count_offset = cookie_offset + 8;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4944) p = xdr_reserve_space(xdr, 12);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4945) if (!p) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4946) status = nfserr_resource;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4947) goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4948) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4949)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4950) count = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4951) left = listxattrs->lsxa_len;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4952) sp = listxattrs->lsxa_buf;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4953) nuser = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4954)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4955) xdrleft = listxattrs->lsxa_maxcount;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4956)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4957) while (left > 0 && xdrleft > 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4958) slen = strlen(sp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4959)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4960) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4961) * Check if this is a "user." attribute, skip it if not.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4962) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4963) if (strncmp(sp, XATTR_USER_PREFIX, XATTR_USER_PREFIX_LEN))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4964) goto contloop;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4965)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4966) slen -= XATTR_USER_PREFIX_LEN;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4967) xdrlen = 4 + ((slen + 3) & ~3);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4968) if (xdrlen > xdrleft) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4969) if (count == 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4970) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4971) * Can't even fit the first attribute name.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4972) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4973) status = nfserr_toosmall;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4974) goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4975) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4976) eof = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4977) goto wreof;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4978) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4979)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4980) left -= XATTR_USER_PREFIX_LEN;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4981) sp += XATTR_USER_PREFIX_LEN;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4982) if (nuser++ < offset)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4983) goto contloop;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4984)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4985)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4986) p = xdr_reserve_space(xdr, xdrlen);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4987) if (!p) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4988) status = nfserr_resource;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4989) goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4990) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4991)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4992) xdr_encode_opaque(p, sp, slen);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4993)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4994) xdrleft -= xdrlen;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4995) count++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4996) contloop:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4997) sp += slen + 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4998) left -= slen + 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4999) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5000)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5001) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5002) * If there were user attributes to copy, but we didn't copy
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5003) * any, the offset was too large (e.g. the cookie was invalid).
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5004) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5005) if (nuser > 0 && count == 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5006) status = nfserr_badcookie;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5007) goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5008) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5009)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5010) wreof:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5011) p = xdr_reserve_space(xdr, 4);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5012) if (!p) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5013) status = nfserr_resource;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5014) goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5015) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5016) *p = cpu_to_be32(eof);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5017)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5018) cookie = offset + count;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5019)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5020) write_bytes_to_xdr_buf(xdr->buf, cookie_offset, &cookie, 8);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5021) tmp = cpu_to_be32(count);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5022) write_bytes_to_xdr_buf(xdr->buf, count_offset, &tmp, 4);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5023) out:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5024) if (listxattrs->lsxa_len)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5025) kvfree(listxattrs->lsxa_buf);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5026) return status;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5027) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5028)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5029) static __be32
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5030) nfsd4_encode_removexattr(struct nfsd4_compoundres *resp, __be32 nfserr,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5031) struct nfsd4_removexattr *removexattr)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5032) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5033) struct xdr_stream *xdr = &resp->xdr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5034) __be32 *p;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5035)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5036) p = xdr_reserve_space(xdr, 20);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5037) if (!p)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5038) return nfserr_resource;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5039)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5040) p = encode_cinfo(p, &removexattr->rmxa_cinfo);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5041) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5042) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5043)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5044) typedef __be32(* nfsd4_enc)(struct nfsd4_compoundres *, __be32, void *);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5045)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5046) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5047) * Note: nfsd4_enc_ops vector is shared for v4.0 and v4.1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5048) * since we don't need to filter out obsolete ops as this is
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5049) * done in the decoding phase.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5050) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5051) static const nfsd4_enc nfsd4_enc_ops[] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5052) [OP_ACCESS] = (nfsd4_enc)nfsd4_encode_access,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5053) [OP_CLOSE] = (nfsd4_enc)nfsd4_encode_close,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5054) [OP_COMMIT] = (nfsd4_enc)nfsd4_encode_commit,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5055) [OP_CREATE] = (nfsd4_enc)nfsd4_encode_create,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5056) [OP_DELEGPURGE] = (nfsd4_enc)nfsd4_encode_noop,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5057) [OP_DELEGRETURN] = (nfsd4_enc)nfsd4_encode_noop,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5058) [OP_GETATTR] = (nfsd4_enc)nfsd4_encode_getattr,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5059) [OP_GETFH] = (nfsd4_enc)nfsd4_encode_getfh,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5060) [OP_LINK] = (nfsd4_enc)nfsd4_encode_link,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5061) [OP_LOCK] = (nfsd4_enc)nfsd4_encode_lock,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5062) [OP_LOCKT] = (nfsd4_enc)nfsd4_encode_lockt,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5063) [OP_LOCKU] = (nfsd4_enc)nfsd4_encode_locku,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5064) [OP_LOOKUP] = (nfsd4_enc)nfsd4_encode_noop,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5065) [OP_LOOKUPP] = (nfsd4_enc)nfsd4_encode_noop,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5066) [OP_NVERIFY] = (nfsd4_enc)nfsd4_encode_noop,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5067) [OP_OPEN] = (nfsd4_enc)nfsd4_encode_open,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5068) [OP_OPENATTR] = (nfsd4_enc)nfsd4_encode_noop,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5069) [OP_OPEN_CONFIRM] = (nfsd4_enc)nfsd4_encode_open_confirm,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5070) [OP_OPEN_DOWNGRADE] = (nfsd4_enc)nfsd4_encode_open_downgrade,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5071) [OP_PUTFH] = (nfsd4_enc)nfsd4_encode_noop,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5072) [OP_PUTPUBFH] = (nfsd4_enc)nfsd4_encode_noop,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5073) [OP_PUTROOTFH] = (nfsd4_enc)nfsd4_encode_noop,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5074) [OP_READ] = (nfsd4_enc)nfsd4_encode_read,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5075) [OP_READDIR] = (nfsd4_enc)nfsd4_encode_readdir,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5076) [OP_READLINK] = (nfsd4_enc)nfsd4_encode_readlink,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5077) [OP_REMOVE] = (nfsd4_enc)nfsd4_encode_remove,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5078) [OP_RENAME] = (nfsd4_enc)nfsd4_encode_rename,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5079) [OP_RENEW] = (nfsd4_enc)nfsd4_encode_noop,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5080) [OP_RESTOREFH] = (nfsd4_enc)nfsd4_encode_noop,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5081) [OP_SAVEFH] = (nfsd4_enc)nfsd4_encode_noop,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5082) [OP_SECINFO] = (nfsd4_enc)nfsd4_encode_secinfo,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5083) [OP_SETATTR] = (nfsd4_enc)nfsd4_encode_setattr,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5084) [OP_SETCLIENTID] = (nfsd4_enc)nfsd4_encode_setclientid,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5085) [OP_SETCLIENTID_CONFIRM] = (nfsd4_enc)nfsd4_encode_noop,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5086) [OP_VERIFY] = (nfsd4_enc)nfsd4_encode_noop,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5087) [OP_WRITE] = (nfsd4_enc)nfsd4_encode_write,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5088) [OP_RELEASE_LOCKOWNER] = (nfsd4_enc)nfsd4_encode_noop,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5089)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5090) /* NFSv4.1 operations */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5091) [OP_BACKCHANNEL_CTL] = (nfsd4_enc)nfsd4_encode_noop,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5092) [OP_BIND_CONN_TO_SESSION] = (nfsd4_enc)nfsd4_encode_bind_conn_to_session,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5093) [OP_EXCHANGE_ID] = (nfsd4_enc)nfsd4_encode_exchange_id,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5094) [OP_CREATE_SESSION] = (nfsd4_enc)nfsd4_encode_create_session,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5095) [OP_DESTROY_SESSION] = (nfsd4_enc)nfsd4_encode_noop,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5096) [OP_FREE_STATEID] = (nfsd4_enc)nfsd4_encode_noop,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5097) [OP_GET_DIR_DELEGATION] = (nfsd4_enc)nfsd4_encode_noop,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5098) #ifdef CONFIG_NFSD_PNFS
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5099) [OP_GETDEVICEINFO] = (nfsd4_enc)nfsd4_encode_getdeviceinfo,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5100) [OP_GETDEVICELIST] = (nfsd4_enc)nfsd4_encode_noop,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5101) [OP_LAYOUTCOMMIT] = (nfsd4_enc)nfsd4_encode_layoutcommit,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5102) [OP_LAYOUTGET] = (nfsd4_enc)nfsd4_encode_layoutget,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5103) [OP_LAYOUTRETURN] = (nfsd4_enc)nfsd4_encode_layoutreturn,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5104) #else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5105) [OP_GETDEVICEINFO] = (nfsd4_enc)nfsd4_encode_noop,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5106) [OP_GETDEVICELIST] = (nfsd4_enc)nfsd4_encode_noop,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5107) [OP_LAYOUTCOMMIT] = (nfsd4_enc)nfsd4_encode_noop,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5108) [OP_LAYOUTGET] = (nfsd4_enc)nfsd4_encode_noop,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5109) [OP_LAYOUTRETURN] = (nfsd4_enc)nfsd4_encode_noop,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5110) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5111) [OP_SECINFO_NO_NAME] = (nfsd4_enc)nfsd4_encode_secinfo_no_name,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5112) [OP_SEQUENCE] = (nfsd4_enc)nfsd4_encode_sequence,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5113) [OP_SET_SSV] = (nfsd4_enc)nfsd4_encode_noop,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5114) [OP_TEST_STATEID] = (nfsd4_enc)nfsd4_encode_test_stateid,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5115) [OP_WANT_DELEGATION] = (nfsd4_enc)nfsd4_encode_noop,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5116) [OP_DESTROY_CLIENTID] = (nfsd4_enc)nfsd4_encode_noop,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5117) [OP_RECLAIM_COMPLETE] = (nfsd4_enc)nfsd4_encode_noop,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5118)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5119) /* NFSv4.2 operations */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5120) [OP_ALLOCATE] = (nfsd4_enc)nfsd4_encode_noop,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5121) [OP_COPY] = (nfsd4_enc)nfsd4_encode_copy,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5122) [OP_COPY_NOTIFY] = (nfsd4_enc)nfsd4_encode_copy_notify,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5123) [OP_DEALLOCATE] = (nfsd4_enc)nfsd4_encode_noop,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5124) [OP_IO_ADVISE] = (nfsd4_enc)nfsd4_encode_noop,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5125) [OP_LAYOUTERROR] = (nfsd4_enc)nfsd4_encode_noop,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5126) [OP_LAYOUTSTATS] = (nfsd4_enc)nfsd4_encode_noop,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5127) [OP_OFFLOAD_CANCEL] = (nfsd4_enc)nfsd4_encode_noop,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5128) [OP_OFFLOAD_STATUS] = (nfsd4_enc)nfsd4_encode_offload_status,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5129) [OP_READ_PLUS] = (nfsd4_enc)nfsd4_encode_read_plus,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5130) [OP_SEEK] = (nfsd4_enc)nfsd4_encode_seek,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5131) [OP_WRITE_SAME] = (nfsd4_enc)nfsd4_encode_noop,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5132) [OP_CLONE] = (nfsd4_enc)nfsd4_encode_noop,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5133)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5134) /* RFC 8276 extended atributes operations */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5135) [OP_GETXATTR] = (nfsd4_enc)nfsd4_encode_getxattr,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5136) [OP_SETXATTR] = (nfsd4_enc)nfsd4_encode_setxattr,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5137) [OP_LISTXATTRS] = (nfsd4_enc)nfsd4_encode_listxattrs,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5138) [OP_REMOVEXATTR] = (nfsd4_enc)nfsd4_encode_removexattr,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5139) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5140)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5141) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5142) * Calculate whether we still have space to encode repsize bytes.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5143) * There are two considerations:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5144) * - For NFS versions >=4.1, the size of the reply must stay within
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5145) * session limits
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5146) * - For all NFS versions, we must stay within limited preallocated
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5147) * buffer space.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5148) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5149) * This is called before the operation is processed, so can only provide
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5150) * an upper estimate. For some nonidempotent operations (such as
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5151) * getattr), it's not necessarily a problem if that estimate is wrong,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5152) * as we can fail it after processing without significant side effects.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5153) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5154) __be32 nfsd4_check_resp_size(struct nfsd4_compoundres *resp, u32 respsize)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5155) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5156) struct xdr_buf *buf = &resp->rqstp->rq_res;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5157) struct nfsd4_slot *slot = resp->cstate.slot;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5158)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5159) if (buf->len + respsize <= buf->buflen)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5160) return nfs_ok;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5161) if (!nfsd4_has_session(&resp->cstate))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5162) return nfserr_resource;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5163) if (slot->sl_flags & NFSD4_SLOT_CACHETHIS) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5164) WARN_ON_ONCE(1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5165) return nfserr_rep_too_big_to_cache;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5166) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5167) return nfserr_rep_too_big;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5168) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5169)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5170) void
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5171) nfsd4_encode_operation(struct nfsd4_compoundres *resp, struct nfsd4_op *op)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5172) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5173) struct xdr_stream *xdr = &resp->xdr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5174) struct nfs4_stateowner *so = resp->cstate.replay_owner;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5175) struct svc_rqst *rqstp = resp->rqstp;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5176) const struct nfsd4_operation *opdesc = op->opdesc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5177) int post_err_offset;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5178) nfsd4_enc encoder;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5179) __be32 *p;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5180)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5181) p = xdr_reserve_space(xdr, 8);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5182) if (!p) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5183) WARN_ON_ONCE(1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5184) return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5185) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5186) *p++ = cpu_to_be32(op->opnum);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5187) post_err_offset = xdr->buf->len;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5188)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5189) if (op->opnum == OP_ILLEGAL)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5190) goto status;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5191) if (op->status && opdesc &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5192) !(opdesc->op_flags & OP_NONTRIVIAL_ERROR_ENCODE))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5193) goto status;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5194) BUG_ON(op->opnum < 0 || op->opnum >= ARRAY_SIZE(nfsd4_enc_ops) ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5195) !nfsd4_enc_ops[op->opnum]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5196) encoder = nfsd4_enc_ops[op->opnum];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5197) op->status = encoder(resp, op->status, &op->u);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5198) if (opdesc && opdesc->op_release)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5199) opdesc->op_release(&op->u);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5200) xdr_commit_encode(xdr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5201)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5202) /* nfsd4_check_resp_size guarantees enough room for error status */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5203) if (!op->status) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5204) int space_needed = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5205) if (!nfsd4_last_compound_op(rqstp))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5206) space_needed = COMPOUND_ERR_SLACK_SPACE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5207) op->status = nfsd4_check_resp_size(resp, space_needed);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5208) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5209) if (op->status == nfserr_resource && nfsd4_has_session(&resp->cstate)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5210) struct nfsd4_slot *slot = resp->cstate.slot;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5211)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5212) if (slot->sl_flags & NFSD4_SLOT_CACHETHIS)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5213) op->status = nfserr_rep_too_big_to_cache;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5214) else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5215) op->status = nfserr_rep_too_big;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5216) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5217) if (op->status == nfserr_resource ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5218) op->status == nfserr_rep_too_big ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5219) op->status == nfserr_rep_too_big_to_cache) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5220) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5221) * The operation may have already been encoded or
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5222) * partially encoded. No op returns anything additional
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5223) * in the case of one of these three errors, so we can
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5224) * just truncate back to after the status. But it's a
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5225) * bug if we had to do this on a non-idempotent op:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5226) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5227) warn_on_nonidempotent_op(op);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5228) xdr_truncate_encode(xdr, post_err_offset);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5229) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5230) if (so) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5231) int len = xdr->buf->len - post_err_offset;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5232)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5233) so->so_replay.rp_status = op->status;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5234) so->so_replay.rp_buflen = len;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5235) read_bytes_from_xdr_buf(xdr->buf, post_err_offset,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5236) so->so_replay.rp_buf, len);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5237) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5238) status:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5239) /* Note that op->status is already in network byte order: */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5240) write_bytes_to_xdr_buf(xdr->buf, post_err_offset - 4, &op->status, 4);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5241) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5242)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5243) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5244) * Encode the reply stored in the stateowner reply cache
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5245) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5246) * XDR note: do not encode rp->rp_buflen: the buffer contains the
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5247) * previously sent already encoded operation.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5248) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5249) void
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5250) nfsd4_encode_replay(struct xdr_stream *xdr, struct nfsd4_op *op)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5251) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5252) __be32 *p;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5253) struct nfs4_replay *rp = op->replay;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5254)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5255) p = xdr_reserve_space(xdr, 8 + rp->rp_buflen);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5256) if (!p) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5257) WARN_ON_ONCE(1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5258) return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5259) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5260) *p++ = cpu_to_be32(op->opnum);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5261) *p++ = rp->rp_status; /* already xdr'ed */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5262)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5263) p = xdr_encode_opaque_fixed(p, rp->rp_buf, rp->rp_buflen);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5264) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5265)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5266) int
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5267) nfs4svc_encode_voidres(struct svc_rqst *rqstp, __be32 *p)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5268) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5269) return xdr_ressize_check(rqstp, p);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5270) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5271)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5272) void nfsd4_release_compoundargs(struct svc_rqst *rqstp)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5273) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5274) struct nfsd4_compoundargs *args = rqstp->rq_argp;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5275)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5276) if (args->ops != args->iops) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5277) kfree(args->ops);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5278) args->ops = args->iops;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5279) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5280) kfree(args->tmpp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5281) args->tmpp = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5282) while (args->to_free) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5283) struct svcxdr_tmpbuf *tb = args->to_free;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5284) args->to_free = tb->next;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5285) kfree(tb);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5286) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5287) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5288)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5289) int
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5290) nfs4svc_decode_voidarg(struct svc_rqst *rqstp, __be32 *p)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5291) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5292) return 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5293) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5294)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5295) int
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5296) nfs4svc_decode_compoundargs(struct svc_rqst *rqstp, __be32 *p)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5297) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5298) struct nfsd4_compoundargs *args = rqstp->rq_argp;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5299)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5300) if (rqstp->rq_arg.head[0].iov_len % 4) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5301) /* client is nuts */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5302) dprintk("%s: compound not properly padded! (peeraddr=%pISc xid=0x%x)",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5303) __func__, svc_addr(rqstp), be32_to_cpu(rqstp->rq_xid));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5304) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5305) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5306) args->p = p;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5307) args->end = rqstp->rq_arg.head[0].iov_base + rqstp->rq_arg.head[0].iov_len;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5308) args->pagelist = rqstp->rq_arg.pages;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5309) args->pagelen = rqstp->rq_arg.page_len;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5310) args->tail = false;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5311) args->tmpp = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5312) args->to_free = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5313) args->ops = args->iops;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5314) args->rqstp = rqstp;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5315)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5316) return !nfsd4_decode_compound(args);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5317) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5318)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5319) int
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5320) nfs4svc_encode_compoundres(struct svc_rqst *rqstp, __be32 *p)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5321) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5322) struct nfsd4_compoundres *resp = rqstp->rq_resp;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5323) struct xdr_buf *buf = resp->xdr.buf;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5324)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5325) WARN_ON_ONCE(buf->len != buf->head[0].iov_len + buf->page_len +
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5326) buf->tail[0].iov_len);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5327)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5328) *p = resp->cstate.status;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5329)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5330) rqstp->rq_next_page = resp->xdr.page_ptr + 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5331)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5332) p = resp->tagp;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5333) *p++ = htonl(resp->taglen);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5334) memcpy(p, resp->tag, resp->taglen);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5335) p += XDR_QUADLEN(resp->taglen);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5336) *p++ = htonl(resp->opcnt);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5337)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5338) nfsd4_sequence_done(resp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5339) return 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5340) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5341)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5342) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5343) * Local variables:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5344) * c-basic-offset: 8
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5345) * End:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5346) */