cachepc-linux

Fork of AMDESE/linux with modifications for CachePC side-channel attack
git clone https://git.sinitax.com/sinitax/cachepc-linux
Log | Files | Refs | README | LICENSE | sfeed.txt

flexfilelayout.c (3493B)


      1// SPDX-License-Identifier: GPL-2.0
      2/*
      3 * Copyright (c) 2016 Tom Haynes <loghyr@primarydata.com>
      4 *
      5 * The following implements a super-simple flex-file server
      6 * where the NFSv4.1 mds is also the ds. And the storage is
      7 * the same. I.e., writing to the mds via a NFSv4.1 WRITE
      8 * goes to the same location as the NFSv3 WRITE.
      9 */
     10#include <linux/slab.h>
     11
     12#include <linux/nfsd/debug.h>
     13
     14#include <linux/sunrpc/addr.h>
     15
     16#include "flexfilelayoutxdr.h"
     17#include "pnfs.h"
     18
     19#define NFSDDBG_FACILITY	NFSDDBG_PNFS
     20
     21static __be32
     22nfsd4_ff_proc_layoutget(struct inode *inode, const struct svc_fh *fhp,
     23		struct nfsd4_layoutget *args)
     24{
     25	struct nfsd4_layout_seg *seg = &args->lg_seg;
     26	u32 device_generation = 0;
     27	int error;
     28	uid_t u;
     29
     30	struct pnfs_ff_layout *fl;
     31
     32	/*
     33	 * The super simple flex file server has 1 mirror, 1 data server,
     34	 * and 1 file handle. So instead of 4 allocs, do 1 for now.
     35	 * Zero it out for the stateid - don't want junk in there!
     36	 */
     37	error = -ENOMEM;
     38	fl = kzalloc(sizeof(*fl), GFP_KERNEL);
     39	if (!fl)
     40		goto out_error;
     41	args->lg_content = fl;
     42
     43	/*
     44	 * Avoid layout commit, try to force the I/O to the DS,
     45	 * and for fun, cause all IOMODE_RW layout segments to
     46	 * effectively be WRITE only.
     47	 */
     48	fl->flags = FF_FLAGS_NO_LAYOUTCOMMIT | FF_FLAGS_NO_IO_THRU_MDS |
     49		    FF_FLAGS_NO_READ_IO;
     50
     51	/* Do not allow a IOMODE_READ segment to have write pemissions */
     52	if (seg->iomode == IOMODE_READ) {
     53		u = from_kuid(&init_user_ns, inode->i_uid) + 1;
     54		fl->uid = make_kuid(&init_user_ns, u);
     55	} else
     56		fl->uid = inode->i_uid;
     57	fl->gid = inode->i_gid;
     58
     59	error = nfsd4_set_deviceid(&fl->deviceid, fhp, device_generation);
     60	if (error)
     61		goto out_error;
     62
     63	fl->fh.size = fhp->fh_handle.fh_size;
     64	memcpy(fl->fh.data, &fhp->fh_handle.fh_raw, fl->fh.size);
     65
     66	/* Give whole file layout segments */
     67	seg->offset = 0;
     68	seg->length = NFS4_MAX_UINT64;
     69
     70	dprintk("GET: 0x%llx:0x%llx %d\n", seg->offset, seg->length,
     71		seg->iomode);
     72	return 0;
     73
     74out_error:
     75	seg->length = 0;
     76	return nfserrno(error);
     77}
     78
     79static __be32
     80nfsd4_ff_proc_getdeviceinfo(struct super_block *sb, struct svc_rqst *rqstp,
     81		struct nfs4_client *clp, struct nfsd4_getdeviceinfo *gdp)
     82{
     83	struct pnfs_ff_device_addr *da;
     84
     85	u16 port;
     86	char addr[INET6_ADDRSTRLEN];
     87
     88	da = kzalloc(sizeof(struct pnfs_ff_device_addr), GFP_KERNEL);
     89	if (!da)
     90		return nfserrno(-ENOMEM);
     91
     92	gdp->gd_device = da;
     93
     94	da->version = 3;
     95	da->minor_version = 0;
     96
     97	da->rsize = svc_max_payload(rqstp);
     98	da->wsize = da->rsize;
     99
    100	rpc_ntop((struct sockaddr *)&rqstp->rq_daddr,
    101		 addr, INET6_ADDRSTRLEN);
    102	if (rqstp->rq_daddr.ss_family == AF_INET) {
    103		struct sockaddr_in *sin;
    104
    105		sin = (struct sockaddr_in *)&rqstp->rq_daddr;
    106		port = ntohs(sin->sin_port);
    107		snprintf(da->netaddr.netid, FF_NETID_LEN + 1, "tcp");
    108		da->netaddr.netid_len = 3;
    109	} else {
    110		struct sockaddr_in6 *sin6;
    111
    112		sin6 = (struct sockaddr_in6 *)&rqstp->rq_daddr;
    113		port = ntohs(sin6->sin6_port);
    114		snprintf(da->netaddr.netid, FF_NETID_LEN + 1, "tcp6");
    115		da->netaddr.netid_len = 4;
    116	}
    117
    118	da->netaddr.addr_len =
    119		snprintf(da->netaddr.addr, FF_ADDR_LEN + 1,
    120			 "%s.%d.%d", addr, port >> 8, port & 0xff);
    121
    122	da->tightly_coupled = false;
    123
    124	return 0;
    125}
    126
    127const struct nfsd4_layout_ops ff_layout_ops = {
    128	.notify_types		=
    129			NOTIFY_DEVICEID4_DELETE | NOTIFY_DEVICEID4_CHANGE,
    130	.disable_recalls	= true,
    131	.proc_getdeviceinfo	= nfsd4_ff_proc_getdeviceinfo,
    132	.encode_getdeviceinfo	= nfsd4_ff_encode_getdeviceinfo,
    133	.proc_layoutget		= nfsd4_ff_proc_layoutget,
    134	.encode_layoutget	= nfsd4_ff_encode_layoutget,
    135};