aboutsummaryrefslogtreecommitdiffstats
path: root/fs
diff options
context:
space:
mode:
Diffstat (limited to 'fs')
-rw-r--r--fs/dquot.c77
-rw-r--r--fs/quota.c5
-rw-r--r--fs/super.c10
3 files changed, 78 insertions, 14 deletions
diff --git a/fs/dquot.c b/fs/dquot.c
index fc26d1097d3c..dfba1623cccb 100644
--- a/fs/dquot.c
+++ b/fs/dquot.c
@@ -1449,31 +1449,43 @@ static inline void set_enable_flags(struct quota_info *dqopt, int type)
1449 switch (type) { 1449 switch (type) {
1450 case USRQUOTA: 1450 case USRQUOTA:
1451 dqopt->flags |= DQUOT_USR_ENABLED; 1451 dqopt->flags |= DQUOT_USR_ENABLED;
1452 dqopt->flags &= ~DQUOT_USR_SUSPENDED;
1452 break; 1453 break;
1453 case GRPQUOTA: 1454 case GRPQUOTA:
1454 dqopt->flags |= DQUOT_GRP_ENABLED; 1455 dqopt->flags |= DQUOT_GRP_ENABLED;
1456 dqopt->flags &= ~DQUOT_GRP_SUSPENDED;
1455 break; 1457 break;
1456 } 1458 }
1457} 1459}
1458 1460
1459static 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)
1460{ 1463{
1461 switch (type) { 1464 switch (type) {
1462 case USRQUOTA: 1465 case USRQUOTA:
1463 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;
1464 break; 1471 break;
1465 case GRPQUOTA: 1472 case GRPQUOTA:
1466 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;
1467 break; 1478 break;
1468 } 1479 }
1469} 1480}
1470 1481
1482
1471/* 1483/*
1472 * 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)
1473 */ 1485 */
1474int vfs_quota_off(struct super_block *sb, int type) 1486int vfs_quota_off(struct super_block *sb, int type, int remount)
1475{ 1487{
1476 int cnt; 1488 int cnt, ret = 0;
1477 struct quota_info *dqopt = sb_dqopt(sb); 1489 struct quota_info *dqopt = sb_dqopt(sb);
1478 struct inode *toputinode[MAXQUOTAS]; 1490 struct inode *toputinode[MAXQUOTAS];
1479 1491
@@ -1483,9 +1495,17 @@ int vfs_quota_off(struct super_block *sb, int type)
1483 toputinode[cnt] = NULL; 1495 toputinode[cnt] = NULL;
1484 if (type != -1 && cnt != type) 1496 if (type != -1 && cnt != type)
1485 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 }
1486 if (!sb_has_quota_enabled(sb, cnt)) 1506 if (!sb_has_quota_enabled(sb, cnt))
1487 continue; 1507 continue;
1488 reset_enable_flags(dqopt, cnt); 1508 reset_enable_flags(dqopt, cnt, remount);
1489 1509
1490 /* Note: these are blocking operations */ 1510 /* Note: these are blocking operations */
1491 drop_dquot_ref(sb, cnt); 1511 drop_dquot_ref(sb, cnt);
@@ -1501,7 +1521,8 @@ int vfs_quota_off(struct super_block *sb, int type)
1501 put_quota_format(dqopt->info[cnt].dqi_format); 1521 put_quota_format(dqopt->info[cnt].dqi_format);
1502 1522
1503 toputinode[cnt] = dqopt->files[cnt]; 1523 toputinode[cnt] = dqopt->files[cnt];
1504 dqopt->files[cnt] = NULL; 1524 if (!remount)
1525 dqopt->files[cnt] = NULL;
1505 dqopt->info[cnt].dqi_flags = 0; 1526 dqopt->info[cnt].dqi_flags = 0;
1506 dqopt->info[cnt].dqi_igrace = 0; 1527 dqopt->info[cnt].dqi_igrace = 0;
1507 dqopt->info[cnt].dqi_bgrace = 0; 1528 dqopt->info[cnt].dqi_bgrace = 0;
@@ -1531,12 +1552,19 @@ int vfs_quota_off(struct super_block *sb, int type)
1531 mutex_unlock(&toputinode[cnt]->i_mutex); 1552 mutex_unlock(&toputinode[cnt]->i_mutex);
1532 mark_inode_dirty(toputinode[cnt]); 1553 mark_inode_dirty(toputinode[cnt]);
1533 } 1554 }
1534 iput(toputinode[cnt]);
1535 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;
1536 } 1564 }
1537 if (sb->s_bdev) 1565 if (sb->s_bdev)
1538 invalidate_bdev(sb->s_bdev); 1566 invalidate_bdev(sb->s_bdev);
1539 return 0; 1567 return ret;
1540} 1568}
1541 1569
1542/* 1570/*
@@ -1574,7 +1602,8 @@ static int vfs_quota_on_inode(struct inode *inode, int type, int format_id)
1574 invalidate_bdev(sb->s_bdev); 1602 invalidate_bdev(sb->s_bdev);
1575 mutex_lock(&inode->i_mutex); 1603 mutex_lock(&inode->i_mutex);
1576 mutex_lock(&dqopt->dqonoff_mutex); 1604 mutex_lock(&dqopt->dqonoff_mutex);
1577 if (sb_has_quota_enabled(sb, type)) { 1605 if (sb_has_quota_enabled(sb, type) ||
1606 sb_has_quota_suspended(sb, type)) {
1578 error = -EBUSY; 1607 error = -EBUSY;
1579 goto out_lock; 1608 goto out_lock;
1580 } 1609 }
@@ -1597,6 +1626,7 @@ static int vfs_quota_on_inode(struct inode *inode, int type, int format_id)
1597 1626
1598 dqopt->ops[type] = fmt->qf_ops; 1627 dqopt->ops[type] = fmt->qf_ops;
1599 dqopt->info[type].dqi_format = fmt; 1628 dqopt->info[type].dqi_format = fmt;
1629 dqopt->info[type].dqi_fmt_id = format_id;
1600 INIT_LIST_HEAD(&dqopt->info[type].dqi_dirty_list); 1630 INIT_LIST_HEAD(&dqopt->info[type].dqi_dirty_list);
1601 mutex_lock(&dqopt->dqio_mutex); 1631 mutex_lock(&dqopt->dqio_mutex);
1602 if ((error = dqopt->ops[type]->read_file_info(sb, type)) < 0) { 1632 if ((error = dqopt->ops[type]->read_file_info(sb, type)) < 0) {
@@ -1632,12 +1662,41 @@ out_fmt:
1632 return error; 1662 return error;
1633} 1663}
1634 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
1635/* Actual function called from quotactl() */ 1690/* Actual function called from quotactl() */
1636int 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)
1637{ 1693{
1638 struct nameidata nd; 1694 struct nameidata nd;
1639 int error; 1695 int error;
1640 1696
1697 if (remount)
1698 return vfs_quota_on_remount(sb, type);
1699
1641 error = path_lookup(path, LOOKUP_FOLLOW, &nd); 1700 error = path_lookup(path, LOOKUP_FOLLOW, &nd);
1642 if (error < 0) 1701 if (error < 0)
1643 return error; 1702 return error;
diff --git a/fs/quota.c b/fs/quota.c
index 84f28dd72116..db1cc9f3c7aa 100644
--- a/fs/quota.c
+++ b/fs/quota.c
@@ -69,7 +69,6 @@ static int generic_quotactl_valid(struct super_block *sb, int type, int cmd, qid
69 switch (cmd) { 69 switch (cmd) {
70 case Q_GETFMT: 70 case Q_GETFMT:
71 case Q_GETINFO: 71 case Q_GETINFO:
72 case Q_QUOTAOFF:
73 case Q_SETINFO: 72 case Q_SETINFO:
74 case Q_SETQUOTA: 73 case Q_SETQUOTA:
75 case Q_GETQUOTA: 74 case Q_GETQUOTA:
@@ -229,12 +228,12 @@ static int do_quotactl(struct super_block *sb, int type, int cmd, qid_t id, void
229 228
230 if (IS_ERR(pathname = getname(addr))) 229 if (IS_ERR(pathname = getname(addr)))
231 return PTR_ERR(pathname); 230 return PTR_ERR(pathname);
232 ret = sb->s_qcop->quota_on(sb, type, id, pathname); 231 ret = sb->s_qcop->quota_on(sb, type, id, pathname, 0);
233 putname(pathname); 232 putname(pathname);
234 return ret; 233 return ret;
235 } 234 }
236 case Q_QUOTAOFF: 235 case Q_QUOTAOFF:
237 return sb->s_qcop->quota_off(sb, type); 236 return sb->s_qcop->quota_off(sb, type, 0);
238 237
239 case Q_GETFMT: { 238 case Q_GETFMT: {
240 __u32 fmt; 239 __u32 fmt;
diff --git a/fs/super.c b/fs/super.c
index 4798350b2bc9..a5a4aca7e22f 100644
--- a/fs/super.c
+++ b/fs/super.c
@@ -179,7 +179,7 @@ void deactivate_super(struct super_block *s)
179 if (atomic_dec_and_lock(&s->s_active, &sb_lock)) { 179 if (atomic_dec_and_lock(&s->s_active, &sb_lock)) {
180 s->s_count -= S_BIAS-1; 180 s->s_count -= S_BIAS-1;
181 spin_unlock(&sb_lock); 181 spin_unlock(&sb_lock);
182 DQUOT_OFF(s); 182 DQUOT_OFF(s, 0);
183 down_write(&s->s_umount); 183 down_write(&s->s_umount);
184 fs->kill_sb(s); 184 fs->kill_sb(s);
185 put_filesystem(fs); 185 put_filesystem(fs);
@@ -608,6 +608,7 @@ retry:
608int do_remount_sb(struct super_block *sb, int flags, void *data, int force) 608int do_remount_sb(struct super_block *sb, int flags, void *data, int force)
609{ 609{
610 int retval; 610 int retval;
611 int remount_rw;
611 612
612#ifdef CONFIG_BLOCK 613#ifdef CONFIG_BLOCK
613 if (!(flags & MS_RDONLY) && bdev_read_only(sb->s_bdev)) 614 if (!(flags & MS_RDONLY) && bdev_read_only(sb->s_bdev))
@@ -625,8 +626,11 @@ int do_remount_sb(struct super_block *sb, int flags, void *data, int force)
625 mark_files_ro(sb); 626 mark_files_ro(sb);
626 else if (!fs_may_remount_ro(sb)) 627 else if (!fs_may_remount_ro(sb))
627 return -EBUSY; 628 return -EBUSY;
628 DQUOT_OFF(sb); 629 retval = DQUOT_OFF(sb, 1);
630 if (retval < 0 && retval != -ENOSYS)
631 return -EBUSY;
629 } 632 }
633 remount_rw = !(flags & MS_RDONLY) && (sb->s_flags & MS_RDONLY);
630 634
631 if (sb->s_op->remount_fs) { 635 if (sb->s_op->remount_fs) {
632 lock_super(sb); 636 lock_super(sb);
@@ -636,6 +640,8 @@ int do_remount_sb(struct super_block *sb, int flags, void *data, int force)
636 return retval; 640 return retval;
637 } 641 }
638 sb->s_flags = (sb->s_flags & ~MS_RMT_MASK) | (flags & MS_RMT_MASK); 642 sb->s_flags = (sb->s_flags & ~MS_RMT_MASK) | (flags & MS_RMT_MASK);
643 if (remount_rw)
644 DQUOT_ON_REMOUNT(sb);
639 return 0; 645 return 0;
640} 646}
641 647