diff options
Diffstat (limited to 'fs/xfs/quota/xfs_qm_syscalls.c')
-rw-r--r-- | fs/xfs/quota/xfs_qm_syscalls.c | 44 |
1 files changed, 26 insertions, 18 deletions
diff --git a/fs/xfs/quota/xfs_qm_syscalls.c b/fs/xfs/quota/xfs_qm_syscalls.c index d2b8be7e75f9..8342823dbdc3 100644 --- a/fs/xfs/quota/xfs_qm_syscalls.c +++ b/fs/xfs/quota/xfs_qm_syscalls.c | |||
@@ -279,9 +279,12 @@ xfs_qm_scall_quotaoff( | |||
279 | 279 | ||
280 | /* | 280 | /* |
281 | * Write the LI_QUOTAOFF log record, and do SB changes atomically, | 281 | * Write the LI_QUOTAOFF log record, and do SB changes atomically, |
282 | * and synchronously. | 282 | * and synchronously. If we fail to write, we should abort the |
283 | * operation as it cannot be recovered safely if we crash. | ||
283 | */ | 284 | */ |
284 | xfs_qm_log_quotaoff(mp, &qoffstart, flags); | 285 | error = xfs_qm_log_quotaoff(mp, &qoffstart, flags); |
286 | if (error) | ||
287 | goto out_error; | ||
285 | 288 | ||
286 | /* | 289 | /* |
287 | * Next we clear the XFS_MOUNT_*DQ_ACTIVE bit(s) in the mount struct | 290 | * Next we clear the XFS_MOUNT_*DQ_ACTIVE bit(s) in the mount struct |
@@ -337,7 +340,12 @@ xfs_qm_scall_quotaoff( | |||
337 | * So, we have QUOTAOFF start and end logitems; the start | 340 | * So, we have QUOTAOFF start and end logitems; the start |
338 | * logitem won't get overwritten until the end logitem appears... | 341 | * logitem won't get overwritten until the end logitem appears... |
339 | */ | 342 | */ |
340 | xfs_qm_log_quotaoff_end(mp, qoffstart, flags); | 343 | error = xfs_qm_log_quotaoff_end(mp, qoffstart, flags); |
344 | if (error) { | ||
345 | /* We're screwed now. Shutdown is the only option. */ | ||
346 | xfs_force_shutdown(mp, SHUTDOWN_CORRUPT_INCORE); | ||
347 | goto out_error; | ||
348 | } | ||
341 | 349 | ||
342 | /* | 350 | /* |
343 | * If quotas is completely disabled, close shop. | 351 | * If quotas is completely disabled, close shop. |
@@ -361,6 +369,7 @@ xfs_qm_scall_quotaoff( | |||
361 | XFS_PURGE_INODE(XFS_QI_GQIP(mp)); | 369 | XFS_PURGE_INODE(XFS_QI_GQIP(mp)); |
362 | XFS_QI_GQIP(mp) = NULL; | 370 | XFS_QI_GQIP(mp) = NULL; |
363 | } | 371 | } |
372 | out_error: | ||
364 | mutex_unlock(&(XFS_QI_QOFFLOCK(mp))); | 373 | mutex_unlock(&(XFS_QI_QOFFLOCK(mp))); |
365 | 374 | ||
366 | return (error); | 375 | return (error); |
@@ -371,12 +380,11 @@ xfs_qm_scall_trunc_qfiles( | |||
371 | xfs_mount_t *mp, | 380 | xfs_mount_t *mp, |
372 | uint flags) | 381 | uint flags) |
373 | { | 382 | { |
374 | int error; | 383 | int error = 0, error2 = 0; |
375 | xfs_inode_t *qip; | 384 | xfs_inode_t *qip; |
376 | 385 | ||
377 | if (!capable(CAP_SYS_ADMIN)) | 386 | if (!capable(CAP_SYS_ADMIN)) |
378 | return XFS_ERROR(EPERM); | 387 | return XFS_ERROR(EPERM); |
379 | error = 0; | ||
380 | if (!xfs_sb_version_hasquota(&mp->m_sb) || flags == 0) { | 388 | if (!xfs_sb_version_hasquota(&mp->m_sb) || flags == 0) { |
381 | qdprintk("qtrunc flags=%x m_qflags=%x\n", flags, mp->m_qflags); | 389 | qdprintk("qtrunc flags=%x m_qflags=%x\n", flags, mp->m_qflags); |
382 | return XFS_ERROR(EINVAL); | 390 | return XFS_ERROR(EINVAL); |
@@ -384,22 +392,22 @@ xfs_qm_scall_trunc_qfiles( | |||
384 | 392 | ||
385 | if ((flags & XFS_DQ_USER) && mp->m_sb.sb_uquotino != NULLFSINO) { | 393 | if ((flags & XFS_DQ_USER) && mp->m_sb.sb_uquotino != NULLFSINO) { |
386 | error = xfs_iget(mp, NULL, mp->m_sb.sb_uquotino, 0, 0, &qip, 0); | 394 | error = xfs_iget(mp, NULL, mp->m_sb.sb_uquotino, 0, 0, &qip, 0); |
387 | if (! error) { | 395 | if (!error) { |
388 | (void) xfs_truncate_file(mp, qip); | 396 | error = xfs_truncate_file(mp, qip); |
389 | VN_RELE(XFS_ITOV(qip)); | 397 | IRELE(qip); |
390 | } | 398 | } |
391 | } | 399 | } |
392 | 400 | ||
393 | if ((flags & (XFS_DQ_GROUP|XFS_DQ_PROJ)) && | 401 | if ((flags & (XFS_DQ_GROUP|XFS_DQ_PROJ)) && |
394 | mp->m_sb.sb_gquotino != NULLFSINO) { | 402 | mp->m_sb.sb_gquotino != NULLFSINO) { |
395 | error = xfs_iget(mp, NULL, mp->m_sb.sb_gquotino, 0, 0, &qip, 0); | 403 | error2 = xfs_iget(mp, NULL, mp->m_sb.sb_gquotino, 0, 0, &qip, 0); |
396 | if (! error) { | 404 | if (!error2) { |
397 | (void) xfs_truncate_file(mp, qip); | 405 | error2 = xfs_truncate_file(mp, qip); |
398 | VN_RELE(XFS_ITOV(qip)); | 406 | IRELE(qip); |
399 | } | 407 | } |
400 | } | 408 | } |
401 | 409 | ||
402 | return (error); | 410 | return error ? error : error2; |
403 | } | 411 | } |
404 | 412 | ||
405 | 413 | ||
@@ -552,13 +560,13 @@ xfs_qm_scall_getqstat( | |||
552 | out->qs_uquota.qfs_nblks = uip->i_d.di_nblocks; | 560 | out->qs_uquota.qfs_nblks = uip->i_d.di_nblocks; |
553 | out->qs_uquota.qfs_nextents = uip->i_d.di_nextents; | 561 | out->qs_uquota.qfs_nextents = uip->i_d.di_nextents; |
554 | if (tempuqip) | 562 | if (tempuqip) |
555 | VN_RELE(XFS_ITOV(uip)); | 563 | IRELE(uip); |
556 | } | 564 | } |
557 | if (gip) { | 565 | if (gip) { |
558 | out->qs_gquota.qfs_nblks = gip->i_d.di_nblocks; | 566 | out->qs_gquota.qfs_nblks = gip->i_d.di_nblocks; |
559 | out->qs_gquota.qfs_nextents = gip->i_d.di_nextents; | 567 | out->qs_gquota.qfs_nextents = gip->i_d.di_nextents; |
560 | if (tempgqip) | 568 | if (tempgqip) |
561 | VN_RELE(XFS_ITOV(gip)); | 569 | IRELE(gip); |
562 | } | 570 | } |
563 | if (mp->m_quotainfo) { | 571 | if (mp->m_quotainfo) { |
564 | out->qs_incoredqs = XFS_QI_MPLNDQUOTS(mp); | 572 | out->qs_incoredqs = XFS_QI_MPLNDQUOTS(mp); |
@@ -726,12 +734,12 @@ xfs_qm_scall_setqlim( | |||
726 | xfs_trans_log_dquot(tp, dqp); | 734 | xfs_trans_log_dquot(tp, dqp); |
727 | 735 | ||
728 | xfs_dqtrace_entry(dqp, "Q_SETQLIM: COMMIT"); | 736 | xfs_dqtrace_entry(dqp, "Q_SETQLIM: COMMIT"); |
729 | xfs_trans_commit(tp, 0); | 737 | error = xfs_trans_commit(tp, 0); |
730 | xfs_qm_dqprint(dqp); | 738 | xfs_qm_dqprint(dqp); |
731 | xfs_qm_dqrele(dqp); | 739 | xfs_qm_dqrele(dqp); |
732 | mutex_unlock(&(XFS_QI_QOFFLOCK(mp))); | 740 | mutex_unlock(&(XFS_QI_QOFFLOCK(mp))); |
733 | 741 | ||
734 | return (0); | 742 | return error; |
735 | } | 743 | } |
736 | 744 | ||
737 | STATIC int | 745 | STATIC int |
@@ -1095,7 +1103,7 @@ again: | |||
1095 | * inactive code in hell. | 1103 | * inactive code in hell. |
1096 | */ | 1104 | */ |
1097 | if (vnode_refd) | 1105 | if (vnode_refd) |
1098 | VN_RELE(vp); | 1106 | IRELE(ip); |
1099 | XFS_MOUNT_ILOCK(mp); | 1107 | XFS_MOUNT_ILOCK(mp); |
1100 | /* | 1108 | /* |
1101 | * If an inode was inserted or removed, we gotta | 1109 | * If an inode was inserted or removed, we gotta |