aboutsummaryrefslogtreecommitdiffstats
path: root/fs/xfs/xfs_dir2_leaf.c
diff options
context:
space:
mode:
authorBarry Naujok <bnaujok@sgi.com>2008-06-26 23:32:11 -0400
committerNiv Sardi <xaiki@debian.org>2008-07-28 02:59:06 -0400
commit07fe4dd48d046feeff8705a2a224a8fba050b1c6 (patch)
treee6c6c206f8c3cc66bb1e8c4fdd0944b34e4bfc73 /fs/xfs/xfs_dir2_leaf.c
parentf9e09f095f323948b26ba09638d2eb3b0578d094 (diff)
[XFS] Fix CI lookup in leaf-form directories
Instead of comparing buffer pointers, compare buffer block numbers and don't keep buff SGI-PV: 983564 SGI-Modid: xfs-linux-melb:xfs-kern:31346a Signed-off-by: Barry Naujok <bnaujok@sgi.com> Signed-off-by: Christoph Hellwig <hch@infradead.org> Signed-off-by: Lachlan McIlroy <lachlan@sgi.com>
Diffstat (limited to 'fs/xfs/xfs_dir2_leaf.c')
-rw-r--r--fs/xfs/xfs_dir2_leaf.c49
1 files changed, 25 insertions, 24 deletions
diff --git a/fs/xfs/xfs_dir2_leaf.c b/fs/xfs/xfs_dir2_leaf.c
index f110242d6dfc..93535992cb60 100644
--- a/fs/xfs/xfs_dir2_leaf.c
+++ b/fs/xfs/xfs_dir2_leaf.c
@@ -1321,8 +1321,8 @@ xfs_dir2_leaf_lookup_int(
1321 int *indexp, /* out: index in leaf block */ 1321 int *indexp, /* out: index in leaf block */
1322 xfs_dabuf_t **dbpp) /* out: data buffer */ 1322 xfs_dabuf_t **dbpp) /* out: data buffer */
1323{ 1323{
1324 xfs_dir2_db_t curdb; /* current data block number */ 1324 xfs_dir2_db_t curdb = -1; /* current data block number */
1325 xfs_dabuf_t *dbp; /* data buffer */ 1325 xfs_dabuf_t *dbp = NULL; /* data buffer */
1326 xfs_dir2_data_entry_t *dep; /* data entry */ 1326 xfs_dir2_data_entry_t *dep; /* data entry */
1327 xfs_inode_t *dp; /* incore directory inode */ 1327 xfs_inode_t *dp; /* incore directory inode */
1328 int error; /* error return code */ 1328 int error; /* error return code */
@@ -1333,7 +1333,7 @@ xfs_dir2_leaf_lookup_int(
1333 xfs_mount_t *mp; /* filesystem mount point */ 1333 xfs_mount_t *mp; /* filesystem mount point */
1334 xfs_dir2_db_t newdb; /* new data block number */ 1334 xfs_dir2_db_t newdb; /* new data block number */
1335 xfs_trans_t *tp; /* transaction pointer */ 1335 xfs_trans_t *tp; /* transaction pointer */
1336 xfs_dabuf_t *cbp; /* case match data buffer */ 1336 xfs_dir2_db_t cidb = -1; /* case match data block no. */
1337 enum xfs_dacmp cmp; /* name compare result */ 1337 enum xfs_dacmp cmp; /* name compare result */
1338 1338
1339 dp = args->dp; 1339 dp = args->dp;
@@ -1342,11 +1342,10 @@ xfs_dir2_leaf_lookup_int(
1342 /* 1342 /*
1343 * Read the leaf block into the buffer. 1343 * Read the leaf block into the buffer.
1344 */ 1344 */
1345 if ((error = 1345 error = xfs_da_read_buf(tp, dp, mp->m_dirleafblk, -1, &lbp,
1346 xfs_da_read_buf(tp, dp, mp->m_dirleafblk, -1, &lbp, 1346 XFS_DATA_FORK);
1347 XFS_DATA_FORK))) { 1347 if (error)
1348 return error; 1348 return error;
1349 }
1350 *lbpp = lbp; 1349 *lbpp = lbp;
1351 leaf = lbp->data; 1350 leaf = lbp->data;
1352 xfs_dir2_leaf_check(dp, lbp); 1351 xfs_dir2_leaf_check(dp, lbp);
@@ -1358,9 +1357,7 @@ xfs_dir2_leaf_lookup_int(
1358 * Loop over all the entries with the right hash value 1357 * Loop over all the entries with the right hash value
1359 * looking to match the name. 1358 * looking to match the name.
1360 */ 1359 */
1361 cbp = NULL; 1360 for (lep = &leaf->ents[index]; index < be16_to_cpu(leaf->hdr.count) &&
1362 for (lep = &leaf->ents[index], dbp = NULL, curdb = -1;
1363 index < be16_to_cpu(leaf->hdr.count) &&
1364 be32_to_cpu(lep->hashval) == args->hashval; 1361 be32_to_cpu(lep->hashval) == args->hashval;
1365 lep++, index++) { 1362 lep++, index++) {
1366 /* 1363 /*
@@ -1377,7 +1374,7 @@ xfs_dir2_leaf_lookup_int(
1377 * need to pitch the old one and read the new one. 1374 * need to pitch the old one and read the new one.
1378 */ 1375 */
1379 if (newdb != curdb) { 1376 if (newdb != curdb) {
1380 if (dbp != cbp) 1377 if (dbp)
1381 xfs_da_brelse(tp, dbp); 1378 xfs_da_brelse(tp, dbp);
1382 error = xfs_da_read_buf(tp, dp, 1379 error = xfs_da_read_buf(tp, dp,
1383 xfs_dir2_db_to_da(mp, newdb), 1380 xfs_dir2_db_to_da(mp, newdb),
@@ -1403,35 +1400,39 @@ xfs_dir2_leaf_lookup_int(
1403 if (cmp != XFS_CMP_DIFFERENT && cmp != args->cmpresult) { 1400 if (cmp != XFS_CMP_DIFFERENT && cmp != args->cmpresult) {
1404 args->cmpresult = cmp; 1401 args->cmpresult = cmp;
1405 *indexp = index; 1402 *indexp = index;
1406 /* 1403 /* case exact match: return the current buffer. */
1407 * case exact match: release the stored CI buffer if it
1408 * exists and return the current buffer.
1409 */
1410 if (cmp == XFS_CMP_EXACT) { 1404 if (cmp == XFS_CMP_EXACT) {
1411 if (cbp && cbp != dbp)
1412 xfs_da_brelse(tp, cbp);
1413 *dbpp = dbp; 1405 *dbpp = dbp;
1414 return 0; 1406 return 0;
1415 } 1407 }
1416 cbp = dbp; 1408 cidb = curdb;
1417 } 1409 }
1418 } 1410 }
1419 ASSERT(args->op_flags & XFS_DA_OP_OKNOENT); 1411 ASSERT(args->op_flags & XFS_DA_OP_OKNOENT);
1420 /* 1412 /*
1421 * Here, we can only be doing a lookup (not a rename or replace). 1413 * Here, we can only be doing a lookup (not a rename or remove).
1422 * If a case-insensitive match was found earlier, release the current 1414 * If a case-insensitive match was found earlier, re-read the
1423 * buffer and return the stored CI matching buffer. 1415 * appropriate data block if required and return it.
1424 */ 1416 */
1425 if (args->cmpresult == XFS_CMP_CASE) { 1417 if (args->cmpresult == XFS_CMP_CASE) {
1426 if (cbp != dbp) 1418 ASSERT(cidb != -1);
1419 if (cidb != curdb) {
1427 xfs_da_brelse(tp, dbp); 1420 xfs_da_brelse(tp, dbp);
1428 *dbpp = cbp; 1421 error = xfs_da_read_buf(tp, dp,
1422 xfs_dir2_db_to_da(mp, cidb),
1423 -1, &dbp, XFS_DATA_FORK);
1424 if (error) {
1425 xfs_da_brelse(tp, lbp);
1426 return error;
1427 }
1428 }
1429 *dbpp = dbp;
1429 return 0; 1430 return 0;
1430 } 1431 }
1431 /* 1432 /*
1432 * No match found, return ENOENT. 1433 * No match found, return ENOENT.
1433 */ 1434 */
1434 ASSERT(cbp == NULL); 1435 ASSERT(cidb == -1);
1435 if (dbp) 1436 if (dbp)
1436 xfs_da_brelse(tp, dbp); 1437 xfs_da_brelse(tp, dbp);
1437 xfs_da_brelse(tp, lbp); 1438 xfs_da_brelse(tp, lbp);