SOURCES: linux-2.6.22-NFS_ALL.dif (NEW), linux-2.6.22-rc5-CITI_NFS...
baggins
baggins at pld-linux.org
Mon Aug 13 19:18:34 CEST 2007
Author: baggins Date: Mon Aug 13 17:18:34 2007 GMT
Module: SOURCES Tag: HEAD
---- Log message:
- NFS fixes and improvements
---- Files affected:
SOURCES:
linux-2.6.22-NFS_ALL.dif (NONE -> 1.1) (NEW), linux-2.6.22-rc5-CITI_NFS4_ALL-1.diff (NONE -> 1.1) (NEW)
---- Diffs:
================================================================
Index: SOURCES/linux-2.6.22-NFS_ALL.dif
diff -u /dev/null SOURCES/linux-2.6.22-NFS_ALL.dif:1.1
--- /dev/null Mon Aug 13 19:18:34 2007
+++ SOURCES/linux-2.6.22-NFS_ALL.dif Mon Aug 13 19:18:29 2007
@@ -0,0 +1,9738 @@
+All of the above
+---
+ fs/lockd/host.c | 39 +
+ fs/lockd/mon.c | 2
+ fs/lockd/svc.c | 6
+ fs/nfs/Makefile | 4
+ fs/nfs/client.c | 28 -
+ fs/nfs/delegation.c | 186 +++--
+ fs/nfs/delegation.h | 26 -
+ fs/nfs/dir.c | 16
+ fs/nfs/direct.c | 34 +
+ fs/nfs/inode.c | 73 +-
+ fs/nfs/internal.h | 4
+ fs/nfs/mount_clnt.c | 169 +++--
+ fs/nfs/nfs2xdr.c | 6
+ fs/nfs/nfs3proc.c | 4
+ fs/nfs/nfs3xdr.c | 8
+ fs/nfs/nfs4_fs.h | 40 +
+ fs/nfs/nfs4proc.c | 760 +++++++++++++---------
+ fs/nfs/nfs4state.c | 310 ++++++---
+ fs/nfs/nfs4xdr.c | 126 ++--
+ fs/nfs/nfsroot.c | 5
+ fs/nfs/pagelist.c | 60 +-
+ fs/nfs/read.c | 40 +
+ fs/nfs/super.c | 1189 +++++++++++++++++++++++++++++-----
+ fs/nfs/write.c | 149 ++--
+ fs/nfsd/nfs4callback.c | 18 -
+ fs/nfsd/nfs4state.c | 1
+ include/linux/lockd/lockd.h | 1
+ include/linux/nfs4.h | 1
+ include/linux/nfs4_mount.h | 3
+ include/linux/nfs_fs.h | 28 -
+ include/linux/nfs_fs_sb.h | 8
+ include/linux/nfs_mount.h | 3
+ include/linux/nfs_page.h | 25 -
+ include/linux/nfs_xdr.h | 5
+ include/linux/sunrpc/auth.h | 48 +
+ include/linux/sunrpc/auth_gss.h | 6
+ include/linux/sunrpc/clnt.h | 33 -
+ include/linux/sunrpc/gss_api.h | 2
+ include/linux/sunrpc/rpc_pipe_fs.h | 2
+ include/linux/sunrpc/sched.h | 6
+ include/linux/sunrpc/svcsock.h | 1
+ include/linux/sunrpc/xprt.h | 16
+ kernel/auditsc.c | 1
+ net/sunrpc/auth.c | 357 +++++++---
+ net/sunrpc/auth_gss/auth_gss.c | 339 ++++++----
+ net/sunrpc/auth_gss/gss_krb5_mech.c | 2
+ net/sunrpc/auth_gss/gss_spkm3_mech.c | 2
+ net/sunrpc/auth_null.c | 10
+ net/sunrpc/auth_unix.c | 54 +-
+ net/sunrpc/clnt.c | 367 +++++++---
+ net/sunrpc/rpc_pipe.c | 87 ++
+ net/sunrpc/rpcb_clnt.c | 65 +-
+ net/sunrpc/sched.c | 209 ++----
+ net/sunrpc/sunrpc_syms.c | 8
+ net/sunrpc/svcsock.c | 20 +
+ net/sunrpc/xprt.c | 19 -
+ net/sunrpc/xprtsock.c | 81 +-
+ 57 files changed, 3305 insertions(+), 1807 deletions(-)
+
+diff --git a/fs/lockd/host.c b/fs/lockd/host.c
+index 96070bf..572601e 100644
+--- a/fs/lockd/host.c
++++ b/fs/lockd/host.c
+@@ -44,9 +44,8 @@ static struct nsm_handle * nsm_find(const struct sockaddr_in *sin,
+ */
+ static struct nlm_host *
+ nlm_lookup_host(int server, const struct sockaddr_in *sin,
+- int proto, int version,
+- const char *hostname,
+- int hostname_len)
++ int proto, int version, const char *hostname,
++ int hostname_len, const struct sockaddr_in *ssin)
+ {
+ struct hlist_head *chain;
+ struct hlist_node *pos;
+@@ -54,7 +53,9 @@ nlm_lookup_host(int server, const struct sockaddr_in *sin,
+ struct nsm_handle *nsm = NULL;
+ int hash;
+
+- dprintk("lockd: nlm_lookup_host(%u.%u.%u.%u, p=%d, v=%d, my role=%s, name=%.*s)\n",
++ dprintk("lockd: nlm_lookup_host("NIPQUAD_FMT"->"NIPQUAD_FMT
++ ", p=%d, v=%d, my role=%s, name=%.*s)\n",
++ NIPQUAD(ssin->sin_addr.s_addr),
+ NIPQUAD(sin->sin_addr.s_addr), proto, version,
+ server? "server" : "client",
+ hostname_len,
+@@ -91,6 +92,8 @@ nlm_lookup_host(int server, const struct sockaddr_in *sin,
+ continue;
+ if (host->h_server != server)
+ continue;
++ if (!nlm_cmp_addr(&host->h_saddr, ssin))
++ continue;
+
+ /* Move to head of hash chain. */
+ hlist_del(&host->h_hash);
+@@ -118,6 +121,7 @@ nlm_lookup_host(int server, const struct sockaddr_in *sin,
+ host->h_name = nsm->sm_name;
+ host->h_addr = *sin;
+ host->h_addr.sin_port = 0; /* ouch! */
++ host->h_saddr = *ssin;
+ host->h_version = version;
+ host->h_proto = proto;
+ host->h_rpcclnt = NULL;
+@@ -161,15 +165,9 @@ nlm_destroy_host(struct nlm_host *host)
+ */
+ nsm_unmonitor(host);
+
+- if ((clnt = host->h_rpcclnt) != NULL) {
+- if (atomic_read(&clnt->cl_users)) {
+- printk(KERN_WARNING
+- "lockd: active RPC handle\n");
+- clnt->cl_dead = 1;
+- } else {
+- rpc_destroy_client(host->h_rpcclnt);
+- }
+- }
++ clnt = host->h_rpcclnt;
++ if (clnt != NULL)
++ rpc_shutdown_client(clnt);
+ kfree(host);
+ }
+
+@@ -180,8 +178,10 @@ struct nlm_host *
+ nlmclnt_lookup_host(const struct sockaddr_in *sin, int proto, int version,
+ const char *hostname, int hostname_len)
+ {
++ struct sockaddr_in ssin = {0};
++
+ return nlm_lookup_host(0, sin, proto, version,
+- hostname, hostname_len);
++ hostname, hostname_len, &ssin);
+ }
+
+ /*
+@@ -191,9 +191,12 @@ struct nlm_host *
+ nlmsvc_lookup_host(struct svc_rqst *rqstp,
+ const char *hostname, int hostname_len)
+ {
++ struct sockaddr_in ssin = {0};
++
++ ssin.sin_addr = rqstp->rq_daddr.addr;
+ return nlm_lookup_host(1, svc_addr_in(rqstp),
+ rqstp->rq_prot, rqstp->rq_vers,
+- hostname, hostname_len);
++ hostname, hostname_len, &ssin);
+ }
+
+ /*
+@@ -204,8 +207,9 @@ nlm_bind_host(struct nlm_host *host)
+ {
+ struct rpc_clnt *clnt;
+
+- dprintk("lockd: nlm_bind_host(%08x)\n",
+- (unsigned)ntohl(host->h_addr.sin_addr.s_addr));
++ dprintk("lockd: nlm_bind_host("NIPQUAD_FMT"->"NIPQUAD_FMT")\n",
++ NIPQUAD(host->h_saddr.sin_addr),
++ NIPQUAD(host->h_addr.sin_addr));
+
+ /* Lock host handle */
+ mutex_lock(&host->h_mutex);
+@@ -232,6 +236,7 @@ nlm_bind_host(struct nlm_host *host)
+ .protocol = host->h_proto,
+ .address = (struct sockaddr *)&host->h_addr,
+ .addrsize = sizeof(host->h_addr),
++ .saddress = (struct sockaddr *)&host->h_saddr,
+ .timeout = &timeparms,
+ .servername = host->h_name,
+ .program = &nlm_program,
+diff --git a/fs/lockd/mon.c b/fs/lockd/mon.c
+index 2102e2d..3353ed8 100644
+--- a/fs/lockd/mon.c
++++ b/fs/lockd/mon.c
+@@ -61,6 +61,7 @@ nsm_mon_unmon(struct nsm_handle *nsm, u32 proc, struct nsm_res *res)
+ status);
+ else
+ status = 0;
++ rpc_shutdown_client(clnt);
+ out:
+ return status;
+ }
+@@ -138,7 +139,6 @@ nsm_create(void)
+ .program = &nsm_program,
+ .version = SM_VERSION,
+ .authflavor = RPC_AUTH_NULL,
+- .flags = (RPC_CLNT_CREATE_ONESHOT),
+ };
+
+ return rpc_create(&args);
+diff --git a/fs/lockd/svc.c b/fs/lockd/svc.c
+index 126b1bf..2680932 100644
+--- a/fs/lockd/svc.c
++++ b/fs/lockd/svc.c
+@@ -123,9 +123,6 @@ lockd(struct svc_rqst *rqstp)
+ /* Process request with signals blocked, but allow SIGKILL. */
+ allow_signal(SIGKILL);
+
+- /* kick rpciod */
+- rpciod_up();
+-
+ dprintk("NFS locking service started (ver " LOCKD_VERSION ").\n");
+
+ if (!nlm_timeout)
+@@ -202,9 +199,6 @@ lockd(struct svc_rqst *rqstp)
+ /* Exit the RPC thread */
+ svc_exit_thread(rqstp);
+
+- /* release rpciod */
+- rpciod_down();
+-
+ /* Release module */
+ unlock_kernel();
+ module_put_and_exit(0);
+diff --git a/fs/nfs/Makefile b/fs/nfs/Makefile
+index f4580b4..b55cb23 100644
+--- a/fs/nfs/Makefile
++++ b/fs/nfs/Makefile
+@@ -6,8 +6,8 @@ obj-$(CONFIG_NFS_FS) += nfs.o
+
+ nfs-y := client.o dir.o file.o getroot.o inode.o super.o nfs2xdr.o \
+ pagelist.o proc.o read.o symlink.o unlink.o \
+- write.o namespace.o
+-nfs-$(CONFIG_ROOT_NFS) += nfsroot.o mount_clnt.o
++ write.o namespace.o mount_clnt.o
++nfs-$(CONFIG_ROOT_NFS) += nfsroot.o
+ nfs-$(CONFIG_NFS_V3) += nfs3proc.o nfs3xdr.o
+ nfs-$(CONFIG_NFS_V3_ACL) += nfs3acl.o
+ nfs-$(CONFIG_NFS_V4) += nfs4proc.o nfs4xdr.o nfs4state.o nfs4renewd.o \
+diff --git a/fs/nfs/client.c b/fs/nfs/client.c
+index 881fa49..ccb4550 100644
+--- a/fs/nfs/client.c
++++ b/fs/nfs/client.c
+@@ -102,19 +102,10 @@ static struct nfs_client *nfs_alloc_client(const char *hostname,
+ int nfsversion)
+ {
+ struct nfs_client *clp;
+- int error;
+
+ if ((clp = kzalloc(sizeof(*clp), GFP_KERNEL)) == NULL)
+ goto error_0;
+
+- error = rpciod_up();
+- if (error < 0) {
+- dprintk("%s: couldn't start rpciod! Error = %d\n",
+- __FUNCTION__, error);
+- goto error_1;
+- }
+- __set_bit(NFS_CS_RPCIOD, &clp->cl_res_state);
+-
+ if (nfsversion == 4) {
+ if (nfs_callback_up() < 0)
+ goto error_2;
+@@ -139,8 +130,6 @@ static struct nfs_client *nfs_alloc_client(const char *hostname,
+ #ifdef CONFIG_NFS_V4
+ init_rwsem(&clp->cl_sem);
+ INIT_LIST_HEAD(&clp->cl_delegations);
+- INIT_LIST_HEAD(&clp->cl_state_owners);
+- INIT_LIST_HEAD(&clp->cl_unused);
+ spin_lock_init(&clp->cl_lock);
+ INIT_DELAYED_WORK(&clp->cl_renewd, nfs4_renew_state);
+ rpc_init_wait_queue(&clp->cl_rpcwaitq, "NFS client");
+@@ -154,9 +143,6 @@ error_3:
+ if (__test_and_clear_bit(NFS_CS_CALLBACK, &clp->cl_res_state))
+ nfs_callback_down();
+ error_2:
+- rpciod_down();
+- __clear_bit(NFS_CS_RPCIOD, &clp->cl_res_state);
+-error_1:
+ kfree(clp);
+ error_0:
+ return NULL;
+@@ -167,16 +153,7 @@ static void nfs4_shutdown_client(struct nfs_client *clp)
+ #ifdef CONFIG_NFS_V4
+ if (__test_and_clear_bit(NFS_CS_RENEWD, &clp->cl_res_state))
+ nfs4_kill_renewd(clp);
+- while (!list_empty(&clp->cl_unused)) {
+- struct nfs4_state_owner *sp;
+-
+- sp = list_entry(clp->cl_unused.next,
+- struct nfs4_state_owner,
+- so_list);
+- list_del(&sp->so_list);
+- kfree(sp);
+- }
+- BUG_ON(!list_empty(&clp->cl_state_owners));
++ BUG_ON(!RB_EMPTY_ROOT(&clp->cl_state_owners));
+ if (__test_and_clear_bit(NFS_CS_IDMAP, &clp->cl_res_state))
+ nfs_idmap_delete(clp);
+ #endif
+@@ -198,9 +175,6 @@ static void nfs_free_client(struct nfs_client *clp)
+ if (__test_and_clear_bit(NFS_CS_CALLBACK, &clp->cl_res_state))
+ nfs_callback_down();
+
+- if (__test_and_clear_bit(NFS_CS_RPCIOD, &clp->cl_res_state))
+- rpciod_down();
+-
+ kfree(clp->cl_hostname);
+ kfree(clp);
+
+diff --git a/fs/nfs/delegation.c b/fs/nfs/delegation.c
+index 7f37d1b..20ac403 100644
+--- a/fs/nfs/delegation.c
++++ b/fs/nfs/delegation.c
+@@ -27,6 +27,13 @@ static void nfs_free_delegation(struct nfs_delegation *delegation)
+ kfree(delegation);
+ }
+
++static void nfs_free_delegation_callback(struct rcu_head *head)
++{
++ struct nfs_delegation *delegation = container_of(head, struct nfs_delegation, rcu);
++
++ nfs_free_delegation(delegation);
++}
++
+ static int nfs_delegation_claim_locks(struct nfs_open_context *ctx, struct nfs4_state *state)
+ {
+ struct inode *inode = state->inode;
+@@ -57,7 +64,7 @@ out_err:
+ return status;
+ }
+
+-static void nfs_delegation_claim_opens(struct inode *inode)
++static void nfs_delegation_claim_opens(struct inode *inode, const nfs4_stateid *stateid)
+ {
+ struct nfs_inode *nfsi = NFS_I(inode);
+ struct nfs_open_context *ctx;
+@@ -72,9 +79,11 @@ again:
+ continue;
+ if (!test_bit(NFS_DELEGATED_STATE, &state->flags))
+ continue;
++ if (memcmp(state->stateid.data, stateid->data, sizeof(state->stateid.data)) != 0)
++ continue;
+ get_nfs_open_context(ctx);
+ spin_unlock(&inode->i_lock);
+- err = nfs4_open_delegation_recall(ctx->dentry, state);
++ err = nfs4_open_delegation_recall(ctx, state, stateid);
+ if (err >= 0)
+ err = nfs_delegation_claim_locks(ctx, state);
+ put_nfs_open_context(ctx);
+@@ -115,10 +124,6 @@ int nfs_inode_set_delegation(struct inode *inode, struct rpc_cred *cred, struct
+ struct nfs_delegation *delegation;
+ int status = 0;
+
+- /* Ensure we first revalidate the attributes and page cache! */
+- if ((nfsi->cache_validity & (NFS_INO_REVAL_PAGECACHE|NFS_INO_INVALID_ATTR)))
+- __nfs_revalidate_inode(NFS_SERVER(inode), inode);
+-
+ delegation = kmalloc(sizeof(*delegation), GFP_KERNEL);
+ if (delegation == NULL)
+ return -ENOMEM;
+@@ -131,10 +136,10 @@ int nfs_inode_set_delegation(struct inode *inode, struct rpc_cred *cred, struct
+ delegation->inode = inode;
+
+ spin_lock(&clp->cl_lock);
+- if (nfsi->delegation == NULL) {
+- list_add(&delegation->super_list, &clp->cl_delegations);
+- nfsi->delegation = delegation;
++ if (rcu_dereference(nfsi->delegation) == NULL) {
++ list_add_rcu(&delegation->super_list, &clp->cl_delegations);
+ nfsi->delegation_state = delegation->type;
++ rcu_assign_pointer(nfsi->delegation, delegation);
+ delegation = NULL;
+ } else {
+ if (memcmp(&delegation->stateid, &nfsi->delegation->stateid,
+@@ -145,6 +150,12 @@ int nfs_inode_set_delegation(struct inode *inode, struct rpc_cred *cred, struct
+ status = -EIO;
+ }
+ }
++
++ /* Ensure we revalidate the attributes and page cache! */
++ spin_lock(&inode->i_lock);
++ nfsi->cache_validity |= NFS_INO_REVAL_FORCED;
++ spin_unlock(&inode->i_lock);
++
+ spin_unlock(&clp->cl_lock);
+ kfree(delegation);
+ return status;
+@@ -155,7 +166,7 @@ static int nfs_do_return_delegation(struct inode *inode, struct nfs_delegation *
+ int res = 0;
+
+ res = nfs4_proc_delegreturn(inode, delegation->cred, &delegation->stateid);
+- nfs_free_delegation(delegation);
++ call_rcu(&delegation->rcu, nfs_free_delegation_callback);
+ return res;
+ }
+
+@@ -170,33 +181,55 @@ static void nfs_msync_inode(struct inode *inode)
+ /*
+ * Basic procedure for returning a delegation to the server
+ */
+-int __nfs_inode_return_delegation(struct inode *inode)
++static int __nfs_inode_return_delegation(struct inode *inode, struct nfs_delegation *delegation)
+ {
+ struct nfs_client *clp = NFS_SERVER(inode)->nfs_client;
+ struct nfs_inode *nfsi = NFS_I(inode);
+- struct nfs_delegation *delegation;
+- int res = 0;
+
+ nfs_msync_inode(inode);
+ down_read(&clp->cl_sem);
+ /* Guard against new delegated open calls */
+ down_write(&nfsi->rwsem);
+- spin_lock(&clp->cl_lock);
+- delegation = nfsi->delegation;
+- if (delegation != NULL) {
+- list_del_init(&delegation->super_list);
+- nfsi->delegation = NULL;
+- nfsi->delegation_state = 0;
+- }
+- spin_unlock(&clp->cl_lock);
+- nfs_delegation_claim_opens(inode);
++ nfs_delegation_claim_opens(inode, &delegation->stateid);
+ up_write(&nfsi->rwsem);
+ up_read(&clp->cl_sem);
+ nfs_msync_inode(inode);
+
+- if (delegation != NULL)
+- res = nfs_do_return_delegation(inode, delegation);
+- return res;
++ return nfs_do_return_delegation(inode, delegation);
++}
++
++static struct nfs_delegation *nfs_detach_delegation_locked(struct nfs_inode *nfsi, const nfs4_stateid *stateid)
++{
++ struct nfs_delegation *delegation = rcu_dereference(nfsi->delegation);
++
++ if (delegation == NULL)
++ goto nomatch;
++ if (stateid != NULL && memcmp(delegation->stateid.data, stateid->data,
++ sizeof(delegation->stateid.data)) != 0)
++ goto nomatch;
++ list_del_rcu(&delegation->super_list);
++ nfsi->delegation_state = 0;
++ rcu_assign_pointer(nfsi->delegation, NULL);
++ return delegation;
++nomatch:
++ return NULL;
++}
++
++int nfs_inode_return_delegation(struct inode *inode)
++{
++ struct nfs_client *clp = NFS_SERVER(inode)->nfs_client;
++ struct nfs_inode *nfsi = NFS_I(inode);
++ struct nfs_delegation *delegation;
++ int err = 0;
++
++ if (rcu_dereference(nfsi->delegation) != NULL) {
++ spin_lock(&clp->cl_lock);
++ delegation = nfs_detach_delegation_locked(nfsi, NULL);
++ spin_unlock(&clp->cl_lock);
++ if (delegation != NULL)
++ err = __nfs_inode_return_delegation(inode, delegation);
++ }
++ return err;
+ }
+
+ /*
+@@ -211,19 +244,23 @@ void nfs_return_all_delegations(struct super_block *sb)
+ if (clp == NULL)
+ return;
+ restart:
+- spin_lock(&clp->cl_lock);
+- list_for_each_entry(delegation, &clp->cl_delegations, super_list) {
++ rcu_read_lock();
++ list_for_each_entry_rcu(delegation, &clp->cl_delegations, super_list) {
+ if (delegation->inode->i_sb != sb)
+ continue;
+ inode = igrab(delegation->inode);
+ if (inode == NULL)
+ continue;
++ spin_lock(&clp->cl_lock);
++ delegation = nfs_detach_delegation_locked(NFS_I(inode), NULL);
+ spin_unlock(&clp->cl_lock);
+- nfs_inode_return_delegation(inode);
++ rcu_read_unlock();
++ if (delegation != NULL)
++ __nfs_inode_return_delegation(inode, delegation);
+ iput(inode);
+ goto restart;
+ }
+- spin_unlock(&clp->cl_lock);
++ rcu_read_unlock();
+ }
+
+ static int nfs_do_expire_all_delegations(void *ptr)
+@@ -234,22 +271,26 @@ static int nfs_do_expire_all_delegations(void *ptr)
+
+ allow_signal(SIGKILL);
+ restart:
+- spin_lock(&clp->cl_lock);
+ if (test_bit(NFS4CLNT_STATE_RECOVER, &clp->cl_state) != 0)
+ goto out;
+ if (test_bit(NFS4CLNT_LEASE_EXPIRED, &clp->cl_state) == 0)
+ goto out;
+- list_for_each_entry(delegation, &clp->cl_delegations, super_list) {
++ rcu_read_lock();
++ list_for_each_entry_rcu(delegation, &clp->cl_delegations, super_list) {
+ inode = igrab(delegation->inode);
+ if (inode == NULL)
+ continue;
++ spin_lock(&clp->cl_lock);
++ delegation = nfs_detach_delegation_locked(NFS_I(inode), NULL);
+ spin_unlock(&clp->cl_lock);
+- nfs_inode_return_delegation(inode);
++ rcu_read_unlock();
++ if (delegation)
++ __nfs_inode_return_delegation(inode, delegation);
+ iput(inode);
+ goto restart;
+ }
++ rcu_read_unlock();
+ out:
+- spin_unlock(&clp->cl_lock);
+ nfs_put_client(clp);
+ module_put_and_exit(0);
+ }
+@@ -280,17 +321,21 @@ void nfs_handle_cb_pathdown(struct nfs_client *clp)
+ if (clp == NULL)
+ return;
+ restart:
+- spin_lock(&clp->cl_lock);
+- list_for_each_entry(delegation, &clp->cl_delegations, super_list) {
++ rcu_read_lock();
++ list_for_each_entry_rcu(delegation, &clp->cl_delegations, super_list) {
+ inode = igrab(delegation->inode);
+ if (inode == NULL)
+ continue;
++ spin_lock(&clp->cl_lock);
++ delegation = nfs_detach_delegation_locked(NFS_I(inode), NULL);
+ spin_unlock(&clp->cl_lock);
+- nfs_inode_return_delegation(inode);
++ rcu_read_unlock();
++ if (delegation != NULL)
++ __nfs_inode_return_delegation(inode, delegation);
+ iput(inode);
+ goto restart;
+ }
+- spin_unlock(&clp->cl_lock);
++ rcu_read_unlock();
+ }
+
+ struct recall_threadargs {
+@@ -316,21 +361,14 @@ static int recall_thread(void *data)
+ down_read(&clp->cl_sem);
+ down_write(&nfsi->rwsem);
+ spin_lock(&clp->cl_lock);
+- delegation = nfsi->delegation;
+- if (delegation != NULL && memcmp(delegation->stateid.data,
+- args->stateid->data,
+- sizeof(delegation->stateid.data)) == 0) {
+- list_del_init(&delegation->super_list);
+- nfsi->delegation = NULL;
+- nfsi->delegation_state = 0;
++ delegation = nfs_detach_delegation_locked(nfsi, args->stateid);
++ if (delegation != NULL)
+ args->result = 0;
+- } else {
+- delegation = NULL;
++ else
+ args->result = -ENOENT;
+- }
+ spin_unlock(&clp->cl_lock);
+ complete(&args->started);
+- nfs_delegation_claim_opens(inode);
++ nfs_delegation_claim_opens(inode, args->stateid);
+ up_write(&nfsi->rwsem);
+ up_read(&clp->cl_sem);
+ nfs_msync_inode(inode);
+@@ -371,14 +409,14 @@ struct inode *nfs_delegation_find_inode(struct nfs_client *clp, const struct nfs
+ {
+ struct nfs_delegation *delegation;
+ struct inode *res = NULL;
+- spin_lock(&clp->cl_lock);
+- list_for_each_entry(delegation, &clp->cl_delegations, super_list) {
++ rcu_read_lock();
++ list_for_each_entry_rcu(delegation, &clp->cl_delegations, super_list) {
+ if (nfs_compare_fh(fhandle, &NFS_I(delegation->inode)->fh) == 0) {
+ res = igrab(delegation->inode);
+ break;
+ }
+ }
+- spin_unlock(&clp->cl_lock);
++ rcu_read_unlock();
+ return res;
+ }
+
+@@ -388,10 +426,10 @@ struct inode *nfs_delegation_find_inode(struct nfs_client *clp, const struct nfs
+ void nfs_delegation_mark_reclaim(struct nfs_client *clp)
+ {
+ struct nfs_delegation *delegation;
<<Diff was trimmed, longer than 597 lines>>
More information about the pld-cvs-commit
mailing list