From 96ae942bbbc8da127db12716959781eb50c3ab18 Mon Sep 17 00:00:00 2001 From: Alexandros Batsakis Date: Thu, 6 Jan 2011 11:36:31 +0000 Subject: [PATCH] --- yaml --- r: 229237 b: refs/heads/master c: 36840370845629e6cb4324d1dd4aff6778670503 h: refs/heads/master i: 229235: 62719186c4037ebd3e99cd48f197b4105031ebb9 v: v3 --- [refs] | 2 +- trunk/fs/nfs/callback.h | 8 ++++++++ trunk/fs/nfs/callback_proc.c | 29 ++++++++++++++++++++++++++--- 3 files changed, 35 insertions(+), 4 deletions(-) diff --git a/[refs] b/[refs] index a08a9d53f6a5..30d52b21900a 100644 --- a/[refs] +++ b/[refs] @@ -1,2 +1,2 @@ --- -refs/heads/master: 43f1b3da8b35d706d6c47880fc211d2519b4a587 +refs/heads/master: 36840370845629e6cb4324d1dd4aff6778670503 diff --git a/trunk/fs/nfs/callback.h b/trunk/fs/nfs/callback.h index f6768ac09190..d3b44f9bd747 100644 --- a/trunk/fs/nfs/callback.h +++ b/trunk/fs/nfs/callback.h @@ -119,6 +119,14 @@ extern int nfs41_validate_delegation_stateid(struct nfs_delegation *delegation, #define RCA4_TYPE_MASK_RDATA_DLG 0 #define RCA4_TYPE_MASK_WDATA_DLG 1 +#define RCA4_TYPE_MASK_DIR_DLG 2 +#define RCA4_TYPE_MASK_FILE_LAYOUT 3 +#define RCA4_TYPE_MASK_BLK_LAYOUT 4 +#define RCA4_TYPE_MASK_OBJ_LAYOUT_MIN 8 +#define RCA4_TYPE_MASK_OBJ_LAYOUT_MAX 9 +#define RCA4_TYPE_MASK_OTHER_LAYOUT_MIN 12 +#define RCA4_TYPE_MASK_OTHER_LAYOUT_MAX 15 +#define RCA4_TYPE_MASK_ALL 0xf31f struct cb_recallanyargs { struct sockaddr *craa_addr; diff --git a/trunk/fs/nfs/callback_proc.c b/trunk/fs/nfs/callback_proc.c index 6619c05b55a0..4bb91cb2620d 100644 --- a/trunk/fs/nfs/callback_proc.c +++ b/trunk/fs/nfs/callback_proc.c @@ -230,6 +230,17 @@ __be32 nfs4_callback_layoutrecall(struct cb_layoutrecallargs *args, return cpu_to_be32(res); } +static void pnfs_recall_all_layouts(struct nfs_client *clp) +{ + struct cb_layoutrecallargs args; + + /* Pretend we got a CB_LAYOUTRECALL(ALL) */ + memset(&args, 0, sizeof(args)); + args.cbl_recall_type = RETURN_ALL; + /* FIXME we ignore errors, what should we do? */ + do_callback_layoutrecall(clp, &args); +} + int nfs41_validate_delegation_stateid(struct nfs_delegation *delegation, const nfs4_stateid *stateid) { if (delegation == NULL) @@ -421,29 +432,41 @@ __be32 nfs4_callback_sequence(struct cb_sequenceargs *args, return status; } +static bool +validate_bitmap_values(unsigned long mask) +{ + return (mask & ~RCA4_TYPE_MASK_ALL) == 0; +} + __be32 nfs4_callback_recallany(struct cb_recallanyargs *args, void *dummy, struct cb_process_state *cps) { __be32 status; fmode_t flags = 0; - status = htonl(NFS4ERR_OP_NOT_IN_SESSION); + status = cpu_to_be32(NFS4ERR_OP_NOT_IN_SESSION); if (!cps->clp) /* set in cb_sequence */ goto out; dprintk("NFS: RECALL_ANY callback request from %s\n", rpc_peeraddr2str(cps->clp->cl_rpcclient, RPC_DISPLAY_ADDR)); + status = cpu_to_be32(NFS4ERR_INVAL); + if (!validate_bitmap_values(args->craa_type_mask)) + goto out; + + status = cpu_to_be32(NFS4_OK); if (test_bit(RCA4_TYPE_MASK_RDATA_DLG, (const unsigned long *) &args->craa_type_mask)) flags = FMODE_READ; if (test_bit(RCA4_TYPE_MASK_WDATA_DLG, (const unsigned long *) &args->craa_type_mask)) flags |= FMODE_WRITE; - + if (test_bit(RCA4_TYPE_MASK_FILE_LAYOUT, (const unsigned long *) + &args->craa_type_mask)) + pnfs_recall_all_layouts(cps->clp); if (flags) nfs_expire_all_delegation_types(cps->clp, flags); - status = htonl(NFS4_OK); out: dprintk("%s: exit with status = %d\n", __func__, ntohl(status)); return status;