aboutsummaryrefslogtreecommitdiffstats
path: root/fs
diff options
context:
space:
mode:
authorChristoph Hellwig <hch@lst.de>2009-01-05 13:10:37 -0500
committerAl Viro <viro@zeniv.linux.org.uk>2009-03-27 14:43:57 -0400
commitb6520c81934848cef126d93951f7ce242e0f656d (patch)
treedda2be723ee831eb1d33ead7f22335f7817f9c61 /fs
parent2b1c6bd77d4e6a727ffac8630cd154b2144b751a (diff)
cleanup d_add_ci
Make sure that comments describe what's going on and not how, and always use __d_instantiate instead of two separate branches, one with d_instantiate and one with __d_instantiate. Signed-off-by: Christoph Hellwig <hch@lst.de> Signed-off-by: Al Viro <viro@zeniv.linux.org.uk>
Diffstat (limited to 'fs')
-rw-r--r--fs/dcache.c48
1 files changed, 18 insertions, 30 deletions
diff --git a/fs/dcache.c b/fs/dcache.c
index 07e2d4a44bda..90bbd7e1b116 100644
--- a/fs/dcache.c
+++ b/fs/dcache.c
@@ -1247,15 +1247,18 @@ struct dentry *d_add_ci(struct dentry *dentry, struct inode *inode,
1247 struct dentry *found; 1247 struct dentry *found;
1248 struct dentry *new; 1248 struct dentry *new;
1249 1249
1250 /* Does a dentry matching the name exist already? */ 1250 /*
1251 * First check if a dentry matching the name already exists,
1252 * if not go ahead and create it now.
1253 */
1251 found = d_hash_and_lookup(dentry->d_parent, name); 1254 found = d_hash_and_lookup(dentry->d_parent, name);
1252 /* If not, create it now and return */
1253 if (!found) { 1255 if (!found) {
1254 new = d_alloc(dentry->d_parent, name); 1256 new = d_alloc(dentry->d_parent, name);
1255 if (!new) { 1257 if (!new) {
1256 error = -ENOMEM; 1258 error = -ENOMEM;
1257 goto err_out; 1259 goto err_out;
1258 } 1260 }
1261
1259 found = d_splice_alias(inode, new); 1262 found = d_splice_alias(inode, new);
1260 if (found) { 1263 if (found) {
1261 dput(new); 1264 dput(new);
@@ -1263,61 +1266,46 @@ struct dentry *d_add_ci(struct dentry *dentry, struct inode *inode,
1263 } 1266 }
1264 return new; 1267 return new;
1265 } 1268 }
1266 /* Matching dentry exists, check if it is negative. */ 1269
1270 /*
1271 * If a matching dentry exists, and it's not negative use it.
1272 *
1273 * Decrement the reference count to balance the iget() done
1274 * earlier on.
1275 */
1267 if (found->d_inode) { 1276 if (found->d_inode) {
1268 if (unlikely(found->d_inode != inode)) { 1277 if (unlikely(found->d_inode != inode)) {
1269 /* This can't happen because bad inodes are unhashed. */ 1278 /* This can't happen because bad inodes are unhashed. */
1270 BUG_ON(!is_bad_inode(inode)); 1279 BUG_ON(!is_bad_inode(inode));
1271 BUG_ON(!is_bad_inode(found->d_inode)); 1280 BUG_ON(!is_bad_inode(found->d_inode));
1272 } 1281 }
1273 /*
1274 * Already have the inode and the dentry attached, decrement
1275 * the reference count to balance the iget() done
1276 * earlier on. We found the dentry using d_lookup() so it
1277 * cannot be disconnected and thus we do not need to worry
1278 * about any NFS/disconnectedness issues here.
1279 */
1280 iput(inode); 1282 iput(inode);
1281 return found; 1283 return found;
1282 } 1284 }
1285
1283 /* 1286 /*
1284 * Negative dentry: instantiate it unless the inode is a directory and 1287 * Negative dentry: instantiate it unless the inode is a directory and
1285 * has a 'disconnected' dentry (i.e. IS_ROOT and DCACHE_DISCONNECTED), 1288 * already has a dentry.
1286 * in which case d_move() that in place of the found dentry.
1287 */ 1289 */
1288 if (!S_ISDIR(inode->i_mode)) {
1289 /* Not a directory; everything is easy. */
1290 d_instantiate(found, inode);
1291 return found;
1292 }
1293 spin_lock(&dcache_lock); 1290 spin_lock(&dcache_lock);
1294 if (list_empty(&inode->i_dentry)) { 1291 if (!S_ISDIR(inode->i_mode) || list_empty(&inode->i_dentry)) {
1295 /*
1296 * Directory without a 'disconnected' dentry; we need to do
1297 * d_instantiate() by hand because it takes dcache_lock which
1298 * we already hold.
1299 */
1300 __d_instantiate(found, inode); 1292 __d_instantiate(found, inode);
1301 spin_unlock(&dcache_lock); 1293 spin_unlock(&dcache_lock);
1302 security_d_instantiate(found, inode); 1294 security_d_instantiate(found, inode);
1303 return found; 1295 return found;
1304 } 1296 }
1297
1305 /* 1298 /*
1306 * Directory with a 'disconnected' dentry; get a reference to the 1299 * In case a directory already has a (disconnected) entry grab a
1307 * 'disconnected' dentry. 1300 * reference to it, move it in place and use it.
1308 */ 1301 */
1309 new = list_entry(inode->i_dentry.next, struct dentry, d_alias); 1302 new = list_entry(inode->i_dentry.next, struct dentry, d_alias);
1310 dget_locked(new); 1303 dget_locked(new);
1311 spin_unlock(&dcache_lock); 1304 spin_unlock(&dcache_lock);
1312 /* Do security vodoo. */
1313 security_d_instantiate(found, inode); 1305 security_d_instantiate(found, inode);
1314 /* Move new in place of found. */
1315 d_move(new, found); 1306 d_move(new, found);
1316 /* Balance the iget() we did above. */
1317 iput(inode); 1307 iput(inode);
1318 /* Throw away found. */
1319 dput(found); 1308 dput(found);
1320 /* Use new as the actual dentry. */
1321 return new; 1309 return new;
1322 1310
1323err_out: 1311err_out: