Skip to content

Commit

Permalink
Merge git://git.linux-nfs.org/projects/trondmy/nfs-2.6
Browse files Browse the repository at this point in the history
* git://git.linux-nfs.org/projects/trondmy/nfs-2.6: (75 commits)
  NFS: Fix nfs_migrate_page()
  rpc: remove unneeded function parameter in gss_add_msg()
  nfs41: Invoke RECLAIM_COMPLETE on all new client ids
  SUNRPC: IS_ERR/PTR_ERR confusion
  NFSv41: Fix a potential state leakage when restarting nfs4_close_prepare
  nfs41: Handle NFSv4.1 session errors in the delegation recall code
  nfs41: Retry delegation return if it failed with session error
  nfs41: Handle session errors during delegation return
  nfs41: Mark stateids in need of reclaim if state manager gets stale clientid
  NFS: Fix up the declaration of nfs4_restart_rpc when NFSv4 not configured
  nfs41: Don't clear DRAINING flag on NFS4ERR_STALE_CLIENTID
  nfs41: nfs41_setup_state_renewal
  NFSv41: More cleanups
  NFSv41: Fix up some bugs in the NFS4CLNT_SESSION_DRAINING code
  NFSv41: Clean up slot table management
  NFSv41: Fix nfs4_proc_create_session
  nfs41: Invoke RECLAIM_COMPLETE
  nfs41: RECLAIM_COMPLETE functionality
  nfs41: RECLAIM_COMPLETE XDR functionality
  Cleanup some NFSv4 XDR decode comments
  ...
  • Loading branch information
Linus Torvalds committed Dec 14, 2009
2 parents d031655 + 52c9948 commit 3f86ce7
Show file tree
Hide file tree
Showing 30 changed files with 1,078 additions and 469 deletions.
13 changes: 1 addition & 12 deletions fs/nfs/callback.c
Original file line number Diff line number Diff line change
Expand Up @@ -78,11 +78,6 @@ nfs4_callback_svc(void *vrqstp)

set_freezable();

/*
* FIXME: do we really need to run this under the BKL? If so, please
* add a comment about what it's intended to protect.
*/
lock_kernel();
while (!kthread_should_stop()) {
/*
* Listen for a request on the socket
Expand All @@ -104,7 +99,6 @@ nfs4_callback_svc(void *vrqstp)
preverr = err;
svc_process(rqstp);
}
unlock_kernel();
return 0;
}

Expand Down Expand Up @@ -160,11 +154,6 @@ nfs41_callback_svc(void *vrqstp)

set_freezable();

/*
* FIXME: do we really need to run this under the BKL? If so, please
* add a comment about what it's intended to protect.
*/
lock_kernel();
while (!kthread_should_stop()) {
prepare_to_wait(&serv->sv_cb_waitq, &wq, TASK_INTERRUPTIBLE);
spin_lock_bh(&serv->sv_cb_lock);
Expand All @@ -183,7 +172,6 @@ nfs41_callback_svc(void *vrqstp)
}
finish_wait(&serv->sv_cb_waitq, &wq);
}
unlock_kernel();
return 0;
}

Expand Down Expand Up @@ -397,6 +385,7 @@ static int nfs_callback_authenticate(struct svc_rqst *rqstp)
*/
static struct svc_version *nfs4_callback_version[] = {
[1] = &nfs4_callback_version1,
[4] = &nfs4_callback_version4,
};

static struct svc_stat nfs4_callback_stats;
Expand Down
16 changes: 15 additions & 1 deletion fs/nfs/callback.h
Original file line number Diff line number Diff line change
Expand Up @@ -106,6 +106,19 @@ struct cb_sequenceres {
extern unsigned nfs4_callback_sequence(struct cb_sequenceargs *args,
struct cb_sequenceres *res);

extern int nfs41_validate_delegation_stateid(struct nfs_delegation *delegation,
const nfs4_stateid *stateid);

#define RCA4_TYPE_MASK_RDATA_DLG 0
#define RCA4_TYPE_MASK_WDATA_DLG 1

struct cb_recallanyargs {
struct sockaddr *craa_addr;
uint32_t craa_objs_to_keep;
uint32_t craa_type_mask;
};

extern unsigned nfs4_callback_recallany(struct cb_recallanyargs *args, void *dummy);
#endif /* CONFIG_NFS_V4_1 */

extern __be32 nfs4_callback_getattr(struct cb_getattrargs *args, struct cb_getattrres *res);
Expand All @@ -114,8 +127,9 @@ extern __be32 nfs4_callback_recall(struct cb_recallargs *args, void *dummy);
#ifdef CONFIG_NFS_V4
extern int nfs_callback_up(u32 minorversion, struct rpc_xprt *xprt);
extern void nfs_callback_down(int minorversion);
extern int nfs4_validate_delegation_stateid(struct nfs_delegation *delegation,
const nfs4_stateid *stateid);
#endif /* CONFIG_NFS_V4 */

/*
* nfs41: Callbacks are expected to not cause substantial latency,
* so we limit their concurrency to 1 by setting up the maximum number
Expand Down
64 changes: 63 additions & 1 deletion fs/nfs/callback_proc.c
Original file line number Diff line number Diff line change
Expand Up @@ -61,6 +61,16 @@ __be32 nfs4_callback_getattr(struct cb_getattrargs *args, struct cb_getattrres *
return res->status;
}

static int (*nfs_validate_delegation_stateid(struct nfs_client *clp))(struct nfs_delegation *, const nfs4_stateid *)
{
#if defined(CONFIG_NFS_V4_1)
if (clp->cl_minorversion > 0)
return nfs41_validate_delegation_stateid;
#endif
return nfs4_validate_delegation_stateid;
}


__be32 nfs4_callback_recall(struct cb_recallargs *args, void *dummy)
{
struct nfs_client *clp;
Expand All @@ -81,7 +91,8 @@ __be32 nfs4_callback_recall(struct cb_recallargs *args, void *dummy)
inode = nfs_delegation_find_inode(clp, &args->fh);
if (inode != NULL) {
/* Set up a helper thread to actually return the delegation */
switch(nfs_async_inode_return_delegation(inode, &args->stateid)) {
switch (nfs_async_inode_return_delegation(inode, &args->stateid,
nfs_validate_delegation_stateid(clp))) {
case 0:
res = 0;
break;
Expand All @@ -102,8 +113,31 @@ __be32 nfs4_callback_recall(struct cb_recallargs *args, void *dummy)
return res;
}

int nfs4_validate_delegation_stateid(struct nfs_delegation *delegation, const nfs4_stateid *stateid)
{
if (delegation == NULL || memcmp(delegation->stateid.data, stateid->data,
sizeof(delegation->stateid.data)) != 0)
return 0;
return 1;
}

#if defined(CONFIG_NFS_V4_1)

int nfs41_validate_delegation_stateid(struct nfs_delegation *delegation, const nfs4_stateid *stateid)
{
if (delegation == NULL)
return 0;

/* seqid is 4-bytes long */
if (((u32 *) &stateid->data)[0] != 0)
return 0;
if (memcmp(&delegation->stateid.data[4], &stateid->data[4],
sizeof(stateid->data)-4))
return 0;

return 1;
}

/*
* Validate the sequenceID sent by the server.
* Return success if the sequenceID is one more than what we last saw on
Expand Down Expand Up @@ -227,4 +261,32 @@ unsigned nfs4_callback_sequence(struct cb_sequenceargs *args,
return res->csr_status;
}

unsigned nfs4_callback_recallany(struct cb_recallanyargs *args, void *dummy)
{
struct nfs_client *clp;
int status;
fmode_t flags = 0;

status = htonl(NFS4ERR_OP_NOT_IN_SESSION);
clp = nfs_find_client(args->craa_addr, 4);
if (clp == NULL)
goto out;

dprintk("NFS: RECALL_ANY callback request from %s\n",
rpc_peeraddr2str(clp->cl_rpcclient, RPC_DISPLAY_ADDR));

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 (flags)
nfs_expire_all_delegation_types(clp, flags);
status = htonl(NFS4_OK);
out:
dprintk("%s: exit with status = %d\n", __func__, ntohl(status));
return status;
}
#endif /* CONFIG_NFS_V4_1 */
34 changes: 33 additions & 1 deletion fs/nfs/callback_xdr.c
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,7 @@
#if defined(CONFIG_NFS_V4_1)
#define CB_OP_SEQUENCE_RES_MAXSZ (CB_OP_HDR_RES_MAXSZ + \
4 + 1 + 3)
#define CB_OP_RECALLANY_RES_MAXSZ (CB_OP_HDR_RES_MAXSZ)
#endif /* CONFIG_NFS_V4_1 */

#define NFSDBG_FACILITY NFSDBG_CALLBACK
Expand Down Expand Up @@ -326,6 +327,25 @@ static unsigned decode_cb_sequence_args(struct svc_rqst *rqstp,
goto out;
}

static unsigned decode_recallany_args(struct svc_rqst *rqstp,
struct xdr_stream *xdr,
struct cb_recallanyargs *args)
{
uint32_t *p;

args->craa_addr = svc_addr(rqstp);
p = read_buf(xdr, 4);
if (unlikely(p == NULL))
return htonl(NFS4ERR_BADXDR);
args->craa_objs_to_keep = ntohl(*p++);
p = read_buf(xdr, 4);
if (unlikely(p == NULL))
return htonl(NFS4ERR_BADXDR);
args->craa_type_mask = ntohl(*p);

return 0;
}

#endif /* CONFIG_NFS_V4_1 */

static __be32 encode_string(struct xdr_stream *xdr, unsigned int len, const char *str)
Expand Down Expand Up @@ -533,14 +553,14 @@ preprocess_nfs41_op(int nop, unsigned int op_nr, struct callback_op **op)
case OP_CB_GETATTR:
case OP_CB_RECALL:
case OP_CB_SEQUENCE:
case OP_CB_RECALL_ANY:
*op = &callback_ops[op_nr];
break;

case OP_CB_LAYOUTRECALL:
case OP_CB_NOTIFY_DEVICEID:
case OP_CB_NOTIFY:
case OP_CB_PUSH_DELEG:
case OP_CB_RECALL_ANY:
case OP_CB_RECALLABLE_OBJ_AVAIL:
case OP_CB_RECALL_SLOT:
case OP_CB_WANTS_CANCELLED:
Expand Down Expand Up @@ -688,6 +708,11 @@ static struct callback_op callback_ops[] = {
.encode_res = (callback_encode_res_t)encode_cb_sequence_res,
.res_maxsize = CB_OP_SEQUENCE_RES_MAXSZ,
},
[OP_CB_RECALL_ANY] = {
.process_op = (callback_process_op_t)nfs4_callback_recallany,
.decode_args = (callback_decode_arg_t)decode_recallany_args,
.res_maxsize = CB_OP_RECALLANY_RES_MAXSZ,
},
#endif /* CONFIG_NFS_V4_1 */
};

Expand Down Expand Up @@ -718,3 +743,10 @@ struct svc_version nfs4_callback_version1 = {
.vs_dispatch = NULL,
};

struct svc_version nfs4_callback_version4 = {
.vs_vers = 4,
.vs_nproc = ARRAY_SIZE(nfs4_callback_procedures1),
.vs_proc = nfs4_callback_procedures1,
.vs_xdrsize = NFS4_CALLBACK_XDRSIZE,
.vs_dispatch = NULL,
};
14 changes: 12 additions & 2 deletions fs/nfs/client.c
Original file line number Diff line number Diff line change
Expand Up @@ -1260,10 +1260,20 @@ static int nfs4_set_client(struct nfs_server *server,
static void nfs4_session_set_rwsize(struct nfs_server *server)
{
#ifdef CONFIG_NFS_V4_1
struct nfs4_session *sess;
u32 server_resp_sz;
u32 server_rqst_sz;

if (!nfs4_has_session(server->nfs_client))
return;
server->rsize = server->nfs_client->cl_session->fc_attrs.max_resp_sz;
server->wsize = server->nfs_client->cl_session->fc_attrs.max_rqst_sz;
sess = server->nfs_client->cl_session;
server_resp_sz = sess->fc_attrs.max_resp_sz - nfs41_maxread_overhead;
server_rqst_sz = sess->fc_attrs.max_rqst_sz - nfs41_maxwrite_overhead;

if (server->rsize > server_resp_sz)
server->rsize = server_resp_sz;
if (server->wsize > server_rqst_sz)
server->wsize = server_rqst_sz;
#endif /* CONFIG_NFS_V4_1 */
}

Expand Down
Loading

0 comments on commit 3f86ce7

Please sign in to comment.