Commit 07fe4dd48d046feeff8705a2a224a8fba050b1c6
Committed by
Niv Sardi
1 parent
f9e09f095f
Exists in
master
and in
7 other branches
[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>
Showing 1 changed file with 25 additions and 24 deletions Side-by-side Diff
fs/xfs/xfs_dir2_leaf.c
... | ... | @@ -1321,8 +1321,8 @@ |
1321 | 1321 | int *indexp, /* out: index in leaf block */ |
1322 | 1322 | xfs_dabuf_t **dbpp) /* out: data buffer */ |
1323 | 1323 | { |
1324 | - xfs_dir2_db_t curdb; /* current data block number */ | |
1325 | - xfs_dabuf_t *dbp; /* data buffer */ | |
1324 | + xfs_dir2_db_t curdb = -1; /* current data block number */ | |
1325 | + xfs_dabuf_t *dbp = NULL; /* data buffer */ | |
1326 | 1326 | xfs_dir2_data_entry_t *dep; /* data entry */ |
1327 | 1327 | xfs_inode_t *dp; /* incore directory inode */ |
1328 | 1328 | int error; /* error return code */ |
... | ... | @@ -1333,7 +1333,7 @@ |
1333 | 1333 | xfs_mount_t *mp; /* filesystem mount point */ |
1334 | 1334 | xfs_dir2_db_t newdb; /* new data block number */ |
1335 | 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 | 1337 | enum xfs_dacmp cmp; /* name compare result */ |
1338 | 1338 | |
1339 | 1339 | dp = args->dp; |
1340 | 1340 | |
... | ... | @@ -1342,11 +1342,10 @@ |
1342 | 1342 | /* |
1343 | 1343 | * Read the leaf block into the buffer. |
1344 | 1344 | */ |
1345 | - if ((error = | |
1346 | - xfs_da_read_buf(tp, dp, mp->m_dirleafblk, -1, &lbp, | |
1347 | - XFS_DATA_FORK))) { | |
1345 | + error = xfs_da_read_buf(tp, dp, mp->m_dirleafblk, -1, &lbp, | |
1346 | + XFS_DATA_FORK); | |
1347 | + if (error) | |
1348 | 1348 | return error; |
1349 | - } | |
1350 | 1349 | *lbpp = lbp; |
1351 | 1350 | leaf = lbp->data; |
1352 | 1351 | xfs_dir2_leaf_check(dp, lbp); |
... | ... | @@ -1358,9 +1357,7 @@ |
1358 | 1357 | * Loop over all the entries with the right hash value |
1359 | 1358 | * looking to match the name. |
1360 | 1359 | */ |
1361 | - cbp = NULL; | |
1362 | - for (lep = &leaf->ents[index], dbp = NULL, curdb = -1; | |
1363 | - index < be16_to_cpu(leaf->hdr.count) && | |
1360 | + for (lep = &leaf->ents[index]; index < be16_to_cpu(leaf->hdr.count) && | |
1364 | 1361 | be32_to_cpu(lep->hashval) == args->hashval; |
1365 | 1362 | lep++, index++) { |
1366 | 1363 | /* |
... | ... | @@ -1377,7 +1374,7 @@ |
1377 | 1374 | * need to pitch the old one and read the new one. |
1378 | 1375 | */ |
1379 | 1376 | if (newdb != curdb) { |
1380 | - if (dbp != cbp) | |
1377 | + if (dbp) | |
1381 | 1378 | xfs_da_brelse(tp, dbp); |
1382 | 1379 | error = xfs_da_read_buf(tp, dp, |
1383 | 1380 | xfs_dir2_db_to_da(mp, newdb), |
1384 | 1381 | |
1385 | 1382 | |
1386 | 1383 | |
1387 | 1384 | |
1388 | 1385 | |
1389 | 1386 | |
... | ... | @@ -1403,35 +1400,39 @@ |
1403 | 1400 | if (cmp != XFS_CMP_DIFFERENT && cmp != args->cmpresult) { |
1404 | 1401 | args->cmpresult = cmp; |
1405 | 1402 | *indexp = index; |
1406 | - /* | |
1407 | - * case exact match: release the stored CI buffer if it | |
1408 | - * exists and return the current buffer. | |
1409 | - */ | |
1403 | + /* case exact match: return the current buffer. */ | |
1410 | 1404 | if (cmp == XFS_CMP_EXACT) { |
1411 | - if (cbp && cbp != dbp) | |
1412 | - xfs_da_brelse(tp, cbp); | |
1413 | 1405 | *dbpp = dbp; |
1414 | 1406 | return 0; |
1415 | 1407 | } |
1416 | - cbp = dbp; | |
1408 | + cidb = curdb; | |
1417 | 1409 | } |
1418 | 1410 | } |
1419 | 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). | |
1422 | - * If a case-insensitive match was found earlier, release the current | |
1423 | - * buffer and return the stored CI matching buffer. | |
1413 | + * Here, we can only be doing a lookup (not a rename or remove). | |
1414 | + * If a case-insensitive match was found earlier, re-read the | |
1415 | + * appropriate data block if required and return it. | |
1424 | 1416 | */ |
1425 | 1417 | if (args->cmpresult == XFS_CMP_CASE) { |
1426 | - if (cbp != dbp) | |
1418 | + ASSERT(cidb != -1); | |
1419 | + if (cidb != curdb) { | |
1427 | 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 | 1430 | return 0; |
1430 | 1431 | } |
1431 | 1432 | /* |
1432 | 1433 | * No match found, return ENOENT. |
1433 | 1434 | */ |
1434 | - ASSERT(cbp == NULL); | |
1435 | + ASSERT(cidb == -1); | |
1435 | 1436 | if (dbp) |
1436 | 1437 | xfs_da_brelse(tp, dbp); |
1437 | 1438 | xfs_da_brelse(tp, lbp); |