aboutsummaryrefslogtreecommitdiffstats
path: root/fs/dquot.c
diff options
context:
space:
mode:
Diffstat (limited to 'fs/dquot.c')
-rw-r--r--fs/dquot.c109
1 files changed, 94 insertions, 15 deletions
diff --git a/fs/dquot.c b/fs/dquot.c
index 41b9dbd68b0e..dfba1623cccb 100644
--- a/fs/dquot.c
+++ b/fs/dquot.c
@@ -289,7 +289,15 @@ static void wait_on_dquot(struct dquot *dquot)
289 mutex_unlock(&dquot->dq_lock); 289 mutex_unlock(&dquot->dq_lock);
290} 290}
291 291
292#define mark_dquot_dirty(dquot) ((dquot)->dq_sb->dq_op->mark_dirty(dquot)) 292static inline int dquot_dirty(struct dquot *dquot)
293{
294 return test_bit(DQ_MOD_B, &dquot->dq_flags);
295}
296
297static inline int mark_dquot_dirty(struct dquot *dquot)
298{
299 return dquot->dq_sb->dq_op->mark_dirty(dquot);
300}
293 301
294int dquot_mark_dquot_dirty(struct dquot *dquot) 302int dquot_mark_dquot_dirty(struct dquot *dquot)
295{ 303{
@@ -1441,31 +1449,43 @@ static inline void set_enable_flags(struct quota_info *dqopt, int type)
1441 switch (type) { 1449 switch (type) {
1442 case USRQUOTA: 1450 case USRQUOTA:
1443 dqopt->flags |= DQUOT_USR_ENABLED; 1451 dqopt->flags |= DQUOT_USR_ENABLED;
1452 dqopt->flags &= ~DQUOT_USR_SUSPENDED;
1444 break; 1453 break;
1445 case GRPQUOTA: 1454 case GRPQUOTA:
1446 dqopt->flags |= DQUOT_GRP_ENABLED; 1455 dqopt->flags |= DQUOT_GRP_ENABLED;
1456 dqopt->flags &= ~DQUOT_GRP_SUSPENDED;
1447 break; 1457 break;
1448 } 1458 }
1449} 1459}
1450 1460
1451static inline void reset_enable_flags(struct quota_info *dqopt, int type) 1461static inline void reset_enable_flags(struct quota_info *dqopt, int type,
1462 int remount)
1452{ 1463{
1453 switch (type) { 1464 switch (type) {
1454 case USRQUOTA: 1465 case USRQUOTA:
1455 dqopt->flags &= ~DQUOT_USR_ENABLED; 1466 dqopt->flags &= ~DQUOT_USR_ENABLED;
1467 if (remount)
1468 dqopt->flags |= DQUOT_USR_SUSPENDED;
1469 else
1470 dqopt->flags &= ~DQUOT_USR_SUSPENDED;
1456 break; 1471 break;
1457 case GRPQUOTA: 1472 case GRPQUOTA:
1458 dqopt->flags &= ~DQUOT_GRP_ENABLED; 1473 dqopt->flags &= ~DQUOT_GRP_ENABLED;
1474 if (remount)
1475 dqopt->flags |= DQUOT_GRP_SUSPENDED;
1476 else
1477 dqopt->flags &= ~DQUOT_GRP_SUSPENDED;
1459 break; 1478 break;
1460 } 1479 }
1461} 1480}
1462 1481
1482
1463/* 1483/*
1464 * Turn quota off on a device. type == -1 ==> quotaoff for all types (umount) 1484 * Turn quota off on a device. type == -1 ==> quotaoff for all types (umount)
1465 */ 1485 */
1466int vfs_quota_off(struct super_block *sb, int type) 1486int vfs_quota_off(struct super_block *sb, int type, int remount)
1467{ 1487{
1468 int cnt; 1488 int cnt, ret = 0;
1469 struct quota_info *dqopt = sb_dqopt(sb); 1489 struct quota_info *dqopt = sb_dqopt(sb);
1470 struct inode *toputinode[MAXQUOTAS]; 1490 struct inode *toputinode[MAXQUOTAS];
1471 1491
@@ -1475,9 +1495,17 @@ int vfs_quota_off(struct super_block *sb, int type)
1475 toputinode[cnt] = NULL; 1495 toputinode[cnt] = NULL;
1476 if (type != -1 && cnt != type) 1496 if (type != -1 && cnt != type)
1477 continue; 1497 continue;
1498 /* If we keep inodes of quota files after remount and quotaoff
1499 * is called, drop kept inodes. */
1500 if (!remount && sb_has_quota_suspended(sb, cnt)) {
1501 iput(dqopt->files[cnt]);
1502 dqopt->files[cnt] = NULL;
1503 reset_enable_flags(dqopt, cnt, 0);
1504 continue;
1505 }
1478 if (!sb_has_quota_enabled(sb, cnt)) 1506 if (!sb_has_quota_enabled(sb, cnt))
1479 continue; 1507 continue;
1480 reset_enable_flags(dqopt, cnt); 1508 reset_enable_flags(dqopt, cnt, remount);
1481 1509
1482 /* Note: these are blocking operations */ 1510 /* Note: these are blocking operations */
1483 drop_dquot_ref(sb, cnt); 1511 drop_dquot_ref(sb, cnt);
@@ -1493,7 +1521,8 @@ int vfs_quota_off(struct super_block *sb, int type)
1493 put_quota_format(dqopt->info[cnt].dqi_format); 1521 put_quota_format(dqopt->info[cnt].dqi_format);
1494 1522
1495 toputinode[cnt] = dqopt->files[cnt]; 1523 toputinode[cnt] = dqopt->files[cnt];
1496 dqopt->files[cnt] = NULL; 1524 if (!remount)
1525 dqopt->files[cnt] = NULL;
1497 dqopt->info[cnt].dqi_flags = 0; 1526 dqopt->info[cnt].dqi_flags = 0;
1498 dqopt->info[cnt].dqi_igrace = 0; 1527 dqopt->info[cnt].dqi_igrace = 0;
1499 dqopt->info[cnt].dqi_bgrace = 0; 1528 dqopt->info[cnt].dqi_bgrace = 0;
@@ -1523,12 +1552,19 @@ int vfs_quota_off(struct super_block *sb, int type)
1523 mutex_unlock(&toputinode[cnt]->i_mutex); 1552 mutex_unlock(&toputinode[cnt]->i_mutex);
1524 mark_inode_dirty(toputinode[cnt]); 1553 mark_inode_dirty(toputinode[cnt]);
1525 } 1554 }
1526 iput(toputinode[cnt]);
1527 mutex_unlock(&dqopt->dqonoff_mutex); 1555 mutex_unlock(&dqopt->dqonoff_mutex);
1556 /* On remount RO, we keep the inode pointer so that we
1557 * can reenable quota on the subsequent remount RW.
1558 * But we have better not keep inode pointer when there
1559 * is pending delete on the quota file... */
1560 if (!remount)
1561 iput(toputinode[cnt]);
1562 else if (!toputinode[cnt]->i_nlink)
1563 ret = -EBUSY;
1528 } 1564 }
1529 if (sb->s_bdev) 1565 if (sb->s_bdev)
1530 invalidate_bdev(sb->s_bdev); 1566 invalidate_bdev(sb->s_bdev);
1531 return 0; 1567 return ret;
1532} 1568}
1533 1569
1534/* 1570/*
@@ -1566,7 +1602,8 @@ static int vfs_quota_on_inode(struct inode *inode, int type, int format_id)
1566 invalidate_bdev(sb->s_bdev); 1602 invalidate_bdev(sb->s_bdev);
1567 mutex_lock(&inode->i_mutex); 1603 mutex_lock(&inode->i_mutex);
1568 mutex_lock(&dqopt->dqonoff_mutex); 1604 mutex_lock(&dqopt->dqonoff_mutex);
1569 if (sb_has_quota_enabled(sb, type)) { 1605 if (sb_has_quota_enabled(sb, type) ||
1606 sb_has_quota_suspended(sb, type)) {
1570 error = -EBUSY; 1607 error = -EBUSY;
1571 goto out_lock; 1608 goto out_lock;
1572 } 1609 }
@@ -1589,6 +1626,7 @@ static int vfs_quota_on_inode(struct inode *inode, int type, int format_id)
1589 1626
1590 dqopt->ops[type] = fmt->qf_ops; 1627 dqopt->ops[type] = fmt->qf_ops;
1591 dqopt->info[type].dqi_format = fmt; 1628 dqopt->info[type].dqi_format = fmt;
1629 dqopt->info[type].dqi_fmt_id = format_id;
1592 INIT_LIST_HEAD(&dqopt->info[type].dqi_dirty_list); 1630 INIT_LIST_HEAD(&dqopt->info[type].dqi_dirty_list);
1593 mutex_lock(&dqopt->dqio_mutex); 1631 mutex_lock(&dqopt->dqio_mutex);
1594 if ((error = dqopt->ops[type]->read_file_info(sb, type)) < 0) { 1632 if ((error = dqopt->ops[type]->read_file_info(sb, type)) < 0) {
@@ -1624,12 +1662,41 @@ out_fmt:
1624 return error; 1662 return error;
1625} 1663}
1626 1664
1665/* Reenable quotas on remount RW */
1666static int vfs_quota_on_remount(struct super_block *sb, int type)
1667{
1668 struct quota_info *dqopt = sb_dqopt(sb);
1669 struct inode *inode;
1670 int ret;
1671
1672 mutex_lock(&dqopt->dqonoff_mutex);
1673 if (!sb_has_quota_suspended(sb, type)) {
1674 mutex_unlock(&dqopt->dqonoff_mutex);
1675 return 0;
1676 }
1677 BUG_ON(sb_has_quota_enabled(sb, type));
1678
1679 inode = dqopt->files[type];
1680 dqopt->files[type] = NULL;
1681 reset_enable_flags(dqopt, type, 0);
1682 mutex_unlock(&dqopt->dqonoff_mutex);
1683
1684 ret = vfs_quota_on_inode(inode, type, dqopt->info[type].dqi_fmt_id);
1685 iput(inode);
1686
1687 return ret;
1688}
1689
1627/* Actual function called from quotactl() */ 1690/* Actual function called from quotactl() */
1628int vfs_quota_on(struct super_block *sb, int type, int format_id, char *path) 1691int vfs_quota_on(struct super_block *sb, int type, int format_id, char *path,
1692 int remount)
1629{ 1693{
1630 struct nameidata nd; 1694 struct nameidata nd;
1631 int error; 1695 int error;
1632 1696
1697 if (remount)
1698 return vfs_quota_on_remount(sb, type);
1699
1633 error = path_lookup(path, LOOKUP_FOLLOW, &nd); 1700 error = path_lookup(path, LOOKUP_FOLLOW, &nd);
1634 if (error < 0) 1701 if (error < 0)
1635 return error; 1702 return error;
@@ -1709,10 +1776,19 @@ int vfs_get_dqblk(struct super_block *sb, int type, qid_t id, struct if_dqblk *d
1709} 1776}
1710 1777
1711/* Generic routine for setting common part of quota structure */ 1778/* Generic routine for setting common part of quota structure */
1712static void do_set_dqblk(struct dquot *dquot, struct if_dqblk *di) 1779static int do_set_dqblk(struct dquot *dquot, struct if_dqblk *di)
1713{ 1780{
1714 struct mem_dqblk *dm = &dquot->dq_dqb; 1781 struct mem_dqblk *dm = &dquot->dq_dqb;
1715 int check_blim = 0, check_ilim = 0; 1782 int check_blim = 0, check_ilim = 0;
1783 struct mem_dqinfo *dqi = &sb_dqopt(dquot->dq_sb)->info[dquot->dq_type];
1784
1785 if ((di->dqb_valid & QIF_BLIMITS &&
1786 (di->dqb_bhardlimit > dqi->dqi_maxblimit ||
1787 di->dqb_bsoftlimit > dqi->dqi_maxblimit)) ||
1788 (di->dqb_valid & QIF_ILIMITS &&
1789 (di->dqb_ihardlimit > dqi->dqi_maxilimit ||
1790 di->dqb_isoftlimit > dqi->dqi_maxilimit)))
1791 return -ERANGE;
1716 1792
1717 spin_lock(&dq_data_lock); 1793 spin_lock(&dq_data_lock);
1718 if (di->dqb_valid & QIF_SPACE) { 1794 if (di->dqb_valid & QIF_SPACE) {
@@ -1744,7 +1820,7 @@ static void do_set_dqblk(struct dquot *dquot, struct if_dqblk *di)
1744 clear_bit(DQ_BLKS_B, &dquot->dq_flags); 1820 clear_bit(DQ_BLKS_B, &dquot->dq_flags);
1745 } 1821 }
1746 else if (!(di->dqb_valid & QIF_BTIME)) /* Set grace only if user hasn't provided his own... */ 1822 else if (!(di->dqb_valid & QIF_BTIME)) /* Set grace only if user hasn't provided his own... */
1747 dm->dqb_btime = get_seconds() + sb_dqopt(dquot->dq_sb)->info[dquot->dq_type].dqi_bgrace; 1823 dm->dqb_btime = get_seconds() + dqi->dqi_bgrace;
1748 } 1824 }
1749 if (check_ilim) { 1825 if (check_ilim) {
1750 if (!dm->dqb_isoftlimit || dm->dqb_curinodes < dm->dqb_isoftlimit) { 1826 if (!dm->dqb_isoftlimit || dm->dqb_curinodes < dm->dqb_isoftlimit) {
@@ -1752,7 +1828,7 @@ static void do_set_dqblk(struct dquot *dquot, struct if_dqblk *di)
1752 clear_bit(DQ_INODES_B, &dquot->dq_flags); 1828 clear_bit(DQ_INODES_B, &dquot->dq_flags);
1753 } 1829 }
1754 else if (!(di->dqb_valid & QIF_ITIME)) /* Set grace only if user hasn't provided his own... */ 1830 else if (!(di->dqb_valid & QIF_ITIME)) /* Set grace only if user hasn't provided his own... */
1755 dm->dqb_itime = get_seconds() + sb_dqopt(dquot->dq_sb)->info[dquot->dq_type].dqi_igrace; 1831 dm->dqb_itime = get_seconds() + dqi->dqi_igrace;
1756 } 1832 }
1757 if (dm->dqb_bhardlimit || dm->dqb_bsoftlimit || dm->dqb_ihardlimit || dm->dqb_isoftlimit) 1833 if (dm->dqb_bhardlimit || dm->dqb_bsoftlimit || dm->dqb_ihardlimit || dm->dqb_isoftlimit)
1758 clear_bit(DQ_FAKE_B, &dquot->dq_flags); 1834 clear_bit(DQ_FAKE_B, &dquot->dq_flags);
@@ -1760,21 +1836,24 @@ static void do_set_dqblk(struct dquot *dquot, struct if_dqblk *di)
1760 set_bit(DQ_FAKE_B, &dquot->dq_flags); 1836 set_bit(DQ_FAKE_B, &dquot->dq_flags);
1761 spin_unlock(&dq_data_lock); 1837 spin_unlock(&dq_data_lock);
1762 mark_dquot_dirty(dquot); 1838 mark_dquot_dirty(dquot);
1839
1840 return 0;
1763} 1841}
1764 1842
1765int vfs_set_dqblk(struct super_block *sb, int type, qid_t id, struct if_dqblk *di) 1843int vfs_set_dqblk(struct super_block *sb, int type, qid_t id, struct if_dqblk *di)
1766{ 1844{
1767 struct dquot *dquot; 1845 struct dquot *dquot;
1846 int rc;
1768 1847
1769 mutex_lock(&sb_dqopt(sb)->dqonoff_mutex); 1848 mutex_lock(&sb_dqopt(sb)->dqonoff_mutex);
1770 if (!(dquot = dqget(sb, id, type))) { 1849 if (!(dquot = dqget(sb, id, type))) {
1771 mutex_unlock(&sb_dqopt(sb)->dqonoff_mutex); 1850 mutex_unlock(&sb_dqopt(sb)->dqonoff_mutex);
1772 return -ESRCH; 1851 return -ESRCH;
1773 } 1852 }
1774 do_set_dqblk(dquot, di); 1853 rc = do_set_dqblk(dquot, di);
1775 dqput(dquot); 1854 dqput(dquot);
1776 mutex_unlock(&sb_dqopt(sb)->dqonoff_mutex); 1855 mutex_unlock(&sb_dqopt(sb)->dqonoff_mutex);
1777 return 0; 1856 return rc;
1778} 1857}
1779 1858
1780/* Generic routine for getting common part of quota file information */ 1859/* Generic routine for getting common part of quota file information */