diff options
Diffstat (limited to 'fs/xfs/quota')
-rw-r--r-- | fs/xfs/quota/xfs_dquot.c | 20 | ||||
-rw-r--r-- | fs/xfs/quota/xfs_dquot_item.c | 14 | ||||
-rw-r--r-- | fs/xfs/quota/xfs_qm.c | 82 | ||||
-rw-r--r-- | fs/xfs/quota/xfs_qm.h | 2 | ||||
-rw-r--r-- | fs/xfs/quota/xfs_qm_bhv.c | 2 | ||||
-rw-r--r-- | fs/xfs/quota/xfs_qm_stats.h | 4 | ||||
-rw-r--r-- | fs/xfs/quota/xfs_qm_syscalls.c | 48 |
7 files changed, 106 insertions, 66 deletions
diff --git a/fs/xfs/quota/xfs_dquot.c b/fs/xfs/quota/xfs_dquot.c index 665babcca6a6..631ebb31b295 100644 --- a/fs/xfs/quota/xfs_dquot.c +++ b/fs/xfs/quota/xfs_dquot.c | |||
@@ -1291,7 +1291,7 @@ xfs_qm_dqflush( | |||
1291 | if (flags & XFS_QMOPT_DELWRI) { | 1291 | if (flags & XFS_QMOPT_DELWRI) { |
1292 | xfs_bdwrite(mp, bp); | 1292 | xfs_bdwrite(mp, bp); |
1293 | } else if (flags & XFS_QMOPT_ASYNC) { | 1293 | } else if (flags & XFS_QMOPT_ASYNC) { |
1294 | xfs_bawrite(mp, bp); | 1294 | error = xfs_bawrite(mp, bp); |
1295 | } else { | 1295 | } else { |
1296 | error = xfs_bwrite(mp, bp); | 1296 | error = xfs_bwrite(mp, bp); |
1297 | } | 1297 | } |
@@ -1439,9 +1439,7 @@ xfs_qm_dqpurge( | |||
1439 | uint flags) | 1439 | uint flags) |
1440 | { | 1440 | { |
1441 | xfs_dqhash_t *thishash; | 1441 | xfs_dqhash_t *thishash; |
1442 | xfs_mount_t *mp; | 1442 | xfs_mount_t *mp = dqp->q_mount; |
1443 | |||
1444 | mp = dqp->q_mount; | ||
1445 | 1443 | ||
1446 | ASSERT(XFS_QM_IS_MPLIST_LOCKED(mp)); | 1444 | ASSERT(XFS_QM_IS_MPLIST_LOCKED(mp)); |
1447 | ASSERT(XFS_DQ_IS_HASH_LOCKED(dqp->q_hash)); | 1445 | ASSERT(XFS_DQ_IS_HASH_LOCKED(dqp->q_hash)); |
@@ -1485,6 +1483,7 @@ xfs_qm_dqpurge( | |||
1485 | * we're unmounting, we do care, so we flush it and wait. | 1483 | * we're unmounting, we do care, so we flush it and wait. |
1486 | */ | 1484 | */ |
1487 | if (XFS_DQ_IS_DIRTY(dqp)) { | 1485 | if (XFS_DQ_IS_DIRTY(dqp)) { |
1486 | int error; | ||
1488 | xfs_dqtrace_entry(dqp, "DQPURGE ->DQFLUSH: DQDIRTY"); | 1487 | xfs_dqtrace_entry(dqp, "DQPURGE ->DQFLUSH: DQDIRTY"); |
1489 | /* dqflush unlocks dqflock */ | 1488 | /* dqflush unlocks dqflock */ |
1490 | /* | 1489 | /* |
@@ -1495,7 +1494,10 @@ xfs_qm_dqpurge( | |||
1495 | * We don't care about getting disk errors here. We need | 1494 | * We don't care about getting disk errors here. We need |
1496 | * to purge this dquot anyway, so we go ahead regardless. | 1495 | * to purge this dquot anyway, so we go ahead regardless. |
1497 | */ | 1496 | */ |
1498 | (void) xfs_qm_dqflush(dqp, XFS_QMOPT_SYNC); | 1497 | error = xfs_qm_dqflush(dqp, XFS_QMOPT_SYNC); |
1498 | if (error) | ||
1499 | xfs_fs_cmn_err(CE_WARN, mp, | ||
1500 | "xfs_qm_dqpurge: dquot %p flush failed", dqp); | ||
1499 | xfs_dqflock(dqp); | 1501 | xfs_dqflock(dqp); |
1500 | } | 1502 | } |
1501 | ASSERT(dqp->q_pincount == 0); | 1503 | ASSERT(dqp->q_pincount == 0); |
@@ -1580,12 +1582,18 @@ xfs_qm_dqflock_pushbuf_wait( | |||
1580 | XFS_INCORE_TRYLOCK); | 1582 | XFS_INCORE_TRYLOCK); |
1581 | if (bp != NULL) { | 1583 | if (bp != NULL) { |
1582 | if (XFS_BUF_ISDELAYWRITE(bp)) { | 1584 | if (XFS_BUF_ISDELAYWRITE(bp)) { |
1585 | int error; | ||
1583 | if (XFS_BUF_ISPINNED(bp)) { | 1586 | if (XFS_BUF_ISPINNED(bp)) { |
1584 | xfs_log_force(dqp->q_mount, | 1587 | xfs_log_force(dqp->q_mount, |
1585 | (xfs_lsn_t)0, | 1588 | (xfs_lsn_t)0, |
1586 | XFS_LOG_FORCE); | 1589 | XFS_LOG_FORCE); |
1587 | } | 1590 | } |
1588 | xfs_bawrite(dqp->q_mount, bp); | 1591 | error = xfs_bawrite(dqp->q_mount, bp); |
1592 | if (error) | ||
1593 | xfs_fs_cmn_err(CE_WARN, dqp->q_mount, | ||
1594 | "xfs_qm_dqflock_pushbuf_wait: " | ||
1595 | "pushbuf error %d on dqp %p, bp %p", | ||
1596 | error, dqp, bp); | ||
1589 | } else { | 1597 | } else { |
1590 | xfs_buf_relse(bp); | 1598 | xfs_buf_relse(bp); |
1591 | } | 1599 | } |
diff --git a/fs/xfs/quota/xfs_dquot_item.c b/fs/xfs/quota/xfs_dquot_item.c index 1800e8d1f646..36e05ca78412 100644 --- a/fs/xfs/quota/xfs_dquot_item.c +++ b/fs/xfs/quota/xfs_dquot_item.c | |||
@@ -146,6 +146,7 @@ xfs_qm_dquot_logitem_push( | |||
146 | xfs_dq_logitem_t *logitem) | 146 | xfs_dq_logitem_t *logitem) |
147 | { | 147 | { |
148 | xfs_dquot_t *dqp; | 148 | xfs_dquot_t *dqp; |
149 | int error; | ||
149 | 150 | ||
150 | dqp = logitem->qli_dquot; | 151 | dqp = logitem->qli_dquot; |
151 | 152 | ||
@@ -161,7 +162,11 @@ xfs_qm_dquot_logitem_push( | |||
161 | * lock without sleeping, then there must not have been | 162 | * lock without sleeping, then there must not have been |
162 | * anyone in the process of flushing the dquot. | 163 | * anyone in the process of flushing the dquot. |
163 | */ | 164 | */ |
164 | xfs_qm_dqflush(dqp, XFS_B_DELWRI); | 165 | error = xfs_qm_dqflush(dqp, XFS_QMOPT_DELWRI); |
166 | if (error) | ||
167 | xfs_fs_cmn_err(CE_WARN, dqp->q_mount, | ||
168 | "xfs_qm_dquot_logitem_push: push error %d on dqp %p", | ||
169 | error, dqp); | ||
165 | xfs_dqunlock(dqp); | 170 | xfs_dqunlock(dqp); |
166 | } | 171 | } |
167 | 172 | ||
@@ -262,11 +267,16 @@ xfs_qm_dquot_logitem_pushbuf( | |||
262 | XFS_LOG_FORCE); | 267 | XFS_LOG_FORCE); |
263 | } | 268 | } |
264 | if (dopush) { | 269 | if (dopush) { |
270 | int error; | ||
265 | #ifdef XFSRACEDEBUG | 271 | #ifdef XFSRACEDEBUG |
266 | delay_for_intr(); | 272 | delay_for_intr(); |
267 | delay(300); | 273 | delay(300); |
268 | #endif | 274 | #endif |
269 | xfs_bawrite(mp, bp); | 275 | error = xfs_bawrite(mp, bp); |
276 | if (error) | ||
277 | xfs_fs_cmn_err(CE_WARN, mp, | ||
278 | "xfs_qm_dquot_logitem_pushbuf: pushbuf error %d on qip %p, bp %p", | ||
279 | error, qip, bp); | ||
270 | } else { | 280 | } else { |
271 | xfs_buf_relse(bp); | 281 | xfs_buf_relse(bp); |
272 | } | 282 | } |
diff --git a/fs/xfs/quota/xfs_qm.c b/fs/xfs/quota/xfs_qm.c index 1f3da5b8657b..40ea56409561 100644 --- a/fs/xfs/quota/xfs_qm.c +++ b/fs/xfs/quota/xfs_qm.c | |||
@@ -304,8 +304,11 @@ xfs_qm_unmount_quotadestroy( | |||
304 | * necessary data structures like quotainfo. This is also responsible for | 304 | * necessary data structures like quotainfo. This is also responsible for |
305 | * running a quotacheck as necessary. We are guaranteed that the superblock | 305 | * running a quotacheck as necessary. We are guaranteed that the superblock |
306 | * is consistently read in at this point. | 306 | * is consistently read in at this point. |
307 | * | ||
308 | * If we fail here, the mount will continue with quota turned off. We don't | ||
309 | * need to inidicate success or failure at all. | ||
307 | */ | 310 | */ |
308 | int | 311 | void |
309 | xfs_qm_mount_quotas( | 312 | xfs_qm_mount_quotas( |
310 | xfs_mount_t *mp, | 313 | xfs_mount_t *mp, |
311 | int mfsi_flags) | 314 | int mfsi_flags) |
@@ -313,7 +316,6 @@ xfs_qm_mount_quotas( | |||
313 | int error = 0; | 316 | int error = 0; |
314 | uint sbf; | 317 | uint sbf; |
315 | 318 | ||
316 | |||
317 | /* | 319 | /* |
318 | * If quotas on realtime volumes is not supported, we disable | 320 | * If quotas on realtime volumes is not supported, we disable |
319 | * quotas immediately. | 321 | * quotas immediately. |
@@ -332,7 +334,8 @@ xfs_qm_mount_quotas( | |||
332 | * Allocate the quotainfo structure inside the mount struct, and | 334 | * Allocate the quotainfo structure inside the mount struct, and |
333 | * create quotainode(s), and change/rev superblock if necessary. | 335 | * create quotainode(s), and change/rev superblock if necessary. |
334 | */ | 336 | */ |
335 | if ((error = xfs_qm_init_quotainfo(mp))) { | 337 | error = xfs_qm_init_quotainfo(mp); |
338 | if (error) { | ||
336 | /* | 339 | /* |
337 | * We must turn off quotas. | 340 | * We must turn off quotas. |
338 | */ | 341 | */ |
@@ -344,12 +347,11 @@ xfs_qm_mount_quotas( | |||
344 | * If any of the quotas are not consistent, do a quotacheck. | 347 | * If any of the quotas are not consistent, do a quotacheck. |
345 | */ | 348 | */ |
346 | if (XFS_QM_NEED_QUOTACHECK(mp) && | 349 | if (XFS_QM_NEED_QUOTACHECK(mp) && |
347 | !(mfsi_flags & XFS_MFSI_NO_QUOTACHECK)) { | 350 | !(mfsi_flags & XFS_MFSI_NO_QUOTACHECK)) { |
348 | if ((error = xfs_qm_quotacheck(mp))) { | 351 | error = xfs_qm_quotacheck(mp); |
349 | /* Quotacheck has failed and quotas have | 352 | if (error) { |
350 | * been disabled. | 353 | /* Quotacheck failed and disabled quotas. */ |
351 | */ | 354 | return; |
352 | return XFS_ERROR(error); | ||
353 | } | 355 | } |
354 | } | 356 | } |
355 | /* | 357 | /* |
@@ -357,12 +359,10 @@ xfs_qm_mount_quotas( | |||
357 | * quotachecked status, since we won't be doing accounting for | 359 | * quotachecked status, since we won't be doing accounting for |
358 | * that type anymore. | 360 | * that type anymore. |
359 | */ | 361 | */ |
360 | if (!XFS_IS_UQUOTA_ON(mp)) { | 362 | if (!XFS_IS_UQUOTA_ON(mp)) |
361 | mp->m_qflags &= ~XFS_UQUOTA_CHKD; | 363 | mp->m_qflags &= ~XFS_UQUOTA_CHKD; |
362 | } | 364 | if (!(XFS_IS_GQUOTA_ON(mp) || XFS_IS_PQUOTA_ON(mp))) |
363 | if (!(XFS_IS_GQUOTA_ON(mp) || XFS_IS_PQUOTA_ON(mp))) { | ||
364 | mp->m_qflags &= ~XFS_OQUOTA_CHKD; | 365 | mp->m_qflags &= ~XFS_OQUOTA_CHKD; |
365 | } | ||
366 | 366 | ||
367 | write_changes: | 367 | write_changes: |
368 | /* | 368 | /* |
@@ -392,7 +392,7 @@ xfs_qm_mount_quotas( | |||
392 | xfs_fs_cmn_err(CE_WARN, mp, | 392 | xfs_fs_cmn_err(CE_WARN, mp, |
393 | "Failed to initialize disk quotas."); | 393 | "Failed to initialize disk quotas."); |
394 | } | 394 | } |
395 | return XFS_ERROR(error); | 395 | return; |
396 | } | 396 | } |
397 | 397 | ||
398 | /* | 398 | /* |
@@ -1405,13 +1405,13 @@ xfs_qm_qino_alloc( | |||
1405 | #if defined(DEBUG) && defined(XFS_LOUD_RECOVERY) | 1405 | #if defined(DEBUG) && defined(XFS_LOUD_RECOVERY) |
1406 | unsigned oldv = mp->m_sb.sb_versionnum; | 1406 | unsigned oldv = mp->m_sb.sb_versionnum; |
1407 | #endif | 1407 | #endif |
1408 | ASSERT(!XFS_SB_VERSION_HASQUOTA(&mp->m_sb)); | 1408 | ASSERT(!xfs_sb_version_hasquota(&mp->m_sb)); |
1409 | ASSERT((sbfields & (XFS_SB_VERSIONNUM | XFS_SB_UQUOTINO | | 1409 | ASSERT((sbfields & (XFS_SB_VERSIONNUM | XFS_SB_UQUOTINO | |
1410 | XFS_SB_GQUOTINO | XFS_SB_QFLAGS)) == | 1410 | XFS_SB_GQUOTINO | XFS_SB_QFLAGS)) == |
1411 | (XFS_SB_VERSIONNUM | XFS_SB_UQUOTINO | | 1411 | (XFS_SB_VERSIONNUM | XFS_SB_UQUOTINO | |
1412 | XFS_SB_GQUOTINO | XFS_SB_QFLAGS)); | 1412 | XFS_SB_GQUOTINO | XFS_SB_QFLAGS)); |
1413 | 1413 | ||
1414 | XFS_SB_VERSION_ADDQUOTA(&mp->m_sb); | 1414 | xfs_sb_version_addquota(&mp->m_sb); |
1415 | mp->m_sb.sb_uquotino = NULLFSINO; | 1415 | mp->m_sb.sb_uquotino = NULLFSINO; |
1416 | mp->m_sb.sb_gquotino = NULLFSINO; | 1416 | mp->m_sb.sb_gquotino = NULLFSINO; |
1417 | 1417 | ||
@@ -1438,7 +1438,7 @@ xfs_qm_qino_alloc( | |||
1438 | } | 1438 | } |
1439 | 1439 | ||
1440 | 1440 | ||
1441 | STATIC int | 1441 | STATIC void |
1442 | xfs_qm_reset_dqcounts( | 1442 | xfs_qm_reset_dqcounts( |
1443 | xfs_mount_t *mp, | 1443 | xfs_mount_t *mp, |
1444 | xfs_buf_t *bp, | 1444 | xfs_buf_t *bp, |
@@ -1478,8 +1478,6 @@ xfs_qm_reset_dqcounts( | |||
1478 | ddq->d_rtbwarns = 0; | 1478 | ddq->d_rtbwarns = 0; |
1479 | ddq = (xfs_disk_dquot_t *) ((xfs_dqblk_t *)ddq + 1); | 1479 | ddq = (xfs_disk_dquot_t *) ((xfs_dqblk_t *)ddq + 1); |
1480 | } | 1480 | } |
1481 | |||
1482 | return 0; | ||
1483 | } | 1481 | } |
1484 | 1482 | ||
1485 | STATIC int | 1483 | STATIC int |
@@ -1520,7 +1518,7 @@ xfs_qm_dqiter_bufs( | |||
1520 | if (error) | 1518 | if (error) |
1521 | break; | 1519 | break; |
1522 | 1520 | ||
1523 | (void) xfs_qm_reset_dqcounts(mp, bp, firstid, type); | 1521 | xfs_qm_reset_dqcounts(mp, bp, firstid, type); |
1524 | xfs_bdwrite(mp, bp); | 1522 | xfs_bdwrite(mp, bp); |
1525 | /* | 1523 | /* |
1526 | * goto the next block. | 1524 | * goto the next block. |
@@ -1810,7 +1808,7 @@ xfs_qm_dqusage_adjust( | |||
1810 | * Now release the inode. This will send it to 'inactive', and | 1808 | * Now release the inode. This will send it to 'inactive', and |
1811 | * possibly even free blocks. | 1809 | * possibly even free blocks. |
1812 | */ | 1810 | */ |
1813 | VN_RELE(XFS_ITOV(ip)); | 1811 | IRELE(ip); |
1814 | 1812 | ||
1815 | /* | 1813 | /* |
1816 | * Goto next inode. | 1814 | * Goto next inode. |
@@ -1880,6 +1878,14 @@ xfs_qm_quotacheck( | |||
1880 | } while (! done); | 1878 | } while (! done); |
1881 | 1879 | ||
1882 | /* | 1880 | /* |
1881 | * We've made all the changes that we need to make incore. | ||
1882 | * Flush them down to disk buffers if everything was updated | ||
1883 | * successfully. | ||
1884 | */ | ||
1885 | if (!error) | ||
1886 | error = xfs_qm_dqflush_all(mp, XFS_QMOPT_DELWRI); | ||
1887 | |||
1888 | /* | ||
1883 | * We can get this error if we couldn't do a dquot allocation inside | 1889 | * We can get this error if we couldn't do a dquot allocation inside |
1884 | * xfs_qm_dqusage_adjust (via bulkstat). We don't care about the | 1890 | * xfs_qm_dqusage_adjust (via bulkstat). We don't care about the |
1885 | * dirty dquots that might be cached, we just want to get rid of them | 1891 | * dirty dquots that might be cached, we just want to get rid of them |
@@ -1890,11 +1896,6 @@ xfs_qm_quotacheck( | |||
1890 | xfs_qm_dqpurge_all(mp, XFS_QMOPT_QUOTALL | XFS_QMOPT_QUOTAOFF); | 1896 | xfs_qm_dqpurge_all(mp, XFS_QMOPT_QUOTALL | XFS_QMOPT_QUOTAOFF); |
1891 | goto error_return; | 1897 | goto error_return; |
1892 | } | 1898 | } |
1893 | /* | ||
1894 | * We've made all the changes that we need to make incore. | ||
1895 | * Now flush_them down to disk buffers. | ||
1896 | */ | ||
1897 | xfs_qm_dqflush_all(mp, XFS_QMOPT_DELWRI); | ||
1898 | 1899 | ||
1899 | /* | 1900 | /* |
1900 | * We didn't log anything, because if we crashed, we'll have to | 1901 | * We didn't log anything, because if we crashed, we'll have to |
@@ -1926,7 +1927,10 @@ xfs_qm_quotacheck( | |||
1926 | ASSERT(mp->m_quotainfo != NULL); | 1927 | ASSERT(mp->m_quotainfo != NULL); |
1927 | ASSERT(xfs_Gqm != NULL); | 1928 | ASSERT(xfs_Gqm != NULL); |
1928 | xfs_qm_destroy_quotainfo(mp); | 1929 | xfs_qm_destroy_quotainfo(mp); |
1929 | (void)xfs_mount_reset_sbqflags(mp); | 1930 | if (xfs_mount_reset_sbqflags(mp)) { |
1931 | cmn_err(CE_WARN, "XFS quotacheck %s: " | ||
1932 | "Failed to reset quota flags.", mp->m_fsname); | ||
1933 | } | ||
1930 | } else { | 1934 | } else { |
1931 | cmn_err(CE_NOTE, "XFS quotacheck %s: Done.", mp->m_fsname); | 1935 | cmn_err(CE_NOTE, "XFS quotacheck %s: Done.", mp->m_fsname); |
1932 | } | 1936 | } |
@@ -1954,7 +1958,7 @@ xfs_qm_init_quotainos( | |||
1954 | /* | 1958 | /* |
1955 | * Get the uquota and gquota inodes | 1959 | * Get the uquota and gquota inodes |
1956 | */ | 1960 | */ |
1957 | if (XFS_SB_VERSION_HASQUOTA(&mp->m_sb)) { | 1961 | if (xfs_sb_version_hasquota(&mp->m_sb)) { |
1958 | if (XFS_IS_UQUOTA_ON(mp) && | 1962 | if (XFS_IS_UQUOTA_ON(mp) && |
1959 | mp->m_sb.sb_uquotino != NULLFSINO) { | 1963 | mp->m_sb.sb_uquotino != NULLFSINO) { |
1960 | ASSERT(mp->m_sb.sb_uquotino > 0); | 1964 | ASSERT(mp->m_sb.sb_uquotino > 0); |
@@ -1968,7 +1972,7 @@ xfs_qm_init_quotainos( | |||
1968 | if ((error = xfs_iget(mp, NULL, mp->m_sb.sb_gquotino, | 1972 | if ((error = xfs_iget(mp, NULL, mp->m_sb.sb_gquotino, |
1969 | 0, 0, &gip, 0))) { | 1973 | 0, 0, &gip, 0))) { |
1970 | if (uip) | 1974 | if (uip) |
1971 | VN_RELE(XFS_ITOV(uip)); | 1975 | IRELE(uip); |
1972 | return XFS_ERROR(error); | 1976 | return XFS_ERROR(error); |
1973 | } | 1977 | } |
1974 | } | 1978 | } |
@@ -1999,7 +2003,7 @@ xfs_qm_init_quotainos( | |||
1999 | sbflags | XFS_SB_GQUOTINO, flags); | 2003 | sbflags | XFS_SB_GQUOTINO, flags); |
2000 | if (error) { | 2004 | if (error) { |
2001 | if (uip) | 2005 | if (uip) |
2002 | VN_RELE(XFS_ITOV(uip)); | 2006 | IRELE(uip); |
2003 | 2007 | ||
2004 | return XFS_ERROR(error); | 2008 | return XFS_ERROR(error); |
2005 | } | 2009 | } |
@@ -2093,12 +2097,17 @@ xfs_qm_shake_freelist( | |||
2093 | * dirty dquots. | 2097 | * dirty dquots. |
2094 | */ | 2098 | */ |
2095 | if (XFS_DQ_IS_DIRTY(dqp)) { | 2099 | if (XFS_DQ_IS_DIRTY(dqp)) { |
2100 | int error; | ||
2096 | xfs_dqtrace_entry(dqp, "DQSHAKE: DQDIRTY"); | 2101 | xfs_dqtrace_entry(dqp, "DQSHAKE: DQDIRTY"); |
2097 | /* | 2102 | /* |
2098 | * We flush it delayed write, so don't bother | 2103 | * We flush it delayed write, so don't bother |
2099 | * releasing the mplock. | 2104 | * releasing the mplock. |
2100 | */ | 2105 | */ |
2101 | (void) xfs_qm_dqflush(dqp, XFS_QMOPT_DELWRI); | 2106 | error = xfs_qm_dqflush(dqp, XFS_QMOPT_DELWRI); |
2107 | if (error) { | ||
2108 | xfs_fs_cmn_err(CE_WARN, dqp->q_mount, | ||
2109 | "xfs_qm_dqflush_all: dquot %p flush failed", dqp); | ||
2110 | } | ||
2102 | xfs_dqunlock(dqp); /* dqflush unlocks dqflock */ | 2111 | xfs_dqunlock(dqp); /* dqflush unlocks dqflock */ |
2103 | dqp = dqp->dq_flnext; | 2112 | dqp = dqp->dq_flnext; |
2104 | continue; | 2113 | continue; |
@@ -2265,12 +2274,17 @@ xfs_qm_dqreclaim_one(void) | |||
2265 | * dirty dquots. | 2274 | * dirty dquots. |
2266 | */ | 2275 | */ |
2267 | if (XFS_DQ_IS_DIRTY(dqp)) { | 2276 | if (XFS_DQ_IS_DIRTY(dqp)) { |
2277 | int error; | ||
2268 | xfs_dqtrace_entry(dqp, "DQRECLAIM: DQDIRTY"); | 2278 | xfs_dqtrace_entry(dqp, "DQRECLAIM: DQDIRTY"); |
2269 | /* | 2279 | /* |
2270 | * We flush it delayed write, so don't bother | 2280 | * We flush it delayed write, so don't bother |
2271 | * releasing the freelist lock. | 2281 | * releasing the freelist lock. |
2272 | */ | 2282 | */ |
2273 | (void) xfs_qm_dqflush(dqp, XFS_QMOPT_DELWRI); | 2283 | error = xfs_qm_dqflush(dqp, XFS_QMOPT_DELWRI); |
2284 | if (error) { | ||
2285 | xfs_fs_cmn_err(CE_WARN, dqp->q_mount, | ||
2286 | "xfs_qm_dqreclaim: dquot %p flush failed", dqp); | ||
2287 | } | ||
2274 | xfs_dqunlock(dqp); /* dqflush unlocks dqflock */ | 2288 | xfs_dqunlock(dqp); /* dqflush unlocks dqflock */ |
2275 | continue; | 2289 | continue; |
2276 | } | 2290 | } |
@@ -2378,9 +2392,9 @@ xfs_qm_write_sb_changes( | |||
2378 | } | 2392 | } |
2379 | 2393 | ||
2380 | xfs_mod_sb(tp, flags); | 2394 | xfs_mod_sb(tp, flags); |
2381 | (void) xfs_trans_commit(tp, 0); | 2395 | error = xfs_trans_commit(tp, 0); |
2382 | 2396 | ||
2383 | return 0; | 2397 | return error; |
2384 | } | 2398 | } |
2385 | 2399 | ||
2386 | 2400 | ||
diff --git a/fs/xfs/quota/xfs_qm.h b/fs/xfs/quota/xfs_qm.h index baf537c1c177..cd2300e374af 100644 --- a/fs/xfs/quota/xfs_qm.h +++ b/fs/xfs/quota/xfs_qm.h | |||
@@ -165,7 +165,7 @@ typedef struct xfs_dquot_acct { | |||
165 | #define XFS_QM_RELE(xqm) ((xqm)->qm_nrefs--) | 165 | #define XFS_QM_RELE(xqm) ((xqm)->qm_nrefs--) |
166 | 166 | ||
167 | extern void xfs_qm_destroy_quotainfo(xfs_mount_t *); | 167 | extern void xfs_qm_destroy_quotainfo(xfs_mount_t *); |
168 | extern int xfs_qm_mount_quotas(xfs_mount_t *, int); | 168 | extern void xfs_qm_mount_quotas(xfs_mount_t *, int); |
169 | extern int xfs_qm_quotacheck(xfs_mount_t *); | 169 | extern int xfs_qm_quotacheck(xfs_mount_t *); |
170 | extern void xfs_qm_unmount_quotadestroy(xfs_mount_t *); | 170 | extern void xfs_qm_unmount_quotadestroy(xfs_mount_t *); |
171 | extern int xfs_qm_unmount_quotas(xfs_mount_t *); | 171 | extern int xfs_qm_unmount_quotas(xfs_mount_t *); |
diff --git a/fs/xfs/quota/xfs_qm_bhv.c b/fs/xfs/quota/xfs_qm_bhv.c index 97bb32937585..f4f6c4c861d7 100644 --- a/fs/xfs/quota/xfs_qm_bhv.c +++ b/fs/xfs/quota/xfs_qm_bhv.c | |||
@@ -118,7 +118,7 @@ xfs_qm_newmount( | |||
118 | *quotaflags = 0; | 118 | *quotaflags = 0; |
119 | *needquotamount = B_FALSE; | 119 | *needquotamount = B_FALSE; |
120 | 120 | ||
121 | quotaondisk = XFS_SB_VERSION_HASQUOTA(&mp->m_sb) && | 121 | quotaondisk = xfs_sb_version_hasquota(&mp->m_sb) && |
122 | (mp->m_sb.sb_qflags & XFS_ALL_QUOTA_ACCT); | 122 | (mp->m_sb.sb_qflags & XFS_ALL_QUOTA_ACCT); |
123 | 123 | ||
124 | if (quotaondisk) { | 124 | if (quotaondisk) { |
diff --git a/fs/xfs/quota/xfs_qm_stats.h b/fs/xfs/quota/xfs_qm_stats.h index a50ffabcf554..5b964fc0dc09 100644 --- a/fs/xfs/quota/xfs_qm_stats.h +++ b/fs/xfs/quota/xfs_qm_stats.h | |||
@@ -45,8 +45,8 @@ extern void xfs_qm_cleanup_procfs(void); | |||
45 | 45 | ||
46 | # define XQM_STATS_INC(count) do { } while (0) | 46 | # define XQM_STATS_INC(count) do { } while (0) |
47 | 47 | ||
48 | static __inline void xfs_qm_init_procfs(void) { }; | 48 | static inline void xfs_qm_init_procfs(void) { }; |
49 | static __inline void xfs_qm_cleanup_procfs(void) { }; | 49 | static inline void xfs_qm_cleanup_procfs(void) { }; |
50 | 50 | ||
51 | #endif | 51 | #endif |
52 | 52 | ||
diff --git a/fs/xfs/quota/xfs_qm_syscalls.c b/fs/xfs/quota/xfs_qm_syscalls.c index 2cc5886cfe85..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,35 +380,34 @@ 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; | 388 | if (!xfs_sb_version_hasquota(&mp->m_sb) || flags == 0) { |
380 | 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); |
383 | } | 391 | } |
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 | ||
@@ -522,7 +530,7 @@ xfs_qm_scall_getqstat( | |||
522 | memset(out, 0, sizeof(fs_quota_stat_t)); | 530 | memset(out, 0, sizeof(fs_quota_stat_t)); |
523 | 531 | ||
524 | out->qs_version = FS_QSTAT_VERSION; | 532 | out->qs_version = FS_QSTAT_VERSION; |
525 | if (! XFS_SB_VERSION_HASQUOTA(&mp->m_sb)) { | 533 | if (!xfs_sb_version_hasquota(&mp->m_sb)) { |
526 | out->qs_uquota.qfs_ino = NULLFSINO; | 534 | out->qs_uquota.qfs_ino = NULLFSINO; |
527 | out->qs_gquota.qfs_ino = NULLFSINO; | 535 | out->qs_gquota.qfs_ino = NULLFSINO; |
528 | return (0); | 536 | return (0); |
@@ -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 |