aboutsummaryrefslogtreecommitdiffstats
path: root/fs/nfs/dir.c
diff options
context:
space:
mode:
authorChuck Lever <cel@citi.umich.edu>2005-08-18 14:24:12 -0400
committerLinus Torvalds <torvalds@g5.osdl.org>2005-08-18 15:53:57 -0400
commitdc59250c6ebed099a9bc0a11298e2281dd896657 (patch)
tree80c294437c0868d90abfa617d873370e6dbe6565 /fs/nfs/dir.c
parent412d582ec1dd59aab2353f8cb7e74f2c79cd20b9 (diff)
[PATCH] NFS: Introduce the use of inode->i_lock to protect fields in nfsi
Down the road we want to eliminate the use of the global kernel lock entirely from the NFS client. To do this, we need to protect the fields in the nfs_inode structure adequately. Start by serializing updates to the "cache_validity" field. Note this change addresses an SMP hang found by njw@osdl.org, where processes deadlock because nfs_end_data_update and nfs_revalidate_mapping update the "cache_validity" field without proper serialization. Test plan: Millions of fsx ops on SMP clients. Run Nick Wilson's breaknfs program on large SMP clients. Signed-off-by: Chuck Lever <cel@netapp.com> Cc: Trond Myklebust <trond.myklebust@fys.uio.no> Signed-off-by: Andrew Morton <akpm@osdl.org> Signed-off-by: Linus Torvalds <torvalds@osdl.org>
Diffstat (limited to 'fs/nfs/dir.c')
-rw-r--r--fs/nfs/dir.c7
1 files changed, 7 insertions, 0 deletions
diff --git a/fs/nfs/dir.c b/fs/nfs/dir.c
index 27cf5577f239..147cbf9261ce 100644
--- a/fs/nfs/dir.c
+++ b/fs/nfs/dir.c
@@ -189,7 +189,9 @@ int nfs_readdir_filler(nfs_readdir_descriptor_t *desc, struct page *page)
189 goto error; 189 goto error;
190 } 190 }
191 SetPageUptodate(page); 191 SetPageUptodate(page);
192 spin_lock(&inode->i_lock);
192 NFS_I(inode)->cache_validity |= NFS_INO_INVALID_ATIME; 193 NFS_I(inode)->cache_validity |= NFS_INO_INVALID_ATIME;
194 spin_unlock(&inode->i_lock);
193 /* Ensure consistent page alignment of the data. 195 /* Ensure consistent page alignment of the data.
194 * Note: assumes we have exclusive access to this mapping either 196 * Note: assumes we have exclusive access to this mapping either
195 * through inode->i_sem or some other mechanism. 197 * through inode->i_sem or some other mechanism.
@@ -462,7 +464,9 @@ int uncached_readdir(nfs_readdir_descriptor_t *desc, void *dirent,
462 page, 464 page,
463 NFS_SERVER(inode)->dtsize, 465 NFS_SERVER(inode)->dtsize,
464 desc->plus); 466 desc->plus);
467 spin_lock(&inode->i_lock);
465 NFS_I(inode)->cache_validity |= NFS_INO_INVALID_ATIME; 468 NFS_I(inode)->cache_validity |= NFS_INO_INVALID_ATIME;
469 spin_unlock(&inode->i_lock);
466 desc->page = page; 470 desc->page = page;
467 desc->ptr = kmap(page); /* matching kunmap in nfs_do_filldir */ 471 desc->ptr = kmap(page); /* matching kunmap in nfs_do_filldir */
468 if (desc->error >= 0) { 472 if (desc->error >= 0) {
@@ -1596,7 +1600,10 @@ void nfs_access_add_cache(struct inode *inode, struct nfs_access_entry *set)
1596 put_rpccred(cache->cred); 1600 put_rpccred(cache->cred);
1597 cache->cred = get_rpccred(set->cred); 1601 cache->cred = get_rpccred(set->cred);
1598 } 1602 }
1603 /* FIXME: replace current access_cache BKL reliance with inode->i_lock */
1604 spin_lock(&inode->i_lock);
1599 nfsi->cache_validity &= ~NFS_INO_INVALID_ACCESS; 1605 nfsi->cache_validity &= ~NFS_INO_INVALID_ACCESS;
1606 spin_unlock(&inode->i_lock);
1600 cache->jiffies = set->jiffies; 1607 cache->jiffies = set->jiffies;
1601 cache->mask = set->mask; 1608 cache->mask = set->mask;
1602} 1609}