Login
[x]
Log in using an account from:
Fedora Account System
Red Hat Associate
Red Hat Customer
Or login using a Red Hat Bugzilla account
Forgot Password
Login:
Hide Forgot
Create an Account
Red Hat Bugzilla – Attachment 292959 Details for
Bug 429391
complete hang of NFSv4 client using Eye of Gnome
[?]
New
Simple Search
Advanced Search
My Links
Browse
Requests
Reports
Current State
Search
Tabular reports
Graphical reports
Duplicates
Other Reports
User Changes
Plotly Reports
Bug Status
Bug Severity
Non-Defaults
|
Product Dashboard
Help
Page Help!
Bug Writing Guidelines
What's new
Browser Support Policy
5.0.4.rh83 Release notes
FAQ
Guides index
User guide
Web Services
Contact
Legal
This site requires JavaScript to be enabled to function correctly, please enable it.
[patch]
Possible patch
linux-2.6.18-037-make_asynchronous_delegreturn.dif (text/plain), 6.99 KB, created by
Peter Staubach
on 2008-01-25 16:35:13 UTC
(
hide
)
Description:
Possible patch
Filename:
MIME Type:
Creator:
Peter Staubach
Created:
2008-01-25 16:35:13 UTC
Size:
6.99 KB
patch
obsolete
>From: Trond Myklebust <Trond.Myklebust@netapp.com> >Date: Thu, 24 Jan 2008 17:45:39 -0500 >NFS: Add an asynchronous delegreturn operation for use in nfs_clear_inode >Subject: No Subject >Message-Id: <1201220636.21748.3.camel@heimdal.trondhjem.org> >Mime-Version: 1.0 > >Otherwise, there is a potential deadlock if the last dput() from an NFSv4 >close() or other asynchronous operation leads to nfs_clear_inode calling >the synchronous delegreturn. > >Signed-off-by: Trond Myklebust <Trond.Myklebust@netapp.com> >--- > > fs/nfs/delegation.c | 52 +++++++++++++++++++++++++++++++++++++++------------ > fs/nfs/delegation.h | 3 ++- > fs/nfs/inode.c | 2 +- > fs/nfs/nfs4proc.c | 22 +++++++++++++--------- > 4 files changed, 56 insertions(+), 23 deletions(-) > >diff --git a/fs/nfs/delegation.c b/fs/nfs/delegation.c >index 8a7eb8e..3772b21 100644 >--- a/fs/nfs/delegation.c >+++ b/fs/nfs/delegation.c >@@ -155,15 +155,50 @@ int nfs_inode_set_delegation(struct inode *inode, struct rpc_cred *cred, struct > return status; > } > >-static int nfs_do_return_delegation(struct inode *inode, struct nfs_delegation *delegation) >+static int nfs_do_return_delegation(struct inode *inode, struct nfs_delegation *delegation, int issync) > { > int res = 0; > >- res = nfs4_proc_delegreturn(inode, delegation->cred, &delegation->stateid); >+ res = nfs4_proc_delegreturn(inode, delegation->cred, &delegation->stateid, issync); > nfs_free_delegation(delegation); > return res; > } > >+static struct nfs_delegation *nfs_detach_delegation(struct inode *inode) >+{ >+ struct nfs_client *clp = NFS_SERVER(inode)->nfs_client; >+ struct nfs_inode *nfsi = NFS_I(inode); >+ struct nfs_delegation *delegation; >+ >+ 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); >+ return delegation; >+} >+ >+/* >+ * This function returns the delegation without reclaiming opens >+ * or protecting against delegation reclaims. >+ * It is therefore really only safe to be called from >+ * nfs4_clear_inode() >+ */ >+void nfs_inode_return_delegation_noreclaim(struct inode *inode) >+{ >+ struct nfs_delegation *delegation; >+ >+ if (NFS_I(inode)->delegation == NULL) >+ return; >+ delegation = nfs_detach_delegation(inode); >+ if (delegation == NULL) >+ return; >+ nfs_do_return_delegation(inode, delegation, 1); >+} >+ > /* Sync all data to disk upon delegation return */ > static void nfs_msync_inode(struct inode *inode) > { >@@ -186,21 +221,14 @@ int __nfs_inode_return_delegation(struct 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); >+ delegation = nfs_detach_delegation(inode); > nfs_delegation_claim_opens(inode); > up_write(&nfsi->rwsem); > up_read(&clp->cl_sem); > nfs_msync_inode(inode); > > if (delegation != NULL) >- res = nfs_do_return_delegation(inode, delegation); >+ res = nfs_do_return_delegation(inode, delegation, 0); > return res; > } > >@@ -341,7 +369,7 @@ static int recall_thread(void *data) > nfs_msync_inode(inode); > > if (delegation != NULL) >- nfs_do_return_delegation(inode, delegation); >+ nfs_do_return_delegation(inode, delegation, 0); > iput(inode); > module_put_and_exit(0); > } >diff --git a/fs/nfs/delegation.h b/fs/nfs/delegation.h >index f6e42fb..cef3cdd 100644 >--- a/fs/nfs/delegation.h >+++ b/fs/nfs/delegation.h >@@ -28,6 +28,7 @@ int nfs_inode_set_delegation(struct inode *inode, struct rpc_cred *cred, struct > void nfs_inode_reclaim_delegation(struct inode *inode, struct rpc_cred *cred, struct nfs_openres *res); > int __nfs_inode_return_delegation(struct inode *inode); > int nfs_async_inode_return_delegation(struct inode *inode, const nfs4_stateid *stateid); >+void nfs_inode_return_delegation_noreclaim(struct inode *inode); > > struct inode *nfs_delegation_find_inode(struct nfs_client *clp, const struct nfs_fh *fhandle); > void nfs_return_all_delegations(struct super_block *sb); >@@ -38,7 +39,7 @@ void nfs_delegation_mark_reclaim(struct nfs_client *clp); > void nfs_delegation_reap_unclaimed(struct nfs_client *clp); > > /* NFSv4 delegation-related procedures */ >-int nfs4_proc_delegreturn(struct inode *inode, struct rpc_cred *cred, const nfs4_stateid *stateid); >+int nfs4_proc_delegreturn(struct inode *inode, struct rpc_cred *cred, const nfs4_stateid *stateid, int issync); > int nfs4_open_delegation_recall(struct nfs_open_context *ctx, struct nfs4_state *state); > int nfs4_lock_delegation_recall(struct nfs4_state *state, struct file_lock *fl); > int nfs4_copy_delegation_stateid(nfs4_stateid *dst, struct inode *inode); >diff --git a/fs/nfs/inode.c b/fs/nfs/inode.c >index b8a32e7..1e9ce09 100644 >--- a/fs/nfs/inode.c >+++ b/fs/nfs/inode.c >@@ -1050,7 +1050,7 @@ static int nfs_update_inode(struct inode *inode, struct nfs_fattr *fattr) > void nfs4_clear_inode(struct inode *inode) > { > /* If we are holding a delegation, return it! */ >- nfs_inode_return_delegation(inode); >+ nfs_inode_return_delegation_noreclaim(inode); > /* First call standard NFS clear_inode() code */ > nfs_clear_inode(inode); > } >diff --git a/fs/nfs/nfs4proc.c b/fs/nfs/nfs4proc.c >index fe43e69..802fa89 100644 >--- a/fs/nfs/nfs4proc.c >+++ b/fs/nfs/nfs4proc.c >@@ -3070,12 +3070,12 @@ static const struct rpc_call_ops nfs4_delegreturn_ops = { > .rpc_release = nfs4_delegreturn_release, > }; > >-static int _nfs4_proc_delegreturn(struct inode *inode, struct rpc_cred *cred, const nfs4_stateid *stateid) >+static int _nfs4_proc_delegreturn(struct inode *inode, struct rpc_cred *cred, const nfs4_stateid *stateid, int issync) > { > struct nfs4_delegreturndata *data; > struct nfs_server *server = NFS_SERVER(inode); > struct rpc_task *task; >- int status; >+ int status = 0; > > data = kmalloc(sizeof(*data), GFP_KERNEL); > if (data == NULL) >@@ -3094,23 +3094,27 @@ static int _nfs4_proc_delegreturn(struct inode *inode, struct rpc_cred *cred, co > task = rpc_run_task(NFS_CLIENT(inode), RPC_TASK_ASYNC, &nfs4_delegreturn_ops, data); > if (IS_ERR(task)) > return PTR_ERR(task); >+ if (!issync) >+ goto out; > status = nfs4_wait_for_completion_rpc_task(task); >- if (status == 0) { >- status = data->rpc_status; >- if (status == 0) >- nfs_refresh_inode(inode, &data->fattr); >- } >+ if (status != 0) >+ goto out; >+ status = data->rpc_status; >+ if (status != 0) >+ goto out; >+ nfs_refresh_inode(inode, &data->fattr); >+out: > rpc_put_task(task); > return status; > } > >-int nfs4_proc_delegreturn(struct inode *inode, struct rpc_cred *cred, const nfs4_stateid *stateid) >+int nfs4_proc_delegreturn(struct inode *inode, struct rpc_cred *cred, const nfs4_stateid *stateid, int issync) > { > struct nfs_server *server = NFS_SERVER(inode); > struct nfs4_exception exception = { }; > int err; > do { >- err = _nfs4_proc_delegreturn(inode, cred, stateid); >+ err = _nfs4_proc_delegreturn(inode, cred, stateid, issync); > switch (err) { > case -NFS4ERR_STALE_STATEID: > case -NFS4ERR_EXPIRED:
You cannot view the attachment while viewing its details because your browser does not support IFRAMEs.
View the attachment on a separate page
.
View Attachment As Diff
View Attachment As Raw
Actions:
View
|
Diff
Attachments on
bug 429391
:
292272
|
292273
|
292415
|
292593
|
292594
|
292959
|
292987
|
293154