aboutsummaryrefslogtreecommitdiffstats
path: root/fs/xfs/quota/xfs_qm_syscalls.c
diff options
context:
space:
mode:
Diffstat (limited to 'fs/xfs/quota/xfs_qm_syscalls.c')
-rw-r--r--fs/xfs/quota/xfs_qm_syscalls.c44
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 }
372out_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
737STATIC int 745STATIC 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