📄 nfs4xdr.c
字号:
/* * fs/nfs/nfs4xdr.c * * Client-side XDR for NFSv4. * * Copyright (c) 2002 The Regents of the University of Michigan. * All rights reserved. * * Kendrick Smith <kmsmith@umich.edu> * Andy Adamson <andros@umich.edu> * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * * 1. Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * 2. Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. * 3. Neither the name of the University nor the names of its * contributors may be used to endorse or promote products derived * from this software without specific prior written permission. * * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE * DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */#include <linux/param.h>#include <linux/time.h>#include <linux/mm.h>#include <linux/slab.h>#include <linux/utsname.h>#include <linux/errno.h>#include <linux/string.h>#include <linux/in.h>#include <linux/pagemap.h>#include <linux/proc_fs.h>#include <linux/kdev_t.h>#include <linux/sunrpc/clnt.h>#include <linux/nfs.h>#include <linux/nfs4.h>#include <linux/nfs_fs.h>#include <linux/nfs_idmap.h>#define NFSDBG_FACILITY NFSDBG_XDR/* Mapping from NFS error code to "errno" error code. */#define errno_NFSERR_IO EIOstatic int nfs_stat_to_errno(int);/* NFSv4 COMPOUND tags are only wanted for debugging purposes */#ifdef DEBUG#define NFS4_MAXTAGLEN 20#else#define NFS4_MAXTAGLEN 0#endif/* lock,open owner id: * we currently use size 1 (u32) out of (NFS4_OPAQUE_LIMIT >> 2) */#define owner_id_maxsz (1 + 1)#define compound_encode_hdr_maxsz (3 + (NFS4_MAXTAGLEN >> 2))#define compound_decode_hdr_maxsz (3 + (NFS4_MAXTAGLEN >> 2))#define op_encode_hdr_maxsz (1)#define op_decode_hdr_maxsz (2)#define encode_putfh_maxsz (op_encode_hdr_maxsz + 1 + \ (NFS4_FHSIZE >> 2))#define decode_putfh_maxsz (op_decode_hdr_maxsz)#define encode_putrootfh_maxsz (op_encode_hdr_maxsz)#define decode_putrootfh_maxsz (op_decode_hdr_maxsz)#define encode_getfh_maxsz (op_encode_hdr_maxsz)#define decode_getfh_maxsz (op_decode_hdr_maxsz + 1 + \ ((3+NFS4_FHSIZE) >> 2))#define encode_getattr_maxsz (op_encode_hdr_maxsz + 3)#define nfs4_name_maxsz (1 + ((3 + NFS4_MAXNAMLEN) >> 2))#define nfs4_path_maxsz (1 + ((3 + NFS4_MAXPATHLEN) >> 2))#define nfs4_fattr_bitmap_maxsz (36 + 2 * nfs4_name_maxsz)#define decode_getattr_maxsz (op_decode_hdr_maxsz + 3 + \ nfs4_fattr_bitmap_maxsz)#define encode_savefh_maxsz (op_encode_hdr_maxsz)#define decode_savefh_maxsz (op_decode_hdr_maxsz)#define encode_fsinfo_maxsz (op_encode_hdr_maxsz + 2)#define decode_fsinfo_maxsz (op_decode_hdr_maxsz + 11)#define encode_renew_maxsz (op_encode_hdr_maxsz + 3)#define decode_renew_maxsz (op_decode_hdr_maxsz)#define encode_setclientid_maxsz \ (op_encode_hdr_maxsz + \ 4 /*server->ip_addr*/ + \ 1 /*Netid*/ + \ 6 /*uaddr*/ + \ 6 + (NFS4_VERIFIER_SIZE >> 2))#define decode_setclientid_maxsz \ (op_decode_hdr_maxsz + \ 2 + \ 1024) /* large value for CLID_INUSE */#define encode_setclientid_confirm_maxsz \ (op_encode_hdr_maxsz + \ 3 + (NFS4_VERIFIER_SIZE >> 2))#define decode_setclientid_confirm_maxsz \ (op_decode_hdr_maxsz)#define encode_lookup_maxsz (op_encode_hdr_maxsz + \ 1 + ((3 + NFS4_FHSIZE) >> 2))#define encode_remove_maxsz (op_encode_hdr_maxsz + \ nfs4_name_maxsz)#define encode_rename_maxsz (op_encode_hdr_maxsz + \ 2 * nfs4_name_maxsz)#define decode_rename_maxsz (op_decode_hdr_maxsz + 5 + 5)#define encode_link_maxsz (op_encode_hdr_maxsz + \ nfs4_name_maxsz)#define decode_link_maxsz (op_decode_hdr_maxsz + 5)#define encode_symlink_maxsz (op_encode_hdr_maxsz + \ 1 + nfs4_name_maxsz + \ nfs4_path_maxsz + \ nfs4_fattr_bitmap_maxsz)#define decode_symlink_maxsz (op_decode_hdr_maxsz + 8)#define encode_create_maxsz (op_encode_hdr_maxsz + \ 2 + nfs4_name_maxsz + \ nfs4_fattr_bitmap_maxsz)#define decode_create_maxsz (op_decode_hdr_maxsz + 8)#define encode_delegreturn_maxsz (op_encode_hdr_maxsz + 4)#define decode_delegreturn_maxsz (op_decode_hdr_maxsz)#define NFS4_enc_compound_sz (1024) /* XXX: large enough? */#define NFS4_dec_compound_sz (1024) /* XXX: large enough? */#define NFS4_enc_read_sz (compound_encode_hdr_maxsz + \ encode_putfh_maxsz + \ op_encode_hdr_maxsz + 7)#define NFS4_dec_read_sz (compound_decode_hdr_maxsz + \ decode_putfh_maxsz + \ op_decode_hdr_maxsz + 2)#define NFS4_enc_readlink_sz (compound_encode_hdr_maxsz + \ encode_putfh_maxsz + \ op_encode_hdr_maxsz)#define NFS4_dec_readlink_sz (compound_decode_hdr_maxsz + \ decode_putfh_maxsz + \ op_decode_hdr_maxsz)#define NFS4_enc_readdir_sz (compound_encode_hdr_maxsz + \ encode_putfh_maxsz + \ op_encode_hdr_maxsz + 9)#define NFS4_dec_readdir_sz (compound_decode_hdr_maxsz + \ decode_putfh_maxsz + \ op_decode_hdr_maxsz + 2)#define NFS4_enc_write_sz (compound_encode_hdr_maxsz + \ encode_putfh_maxsz + \ op_encode_hdr_maxsz + 8)#define NFS4_dec_write_sz (compound_decode_hdr_maxsz + \ decode_putfh_maxsz + \ op_decode_hdr_maxsz + 4)#define NFS4_enc_commit_sz (compound_encode_hdr_maxsz + \ encode_putfh_maxsz + \ op_encode_hdr_maxsz + 3)#define NFS4_dec_commit_sz (compound_decode_hdr_maxsz + \ decode_putfh_maxsz + \ op_decode_hdr_maxsz + 2)#define NFS4_enc_open_sz (compound_encode_hdr_maxsz + \ encode_putfh_maxsz + \ op_encode_hdr_maxsz + \ 13 + 3 + 2 + 64 + \ encode_getattr_maxsz + \ encode_getfh_maxsz)#define NFS4_dec_open_sz (compound_decode_hdr_maxsz + \ decode_putfh_maxsz + \ op_decode_hdr_maxsz + 4 + 5 + 2 + 3 + \ decode_getattr_maxsz + \ decode_getfh_maxsz)#define NFS4_enc_open_confirm_sz \ (compound_encode_hdr_maxsz + \ encode_putfh_maxsz + \ op_encode_hdr_maxsz + 5)#define NFS4_dec_open_confirm_sz (compound_decode_hdr_maxsz + \ decode_putfh_maxsz + \ op_decode_hdr_maxsz + 4)#define NFS4_enc_open_noattr_sz (compound_encode_hdr_maxsz + \ encode_putfh_maxsz + \ op_encode_hdr_maxsz + \ 11)#define NFS4_dec_open_noattr_sz (compound_decode_hdr_maxsz + \ decode_putfh_maxsz + \ op_decode_hdr_maxsz + \ 4 + 5 + 2 + 3)#define NFS4_enc_open_downgrade_sz \ (compound_encode_hdr_maxsz + \ encode_putfh_maxsz + \ op_encode_hdr_maxsz + 7)#define NFS4_dec_open_downgrade_sz \ (compound_decode_hdr_maxsz + \ decode_putfh_maxsz + \ op_decode_hdr_maxsz + 4)#define NFS4_enc_close_sz (compound_encode_hdr_maxsz + \ encode_putfh_maxsz + \ op_encode_hdr_maxsz + 5)#define NFS4_dec_close_sz (compound_decode_hdr_maxsz + \ decode_putfh_maxsz + \ op_decode_hdr_maxsz + 4)#define NFS4_enc_setattr_sz (compound_encode_hdr_maxsz + \ encode_putfh_maxsz + \ op_encode_hdr_maxsz + 4 + \ nfs4_fattr_bitmap_maxsz + \ encode_getattr_maxsz)#define NFS4_dec_setattr_sz (compound_decode_hdr_maxsz + \ decode_putfh_maxsz + \ op_decode_hdr_maxsz + 3)#define NFS4_enc_fsinfo_sz (compound_encode_hdr_maxsz + \ encode_putfh_maxsz + \ encode_fsinfo_maxsz)#define NFS4_dec_fsinfo_sz (compound_decode_hdr_maxsz + \ decode_putfh_maxsz + \ decode_fsinfo_maxsz)#define NFS4_enc_renew_sz (compound_encode_hdr_maxsz + \ encode_renew_maxsz)#define NFS4_dec_renew_sz (compound_decode_hdr_maxsz + \ decode_renew_maxsz)#define NFS4_enc_setclientid_sz (compound_encode_hdr_maxsz + \ encode_setclientid_maxsz)#define NFS4_dec_setclientid_sz (compound_decode_hdr_maxsz + \ decode_setclientid_maxsz)#define NFS4_enc_setclientid_confirm_sz \ (compound_encode_hdr_maxsz + \ encode_setclientid_confirm_maxsz + \ encode_putrootfh_maxsz + \ encode_fsinfo_maxsz)#define NFS4_dec_setclientid_confirm_sz \ (compound_decode_hdr_maxsz + \ decode_setclientid_confirm_maxsz + \ decode_putrootfh_maxsz + \ decode_fsinfo_maxsz)#define NFS4_enc_lock_sz (compound_encode_hdr_maxsz + \ encode_putfh_maxsz + \ encode_getattr_maxsz + \ op_encode_hdr_maxsz + \ 1 + 1 + 2 + 2 + \ 1 + 4 + 1 + 2 + \ owner_id_maxsz)#define NFS4_dec_lock_sz (compound_decode_hdr_maxsz + \ decode_putfh_maxsz + \ decode_getattr_maxsz + \ op_decode_hdr_maxsz + \ 2 + 2 + 1 + 2 + \ owner_id_maxsz)#define NFS4_enc_lockt_sz (compound_encode_hdr_maxsz + \ encode_putfh_maxsz + \ encode_getattr_maxsz + \ op_encode_hdr_maxsz + \ 1 + 2 + 2 + 2 + \ owner_id_maxsz)#define NFS4_dec_lockt_sz (NFS4_dec_lock_sz)#define NFS4_enc_locku_sz (compound_encode_hdr_maxsz + \ encode_putfh_maxsz + \ encode_getattr_maxsz + \ op_encode_hdr_maxsz + \ 1 + 1 + 4 + 2 + 2)#define NFS4_dec_locku_sz (compound_decode_hdr_maxsz + \ decode_putfh_maxsz + \ decode_getattr_maxsz + \ op_decode_hdr_maxsz + 4)#define NFS4_enc_access_sz (compound_encode_hdr_maxsz + \ encode_putfh_maxsz + \ op_encode_hdr_maxsz + 1)#define NFS4_dec_access_sz (compound_decode_hdr_maxsz + \ decode_putfh_maxsz + \ op_decode_hdr_maxsz + 2)#define NFS4_enc_getattr_sz (compound_encode_hdr_maxsz + \ encode_putfh_maxsz + \ encode_getattr_maxsz)#define NFS4_dec_getattr_sz (compound_decode_hdr_maxsz + \ decode_putfh_maxsz + \ decode_getattr_maxsz)#define NFS4_enc_lookup_sz (compound_encode_hdr_maxsz + \ encode_putfh_maxsz + \ encode_lookup_maxsz + \ encode_getattr_maxsz + \ encode_getfh_maxsz)#define NFS4_dec_lookup_sz (compound_decode_hdr_maxsz + \ decode_putfh_maxsz + \ op_decode_hdr_maxsz + \ decode_getattr_maxsz + \ decode_getfh_maxsz)#define NFS4_enc_lookup_root_sz (compound_encode_hdr_maxsz + \ encode_putrootfh_maxsz + \ encode_getattr_maxsz + \ encode_getfh_maxsz)#define NFS4_dec_lookup_root_sz (compound_decode_hdr_maxsz + \ decode_putrootfh_maxsz + \ decode_getattr_maxsz + \ decode_getfh_maxsz)#define NFS4_enc_remove_sz (compound_encode_hdr_maxsz + \ encode_putfh_maxsz + \ encode_remove_maxsz)#define NFS4_dec_remove_sz (compound_decode_hdr_maxsz + \ decode_putfh_maxsz + \ op_decode_hdr_maxsz + 5)#define NFS4_enc_rename_sz (compound_encode_hdr_maxsz + \ encode_putfh_maxsz + \ encode_savefh_maxsz + \ encode_putfh_maxsz + \ encode_rename_maxsz)#define NFS4_dec_rename_sz (compound_decode_hdr_maxsz + \ decode_putfh_maxsz + \ decode_savefh_maxsz + \ decode_putfh_maxsz + \ decode_rename_maxsz)#define NFS4_enc_link_sz (compound_encode_hdr_maxsz + \ encode_putfh_maxsz + \ encode_savefh_maxsz + \ encode_putfh_maxsz + \ encode_link_maxsz)#define NFS4_dec_link_sz (compound_decode_hdr_maxsz + \ decode_putfh_maxsz + \ decode_savefh_maxsz + \ decode_putfh_maxsz + \ decode_link_maxsz)#define NFS4_enc_symlink_sz (compound_encode_hdr_maxsz + \ encode_putfh_maxsz + \ encode_symlink_maxsz + \ encode_getattr_maxsz + \ encode_getfh_maxsz)#define NFS4_dec_symlink_sz (compound_decode_hdr_maxsz + \ decode_putfh_maxsz + \ decode_symlink_maxsz + \ decode_getattr_maxsz + \ decode_getfh_maxsz)#define NFS4_enc_create_sz (compound_encode_hdr_maxsz + \ encode_putfh_maxsz + \ encode_create_maxsz + \ encode_getattr_maxsz + \ encode_getfh_maxsz)#define NFS4_dec_create_sz (compound_decode_hdr_maxsz + \ decode_putfh_maxsz + \ decode_create_maxsz + \ decode_getattr_maxsz + \ decode_getfh_maxsz)#define NFS4_enc_pathconf_sz (compound_encode_hdr_maxsz + \ encode_putfh_maxsz + \ encode_getattr_maxsz)#define NFS4_dec_pathconf_sz (compound_decode_hdr_maxsz + \ decode_putfh_maxsz + \ decode_getattr_maxsz)#define NFS4_enc_statfs_sz (compound_encode_hdr_maxsz + \ encode_putfh_maxsz + \ encode_getattr_maxsz)#define NFS4_dec_statfs_sz (compound_decode_hdr_maxsz + \ decode_putfh_maxsz + \ op_decode_hdr_maxsz + 12)#define NFS4_enc_server_caps_sz (compound_encode_hdr_maxsz + \ encode_getattr_maxsz)#define NFS4_dec_server_caps_sz (compound_decode_hdr_maxsz + \ decode_getattr_maxsz)#define NFS4_enc_delegreturn_sz (compound_encode_hdr_maxsz + \ encode_putfh_maxsz + \ encode_delegreturn_maxsz)#define NFS4_dec_delegreturn_sz (compound_decode_hdr_maxsz + \ decode_delegreturn_maxsz)static struct { unsigned int mode; unsigned int nfs2type;} nfs_type2fmt[] = { { 0, NFNON }, { S_IFREG, NFREG }, { S_IFDIR, NFDIR }, { S_IFBLK, NFBLK }, { S_IFCHR, NFCHR }, { S_IFLNK, NFLNK }, { S_IFSOCK, NFSOCK }, { S_IFIFO, NFFIFO }, { 0, NFNON }, { 0, NFNON },};struct compound_hdr { int32_t status; uint32_t nops; uint32_t taglen; char * tag;};/* * START OF "GENERIC" ENCODE ROUTINES. * These may look a little ugly since they are imported from a "generic" * set of XDR encode/decode routines which are intended to be shared by * all of our NFSv4 implementations (OpenBSD, MacOS X...). * * If the pain of reading these is too great, it should be a straightforward * task to translate them into Linux-specific versions which are more * consistent with the style used in NFSv2/v3... */#define WRITE32(n) *p++ = htonl(n)#define WRITE64(n) do { \ *p++ = htonl((uint32_t)((n) >> 32)); \ *p++ = htonl((uint32_t)(n)); \} while (0)#define WRITEMEM(ptr,nbytes) do { \ p = xdr_encode_opaque_fixed(p, ptr, nbytes); \} while (0)#define RESERVE_SPACE(nbytes) do { \ p = xdr_reserve_space(xdr, nbytes); \ if (!p) printk("RESERVE_SPACE(%d) failed in function %s\n", (int) (nbytes), __FUNCTION__); \ BUG_ON(!p); \} while (0)static void encode_string(struct xdr_stream *xdr, unsigned int len, const char *str){ uint32_t *p; p = xdr_reserve_space(xdr, 4 + len); BUG_ON(p == NULL); xdr_encode_opaque(p, str, len);}static int encode_compound_hdr(struct xdr_stream *xdr, struct compound_hdr *hdr){ uint32_t *p; dprintk("encode_compound: tag=%.*s\n", (int)hdr->taglen, hdr->tag); BUG_ON(hdr->taglen > NFS4_MAXTAGLEN); RESERVE_SPACE(12+(XDR_QUADLEN(hdr->taglen)<<2)); WRITE32(hdr->taglen); WRITEMEM(hdr->tag, hdr->taglen); WRITE32(NFS4_MINOR_VERSION); WRITE32(hdr->nops); return 0;}static void encode_nfs4_verifier(struct xdr_stream *xdr, const nfs4_verifier *verf){ uint32_t *p; p = xdr_reserve_space(xdr, NFS4_VERIFIER_SIZE); BUG_ON(p == NULL); xdr_encode_opaque_fixed(p, verf->data, NFS4_VERIFIER_SIZE);}static int encode_attrs(struct xdr_stream *xdr, const struct iattr *iap, const struct nfs_server *server){ char owner_name[IDMAP_NAMESZ]; char owner_group[IDMAP_NAMESZ]; int owner_namelen = 0; int owner_grouplen = 0; uint32_t *p; uint32_t *q; int len; uint32_t bmval0 = 0; uint32_t bmval1 = 0; int status; /* * We reserve enough space to write the entire attribute buffer at once. * In the worst-case, this would be * 12(bitmap) + 4(attrlen) + 8(size) + 4(mode) + 4(atime) + 4(mtime) * = 36 bytes, plus any contribution from variable-length fields * such as owner/group/acl's. */ len = 16; /* Sigh */ if (iap->ia_valid & ATTR_SIZE) len += 8; if (iap->ia_valid & ATTR_MODE) len += 4; if (iap->ia_valid & ATTR_UID) { owner_namelen = nfs_map_uid_to_name(server->nfs4_state, iap->ia_uid, owner_name); if (owner_namelen < 0) { printk(KERN_WARNING "nfs: couldn't resolve uid %d to string\n", iap->ia_uid); /* XXX */ strcpy(owner_name, "nobody"); owner_namelen = sizeof("nobody") - 1; /* goto out; */ } len += 4 + (XDR_QUADLEN(owner_namelen) << 2); } if (iap->ia_valid & ATTR_GID) { owner_grouplen = nfs_map_gid_to_group(server->nfs4_state, iap->ia_gid, owner_group); if (owner_grouplen < 0) { printk(KERN_WARNING "nfs4: couldn't resolve gid %d to string\n", iap->ia_gid); strcpy(owner_group, "nobody"); owner_grouplen = sizeof("nobody") - 1; /* goto out; */ } len += 4 + (XDR_QUADLEN(owner_grouplen) << 2); } if (iap->ia_valid & ATTR_ATIME_SET) len += 16; else if (iap->ia_valid & ATTR_ATIME) len += 4; if (iap->ia_valid & ATTR_MTIME_SET) len += 16; else if (iap->ia_valid & ATTR_MTIME) len += 4; RESERVE_SPACE(len); /* * We write the bitmap length now, but leave the bitmap and the attribute * buffer length to be backfilled at the end of this routine. */ WRITE32(2); q = p; p += 3;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -