patch-2.2.2 linux/fs/lockd/clntproc.c

Next file: linux/fs/lockd/svc.c
Previous file: linux/fs/inode.c
Back to the patch index
Back to the overall index

diff -u --recursive --new-file v2.2.1/linux/fs/lockd/clntproc.c linux/fs/lockd/clntproc.c
@@ -30,6 +30,14 @@
  */
 static u32	nlm_cookie = 0x1234;
 
+static inline void nlmclnt_next_cookie(struct nlm_cookie *c)
+{
+	memcpy(c->data, &nlm_cookie, 4);
+	memset(c->data+4, 0, 4);
+	c->len=4;
+	nlm_cookie++;
+}
+
 /*
  * Initialize arguments for TEST/LOCK/UNLOCK/CANCEL calls
  */
@@ -40,7 +48,7 @@
 	struct nlm_lock	*lock = &argp->lock;
 
 	memset(argp, 0, sizeof(*argp));
-	argp->cookie  = nlm_cookie++;
+	nlmclnt_next_cookie(&argp->cookie);
 	argp->state   = nsm_local_state;
 	lock->fh      = *NFS_FH(fl->fl_file->f_dentry);
 	lock->caller  = system_utsname.nodename;
@@ -57,7 +65,7 @@
 int
 nlmclnt_setgrantargs(struct nlm_rqst *call, struct nlm_lock *lock)
 {
-	call->a_args.cookie  = nlm_cookie++;
+	nlmclnt_next_cookie(&call->a_args.cookie);
 	call->a_args.lock    = *lock;
 	call->a_args.lock.caller = system_utsname.nodename;
 
@@ -230,9 +238,24 @@
 		/* Perform the RPC call. If an error occurs, try again */
 		if ((status = rpc_call(clnt, proc, argp, resp, 0)) < 0) {
 			dprintk("lockd: rpc_call returned error %d\n", -status);
-			if (status == -ERESTARTSYS)
-				return status;
-			nlm_rebind_host(host);
+			switch (status) {
+			case -EPROTONOSUPPORT:
+				status = -EINVAL;
+				break;
+			case -ECONNREFUSED:
+			case -ETIMEDOUT:
+			case -ENOTCONN:
+				status = -EAGAIN;
+				break;
+			case -ERESTARTSYS:
+				return signalled () ? -EINTR : status;
+			default:
+				break;
+			}
+			if (req->a_args.block)
+				nlm_rebind_host(host);
+			else
+				break;
 		} else
 		if (resp->status == NLM_LCK_DENIED_GRACE_PERIOD) {
 			dprintk("lockd: server in grace period\n");
@@ -248,9 +271,18 @@
 
 		/* Back off a little and try again */
 		interruptible_sleep_on_timeout(&host->h_gracewait, 15*HZ);
-	} while (!signalled());
 
-	return -ERESTARTSYS;
+		/* When the lock requested by F_SETLKW isn't available,
+		   we will wait until the request can be satisfied. If
+		   a signal is received during wait, we should return
+		   -EINTR. */
+		if (signalled ()) {
+			status = -EINTR;
+			break;
+		}
+	} while (1);
+
+	return status;
 }
 
 /*

FUNET's LINUX-ADM group, linux-adm@nic.funet.fi
TCL-scripts by Sam Shen (who was at: slshen@lbl.gov)