dir.c (f3324a2a94c229831cfd42d871902cd4a9bd5e0f) | dir.c (912a108da767ae75cc929d2854e698aff527ec5d) |
---|---|
1/* 2 * linux/fs/nfs/dir.c 3 * 4 * Copyright (C) 1992 Rick Sladkey 5 * 6 * nfs directory handling functions 7 * 8 * 10 Apr 1996 Added silly rename for unlink --okir --- 974 unchanged lines hidden (view full) --- 983 NFS_I(dir)->cache_change_attribute++; 984} 985EXPORT_SYMBOL_GPL(nfs_force_lookup_revalidate); 986 987/* 988 * A check for whether or not the parent directory has changed. 989 * In the case it has, we assume that the dentries are untrustworthy 990 * and may need to be looked up again. | 1/* 2 * linux/fs/nfs/dir.c 3 * 4 * Copyright (C) 1992 Rick Sladkey 5 * 6 * nfs directory handling functions 7 * 8 * 10 Apr 1996 Added silly rename for unlink --okir --- 974 unchanged lines hidden (view full) --- 983 NFS_I(dir)->cache_change_attribute++; 984} 985EXPORT_SYMBOL_GPL(nfs_force_lookup_revalidate); 986 987/* 988 * A check for whether or not the parent directory has changed. 989 * In the case it has, we assume that the dentries are untrustworthy 990 * and may need to be looked up again. |
991 * If rcu_walk prevents us from performing a full check, return 0. |
|
991 */ | 992 */ |
992static int nfs_check_verifier(struct inode *dir, struct dentry *dentry) | 993static int nfs_check_verifier(struct inode *dir, struct dentry *dentry, 994 int rcu_walk) |
993{ | 995{ |
996 int ret; 997 |
|
994 if (IS_ROOT(dentry)) 995 return 1; 996 if (NFS_SERVER(dir)->flags & NFS_MOUNT_LOOKUP_CACHE_NONE) 997 return 0; 998 if (!nfs_verify_change_attribute(dir, dentry->d_time)) 999 return 0; 1000 /* Revalidate nfsi->cache_change_attribute before we declare a match */ | 998 if (IS_ROOT(dentry)) 999 return 1; 1000 if (NFS_SERVER(dir)->flags & NFS_MOUNT_LOOKUP_CACHE_NONE) 1001 return 0; 1002 if (!nfs_verify_change_attribute(dir, dentry->d_time)) 1003 return 0; 1004 /* Revalidate nfsi->cache_change_attribute before we declare a match */ |
1001 if (nfs_revalidate_inode(NFS_SERVER(dir), dir) < 0) | 1005 if (rcu_walk) 1006 ret = nfs_revalidate_inode_rcu(NFS_SERVER(dir), dir); 1007 else 1008 ret = nfs_revalidate_inode(NFS_SERVER(dir), dir); 1009 if (ret < 0) |
1002 return 0; 1003 if (!nfs_verify_change_attribute(dir, dentry->d_time)) 1004 return 0; 1005 return 1; 1006} 1007 1008/* 1009 * Use intent information to check whether or not we're going to do --- 39 unchanged lines hidden (view full) --- 1049} 1050 1051/* 1052 * We judge how long we want to trust negative 1053 * dentries by looking at the parent inode mtime. 1054 * 1055 * If parent mtime has changed, we revalidate, else we wait for a 1056 * period corresponding to the parent's attribute cache timeout value. | 1010 return 0; 1011 if (!nfs_verify_change_attribute(dir, dentry->d_time)) 1012 return 0; 1013 return 1; 1014} 1015 1016/* 1017 * Use intent information to check whether or not we're going to do --- 39 unchanged lines hidden (view full) --- 1057} 1058 1059/* 1060 * We judge how long we want to trust negative 1061 * dentries by looking at the parent inode mtime. 1062 * 1063 * If parent mtime has changed, we revalidate, else we wait for a 1064 * period corresponding to the parent's attribute cache timeout value. |
1065 * 1066 * If LOOKUP_RCU prevents us from performing a full check, return 1 1067 * suggesting a reval is needed. |
|
1057 */ 1058static inline 1059int nfs_neg_need_reval(struct inode *dir, struct dentry *dentry, 1060 unsigned int flags) 1061{ 1062 /* Don't revalidate a negative dentry if we're creating a new file */ 1063 if (flags & LOOKUP_CREATE) 1064 return 0; 1065 if (NFS_SERVER(dir)->flags & NFS_MOUNT_LOOKUP_CACHE_NONEG) 1066 return 1; | 1068 */ 1069static inline 1070int nfs_neg_need_reval(struct inode *dir, struct dentry *dentry, 1071 unsigned int flags) 1072{ 1073 /* Don't revalidate a negative dentry if we're creating a new file */ 1074 if (flags & LOOKUP_CREATE) 1075 return 0; 1076 if (NFS_SERVER(dir)->flags & NFS_MOUNT_LOOKUP_CACHE_NONEG) 1077 return 1; |
1067 return !nfs_check_verifier(dir, dentry); | 1078 return !nfs_check_verifier(dir, dentry, flags & LOOKUP_RCU); |
1068} 1069 1070/* 1071 * This is called every time the dcache has a lookup hit, 1072 * and we should check whether we can really trust that 1073 * lookup. 1074 * 1075 * NOTE! The hit can be a negative hit too, don't assume --- 20 unchanged lines hidden (view full) --- 1096 } else { 1097 parent = dget_parent(dentry); 1098 dir = parent->d_inode; 1099 } 1100 nfs_inc_stats(dir, NFSIOS_DENTRYREVALIDATE); 1101 inode = dentry->d_inode; 1102 1103 if (!inode) { | 1079} 1080 1081/* 1082 * This is called every time the dcache has a lookup hit, 1083 * and we should check whether we can really trust that 1084 * lookup. 1085 * 1086 * NOTE! The hit can be a negative hit too, don't assume --- 20 unchanged lines hidden (view full) --- 1107 } else { 1108 parent = dget_parent(dentry); 1109 dir = parent->d_inode; 1110 } 1111 nfs_inc_stats(dir, NFSIOS_DENTRYREVALIDATE); 1112 inode = dentry->d_inode; 1113 1114 if (!inode) { |
1104 if (flags & LOOKUP_RCU) 1105 return -ECHILD; 1106 1107 if (nfs_neg_need_reval(dir, dentry, flags)) | 1115 if (nfs_neg_need_reval(dir, dentry, flags)) { 1116 if (flags & LOOKUP_RCU) 1117 return -ECHILD; |
1108 goto out_bad; | 1118 goto out_bad; |
1119 } |
|
1109 goto out_valid_noent; 1110 } 1111 1112 if (is_bad_inode(inode)) { 1113 if (flags & LOOKUP_RCU) 1114 return -ECHILD; 1115 dfprintk(LOOKUPCACHE, "%s: %pd2 has dud inode\n", 1116 __func__, dentry); 1117 goto out_bad; 1118 } 1119 1120 if (NFS_PROTO(dir)->have_delegation(inode, FMODE_READ)) 1121 goto out_set_verifier; 1122 | 1120 goto out_valid_noent; 1121 } 1122 1123 if (is_bad_inode(inode)) { 1124 if (flags & LOOKUP_RCU) 1125 return -ECHILD; 1126 dfprintk(LOOKUPCACHE, "%s: %pd2 has dud inode\n", 1127 __func__, dentry); 1128 goto out_bad; 1129 } 1130 1131 if (NFS_PROTO(dir)->have_delegation(inode, FMODE_READ)) 1132 goto out_set_verifier; 1133 |
1123 if (flags & LOOKUP_RCU) 1124 return -ECHILD; 1125 | |
1126 /* Force a full look up iff the parent directory has changed */ | 1134 /* Force a full look up iff the parent directory has changed */ |
1127 if (!nfs_is_exclusive_create(dir, flags) && nfs_check_verifier(dir, dentry)) { | 1135 if (!nfs_is_exclusive_create(dir, flags) && 1136 nfs_check_verifier(dir, dentry, flags & LOOKUP_RCU)) { 1137 1138 if (flags & LOOKUP_RCU) 1139 return -ECHILD; 1140 |
1128 if (nfs_lookup_verify_inode(inode, flags)) 1129 goto out_zap_parent; 1130 goto out_valid; 1131 } 1132 | 1141 if (nfs_lookup_verify_inode(inode, flags)) 1142 goto out_zap_parent; 1143 goto out_valid; 1144 } 1145 |
1146 if (flags & LOOKUP_RCU) 1147 return -ECHILD; 1148 |
|
1133 if (NFS_STALE(inode)) 1134 goto out_bad; 1135 1136 error = -ENOMEM; 1137 fhandle = nfs_alloc_fhandle(); 1138 fattr = nfs_alloc_fattr(); 1139 if (fhandle == NULL || fattr == NULL) 1140 goto out_error; --- 420 unchanged lines hidden (view full) --- 1561 1562 /* We can't create new files in nfs_open_revalidate(), so we 1563 * optimize away revalidation of negative dentries. 1564 */ 1565 if (inode == NULL) { 1566 struct dentry *parent; 1567 struct inode *dir; 1568 | 1149 if (NFS_STALE(inode)) 1150 goto out_bad; 1151 1152 error = -ENOMEM; 1153 fhandle = nfs_alloc_fhandle(); 1154 fattr = nfs_alloc_fattr(); 1155 if (fhandle == NULL || fattr == NULL) 1156 goto out_error; --- 420 unchanged lines hidden (view full) --- 1577 1578 /* We can't create new files in nfs_open_revalidate(), so we 1579 * optimize away revalidation of negative dentries. 1580 */ 1581 if (inode == NULL) { 1582 struct dentry *parent; 1583 struct inode *dir; 1584 |
1569 if (flags & LOOKUP_RCU) 1570 return -ECHILD; 1571 1572 parent = dget_parent(dentry); 1573 dir = parent->d_inode; | 1585 if (flags & LOOKUP_RCU) { 1586 parent = rcu_dereference(dentry); 1587 dir = ACCESS_ONCE(parent->d_inode); 1588 if (!dir) 1589 return -ECHILD; 1590 } else { 1591 parent = dget_parent(dentry); 1592 dir = parent->d_inode; 1593 } |
1574 if (!nfs_neg_need_reval(dir, dentry, flags)) 1575 ret = 1; | 1594 if (!nfs_neg_need_reval(dir, dentry, flags)) 1595 ret = 1; |
1576 dput(parent); | 1596 else if (flags & LOOKUP_RCU) 1597 ret = -ECHILD; 1598 if (!(flags & LOOKUP_RCU)) 1599 dput(parent); 1600 else if (parent != rcu_dereference(dentry)) 1601 return -ECHILD; |
1577 goto out; 1578 } 1579 1580 /* NFS only supports OPEN on regular files */ 1581 if (!S_ISREG(inode->i_mode)) 1582 goto no_open; 1583 /* We cannot do exclusive creation on a positive dentry */ 1584 if (flags & LOOKUP_EXCL) --- 855 unchanged lines hidden --- | 1602 goto out; 1603 } 1604 1605 /* NFS only supports OPEN on regular files */ 1606 if (!S_ISREG(inode->i_mode)) 1607 goto no_open; 1608 /* We cannot do exclusive creation on a positive dentry */ 1609 if (flags & LOOKUP_EXCL) --- 855 unchanged lines hidden --- |