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
  2004-12-17  5:23 ` [PATCH kNFSd 3 of 23] Count the nfs4_client structure usage 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 ` NeilBrown
  2004-12-17  5:23 ` [PATCH kNFSd 5 of 23] Probe the callback path upon a successful setclientid_confirm NeilBrown
                   ` (19 subsequent siblings)
  22 siblings, 0 replies; 27+ 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] 27+ messages in thread

* [PATCH kNFSd 0 of 23] Introduction
@ 2004-12-17  5:23 NeilBrown
  2004-12-17  5:23 ` [PATCH kNFSd 3 of 23] Count the nfs4_client structure usage NeilBrown
                   ` (22 more replies)
  0 siblings, 23 replies; 27+ 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] 27+ 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 3 of 23] Count the nfs4_client structure usage NeilBrown
@ 2004-12-17  5:23 ` NeilBrown
  2004-12-17  5:23 ` [PATCH kNFSd 7 of 23] Get rid of the special delegation_stateid_t, use the existing stateid_t NeilBrown
                   ` (20 subsequent siblings)
  22 siblings, 0 replies; 27+ 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] 27+ 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
@ 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
                   ` (21 subsequent siblings)
  22 siblings, 0 replies; 27+ 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] 27+ 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
                   ` (2 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 4 of 23] Preparation for delegation: client callback probe NeilBrown
                   ` (18 subsequent siblings)
  22 siblings, 0 replies; 27+ 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] 27+ 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
                   ` (4 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 1 of 23] Move nfserr_openmode checking from nfsd_read/write into nfs4_preprocess_stateid_op() in preperation for delegation state NeilBrown
                   ` (16 subsequent siblings)
  22 siblings, 0 replies; 27+ 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] 27+ 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
                   ` (5 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 9 of 23] Allocate and initialize the delegation structure NeilBrown
                   ` (15 subsequent siblings)
  22 siblings, 0 replies; 27+ 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] 27+ 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
                   ` (3 preceding siblings ...)
  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  6:45   ` Mike Waychison
  2004-12-17  5:23 ` [PATCH kNFSd 2 of 23] Check the callback netid in gen_callback NeilBrown
                   ` (17 subsequent siblings)
  22 siblings, 1 reply; 27+ 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] 27+ 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 9 of 23] Allocate and initialize the delegation structure 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
                   ` (13 subsequent siblings)
  22 siblings, 0 replies; 27+ 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] 27+ 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
                   ` (6 preceding siblings ...)
  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 16 of 23] Helper functions for deciding to grant a delegation NeilBrown
                   ` (14 subsequent siblings)
  22 siblings, 0 replies; 27+ 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] 27+ 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
                   ` (10 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 18 of 23] Remove unnecessary stateowner existence check NeilBrown
                   ` (10 subsequent siblings)
  22 siblings, 0 replies; 27+ 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] 27+ 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
                   ` (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 17 of 23] Attempt to hand out a delegation NeilBrown
                   ` (12 subsequent siblings)
  22 siblings, 0 replies; 27+ 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] 27+ 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
                   ` (9 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 11 of 23] Add the delegation release and free functions NeilBrown
                   ` (11 subsequent siblings)
  22 siblings, 0 replies; 27+ 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] 27+ messages in thread

* [PATCH kNFSd 12 of 23] Changes to expire_client
  2004-12-17  5:23 [PATCH kNFSd 0 of 23] Introduction NeilBrown
                   ` (14 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 8 of 23] Add structures for delegation support NeilBrown
                   ` (6 subsequent siblings)
  22 siblings, 0 replies; 27+ 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] 27+ 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 11 of 23] Add the delegation release and free functions NeilBrown
@ 2004-12-17  5:23 ` NeilBrown
  2004-12-17  5:23 ` [PATCH kNFSd 15 of 23] Kernel thread for delegation callback NeilBrown
                   ` (9 subsequent siblings)
  22 siblings, 0 replies; 27+ 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] 27+ 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
                   ` (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 14 of 23] Delegation recall callback rpc NeilBrown
                   ` (8 subsequent siblings)
  22 siblings, 0 replies; 27+ 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] 27+ 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
                   ` (15 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 13 of 23] Delay nfsd_colse for delegations until reaping NeilBrown
                   ` (5 subsequent siblings)
  22 siblings, 0 replies; 27+ 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] 27+ 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
                   ` (16 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 23 of 23] Clear the recall_lru of delegations at shutdown NeilBrown
                   ` (4 subsequent siblings)
  22 siblings, 0 replies; 27+ 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] 27+ messages in thread

* [PATCH kNFSd 14 of 23] Delegation recall callback rpc.
  2004-12-17  5:23 [PATCH kNFSd 0 of 23] Introduction NeilBrown
                   ` (13 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 12 of 23] Changes to expire_client NeilBrown
                   ` (7 subsequent siblings)
  22 siblings, 0 replies; 27+ 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] 27+ 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
                   ` (19 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
  2004-12-17  5:23 ` [PATCH kNFSd 22 of 23] Add to the laundromat service for delegations NeilBrown
  22 siblings, 0 replies; 27+ 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] 27+ 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
                   ` (17 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 20 of 23] Add checking of delegation stateids to nfs4_preprocess_stateid_op NeilBrown
                   ` (3 subsequent siblings)
  22 siblings, 0 replies; 27+ 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] 27+ 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
                   ` (18 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
  2004-12-17  5:23 ` [PATCH kNFSd 19 of 23] Check for openmode violations given a delegation stateid NeilBrown
                   ` (2 subsequent siblings)
  22 siblings, 0 replies; 27+ 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] 27+ 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
                   ` (21 preceding siblings ...)
  2004-12-17  5:23 ` [PATCH kNFSd 21 of 23] Add the DELEGRETURN operation NeilBrown
@ 2004-12-17  5:23 ` NeilBrown
  22 siblings, 0 replies; 27+ 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] 27+ messages in thread

* [PATCH kNFSd 21 of 23] Add the DELEGRETURN operation.
  2004-12-17  5:23 [PATCH kNFSd 0 of 23] Introduction NeilBrown
                   ` (20 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 22 of 23] Add to the laundromat service for delegations NeilBrown
  22 siblings, 0 replies; 27+ 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] 27+ 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; 27+ 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] 27+ 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; 27+ 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] 27+ 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; 27+ 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] 27+ messages in thread

end of thread, other threads:[~2004-12-21 15:56 UTC | newest]

Thread overview: 27+ 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 3 of 23] Count the nfs4_client structure usage 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 7 of 23] Get rid of the special delegation_stateid_t, use the existing stateid_t 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 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 2 of 23] Check the callback netid in gen_callback 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 9 of 23] Allocate and initialize the delegation structure 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 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 11 of 23] Add the delegation release and free functions NeilBrown
2004-12-17  5:23 ` [PATCH kNFSd 18 of 23] Remove unnecessary stateowner existence check NeilBrown
2004-12-17  5:23 ` [PATCH kNFSd 15 of 23] Kernel thread for delegation callback NeilBrown
2004-12-17  5:23 ` [PATCH kNFSd 14 of 23] Delegation recall callback rpc 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 13 of 23] Delay nfsd_colse for delegations until reaping 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 20 of 23] Add checking of delegation stateids to nfs4_preprocess_stateid_op 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 21 of 23] Add the DELEGRETURN operation NeilBrown
2004-12-17  5:23 ` [PATCH kNFSd 22 of 23] Add to the laundromat service for delegations NeilBrown

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.