Commit 07fe4dd48d046feeff8705a2a224a8fba050b1c6

Authored by Barry Naujok
Committed by Niv Sardi
1 parent f9e09f095f

[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);