diff options
author | Barry Naujok <bnaujok@sgi.com> | 2008-06-26 23:32:11 -0400 |
---|---|---|
committer | Niv Sardi <xaiki@debian.org> | 2008-07-28 02:59:06 -0400 |
commit | 07fe4dd48d046feeff8705a2a224a8fba050b1c6 (patch) | |
tree | e6c6c206f8c3cc66bb1e8c4fdd0944b34e4bfc73 /fs | |
parent | f9e09f095f323948b26ba09638d2eb3b0578d094 (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')
-rw-r--r-- | fs/xfs/xfs_dir2_leaf.c | 49 |
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); |