* [PATCH kNFSd 7 of 23] Get rid of the special delegation_stateid_t, use the existing stateid_t.
2004-12-17 5:23 [PATCH kNFSd 0 of 23] Introduction NeilBrown
` (3 preceding siblings ...)
2004-12-17 5:23 ` [PATCH kNFSd 4 of 23] Preparation for delegation: client callback probe NeilBrown
@ 2004-12-17 5:23 ` NeilBrown
2004-12-17 5:23 ` [PATCH kNFSd 3 of 23] Count the nfs4_client structure usage NeilBrown
` (17 subsequent siblings)
22 siblings, 0 replies; 29+ messages in thread
From: NeilBrown @ 2004-12-17 5:23 UTC (permalink / raw)
To: Andrew Morton; +Cc: nfs
Signed-off-by: Andy Adamson <andros@citi.umich.edu>
Signed-off-by: Neil Brown <neilb@cse.unsw.edu.au>
### Diffstat output
./fs/nfsd/nfs4xdr.c | 12 ++++++------
./include/linux/nfsd/xdr4.h | 16 +++-------------
2 files changed, 9 insertions(+), 19 deletions(-)
diff ./fs/nfsd/nfs4xdr.c~current~ ./fs/nfsd/nfs4xdr.c
--- ./fs/nfsd/nfs4xdr.c~current~ 2004-12-15 11:57:44.000000000 +1100
+++ ./fs/nfsd/nfs4xdr.c 2004-12-15 11:57:44.000000000 +1100
@@ -790,8 +790,8 @@ nfsd4_decode_open(struct nfsd4_compounda
READ32(open->op_delegate_type);
break;
case NFS4_OPEN_CLAIM_DELEGATE_CUR:
- READ_BUF(sizeof(delegation_stateid_t) + 4);
- COPYMEM(&open->op_delegate_stateid, sizeof(delegation_stateid_t));
+ READ_BUF(sizeof(stateid_t) + 4);
+ COPYMEM(&open->op_delegate_stateid, sizeof(stateid_t));
READ32(open->op_fname.len);
READ_BUF(open->op_fname.len);
SAVEMEM(open->op_fname.data, open->op_fname.len);
@@ -2072,8 +2072,8 @@ nfsd4_encode_open(struct nfsd4_compoundr
case NFS4_OPEN_DELEGATE_NONE:
break;
case NFS4_OPEN_DELEGATE_READ:
- RESERVE_SPACE(20 + sizeof(delegation_stateid_t));
- WRITEMEM(&open->op_delegate_stateid, sizeof(delegation_stateid_t));
+ RESERVE_SPACE(20 + sizeof(stateid_t));
+ WRITEMEM(&open->op_delegate_stateid, sizeof(stateid_t));
WRITE32(0);
/*
@@ -2086,8 +2086,8 @@ nfsd4_encode_open(struct nfsd4_compoundr
ADJUST_ARGS();
break;
case NFS4_OPEN_DELEGATE_WRITE:
- RESERVE_SPACE(32 + sizeof(delegation_stateid_t));
- WRITEMEM(&open->op_delegate_stateid, sizeof(delegation_stateid_t));
+ RESERVE_SPACE(32 + sizeof(stateid_t));
+ WRITEMEM(&open->op_delegate_stateid, sizeof(stateid_t));
WRITE32(0);
/*
diff ./include/linux/nfsd/xdr4.h~current~ ./include/linux/nfsd/xdr4.h
--- ./include/linux/nfsd/xdr4.h~current~ 2004-12-15 11:57:44.000000000 +1100
+++ ./include/linux/nfsd/xdr4.h 2004-12-15 11:57:44.000000000 +1100
@@ -44,16 +44,6 @@
#define NFSD4_MAX_TAGLEN 128
#define XDR_LEN(n) (((n) + 3) & ~3)
-typedef u32 delegation_zero_t;
-typedef u32 delegation_boot_t;
-typedef u64 delegation_id_t;
-
-typedef struct {
- delegation_zero_t ds_zero;
- delegation_boot_t ds_boot;
- delegation_id_t ds_id;
-} delegation_stateid_t;
-
struct nfsd4_change_info {
u32 atomic;
u32 before_ctime_sec;
@@ -202,13 +192,13 @@ struct nfsd4_open {
u32 op_claim_type; /* request */
struct xdr_netobj op_fname; /* request - everything but CLAIM_PREV */
u32 op_delegate_type; /* request - CLAIM_PREV only */
- delegation_stateid_t op_delegate_stateid; /* request - CLAIM_DELEGATE_CUR only */
+ stateid_t op_delegate_stateid; /* request - response */
u32 op_create; /* request */
u32 op_createmode; /* request */
u32 op_bmval[2]; /* request */
union { /* request */
- struct iattr iattr; /* UNCHECKED4,GUARDED4 */
- nfs4_verifier verf; /* EXCLUSIVE4 */
+ struct iattr iattr; /* UNCHECKED4,GUARDED4 */
+ nfs4_verifier verf; /* EXCLUSIVE4 */
} u;
clientid_t op_clientid; /* request */
struct xdr_netobj op_owner; /* request */
-------------------------------------------------------
SF email is sponsored by - The IT Product Guide
Read honest & candid reviews on hundreds of IT Products from real users.
Discover which products truly live up to the hype. Start reading now.
http://productguide.itmanagersjournal.com/
_______________________________________________
NFS maillist - NFS@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/nfs
^ permalink raw reply [flat|nested] 29+ messages in thread
* [PATCH kNFSd 0 of 23] Introduction
@ 2004-12-17 5:23 NeilBrown
2004-12-17 5:23 ` [PATCH kNFSd 5 of 23] Probe the callback path upon a successful setclientid_confirm NeilBrown
` (22 more replies)
0 siblings, 23 replies; 29+ messages in thread
From: NeilBrown @ 2004-12-17 5:23 UTC (permalink / raw)
To: Andrew Morton; +Cc: nfs
Following are 23 patches that provide "delegation" support in the
NFSv4 server.
"Delegation" is when the client opens a file and the server says "Ok,
that file is all yours for a while. No-one else will touch it without
me first telling you about it". This requires the server to be able to
make call-backs to the client to "reclaim" a delegation when someone
else wants access to the file.
These are certainly not needed for 2.6.10.
NeilBrown
-------------------------------------------------------
SF email is sponsored by - The IT Product Guide
Read honest & candid reviews on hundreds of IT Products from real users.
Discover which products truly live up to the hype. Start reading now.
http://productguide.itmanagersjournal.com/
_______________________________________________
NFS maillist - NFS@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/nfs
^ permalink raw reply [flat|nested] 29+ messages in thread
* [PATCH kNFSd 6 of 23] Check for existence of file_lock parameter inside of the kernel lock.
2004-12-17 5:23 [PATCH kNFSd 0 of 23] Introduction NeilBrown
2004-12-17 5:23 ` [PATCH kNFSd 5 of 23] Probe the callback path upon a successful setclientid_confirm NeilBrown
2004-12-17 5:23 ` [PATCH kNFSd 1 of 23] Move nfserr_openmode checking from nfsd_read/write into nfs4_preprocess_stateid_op() in preperation for delegation state NeilBrown
@ 2004-12-17 5:23 ` NeilBrown
2004-12-17 5:23 ` [PATCH kNFSd 4 of 23] Preparation for delegation: client callback probe NeilBrown
` (19 subsequent siblings)
22 siblings, 0 replies; 29+ messages in thread
From: NeilBrown @ 2004-12-17 5:23 UTC (permalink / raw)
To: Andrew Morton; +Cc: nfs
Signed-off-by: Andy Adamson <andros@citi.umich.edu>
Signed-off-by: Neil Brown <neilb@cse.unsw.edu.au>
### Diffstat output
./fs/locks.c | 8 +++-----
1 files changed, 3 insertions(+), 5 deletions(-)
diff ./fs/locks.c~current~ ./fs/locks.c
--- ./fs/locks.c~current~ 2004-12-15 11:57:12.000000000 +1100
+++ ./fs/locks.c 2004-12-15 11:57:12.000000000 +1100
@@ -1096,15 +1096,13 @@ static void time_out_leases(struct inode
*/
void remove_lease(struct file_lock *fl)
{
- if (!IS_LEASE(fl))
- return;
-
lock_kernel();
-
+ if (!fl || !IS_LEASE(fl))
+ goto out;
fl->fl_type = F_UNLCK | F_INPROGRESS;
fl->fl_break_time = jiffies - 10;
time_out_leases(fl->fl_file->f_dentry->d_inode);
-
+out:
unlock_kernel();
}
-------------------------------------------------------
SF email is sponsored by - The IT Product Guide
Read honest & candid reviews on hundreds of IT Products from real users.
Discover which products truly live up to the hype. Start reading now.
http://productguide.itmanagersjournal.com/
_______________________________________________
NFS maillist - NFS@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/nfs
^ permalink raw reply [flat|nested] 29+ messages in thread
* [PATCH kNFSd 3 of 23] Count the nfs4_client structure usage
2004-12-17 5:23 [PATCH kNFSd 0 of 23] Introduction NeilBrown
` (4 preceding siblings ...)
2004-12-17 5:23 ` [PATCH kNFSd 7 of 23] Get rid of the special delegation_stateid_t, use the existing stateid_t NeilBrown
@ 2004-12-17 5:23 ` NeilBrown
2004-12-17 5:23 ` [PATCH kNFSd 2 of 23] Check the callback netid in gen_callback NeilBrown
` (16 subsequent siblings)
22 siblings, 0 replies; 29+ messages in thread
From: NeilBrown @ 2004-12-17 5:23 UTC (permalink / raw)
To: Andrew Morton; +Cc: nfs
... to protect the null (probe) callback asynchronous rpc's reference.
Atomically inc and set the cb_set flag.
Signed-off-by: Andy Adamson <andros@citi.umich.edu>
Signed-off-by: Neil Brown <neilb@cse.unsw.edu.au>
### Diffstat output
./fs/nfsd/nfs4state.c | 14 ++++++++++++--
./include/linux/nfsd/state.h | 4 +++-
2 files changed, 15 insertions(+), 3 deletions(-)
diff ./fs/nfsd/nfs4state.c~current~ ./fs/nfsd/nfs4state.c
--- ./fs/nfsd/nfs4state.c~current~ 2004-12-15 11:46:29.000000000 +1100
+++ ./fs/nfsd/nfs4state.c 2004-12-15 11:49:34.000000000 +1100
@@ -213,12 +213,19 @@ free_client(struct nfs4_client *clp)
kfree(clp);
}
+void
+put_nfs4_client(struct nfs4_client *clp)
+{
+ if (atomic_dec_and_test(&clp->cl_count))
+ free_client(clp);
+}
+
static void
expire_client(struct nfs4_client *clp)
{
struct nfs4_stateowner *sop;
- dprintk("NFSD: expire_client\n");
+ dprintk("NFSD: expire_client cl_count %d\n",atomic_read(&clp->cl_count));
list_del(&clp->cl_idhash);
list_del(&clp->cl_strhash);
list_del(&clp->cl_lru);
@@ -226,7 +233,7 @@ expire_client(struct nfs4_client *clp)
sop = list_entry(clp->cl_perclient.next, struct nfs4_stateowner, so_perclient);
release_stateowner(sop);
}
- free_client(clp);
+ put_nfs4_client(clp);
}
static struct nfs4_client *
@@ -235,6 +242,9 @@ create_client(struct xdr_netobj name) {
if (!(clp = alloc_client(name)))
goto out;
+ atomic_set(&clp->cl_count, 1);
+ atomic_set(&clp->cl_callback.cb_set, 0);
+ clp->cl_callback.cb_parsed = 0;
INIT_LIST_HEAD(&clp->cl_idhash);
INIT_LIST_HEAD(&clp->cl_strhash);
INIT_LIST_HEAD(&clp->cl_perclient);
diff ./include/linux/nfsd/state.h~current~ ./include/linux/nfsd/state.h
--- ./include/linux/nfsd/state.h~current~ 2004-12-15 11:46:29.000000000 +1100
+++ ./include/linux/nfsd/state.h 2004-12-15 11:49:34.000000000 +1100
@@ -76,7 +76,7 @@ struct nfs4_callback {
u32 cb_prog;
u32 cb_ident;
/* RPC client info */
- u32 cb_set; /* successful CB_NULL call */
+ atomic_t cb_set; /* successful CB_NULL call */
struct rpc_program cb_program;
struct rpc_stat cb_stat;
struct rpc_clnt * cb_client;
@@ -106,6 +106,7 @@ struct nfs4_client {
nfs4_verifier cl_confirm; /* generated by server */
struct nfs4_callback cl_callback; /* callback info */
time_t cl_first_state; /* first state aquisition*/
+ atomic_t cl_count; /* ref count */
};
/* struct nfs4_client_reset
@@ -250,6 +251,7 @@ extern void nfs4_lock_state(void);
extern void nfs4_unlock_state(void);
extern int nfs4_in_grace(void);
extern int nfs4_check_open_reclaim(clientid_t *clid);
+extern void put_nfs4_client(struct nfs4_client *clp);
extern void nfs4_free_stateowner(struct kref *kref);
static inline void
-------------------------------------------------------
SF email is sponsored by - The IT Product Guide
Read honest & candid reviews on hundreds of IT Products from real users.
Discover which products truly live up to the hype. Start reading now.
http://productguide.itmanagersjournal.com/
_______________________________________________
NFS maillist - NFS@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/nfs
^ permalink raw reply [flat|nested] 29+ messages in thread
* [PATCH kNFSd 5 of 23] Probe the callback path upon a successful setclientid_confirm
2004-12-17 5:23 [PATCH kNFSd 0 of 23] Introduction NeilBrown
@ 2004-12-17 5:23 ` NeilBrown
2004-12-17 5:23 ` [PATCH kNFSd 1 of 23] Move nfserr_openmode checking from nfsd_read/write into nfs4_preprocess_stateid_op() in preperation for delegation state NeilBrown
` (21 subsequent siblings)
22 siblings, 0 replies; 29+ messages in thread
From: NeilBrown @ 2004-12-17 5:23 UTC (permalink / raw)
To: Andrew Morton; +Cc: nfs
Signed-off-by: Andy Adamson <andros@citi.umich.edu>
Signed-off-by: Neil Brown <neilb@cse.unsw.edu.au>
### Diffstat output
./fs/nfsd/nfs4state.c | 6 +++++-
1 files changed, 5 insertions(+), 1 deletion(-)
diff ./fs/nfsd/nfs4state.c~current~ ./fs/nfsd/nfs4state.c
--- ./fs/nfsd/nfs4state.c~current~ 2004-12-15 11:49:34.000000000 +1100
+++ ./fs/nfsd/nfs4state.c 2004-12-15 11:55:28.000000000 +1100
@@ -724,6 +724,7 @@ nfsd4_setclientid_confirm(struct svc_rqs
status = nfserr_clid_inuse;
else {
expire_client(conf);
+ clp = unconf;
move_to_confirmed(unconf, idhashval);
status = nfs_ok;
}
@@ -741,6 +742,7 @@ nfsd4_setclientid_confirm(struct svc_rqs
if (!cmp_creds(&conf->cl_cred,&rqstp->rq_cred)) {
status = nfserr_clid_inuse;
} else {
+ clp = conf;
status = nfs_ok;
}
goto out;
@@ -755,6 +757,7 @@ nfsd4_setclientid_confirm(struct svc_rqs
status = nfserr_clid_inuse;
} else {
status = nfs_ok;
+ clp = unconf;
move_to_confirmed(unconf, idhashval);
}
goto out;
@@ -774,7 +777,8 @@ nfsd4_setclientid_confirm(struct svc_rqs
status = nfserr_inval;
goto out;
out:
- /* XXX if status == nfs_ok, probe callback path */
+ if (!status)
+ nfsd4_probe_callback(clp);
nfs4_unlock_state();
return status;
}
-------------------------------------------------------
SF email is sponsored by - The IT Product Guide
Read honest & candid reviews on hundreds of IT Products from real users.
Discover which products truly live up to the hype. Start reading now.
http://productguide.itmanagersjournal.com/
_______________________________________________
NFS maillist - NFS@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/nfs
^ permalink raw reply [flat|nested] 29+ messages in thread
* [PATCH kNFSd 2 of 23] Check the callback netid in gen_callback.
2004-12-17 5:23 [PATCH kNFSd 0 of 23] Introduction NeilBrown
` (5 preceding siblings ...)
2004-12-17 5:23 ` [PATCH kNFSd 3 of 23] Count the nfs4_client structure usage NeilBrown
@ 2004-12-17 5:23 ` NeilBrown
2004-12-17 5:23 ` [PATCH kNFSd 14 of 23] Delegation recall callback rpc NeilBrown
` (15 subsequent siblings)
22 siblings, 0 replies; 29+ messages in thread
From: NeilBrown @ 2004-12-17 5:23 UTC (permalink / raw)
To: Andrew Morton; +Cc: nfs
since we only support tcp, don't save the netinfo.
Signed-off-by: Andy Adamson <andros@citi.umich.edu>
Signed-off-by: Neil Brown <neilb@cse.unsw.edu.au>
### Diffstat output
./fs/nfsd/nfs4state.c | 21 ++++++++++++++-------
./include/linux/nfsd/state.h | 1 -
2 files changed, 14 insertions(+), 8 deletions(-)
diff ./fs/nfsd/nfs4state.c~current~ ./fs/nfsd/nfs4state.c
--- ./fs/nfsd/nfs4state.c~current~ 2004-12-15 11:44:49.000000000 +1100
+++ ./fs/nfsd/nfs4state.c 2004-12-15 11:46:29.000000000 +1100
@@ -420,17 +420,24 @@ gen_callback(struct nfs4_client *clp, st
{
struct nfs4_callback *cb = &clp->cl_callback;
+ /* Currently, we only support tcp for the callback channel */
+ if ((se->se_callback_netid_len != 3) || memcmp((char *)se->se_callback_netid_val, "tcp", 3))
+ goto out_err;
+
if ( !(parse_ipv4(se->se_callback_addr_len, se->se_callback_addr_val,
- &cb->cb_addr, &cb->cb_port))) {
- printk(KERN_INFO "NFSD: BAD callback address. client will not receive delegations\n");
- cb->cb_parsed = 0;
- return;
- }
- cb->cb_netid.len = se->se_callback_netid_len;
- cb->cb_netid.data = se->se_callback_netid_val;
+ &cb->cb_addr, &cb->cb_port)))
+ goto out_err;
cb->cb_prog = se->se_callback_prog;
cb->cb_ident = se->se_callback_ident;
cb->cb_parsed = 1;
+ return;
+out_err:
+ printk(KERN_INFO "NFSD: this client (clientid %08x/%08x) "
+ "will not receive delegations\n",
+ clp->cl_clientid.cl_boot, clp->cl_clientid.cl_id);
+
+ cb->cb_parsed = 0;
+ return;
}
/*
diff ./include/linux/nfsd/state.h~current~ ./include/linux/nfsd/state.h
--- ./include/linux/nfsd/state.h~current~ 2004-12-15 11:44:49.000000000 +1100
+++ ./include/linux/nfsd/state.h 2004-12-15 11:46:29.000000000 +1100
@@ -75,7 +75,6 @@ struct nfs4_callback {
unsigned short cb_port;
u32 cb_prog;
u32 cb_ident;
- struct xdr_netobj cb_netid;
/* RPC client info */
u32 cb_set; /* successful CB_NULL call */
struct rpc_program cb_program;
-------------------------------------------------------
SF email is sponsored by - The IT Product Guide
Read honest & candid reviews on hundreds of IT Products from real users.
Discover which products truly live up to the hype. Start reading now.
http://productguide.itmanagersjournal.com/
_______________________________________________
NFS maillist - NFS@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/nfs
^ permalink raw reply [flat|nested] 29+ messages in thread
* [PATCH kNFSd 1 of 23] Move nfserr_openmode checking from nfsd_read/write into nfs4_preprocess_stateid_op() in preperation for delegation state.
2004-12-17 5:23 [PATCH kNFSd 0 of 23] Introduction NeilBrown
2004-12-17 5:23 ` [PATCH kNFSd 5 of 23] Probe the callback path upon a successful setclientid_confirm NeilBrown
@ 2004-12-17 5:23 ` NeilBrown
2004-12-17 5:23 ` [PATCH kNFSd 6 of 23] Check for existence of file_lock parameter inside of the kernel lock NeilBrown
` (20 subsequent siblings)
22 siblings, 0 replies; 29+ messages in thread
From: NeilBrown @ 2004-12-17 5:23 UTC (permalink / raw)
To: Andrew Morton; +Cc: nfs
Signed-off-by: Andy Adamson <andros@citi.umich.edu>
Signed-off-by: Neil Brown <neilb@cse.unsw.edu.au>
### Diffstat output
./fs/nfsd/nfs4proc.c | 40 ++++------------------------------------
./fs/nfsd/nfs4state.c | 42 +++++++++++++++++++++++++++++++++++-------
./include/linux/nfsd/state.h | 7 ++++---
3 files changed, 43 insertions(+), 46 deletions(-)
diff ./fs/nfsd/nfs4proc.c~current~ ./fs/nfsd/nfs4proc.c
--- ./fs/nfsd/nfs4proc.c~current~ 2004-12-15 11:44:49.000000000 +1100
+++ ./fs/nfsd/nfs4proc.c 2004-12-15 11:44:49.000000000 +1100
@@ -461,23 +461,8 @@ nfsd4_lookup(struct svc_rqst *rqstp, str
}
static inline int
-access_bits_permit_read(unsigned long access_bmap)
-{
- return test_bit(NFS4_SHARE_ACCESS_READ, &access_bmap) ||
- test_bit(NFS4_SHARE_ACCESS_BOTH, &access_bmap);
-}
-
-static inline int
-access_bits_permit_write(unsigned long access_bmap)
-{
- return test_bit(NFS4_SHARE_ACCESS_WRITE, &access_bmap) ||
- test_bit(NFS4_SHARE_ACCESS_BOTH, &access_bmap);
-}
-
-static inline int
nfsd4_read(struct svc_rqst *rqstp, struct svc_fh *current_fh, struct nfsd4_read *read)
{
- struct nfs4_stateid *stp;
int status;
/* no need to check permission - this will be done in nfsd_read() */
@@ -509,15 +494,10 @@ nfsd4_read(struct svc_rqst *rqstp, struc
}
/* check stateid */
if ((status = nfs4_preprocess_stateid_op(current_fh, &read->rd_stateid,
- CHECK_FH | RDWR_STATE, &stp))) {
+ CHECK_FH | RD_STATE))) {
dprintk("NFSD: nfsd4_read: couldn't process stateid!\n");
goto out;
}
- status = nfserr_openmode;
- if (!access_bits_permit_read(stp->st_access_bmap)) {
- dprintk("NFSD: nfsd4_read: file not opened for read!\n");
- goto out;
- }
status = nfs_ok;
out:
nfs4_unlock_state();
@@ -605,7 +585,6 @@ nfsd4_rename(struct svc_rqst *rqstp, str
static inline int
nfsd4_setattr(struct svc_rqst *rqstp, struct svc_fh *current_fh, struct nfsd4_setattr *setattr)
{
- struct nfs4_stateid *stp;
int status = nfs_ok;
if (nfs4_in_grace())
@@ -626,15 +605,10 @@ nfsd4_setattr(struct svc_rqst *rqstp, st
nfs4_lock_state();
if ((status = nfs4_preprocess_stateid_op(current_fh,
&setattr->sa_stateid,
- CHECK_FH | RDWR_STATE, &stp))) {
+ CHECK_FH | WR_STATE))) {
dprintk("NFSD: nfsd4_setattr: couldn't process stateid!\n");
goto out_unlock;
}
- status = nfserr_openmode;
- if (!access_bits_permit_write(stp->st_access_bmap)) {
- dprintk("NFSD: nfsd4_setattr: not opened for write!\n");
- goto out_unlock;
- }
nfs4_unlock_state();
}
status = nfs_ok;
@@ -654,7 +628,6 @@ out_unlock:
static inline int
nfsd4_write(struct svc_rqst *rqstp, struct svc_fh *current_fh, struct nfsd4_write *write)
{
- struct nfs4_stateid *stp;
stateid_t *stateid = &write->wr_stateid;
u32 *p;
int status = nfs_ok;
@@ -677,18 +650,13 @@ nfsd4_write(struct svc_rqst *rqstp, stru
goto zero_stateid;
}
if ((status = nfs4_preprocess_stateid_op(current_fh, stateid,
- CHECK_FH | RDWR_STATE, &stp))) {
+ CHECK_FH | WR_STATE))) {
dprintk("NFSD: nfsd4_write: couldn't process stateid!\n");
goto out;
}
- status = nfserr_openmode;
- if (!access_bits_permit_write(stp->st_access_bmap)) {
- dprintk("NFSD: nfsd4_write: file not open for write!\n");
- goto out;
- }
-
zero_stateid:
+
nfs4_unlock_state();
write->wr_bytes_written = write->wr_buflen;
write->wr_how_written = write->wr_stable_how;
diff ./fs/nfsd/nfs4state.c~current~ ./fs/nfsd/nfs4state.c
--- ./fs/nfsd/nfs4state.c~current~ 2004-12-15 11:44:49.000000000 +1100
+++ ./fs/nfsd/nfs4state.c 2004-12-15 11:44:49.000000000 +1100
@@ -1564,12 +1564,39 @@ STALE_STATEID(stateid_t *stateid)
return 1;
}
+static inline int
+access_permit_read(unsigned long access_bmap)
+{
+ return test_bit(NFS4_SHARE_ACCESS_READ, &access_bmap) ||
+ test_bit(NFS4_SHARE_ACCESS_BOTH, &access_bmap);
+}
+
+static inline int
+access_permit_write(unsigned long access_bmap)
+{
+ return test_bit(NFS4_SHARE_ACCESS_WRITE, &access_bmap) ||
+ test_bit(NFS4_SHARE_ACCESS_BOTH, &access_bmap);
+}
+
+static
+int check_openmode(struct nfs4_stateid *stp, int flags)
+{
+ int status = nfserr_openmode;
+
+ if ((flags & WR_STATE) && (!access_permit_write(stp->st_access_bmap)))
+ goto out;
+ if ((flags & RD_STATE) && (!access_permit_read(stp->st_access_bmap)))
+ goto out;
+ status = nfs_ok;
+out:
+ return status;
+}
/*
* Checks for stateid operations
*/
int
-nfs4_preprocess_stateid_op(struct svc_fh *current_fh, stateid_t *stateid, int flags, struct nfs4_stateid **stpp)
+nfs4_preprocess_stateid_op(struct svc_fh *current_fh, stateid_t *stateid, int flags)
{
struct nfs4_stateid *stp;
int status;
@@ -1578,8 +1605,6 @@ nfs4_preprocess_stateid_op(struct svc_fh
stateid->si_boot, stateid->si_stateownerid,
stateid->si_fileid, stateid->si_generation);
- *stpp = NULL;
-
/* STALE STATEID */
status = nfserr_stale_stateid;
if (STALE_STATEID(stateid))
@@ -1611,9 +1636,12 @@ nfs4_preprocess_stateid_op(struct svc_fh
dprintk("preprocess_stateid_op: old stateid!\n");
goto out;
}
- *stpp = stp;
- status = nfs_ok;
renew_client(stp->st_stateowner->so_client);
+
+ if((status = check_openmode(stp, flags)))
+ goto out;
+
+ status = nfs_ok;
out:
return status;
}
@@ -1938,7 +1966,7 @@ find_stateid(stateid_t *stid, int flags)
unsigned int hashval;
dprintk("NFSD: find_stateid flags 0x%x\n",flags);
- if ((flags & LOCK_STATE) || (flags & RDWR_STATE)) {
+ if ((flags & LOCK_STATE) || (flags & RD_STATE) || (flags & WR_STATE)) {
hashval = stateid_hashval(st_id, f_id);
list_for_each_entry(local, &lockstateid_hashtbl[hashval], st_hash) {
if ((local->st_stateid.si_stateownerid == st_id) &&
@@ -1946,7 +1974,7 @@ find_stateid(stateid_t *stid, int flags)
return local;
}
}
- if ((flags & OPEN_STATE) || (flags & RDWR_STATE)) {
+ if ((flags & OPEN_STATE) || (flags & RD_STATE) || (flags & WR_STATE)) {
hashval = stateid_hashval(st_id, f_id);
list_for_each_entry(local, &stateid_hashtbl[hashval], st_hash) {
if ((local->st_stateid.si_stateownerid == st_id) &&
diff ./include/linux/nfsd/state.h~current~ ./include/linux/nfsd/state.h
--- ./include/linux/nfsd/state.h~current~ 2004-12-15 11:44:49.000000000 +1100
+++ ./include/linux/nfsd/state.h 2004-12-15 11:44:49.000000000 +1100
@@ -231,8 +231,9 @@ struct nfs4_stateid {
#define CONFIRM 0x00000002
#define OPEN_STATE 0x00000004
#define LOCK_STATE 0x00000008
-#define RDWR_STATE 0x00000010
-#define CLOSE_STATE 0x00000020
+#define RD_STATE 0x00000010
+#define WR_STATE 0x00000020
+#define CLOSE_STATE 0x00000040
#define seqid_mutating_err(err) \
(((err) != nfserr_stale_clientid) && \
@@ -243,7 +244,7 @@ struct nfs4_stateid {
extern time_t nfs4_laundromat(void);
extern int nfsd4_renew(clientid_t *clid);
extern int nfs4_preprocess_stateid_op(struct svc_fh *current_fh,
- stateid_t *stateid, int flags, struct nfs4_stateid **stpp);
+ stateid_t *stateid, int flags);
extern int nfs4_share_conflict(struct svc_fh *current_fh,
unsigned int deny_type);
extern void nfs4_lock_state(void);
-------------------------------------------------------
SF email is sponsored by - The IT Product Guide
Read honest & candid reviews on hundreds of IT Products from real users.
Discover which products truly live up to the hype. Start reading now.
http://productguide.itmanagersjournal.com/
_______________________________________________
NFS maillist - NFS@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/nfs
^ permalink raw reply [flat|nested] 29+ messages in thread
* [PATCH kNFSd 4 of 23] Preparation for delegation: client callback probe
2004-12-17 5:23 [PATCH kNFSd 0 of 23] Introduction NeilBrown
` (2 preceding siblings ...)
2004-12-17 5:23 ` [PATCH kNFSd 6 of 23] Check for existence of file_lock parameter inside of the kernel lock NeilBrown
@ 2004-12-17 5:23 ` NeilBrown
2004-12-17 6:45 ` Mike Waychison
2004-12-17 5:23 ` [PATCH kNFSd 7 of 23] Get rid of the special delegation_stateid_t, use the existing stateid_t NeilBrown
` (18 subsequent siblings)
22 siblings, 1 reply; 29+ messages in thread
From: NeilBrown @ 2004-12-17 5:23 UTC (permalink / raw)
To: Andrew Morton; +Cc: nfs
client callback rpc to probe the callback
channel on setclientid with a null request.
Signed-off-by: Andy Adamson <andros@citi.umich.edu>
Signed-off-by: Neil Brown <neilb@cse.unsw.edu.au>
### Diffstat output
./fs/nfsd/Makefile | 2
./fs/nfsd/nfs4callback.c | 269 +++++++++++++++++++++++++++++++++++++++++++
./include/linux/nfsd/state.h | 1
3 files changed, 271 insertions(+), 1 deletion(-)
diff ./fs/nfsd/Makefile~current~ ./fs/nfsd/Makefile
--- ./fs/nfsd/Makefile~current~ 2004-12-15 11:51:29.000000000 +1100
+++ ./fs/nfsd/Makefile 2004-12-15 11:51:29.000000000 +1100
@@ -8,5 +8,5 @@ nfsd-y := nfssvc.o nfsctl.o nfsproc.o
export.o auth.o lockd.o nfscache.o nfsxdr.o stats.o
nfsd-$(CONFIG_NFSD_V3) += nfs3proc.o nfs3xdr.o
nfsd-$(CONFIG_NFSD_V4) += nfs4proc.o nfs4xdr.o nfs4state.o nfs4idmap.o \
- nfs4acl.o
+ nfs4acl.o nfs4callback.o
nfsd-objs := $(nfsd-y)
diff ./fs/nfsd/nfs4callback.c~current~ ./fs/nfsd/nfs4callback.c
--- ./fs/nfsd/nfs4callback.c~current~ 2004-12-15 11:51:29.000000000 +1100
+++ ./fs/nfsd/nfs4callback.c 2004-12-15 11:51:29.000000000 +1100
@@ -0,0 +1,269 @@
+/*
+ * linux/fs/nfsd/nfs4callback.c
+ *
+ * Copyright (c) 2001 The Regents of the University of Michigan.
+ * All rights reserved.
+ *
+ * Kendrick Smith <kmsmith@umich.edu>
+ * Andy Adamson <andros@umich.edu>
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. Neither the name of the University nor the names of its
+ * contributors may be used to endorse or promote products derived
+ * from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED
+ * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
+ * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
+ * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+ * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include <linux/config.h>
+#include <linux/module.h>
+#include <linux/list.h>
+#include <linux/inet.h>
+#include <linux/errno.h>
+#include <linux/sunrpc/xdr.h>
+#include <linux/sunrpc/svc.h>
+#include <linux/sunrpc/clnt.h>
+#include <linux/nfsd/nfsd.h>
+#include <linux/nfsd/state.h>
+#include <linux/sunrpc/sched.h>
+#include <linux/nfs4.h>
+
+#define NFSDDBG_FACILITY NFSDDBG_PROC
+
+#define NFSPROC4_CB_NULL 0
+
+/* forward declarations */
+static void nfs4_cb_null(struct rpc_task *task);
+
+/* Index of predefined Linux callback client operations */
+
+enum {
+ NFSPROC4_CLNT_CB_NULL = 0,
+};
+
+#define NFS4_MAXTAGLEN 20
+
+#define NFS4_enc_cb_null_sz 0
+#define NFS4_dec_cb_null_sz 0
+
+/*
+* Generic encode routines from fs/nfs/nfs4xdr.c
+*/
+#define RESERVE_SPACE(nbytes) do { \
+ p = xdr_reserve_space(xdr, nbytes); \
+ if (!p) dprintk("NFSD: RESERVE_SPACE(%d) failed in function %s\n", (int) (nbytes), __FUNCTION__); \
+ BUG_ON(!p); \
+} while (0)
+
+/*
+ * XDR encode
+ */
+
+static int
+nfs4_xdr_enc_cb_null(struct rpc_rqst *req, u32 *p)
+{
+ struct xdr_stream xdrs, *xdr = &xdrs;
+
+ xdr_init_encode(&xdrs, &req->rq_snd_buf, p);
+ RESERVE_SPACE(0);
+ return 0;
+}
+
+static int
+nfs4_xdr_dec_cb_null(struct rpc_rqst *req, u32 *p)
+{
+ return 0;
+}
+
+/*
+ * RPC procedure tables
+ */
+#ifndef MAX
+# define MAX(a, b) (((a) > (b))? (a) : (b))
+#endif
+
+#define PROC(proc, call, argtype, restype) \
+[NFSPROC4_CLNT_##proc] = { \
+ .p_proc = NFSPROC4_CB_##call, \
+ .p_encode = (kxdrproc_t) nfs4_xdr_##argtype, \
+ .p_decode = (kxdrproc_t) nfs4_xdr_##restype, \
+ .p_bufsiz = MAX(NFS4_##argtype##_sz,NFS4_##restype##_sz) << 2, \
+}
+
+struct rpc_procinfo nfs4_cb_procedures[] = {
+ PROC(CB_NULL, NULL, enc_cb_null, dec_cb_null),
+};
+
+struct rpc_version nfs_cb_version4 = {
+ .number = 1,
+ .nrprocs = sizeof(nfs4_cb_procedures)/sizeof(nfs4_cb_procedures[0]),
+ .procs = nfs4_cb_procedures
+};
+
+static struct rpc_version * nfs_cb_version[] = {
+ NULL,
+ &nfs_cb_version4,
+};
+
+/*
+ * Use the SETCLIENTID credential
+ */
+struct rpc_cred *
+nfsd4_lookupcred(struct nfs4_client *clp, int taskflags)
+{
+ struct auth_cred acred;
+ struct rpc_clnt *clnt = clp->cl_callback.cb_client;
+ struct rpc_cred *ret = NULL;
+
+ if (!clnt)
+ goto out;
+ get_group_info(clp->cl_cred.cr_group_info);
+ acred.uid = clp->cl_cred.cr_uid;
+ acred.gid = clp->cl_cred.cr_gid;
+ acred.group_info = clp->cl_cred.cr_group_info;
+
+ dprintk("NFSD: looking up %s cred\n",
+ clnt->cl_auth->au_ops->au_name);
+ ret = rpcauth_lookup_credcache(clnt->cl_auth, &acred, taskflags);
+ put_group_info(clp->cl_cred.cr_group_info);
+out:
+ return ret;
+}
+
+/*
+ * Set up the callback client and put a NFSPROC4_CB_NULL on the wire...
+ */
+void
+nfsd4_probe_callback(struct nfs4_client *clp)
+{
+ struct sockaddr_in addr;
+ struct nfs4_callback *cb = &clp->cl_callback;
+ struct rpc_timeout timeparms;
+ struct rpc_xprt * xprt;
+ struct rpc_program * program = &cb->cb_program;
+ struct rpc_stat * stat = &cb->cb_stat;
+ struct rpc_clnt * clnt;
+ struct rpc_message msg = {
+ .rpc_proc = &nfs4_cb_procedures[NFSPROC4_CLNT_CB_NULL],
+ .rpc_argp = clp,
+ };
+ char hostname[32];
+ int status;
+
+ dprintk("NFSD: probe_callback. cb_parsed %d cb_set %d\n",
+ cb->cb_parsed, atomic_read(&cb->cb_set));
+ if (!cb->cb_parsed || atomic_read(&cb->cb_set))
+ return;
+
+ /* Initialize address */
+ memset(&addr, 0, sizeof(addr));
+ addr.sin_family = AF_INET;
+ addr.sin_port = htons(cb->cb_port);
+ addr.sin_addr.s_addr = htonl(cb->cb_addr);
+
+ /* Initialize timeout */
+ timeparms.to_initval = (NFSD_LEASE_TIME/4) * HZ;
+ timeparms.to_retries = 5;
+ timeparms.to_maxval = (NFSD_LEASE_TIME/2) * HZ;
+ timeparms.to_exponential = 1;
+
+ /* Create RPC transport */
+ if (!(xprt = xprt_create_proto(IPPROTO_TCP, &addr, &timeparms))) {
+ dprintk("NFSD: couldn't create callback transport!\n");
+ goto out_err;
+ }
+
+ /* Initialize rpc_program */
+ program->name = "nfs4_cb";
+ program->number = cb->cb_prog;
+ program->nrvers = sizeof(nfs_cb_version)/sizeof(nfs_cb_version[0]);
+ program->version = nfs_cb_version;
+ program->stats = stat;
+
+ /* Initialize rpc_stat */
+ memset(stat, 0, sizeof(struct rpc_stat));
+ stat->program = program;
+
+ /* Create RPC client
+ *
+ * XXX AUTH_UNIX only - need AUTH_GSS....
+ */
+ sprintf(hostname, "%u.%u.%u.%u", NIPQUAD(addr.sin_addr.s_addr));
+ if (!(clnt = rpc_create_client(xprt, hostname, program, 1, RPC_AUTH_UNIX))) {
+ dprintk("NFSD: couldn't create callback client\n");
+ goto out_xprt;
+ }
+ clnt->cl_intr = 1;
+ clnt->cl_softrtry = 1;
+ clnt->cl_chatty = 1;
+ cb->cb_client = clnt;
+
+ /* Kick rpciod, put the call on the wire. */
+
+ if (rpciod_up() != 0) {
+ dprintk("nfsd: couldn't start rpciod for callbacks!\n");
+ goto out_clnt;
+ }
+
+ /* the task holds a reference to the nfs4_client struct */
+ atomic_inc(&clp->cl_count);
+
+ msg.rpc_cred = nfsd4_lookupcred(clp,0);
+ status = rpc_call_async(clnt, &msg, RPC_TASK_ASYNC, nfs4_cb_null, NULL);
+
+ if (status != 0) {
+ dprintk("NFSD: asynchronous NFSPROC4_CB_NULL failed!\n");
+ goto out_rpciod;
+ }
+ return;
+
+out_rpciod:
+ rpciod_down();
+out_clnt:
+ rpc_shutdown_client(clnt);
+ goto out_err;
+out_xprt:
+ xprt_destroy(xprt);
+out_err:
+ dprintk("NFSD: warning: no callback path to client %.*s\n",
+ clp->cl_name.len, clp->cl_name.data);
+ cb->cb_client = NULL;
+}
+
+static void
+nfs4_cb_null(struct rpc_task *task)
+{
+ struct nfs4_client *clp = (struct nfs4_client *)task->tk_msg.rpc_argp;
+ struct nfs4_callback *cb = &clp->cl_callback;
+ u32 addr = htonl(cb->cb_addr);
+
+ dprintk("NFSD: nfs4_cb_null task->tk_status %d\n", task->tk_status);
+
+ if (task->tk_status < 0) {
+ dprintk("NFSD: callback establishment to client %.*s failed\n",
+ clp->cl_name.len, clp->cl_name.data);
+ goto out;
+ }
+ atomic_set(&cb->cb_set, 1);
+ dprintk("NFSD: callback set to client %u.%u.%u.%u\n", NIPQUAD(addr));
+out:
+ put_nfs4_client(clp);
+}
diff ./include/linux/nfsd/state.h~current~ ./include/linux/nfsd/state.h
--- ./include/linux/nfsd/state.h~current~ 2004-12-15 11:49:34.000000000 +1100
+++ ./include/linux/nfsd/state.h 2004-12-15 11:51:29.000000000 +1100
@@ -253,6 +253,7 @@ extern int nfs4_in_grace(void);
extern int nfs4_check_open_reclaim(clientid_t *clid);
extern void put_nfs4_client(struct nfs4_client *clp);
extern void nfs4_free_stateowner(struct kref *kref);
+extern void nfsd4_probe_callback(struct nfs4_client *clp);
static inline void
nfs4_put_stateowner(struct nfs4_stateowner *so)
-------------------------------------------------------
SF email is sponsored by - The IT Product Guide
Read honest & candid reviews on hundreds of IT Products from real users.
Discover which products truly live up to the hype. Start reading now.
http://productguide.itmanagersjournal.com/
_______________________________________________
NFS maillist - NFS@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/nfs
^ permalink raw reply [flat|nested] 29+ messages in thread
* [PATCH kNFSd 16 of 23] Helper functions for deciding to grant a delegation.
2004-12-17 5:23 [PATCH kNFSd 0 of 23] Introduction NeilBrown
` (7 preceding siblings ...)
2004-12-17 5:23 ` [PATCH kNFSd 14 of 23] Delegation recall callback rpc NeilBrown
@ 2004-12-17 5:23 ` NeilBrown
2004-12-17 5:23 ` [PATCH kNFSd 15 of 23] Kernel thread for delegation callback NeilBrown
` (13 subsequent siblings)
22 siblings, 0 replies; 29+ messages in thread
From: NeilBrown @ 2004-12-17 5:23 UTC (permalink / raw)
To: Andrew Morton; +Cc: nfs
Signed-off-by: Andy Adamson <andros@citi.umich.edu>
Signed-off-by: Neil Brown <neilb@cse.unsw.edu.au>
### Diffstat output
./fs/nfsd/nfs4state.c | 37 +++++++++++++++++++++++++++++++++++++
1 files changed, 37 insertions(+)
diff ./fs/nfsd/nfs4state.c~current~ ./fs/nfsd/nfs4state.c
--- ./fs/nfsd/nfs4state.c~current~ 2004-12-15 13:37:36.000000000 +1100
+++ ./fs/nfsd/nfs4state.c 2004-12-15 13:37:50.000000000 +1100
@@ -1504,6 +1504,43 @@ out:
}
static int
+nfs4_deleg_conflict(u32 share, u32 dtype)
+{
+ return (((share & NFS4_SHARE_ACCESS_WRITE) &&
+ dtype == NFS4_OPEN_DELEGATE_READ) ||
+ ((share & NFS4_SHARE_ACCESS_READ) &&
+ dtype == NFS4_OPEN_DELEGATE_WRITE));
+}
+
+#define DONT_DELEGATE 8
+
+/*
+ * nfs4_check_deleg_recall()
+ *
+ * Test any delegation that is currently within an incompleted recalled
+ * state, and return NFSERR_DELAY for conflicting open share.
+ * flag is set to DONT_DELEGATE for shares that match the deleg type.
+ */
+static int
+nfs4_check_deleg_recall(struct nfs4_file *fp, struct nfsd4_open *op, int *flag)
+{
+ struct nfs4_delegation *dp;
+ int status = 0;
+
+ list_for_each_entry(dp, &fp->fi_del_perfile, dl_del_perfile) {
+ dprintk("NFSD: found delegation %p with dl_state %d\n",
+ dp, atomic_read(&dp->dl_state));
+ if (atomic_read(&dp->dl_state) == NFS4_RECALL_IN_PROGRESS) {
+ if(nfs4_deleg_conflict(op->op_share_access, dp->dl_type))
+ status = nfserr_jukebox;
+ else
+ *flag = DONT_DELEGATE;
+ }
+ }
+ return status;
+}
+
+static int
nfs4_check_open(struct nfs4_file *fp, struct nfs4_stateowner *sop, struct nfsd4_open *open, struct nfs4_stateid **stpp)
{
struct nfs4_stateid *local;
-------------------------------------------------------
SF email is sponsored by - The IT Product Guide
Read honest & candid reviews on hundreds of IT Products from real users.
Discover which products truly live up to the hype. Start reading now.
http://productguide.itmanagersjournal.com/
_______________________________________________
NFS maillist - NFS@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/nfs
^ permalink raw reply [flat|nested] 29+ messages in thread
* [PATCH kNFSd 9 of 23] Allocate and initialize the delegation structure.
2004-12-17 5:23 [PATCH kNFSd 0 of 23] Introduction NeilBrown
` (9 preceding siblings ...)
2004-12-17 5:23 ` [PATCH kNFSd 15 of 23] Kernel thread for delegation callback NeilBrown
@ 2004-12-17 5:23 ` NeilBrown
2004-12-17 5:23 ` [PATCH kNFSd 13 of 23] Delay nfsd_colse for delegations until reaping NeilBrown
` (11 subsequent siblings)
22 siblings, 0 replies; 29+ messages in thread
From: NeilBrown @ 2004-12-17 5:23 UTC (permalink / raw)
To: Andrew Morton; +Cc: nfs
Declare and initialize the recall_lru list.
Signed-off-by: Andy Adamson <andros@citi.umich.edu>
Signed-off-by: Neil Brown <neilb@cse.unsw.edu.au>
### Diffstat output
./fs/nfsd/nfs4state.c | 58 ++++++++++++++++++++++++++++++++++++++++++++++++--
1 files changed, 56 insertions(+), 2 deletions(-)
diff ./fs/nfsd/nfs4state.c~current~ ./fs/nfsd/nfs4state.c
--- ./fs/nfsd/nfs4state.c~current~ 2004-12-15 11:55:28.000000000 +1100
+++ ./fs/nfsd/nfs4state.c 2004-12-15 12:00:46.000000000 +1100
@@ -57,8 +57,9 @@ static u32 nfs4_reclaim_init = 0;
time_t boot_time;
static time_t grace_end = 0;
static u32 current_clientid = 1;
-static u32 current_ownerid;
-static u32 current_fileid;
+static u32 current_ownerid = 1;
+static u32 current_fileid = 1;
+static u32 current_delegid = 1;
static u32 nfs4_init;
stateid_t zerostateid; /* bits all 0 */
stateid_t onestateid; /* bits all 1 */
@@ -75,6 +76,8 @@ u32 free_sowner = 0;
u32 vfsopen = 0;
u32 vfsclose = 0;
u32 alloc_lsowner= 0;
+u32 alloc_delegation= 0;
+u32 free_delegation= 0;
/* forward declarations */
struct nfs4_stateid * find_stateid(stateid_t *stid, int flags);
@@ -117,6 +120,50 @@ static void release_stateowner(struct nf
static void release_stateid(struct nfs4_stateid *stp, int flags);
static void release_file(struct nfs4_file *fp);
+/*
+ * Delegation state
+ */
+
+/* recall_lock protects the del_recall_lru */
+spinlock_t recall_lock;
+static struct list_head del_recall_lru;
+
+static struct nfs4_delegation *
+alloc_init_deleg(struct nfs4_client *clp, struct nfs4_file *fp, struct svc_fh *current_fh, u32 type)
+{
+ struct nfs4_delegation *dp;
+
+ dprintk("NFSD alloc_init_deleg\n");
+ if ((dp = kmalloc(sizeof(struct nfs4_delegation),
+ GFP_KERNEL)) == NULL)
+ return dp;
+ INIT_LIST_HEAD(&dp->dl_del_perfile);
+ INIT_LIST_HEAD(&dp->dl_del_perclnt);
+ INIT_LIST_HEAD(&dp->dl_recall_lru);
+ dp->dl_client = clp;
+ dp->dl_file = fp;
+ dp->dl_flock = NULL;
+ dp->dl_stp = NULL;
+ dp->dl_type = type;
+ dp->dl_recall.cbr_dp = NULL;
+ dp->dl_recall.cbr_ident = 0;
+ dp->dl_recall.cbr_trunc = 0;
+ dp->dl_stateid.si_boot = boot_time;
+ dp->dl_stateid.si_stateownerid = current_delegid++;
+ dp->dl_stateid.si_fileid = 0;
+ dp->dl_stateid.si_generation = 0;
+ dp->dl_fhlen = current_fh->fh_handle.fh_size;
+ memcpy(dp->dl_fhval, ¤t_fh->fh_handle.fh_base,
+ current_fh->fh_handle.fh_size);
+ dp->dl_time = 0;
+ atomic_set(&dp->dl_state, NFS4_NO_RECALL);
+ atomic_set(&dp->dl_count, 1);
+ atomic_set(&dp->dl_recall_cnt, 0);
+ list_add(&dp->dl_del_perfile, &fp->fi_del_perfile);
+ list_add(&dp->dl_del_perclnt, &clp->cl_del_perclnt);
+ alloc_delegation++;
+ return dp;
+}
/*
* SETCLIENTID state
@@ -248,6 +295,7 @@ create_client(struct xdr_netobj name) {
INIT_LIST_HEAD(&clp->cl_idhash);
INIT_LIST_HEAD(&clp->cl_strhash);
INIT_LIST_HEAD(&clp->cl_perclient);
+ INIT_LIST_HEAD(&clp->cl_del_perclnt);
INIT_LIST_HEAD(&clp->cl_lru);
out:
return clp;
@@ -824,6 +872,7 @@ alloc_init_file(unsigned int hashval, st
if ((fp = kmalloc(sizeof(struct nfs4_file),GFP_KERNEL))) {
INIT_LIST_HEAD(&fp->fi_hash);
INIT_LIST_HEAD(&fp->fi_perfile);
+ INIT_LIST_HEAD(&fp->fi_del_perfile);
list_add(&fp->fi_hash, &file_hashtbl[hashval]);
fp->fi_inode = igrab(ino);
fp->fi_id = current_fileid++;
@@ -2738,6 +2787,8 @@ nfs4_state_init(void)
INIT_LIST_HEAD(&close_lru);
INIT_LIST_HEAD(&client_lru);
+ INIT_LIST_HEAD(&del_recall_lru);
+ spin_lock_init(&recall_lock);
boot_time = get_seconds();
grace_time = max(old_lease_time, lease_time);
if (reclaim_str_hashtbl_size == 0)
@@ -2799,6 +2850,9 @@ __nfs4_state_shutdown(void)
alloc_sowner, alloc_lsowner, free_sowner);
dprintk("NFSD: vfsopen %d vfsclose %d\n",
vfsopen, vfsclose);
+ dprintk("NFSD: alloc_delegation %d free_delegation %d\n",
+ alloc_delegation, free_delegation);
+
}
void
-------------------------------------------------------
SF email is sponsored by - The IT Product Guide
Read honest & candid reviews on hundreds of IT Products from real users.
Discover which products truly live up to the hype. Start reading now.
http://productguide.itmanagersjournal.com/
_______________________________________________
NFS maillist - NFS@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/nfs
^ permalink raw reply [flat|nested] 29+ messages in thread
* [PATCH kNFSd 11 of 23] Add the delegation release and free functions
2004-12-17 5:23 [PATCH kNFSd 0 of 23] Introduction NeilBrown
` (12 preceding siblings ...)
2004-12-17 5:23 ` [PATCH kNFSd 18 of 23] Remove unnecessary stateowner existence check NeilBrown
@ 2004-12-17 5:23 ` NeilBrown
2004-12-17 5:23 ` [PATCH kNFSd 12 of 23] Changes to expire_client NeilBrown
` (8 subsequent siblings)
22 siblings, 0 replies; 29+ messages in thread
From: NeilBrown @ 2004-12-17 5:23 UTC (permalink / raw)
To: Andrew Morton; +Cc: nfs
Signed-off-by: Andy Adamson <andros@citi.umich.edu>
Signed-off-by: Neil Brown <neilb@cse.unsw.edu.au>
### Diffstat output
./fs/nfsd/nfs4state.c | 63 ++++++++++++++++++++++++++++++++++++++++++++++++++
1 files changed, 63 insertions(+)
diff ./fs/nfsd/nfs4state.c~current~ ./fs/nfsd/nfs4state.c
--- ./fs/nfsd/nfs4state.c~current~ 2004-12-15 12:03:23.000000000 +1100
+++ ./fs/nfsd/nfs4state.c 2004-12-15 12:04:09.000000000 +1100
@@ -82,6 +82,8 @@ u32 free_delegation= 0;
/* forward declarations */
struct nfs4_stateid * find_stateid(stateid_t *stid, int flags);
static struct nfs4_delegation * find_delegation_stateid(struct inode *ino, stateid_t *stid);
+static void release_delegation(struct nfs4_delegation *dp);
+static void release_stateid_lockowner(struct nfs4_stateid *open_stp);
/* Locking:
*
@@ -166,6 +168,67 @@ alloc_init_deleg(struct nfs4_client *clp
return dp;
}
+/*
+ * Free the delegation structure.
+ * Called with the recall_lock held.
+ */
+static void
+nfs4_free_delegation(struct nfs4_delegation *dp)
+{
+ dprintk("NFSD: nfs4_free_delegation freeing dp %p\n",dp);
+ list_del(&dp->dl_recall_lru);
+ kfree(dp);
+ free_delegation++;
+}
+
+/* release_delegation:
+ *
+ * Remove the associated file_lock first, then remove the delegation.
+ * lease_modify() is called to remove the FS_LEASE file_lock from
+ * the i_flock list, eventually calling nfsd's lock_manager
+ * fl_release_callback.
+ *
+ * call either:
+ * nfsd_close : if last close, locks_remove_flock calls lease_modify.
+ * otherwise, recalled state set to NFS4_RECALL_COMPLETE
+ * so that it will be reaped by the laundromat service.
+ * or
+ * remove_lease (calls time_out_lease which calls lease_modify).
+ * and nfs4_free_delegation.
+ *
+ * Called with nfs_lock_state() held.
+ * Called with the recall_lock held.
+ */
+
+static void
+release_delegation(struct nfs4_delegation *dp)
+{
+ /* delayed nfsd_close */
+ if (dp->dl_stp) {
+ struct file *filp = dp->dl_stp->st_vfs_file;
+
+ dprintk("NFSD: release_delegation CLOSE\n");
+ release_stateid_lockowner(dp->dl_stp);
+ kfree(dp->dl_stp);
+ dp->dl_stp = NULL;
+ atomic_set(&dp->dl_state, NFS4_RECALL_COMPLETE);
+ nfsd_close(filp);
+ vfsclose++;
+ } else {
+ dprintk("NFSD: release_delegation remove lease dl_flock %p\n",
+ dp->dl_flock);
+ remove_lease(dp->dl_flock);
+ list_del_init(&dp->dl_del_perfile);
+ list_del_init(&dp->dl_del_perclnt);
+ /* dl_count > 0 => outstanding recall rpc */
+ dprintk("NFSD: release_delegation free deleg dl_count %d\n",
+ atomic_read(&dp->dl_count));
+ if ((atomic_read(&dp->dl_state) == NFS4_REAP_DELEG)
+ || atomic_dec_and_test(&dp->dl_count))
+ nfs4_free_delegation(dp);
+ }
+}
+
/*
* SETCLIENTID state
*/
-------------------------------------------------------
SF email is sponsored by - The IT Product Guide
Read honest & candid reviews on hundreds of IT Products from real users.
Discover which products truly live up to the hype. Start reading now.
http://productguide.itmanagersjournal.com/
_______________________________________________
NFS maillist - NFS@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/nfs
^ permalink raw reply [flat|nested] 29+ messages in thread
* [PATCH kNFSd 10 of 23] Find a delegation for a file given a stateid.
2004-12-17 5:23 [PATCH kNFSd 0 of 23] Introduction NeilBrown
` (15 preceding siblings ...)
2004-12-17 5:23 ` [PATCH kNFSd 8 of 23] Add structures for delegation support NeilBrown
@ 2004-12-17 5:23 ` NeilBrown
2004-12-17 5:23 ` [PATCH kNFSd 17 of 23] Attempt to hand out a delegation NeilBrown
` (5 subsequent siblings)
22 siblings, 0 replies; 29+ messages in thread
From: NeilBrown @ 2004-12-17 5:23 UTC (permalink / raw)
To: Andrew Morton; +Cc: nfs
Signed-off-by: Andy Adamson <andros@citi.umich.edu>
Signed-off-by: Neil Brown <neilb@cse.unsw.edu.au>
### Diffstat output
./fs/nfsd/nfs4state.c | 27 +++++++++++++++++++++++++++
1 files changed, 27 insertions(+)
diff ./fs/nfsd/nfs4state.c~current~ ./fs/nfsd/nfs4state.c
--- ./fs/nfsd/nfs4state.c~current~ 2004-12-15 12:00:46.000000000 +1100
+++ ./fs/nfsd/nfs4state.c 2004-12-15 12:03:23.000000000 +1100
@@ -81,6 +81,7 @@ u32 free_delegation= 0;
/* forward declarations */
struct nfs4_stateid * find_stateid(stateid_t *stid, int flags);
+static struct nfs4_delegation * find_delegation_stateid(struct inode *ino, stateid_t *stid);
/* Locking:
*
@@ -2056,6 +2057,32 @@ find_stateid(stateid_t *stid, int flags)
return NULL;
}
+static struct nfs4_delegation *
+find_delegation_stateid(struct inode *ino, stateid_t *stid)
+{
+ struct nfs4_delegation *dp = NULL;
+ struct nfs4_file *fp = NULL;
+ u32 st_id;
+ unsigned int fi_hashval;
+
+ dprintk("NFSD:find_delegation_stateid stateid=(%08x/%08x/%08x/%08x)\n",
+ stid->si_boot, stid->si_stateownerid,
+ stid->si_fileid, stid->si_generation);
+
+ if(!ino || !stid)
+ return NULL;
+ st_id = stid->si_stateownerid;
+ fi_hashval = file_hashval(ino);
+ if (find_file(fi_hashval, ino, &fp)) {
+ list_for_each_entry(dp, &fp->fi_del_perfile, dl_del_perfile) {
+ if(dp->dl_stateid.si_stateownerid == st_id) {
+ dprintk("NFSD: find_delegation dp %p\n",dp);
+ return dp;
+ }
+ }
+ }
+ return NULL;
+}
/*
* TODO: Linux file offsets are _signed_ 64-bit quantities, which means that
-------------------------------------------------------
SF email is sponsored by - The IT Product Guide
Read honest & candid reviews on hundreds of IT Products from real users.
Discover which products truly live up to the hype. Start reading now.
http://productguide.itmanagersjournal.com/
_______________________________________________
NFS maillist - NFS@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/nfs
^ permalink raw reply [flat|nested] 29+ messages in thread
* [PATCH kNFSd 17 of 23] Attempt to hand out a delegation
2004-12-17 5:23 [PATCH kNFSd 0 of 23] Introduction NeilBrown
` (16 preceding siblings ...)
2004-12-17 5:23 ` [PATCH kNFSd 10 of 23] Find a delegation for a file given a stateid NeilBrown
@ 2004-12-17 5:23 ` NeilBrown
2004-12-17 5:23 ` [PATCH kNFSd 19 of 23] Check for openmode violations given a delegation stateid NeilBrown
` (4 subsequent siblings)
22 siblings, 0 replies; 29+ messages in thread
From: NeilBrown @ 2004-12-17 5:23 UTC (permalink / raw)
To: Andrew Morton; +Cc: nfs
Signed-off-by: Andy Adamson <andros@citi.umich.edu>
Signed-off-by: Neil Brown <neilb@cse.unsw.edu.au>
### Diffstat output
./fs/nfsd/nfs4state.c | 59 ++++++++++++++++++++++++++++++++++++++++++++++++++
1 files changed, 59 insertions(+)
diff ./fs/nfsd/nfs4state.c~current~ ./fs/nfsd/nfs4state.c
--- ./fs/nfsd/nfs4state.c~current~ 2004-12-15 13:37:50.000000000 +1100
+++ ./fs/nfsd/nfs4state.c 2004-12-15 13:37:50.000000000 +1100
@@ -1642,6 +1642,65 @@ nfs4_set_claim_prev(struct nfsd4_open *o
}
/*
+ * Attempt to hand out a delegation.
+ */
+static void
+nfs4_open_delegation(struct svc_fh *fh, struct nfsd4_open *open, struct nfs4_stateid *stp, int *flag)
+{
+ struct nfs4_delegation *dp;
+ struct nfs4_stateowner *sop = stp->st_stateowner;
+ struct nfs4_callback *cb = &sop->so_client->cl_callback;
+ struct file_lock fl, *flp = &fl;
+ int status;
+
+ if (*flag == DONT_DELEGATE) {
+ *flag = NFS4_OPEN_DELEGATE_NONE;
+ return;
+ }
+
+ /* set flag */
+ *flag = NFS4_OPEN_DELEGATE_NONE;
+ if (open->op_claim_type != NFS4_OPEN_CLAIM_NULL
+ || !atomic_read(&cb->cb_set) || !sop->so_confirmed)
+ return;
+
+ if (!(open->op_share_access & NFS4_SHARE_ACCESS_WRITE))
+ *flag = NFS4_OPEN_DELEGATE_READ;
+
+ else if (!(open->op_share_access & NFS4_SHARE_ACCESS_READ))
+ *flag = NFS4_OPEN_DELEGATE_WRITE;
+
+ if (!(dp = alloc_init_deleg(sop->so_client, stp->st_file, fh, *flag)))
+ return;
+ locks_init_lock(&fl);
+ fl.fl_lmops = &nfsd_lease_mng_ops;
+ fl.fl_flags = FL_LEASE;
+ fl.fl_end = OFFSET_MAX;
+ fl.fl_owner = (fl_owner_t)dp;
+ fl.fl_file = stp->st_vfs_file;
+ fl.fl_pid = current->tgid;
+
+ if ((status = setlease(stp->st_vfs_file,
+ *flag == NFS4_OPEN_DELEGATE_READ? F_RDLCK: F_WRLCK, &flp))) {
+ dprintk("NFSD: setlease failed [%d], no delegation\n", status);
+ list_del(&dp->dl_del_perfile);
+ list_del(&dp->dl_del_perclnt);
+ kfree(dp);
+ free_delegation++;
+ *flag = NFS4_OPEN_DELEGATE_NONE;
+ return;
+ }
+
+ memcpy(&open->op_delegate_stateid, &dp->dl_stateid, sizeof(dp->dl_stateid));
+
+ dprintk("NFSD: delegation stateid=(%08x/%08x/%08x/%08x)\n\n",
+ dp->dl_stateid.si_boot,
+ dp->dl_stateid.si_stateownerid,
+ dp->dl_stateid.si_fileid,
+ dp->dl_stateid.si_generation);
+}
+
+/*
* called with nfs4_lock_state() held.
*/
int
-------------------------------------------------------
SF email is sponsored by - The IT Product Guide
Read honest & candid reviews on hundreds of IT Products from real users.
Discover which products truly live up to the hype. Start reading now.
http://productguide.itmanagersjournal.com/
_______________________________________________
NFS maillist - NFS@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/nfs
^ permalink raw reply [flat|nested] 29+ messages in thread
* [PATCH kNFSd 12 of 23] Changes to expire_client
2004-12-17 5:23 [PATCH kNFSd 0 of 23] Introduction NeilBrown
` (13 preceding siblings ...)
2004-12-17 5:23 ` [PATCH kNFSd 11 of 23] Add the delegation release and free functions NeilBrown
@ 2004-12-17 5:23 ` NeilBrown
2004-12-17 5:23 ` [PATCH kNFSd 8 of 23] Add structures for delegation support NeilBrown
` (7 subsequent siblings)
22 siblings, 0 replies; 29+ messages in thread
From: NeilBrown @ 2004-12-17 5:23 UTC (permalink / raw)
To: Andrew Morton; +Cc: nfs
... to shutdown the rpc callback client and remove all
client associated delegations
Signed-off-by: Andy Adamson <andros@citi.umich.edu>
Signed-off-by: Neil Brown <neilb@cse.unsw.edu.au>
### Diffstat output
./fs/nfsd/nfs4state.c | 23 ++++++++++++++++++++++-
1 files changed, 22 insertions(+), 1 deletion(-)
diff ./fs/nfsd/nfs4state.c~current~ ./fs/nfsd/nfs4state.c
--- ./fs/nfsd/nfs4state.c~current~ 2004-12-15 12:04:09.000000000 +1100
+++ ./fs/nfsd/nfs4state.c 2004-12-15 12:05:08.000000000 +1100
@@ -335,8 +335,29 @@ static void
expire_client(struct nfs4_client *clp)
{
struct nfs4_stateowner *sop;
+ struct nfs4_delegation *dp;
+ struct nfs4_callback *cb = &clp->cl_callback;
+ struct rpc_clnt *clnt = clp->cl_callback.cb_client;
+
+ dprintk("NFSD: expire_client cl_count %d\n",
+ atomic_read(&clp->cl_count));
- dprintk("NFSD: expire_client cl_count %d\n",atomic_read(&clp->cl_count));
+ /* shutdown rpc client, ending any outstanding recall rpcs */
+ if (atomic_read(&cb->cb_set) == 1 && clnt) {
+ rpc_shutdown_client(clnt);
+ clnt = clp->cl_callback.cb_client = NULL;
+ }
+ spin_lock(&recall_lock);
+ while (!list_empty(&clp->cl_del_perclnt)) {
+ dp = list_entry(clp->cl_del_perclnt.next, struct nfs4_delegation, dl_del_perclnt);
+ dprintk("NFSD: expire client. dp %p, dl_state %d, fp %p\n",
+ dp, atomic_read(&dp->dl_state), dp->dl_flock);
+
+ /* force release of delegation. */
+ atomic_set(&dp->dl_state, NFS4_RECALL_COMPLETE);
+ release_delegation(dp);
+ }
+ spin_unlock(&recall_lock);
list_del(&clp->cl_idhash);
list_del(&clp->cl_strhash);
list_del(&clp->cl_lru);
-------------------------------------------------------
SF email is sponsored by - The IT Product Guide
Read honest & candid reviews on hundreds of IT Products from real users.
Discover which products truly live up to the hype. Start reading now.
http://productguide.itmanagersjournal.com/
_______________________________________________
NFS maillist - NFS@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/nfs
^ permalink raw reply [flat|nested] 29+ messages in thread
* [PATCH kNFSd 18 of 23] Remove unnecessary stateowner existence check.
2004-12-17 5:23 [PATCH kNFSd 0 of 23] Introduction NeilBrown
` (11 preceding siblings ...)
2004-12-17 5:23 ` [PATCH kNFSd 13 of 23] Delay nfsd_colse for delegations until reaping NeilBrown
@ 2004-12-17 5:23 ` NeilBrown
2004-12-17 5:23 ` [PATCH kNFSd 11 of 23] Add the delegation release and free functions NeilBrown
` (9 subsequent siblings)
22 siblings, 0 replies; 29+ messages in thread
From: NeilBrown @ 2004-12-17 5:23 UTC (permalink / raw)
To: Andrew Morton; +Cc: nfs
At OPEN:
Check for delegations in the process of being recalled.
Attempt to hand out a delegation.
Signed-off-by: Andy Adamson <andros@citi.umich.edu>
Signed-off-by: Neil Brown <neilb@cse.unsw.edu.au>
### Diffstat output
./fs/nfsd/nfs4state.c | 36 +++++++++++++++++++-----------------
1 files changed, 19 insertions(+), 17 deletions(-)
diff ./fs/nfsd/nfs4state.c~current~ ./fs/nfsd/nfs4state.c
--- ./fs/nfsd/nfs4state.c~current~ 2004-12-15 13:37:50.000000000 +1100
+++ ./fs/nfsd/nfs4state.c 2004-12-15 13:37:51.000000000 +1100
@@ -1708,28 +1708,24 @@ nfsd4_process_open2(struct svc_rqst *rqs
{
struct nfs4_stateowner *sop = open->op_stateowner;
struct nfs4_file *fp = NULL;
- struct inode *ino;
+ struct inode *ino = current_fh->fh_dentry->d_inode;
unsigned int fi_hashval;
struct nfs4_stateid *stp = NULL;
- int status;
-
- status = nfserr_resource;
- if (!sop)
- return status;
-
- ino = current_fh->fh_dentry->d_inode;
+ int status, delegflag = 0;
status = nfserr_inval;
if (!TEST_ACCESS(open->op_share_access) || !TEST_DENY(open->op_share_deny))
goto out;
/*
- * Lookup file; if found, lookup stateid and check open request;
- * not found, create
+ * Lookup file; if found, lookup stateid and check open request,
+ * and check for delegations in the process of being recalled.
+ * If not found, create the nfs4_file struct
*/
fi_hashval = file_hashval(ino);
if (find_file(fi_hashval, ino, &fp)) {
- status = nfs4_check_open(fp, sop, open, &stp);
- if (status)
+ if ((status = nfs4_check_open(fp, sop, open, &stp)))
+ goto out;
+ if ((status = nfs4_check_deleg_recall(fp, open, &delegflag)))
goto out;
} else {
status = nfserr_resource;
@@ -1769,14 +1765,20 @@ nfsd4_process_open2(struct svc_rqst *rqs
}
}
}
- dprintk("nfs4_process_open2: stateid=(%08x/%08x/%08x/%08x)\n",
- stp->st_stateid.si_boot, stp->st_stateid.si_stateownerid,
- stp->st_stateid.si_fileid, stp->st_stateid.si_generation);
-
memcpy(&open->op_stateid, &stp->st_stateid, sizeof(stateid_t));
- open->op_delegate_type = NFS4_OPEN_DELEGATE_NONE;
+ /*
+ * Attempt to hand out a delegation. No error return, because the
+ * OPEN succeeds even if we fail.
+ */
+ nfs4_open_delegation(current_fh, open, stp, &delegflag);
+ open->op_delegate_type = delegflag;
+
status = nfs_ok;
+
+ dprintk("nfs4_process_open2: stateid=(%08x/%08x/%08x/%08x)\n",
+ stp->st_stateid.si_boot, stp->st_stateid.si_stateownerid,
+ stp->st_stateid.si_fileid, stp->st_stateid.si_generation);
out:
/* take the opportunity to clean up unused state */
if (fp && list_empty(&fp->fi_perfile))
-------------------------------------------------------
SF email is sponsored by - The IT Product Guide
Read honest & candid reviews on hundreds of IT Products from real users.
Discover which products truly live up to the hype. Start reading now.
http://productguide.itmanagersjournal.com/
_______________________________________________
NFS maillist - NFS@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/nfs
^ permalink raw reply [flat|nested] 29+ messages in thread
* [PATCH kNFSd 15 of 23] Kernel thread for delegation callback
2004-12-17 5:23 [PATCH kNFSd 0 of 23] Introduction NeilBrown
` (8 preceding siblings ...)
2004-12-17 5:23 ` [PATCH kNFSd 16 of 23] Helper functions for deciding to grant a delegation NeilBrown
@ 2004-12-17 5:23 ` NeilBrown
2004-12-17 5:23 ` [PATCH kNFSd 9 of 23] Allocate and initialize the delegation structure NeilBrown
` (12 subsequent siblings)
22 siblings, 0 replies; 29+ messages in thread
From: NeilBrown @ 2004-12-17 5:23 UTC (permalink / raw)
To: Andrew Morton; +Cc: nfs
Any task can call break_lease or time_out_leases
on a v4 delegated file which results in a recall callback rpc sent to the
NFSv4 client holding the delegation, and/or the FL_LEASE to be removed.
Spawn a kernel thread to perform the callback.
Signed-off-by: Andy Adamson <andros@citi.umich.edu>
Signed-off-by: Neil Brown <neilb@cse.unsw.edu.au>
### Diffstat output
./fs/nfsd/nfs4state.c | 96 ++++++++++++++++++++++++++++++++++++++++++++++++++
1 files changed, 96 insertions(+)
diff ./fs/nfsd/nfs4state.c~current~ ./fs/nfsd/nfs4state.c
--- ./fs/nfsd/nfs4state.c~current~ 2004-12-15 13:37:21.000000000 +1100
+++ ./fs/nfsd/nfs4state.c 2004-12-15 13:37:36.000000000 +1100
@@ -44,6 +44,7 @@
#include <linux/mount.h>
#include <linux/workqueue.h>
#include <linux/smp_lock.h>
+#include <linux/kthread.h>
#include <linux/nfs4.h>
#include <linux/nfsd/state.h>
#include <linux/nfsd/xdr4.h>
@@ -1311,6 +1312,101 @@ nfs4_file_downgrade(struct file *filp, u
}
}
+/*
+ * Recall a delegation
+ */
+static int
+do_recall(void *__dp)
+{
+ struct nfs4_delegation *dp = __dp;
+
+ daemonize("nfsv4-recall");
+
+ atomic_inc(&dp->dl_count);
+ nfsd4_cb_recall(dp);
+ return 0;
+}
+
+/*
+ * Spawn a thread to perform a recall on the delegation represented
+ * by the lease (file_lock)
+ *
+ * Called from break_lease() with lock_kernel() held,
+ *
+ */
+static
+void nfsd_break_deleg_cb(struct file_lock *fl)
+{
+ struct nfs4_delegation *dp= (struct nfs4_delegation *)fl->fl_owner;
+ struct task_struct *t;
+
+ dprintk("NFSD nfsd_break_deleg_cb: dp %p fl %p\n",dp,fl);
+ if (!dp)
+ return;
+
+ /* schedule delegation for recall */
+ spin_lock(&recall_lock);
+ atomic_set(&dp->dl_state, NFS4_RECALL_IN_PROGRESS);
+ list_add_tail(&dp->dl_recall_lru, &del_recall_lru);
+ spin_unlock(&recall_lock);
+
+ /* only place dl_time is set. protected by lock_kernel*/
+ dp->dl_time = get_seconds();
+
+ /* XXX need to merge NFSD_LEASE_TIME with fs/locks.c:lease_break_time */
+ fl->fl_break_time = jiffies + NFSD_LEASE_TIME * HZ;
+
+ t = kthread_run(do_recall, dp, "%s", "nfs4_cb_recall");
+ if (IS_ERR(t)) {
+ struct nfs4_client *clp = dp->dl_client;
+
+ printk(KERN_INFO "NFSD: Callback thread failed for "
+ "for client (clientid %08x/%08x)\n",
+ clp->cl_clientid.cl_boot, clp->cl_clientid.cl_id);
+ }
+}
+
+/*
+ * The file_lock is being reapd.
+ *
+ * Called by locks_free_lock() with lock_kernel() held.
+ */
+static
+void nfsd_release_deleg_cb(struct file_lock *fl)
+{
+ struct nfs4_delegation *dp = (struct nfs4_delegation *)fl->fl_owner;
+
+ dprintk("NFSD nfsd_release_deleg_cb: fl %p dp %p dl_count %d, dl_state %d\n", fl,dp, atomic_read(&dp->dl_count), atomic_read(&dp->dl_state));
+
+ if (!(fl->fl_flags & FL_LEASE) || !dp)
+ return;
+ atomic_set(&dp->dl_state,NFS4_RECALL_COMPLETE);
+ dp->dl_flock = NULL;
+}
+
+/*
+ * Set the delegation file_lock back pointer.
+ *
+ * Called from __setlease() with lock_kernel() held.
+ */
+static
+void nfsd_copy_lock_deleg_cb(struct file_lock *new, struct file_lock *fl)
+{
+ struct nfs4_delegation *dp = (struct nfs4_delegation *)new->fl_owner;
+
+ dprintk("NFSD: nfsd_copy_lock_deleg_cb: new fl %p dp %p\n", new, dp);
+ if (!dp)
+ return;
+ dp->dl_flock = new;
+}
+
+struct lock_manager_operations nfsd_lease_mng_ops = {
+ .fl_break = nfsd_break_deleg_cb,
+ .fl_release_private = nfsd_release_deleg_cb,
+ .fl_copy_lock = nfsd_copy_lock_deleg_cb,
+};
+
+
/*
* nfsd4_process_open1()
-------------------------------------------------------
SF email is sponsored by - The IT Product Guide
Read honest & candid reviews on hundreds of IT Products from real users.
Discover which products truly live up to the hype. Start reading now.
http://productguide.itmanagersjournal.com/
_______________________________________________
NFS maillist - NFS@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/nfs
^ permalink raw reply [flat|nested] 29+ messages in thread
* [PATCH kNFSd 8 of 23] Add structures for delegation support
2004-12-17 5:23 [PATCH kNFSd 0 of 23] Introduction NeilBrown
` (14 preceding siblings ...)
2004-12-17 5:23 ` [PATCH kNFSd 12 of 23] Changes to expire_client NeilBrown
@ 2004-12-17 5:23 ` NeilBrown
2004-12-17 5:23 ` [PATCH kNFSd 10 of 23] Find a delegation for a file given a stateid NeilBrown
` (6 subsequent siblings)
22 siblings, 0 replies; 29+ messages in thread
From: NeilBrown @ 2004-12-17 5:23 UTC (permalink / raw)
To: Andrew Morton; +Cc: nfs
Signed-off-by: Andy Adamson <andros@citi.umich.edu>
Signed-off-by: Neil Brown <neilb@cse.unsw.edu.au>
### Diffstat output
./include/linux/nfsd/state.h | 37 +++++++++++++++++++++++++++++++++++++
1 files changed, 37 insertions(+)
diff ./include/linux/nfsd/state.h~current~ ./include/linux/nfsd/state.h
--- ./include/linux/nfsd/state.h~current~ 2004-12-15 11:51:29.000000000 +1100
+++ ./include/linux/nfsd/state.h 2004-12-15 11:59:23.000000000 +1100
@@ -67,6 +67,41 @@ extern stateid_t onestateid;
#define ZERO_STATEID(stateid) (!memcmp((stateid), &zerostateid, sizeof(stateid_t)))
#define ONE_STATEID(stateid) (!memcmp((stateid), &onestateid, sizeof(stateid_t)))
+/* Delegation recall states */
+#define NFS4_NO_RECALL 0x000
+#define NFS4_RECALL_IN_PROGRESS 0x001
+#define NFS4_RECALL_COMPLETE 0x002
+#define NFS4_REAP_DELEG 0x004
+
+struct nfs4_cb_recall {
+ u32 cbr_ident;
+ int cbr_trunc;
+ stateid_t cbr_stateid;
+ u32 cbr_fhlen;
+ u32 cbr_fhval[NFS4_FHSIZE];
+ struct nfs4_delegation *cbr_dp;
+};
+
+struct nfs4_delegation {
+ struct list_head dl_del_perfile; /* nfs4_file->fi_del_perfile */
+ struct list_head dl_del_perclnt; /* nfs4_client->cl_del_perclnt*/
+ struct list_head dl_recall_lru; /* delegation recalled */
+ atomic_t dl_recall_cnt; /* resend cb_recall only once */
+ atomic_t dl_count; /* ref count */
+ atomic_t dl_state; /* recall state */
+ struct nfs4_client *dl_client;
+ struct nfs4_file *dl_file;
+ struct file_lock *dl_flock;
+ struct nfs4_stateid *dl_stp;
+ u32 dl_type;
+ time_t dl_time;
+ struct nfs4_cb_recall dl_recall;
+};
+
+#define dl_stateid dl_recall.cbr_stateid
+#define dl_fhlen dl_recall.cbr_fhlen
+#define dl_fhval dl_recall.cbr_fhval
+
/* client delegation callback info */
struct nfs4_callback {
/* SETCLIENTID info */
@@ -96,6 +131,7 @@ struct nfs4_client {
struct list_head cl_idhash; /* hash by cl_clientid.id */
struct list_head cl_strhash; /* hash by cl_name */
struct list_head cl_perclient; /* list: stateowners */
+ struct list_head cl_del_perclnt; /* list: delegations */
struct list_head cl_lru; /* tail queue */
struct xdr_netobj cl_name; /* id generated by client */
nfs4_verifier cl_verifier; /* generated by client */
@@ -194,6 +230,7 @@ struct nfs4_stateowner {
struct nfs4_file {
struct list_head fi_hash; /* hash by "struct inode *" */
struct list_head fi_perfile; /* list: nfs4_stateid */
+ struct list_head fi_del_perfile; /* list: nfs4_delegation */
struct inode *fi_inode;
u32 fi_id; /* used with stateowner->so_id
* for stateid_hashtbl hash */
-------------------------------------------------------
SF email is sponsored by - The IT Product Guide
Read honest & candid reviews on hundreds of IT Products from real users.
Discover which products truly live up to the hype. Start reading now.
http://productguide.itmanagersjournal.com/
_______________________________________________
NFS maillist - NFS@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/nfs
^ permalink raw reply [flat|nested] 29+ messages in thread
* [PATCH kNFSd 13 of 23] Delay nfsd_colse for delegations until reaping
2004-12-17 5:23 [PATCH kNFSd 0 of 23] Introduction NeilBrown
` (10 preceding siblings ...)
2004-12-17 5:23 ` [PATCH kNFSd 9 of 23] Allocate and initialize the delegation structure NeilBrown
@ 2004-12-17 5:23 ` NeilBrown
2004-12-17 5:23 ` [PATCH kNFSd 18 of 23] Remove unnecessary stateowner existence check NeilBrown
` (10 subsequent siblings)
22 siblings, 0 replies; 29+ messages in thread
From: NeilBrown @ 2004-12-17 5:23 UTC (permalink / raw)
To: Andrew Morton; +Cc: nfs
Because nfsd_close() can call locks_remove_flock() which removes leases,
delay nfsd_close() for delegations until the delegation is reaped.
Don't release an nfs4_file struct with delegations.
Signed-off-by: Andy Adamson <andros@citi.umich.edu>
Signed-off-by: Neil Brown <neilb@cse.unsw.edu.au>
### Diffstat output
./fs/nfsd/nfs4state.c | 21 ++++++++++++++++++---
1 files changed, 18 insertions(+), 3 deletions(-)
diff ./fs/nfsd/nfs4state.c~current~ ./fs/nfsd/nfs4state.c
--- ./fs/nfsd/nfs4state.c~current~ 2004-12-15 12:05:08.000000000 +1100
+++ ./fs/nfsd/nfs4state.c 2004-12-15 13:18:49.000000000 +1100
@@ -977,7 +977,7 @@ release_all_files(void)
while (!list_empty(&file_hashtbl[i])) {
fp = list_entry(file_hashtbl[i].next, struct nfs4_file, fi_hash);
/* this should never be more than once... */
- if (!list_empty(&fp->fi_perfile)) {
+ if (!list_empty(&fp->fi_perfile) || !list_empty(&fp->fi_del_perfile)) {
printk("ERROR: release_all_files: file %p is open, creating dangling state !!!\n",fp);
}
release_file(fp);
@@ -1112,14 +1112,29 @@ init_stateid(struct nfs4_stateid *stp, s
__set_bit(open->op_share_deny, &stp->st_deny_bmap);
}
+/*
+* Because nfsd_close() can call locks_remove_flock() which removes leases,
+* delay nfsd_close() for delegations from the nfsd_open() clientid
+* until the delegation is reaped.
+*/
static void
-release_stateid(struct nfs4_stateid *stp, int flags) {
+release_stateid(struct nfs4_stateid *stp, int flags)
+{
+ struct nfs4_delegation *dp;
+ struct nfs4_file *fp = stp->st_file;
list_del(&stp->st_hash);
list_del_perfile++;
list_del(&stp->st_perfile);
list_del(&stp->st_perfilestate);
if ((stp->st_vfs_set) && (flags & OPEN_STATE)) {
+ list_for_each_entry(dp, &fp->fi_del_perfile, dl_del_perfile) {
+ if(cmp_clid(&dp->dl_client->cl_clientid,
+ &stp->st_stateowner->so_client->cl_clientid)) {
+ dp->dl_stp = stp;
+ return;
+ }
+ }
release_stateid_lockowner(stp);
nfsd_close(stp->st_vfs_file);
vfsclose++;
@@ -1168,7 +1183,7 @@ release_state_owner(struct nfs4_stateid
if (sop->so_confirmed && list_empty(&sop->so_perfilestate))
move_to_close_lru(sop);
/* unused nfs4_file's are releseed. XXX slab cache? */
- if (list_empty(&fp->fi_perfile)) {
+ if (list_empty(&fp->fi_perfile) && list_empty(&fp->fi_del_perfile)) {
release_file(fp);
}
}
-------------------------------------------------------
SF email is sponsored by - The IT Product Guide
Read honest & candid reviews on hundreds of IT Products from real users.
Discover which products truly live up to the hype. Start reading now.
http://productguide.itmanagersjournal.com/
_______________________________________________
NFS maillist - NFS@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/nfs
^ permalink raw reply [flat|nested] 29+ messages in thread
* [PATCH kNFSd 14 of 23] Delegation recall callback rpc.
2004-12-17 5:23 [PATCH kNFSd 0 of 23] Introduction NeilBrown
` (6 preceding siblings ...)
2004-12-17 5:23 ` [PATCH kNFSd 2 of 23] Check the callback netid in gen_callback NeilBrown
@ 2004-12-17 5:23 ` NeilBrown
2004-12-17 5:23 ` [PATCH kNFSd 16 of 23] Helper functions for deciding to grant a delegation NeilBrown
` (14 subsequent siblings)
22 siblings, 0 replies; 29+ messages in thread
From: NeilBrown @ 2004-12-17 5:23 UTC (permalink / raw)
To: Andrew Morton; +Cc: nfs
Signed-off-by: Andy Adamson <andros@citi.umich.edu>
Signed-off-by: Neil Brown <neilb@cse.unsw.edu.au>
### Diffstat output
./fs/nfsd/nfs4callback.c | 316 ++++++++++++++++++++++++++++++++++++++++++-
./include/linux/nfsd/state.h | 1
2 files changed, 316 insertions(+), 1 deletion(-)
diff ./fs/nfsd/nfs4callback.c~current~ ./fs/nfsd/nfs4callback.c
--- ./fs/nfsd/nfs4callback.c~current~ 2004-12-15 11:51:29.000000000 +1100
+++ ./fs/nfsd/nfs4callback.c 2004-12-15 13:19:50.000000000 +1100
@@ -49,24 +49,58 @@
#define NFSDDBG_FACILITY NFSDDBG_PROC
#define NFSPROC4_CB_NULL 0
+#define NFSPROC4_CB_COMPOUND 1
-/* forward declarations */
+/* declarations */
static void nfs4_cb_null(struct rpc_task *task);
+extern spinlock_t recall_lock;
/* Index of predefined Linux callback client operations */
enum {
NFSPROC4_CLNT_CB_NULL = 0,
+ NFSPROC4_CLNT_CB_RECALL,
+};
+
+enum nfs_cb_opnum4 {
+ OP_CB_RECALL = 4,
};
#define NFS4_MAXTAGLEN 20
#define NFS4_enc_cb_null_sz 0
#define NFS4_dec_cb_null_sz 0
+#define cb_compound_enc_hdr_sz 4
+#define cb_compound_dec_hdr_sz (3 + (NFS4_MAXTAGLEN >> 2))
+#define op_enc_sz 1
+#define op_dec_sz 2
+#define enc_nfs4_fh_sz (1 + (NFS4_FHSIZE >> 2))
+#define enc_stateid_sz 16
+#define NFS4_enc_cb_recall_sz (cb_compound_enc_hdr_sz + \
+ 1 + enc_stateid_sz + \
+ enc_nfs4_fh_sz)
+
+#define NFS4_dec_cb_recall_sz (cb_compound_dec_hdr_sz + \
+ op_dec_sz)
/*
* Generic encode routines from fs/nfs/nfs4xdr.c
*/
+static inline u32 *
+xdr_writemem(u32 *p, const void *ptr, int nbytes)
+{
+ int tmp = XDR_QUADLEN(nbytes);
+ if (!tmp)
+ return p;
+ p[tmp-1] = 0;
+ memcpy(p, ptr, nbytes);
+ return p + tmp;
+}
+
+#define WRITE32(n) *p++ = htonl(n)
+#define WRITEMEM(ptr,nbytes) do { \
+ p = xdr_writemem(p, ptr, nbytes); \
+} while (0)
#define RESERVE_SPACE(nbytes) do { \
p = xdr_reserve_space(xdr, nbytes); \
if (!p) dprintk("NFSD: RESERVE_SPACE(%d) failed in function %s\n", (int) (nbytes), __FUNCTION__); \
@@ -74,10 +108,130 @@ enum {
} while (0)
/*
+ * Generic decode routines from fs/nfs/nfs4xdr.c
+ */
+#define DECODE_TAIL \
+ status = 0; \
+out: \
+ return status; \
+xdr_error: \
+ dprintk("NFSD: xdr error! (%s:%d)\n", __FILE__, __LINE__); \
+ status = -EIO; \
+ goto out
+
+#define READ32(x) (x) = ntohl(*p++)
+#define READ64(x) do { \
+ (x) = (u64)ntohl(*p++) << 32; \
+ (x) |= ntohl(*p++); \
+} while (0)
+#define READTIME(x) do { \
+ p++; \
+ (x.tv_sec) = ntohl(*p++); \
+ (x.tv_nsec) = ntohl(*p++); \
+} while (0)
+#define READ_BUF(nbytes) do { \
+ p = xdr_inline_decode(xdr, nbytes); \
+ if (!p) { \
+ dprintk("NFSD: %s: reply buffer overflowed in line %d.", \
+ __FUNCTION__, __LINE__); \
+ return -EIO; \
+ } \
+} while (0)
+
+struct nfs4_cb_compound_hdr {
+ int status;
+ u32 ident;
+ u32 nops;
+ u32 taglen;
+ char * tag;
+};
+
+static struct {
+int stat;
+int errno;
+} nfs_cb_errtbl[] = {
+ { NFS4_OK, 0 },
+ { NFS4ERR_PERM, EPERM },
+ { NFS4ERR_NOENT, ENOENT },
+ { NFS4ERR_IO, EIO },
+ { NFS4ERR_NXIO, ENXIO },
+ { NFS4ERR_ACCESS, EACCES },
+ { NFS4ERR_EXIST, EEXIST },
+ { NFS4ERR_XDEV, EXDEV },
+ { NFS4ERR_NOTDIR, ENOTDIR },
+ { NFS4ERR_ISDIR, EISDIR },
+ { NFS4ERR_INVAL, EINVAL },
+ { NFS4ERR_FBIG, EFBIG },
+ { NFS4ERR_NOSPC, ENOSPC },
+ { NFS4ERR_ROFS, EROFS },
+ { NFS4ERR_MLINK, EMLINK },
+ { NFS4ERR_NAMETOOLONG, ENAMETOOLONG },
+ { NFS4ERR_NOTEMPTY, ENOTEMPTY },
+ { NFS4ERR_DQUOT, EDQUOT },
+ { NFS4ERR_STALE, ESTALE },
+ { NFS4ERR_BADHANDLE, EBADHANDLE },
+ { NFS4ERR_BAD_COOKIE, EBADCOOKIE },
+ { NFS4ERR_NOTSUPP, ENOTSUPP },
+ { NFS4ERR_TOOSMALL, ETOOSMALL },
+ { NFS4ERR_SERVERFAULT, ESERVERFAULT },
+ { NFS4ERR_BADTYPE, EBADTYPE },
+ { NFS4ERR_LOCKED, EAGAIN },
+ { NFS4ERR_RESOURCE, EREMOTEIO },
+ { NFS4ERR_SYMLINK, ELOOP },
+ { NFS4ERR_OP_ILLEGAL, EOPNOTSUPP },
+ { NFS4ERR_DEADLOCK, EDEADLK },
+ { -1, EIO }
+};
+
+static int
+nfs_cb_stat_to_errno(int stat)
+{
+ int i;
+ for (i = 0; nfs_cb_errtbl[i].stat != -1; i++) {
+ if (nfs_cb_errtbl[i].stat == stat)
+ return nfs_cb_errtbl[i].errno;
+ }
+ /* If we cannot translate the error, the recovery routines should
+ * handle it.
+ * Note: remaining NFSv4 error codes have values > 10000, so should
+ * not conflict with native Linux error codes.
+ */
+ return stat;
+}
+
+/*
* XDR encode
*/
static int
+encode_cb_compound_hdr(struct xdr_stream *xdr, struct nfs4_cb_compound_hdr *hdr)
+{
+ u32 * p;
+
+ RESERVE_SPACE(16);
+ WRITE32(0); /* tag length is always 0 */
+ WRITE32(NFS4_MINOR_VERSION);
+ WRITE32(hdr->ident);
+ WRITE32(hdr->nops);
+ return 0;
+}
+
+static int
+encode_cb_recall(struct xdr_stream *xdr, struct nfs4_cb_recall *cb_rec)
+{
+ u32 *p;
+ int len = cb_rec->cbr_fhlen;
+
+ RESERVE_SPACE(12+sizeof(cb_rec->cbr_stateid) + len);
+ WRITE32(OP_CB_RECALL);
+ WRITEMEM(&cb_rec->cbr_stateid, sizeof(stateid_t));
+ WRITE32(cb_rec->cbr_trunc);
+ WRITE32(len);
+ WRITEMEM(cb_rec->cbr_fhval, len);
+ return 0;
+}
+
+static int
nfs4_xdr_enc_cb_null(struct rpc_rqst *req, u32 *p)
{
struct xdr_stream xdrs, *xdr = &xdrs;
@@ -88,11 +242,76 @@ nfs4_xdr_enc_cb_null(struct rpc_rqst *re
}
static int
+nfs4_xdr_enc_cb_recall(struct rpc_rqst *req, u32 *p, struct nfs4_cb_recall *args)
+{
+ struct xdr_stream xdr;
+ struct nfs4_cb_compound_hdr hdr = {
+ .nops = 1,
+ };
+
+ xdr_init_encode(&xdr, &req->rq_snd_buf, p);
+ encode_cb_compound_hdr(&xdr, &hdr);
+ return (encode_cb_recall(&xdr, args));
+}
+
+
+static int
+decode_cb_compound_hdr(struct xdr_stream *xdr, struct nfs4_cb_compound_hdr *hdr){
+ u32 *p;
+
+ READ_BUF(8);
+ READ32(hdr->status);
+ READ32(hdr->taglen);
+ READ_BUF(hdr->taglen + 4);
+ hdr->tag = (char *)p;
+ p += XDR_QUADLEN(hdr->taglen);
+ READ32(hdr->nops);
+ return 0;
+}
+
+static int
+decode_cb_op_hdr(struct xdr_stream *xdr, enum nfs_opnum4 expected)
+{
+ u32 *p;
+ u32 op;
+ int32_t nfserr;
+
+ READ_BUF(8);
+ READ32(op);
+ if (op != expected) {
+ dprintk("NFSD: decode_cb_op_hdr: Callback server returned "
+ " operation %d but we issued a request for %d\n",
+ op, expected);
+ return -EIO;
+ }
+ READ32(nfserr);
+ if (nfserr != NFS_OK)
+ return -nfs_cb_stat_to_errno(nfserr);
+ return 0;
+}
+
+static int
nfs4_xdr_dec_cb_null(struct rpc_rqst *req, u32 *p)
{
return 0;
}
+static int
+nfs4_xdr_dec_cb_recall(struct rpc_rqst *rqstp, u32 *p)
+{
+ struct xdr_stream xdr;
+ struct nfs4_cb_compound_hdr hdr;
+ int status;
+
+ xdr_init_decode(&xdr, &rqstp->rq_rcv_buf, p);
+ status = decode_cb_compound_hdr(&xdr, &hdr);
+ if (status)
+ goto out;
+ status = decode_cb_op_hdr(&xdr, OP_CB_RECALL);
+out :
+ return status;
+}
+
/*
* RPC procedure tables
*/
@@ -110,6 +329,7 @@ nfs4_xdr_dec_cb_null(struct rpc_rqst *re
struct rpc_procinfo nfs4_cb_procedures[] = {
PROC(CB_NULL, NULL, enc_cb_null, dec_cb_null),
+ PROC(CB_RECALL, COMPOUND, enc_cb_recall, dec_cb_recall),
};
struct rpc_version nfs_cb_version4 = {
@@ -267,3 +487,97 @@ nfs4_cb_null(struct rpc_task *task)
out:
put_nfs4_client(clp);
}
+
+/*
+ * Called with dp->dl_count incremented
+ */
+static void
+nfs4_cb_recall_done(struct rpc_task *task)
+{
+ struct nfs4_cb_recall *cbr = (struct nfs4_cb_recall *)task->tk_calldata;
+ struct nfs4_delegation *dp = cbr->cbr_dp;
+ int status;
+
+ /* all is well... */
+ if (task->tk_status == 0)
+ goto out;
+
+ /* network partition, retry nfsd4_cb_recall once. */
+ if (task->tk_status == -EIO) {
+ if (atomic_read(&dp->dl_recall_cnt) == 0)
+ goto retry;
+ else
+ /* callback channel no longer available */
+ atomic_set(&dp->dl_client->cl_callback.cb_set, 0);
+ }
+
+ /* Race: a recall occurred miliseconds after a delegation was granted.
+ * Client may have received recall prior to delegation. retry recall
+ * once.
+ */
+ if ((task->tk_status == -EBADHANDLE) || (task->tk_status == -NFS4ERR_BAD_STATEID)){
+ if (atomic_read(&dp->dl_recall_cnt) == 0)
+ goto retry;
+ }
+ atomic_set(&dp->dl_state, NFS4_RECALL_COMPLETE);
+
+out:
+ if (atomic_dec_and_test(&dp->dl_count))
+ atomic_set(&dp->dl_state, NFS4_REAP_DELEG);
+ BUG_ON(atomic_read(&dp->dl_count) < 0);
+ dprintk("NFSD: nfs4_cb_recall_done: dp %p dl_flock %p dl_count %d\n",dp, dp->dl_flock, atomic_read(&dp->dl_count));
+ return;
+
+retry:
+ atomic_inc(&dp->dl_recall_cnt);
+ /* sleep 2 seconds before retrying recall */
+ set_current_state(TASK_UNINTERRUPTIBLE);
+ schedule_timeout(2*HZ);
+ status = nfsd4_cb_recall(dp);
+ dprintk("NFSD: nfs4_cb_recall_done: retry status: %d dp %p dl_flock %p\n",status,dp, dp->dl_flock);
+}
+
+/*
+ * called with dp->dl_count inc'ed.
+ * nfs4_lock_state() may or may not have been called.
+ */
+int
+nfsd4_cb_recall(struct nfs4_delegation *dp)
+{
+ struct nfs4_client *clp;
+ struct rpc_clnt *clnt;
+ struct rpc_message msg = {
+ .rpc_proc = &nfs4_cb_procedures[NFSPROC4_CLNT_CB_RECALL],
+ };
+ struct nfs4_cb_recall *cbr = &dp->dl_recall;
+ int status;
+
+ dprintk("NFSD: nfsd4_cb_recall NFS4_enc_cb_recall_sz %d NFS4_dec_cb_recall_sz %d \n",NFS4_enc_cb_recall_sz,NFS4_dec_cb_recall_sz);
+
+ clp = dp->dl_client;
+ clnt = clp->cl_callback.cb_client;
+ status = EIO;
+ if ((!atomic_read(&clp->cl_callback.cb_set)) || !clnt)
+ goto out_free;
+
+ msg.rpc_argp = cbr;
+ msg.rpc_resp = cbr;
+ msg.rpc_cred = nfsd4_lookupcred(clp,0);
+
+ cbr->cbr_trunc = 0; /* XXX need to implement truncate optimization */
+ cbr->cbr_dp = dp;
+
+ if ((status = rpc_call_async(clnt, &msg, RPC_TASK_SOFT,
+ nfs4_cb_recall_done, cbr ))) {
+ dprintk("NFSD: recall_delegation: rpc_call_async failed %d\n",
+ status);
+ goto out_fail;
+ }
+out:
+ return status;
+out_fail:
+ status = nfserrno(status);
+ out_free:
+ kfree(cbr);
+ goto out;
+}
diff ./include/linux/nfsd/state.h~current~ ./include/linux/nfsd/state.h
--- ./include/linux/nfsd/state.h~current~ 2004-12-15 11:59:23.000000000 +1100
+++ ./include/linux/nfsd/state.h 2004-12-15 13:19:50.000000000 +1100
@@ -291,6 +291,7 @@ extern int nfs4_check_open_reclaim(clien
extern void put_nfs4_client(struct nfs4_client *clp);
extern void nfs4_free_stateowner(struct kref *kref);
extern void nfsd4_probe_callback(struct nfs4_client *clp);
+extern int nfsd4_cb_recall(struct nfs4_delegation *dp);
static inline void
nfs4_put_stateowner(struct nfs4_stateowner *so)
-------------------------------------------------------
SF email is sponsored by - The IT Product Guide
Read honest & candid reviews on hundreds of IT Products from real users.
Discover which products truly live up to the hype. Start reading now.
http://productguide.itmanagersjournal.com/
_______________________________________________
NFS maillist - NFS@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/nfs
^ permalink raw reply [flat|nested] 29+ messages in thread
* [PATCH kNFSd 19 of 23] Check for openmode violations given a delegation stateid.
2004-12-17 5:23 [PATCH kNFSd 0 of 23] Introduction NeilBrown
` (17 preceding siblings ...)
2004-12-17 5:23 ` [PATCH kNFSd 17 of 23] Attempt to hand out a delegation NeilBrown
@ 2004-12-17 5:23 ` NeilBrown
2004-12-17 5:23 ` [PATCH kNFSd 22 of 23] Add to the laundromat service for delegations NeilBrown
` (3 subsequent siblings)
22 siblings, 0 replies; 29+ messages in thread
From: NeilBrown @ 2004-12-17 5:23 UTC (permalink / raw)
To: Andrew Morton; +Cc: nfs
Signed-off-by: Andy Adamson <andros@citi.umich.edu>
Signed-off-by: Neil Brown <neilb@cse.unsw.edu.au>
### Diffstat output
./fs/nfsd/nfs4state.c | 14 ++++++++++++++
1 files changed, 14 insertions(+)
diff ./fs/nfsd/nfs4state.c~current~ ./fs/nfsd/nfs4state.c
--- ./fs/nfsd/nfs4state.c~current~ 2004-12-15 13:37:51.000000000 +1100
+++ ./fs/nfsd/nfs4state.c 2004-12-15 13:37:51.000000000 +1100
@@ -1956,6 +1956,20 @@ out:
return status;
}
+static int
+nfs4_check_delegmode(struct nfs4_delegation *dp, int flags)
+{
+ int status = nfserr_openmode;
+
+ if ((flags & WR_STATE) & (dp->dl_type == NFS4_OPEN_DELEGATE_READ))
+ goto out;
+ if ((flags & RD_STATE) & (dp->dl_type == NFS4_OPEN_DELEGATE_WRITE))
+ goto out;
+ status = nfs_ok;
+out:
+ return status;
+}
+
/*
* Checks for stateid operations
*/
-------------------------------------------------------
SF email is sponsored by - The IT Product Guide
Read honest & candid reviews on hundreds of IT Products from real users.
Discover which products truly live up to the hype. Start reading now.
http://productguide.itmanagersjournal.com/
_______________________________________________
NFS maillist - NFS@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/nfs
^ permalink raw reply [flat|nested] 29+ messages in thread
* [PATCH kNFSd 23 of 23] Clear the recall_lru of delegations at shutdown
2004-12-17 5:23 [PATCH kNFSd 0 of 23] Introduction NeilBrown
` (20 preceding siblings ...)
2004-12-17 5:23 ` [PATCH kNFSd 20 of 23] Add checking of delegation stateids to nfs4_preprocess_stateid_op NeilBrown
@ 2004-12-17 5:23 ` NeilBrown
2004-12-17 5:23 ` [PATCH kNFSd 21 of 23] Add the DELEGRETURN operation NeilBrown
22 siblings, 0 replies; 29+ messages in thread
From: NeilBrown @ 2004-12-17 5:23 UTC (permalink / raw)
To: Andrew Morton; +Cc: nfs
Signed-off-by: Andy Adamson <andros@citi.umich.edu>
Signed-off-by: Neil Brown <neilb@cse.unsw.edu.au>
### Diffstat output
./fs/nfsd/nfs4state.c | 10 ++++++++++
1 files changed, 10 insertions(+)
diff ./fs/nfsd/nfs4state.c~current~ ./fs/nfsd/nfs4state.c
--- ./fs/nfsd/nfs4state.c~current~ 2004-12-15 13:37:51.000000000 +1100
+++ ./fs/nfsd/nfs4state.c 2004-12-15 13:37:51.000000000 +1100
@@ -3208,6 +3208,8 @@ __nfs4_state_shutdown(void)
{
int i;
struct nfs4_client *clp = NULL;
+ struct nfs4_delegation *dp = NULL;
+ struct list_head *pos, *next;
for (i = 0; i < CLIENT_HASH_SIZE; i++) {
while (!list_empty(&conf_id_hashtbl[i])) {
@@ -3219,6 +3221,14 @@ __nfs4_state_shutdown(void)
expire_client(clp);
}
}
+ spin_lock(&recall_lock);
+ list_for_each_safe(pos, next, &del_recall_lru) {
+ dp = list_entry (pos, struct nfs4_delegation, dl_recall_lru);
+ atomic_set(&dp->dl_state, NFS4_RECALL_COMPLETE);
+ release_delegation(dp);
+ }
+ spin_unlock(&recall_lock);
+
release_all_files();
cancel_delayed_work(&laundromat_work);
flush_scheduled_work();
-------------------------------------------------------
SF email is sponsored by - The IT Product Guide
Read honest & candid reviews on hundreds of IT Products from real users.
Discover which products truly live up to the hype. Start reading now.
http://productguide.itmanagersjournal.com/
_______________________________________________
NFS maillist - NFS@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/nfs
^ permalink raw reply [flat|nested] 29+ messages in thread
* [PATCH kNFSd 20 of 23] Add checking of delegation stateids to nfs4_preprocess_stateid_op.
2004-12-17 5:23 [PATCH kNFSd 0 of 23] Introduction NeilBrown
` (19 preceding siblings ...)
2004-12-17 5:23 ` [PATCH kNFSd 22 of 23] Add to the laundromat service for delegations NeilBrown
@ 2004-12-17 5:23 ` NeilBrown
2004-12-17 5:23 ` [PATCH kNFSd 23 of 23] Clear the recall_lru of delegations at shutdown NeilBrown
2004-12-17 5:23 ` [PATCH kNFSd 21 of 23] Add the DELEGRETURN operation NeilBrown
22 siblings, 0 replies; 29+ messages in thread
From: NeilBrown @ 2004-12-17 5:23 UTC (permalink / raw)
To: Andrew Morton; +Cc: nfs
Call release_delegation on delegreturn (DELEG_RET).
Signed-off-by: Andy Adamson <andros@citi.umich.edu>
Signed-off-by: Neil Brown <neilb@cse.unsw.edu.au>
### Diffstat output
./fs/nfsd/nfs4state.c | 62 ++++++++++++++++++++++++++-----------------
./include/linux/nfsd/state.h | 1
2 files changed, 39 insertions(+), 24 deletions(-)
diff ./fs/nfsd/nfs4state.c~current~ ./fs/nfsd/nfs4state.c
--- ./fs/nfsd/nfs4state.c~current~ 2004-12-15 13:37:51.000000000 +1100
+++ ./fs/nfsd/nfs4state.c 2004-12-15 13:37:51.000000000 +1100
@@ -1943,7 +1943,7 @@ access_permit_write(unsigned long access
}
static
-int check_openmode(struct nfs4_stateid *stp, int flags)
+int nfs4_check_openmode(struct nfs4_stateid *stp, int flags)
{
int status = nfserr_openmode;
@@ -1976,7 +1976,9 @@ out:
int
nfs4_preprocess_stateid_op(struct svc_fh *current_fh, stateid_t *stateid, int flags)
{
- struct nfs4_stateid *stp;
+ struct nfs4_stateid *stp = NULL;
+ struct nfs4_delegation *dp = NULL;
+ stateid_t *stidp;
int status;
dprintk("NFSD: preprocess_stateid_op: stateid = (%08x/%08x/%08x/%08x)\n",
@@ -1990,35 +1992,47 @@ nfs4_preprocess_stateid_op(struct svc_fh
/* BAD STATEID */
status = nfserr_bad_stateid;
- if (!(stp = find_stateid(stateid, flags))) {
- dprintk("NFSD: preprocess_stateid_op: no open stateid!\n");
- goto out;
- }
- if ((flags & CHECK_FH) && nfs4_check_fh(current_fh, stp)) {
- dprintk("NFSD: preprocess_stateid_op: fh-stateid mismatch!\n");
- stp->st_vfs_set = 0;
- goto out;
- }
- if (!stp->st_stateowner->so_confirmed) {
- dprintk("preprocess_stateid_op: lockowner not confirmed yet!\n");
- goto out;
+ if (!stateid->si_fileid) { /* delegation stateid */
+ struct inode *ino = current_fh->fh_dentry->d_inode;
+
+ if(!(dp = find_delegation_stateid(ino, stateid))) {
+ dprintk("NFSD: delegation stateid not found\n");
+ goto out;
+ }
+ stidp = &dp->dl_stateid;
+ } else { /* open or lock stateid */
+ if (!(stp = find_stateid(stateid, flags))) {
+ dprintk("NFSD: open or lock stateid not found\n");
+ goto out;
+ }
+ if ((flags & CHECK_FH) && nfs4_check_fh(current_fh, stp))
+ goto out;
+ if (!stp->st_stateowner->so_confirmed)
+ goto out;
+ stidp = &stp->st_stateid;
}
- if (stateid->si_generation > stp->st_stateid.si_generation) {
- dprintk("preprocess_stateid_op: future stateid?!\n");
+ if (stateid->si_generation > stidp->si_generation)
goto out;
- }
/* OLD STATEID */
status = nfserr_old_stateid;
- if (stateid->si_generation < stp->st_stateid.si_generation) {
- dprintk("preprocess_stateid_op: old stateid!\n");
+ if (stateid->si_generation < stidp->si_generation)
goto out;
+ if (stp) {
+ if ((status = nfs4_check_openmode(stp,flags)))
+ goto out;
+ renew_client(stp->st_stateowner->so_client);
+ } else if (dp) {
+ if ((status = nfs4_check_delegmode(dp, flags)))
+ goto out;
+ renew_client(dp->dl_client);
+ if (flags & DELEG_RET) {
+ atomic_set(&dp->dl_state,NFS4_RECALL_COMPLETE);
+ spin_lock(&recall_lock);
+ release_delegation(dp);
+ spin_unlock(&recall_lock);
+ }
}
- renew_client(stp->st_stateowner->so_client);
-
- if((status = check_openmode(stp, flags)))
- goto out;
-
status = nfs_ok;
out:
return status;
diff ./include/linux/nfsd/state.h~current~ ./include/linux/nfsd/state.h
--- ./include/linux/nfsd/state.h~current~ 2004-12-15 13:37:21.000000000 +1100
+++ ./include/linux/nfsd/state.h 2004-12-15 13:37:51.000000000 +1100
@@ -271,6 +271,7 @@ struct nfs4_stateid {
#define RD_STATE 0x00000010
#define WR_STATE 0x00000020
#define CLOSE_STATE 0x00000040
+#define DELEG_RET 0x00000080
#define seqid_mutating_err(err) \
(((err) != nfserr_stale_clientid) && \
-------------------------------------------------------
SF email is sponsored by - The IT Product Guide
Read honest & candid reviews on hundreds of IT Products from real users.
Discover which products truly live up to the hype. Start reading now.
http://productguide.itmanagersjournal.com/
_______________________________________________
NFS maillist - NFS@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/nfs
^ permalink raw reply [flat|nested] 29+ messages in thread
* [PATCH kNFSd 22 of 23] Add to the laundromat service for delegations.
2004-12-17 5:23 [PATCH kNFSd 0 of 23] Introduction NeilBrown
` (18 preceding siblings ...)
2004-12-17 5:23 ` [PATCH kNFSd 19 of 23] Check for openmode violations given a delegation stateid NeilBrown
@ 2004-12-17 5:23 ` NeilBrown
2004-12-17 5:23 ` [PATCH kNFSd 20 of 23] Add checking of delegation stateids to nfs4_preprocess_stateid_op NeilBrown
` (2 subsequent siblings)
22 siblings, 0 replies; 29+ messages in thread
From: NeilBrown @ 2004-12-17 5:23 UTC (permalink / raw)
To: Andrew Morton; +Cc: nfs
Walk the recall_lru and reap unused or timed-out delegations.
Signed-off-by: Andy Adamson <andros@citi.umich.edu>
Signed-off-by: Neil Brown <neilb@cse.unsw.edu.au>
### Diffstat output
./fs/nfsd/nfs4state.c | 27 +++++++++++++++++++++++----
1 files changed, 23 insertions(+), 4 deletions(-)
diff ./fs/nfsd/nfs4state.c~current~ ./fs/nfsd/nfs4state.c
--- ./fs/nfsd/nfs4state.c~current~ 2004-12-15 13:37:51.000000000 +1100
+++ ./fs/nfsd/nfs4state.c 2004-12-15 13:37:51.000000000 +1100
@@ -1844,14 +1844,15 @@ nfs4_laundromat(void)
{
struct nfs4_client *clp;
struct nfs4_stateowner *sop;
+ struct nfs4_delegation *dp;
struct list_head *pos, *next;
time_t cutoff = get_seconds() - NFSD_LEASE_TIME;
time_t t, clientid_val = NFSD_LEASE_TIME;
- time_t u, close_val = NFSD_LEASE_TIME;
+ time_t u, test_val = NFSD_LEASE_TIME;
nfs4_lock_state();
- dprintk("NFSD: laundromat service - starting, examining clients\n");
+ dprintk("NFSD: laundromat service - starting\n");
list_for_each_safe(pos, next, &client_lru) {
clp = list_entry(pos, struct nfs4_client, cl_lru);
if (time_after((unsigned long)clp->cl_time, (unsigned long)cutoff)) {
@@ -1864,12 +1865,30 @@ nfs4_laundromat(void)
clp->cl_clientid.cl_id);
expire_client(clp);
}
+ spin_lock(&recall_lock);
+ list_for_each_safe(pos, next, &del_recall_lru) {
+ dp = list_entry (pos, struct nfs4_delegation, dl_recall_lru);
+ if (atomic_read(&dp->dl_state) == NFS4_RECALL_COMPLETE)
+ goto reap;
+ if (time_after((unsigned long)dp->dl_time, (unsigned long)cutoff)) {
+ u = dp->dl_time - cutoff;
+ if (test_val > u)
+ test_val = u;
+ break;
+ }
+reap:
+ dprintk("NFSD: purging unused delegation dp %p, fp %p\n",
+ dp, dp->dl_flock);
+ release_delegation(dp);
+ }
+ spin_unlock(&recall_lock);
+ test_val = NFSD_LEASE_TIME;
list_for_each_safe(pos, next, &close_lru) {
sop = list_entry(pos, struct nfs4_stateowner, so_close_lru);
if (time_after((unsigned long)sop->so_time, (unsigned long)cutoff)) {
u = sop->so_time - cutoff;
- if (close_val > u)
- close_val = u;
+ if (test_val > u)
+ test_val = u;
break;
}
dprintk("NFSD: purging unused open stateowner (so_id %d)\n",
-------------------------------------------------------
SF email is sponsored by - The IT Product Guide
Read honest & candid reviews on hundreds of IT Products from real users.
Discover which products truly live up to the hype. Start reading now.
http://productguide.itmanagersjournal.com/
_______________________________________________
NFS maillist - NFS@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/nfs
^ permalink raw reply [flat|nested] 29+ messages in thread
* [PATCH kNFSd 21 of 23] Add the DELEGRETURN operation.
2004-12-17 5:23 [PATCH kNFSd 0 of 23] Introduction NeilBrown
` (21 preceding siblings ...)
2004-12-17 5:23 ` [PATCH kNFSd 23 of 23] Clear the recall_lru of delegations at shutdown NeilBrown
@ 2004-12-17 5:23 ` NeilBrown
22 siblings, 0 replies; 29+ messages in thread
From: NeilBrown @ 2004-12-17 5:23 UTC (permalink / raw)
To: Andrew Morton; +Cc: nfs
Signed-off-by: Andy Adamson <andros@citi.umich.edu>
Signed-off-by: Neil Brown <neilb@cse.unsw.edu.au>
### Diffstat output
./fs/nfsd/nfs4proc.c | 3 +++
./fs/nfsd/nfs4state.c | 16 ++++++++++++++++
./fs/nfsd/nfs4xdr.c | 17 +++++++++++++++++
./include/linux/nfsd/xdr4.h | 7 +++++++
4 files changed, 43 insertions(+)
diff ./fs/nfsd/nfs4proc.c~current~ ./fs/nfsd/nfs4proc.c
--- ./fs/nfsd/nfs4proc.c~current~ 2004-12-15 13:37:21.000000000 +1100
+++ ./fs/nfsd/nfs4proc.c 2004-12-15 13:37:51.000000000 +1100
@@ -840,6 +840,9 @@ nfsd4_proc_compound(struct svc_rqst *rqs
case OP_CREATE:
op->status = nfsd4_create(rqstp, current_fh, &op->u.create);
break;
+ case OP_DELEGRETURN:
+ op->status = nfsd4_delegreturn(rqstp, current_fh, &op->u.delegreturn);
+ break;
case OP_GETATTR:
op->status = nfsd4_getattr(rqstp, current_fh, &op->u.getattr);
break;
diff ./fs/nfsd/nfs4state.c~current~ ./fs/nfsd/nfs4state.c
--- ./fs/nfsd/nfs4state.c~current~ 2004-12-15 13:37:51.000000000 +1100
+++ ./fs/nfsd/nfs4state.c 2004-12-15 13:37:51.000000000 +1100
@@ -2332,6 +2332,22 @@ out:
return status;
}
+int
+nfsd4_delegreturn(struct svc_rqst *rqstp, struct svc_fh *current_fh, struct nfsd4_delegreturn *dr)
+{
+ int status;
+
+ if ((status = fh_verify(rqstp, current_fh, S_IFREG, 0)))
+ goto out;
+
+ nfs4_lock_state();
+ status = nfs4_preprocess_stateid_op(current_fh, &dr->dr_stateid, DELEG_RET);
+ nfs4_unlock_state();
+out:
+ return status;
+}
+
+
/*
* Lock owner state (byte-range locks)
*/
diff ./fs/nfsd/nfs4xdr.c~current~ ./fs/nfsd/nfs4xdr.c
--- ./fs/nfsd/nfs4xdr.c~current~ 2004-12-15 13:37:21.000000000 +1100
+++ ./fs/nfsd/nfs4xdr.c 2004-12-15 13:37:51.000000000 +1100
@@ -615,6 +615,18 @@ nfsd4_decode_create(struct nfsd4_compoun
}
static inline int
+nfsd4_decode_delegreturn(struct nfsd4_compoundargs *argp, struct nfsd4_delegreturn *dr)
+{
+ DECODE_HEAD;
+
+ READ_BUF(sizeof(stateid_t));
+ READ32(dr->dr_stateid.si_generation);
+ COPYMEM(&dr->dr_stateid.si_opaque, sizeof(stateid_opaque_t));
+
+ DECODE_TAIL;
+}
+
+static inline int
nfsd4_decode_getattr(struct nfsd4_compoundargs *argp, struct nfsd4_getattr *getattr)
{
return nfsd4_decode_bitmap(argp, getattr->ga_bmval);
@@ -1170,6 +1182,9 @@ nfsd4_decode_compound(struct nfsd4_compo
case OP_CREATE:
op->status = nfsd4_decode_create(argp, &op->u.create);
break;
+ case OP_DELEGRETURN:
+ op->status = nfsd4_decode_delegreturn(argp, &op->u.delegreturn);
+ break;
case OP_GETATTR:
op->status = nfsd4_decode_getattr(argp, &op->u.getattr);
break;
@@ -2451,6 +2466,8 @@ nfsd4_encode_operation(struct nfsd4_comp
case OP_CREATE:
nfsd4_encode_create(resp, op->status, &op->u.create);
break;
+ case OP_DELEGRETURN:
+ break;
case OP_GETATTR:
op->status = nfsd4_encode_getattr(resp, op->status, &op->u.getattr);
break;
diff ./include/linux/nfsd/xdr4.h~current~ ./include/linux/nfsd/xdr4.h
--- ./include/linux/nfsd/xdr4.h~current~ 2004-12-15 13:37:21.000000000 +1100
+++ ./include/linux/nfsd/xdr4.h 2004-12-15 13:37:51.000000000 +1100
@@ -94,6 +94,10 @@ struct nfsd4_create {
#define cr_specdata1 u.dev.specdata1
#define cr_specdata2 u.dev.specdata2
+struct nfsd4_delegreturn {
+ stateid_t dr_stateid;
+};
+
struct nfsd4_getattr {
u32 ga_bmval[2]; /* request */
struct svc_fh *ga_fhp; /* response */
@@ -335,6 +339,7 @@ struct nfsd4_op {
struct nfsd4_close close;
struct nfsd4_commit commit;
struct nfsd4_create create;
+ struct nfsd4_delegreturn delegreturn;
struct nfsd4_getattr getattr;
struct svc_fh * getfh;
struct nfsd4_link link;
@@ -446,6 +451,8 @@ extern int
nfsd4_release_lockowner(struct svc_rqst *rqstp,
struct nfsd4_release_lockowner *rlockowner);
extern void nfsd4_release_compoundargs(struct nfsd4_compoundargs *);
+extern int nfsd4_delegreturn(struct svc_rqst *rqstp,
+ struct svc_fh *current_fh, struct nfsd4_delegreturn *dr);
#endif
/*
-------------------------------------------------------
SF email is sponsored by - The IT Product Guide
Read honest & candid reviews on hundreds of IT Products from real users.
Discover which products truly live up to the hype. Start reading now.
http://productguide.itmanagersjournal.com/
_______________________________________________
NFS maillist - NFS@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/nfs
^ permalink raw reply [flat|nested] 29+ messages in thread
* Re: [PATCH kNFSd 4 of 23] Preparation for delegation: client callback probe
2004-12-17 5:23 ` [PATCH kNFSd 4 of 23] Preparation for delegation: client callback probe NeilBrown
@ 2004-12-17 6:45 ` Mike Waychison
2004-12-17 19:01 ` William A.(Andy) Adamson
0 siblings, 1 reply; 29+ messages in thread
From: Mike Waychison @ 2004-12-17 6:45 UTC (permalink / raw)
To: NeilBrown; +Cc: Andrew Morton, nfs
-----BEGIN PGP SIGNED MESSAGE-----
Hash: SHA1
NeilBrown wrote:
> client callback rpc to probe the callback
> channel on setclientid with a null request.
>
...
> +/*
> + * Set up the callback client and put a NFSPROC4_CB_NULL on the wire...
> + */
> +void
> +nfsd4_probe_callback(struct nfs4_client *clp)
> +{
> + struct sockaddr_in addr;
> + struct nfs4_callback *cb = &clp->cl_callback;
> + struct rpc_timeout timeparms;
> + struct rpc_xprt * xprt;
> + struct rpc_program * program = &cb->cb_program;
> + struct rpc_stat * stat = &cb->cb_stat;
> + struct rpc_clnt * clnt;
> + struct rpc_message msg = {
> + .rpc_proc = &nfs4_cb_procedures[NFSPROC4_CLNT_CB_NULL],
> + .rpc_argp = clp,
> + };
> + char hostname[32];
> + int status;
> +
> + dprintk("NFSD: probe_callback. cb_parsed %d cb_set %d\n",
> + cb->cb_parsed, atomic_read(&cb->cb_set));
> + if (!cb->cb_parsed || atomic_read(&cb->cb_set))
> + return;
> +
> + /* Initialize address */
> + memset(&addr, 0, sizeof(addr));
> + addr.sin_family = AF_INET;
> + addr.sin_port = htons(cb->cb_port);
> + addr.sin_addr.s_addr = htonl(cb->cb_addr);
> +
> + /* Initialize timeout */
> + timeparms.to_initval = (NFSD_LEASE_TIME/4) * HZ;
> + timeparms.to_retries = 5;
> + timeparms.to_maxval = (NFSD_LEASE_TIME/2) * HZ;
> + timeparms.to_exponential = 1;
> +
> + /* Create RPC transport */
> + if (!(xprt = xprt_create_proto(IPPROTO_TCP, &addr, &timeparms))) {
> + dprintk("NFSD: couldn't create callback transport!\n");
> + goto out_err;
> + }
> +
> + /* Initialize rpc_program */
> + program->name = "nfs4_cb";
> + program->number = cb->cb_prog;
> + program->nrvers = sizeof(nfs_cb_version)/sizeof(nfs_cb_version[0]);
> + program->version = nfs_cb_version;
> + program->stats = stat;
> +
> + /* Initialize rpc_stat */
> + memset(stat, 0, sizeof(struct rpc_stat));
> + stat->program = program;
> +
> + /* Create RPC client
> + *
> + * XXX AUTH_UNIX only - need AUTH_GSS....
> + */
> + sprintf(hostname, "%u.%u.%u.%u", NIPQUAD(addr.sin_addr.s_addr));
> + if (!(clnt = rpc_create_client(xprt, hostname, program, 1, RPC_AUTH_UNIX))) {
> + dprintk("NFSD: couldn't create callback client\n");
> + goto out_xprt;
> + }
Out of curiosity, does this have to be a reserved port?
- --
Mike Waychison
Sun Microsystems, Inc.
1 (650) 352-5299 voice
1 (416) 202-8336 voice
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
NOTICE: The opinions expressed in this email are held by me,
and may not represent the views of Sun Microsystems, Inc.
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
-----BEGIN PGP SIGNATURE-----
Version: GnuPG v1.2.5 (GNU/Linux)
Comment: Using GnuPG with Thunderbird - http://enigmail.mozdev.org
iD8DBQFBwoBsdQs4kOxk3/MRAgHCAJ4xgWFHL+6IlrslbifbQoCR1RDlQQCeLw8p
VsUf2XAdv0ihP2qfBOTlp40=
=1WbB
-----END PGP SIGNATURE-----
-------------------------------------------------------
SF email is sponsored by - The IT Product Guide
Read honest & candid reviews on hundreds of IT Products from real users.
Discover which products truly live up to the hype. Start reading now.
http://productguide.itmanagersjournal.com/
_______________________________________________
NFS maillist - NFS@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/nfs
^ permalink raw reply [flat|nested] 29+ messages in thread
* Re: [PATCH kNFSd 4 of 23] Preparation for delegation: client callback probe
2004-12-17 6:45 ` Mike Waychison
@ 2004-12-17 19:01 ` William A.(Andy) Adamson
2004-12-21 15:56 ` Mike Waychison
0 siblings, 1 reply; 29+ messages in thread
From: William A.(Andy) Adamson @ 2004-12-17 19:01 UTC (permalink / raw)
To: Mike Waychison; +Cc: NeilBrown, Andrew Morton, nfs, andros
the NFSv4.0 callback client and server do not use reserved ports. this makes
the use of delegations through firewalls or to a NAT network fail. this is
fixed in the proposed NFSv4.1 minor version 'sessions' feature which allows
for the use of the NFSv4 reserved port 2049 for callbacks.
-->Andy
> -----BEGIN PGP SIGNED MESSAGE-----
> Hash: SHA1
>
> NeilBrown wrote:
> > client callback rpc to probe the callback
> > channel on setclientid with a null request.
> >
> ...
>
> > +/*
> > + * Set up the callback client and put a NFSPROC4_CB_NULL on the wire...
> > + */
> > +void
> > +nfsd4_probe_callback(struct nfs4_client *clp)
> > +{
> > + struct sockaddr_in addr;
> > + struct nfs4_callback *cb = &clp->cl_callback;
> > + struct rpc_timeout timeparms;
> > + struct rpc_xprt * xprt;
> > + struct rpc_program * program = &cb->cb_program;
> > + struct rpc_stat * stat = &cb->cb_stat;
> > + struct rpc_clnt * clnt;
> > + struct rpc_message msg = {
> > + .rpc_proc = &nfs4_cb_procedures[NFSPROC4_CLNT_CB_NULL],
> > + .rpc_argp = clp,
> > + };
> > + char hostname[32];
> > + int status;
> > +
> > + dprintk("NFSD: probe_callback. cb_parsed %d cb_set %d\n",
> > + cb->cb_parsed, atomic_read(&cb->cb_set));
> > + if (!cb->cb_parsed || atomic_read(&cb->cb_set))
> > + return;
> > +
> > + /* Initialize address */
> > + memset(&addr, 0, sizeof(addr));
> > + addr.sin_family = AF_INET;
> > + addr.sin_port = htons(cb->cb_port);
> > + addr.sin_addr.s_addr = htonl(cb->cb_addr);
> > +
> > + /* Initialize timeout */
> > + timeparms.to_initval = (NFSD_LEASE_TIME/4) * HZ;
> > + timeparms.to_retries = 5;
> > + timeparms.to_maxval = (NFSD_LEASE_TIME/2) * HZ;
> > + timeparms.to_exponential = 1;
> > +
> > + /* Create RPC transport */
> > + if (!(xprt = xprt_create_proto(IPPROTO_TCP, &addr, &timeparms))) {
> > + dprintk("NFSD: couldn't create callback transport!\n");
> > + goto out_err;
> > + }
> > +
> > + /* Initialize rpc_program */
> > + program->name = "nfs4_cb";
> > + program->number = cb->cb_prog;
> > + program->nrvers = sizeof(nfs_cb_version)/sizeof(nfs_cb_version[0]);
> > + program->version = nfs_cb_version;
> > + program->stats = stat;
> > +
> > + /* Initialize rpc_stat */
> > + memset(stat, 0, sizeof(struct rpc_stat));
> > + stat->program = program;
> > +
> > + /* Create RPC client
> > + *
> > + * XXX AUTH_UNIX only - need AUTH_GSS....
> > + */
> > + sprintf(hostname, "%u.%u.%u.%u", NIPQUAD(addr.sin_addr.s_addr));
> > + if (!(clnt = rpc_create_client(xprt, hostname, program, 1, RPC_AUTH_UNIX))) {
> > + dprintk("NFSD: couldn't create callback client\n");
> > + goto out_xprt;
> > + }
>
> Out of curiosity, does this have to be a reserved port?
>
> - --
> Mike Waychison
> Sun Microsystems, Inc.
> 1 (650) 352-5299 voice
> 1 (416) 202-8336 voice
>
> ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
> NOTICE: The opinions expressed in this email are held by me,
> and may not represent the views of Sun Microsystems, Inc.
> ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
> -----BEGIN PGP SIGNATURE-----
> Version: GnuPG v1.2.5 (GNU/Linux)
> Comment: Using GnuPG with Thunderbird - http://enigmail.mozdev.org
>
> iD8DBQFBwoBsdQs4kOxk3/MRAgHCAJ4xgWFHL+6IlrslbifbQoCR1RDlQQCeLw8p
> VsUf2XAdv0ihP2qfBOTlp40=
> =1WbB
> -----END PGP SIGNATURE-----
>
>
> -------------------------------------------------------
> SF email is sponsored by - The IT Product Guide
> Read honest & candid reviews on hundreds of IT Products from real users.
> Discover which products truly live up to the hype. Start reading now.
> http://productguide.itmanagersjournal.com/
> _______________________________________________
> NFS maillist - NFS@lists.sourceforge.net
> https://lists.sourceforge.net/lists/listinfo/nfs
>
-------------------------------------------------------
SF email is sponsored by - The IT Product Guide
Read honest & candid reviews on hundreds of IT Products from real users.
Discover which products truly live up to the hype. Start reading now.
http://productguide.itmanagersjournal.com/
_______________________________________________
NFS maillist - NFS@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/nfs
^ permalink raw reply [flat|nested] 29+ messages in thread
* Re: [PATCH kNFSd 4 of 23] Preparation for delegation: client callback probe
2004-12-17 19:01 ` William A.(Andy) Adamson
@ 2004-12-21 15:56 ` Mike Waychison
0 siblings, 0 replies; 29+ messages in thread
From: Mike Waychison @ 2004-12-21 15:56 UTC (permalink / raw)
To: William A.(Andy) Adamson; +Cc: NeilBrown, Andrew Morton, nfs
-----BEGIN PGP SIGNED MESSAGE-----
Hash: SHA1
William A.(Andy) Adamson wrote:
> the NFSv4.0 callback client and server do not use reserved ports. this makes
> the use of delegations through firewalls or to a NAT network fail. this is
> fixed in the proposed NFSv4.1 minor version 'sessions' feature which allows
> for the use of the NFSv4 reserved port 2049 for callbacks.
>
Hmm, in that case, we might want to modify the xprt_create_proto call
somehow to reflect that we don't need a port < XPRT_MAX_RESVPORT(800),
which would limit the number of clients possible.
I'd patch something up, but I'm not sure where that stands with the
transport switch work.
> -->Andy
>
>
> NeilBrown wrote:
>
>>client callback rpc to probe the callback
>>channel on setclientid with a null request.
>
>
> ...
>
>
>>+/*
>>+ * Set up the callback client and put a NFSPROC4_CB_NULL on the wire...
>>+ */
>>+void
>>+nfsd4_probe_callback(struct nfs4_client *clp)
>>+{
>>+ struct sockaddr_in addr;
>>+ struct nfs4_callback *cb = &clp->cl_callback;
>>+ struct rpc_timeout timeparms;
>>+ struct rpc_xprt * xprt;
>>+ struct rpc_program * program = &cb->cb_program;
>>+ struct rpc_stat * stat = &cb->cb_stat;
>>+ struct rpc_clnt * clnt;
>>+ struct rpc_message msg = {
>>+ .rpc_proc = &nfs4_cb_procedures[NFSPROC4_CLNT_CB_NULL],
>>+ .rpc_argp = clp,
>>+ };
>>+ char hostname[32];
>>+ int status;
>>+
>>+ dprintk("NFSD: probe_callback. cb_parsed %d cb_set %d\n",
>>+ cb->cb_parsed, atomic_read(&cb->cb_set));
>>+ if (!cb->cb_parsed || atomic_read(&cb->cb_set))
>>+ return;
>>+
>>+ /* Initialize address */
>>+ memset(&addr, 0, sizeof(addr));
>>+ addr.sin_family = AF_INET;
>>+ addr.sin_port = htons(cb->cb_port);
>>+ addr.sin_addr.s_addr = htonl(cb->cb_addr);
>>+
>>+ /* Initialize timeout */
>>+ timeparms.to_initval = (NFSD_LEASE_TIME/4) * HZ;
>>+ timeparms.to_retries = 5;
>>+ timeparms.to_maxval = (NFSD_LEASE_TIME/2) * HZ;
>>+ timeparms.to_exponential = 1;
>>+
>>+ /* Create RPC transport */
>>+ if (!(xprt = xprt_create_proto(IPPROTO_TCP, &addr, &timeparms))) {
>>+ dprintk("NFSD: couldn't create callback transport!\n");
>>+ goto out_err;
>>+ }
>>+
>>+ /* Initialize rpc_program */
>>+ program->name = "nfs4_cb";
>>+ program->number = cb->cb_prog;
>>+ program->nrvers = sizeof(nfs_cb_version)/sizeof(nfs_cb_version[0]);
>>+ program->version = nfs_cb_version;
>>+ program->stats = stat;
>>+
>>+ /* Initialize rpc_stat */
>>+ memset(stat, 0, sizeof(struct rpc_stat));
>>+ stat->program = program;
>>+
>>+ /* Create RPC client
>>+ *
>>+ * XXX AUTH_UNIX only - need AUTH_GSS....
>>+ */
>>+ sprintf(hostname, "%u.%u.%u.%u", NIPQUAD(addr.sin_addr.s_addr));
>>+ if (!(clnt = rpc_create_client(xprt, hostname, program, 1, RPC_AUTH_UNIX))) {
>>+ dprintk("NFSD: couldn't create callback client\n");
>>+ goto out_xprt;
>>+ }
>
> Out of curiosity, does this have to be a reserved port?
>
> --
> Mike Waychison
> Sun Microsystems, Inc.
> 1 (650) 352-5299 voice
> 1 (416) 202-8336 voice
>
> ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
> NOTICE: The opinions expressed in this email are held by me,
> and may not represent the views of Sun Microsystems, Inc.
> ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
- -------------------------------------------------------
SF email is sponsored by - The IT Product Guide
Read honest & candid reviews on hundreds of IT Products from real users.
Discover which products truly live up to the hype. Start reading now.
http://productguide.itmanagersjournal.com/
_______________________________________________
NFS maillist - NFS@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/nfs
> -------------------------------------------------------
> SF email is sponsored by - The IT Product Guide
> Read honest & candid reviews on hundreds of IT Products from real users.
> Discover which products truly live up to the hype. Start reading now.
> http://productguide.itmanagersjournal.com/
> _______________________________________________
> NFS maillist - NFS@lists.sourceforge.net
> https://lists.sourceforge.net/lists/listinfo/nfs
- --
Mike Waychison
Sun Microsystems, Inc.
1 (650) 352-5299 voice
1 (416) 202-8336 voice
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
NOTICE: The opinions expressed in this email are held by me,
and may not represent the views of Sun Microsystems, Inc.
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
-----BEGIN PGP SIGNATURE-----
Version: GnuPG v1.2.5 (GNU/Linux)
Comment: Using GnuPG with Thunderbird - http://enigmail.mozdev.org
iD8DBQFByEesdQs4kOxk3/MRAsV8AJ0eCtRfyWJDnVcy4k69SUcAY9k+iACfSG8G
Yk40NgRI+AYl95FIawFi0kY=
=+6b9
-----END PGP SIGNATURE-----
-------------------------------------------------------
SF email is sponsored by - The IT Product Guide
Read honest & candid reviews on hundreds of IT Products from real users.
Discover which products truly live up to the hype. Start reading now.
http://productguide.itmanagersjournal.com/
_______________________________________________
NFS maillist - NFS@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/nfs
^ permalink raw reply [flat|nested] 29+ messages in thread
* RE: [PATCH kNFSd 4 of 23] Preparation for delegation: client callback probe
@ 2004-12-21 16:12 Lever, Charles
2004-12-21 16:48 ` Mike Waychison
0 siblings, 1 reply; 29+ messages in thread
From: Lever, Charles @ 2004-12-21 16:12 UTC (permalink / raw)
To: Mike Waychison, William A.(Andy) Adamson; +Cc: NeilBrown, Andrew Morton, nfs
mike-
the latest client side transport switch patches are here:
http://troy.citi.umich.edu/~cel/linux-2.6/2.6.9-a/release-notes.html
for your review. i don't think these are going in any time soon.
we need some time to consider the port number issues. can the patch
with the borg designation 4 of 23 go in without the port number change
you suggested?
> -----Original Message-----
> From: Mike Waychison [mailto:Michael.Waychison@Sun.COM]=20
> Sent: Tuesday, December 21, 2004 10:56 AM
> To: William A.(Andy) Adamson
> Cc: NeilBrown; Andrew Morton; nfs@lists.sourceforge.net
> Subject: Re: [NFS] [PATCH kNFSd 4 of 23] Preparation for=20
> delegation: client callback probe
>=20
>=20
> -----BEGIN PGP SIGNED MESSAGE-----
> Hash: SHA1
>=20
> William A.(Andy) Adamson wrote:
> > the NFSv4.0 callback client and server do not use reserved=20
> ports. this=20
> > makes
> > the use of delegations through firewalls or to a NAT=20
> network fail. this is=20
> > fixed in the proposed NFSv4.1 minor version 'sessions'=20
> feature which allows=20
> > for the use of the NFSv4 reserved port 2049 for callbacks.
> >=20
>=20
> Hmm, in that case, we might want to modify the=20
> xprt_create_proto call somehow to reflect that we don't need=20
> a port < XPRT_MAX_RESVPORT(800), which would limit the number=20
> of clients possible.
>=20
> I'd patch something up, but I'm not sure where that stands=20
> with the transport switch work.
>=20
> > -->Andy
> >=20
> >=20
> > NeilBrown wrote:
> >=20
> >>client callback rpc to probe the callback
> >>channel on setclientid with a null request.
> >=20
> >=20
> > ...
> >=20
> >=20
> >>+/*
> >>+ * Set up the callback client and put a NFSPROC4_CB_NULL on the=20
> >>+wire... */ void
> >>+nfsd4_probe_callback(struct nfs4_client *clp)
> >>+{
> >>+ struct sockaddr_in addr;
> >>+ struct nfs4_callback *cb =3D &clp->cl_callback;
> >>+ struct rpc_timeout timeparms;
> >>+ struct rpc_xprt * xprt;
> >>+ struct rpc_program * program =3D &cb->cb_program;
> >>+ struct rpc_stat * stat =3D &cb->cb_stat;
> >>+ struct rpc_clnt * clnt;
> >>+ struct rpc_message msg =3D {
> >>+ .rpc_proc =3D=20
> &nfs4_cb_procedures[NFSPROC4_CLNT_CB_NULL],
> >>+ .rpc_argp =3D clp,
> >>+ };
> >>+ char hostname[32];
> >>+ int status;
> >>+
> >>+ dprintk("NFSD: probe_callback. cb_parsed %d cb_set %d\n",
> >>+ cb->cb_parsed, atomic_read(&cb->cb_set));
> >>+ if (!cb->cb_parsed || atomic_read(&cb->cb_set))
> >>+ return;
> >>+
> >>+ /* Initialize address */
> >>+ memset(&addr, 0, sizeof(addr));
> >>+ addr.sin_family =3D AF_INET;
> >>+ addr.sin_port =3D htons(cb->cb_port);
> >>+ addr.sin_addr.s_addr =3D htonl(cb->cb_addr);
> >>+
> >>+ /* Initialize timeout */
> >>+ timeparms.to_initval =3D (NFSD_LEASE_TIME/4) * HZ;
> >>+ timeparms.to_retries =3D 5;
> >>+ timeparms.to_maxval =3D (NFSD_LEASE_TIME/2) * HZ;
> >>+ timeparms.to_exponential =3D 1;
> >>+
> >>+ /* Create RPC transport */
> >>+ if (!(xprt =3D xprt_create_proto(IPPROTO_TCP, &addr,=20
> &timeparms))) {
> >>+ dprintk("NFSD: couldn't create callback transport!\n");
> >>+ goto out_err;
> >>+ }
> >>+
> >>+ /* Initialize rpc_program */
> >>+ program->name =3D "nfs4_cb";
> >>+ program->number =3D cb->cb_prog;
> >>+ program->nrvers =3D=20
> sizeof(nfs_cb_version)/sizeof(nfs_cb_version[0]);
> >>+ program->version =3D nfs_cb_version;
> >>+ program->stats =3D stat;
> >>+
> >>+ /* Initialize rpc_stat */
> >>+ memset(stat, 0, sizeof(struct rpc_stat));
> >>+ stat->program =3D program;
> >>+
> >>+ /* Create RPC client
> >>+ *
> >>+ * XXX AUTH_UNIX only - need AUTH_GSS....
> >>+ */
> >>+ sprintf(hostname, "%u.%u.%u.%u", NIPQUAD(addr.sin_addr.s_addr));
> >>+ if (!(clnt =3D rpc_create_client(xprt, hostname, program,=20
> 1, RPC_AUTH_UNIX))) {
> >>+ dprintk("NFSD: couldn't create callback client\n");
> >>+ goto out_xprt;
> >>+ }
> >=20
> > Out of curiosity, does this have to be a reserved port?
> >=20
> > --
> > Mike Waychison
> > Sun Microsystems, Inc.
> > 1 (650) 352-5299 voice
> > 1 (416) 202-8336 voice
> >=20
> > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
> > NOTICE: The opinions expressed in this email are held by=20
> me, and may=20
> > not represent the views of Sun Microsystems, Inc.=20
> > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
>=20
> - -------------------------------------------------------
> SF email is sponsored by - The IT Product Guide
> Read honest & candid reviews on hundreds of IT Products from=20
> real users. Discover which products truly live up to the=20
> hype. Start reading now. http://productguide.itmanagersjournal.com/
> _______________________________________________
> NFS maillist - NFS@lists.sourceforge.net=20
> https://lists.sourceforge.net/lists/listinfo/nfs
>=20
>=20
>=20
>=20
>=20
>=20
> > -------------------------------------------------------
> > SF email is sponsored by - The IT Product Guide
> > Read honest & candid reviews on hundreds of IT Products from real=20
> > users. Discover which products truly live up to the hype. Start=20
> > reading now. http://productguide.itmanagersjournal.com/
> > _______________________________________________
> > NFS maillist - NFS@lists.sourceforge.net=20
> > https://lists.sourceforge.net/lists/listinfo/nfs
>=20
>=20
> - --
> Mike Waychison
> Sun Microsystems, Inc.
> 1 (650) 352-5299 voice
> 1 (416) 202-8336 voice
>=20
> ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
> NOTICE: The opinions expressed in this email are held by me,=20
> and may not represent the views of Sun Microsystems, Inc.=20
> ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
> -----BEGIN PGP SIGNATURE-----
> Version: GnuPG v1.2.5 (GNU/Linux)
> Comment: Using GnuPG with Thunderbird - http://enigmail.mozdev.org
>=20
> iD8DBQFByEesdQs4kOxk3/MRAsV8AJ0eCtRfyWJDnVcy4k69SUcAY9k+iACfSG8G
> Yk40NgRI+AYl95FIawFi0kY=3D
> =3D+6b9
> -----END PGP SIGNATURE-----
>=20
>=20
> -------------------------------------------------------
> SF email is sponsored by - The IT Product Guide
> Read honest & candid reviews on hundreds of IT Products from=20
> real users. Discover which products truly live up to the=20
> hype. Start reading now.=20
> http://productguide.itmanagersjournal.com/
> _______________________________________________
> NFS maillist - NFS@lists.sourceforge.net=20
> https://lists.sourceforge.net/lists/listinfo/n> fs
>=20
-------------------------------------------------------
SF email is sponsored by - The IT Product Guide
Read honest & candid reviews on hundreds of IT Products from real users.
Discover which products truly live up to the hype. Start reading now.
http://productguide.itmanagersjournal.com/
_______________________________________________
NFS maillist - NFS@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/nfs
^ permalink raw reply [flat|nested] 29+ messages in thread
* Re: [PATCH kNFSd 4 of 23] Preparation for delegation: client callback probe
2004-12-21 16:12 [PATCH kNFSd 4 of 23] Preparation for delegation: client callback probe Lever, Charles
@ 2004-12-21 16:48 ` Mike Waychison
0 siblings, 0 replies; 29+ messages in thread
From: Mike Waychison @ 2004-12-21 16:48 UTC (permalink / raw)
To: Lever, Charles; +Cc: William A.(Andy) Adamson, NeilBrown, Andrew Morton, nfs
-----BEGIN PGP SIGNED MESSAGE-----
Hash: SHA1
Lever, Charles wrote:
> mike-
>
> the latest client side transport switch patches are here:
>
> http://troy.citi.umich.edu/~cel/linux-2.6/2.6.9-a/release-notes.html
>
> for your review. i don't think these are going in any time soon.
>
> we need some time to consider the port number issues. can the patch
> with the borg designation 4 of 23 go in without the port number change
> you suggested?
It can, but it's a scaling issue that early adopters are going to hit.
As long as the port number stuff is forthcoming, I don't see any issue
with this patch.
>
>
>
>>-----Original Message-----
>>From: Mike Waychison [mailto:Michael.Waychison@Sun.COM]
>>Sent: Tuesday, December 21, 2004 10:56 AM
>>To: William A.(Andy) Adamson
>>Cc: NeilBrown; Andrew Morton; nfs@lists.sourceforge.net
>>Subject: Re: [NFS] [PATCH kNFSd 4 of 23] Preparation for
>>delegation: client callback probe
>>
>>
> William A.(Andy) Adamson wrote:
>
>>the NFSv4.0 callback client and server do not use reserved
>
> ports. this
>
>>makes
>>the use of delegations through firewalls or to a NAT
>
> network fail. this is
>
>>fixed in the proposed NFSv4.1 minor version 'sessions'
>
> feature which allows
>
>>for the use of the NFSv4 reserved port 2049 for callbacks.
>
>
> Hmm, in that case, we might want to modify the
> xprt_create_proto call somehow to reflect that we don't need
> a port < XPRT_MAX_RESVPORT(800), which would limit the number
> of clients possible.
>
> I'd patch something up, but I'm not sure where that stands
> with the transport switch work.
>
>
>>-->Andy
>
>
>>NeilBrown wrote:
>
>
>>>client callback rpc to probe the callback
>>>channel on setclientid with a null request.
>
>
>>...
>
>
>
>>>+/*
>>>+ * Set up the callback client and put a NFSPROC4_CB_NULL on the
>>>+wire... */ void
>>>+nfsd4_probe_callback(struct nfs4_client *clp)
>>>+{
>>>+ struct sockaddr_in addr;
>>>+ struct nfs4_callback *cb = &clp->cl_callback;
>>>+ struct rpc_timeout timeparms;
>>>+ struct rpc_xprt * xprt;
>>>+ struct rpc_program * program = &cb->cb_program;
>>>+ struct rpc_stat * stat = &cb->cb_stat;
>>>+ struct rpc_clnt * clnt;
>>>+ struct rpc_message msg = {
>>>+ .rpc_proc =
>
> &nfs4_cb_procedures[NFSPROC4_CLNT_CB_NULL],
>
>>>+ .rpc_argp = clp,
>>>+ };
>>>+ char hostname[32];
>>>+ int status;
>>>+
>>>+ dprintk("NFSD: probe_callback. cb_parsed %d cb_set %d\n",
>>>+ cb->cb_parsed, atomic_read(&cb->cb_set));
>>>+ if (!cb->cb_parsed || atomic_read(&cb->cb_set))
>>>+ return;
>>>+
>>>+ /* Initialize address */
>>>+ memset(&addr, 0, sizeof(addr));
>>>+ addr.sin_family = AF_INET;
>>>+ addr.sin_port = htons(cb->cb_port);
>>>+ addr.sin_addr.s_addr = htonl(cb->cb_addr);
>>>+
>>>+ /* Initialize timeout */
>>>+ timeparms.to_initval = (NFSD_LEASE_TIME/4) * HZ;
>>>+ timeparms.to_retries = 5;
>>>+ timeparms.to_maxval = (NFSD_LEASE_TIME/2) * HZ;
>>>+ timeparms.to_exponential = 1;
>>>+
>>>+ /* Create RPC transport */
>>>+ if (!(xprt = xprt_create_proto(IPPROTO_TCP, &addr,
>
> &timeparms))) {
>
>>>+ dprintk("NFSD: couldn't create callback transport!\n");
>>>+ goto out_err;
>>>+ }
>>>+
>>>+ /* Initialize rpc_program */
>>>+ program->name = "nfs4_cb";
>>>+ program->number = cb->cb_prog;
>>>+ program->nrvers =
>
> sizeof(nfs_cb_version)/sizeof(nfs_cb_version[0]);
>
>>>+ program->version = nfs_cb_version;
>>>+ program->stats = stat;
>>>+
>>>+ /* Initialize rpc_stat */
>>>+ memset(stat, 0, sizeof(struct rpc_stat));
>>>+ stat->program = program;
>>>+
>>>+ /* Create RPC client
>>>+ *
>>>+ * XXX AUTH_UNIX only - need AUTH_GSS....
>>>+ */
>>>+ sprintf(hostname, "%u.%u.%u.%u", NIPQUAD(addr.sin_addr.s_addr));
>>>+ if (!(clnt = rpc_create_client(xprt, hostname, program,
>
> 1, RPC_AUTH_UNIX))) {
>
>>>+ dprintk("NFSD: couldn't create callback client\n");
>>>+ goto out_xprt;
>>>+ }
>
>>Out of curiosity, does this have to be a reserved port?
>
>>--
>>Mike Waychison
>>Sun Microsystems, Inc.
>>1 (650) 352-5299 voice
>>1 (416) 202-8336 voice
>
>>~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
>>NOTICE: The opinions expressed in this email are held by
>
> me, and may
>
>>not represent the views of Sun Microsystems, Inc.
>>~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
>
> -------------------------------------------------------
> SF email is sponsored by - The IT Product Guide
> Read honest & candid reviews on hundreds of IT Products from
> real users. Discover which products truly live up to the
> hype. Start reading now. http://productguide.itmanagersjournal.com/
> _______________________________________________
> NFS maillist - NFS@lists.sourceforge.net
> https://lists.sourceforge.net/lists/listinfo/nfs
>
>
>
>
>
>
>
>>-------------------------------------------------------
>>SF email is sponsored by - The IT Product Guide
>>Read honest & candid reviews on hundreds of IT Products from real
>>users. Discover which products truly live up to the hype. Start
>>reading now. http://productguide.itmanagersjournal.com/
>>_______________________________________________
>>NFS maillist - NFS@lists.sourceforge.net
>>https://lists.sourceforge.net/lists/listinfo/nfs
>
>
> --
> Mike Waychison
> Sun Microsystems, Inc.
> 1 (650) 352-5299 voice
> 1 (416) 202-8336 voice
>
> ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
> NOTICE: The opinions expressed in this email are held by me,
> and may not represent the views of Sun Microsystems, Inc.
> ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
- -------------------------------------------------------
SF email is sponsored by - The IT Product Guide
Read honest & candid reviews on hundreds of IT Products from
real users. Discover which products truly live up to the
hype. Start reading now.
http://productguide.itmanagersjournal.com/
_______________________________________________
NFS maillist - NFS@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/n> fs
- --
Mike Waychison
Sun Microsystems, Inc.
1 (650) 352-5299 voice
1 (416) 202-8336 voice
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
NOTICE: The opinions expressed in this email are held by me,
and may not represent the views of Sun Microsystems, Inc.
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
-----BEGIN PGP SIGNATURE-----
Version: GnuPG v1.2.5 (GNU/Linux)
Comment: Using GnuPG with Thunderbird - http://enigmail.mozdev.org
iD8DBQFByFPLdQs4kOxk3/MRAkqZAKCDKgSjaQ8bOClJXtLEHFUgVfSSxQCdE/PN
hUW11mLO1c7Ljsdoq1Q3V8M=
=DS14
-----END PGP SIGNATURE-----
-------------------------------------------------------
SF email is sponsored by - The IT Product Guide
Read honest & candid reviews on hundreds of IT Products from real users.
Discover which products truly live up to the hype. Start reading now.
http://productguide.itmanagersjournal.com/
_______________________________________________
NFS maillist - NFS@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/nfs
^ permalink raw reply [flat|nested] 29+ messages in thread
end of thread, other threads:[~2004-12-21 16:48 UTC | newest]
Thread overview: 29+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2004-12-17 5:23 [PATCH kNFSd 0 of 23] Introduction NeilBrown
2004-12-17 5:23 ` [PATCH kNFSd 5 of 23] Probe the callback path upon a successful setclientid_confirm NeilBrown
2004-12-17 5:23 ` [PATCH kNFSd 1 of 23] Move nfserr_openmode checking from nfsd_read/write into nfs4_preprocess_stateid_op() in preperation for delegation state NeilBrown
2004-12-17 5:23 ` [PATCH kNFSd 6 of 23] Check for existence of file_lock parameter inside of the kernel lock NeilBrown
2004-12-17 5:23 ` [PATCH kNFSd 4 of 23] Preparation for delegation: client callback probe NeilBrown
2004-12-17 6:45 ` Mike Waychison
2004-12-17 19:01 ` William A.(Andy) Adamson
2004-12-21 15:56 ` Mike Waychison
2004-12-17 5:23 ` [PATCH kNFSd 7 of 23] Get rid of the special delegation_stateid_t, use the existing stateid_t NeilBrown
2004-12-17 5:23 ` [PATCH kNFSd 3 of 23] Count the nfs4_client structure usage NeilBrown
2004-12-17 5:23 ` [PATCH kNFSd 2 of 23] Check the callback netid in gen_callback NeilBrown
2004-12-17 5:23 ` [PATCH kNFSd 14 of 23] Delegation recall callback rpc NeilBrown
2004-12-17 5:23 ` [PATCH kNFSd 16 of 23] Helper functions for deciding to grant a delegation NeilBrown
2004-12-17 5:23 ` [PATCH kNFSd 15 of 23] Kernel thread for delegation callback NeilBrown
2004-12-17 5:23 ` [PATCH kNFSd 9 of 23] Allocate and initialize the delegation structure NeilBrown
2004-12-17 5:23 ` [PATCH kNFSd 13 of 23] Delay nfsd_colse for delegations until reaping NeilBrown
2004-12-17 5:23 ` [PATCH kNFSd 18 of 23] Remove unnecessary stateowner existence check NeilBrown
2004-12-17 5:23 ` [PATCH kNFSd 11 of 23] Add the delegation release and free functions NeilBrown
2004-12-17 5:23 ` [PATCH kNFSd 12 of 23] Changes to expire_client NeilBrown
2004-12-17 5:23 ` [PATCH kNFSd 8 of 23] Add structures for delegation support NeilBrown
2004-12-17 5:23 ` [PATCH kNFSd 10 of 23] Find a delegation for a file given a stateid NeilBrown
2004-12-17 5:23 ` [PATCH kNFSd 17 of 23] Attempt to hand out a delegation NeilBrown
2004-12-17 5:23 ` [PATCH kNFSd 19 of 23] Check for openmode violations given a delegation stateid NeilBrown
2004-12-17 5:23 ` [PATCH kNFSd 22 of 23] Add to the laundromat service for delegations NeilBrown
2004-12-17 5:23 ` [PATCH kNFSd 20 of 23] Add checking of delegation stateids to nfs4_preprocess_stateid_op NeilBrown
2004-12-17 5:23 ` [PATCH kNFSd 23 of 23] Clear the recall_lru of delegations at shutdown NeilBrown
2004-12-17 5:23 ` [PATCH kNFSd 21 of 23] Add the DELEGRETURN operation NeilBrown
-- strict thread matches above, loose matches on Subject: below --
2004-12-21 16:12 [PATCH kNFSd 4 of 23] Preparation for delegation: client callback probe Lever, Charles
2004-12-21 16:48 ` Mike Waychison
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.