Skip to content

Commit c5c707f

Browse files
author
Christoph Hellwig
committed
nfsd: implement pNFS layout recalls
Add support to issue layout recalls to clients. For now we only support full-file recalls to get a simple and stable implementation. This allows to embedd a nfsd4_callback structure in the layout_state and thus avoid any memory allocations under spinlocks during a recall. For normal use cases that do not intent to share a single file between multiple clients this implementation is fully sufficient. To ensure layouts are recalled on local filesystem access each layout state registers a new FL_LAYOUT lease with the kernel file locking code, which filesystems that support pNFS exports that require recalls need to break on conflicting access patterns. The XDR code is based on the old pNFS server implementation by Andy Adamson, Benny Halevy, Boaz Harrosh, Dean Hildebrand, Fred Isaman, Marc Eshel, Mike Sager and Ricardo Labiaga. Signed-off-by: Christoph Hellwig <[email protected]>
1 parent 9cf514c commit c5c707f

File tree

6 files changed

+330
-1
lines changed

6 files changed

+330
-1
lines changed

fs/nfsd/nfs4callback.c

Lines changed: 99 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -546,6 +546,102 @@ static int nfs4_xdr_dec_cb_recall(struct rpc_rqst *rqstp,
546546
return status;
547547
}
548548

549+
#ifdef CONFIG_NFSD_PNFS
550+
/*
551+
* CB_LAYOUTRECALL4args
552+
*
553+
* struct layoutrecall_file4 {
554+
* nfs_fh4 lor_fh;
555+
* offset4 lor_offset;
556+
* length4 lor_length;
557+
* stateid4 lor_stateid;
558+
* };
559+
*
560+
* union layoutrecall4 switch(layoutrecall_type4 lor_recalltype) {
561+
* case LAYOUTRECALL4_FILE:
562+
* layoutrecall_file4 lor_layout;
563+
* case LAYOUTRECALL4_FSID:
564+
* fsid4 lor_fsid;
565+
* case LAYOUTRECALL4_ALL:
566+
* void;
567+
* };
568+
*
569+
* struct CB_LAYOUTRECALL4args {
570+
* layouttype4 clora_type;
571+
* layoutiomode4 clora_iomode;
572+
* bool clora_changed;
573+
* layoutrecall4 clora_recall;
574+
* };
575+
*/
576+
static void encode_cb_layout4args(struct xdr_stream *xdr,
577+
const struct nfs4_layout_stateid *ls,
578+
struct nfs4_cb_compound_hdr *hdr)
579+
{
580+
__be32 *p;
581+
582+
BUG_ON(hdr->minorversion == 0);
583+
584+
p = xdr_reserve_space(xdr, 5 * 4);
585+
*p++ = cpu_to_be32(OP_CB_LAYOUTRECALL);
586+
*p++ = cpu_to_be32(ls->ls_layout_type);
587+
*p++ = cpu_to_be32(IOMODE_ANY);
588+
*p++ = cpu_to_be32(1);
589+
*p = cpu_to_be32(RETURN_FILE);
590+
591+
encode_nfs_fh4(xdr, &ls->ls_stid.sc_file->fi_fhandle);
592+
593+
p = xdr_reserve_space(xdr, 2 * 8);
594+
p = xdr_encode_hyper(p, 0);
595+
xdr_encode_hyper(p, NFS4_MAX_UINT64);
596+
597+
encode_stateid4(xdr, &ls->ls_recall_sid);
598+
599+
hdr->nops++;
600+
}
601+
602+
static void nfs4_xdr_enc_cb_layout(struct rpc_rqst *req,
603+
struct xdr_stream *xdr,
604+
const struct nfsd4_callback *cb)
605+
{
606+
const struct nfs4_layout_stateid *ls =
607+
container_of(cb, struct nfs4_layout_stateid, ls_recall);
608+
struct nfs4_cb_compound_hdr hdr = {
609+
.ident = 0,
610+
.minorversion = cb->cb_minorversion,
611+
};
612+
613+
encode_cb_compound4args(xdr, &hdr);
614+
encode_cb_sequence4args(xdr, cb, &hdr);
615+
encode_cb_layout4args(xdr, ls, &hdr);
616+
encode_cb_nops(&hdr);
617+
}
618+
619+
static int nfs4_xdr_dec_cb_layout(struct rpc_rqst *rqstp,
620+
struct xdr_stream *xdr,
621+
struct nfsd4_callback *cb)
622+
{
623+
struct nfs4_cb_compound_hdr hdr;
624+
enum nfsstat4 nfserr;
625+
int status;
626+
627+
status = decode_cb_compound4res(xdr, &hdr);
628+
if (unlikely(status))
629+
goto out;
630+
if (cb) {
631+
status = decode_cb_sequence4res(xdr, cb);
632+
if (unlikely(status))
633+
goto out;
634+
}
635+
status = decode_cb_op_status(xdr, OP_CB_LAYOUTRECALL, &nfserr);
636+
if (unlikely(status))
637+
goto out;
638+
if (unlikely(nfserr != NFS4_OK))
639+
status = nfs_cb_stat_to_errno(nfserr);
640+
out:
641+
return status;
642+
}
643+
#endif /* CONFIG_NFSD_PNFS */
644+
549645
/*
550646
* RPC procedure tables
551647
*/
@@ -563,6 +659,9 @@ static int nfs4_xdr_dec_cb_recall(struct rpc_rqst *rqstp,
563659
static struct rpc_procinfo nfs4_cb_procedures[] = {
564660
PROC(CB_NULL, NULL, cb_null, cb_null),
565661
PROC(CB_RECALL, COMPOUND, cb_recall, cb_recall),
662+
#ifdef CONFIG_NFSD_PNFS
663+
PROC(CB_LAYOUT, COMPOUND, cb_layout, cb_layout),
664+
#endif
566665
};
567666

568667
static struct rpc_version nfs_cb_version4 = {

0 commit comments

Comments
 (0)