diff options
Diffstat (limited to 'fs/gfs2')
-rw-r--r-- | fs/gfs2/glock.c | 64 |
1 files changed, 13 insertions, 51 deletions
diff --git a/fs/gfs2/glock.c b/fs/gfs2/glock.c index 384cae623ed3..3f0974e1afef 100644 --- a/fs/gfs2/glock.c +++ b/fs/gfs2/glock.c | |||
@@ -1327,10 +1327,6 @@ static int nq_m_sync(unsigned int num_gh, struct gfs2_holder *ghs, | |||
1327 | * @num_gh: the number of structures | 1327 | * @num_gh: the number of structures |
1328 | * @ghs: an array of struct gfs2_holder structures | 1328 | * @ghs: an array of struct gfs2_holder structures |
1329 | * | 1329 | * |
1330 | * Figure out how big an impact this function has. Either: | ||
1331 | * 1) Replace this code with code that calls gfs2_glock_prefetch() | ||
1332 | * 2) Forget async stuff and just call nq_m_sync() | ||
1333 | * 3) Leave it like it is | ||
1334 | * | 1330 | * |
1335 | * Returns: 0 on success (all glocks acquired), | 1331 | * Returns: 0 on success (all glocks acquired), |
1336 | * errno on failure (no glocks acquired) | 1332 | * errno on failure (no glocks acquired) |
@@ -1338,62 +1334,28 @@ static int nq_m_sync(unsigned int num_gh, struct gfs2_holder *ghs, | |||
1338 | 1334 | ||
1339 | int gfs2_glock_nq_m(unsigned int num_gh, struct gfs2_holder *ghs) | 1335 | int gfs2_glock_nq_m(unsigned int num_gh, struct gfs2_holder *ghs) |
1340 | { | 1336 | { |
1341 | int *e; | 1337 | struct gfs2_holder *tmp[4]; |
1342 | unsigned int x; | 1338 | struct gfs2_holder **pph = tmp; |
1343 | int borked = 0, serious = 0; | ||
1344 | int error = 0; | 1339 | int error = 0; |
1345 | 1340 | ||
1346 | if (!num_gh) | 1341 | switch(num_gh) { |
1342 | case 0: | ||
1347 | return 0; | 1343 | return 0; |
1348 | 1344 | case 1: | |
1349 | if (num_gh == 1) { | ||
1350 | ghs->gh_flags &= ~(LM_FLAG_TRY | GL_ASYNC); | 1345 | ghs->gh_flags &= ~(LM_FLAG_TRY | GL_ASYNC); |
1351 | return gfs2_glock_nq(ghs); | 1346 | return gfs2_glock_nq(ghs); |
1352 | } | 1347 | default: |
1353 | 1348 | if (num_gh <= 4) | |
1354 | e = kcalloc(num_gh, sizeof(struct gfs2_holder *), GFP_KERNEL); | ||
1355 | if (!e) | ||
1356 | return -ENOMEM; | ||
1357 | |||
1358 | for (x = 0; x < num_gh; x++) { | ||
1359 | ghs[x].gh_flags |= LM_FLAG_TRY | GL_ASYNC; | ||
1360 | error = gfs2_glock_nq(&ghs[x]); | ||
1361 | if (error) { | ||
1362 | borked = 1; | ||
1363 | serious = error; | ||
1364 | num_gh = x; | ||
1365 | break; | 1349 | break; |
1366 | } | 1350 | pph = kmalloc(num_gh * sizeof(struct gfs2_holder *), GFP_NOFS); |
1351 | if (!pph) | ||
1352 | return -ENOMEM; | ||
1367 | } | 1353 | } |
1368 | 1354 | ||
1369 | for (x = 0; x < num_gh; x++) { | 1355 | error = nq_m_sync(num_gh, ghs, pph); |
1370 | error = e[x] = glock_wait_internal(&ghs[x]); | ||
1371 | if (error) { | ||
1372 | borked = 1; | ||
1373 | if (error != GLR_TRYFAILED && error != GLR_CANCELED) | ||
1374 | serious = error; | ||
1375 | } | ||
1376 | } | ||
1377 | |||
1378 | if (!borked) { | ||
1379 | kfree(e); | ||
1380 | return 0; | ||
1381 | } | ||
1382 | |||
1383 | for (x = 0; x < num_gh; x++) | ||
1384 | if (!e[x]) | ||
1385 | gfs2_glock_dq(&ghs[x]); | ||
1386 | |||
1387 | if (serious) | ||
1388 | error = serious; | ||
1389 | else { | ||
1390 | for (x = 0; x < num_gh; x++) | ||
1391 | gfs2_holder_reinit(ghs[x].gh_state, ghs[x].gh_flags, | ||
1392 | &ghs[x]); | ||
1393 | error = nq_m_sync(num_gh, ghs, (struct gfs2_holder **)e); | ||
1394 | } | ||
1395 | 1356 | ||
1396 | kfree(e); | 1357 | if (pph != tmp) |
1358 | kfree(pph); | ||
1397 | 1359 | ||
1398 | return error; | 1360 | return error; |
1399 | } | 1361 | } |