Back to home page

OSCL-LXR

 
 

    


0001 // SPDX-License-Identifier: GPL-2.0
0002 /*
0003  * Copyright (c) 2016 Tom Haynes <loghyr@primarydata.com>
0004  */
0005 #include <linux/sunrpc/svc.h>
0006 #include <linux/nfs4.h>
0007 
0008 #include "nfsd.h"
0009 #include "flexfilelayoutxdr.h"
0010 
0011 #define NFSDDBG_FACILITY    NFSDDBG_PNFS
0012 
0013 struct ff_idmap {
0014     char buf[11];
0015     int len;
0016 };
0017 
0018 __be32
0019 nfsd4_ff_encode_layoutget(struct xdr_stream *xdr,
0020         struct nfsd4_layoutget *lgp)
0021 {
0022     struct pnfs_ff_layout *fl = lgp->lg_content;
0023     int len, mirror_len, ds_len, fh_len;
0024     __be32 *p;
0025 
0026     /*
0027      * Unlike nfsd4_encode_user, we know these will
0028      * always be stringified.
0029      */
0030     struct ff_idmap uid;
0031     struct ff_idmap gid;
0032 
0033     fh_len = 4 + fl->fh.size;
0034 
0035     uid.len = sprintf(uid.buf, "%u", from_kuid(&init_user_ns, fl->uid));
0036     gid.len = sprintf(gid.buf, "%u", from_kgid(&init_user_ns, fl->gid));
0037 
0038     /* 8 + len for recording the length, name, and padding */
0039     ds_len = 20 + sizeof(stateid_opaque_t) + 4 + fh_len +
0040          8 + uid.len + 8 + gid.len;
0041 
0042     mirror_len = 4 + ds_len;
0043 
0044     /* The layout segment */
0045     len = 20 + mirror_len;
0046 
0047     p = xdr_reserve_space(xdr, sizeof(__be32) + len);
0048     if (!p)
0049         return nfserr_toosmall;
0050 
0051     *p++ = cpu_to_be32(len);
0052     p = xdr_encode_hyper(p, 0);     /* stripe unit of 1 */
0053 
0054     *p++ = cpu_to_be32(1);          /* single mirror */
0055     *p++ = cpu_to_be32(1);          /* single data server */
0056 
0057     p = xdr_encode_opaque_fixed(p, &fl->deviceid,
0058             sizeof(struct nfsd4_deviceid));
0059 
0060     *p++ = cpu_to_be32(1);          /* efficiency */
0061 
0062     *p++ = cpu_to_be32(fl->stateid.si_generation);
0063     p = xdr_encode_opaque_fixed(p, &fl->stateid.si_opaque,
0064                     sizeof(stateid_opaque_t));
0065 
0066     *p++ = cpu_to_be32(1);          /* single file handle */
0067     p = xdr_encode_opaque(p, fl->fh.data, fl->fh.size);
0068 
0069     p = xdr_encode_opaque(p, uid.buf, uid.len);
0070     p = xdr_encode_opaque(p, gid.buf, gid.len);
0071 
0072     *p++ = cpu_to_be32(fl->flags);
0073     *p++ = cpu_to_be32(0);          /* No stats collect hint */
0074 
0075     return 0;
0076 }
0077 
0078 __be32
0079 nfsd4_ff_encode_getdeviceinfo(struct xdr_stream *xdr,
0080         struct nfsd4_getdeviceinfo *gdp)
0081 {
0082     struct pnfs_ff_device_addr *da = gdp->gd_device;
0083     int len;
0084     int ver_len;
0085     int addr_len;
0086     __be32 *p;
0087 
0088     /* len + padding for two strings */
0089     addr_len = 16 + da->netaddr.netid_len + da->netaddr.addr_len;
0090     ver_len = 20;
0091 
0092     len = 4 + ver_len + 4 + addr_len;
0093 
0094     p = xdr_reserve_space(xdr, len + sizeof(__be32));
0095     if (!p)
0096         return nfserr_resource;
0097 
0098     /*
0099      * Fill in the overall length and number of volumes at the beginning
0100      * of the layout.
0101      */
0102     *p++ = cpu_to_be32(len);
0103     *p++ = cpu_to_be32(1);          /* 1 netaddr */
0104     p = xdr_encode_opaque(p, da->netaddr.netid, da->netaddr.netid_len);
0105     p = xdr_encode_opaque(p, da->netaddr.addr, da->netaddr.addr_len);
0106 
0107     *p++ = cpu_to_be32(1);          /* 1 versions */
0108 
0109     *p++ = cpu_to_be32(da->version);
0110     *p++ = cpu_to_be32(da->minor_version);
0111     *p++ = cpu_to_be32(da->rsize);
0112     *p++ = cpu_to_be32(da->wsize);
0113     *p++ = cpu_to_be32(da->tightly_coupled);
0114 
0115     return 0;
0116 }