forked from torvalds/linux
-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Merge tag 'nfsd-4.8' of git://linux-nfs.org/~bfields/linux
Pull nfsd updates from Bruce Fields: "Highlights: - Trond made a change to the server's tcp logic that allows a fast client to better take advantage of high bandwidth networks, but may increase the risk that a single client could starve other clients; a new sunrpc.svc_rpc_per_connection_limit parameter should help mitigate this in the (hopefully unlikely) event this becomes a problem in practice. - Tom Haynes added a minimal flex-layout pnfs server, which is of no use in production for now--don't build it unless you're doing client testing or further server development" * tag 'nfsd-4.8' of git://linux-nfs.org/~bfields/linux: (32 commits) nfsd: remove some dead code in nfsd_create_locked() nfsd: drop unnecessary MAY_EXEC check from create nfsd: clean up bad-type check in nfsd_create_locked nfsd: remove unnecessary positive-dentry check nfsd: reorganize nfsd_create nfsd: check d_can_lookup in fh_verify of directories nfsd: remove redundant zero-length check from create nfsd: Make creates return EEXIST instead of EACCES SUNRPC: Detect immediate closure of accepted sockets SUNRPC: accept() may return sockets that are still in SYN_RECV nfsd: allow nfsd to advertise multiple layout types nfsd: Close race between nfsd4_release_lockowner and nfsd4_lock nfsd/blocklayout: Make sure calculate signature/designator length aligned xfs: abstract block export operations from nfsd layouts SUNRPC: Remove unused callback xpo_adjust_wspace() SUNRPC: Change TCP socket space reservation SUNRPC: Add a server side per-connection limit SUNRPC: Micro optimisation for svc_data_ready SUNRPC: Call the default socket callbacks instead of open coding SUNRPC: lock the socket while detaching it ...
- Loading branch information
Showing
37 changed files
with
784 additions
and
335 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,133 @@ | ||
/* | ||
* Copyright (c) 2016 Tom Haynes <loghyr@primarydata.com> | ||
* | ||
* The following implements a super-simple flex-file server | ||
* where the NFSv4.1 mds is also the ds. And the storage is | ||
* the same. I.e., writing to the mds via a NFSv4.1 WRITE | ||
* goes to the same location as the NFSv3 WRITE. | ||
*/ | ||
#include <linux/slab.h> | ||
|
||
#include <linux/nfsd/debug.h> | ||
|
||
#include <linux/sunrpc/addr.h> | ||
|
||
#include "flexfilelayoutxdr.h" | ||
#include "pnfs.h" | ||
|
||
#define NFSDDBG_FACILITY NFSDDBG_PNFS | ||
|
||
static __be32 | ||
nfsd4_ff_proc_layoutget(struct inode *inode, const struct svc_fh *fhp, | ||
struct nfsd4_layoutget *args) | ||
{ | ||
struct nfsd4_layout_seg *seg = &args->lg_seg; | ||
u32 device_generation = 0; | ||
int error; | ||
uid_t u; | ||
|
||
struct pnfs_ff_layout *fl; | ||
|
||
/* | ||
* The super simple flex file server has 1 mirror, 1 data server, | ||
* and 1 file handle. So instead of 4 allocs, do 1 for now. | ||
* Zero it out for the stateid - don't want junk in there! | ||
*/ | ||
error = -ENOMEM; | ||
fl = kzalloc(sizeof(*fl), GFP_KERNEL); | ||
if (!fl) | ||
goto out_error; | ||
args->lg_content = fl; | ||
|
||
/* | ||
* Avoid layout commit, try to force the I/O to the DS, | ||
* and for fun, cause all IOMODE_RW layout segments to | ||
* effectively be WRITE only. | ||
*/ | ||
fl->flags = FF_FLAGS_NO_LAYOUTCOMMIT | FF_FLAGS_NO_IO_THRU_MDS | | ||
FF_FLAGS_NO_READ_IO; | ||
|
||
/* Do not allow a IOMODE_READ segment to have write pemissions */ | ||
if (seg->iomode == IOMODE_READ) { | ||
u = from_kuid(&init_user_ns, inode->i_uid) + 1; | ||
fl->uid = make_kuid(&init_user_ns, u); | ||
} else | ||
fl->uid = inode->i_uid; | ||
fl->gid = inode->i_gid; | ||
|
||
error = nfsd4_set_deviceid(&fl->deviceid, fhp, device_generation); | ||
if (error) | ||
goto out_error; | ||
|
||
fl->fh.size = fhp->fh_handle.fh_size; | ||
memcpy(fl->fh.data, &fhp->fh_handle.fh_base, fl->fh.size); | ||
|
||
/* Give whole file layout segments */ | ||
seg->offset = 0; | ||
seg->length = NFS4_MAX_UINT64; | ||
|
||
dprintk("GET: 0x%llx:0x%llx %d\n", seg->offset, seg->length, | ||
seg->iomode); | ||
return 0; | ||
|
||
out_error: | ||
seg->length = 0; | ||
return nfserrno(error); | ||
} | ||
|
||
static __be32 | ||
nfsd4_ff_proc_getdeviceinfo(struct super_block *sb, struct svc_rqst *rqstp, | ||
struct nfs4_client *clp, struct nfsd4_getdeviceinfo *gdp) | ||
{ | ||
struct pnfs_ff_device_addr *da; | ||
|
||
u16 port; | ||
char addr[INET6_ADDRSTRLEN]; | ||
|
||
da = kzalloc(sizeof(struct pnfs_ff_device_addr), GFP_KERNEL); | ||
if (!da) | ||
return nfserrno(-ENOMEM); | ||
|
||
gdp->gd_device = da; | ||
|
||
da->version = 3; | ||
da->minor_version = 0; | ||
|
||
da->rsize = svc_max_payload(rqstp); | ||
da->wsize = da->rsize; | ||
|
||
rpc_ntop((struct sockaddr *)&rqstp->rq_daddr, | ||
addr, INET6_ADDRSTRLEN); | ||
if (rqstp->rq_daddr.ss_family == AF_INET) { | ||
struct sockaddr_in *sin; | ||
|
||
sin = (struct sockaddr_in *)&rqstp->rq_daddr; | ||
port = ntohs(sin->sin_port); | ||
snprintf(da->netaddr.netid, FF_NETID_LEN + 1, "tcp"); | ||
da->netaddr.netid_len = 3; | ||
} else { | ||
struct sockaddr_in6 *sin6; | ||
|
||
sin6 = (struct sockaddr_in6 *)&rqstp->rq_daddr; | ||
port = ntohs(sin6->sin6_port); | ||
snprintf(da->netaddr.netid, FF_NETID_LEN + 1, "tcp6"); | ||
da->netaddr.netid_len = 4; | ||
} | ||
|
||
da->netaddr.addr_len = | ||
snprintf(da->netaddr.addr, FF_ADDR_LEN + 1, | ||
"%s.%hhu.%hhu", addr, port >> 8, port & 0xff); | ||
|
||
da->tightly_coupled = false; | ||
|
||
return 0; | ||
} | ||
|
||
const struct nfsd4_layout_ops ff_layout_ops = { | ||
.notify_types = | ||
NOTIFY_DEVICEID4_DELETE | NOTIFY_DEVICEID4_CHANGE, | ||
.proc_getdeviceinfo = nfsd4_ff_proc_getdeviceinfo, | ||
.encode_getdeviceinfo = nfsd4_ff_encode_getdeviceinfo, | ||
.proc_layoutget = nfsd4_ff_proc_layoutget, | ||
.encode_layoutget = nfsd4_ff_encode_layoutget, | ||
}; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,115 @@ | ||
/* | ||
* Copyright (c) 2016 Tom Haynes <loghyr@primarydata.com> | ||
*/ | ||
#include <linux/sunrpc/svc.h> | ||
#include <linux/nfs4.h> | ||
|
||
#include "nfsd.h" | ||
#include "flexfilelayoutxdr.h" | ||
|
||
#define NFSDDBG_FACILITY NFSDDBG_PNFS | ||
|
||
struct ff_idmap { | ||
char buf[11]; | ||
int len; | ||
}; | ||
|
||
__be32 | ||
nfsd4_ff_encode_layoutget(struct xdr_stream *xdr, | ||
struct nfsd4_layoutget *lgp) | ||
{ | ||
struct pnfs_ff_layout *fl = lgp->lg_content; | ||
int len, mirror_len, ds_len, fh_len; | ||
__be32 *p; | ||
|
||
/* | ||
* Unlike nfsd4_encode_user, we know these will | ||
* always be stringified. | ||
*/ | ||
struct ff_idmap uid; | ||
struct ff_idmap gid; | ||
|
||
fh_len = 4 + fl->fh.size; | ||
|
||
uid.len = sprintf(uid.buf, "%u", from_kuid(&init_user_ns, fl->uid)); | ||
gid.len = sprintf(gid.buf, "%u", from_kgid(&init_user_ns, fl->gid)); | ||
|
||
/* 8 + len for recording the length, name, and padding */ | ||
ds_len = 20 + sizeof(stateid_opaque_t) + 4 + fh_len + | ||
8 + uid.len + 8 + gid.len; | ||
|
||
mirror_len = 4 + ds_len; | ||
|
||
/* The layout segment */ | ||
len = 20 + mirror_len; | ||
|
||
p = xdr_reserve_space(xdr, sizeof(__be32) + len); | ||
if (!p) | ||
return nfserr_toosmall; | ||
|
||
*p++ = cpu_to_be32(len); | ||
p = xdr_encode_hyper(p, 0); /* stripe unit of 1 */ | ||
|
||
*p++ = cpu_to_be32(1); /* single mirror */ | ||
*p++ = cpu_to_be32(1); /* single data server */ | ||
|
||
p = xdr_encode_opaque_fixed(p, &fl->deviceid, | ||
sizeof(struct nfsd4_deviceid)); | ||
|
||
*p++ = cpu_to_be32(1); /* efficiency */ | ||
|
||
*p++ = cpu_to_be32(fl->stateid.si_generation); | ||
p = xdr_encode_opaque_fixed(p, &fl->stateid.si_opaque, | ||
sizeof(stateid_opaque_t)); | ||
|
||
*p++ = cpu_to_be32(1); /* single file handle */ | ||
p = xdr_encode_opaque(p, fl->fh.data, fl->fh.size); | ||
|
||
p = xdr_encode_opaque(p, uid.buf, uid.len); | ||
p = xdr_encode_opaque(p, gid.buf, gid.len); | ||
|
||
*p++ = cpu_to_be32(fl->flags); | ||
*p++ = cpu_to_be32(0); /* No stats collect hint */ | ||
|
||
return 0; | ||
} | ||
|
||
__be32 | ||
nfsd4_ff_encode_getdeviceinfo(struct xdr_stream *xdr, | ||
struct nfsd4_getdeviceinfo *gdp) | ||
{ | ||
struct pnfs_ff_device_addr *da = gdp->gd_device; | ||
int len; | ||
int ver_len; | ||
int addr_len; | ||
__be32 *p; | ||
|
||
/* len + padding for two strings */ | ||
addr_len = 16 + da->netaddr.netid_len + da->netaddr.addr_len; | ||
ver_len = 20; | ||
|
||
len = 4 + ver_len + 4 + addr_len; | ||
|
||
p = xdr_reserve_space(xdr, len + sizeof(__be32)); | ||
if (!p) | ||
return nfserr_resource; | ||
|
||
/* | ||
* Fill in the overall length and number of volumes at the beginning | ||
* of the layout. | ||
*/ | ||
*p++ = cpu_to_be32(len); | ||
*p++ = cpu_to_be32(1); /* 1 netaddr */ | ||
p = xdr_encode_opaque(p, da->netaddr.netid, da->netaddr.netid_len); | ||
p = xdr_encode_opaque(p, da->netaddr.addr, da->netaddr.addr_len); | ||
|
||
*p++ = cpu_to_be32(1); /* 1 versions */ | ||
|
||
*p++ = cpu_to_be32(da->version); | ||
*p++ = cpu_to_be32(da->minor_version); | ||
*p++ = cpu_to_be32(da->rsize); | ||
*p++ = cpu_to_be32(da->wsize); | ||
*p++ = cpu_to_be32(da->tightly_coupled); | ||
|
||
return 0; | ||
} |
Oops, something went wrong.