All of lore.kernel.org
 help / color / mirror / Atom feed
* [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, &current_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.