Message ID | 20110411040209.GA21395@dastard (mailing list archive) |
---|---|
State | New, archived |
Headers | show |
On 14:02 Mon 11 Apr , Dave Chinner wrote: > On Sat, Apr 09, 2011 at 10:55:02PM -0400, Will Simoneau wrote: > > This seems to happen consistently when running "apt-get update". Ideas? > > Known bug? > > The bug is in nfs_commit_inode(), where it calls nfs_scan_commit() > with the inode->i_lock held and that calls __mark_inode_dirty() > which takes the inode->i_lock.... > > The patch below should fix this problem. I can confirm that your patch fixes the issue. Thanks for the fix! Tested-by: Will Simoneau <simoneau@ele.uri.edu>
diff --git a/fs/nfs/write.c b/fs/nfs/write.c index af0c627..e4cbc11 100644 --- a/fs/nfs/write.c +++ b/fs/nfs/write.c @@ -542,11 +542,15 @@ nfs_scan_commit(struct inode *inode, struct list_head *dst, pgoff_t idx_start, u if (!nfs_need_commit(nfsi)) return 0; + spin_lock(&inode->i_lock); ret = nfs_scan_list(nfsi, dst, idx_start, npages, NFS_PAGE_TAG_COMMIT); if (ret > 0) nfsi->ncommit -= ret; + spin_unlock(&inode->i_lock); + if (nfs_need_commit(NFS_I(inode))) __mark_inode_dirty(inode, I_DIRTY_DATASYNC); + return ret; } #else @@ -1483,9 +1487,7 @@ int nfs_commit_inode(struct inode *inode, int how) res = nfs_commit_set_lock(NFS_I(inode), may_wait); if (res <= 0) goto out_mark_dirty; - spin_lock(&inode->i_lock); res = nfs_scan_commit(inode, &head, 0, 0); - spin_unlock(&inode->i_lock); if (res) { int error;