aboutsummaryrefslogtreecommitdiffstats
path: root/fs/nfs/dir.c
diff options
context:
space:
mode:
authorLinus Torvalds <torvalds@linux-foundation.org>2012-12-18 12:36:34 -0500
committerLinus Torvalds <torvalds@linux-foundation.org>2012-12-18 12:36:34 -0500
commit2d4dce0070448bcb5ccd04553a4be4635417f565 (patch)
tree300915d2df0b8f28072d090c21d8ac084cd5f6c0 /fs/nfs/dir.c
parentea88eeac0cb8328014b53d80ca631e8dc0dc18dc (diff)
parentcd6c5968582a273561464fe6b1e8cc8214be02df (diff)
Merge tag 'nfs-for-3.8-1' of git://git.linux-nfs.org/projects/trondmy/linux-nfs
Pull NFS client updates from Trond Myklebust: "Features include: - Full audit of BUG_ON asserts in the NFS, SUNRPC and lockd client code. Remove altogether where possible, and replace with WARN_ON_ONCE and appropriate error returns where not. - NFSv4.1 client adds session dynamic slot table management. There is matching server side code that has been submitted to Bruce for consideration. Together, this code allows the server to dynamically manage the amount of memory it allocates to the duplicate request cache for each client. It will constantly resize those caches to reserve more memory for clients that are hot while shrinking caches for those that are quiescent. In addition, there are assorted bugfixes for the generic NFS write code, fixes to deal with the drop_nlink() warnings, and yet another fix for NFSv4 getacl." * tag 'nfs-for-3.8-1' of git://git.linux-nfs.org/projects/trondmy/linux-nfs: (106 commits) SUNRPC: continue run over clients list on PipeFS event instead of break NFS: Don't use SetPageError in the NFS writeback code SUNRPC: variable 'svsk' is unused in function bc_send_request SUNRPC: Handle ECONNREFUSED in xs_local_setup_socket NFSv4.1: Deal effectively with interrupted RPC calls. NFSv4.1: Move the RPC timestamp out of the slot. NFSv4.1: Try to deal with NFS4ERR_SEQ_MISORDERED. NFS: nfs_lookup_revalidate should not trust an inode with i_nlink == 0 NFS: Fix calls to drop_nlink() NFS: Ensure that we always drop inodes that have been marked as stale nfs: Remove unused list nfs4_clientid_list nfs: Remove duplicate function declaration in internal.h NFS: avoid NULL dereference in nfs_destroy_server SUNRPC handle EKEYEXPIRED in call_refreshresult SUNRPC set gss gc_expiry to full lifetime nfs: fix page dirtying in NFS DIO read codepath nfs: don't zero out the rest of the page if we hit the EOF on a DIO READ NFSv4.1: Be conservative about the client highest slotid NFSv4.1: Handle NFS4ERR_BADSLOT errors correctly nfs: don't extend writes to cover entire page if pagecache is invalid ...
Diffstat (limited to 'fs/nfs/dir.c')
-rw-r--r--fs/nfs/dir.c22
1 files changed, 14 insertions, 8 deletions
diff --git a/fs/nfs/dir.c b/fs/nfs/dir.c
index 1cc71f60b491..32e6c53520e2 100644
--- a/fs/nfs/dir.c
+++ b/fs/nfs/dir.c
@@ -979,10 +979,11 @@ static int nfs_is_exclusive_create(struct inode *dir, unsigned int flags)
979 * particular file and the "nocto" mount flag is not set. 979 * particular file and the "nocto" mount flag is not set.
980 * 980 *
981 */ 981 */
982static inline 982static
983int nfs_lookup_verify_inode(struct inode *inode, unsigned int flags) 983int nfs_lookup_verify_inode(struct inode *inode, unsigned int flags)
984{ 984{
985 struct nfs_server *server = NFS_SERVER(inode); 985 struct nfs_server *server = NFS_SERVER(inode);
986 int ret;
986 987
987 if (IS_AUTOMOUNT(inode)) 988 if (IS_AUTOMOUNT(inode))
988 return 0; 989 return 0;
@@ -993,9 +994,13 @@ int nfs_lookup_verify_inode(struct inode *inode, unsigned int flags)
993 if ((flags & LOOKUP_OPEN) && !(server->flags & NFS_MOUNT_NOCTO) && 994 if ((flags & LOOKUP_OPEN) && !(server->flags & NFS_MOUNT_NOCTO) &&
994 (S_ISREG(inode->i_mode) || S_ISDIR(inode->i_mode))) 995 (S_ISREG(inode->i_mode) || S_ISDIR(inode->i_mode)))
995 goto out_force; 996 goto out_force;
996 return 0; 997out:
998 return (inode->i_nlink == 0) ? -ENOENT : 0;
997out_force: 999out_force:
998 return __nfs_revalidate_inode(server, inode); 1000 ret = __nfs_revalidate_inode(server, inode);
1001 if (ret != 0)
1002 return ret;
1003 goto out;
999} 1004}
1000 1005
1001/* 1006/*
@@ -1156,11 +1161,14 @@ static int nfs_dentry_delete(const struct dentry *dentry)
1156 1161
1157} 1162}
1158 1163
1164/* Ensure that we revalidate inode->i_nlink */
1159static void nfs_drop_nlink(struct inode *inode) 1165static void nfs_drop_nlink(struct inode *inode)
1160{ 1166{
1161 spin_lock(&inode->i_lock); 1167 spin_lock(&inode->i_lock);
1162 if (inode->i_nlink > 0) 1168 /* drop the inode if we're reasonably sure this is the last link */
1163 drop_nlink(inode); 1169 if (inode->i_nlink == 1)
1170 clear_nlink(inode);
1171 NFS_I(inode)->cache_validity |= NFS_INO_INVALID_ATTR;
1164 spin_unlock(&inode->i_lock); 1172 spin_unlock(&inode->i_lock);
1165} 1173}
1166 1174
@@ -1175,8 +1183,8 @@ static void nfs_dentry_iput(struct dentry *dentry, struct inode *inode)
1175 NFS_I(inode)->cache_validity |= NFS_INO_INVALID_DATA; 1183 NFS_I(inode)->cache_validity |= NFS_INO_INVALID_DATA;
1176 1184
1177 if (dentry->d_flags & DCACHE_NFSFS_RENAMED) { 1185 if (dentry->d_flags & DCACHE_NFSFS_RENAMED) {
1178 drop_nlink(inode);
1179 nfs_complete_unlink(dentry, inode); 1186 nfs_complete_unlink(dentry, inode);
1187 nfs_drop_nlink(inode);
1180 } 1188 }
1181 iput(inode); 1189 iput(inode);
1182} 1190}
@@ -1647,10 +1655,8 @@ static int nfs_safe_remove(struct dentry *dentry)
1647 if (inode != NULL) { 1655 if (inode != NULL) {
1648 NFS_PROTO(inode)->return_delegation(inode); 1656 NFS_PROTO(inode)->return_delegation(inode);
1649 error = NFS_PROTO(dir)->remove(dir, &dentry->d_name); 1657 error = NFS_PROTO(dir)->remove(dir, &dentry->d_name);
1650 /* The VFS may want to delete this inode */
1651 if (error == 0) 1658 if (error == 0)
1652 nfs_drop_nlink(inode); 1659 nfs_drop_nlink(inode);
1653 nfs_mark_for_revalidate(inode);
1654 } else 1660 } else
1655 error = NFS_PROTO(dir)->remove(dir, &dentry->d_name); 1661 error = NFS_PROTO(dir)->remove(dir, &dentry->d_name);
1656 if (error == -ENOENT) 1662 if (error == -ENOENT)