diff options
author | Linus Torvalds <torvalds@linux-foundation.org> | 2015-04-16 22:19:33 -0400 |
---|---|---|
committer | Linus Torvalds <torvalds@linux-foundation.org> | 2015-04-16 22:19:33 -0400 |
commit | 84588e7a5d8220446d677d7b909a20ee7a4496b9 (patch) | |
tree | 5633f76cba4788cb2b073ac0c0f93541c267e7ee /fs | |
parent | a39ef1a7c6093bbd4e0a8197350b99cd635e5446 (diff) | |
parent | 3adc12e9648291149a1e3f354d0ad158fc2571e7 (diff) |
Merge branch 'for_linus' of git://git.kernel.org/pub/scm/linux/kernel/git/jack/linux-fs
Pull quota and udf updates from Jan Kara:
"The pull contains quota changes which complete unification of XFS and
VFS quota interfaces (so tools can use either interface to manipulate
any filesystem). There's also a patch to support project quotas in
VFS quota subsystem from Li Xi.
Finally there's a bunch of UDF fixes and cleanups and tiny cleanup in
reiserfs & ext3"
* 'for_linus' of git://git.kernel.org/pub/scm/linux/kernel/git/jack/linux-fs: (21 commits)
udf: Update ctime and mtime when directory is modified
udf: return correct errno for udf_update_inode()
ext3: Remove useless condition in if statement.
vfs: Add general support to enforce project quota limits
reiserfs: fix __RASSERT format string
udf: use int for allocated blocks instead of sector_t
udf: remove redundant buffer_head.h includes
udf: remove else after return in __load_block_bitmap()
udf: remove unused variable in udf_table_free_blocks()
quota: Fix maximum quota limit settings
quota: reorder flags in quota state
quota: paranoia: check quota tree root
quota: optimize i_dquot access
quota: Hook up Q_XSETQLIM for id 0 to ->set_info
xfs: Add support for Q_SETINFO
quota: Make ->set_info use structure with neccesary info to VFS and XFS
quota: Remove ->get_xstate and ->get_xstatev callbacks
gfs2: Convert to using ->get_state callback
xfs: Convert to using ->get_state callback
quota: Wire up Q_GETXSTATE and Q_GETXSTATV calls to work with ->get_state
...
Diffstat (limited to 'fs')
-rw-r--r-- | fs/ext3/super.c | 2 | ||||
-rw-r--r-- | fs/ext3/xattr.c | 3 | ||||
-rw-r--r-- | fs/ext4/super.c | 2 | ||||
-rw-r--r-- | fs/gfs2/quota.c | 28 | ||||
-rw-r--r-- | fs/quota/dquot.c | 151 | ||||
-rw-r--r-- | fs/quota/quota.c | 217 | ||||
-rw-r--r-- | fs/quota/quota_tree.c | 7 | ||||
-rw-r--r-- | fs/quota/quota_v2.c | 12 | ||||
-rw-r--r-- | fs/quota/quotaio_v2.h | 6 | ||||
-rw-r--r-- | fs/reiserfs/reiserfs.h | 1 | ||||
-rw-r--r-- | fs/reiserfs/super.c | 2 | ||||
-rw-r--r-- | fs/udf/balloc.c | 20 | ||||
-rw-r--r-- | fs/udf/dir.c | 1 | ||||
-rw-r--r-- | fs/udf/directory.c | 1 | ||||
-rw-r--r-- | fs/udf/file.c | 1 | ||||
-rw-r--r-- | fs/udf/inode.c | 3 | ||||
-rw-r--r-- | fs/udf/misc.c | 1 | ||||
-rw-r--r-- | fs/udf/namei.c | 10 | ||||
-rw-r--r-- | fs/udf/partition.c | 1 | ||||
-rw-r--r-- | fs/udf/super.c | 1 | ||||
-rw-r--r-- | fs/udf/symlink.c | 1 | ||||
-rw-r--r-- | fs/udf/truncate.c | 1 | ||||
-rw-r--r-- | fs/xfs/xfs_qm.h | 4 | ||||
-rw-r--r-- | fs/xfs/xfs_qm_syscalls.c | 176 | ||||
-rw-r--r-- | fs/xfs/xfs_quotaops.c | 117 |
25 files changed, 461 insertions, 308 deletions
diff --git a/fs/ext3/super.c b/fs/ext3/super.c index d4dbf3c259b3..f037b4b27300 100644 --- a/fs/ext3/super.c +++ b/fs/ext3/super.c | |||
@@ -789,7 +789,7 @@ static const struct quotactl_ops ext3_qctl_operations = { | |||
789 | .quota_on = ext3_quota_on, | 789 | .quota_on = ext3_quota_on, |
790 | .quota_off = dquot_quota_off, | 790 | .quota_off = dquot_quota_off, |
791 | .quota_sync = dquot_quota_sync, | 791 | .quota_sync = dquot_quota_sync, |
792 | .get_info = dquot_get_dqinfo, | 792 | .get_state = dquot_get_state, |
793 | .set_info = dquot_set_dqinfo, | 793 | .set_info = dquot_set_dqinfo, |
794 | .get_dqblk = dquot_get_dqblk, | 794 | .get_dqblk = dquot_get_dqblk, |
795 | .set_dqblk = dquot_set_dqblk | 795 | .set_dqblk = dquot_set_dqblk |
diff --git a/fs/ext3/xattr.c b/fs/ext3/xattr.c index c6874be6d58b..24215dc09a18 100644 --- a/fs/ext3/xattr.c +++ b/fs/ext3/xattr.c | |||
@@ -546,8 +546,7 @@ ext3_xattr_set_entry(struct ext3_xattr_info *i, struct ext3_xattr_search *s) | |||
546 | free += EXT3_XATTR_LEN(name_len); | 546 | free += EXT3_XATTR_LEN(name_len); |
547 | } | 547 | } |
548 | if (i->value) { | 548 | if (i->value) { |
549 | if (free < EXT3_XATTR_SIZE(i->value_len) || | 549 | if (free < EXT3_XATTR_LEN(name_len) + |
550 | free < EXT3_XATTR_LEN(name_len) + | ||
551 | EXT3_XATTR_SIZE(i->value_len)) | 550 | EXT3_XATTR_SIZE(i->value_len)) |
552 | return -ENOSPC; | 551 | return -ENOSPC; |
553 | } | 552 | } |
diff --git a/fs/ext4/super.c b/fs/ext4/super.c index e061e66c8280..d348c7d29d80 100644 --- a/fs/ext4/super.c +++ b/fs/ext4/super.c | |||
@@ -1076,7 +1076,7 @@ static const struct quotactl_ops ext4_qctl_operations = { | |||
1076 | .quota_on = ext4_quota_on, | 1076 | .quota_on = ext4_quota_on, |
1077 | .quota_off = ext4_quota_off, | 1077 | .quota_off = ext4_quota_off, |
1078 | .quota_sync = dquot_quota_sync, | 1078 | .quota_sync = dquot_quota_sync, |
1079 | .get_info = dquot_get_dqinfo, | 1079 | .get_state = dquot_get_state, |
1080 | .set_info = dquot_set_dqinfo, | 1080 | .set_info = dquot_set_dqinfo, |
1081 | .get_dqblk = dquot_get_dqblk, | 1081 | .get_dqblk = dquot_get_dqblk, |
1082 | .set_dqblk = dquot_set_dqblk | 1082 | .set_dqblk = dquot_set_dqblk |
diff --git a/fs/gfs2/quota.c b/fs/gfs2/quota.c index 5c27e48aa76f..e3065cb9ab08 100644 --- a/fs/gfs2/quota.c +++ b/fs/gfs2/quota.c | |||
@@ -1494,32 +1494,34 @@ int gfs2_quotad(void *data) | |||
1494 | return 0; | 1494 | return 0; |
1495 | } | 1495 | } |
1496 | 1496 | ||
1497 | static int gfs2_quota_get_xstate(struct super_block *sb, | 1497 | static int gfs2_quota_get_state(struct super_block *sb, struct qc_state *state) |
1498 | struct fs_quota_stat *fqs) | ||
1499 | { | 1498 | { |
1500 | struct gfs2_sbd *sdp = sb->s_fs_info; | 1499 | struct gfs2_sbd *sdp = sb->s_fs_info; |
1501 | 1500 | ||
1502 | memset(fqs, 0, sizeof(struct fs_quota_stat)); | 1501 | memset(state, 0, sizeof(*state)); |
1503 | fqs->qs_version = FS_QSTAT_VERSION; | ||
1504 | 1502 | ||
1505 | switch (sdp->sd_args.ar_quota) { | 1503 | switch (sdp->sd_args.ar_quota) { |
1506 | case GFS2_QUOTA_ON: | 1504 | case GFS2_QUOTA_ON: |
1507 | fqs->qs_flags |= (FS_QUOTA_UDQ_ENFD | FS_QUOTA_GDQ_ENFD); | 1505 | state->s_state[USRQUOTA].flags |= QCI_LIMITS_ENFORCED; |
1506 | state->s_state[GRPQUOTA].flags |= QCI_LIMITS_ENFORCED; | ||
1508 | /*FALLTHRU*/ | 1507 | /*FALLTHRU*/ |
1509 | case GFS2_QUOTA_ACCOUNT: | 1508 | case GFS2_QUOTA_ACCOUNT: |
1510 | fqs->qs_flags |= (FS_QUOTA_UDQ_ACCT | FS_QUOTA_GDQ_ACCT); | 1509 | state->s_state[USRQUOTA].flags |= QCI_ACCT_ENABLED | |
1510 | QCI_SYSFILE; | ||
1511 | state->s_state[GRPQUOTA].flags |= QCI_ACCT_ENABLED | | ||
1512 | QCI_SYSFILE; | ||
1511 | break; | 1513 | break; |
1512 | case GFS2_QUOTA_OFF: | 1514 | case GFS2_QUOTA_OFF: |
1513 | break; | 1515 | break; |
1514 | } | 1516 | } |
1515 | |||
1516 | if (sdp->sd_quota_inode) { | 1517 | if (sdp->sd_quota_inode) { |
1517 | fqs->qs_uquota.qfs_ino = GFS2_I(sdp->sd_quota_inode)->i_no_addr; | 1518 | state->s_state[USRQUOTA].ino = |
1518 | fqs->qs_uquota.qfs_nblks = sdp->sd_quota_inode->i_blocks; | 1519 | GFS2_I(sdp->sd_quota_inode)->i_no_addr; |
1520 | state->s_state[USRQUOTA].blocks = sdp->sd_quota_inode->i_blocks; | ||
1519 | } | 1521 | } |
1520 | fqs->qs_uquota.qfs_nextents = 1; /* unsupported */ | 1522 | state->s_state[USRQUOTA].nextents = 1; /* unsupported */ |
1521 | fqs->qs_gquota = fqs->qs_uquota; /* its the same inode in both cases */ | 1523 | state->s_state[GRPQUOTA] = state->s_state[USRQUOTA]; |
1522 | fqs->qs_incoredqs = list_lru_count(&gfs2_qd_lru); | 1524 | state->s_incoredqs = list_lru_count(&gfs2_qd_lru); |
1523 | return 0; | 1525 | return 0; |
1524 | } | 1526 | } |
1525 | 1527 | ||
@@ -1664,7 +1666,7 @@ out_put: | |||
1664 | 1666 | ||
1665 | const struct quotactl_ops gfs2_quotactl_ops = { | 1667 | const struct quotactl_ops gfs2_quotactl_ops = { |
1666 | .quota_sync = gfs2_quota_sync, | 1668 | .quota_sync = gfs2_quota_sync, |
1667 | .get_xstate = gfs2_quota_get_xstate, | 1669 | .get_state = gfs2_quota_get_state, |
1668 | .get_dqblk = gfs2_get_dqblk, | 1670 | .get_dqblk = gfs2_get_dqblk, |
1669 | .set_dqblk = gfs2_set_dqblk, | 1671 | .set_dqblk = gfs2_set_dqblk, |
1670 | }; | 1672 | }; |
diff --git a/fs/quota/dquot.c b/fs/quota/dquot.c index 0ccd4ba3a246..ecc25cf0ee6e 100644 --- a/fs/quota/dquot.c +++ b/fs/quota/dquot.c | |||
@@ -900,14 +900,17 @@ static inline struct dquot **i_dquot(struct inode *inode) | |||
900 | 900 | ||
901 | static int dqinit_needed(struct inode *inode, int type) | 901 | static int dqinit_needed(struct inode *inode, int type) |
902 | { | 902 | { |
903 | struct dquot * const *dquots; | ||
903 | int cnt; | 904 | int cnt; |
904 | 905 | ||
905 | if (IS_NOQUOTA(inode)) | 906 | if (IS_NOQUOTA(inode)) |
906 | return 0; | 907 | return 0; |
908 | |||
909 | dquots = i_dquot(inode); | ||
907 | if (type != -1) | 910 | if (type != -1) |
908 | return !i_dquot(inode)[type]; | 911 | return !dquots[type]; |
909 | for (cnt = 0; cnt < MAXQUOTAS; cnt++) | 912 | for (cnt = 0; cnt < MAXQUOTAS; cnt++) |
910 | if (!i_dquot(inode)[cnt]) | 913 | if (!dquots[cnt]) |
911 | return 1; | 914 | return 1; |
912 | return 0; | 915 | return 0; |
913 | } | 916 | } |
@@ -970,12 +973,13 @@ static void add_dquot_ref(struct super_block *sb, int type) | |||
970 | static void remove_inode_dquot_ref(struct inode *inode, int type, | 973 | static void remove_inode_dquot_ref(struct inode *inode, int type, |
971 | struct list_head *tofree_head) | 974 | struct list_head *tofree_head) |
972 | { | 975 | { |
973 | struct dquot *dquot = i_dquot(inode)[type]; | 976 | struct dquot **dquots = i_dquot(inode); |
977 | struct dquot *dquot = dquots[type]; | ||
974 | 978 | ||
975 | i_dquot(inode)[type] = NULL; | ||
976 | if (!dquot) | 979 | if (!dquot) |
977 | return; | 980 | return; |
978 | 981 | ||
982 | dquots[type] = NULL; | ||
979 | if (list_empty(&dquot->dq_free)) { | 983 | if (list_empty(&dquot->dq_free)) { |
980 | /* | 984 | /* |
981 | * The inode still has reference to dquot so it can't be in the | 985 | * The inode still has reference to dquot so it can't be in the |
@@ -1159,8 +1163,8 @@ static int need_print_warning(struct dquot_warn *warn) | |||
1159 | return uid_eq(current_fsuid(), warn->w_dq_id.uid); | 1163 | return uid_eq(current_fsuid(), warn->w_dq_id.uid); |
1160 | case GRPQUOTA: | 1164 | case GRPQUOTA: |
1161 | return in_group_p(warn->w_dq_id.gid); | 1165 | return in_group_p(warn->w_dq_id.gid); |
1162 | case PRJQUOTA: /* Never taken... Just make gcc happy */ | 1166 | case PRJQUOTA: |
1163 | return 0; | 1167 | return 1; |
1164 | } | 1168 | } |
1165 | return 0; | 1169 | return 0; |
1166 | } | 1170 | } |
@@ -1389,16 +1393,21 @@ static int dquot_active(const struct inode *inode) | |||
1389 | static void __dquot_initialize(struct inode *inode, int type) | 1393 | static void __dquot_initialize(struct inode *inode, int type) |
1390 | { | 1394 | { |
1391 | int cnt, init_needed = 0; | 1395 | int cnt, init_needed = 0; |
1392 | struct dquot *got[MAXQUOTAS]; | 1396 | struct dquot **dquots, *got[MAXQUOTAS]; |
1393 | struct super_block *sb = inode->i_sb; | 1397 | struct super_block *sb = inode->i_sb; |
1394 | qsize_t rsv; | 1398 | qsize_t rsv; |
1395 | 1399 | ||
1396 | if (!dquot_active(inode)) | 1400 | if (!dquot_active(inode)) |
1397 | return; | 1401 | return; |
1398 | 1402 | ||
1403 | dquots = i_dquot(inode); | ||
1404 | |||
1399 | /* First get references to structures we might need. */ | 1405 | /* First get references to structures we might need. */ |
1400 | for (cnt = 0; cnt < MAXQUOTAS; cnt++) { | 1406 | for (cnt = 0; cnt < MAXQUOTAS; cnt++) { |
1401 | struct kqid qid; | 1407 | struct kqid qid; |
1408 | kprojid_t projid; | ||
1409 | int rc; | ||
1410 | |||
1402 | got[cnt] = NULL; | 1411 | got[cnt] = NULL; |
1403 | if (type != -1 && cnt != type) | 1412 | if (type != -1 && cnt != type) |
1404 | continue; | 1413 | continue; |
@@ -1407,8 +1416,12 @@ static void __dquot_initialize(struct inode *inode, int type) | |||
1407 | * we check it without locking here to avoid unnecessary | 1416 | * we check it without locking here to avoid unnecessary |
1408 | * dqget()/dqput() calls. | 1417 | * dqget()/dqput() calls. |
1409 | */ | 1418 | */ |
1410 | if (i_dquot(inode)[cnt]) | 1419 | if (dquots[cnt]) |
1420 | continue; | ||
1421 | |||
1422 | if (!sb_has_quota_active(sb, cnt)) | ||
1411 | continue; | 1423 | continue; |
1424 | |||
1412 | init_needed = 1; | 1425 | init_needed = 1; |
1413 | 1426 | ||
1414 | switch (cnt) { | 1427 | switch (cnt) { |
@@ -1418,6 +1431,12 @@ static void __dquot_initialize(struct inode *inode, int type) | |||
1418 | case GRPQUOTA: | 1431 | case GRPQUOTA: |
1419 | qid = make_kqid_gid(inode->i_gid); | 1432 | qid = make_kqid_gid(inode->i_gid); |
1420 | break; | 1433 | break; |
1434 | case PRJQUOTA: | ||
1435 | rc = inode->i_sb->dq_op->get_projid(inode, &projid); | ||
1436 | if (rc) | ||
1437 | continue; | ||
1438 | qid = make_kqid_projid(projid); | ||
1439 | break; | ||
1421 | } | 1440 | } |
1422 | got[cnt] = dqget(sb, qid); | 1441 | got[cnt] = dqget(sb, qid); |
1423 | } | 1442 | } |
@@ -1438,8 +1457,8 @@ static void __dquot_initialize(struct inode *inode, int type) | |||
1438 | /* We could race with quotaon or dqget() could have failed */ | 1457 | /* We could race with quotaon or dqget() could have failed */ |
1439 | if (!got[cnt]) | 1458 | if (!got[cnt]) |
1440 | continue; | 1459 | continue; |
1441 | if (!i_dquot(inode)[cnt]) { | 1460 | if (!dquots[cnt]) { |
1442 | i_dquot(inode)[cnt] = got[cnt]; | 1461 | dquots[cnt] = got[cnt]; |
1443 | got[cnt] = NULL; | 1462 | got[cnt] = NULL; |
1444 | /* | 1463 | /* |
1445 | * Make quota reservation system happy if someone | 1464 | * Make quota reservation system happy if someone |
@@ -1447,7 +1466,7 @@ static void __dquot_initialize(struct inode *inode, int type) | |||
1447 | */ | 1466 | */ |
1448 | rsv = inode_get_rsv_space(inode); | 1467 | rsv = inode_get_rsv_space(inode); |
1449 | if (unlikely(rsv)) | 1468 | if (unlikely(rsv)) |
1450 | dquot_resv_space(i_dquot(inode)[cnt], rsv); | 1469 | dquot_resv_space(dquots[cnt], rsv); |
1451 | } | 1470 | } |
1452 | } | 1471 | } |
1453 | out_err: | 1472 | out_err: |
@@ -1473,12 +1492,13 @@ EXPORT_SYMBOL(dquot_initialize); | |||
1473 | static void __dquot_drop(struct inode *inode) | 1492 | static void __dquot_drop(struct inode *inode) |
1474 | { | 1493 | { |
1475 | int cnt; | 1494 | int cnt; |
1495 | struct dquot **dquots = i_dquot(inode); | ||
1476 | struct dquot *put[MAXQUOTAS]; | 1496 | struct dquot *put[MAXQUOTAS]; |
1477 | 1497 | ||
1478 | spin_lock(&dq_data_lock); | 1498 | spin_lock(&dq_data_lock); |
1479 | for (cnt = 0; cnt < MAXQUOTAS; cnt++) { | 1499 | for (cnt = 0; cnt < MAXQUOTAS; cnt++) { |
1480 | put[cnt] = i_dquot(inode)[cnt]; | 1500 | put[cnt] = dquots[cnt]; |
1481 | i_dquot(inode)[cnt] = NULL; | 1501 | dquots[cnt] = NULL; |
1482 | } | 1502 | } |
1483 | spin_unlock(&dq_data_lock); | 1503 | spin_unlock(&dq_data_lock); |
1484 | dqput_all(put); | 1504 | dqput_all(put); |
@@ -1486,6 +1506,7 @@ static void __dquot_drop(struct inode *inode) | |||
1486 | 1506 | ||
1487 | void dquot_drop(struct inode *inode) | 1507 | void dquot_drop(struct inode *inode) |
1488 | { | 1508 | { |
1509 | struct dquot * const *dquots; | ||
1489 | int cnt; | 1510 | int cnt; |
1490 | 1511 | ||
1491 | if (IS_NOQUOTA(inode)) | 1512 | if (IS_NOQUOTA(inode)) |
@@ -1498,8 +1519,9 @@ void dquot_drop(struct inode *inode) | |||
1498 | * must assure that nobody can come after the DQUOT_DROP and | 1519 | * must assure that nobody can come after the DQUOT_DROP and |
1499 | * add quota pointers back anyway. | 1520 | * add quota pointers back anyway. |
1500 | */ | 1521 | */ |
1522 | dquots = i_dquot(inode); | ||
1501 | for (cnt = 0; cnt < MAXQUOTAS; cnt++) { | 1523 | for (cnt = 0; cnt < MAXQUOTAS; cnt++) { |
1502 | if (i_dquot(inode)[cnt]) | 1524 | if (dquots[cnt]) |
1503 | break; | 1525 | break; |
1504 | } | 1526 | } |
1505 | 1527 | ||
@@ -1600,8 +1622,8 @@ int __dquot_alloc_space(struct inode *inode, qsize_t number, int flags) | |||
1600 | { | 1622 | { |
1601 | int cnt, ret = 0, index; | 1623 | int cnt, ret = 0, index; |
1602 | struct dquot_warn warn[MAXQUOTAS]; | 1624 | struct dquot_warn warn[MAXQUOTAS]; |
1603 | struct dquot **dquots = i_dquot(inode); | ||
1604 | int reserve = flags & DQUOT_SPACE_RESERVE; | 1625 | int reserve = flags & DQUOT_SPACE_RESERVE; |
1626 | struct dquot **dquots; | ||
1605 | 1627 | ||
1606 | if (!dquot_active(inode)) { | 1628 | if (!dquot_active(inode)) { |
1607 | inode_incr_space(inode, number, reserve); | 1629 | inode_incr_space(inode, number, reserve); |
@@ -1611,6 +1633,7 @@ int __dquot_alloc_space(struct inode *inode, qsize_t number, int flags) | |||
1611 | for (cnt = 0; cnt < MAXQUOTAS; cnt++) | 1633 | for (cnt = 0; cnt < MAXQUOTAS; cnt++) |
1612 | warn[cnt].w_type = QUOTA_NL_NOWARN; | 1634 | warn[cnt].w_type = QUOTA_NL_NOWARN; |
1613 | 1635 | ||
1636 | dquots = i_dquot(inode); | ||
1614 | index = srcu_read_lock(&dquot_srcu); | 1637 | index = srcu_read_lock(&dquot_srcu); |
1615 | spin_lock(&dq_data_lock); | 1638 | spin_lock(&dq_data_lock); |
1616 | for (cnt = 0; cnt < MAXQUOTAS; cnt++) { | 1639 | for (cnt = 0; cnt < MAXQUOTAS; cnt++) { |
@@ -1652,13 +1675,14 @@ int dquot_alloc_inode(struct inode *inode) | |||
1652 | { | 1675 | { |
1653 | int cnt, ret = 0, index; | 1676 | int cnt, ret = 0, index; |
1654 | struct dquot_warn warn[MAXQUOTAS]; | 1677 | struct dquot_warn warn[MAXQUOTAS]; |
1655 | struct dquot * const *dquots = i_dquot(inode); | 1678 | struct dquot * const *dquots; |
1656 | 1679 | ||
1657 | if (!dquot_active(inode)) | 1680 | if (!dquot_active(inode)) |
1658 | return 0; | 1681 | return 0; |
1659 | for (cnt = 0; cnt < MAXQUOTAS; cnt++) | 1682 | for (cnt = 0; cnt < MAXQUOTAS; cnt++) |
1660 | warn[cnt].w_type = QUOTA_NL_NOWARN; | 1683 | warn[cnt].w_type = QUOTA_NL_NOWARN; |
1661 | 1684 | ||
1685 | dquots = i_dquot(inode); | ||
1662 | index = srcu_read_lock(&dquot_srcu); | 1686 | index = srcu_read_lock(&dquot_srcu); |
1663 | spin_lock(&dq_data_lock); | 1687 | spin_lock(&dq_data_lock); |
1664 | for (cnt = 0; cnt < MAXQUOTAS; cnt++) { | 1688 | for (cnt = 0; cnt < MAXQUOTAS; cnt++) { |
@@ -1690,6 +1714,7 @@ EXPORT_SYMBOL(dquot_alloc_inode); | |||
1690 | */ | 1714 | */ |
1691 | int dquot_claim_space_nodirty(struct inode *inode, qsize_t number) | 1715 | int dquot_claim_space_nodirty(struct inode *inode, qsize_t number) |
1692 | { | 1716 | { |
1717 | struct dquot **dquots; | ||
1693 | int cnt, index; | 1718 | int cnt, index; |
1694 | 1719 | ||
1695 | if (!dquot_active(inode)) { | 1720 | if (!dquot_active(inode)) { |
@@ -1697,18 +1722,18 @@ int dquot_claim_space_nodirty(struct inode *inode, qsize_t number) | |||
1697 | return 0; | 1722 | return 0; |
1698 | } | 1723 | } |
1699 | 1724 | ||
1725 | dquots = i_dquot(inode); | ||
1700 | index = srcu_read_lock(&dquot_srcu); | 1726 | index = srcu_read_lock(&dquot_srcu); |
1701 | spin_lock(&dq_data_lock); | 1727 | spin_lock(&dq_data_lock); |
1702 | /* Claim reserved quotas to allocated quotas */ | 1728 | /* Claim reserved quotas to allocated quotas */ |
1703 | for (cnt = 0; cnt < MAXQUOTAS; cnt++) { | 1729 | for (cnt = 0; cnt < MAXQUOTAS; cnt++) { |
1704 | if (i_dquot(inode)[cnt]) | 1730 | if (dquots[cnt]) |
1705 | dquot_claim_reserved_space(i_dquot(inode)[cnt], | 1731 | dquot_claim_reserved_space(dquots[cnt], number); |
1706 | number); | ||
1707 | } | 1732 | } |
1708 | /* Update inode bytes */ | 1733 | /* Update inode bytes */ |
1709 | inode_claim_rsv_space(inode, number); | 1734 | inode_claim_rsv_space(inode, number); |
1710 | spin_unlock(&dq_data_lock); | 1735 | spin_unlock(&dq_data_lock); |
1711 | mark_all_dquot_dirty(i_dquot(inode)); | 1736 | mark_all_dquot_dirty(dquots); |
1712 | srcu_read_unlock(&dquot_srcu, index); | 1737 | srcu_read_unlock(&dquot_srcu, index); |
1713 | return 0; | 1738 | return 0; |
1714 | } | 1739 | } |
@@ -1719,6 +1744,7 @@ EXPORT_SYMBOL(dquot_claim_space_nodirty); | |||
1719 | */ | 1744 | */ |
1720 | void dquot_reclaim_space_nodirty(struct inode *inode, qsize_t number) | 1745 | void dquot_reclaim_space_nodirty(struct inode *inode, qsize_t number) |
1721 | { | 1746 | { |
1747 | struct dquot **dquots; | ||
1722 | int cnt, index; | 1748 | int cnt, index; |
1723 | 1749 | ||
1724 | if (!dquot_active(inode)) { | 1750 | if (!dquot_active(inode)) { |
@@ -1726,18 +1752,18 @@ void dquot_reclaim_space_nodirty(struct inode *inode, qsize_t number) | |||
1726 | return; | 1752 | return; |
1727 | } | 1753 | } |
1728 | 1754 | ||
1755 | dquots = i_dquot(inode); | ||
1729 | index = srcu_read_lock(&dquot_srcu); | 1756 | index = srcu_read_lock(&dquot_srcu); |
1730 | spin_lock(&dq_data_lock); | 1757 | spin_lock(&dq_data_lock); |
1731 | /* Claim reserved quotas to allocated quotas */ | 1758 | /* Claim reserved quotas to allocated quotas */ |
1732 | for (cnt = 0; cnt < MAXQUOTAS; cnt++) { | 1759 | for (cnt = 0; cnt < MAXQUOTAS; cnt++) { |
1733 | if (i_dquot(inode)[cnt]) | 1760 | if (dquots[cnt]) |
1734 | dquot_reclaim_reserved_space(i_dquot(inode)[cnt], | 1761 | dquot_reclaim_reserved_space(dquots[cnt], number); |
1735 | number); | ||
1736 | } | 1762 | } |
1737 | /* Update inode bytes */ | 1763 | /* Update inode bytes */ |
1738 | inode_reclaim_rsv_space(inode, number); | 1764 | inode_reclaim_rsv_space(inode, number); |
1739 | spin_unlock(&dq_data_lock); | 1765 | spin_unlock(&dq_data_lock); |
1740 | mark_all_dquot_dirty(i_dquot(inode)); | 1766 | mark_all_dquot_dirty(dquots); |
1741 | srcu_read_unlock(&dquot_srcu, index); | 1767 | srcu_read_unlock(&dquot_srcu, index); |
1742 | return; | 1768 | return; |
1743 | } | 1769 | } |
@@ -1750,7 +1776,7 @@ void __dquot_free_space(struct inode *inode, qsize_t number, int flags) | |||
1750 | { | 1776 | { |
1751 | unsigned int cnt; | 1777 | unsigned int cnt; |
1752 | struct dquot_warn warn[MAXQUOTAS]; | 1778 | struct dquot_warn warn[MAXQUOTAS]; |
1753 | struct dquot **dquots = i_dquot(inode); | 1779 | struct dquot **dquots; |
1754 | int reserve = flags & DQUOT_SPACE_RESERVE, index; | 1780 | int reserve = flags & DQUOT_SPACE_RESERVE, index; |
1755 | 1781 | ||
1756 | if (!dquot_active(inode)) { | 1782 | if (!dquot_active(inode)) { |
@@ -1758,6 +1784,7 @@ void __dquot_free_space(struct inode *inode, qsize_t number, int flags) | |||
1758 | return; | 1784 | return; |
1759 | } | 1785 | } |
1760 | 1786 | ||
1787 | dquots = i_dquot(inode); | ||
1761 | index = srcu_read_lock(&dquot_srcu); | 1788 | index = srcu_read_lock(&dquot_srcu); |
1762 | spin_lock(&dq_data_lock); | 1789 | spin_lock(&dq_data_lock); |
1763 | for (cnt = 0; cnt < MAXQUOTAS; cnt++) { | 1790 | for (cnt = 0; cnt < MAXQUOTAS; cnt++) { |
@@ -1793,12 +1820,13 @@ void dquot_free_inode(struct inode *inode) | |||
1793 | { | 1820 | { |
1794 | unsigned int cnt; | 1821 | unsigned int cnt; |
1795 | struct dquot_warn warn[MAXQUOTAS]; | 1822 | struct dquot_warn warn[MAXQUOTAS]; |
1796 | struct dquot * const *dquots = i_dquot(inode); | 1823 | struct dquot * const *dquots; |
1797 | int index; | 1824 | int index; |
1798 | 1825 | ||
1799 | if (!dquot_active(inode)) | 1826 | if (!dquot_active(inode)) |
1800 | return; | 1827 | return; |
1801 | 1828 | ||
1829 | dquots = i_dquot(inode); | ||
1802 | index = srcu_read_lock(&dquot_srcu); | 1830 | index = srcu_read_lock(&dquot_srcu); |
1803 | spin_lock(&dq_data_lock); | 1831 | spin_lock(&dq_data_lock); |
1804 | for (cnt = 0; cnt < MAXQUOTAS; cnt++) { | 1832 | for (cnt = 0; cnt < MAXQUOTAS; cnt++) { |
@@ -2161,7 +2189,8 @@ static int vfs_load_quota_inode(struct inode *inode, int type, int format_id, | |||
2161 | error = -EROFS; | 2189 | error = -EROFS; |
2162 | goto out_fmt; | 2190 | goto out_fmt; |
2163 | } | 2191 | } |
2164 | if (!sb->s_op->quota_write || !sb->s_op->quota_read) { | 2192 | if (!sb->s_op->quota_write || !sb->s_op->quota_read || |
2193 | (type == PRJQUOTA && sb->dq_op->get_projid == NULL)) { | ||
2165 | error = -EINVAL; | 2194 | error = -EINVAL; |
2166 | goto out_fmt; | 2195 | goto out_fmt; |
2167 | } | 2196 | } |
@@ -2614,55 +2643,73 @@ out: | |||
2614 | EXPORT_SYMBOL(dquot_set_dqblk); | 2643 | EXPORT_SYMBOL(dquot_set_dqblk); |
2615 | 2644 | ||
2616 | /* Generic routine for getting common part of quota file information */ | 2645 | /* Generic routine for getting common part of quota file information */ |
2617 | int dquot_get_dqinfo(struct super_block *sb, int type, struct if_dqinfo *ii) | 2646 | int dquot_get_state(struct super_block *sb, struct qc_state *state) |
2618 | { | 2647 | { |
2619 | struct mem_dqinfo *mi; | 2648 | struct mem_dqinfo *mi; |
2649 | struct qc_type_state *tstate; | ||
2650 | struct quota_info *dqopt = sb_dqopt(sb); | ||
2651 | int type; | ||
2620 | 2652 | ||
2621 | mutex_lock(&sb_dqopt(sb)->dqonoff_mutex); | 2653 | mutex_lock(&sb_dqopt(sb)->dqonoff_mutex); |
2622 | if (!sb_has_quota_active(sb, type)) { | 2654 | memset(state, 0, sizeof(*state)); |
2623 | mutex_unlock(&sb_dqopt(sb)->dqonoff_mutex); | 2655 | for (type = 0; type < MAXQUOTAS; type++) { |
2624 | return -ESRCH; | 2656 | if (!sb_has_quota_active(sb, type)) |
2657 | continue; | ||
2658 | tstate = state->s_state + type; | ||
2659 | mi = sb_dqopt(sb)->info + type; | ||
2660 | tstate->flags = QCI_ACCT_ENABLED; | ||
2661 | spin_lock(&dq_data_lock); | ||
2662 | if (mi->dqi_flags & DQF_SYS_FILE) | ||
2663 | tstate->flags |= QCI_SYSFILE; | ||
2664 | if (mi->dqi_flags & DQF_ROOT_SQUASH) | ||
2665 | tstate->flags |= QCI_ROOT_SQUASH; | ||
2666 | if (sb_has_quota_limits_enabled(sb, type)) | ||
2667 | tstate->flags |= QCI_LIMITS_ENFORCED; | ||
2668 | tstate->spc_timelimit = mi->dqi_bgrace; | ||
2669 | tstate->ino_timelimit = mi->dqi_igrace; | ||
2670 | tstate->ino = dqopt->files[type]->i_ino; | ||
2671 | tstate->blocks = dqopt->files[type]->i_blocks; | ||
2672 | tstate->nextents = 1; /* We don't know... */ | ||
2673 | spin_unlock(&dq_data_lock); | ||
2625 | } | 2674 | } |
2626 | mi = sb_dqopt(sb)->info + type; | ||
2627 | spin_lock(&dq_data_lock); | ||
2628 | ii->dqi_bgrace = mi->dqi_bgrace; | ||
2629 | ii->dqi_igrace = mi->dqi_igrace; | ||
2630 | ii->dqi_flags = mi->dqi_flags & DQF_GETINFO_MASK; | ||
2631 | ii->dqi_valid = IIF_ALL; | ||
2632 | spin_unlock(&dq_data_lock); | ||
2633 | mutex_unlock(&sb_dqopt(sb)->dqonoff_mutex); | 2675 | mutex_unlock(&sb_dqopt(sb)->dqonoff_mutex); |
2634 | return 0; | 2676 | return 0; |
2635 | } | 2677 | } |
2636 | EXPORT_SYMBOL(dquot_get_dqinfo); | 2678 | EXPORT_SYMBOL(dquot_get_state); |
2637 | 2679 | ||
2638 | /* Generic routine for setting common part of quota file information */ | 2680 | /* Generic routine for setting common part of quota file information */ |
2639 | int dquot_set_dqinfo(struct super_block *sb, int type, struct if_dqinfo *ii) | 2681 | int dquot_set_dqinfo(struct super_block *sb, int type, struct qc_info *ii) |
2640 | { | 2682 | { |
2641 | struct mem_dqinfo *mi; | 2683 | struct mem_dqinfo *mi; |
2642 | int err = 0; | 2684 | int err = 0; |
2643 | 2685 | ||
2686 | if ((ii->i_fieldmask & QC_WARNS_MASK) || | ||
2687 | (ii->i_fieldmask & QC_RT_SPC_TIMER)) | ||
2688 | return -EINVAL; | ||
2644 | mutex_lock(&sb_dqopt(sb)->dqonoff_mutex); | 2689 | mutex_lock(&sb_dqopt(sb)->dqonoff_mutex); |
2645 | if (!sb_has_quota_active(sb, type)) { | 2690 | if (!sb_has_quota_active(sb, type)) { |
2646 | err = -ESRCH; | 2691 | err = -ESRCH; |
2647 | goto out; | 2692 | goto out; |
2648 | } | 2693 | } |
2649 | mi = sb_dqopt(sb)->info + type; | 2694 | mi = sb_dqopt(sb)->info + type; |
2650 | if (ii->dqi_valid & IIF_FLAGS) { | 2695 | if (ii->i_fieldmask & QC_FLAGS) { |
2651 | if (ii->dqi_flags & ~DQF_SETINFO_MASK || | 2696 | if ((ii->i_flags & QCI_ROOT_SQUASH && |
2652 | (ii->dqi_flags & DQF_ROOT_SQUASH && | ||
2653 | mi->dqi_format->qf_fmt_id != QFMT_VFS_OLD)) { | 2697 | mi->dqi_format->qf_fmt_id != QFMT_VFS_OLD)) { |
2654 | err = -EINVAL; | 2698 | err = -EINVAL; |
2655 | goto out; | 2699 | goto out; |
2656 | } | 2700 | } |
2657 | } | 2701 | } |
2658 | spin_lock(&dq_data_lock); | 2702 | spin_lock(&dq_data_lock); |
2659 | if (ii->dqi_valid & IIF_BGRACE) | 2703 | if (ii->i_fieldmask & QC_SPC_TIMER) |
2660 | mi->dqi_bgrace = ii->dqi_bgrace; | 2704 | mi->dqi_bgrace = ii->i_spc_timelimit; |
2661 | if (ii->dqi_valid & IIF_IGRACE) | 2705 | if (ii->i_fieldmask & QC_INO_TIMER) |
2662 | mi->dqi_igrace = ii->dqi_igrace; | 2706 | mi->dqi_igrace = ii->i_ino_timelimit; |
2663 | if (ii->dqi_valid & IIF_FLAGS) | 2707 | if (ii->i_fieldmask & QC_FLAGS) { |
2664 | mi->dqi_flags = (mi->dqi_flags & ~DQF_SETINFO_MASK) | | 2708 | if (ii->i_flags & QCI_ROOT_SQUASH) |
2665 | (ii->dqi_flags & DQF_SETINFO_MASK); | 2709 | mi->dqi_flags |= DQF_ROOT_SQUASH; |
2710 | else | ||
2711 | mi->dqi_flags &= ~DQF_ROOT_SQUASH; | ||
2712 | } | ||
2666 | spin_unlock(&dq_data_lock); | 2713 | spin_unlock(&dq_data_lock); |
2667 | mark_info_dirty(sb, type); | 2714 | mark_info_dirty(sb, type); |
2668 | /* Force write to disk */ | 2715 | /* Force write to disk */ |
@@ -2677,7 +2724,7 @@ const struct quotactl_ops dquot_quotactl_ops = { | |||
2677 | .quota_on = dquot_quota_on, | 2724 | .quota_on = dquot_quota_on, |
2678 | .quota_off = dquot_quota_off, | 2725 | .quota_off = dquot_quota_off, |
2679 | .quota_sync = dquot_quota_sync, | 2726 | .quota_sync = dquot_quota_sync, |
2680 | .get_info = dquot_get_dqinfo, | 2727 | .get_state = dquot_get_state, |
2681 | .set_info = dquot_set_dqinfo, | 2728 | .set_info = dquot_set_dqinfo, |
2682 | .get_dqblk = dquot_get_dqblk, | 2729 | .get_dqblk = dquot_get_dqblk, |
2683 | .set_dqblk = dquot_set_dqblk | 2730 | .set_dqblk = dquot_set_dqblk |
@@ -2688,7 +2735,7 @@ const struct quotactl_ops dquot_quotactl_sysfile_ops = { | |||
2688 | .quota_enable = dquot_quota_enable, | 2735 | .quota_enable = dquot_quota_enable, |
2689 | .quota_disable = dquot_quota_disable, | 2736 | .quota_disable = dquot_quota_disable, |
2690 | .quota_sync = dquot_quota_sync, | 2737 | .quota_sync = dquot_quota_sync, |
2691 | .get_info = dquot_get_dqinfo, | 2738 | .get_state = dquot_get_state, |
2692 | .set_info = dquot_set_dqinfo, | 2739 | .set_info = dquot_set_dqinfo, |
2693 | .get_dqblk = dquot_get_dqblk, | 2740 | .get_dqblk = dquot_get_dqblk, |
2694 | .set_dqblk = dquot_set_dqblk | 2741 | .set_dqblk = dquot_set_dqblk |
diff --git a/fs/quota/quota.c b/fs/quota/quota.c index d14a799c7785..86ded7375c21 100644 --- a/fs/quota/quota.c +++ b/fs/quota/quota.c | |||
@@ -118,13 +118,30 @@ static int quota_getfmt(struct super_block *sb, int type, void __user *addr) | |||
118 | 118 | ||
119 | static int quota_getinfo(struct super_block *sb, int type, void __user *addr) | 119 | static int quota_getinfo(struct super_block *sb, int type, void __user *addr) |
120 | { | 120 | { |
121 | struct if_dqinfo info; | 121 | struct qc_state state; |
122 | struct qc_type_state *tstate; | ||
123 | struct if_dqinfo uinfo; | ||
122 | int ret; | 124 | int ret; |
123 | 125 | ||
124 | if (!sb->s_qcop->get_info) | 126 | /* This checks whether qc_state has enough entries... */ |
127 | BUILD_BUG_ON(MAXQUOTAS > XQM_MAXQUOTAS); | ||
128 | if (!sb->s_qcop->get_state) | ||
125 | return -ENOSYS; | 129 | return -ENOSYS; |
126 | ret = sb->s_qcop->get_info(sb, type, &info); | 130 | ret = sb->s_qcop->get_state(sb, &state); |
127 | if (!ret && copy_to_user(addr, &info, sizeof(info))) | 131 | if (ret) |
132 | return ret; | ||
133 | tstate = state.s_state + type; | ||
134 | if (!(tstate->flags & QCI_ACCT_ENABLED)) | ||
135 | return -ESRCH; | ||
136 | memset(&uinfo, 0, sizeof(uinfo)); | ||
137 | uinfo.dqi_bgrace = tstate->spc_timelimit; | ||
138 | uinfo.dqi_igrace = tstate->ino_timelimit; | ||
139 | if (tstate->flags & QCI_SYSFILE) | ||
140 | uinfo.dqi_flags |= DQF_SYS_FILE; | ||
141 | if (tstate->flags & QCI_ROOT_SQUASH) | ||
142 | uinfo.dqi_flags |= DQF_ROOT_SQUASH; | ||
143 | uinfo.dqi_valid = IIF_ALL; | ||
144 | if (!ret && copy_to_user(addr, &uinfo, sizeof(uinfo))) | ||
128 | return -EFAULT; | 145 | return -EFAULT; |
129 | return ret; | 146 | return ret; |
130 | } | 147 | } |
@@ -132,12 +149,31 @@ static int quota_getinfo(struct super_block *sb, int type, void __user *addr) | |||
132 | static int quota_setinfo(struct super_block *sb, int type, void __user *addr) | 149 | static int quota_setinfo(struct super_block *sb, int type, void __user *addr) |
133 | { | 150 | { |
134 | struct if_dqinfo info; | 151 | struct if_dqinfo info; |
152 | struct qc_info qinfo; | ||
135 | 153 | ||
136 | if (copy_from_user(&info, addr, sizeof(info))) | 154 | if (copy_from_user(&info, addr, sizeof(info))) |
137 | return -EFAULT; | 155 | return -EFAULT; |
138 | if (!sb->s_qcop->set_info) | 156 | if (!sb->s_qcop->set_info) |
139 | return -ENOSYS; | 157 | return -ENOSYS; |
140 | return sb->s_qcop->set_info(sb, type, &info); | 158 | if (info.dqi_valid & ~(IIF_FLAGS | IIF_BGRACE | IIF_IGRACE)) |
159 | return -EINVAL; | ||
160 | memset(&qinfo, 0, sizeof(qinfo)); | ||
161 | if (info.dqi_valid & IIF_FLAGS) { | ||
162 | if (info.dqi_flags & ~DQF_SETINFO_MASK) | ||
163 | return -EINVAL; | ||
164 | if (info.dqi_flags & DQF_ROOT_SQUASH) | ||
165 | qinfo.i_flags |= QCI_ROOT_SQUASH; | ||
166 | qinfo.i_fieldmask |= QC_FLAGS; | ||
167 | } | ||
168 | if (info.dqi_valid & IIF_BGRACE) { | ||
169 | qinfo.i_spc_timelimit = info.dqi_bgrace; | ||
170 | qinfo.i_fieldmask |= QC_SPC_TIMER; | ||
171 | } | ||
172 | if (info.dqi_valid & IIF_IGRACE) { | ||
173 | qinfo.i_ino_timelimit = info.dqi_igrace; | ||
174 | qinfo.i_fieldmask |= QC_INO_TIMER; | ||
175 | } | ||
176 | return sb->s_qcop->set_info(sb, type, &qinfo); | ||
141 | } | 177 | } |
142 | 178 | ||
143 | static inline qsize_t qbtos(qsize_t blocks) | 179 | static inline qsize_t qbtos(qsize_t blocks) |
@@ -252,25 +288,149 @@ static int quota_disable(struct super_block *sb, void __user *addr) | |||
252 | return sb->s_qcop->quota_disable(sb, flags); | 288 | return sb->s_qcop->quota_disable(sb, flags); |
253 | } | 289 | } |
254 | 290 | ||
291 | static int quota_state_to_flags(struct qc_state *state) | ||
292 | { | ||
293 | int flags = 0; | ||
294 | |||
295 | if (state->s_state[USRQUOTA].flags & QCI_ACCT_ENABLED) | ||
296 | flags |= FS_QUOTA_UDQ_ACCT; | ||
297 | if (state->s_state[USRQUOTA].flags & QCI_LIMITS_ENFORCED) | ||
298 | flags |= FS_QUOTA_UDQ_ENFD; | ||
299 | if (state->s_state[GRPQUOTA].flags & QCI_ACCT_ENABLED) | ||
300 | flags |= FS_QUOTA_GDQ_ACCT; | ||
301 | if (state->s_state[GRPQUOTA].flags & QCI_LIMITS_ENFORCED) | ||
302 | flags |= FS_QUOTA_GDQ_ENFD; | ||
303 | if (state->s_state[PRJQUOTA].flags & QCI_ACCT_ENABLED) | ||
304 | flags |= FS_QUOTA_PDQ_ACCT; | ||
305 | if (state->s_state[PRJQUOTA].flags & QCI_LIMITS_ENFORCED) | ||
306 | flags |= FS_QUOTA_PDQ_ENFD; | ||
307 | return flags; | ||
308 | } | ||
309 | |||
310 | static int quota_getstate(struct super_block *sb, struct fs_quota_stat *fqs) | ||
311 | { | ||
312 | int type; | ||
313 | struct qc_state state; | ||
314 | int ret; | ||
315 | |||
316 | ret = sb->s_qcop->get_state(sb, &state); | ||
317 | if (ret < 0) | ||
318 | return ret; | ||
319 | |||
320 | memset(fqs, 0, sizeof(*fqs)); | ||
321 | fqs->qs_version = FS_QSTAT_VERSION; | ||
322 | fqs->qs_flags = quota_state_to_flags(&state); | ||
323 | /* No quota enabled? */ | ||
324 | if (!fqs->qs_flags) | ||
325 | return -ENOSYS; | ||
326 | fqs->qs_incoredqs = state.s_incoredqs; | ||
327 | /* | ||
328 | * GETXSTATE quotactl has space for just one set of time limits so | ||
329 | * report them for the first enabled quota type | ||
330 | */ | ||
331 | for (type = 0; type < XQM_MAXQUOTAS; type++) | ||
332 | if (state.s_state[type].flags & QCI_ACCT_ENABLED) | ||
333 | break; | ||
334 | BUG_ON(type == XQM_MAXQUOTAS); | ||
335 | fqs->qs_btimelimit = state.s_state[type].spc_timelimit; | ||
336 | fqs->qs_itimelimit = state.s_state[type].ino_timelimit; | ||
337 | fqs->qs_rtbtimelimit = state.s_state[type].rt_spc_timelimit; | ||
338 | fqs->qs_bwarnlimit = state.s_state[type].spc_warnlimit; | ||
339 | fqs->qs_iwarnlimit = state.s_state[type].ino_warnlimit; | ||
340 | if (state.s_state[USRQUOTA].flags & QCI_ACCT_ENABLED) { | ||
341 | fqs->qs_uquota.qfs_ino = state.s_state[USRQUOTA].ino; | ||
342 | fqs->qs_uquota.qfs_nblks = state.s_state[USRQUOTA].blocks; | ||
343 | fqs->qs_uquota.qfs_nextents = state.s_state[USRQUOTA].nextents; | ||
344 | } | ||
345 | if (state.s_state[GRPQUOTA].flags & QCI_ACCT_ENABLED) { | ||
346 | fqs->qs_gquota.qfs_ino = state.s_state[GRPQUOTA].ino; | ||
347 | fqs->qs_gquota.qfs_nblks = state.s_state[GRPQUOTA].blocks; | ||
348 | fqs->qs_gquota.qfs_nextents = state.s_state[GRPQUOTA].nextents; | ||
349 | } | ||
350 | if (state.s_state[PRJQUOTA].flags & QCI_ACCT_ENABLED) { | ||
351 | /* | ||
352 | * Q_XGETQSTAT doesn't have room for both group and project | ||
353 | * quotas. So, allow the project quota values to be copied out | ||
354 | * only if there is no group quota information available. | ||
355 | */ | ||
356 | if (!(state.s_state[GRPQUOTA].flags & QCI_ACCT_ENABLED)) { | ||
357 | fqs->qs_gquota.qfs_ino = state.s_state[PRJQUOTA].ino; | ||
358 | fqs->qs_gquota.qfs_nblks = | ||
359 | state.s_state[PRJQUOTA].blocks; | ||
360 | fqs->qs_gquota.qfs_nextents = | ||
361 | state.s_state[PRJQUOTA].nextents; | ||
362 | } | ||
363 | } | ||
364 | return 0; | ||
365 | } | ||
366 | |||
255 | static int quota_getxstate(struct super_block *sb, void __user *addr) | 367 | static int quota_getxstate(struct super_block *sb, void __user *addr) |
256 | { | 368 | { |
257 | struct fs_quota_stat fqs; | 369 | struct fs_quota_stat fqs; |
258 | int ret; | 370 | int ret; |
259 | 371 | ||
260 | if (!sb->s_qcop->get_xstate) | 372 | if (!sb->s_qcop->get_state) |
261 | return -ENOSYS; | 373 | return -ENOSYS; |
262 | ret = sb->s_qcop->get_xstate(sb, &fqs); | 374 | ret = quota_getstate(sb, &fqs); |
263 | if (!ret && copy_to_user(addr, &fqs, sizeof(fqs))) | 375 | if (!ret && copy_to_user(addr, &fqs, sizeof(fqs))) |
264 | return -EFAULT; | 376 | return -EFAULT; |
265 | return ret; | 377 | return ret; |
266 | } | 378 | } |
267 | 379 | ||
380 | static int quota_getstatev(struct super_block *sb, struct fs_quota_statv *fqs) | ||
381 | { | ||
382 | int type; | ||
383 | struct qc_state state; | ||
384 | int ret; | ||
385 | |||
386 | ret = sb->s_qcop->get_state(sb, &state); | ||
387 | if (ret < 0) | ||
388 | return ret; | ||
389 | |||
390 | memset(fqs, 0, sizeof(*fqs)); | ||
391 | fqs->qs_version = FS_QSTAT_VERSION; | ||
392 | fqs->qs_flags = quota_state_to_flags(&state); | ||
393 | /* No quota enabled? */ | ||
394 | if (!fqs->qs_flags) | ||
395 | return -ENOSYS; | ||
396 | fqs->qs_incoredqs = state.s_incoredqs; | ||
397 | /* | ||
398 | * GETXSTATV quotactl has space for just one set of time limits so | ||
399 | * report them for the first enabled quota type | ||
400 | */ | ||
401 | for (type = 0; type < XQM_MAXQUOTAS; type++) | ||
402 | if (state.s_state[type].flags & QCI_ACCT_ENABLED) | ||
403 | break; | ||
404 | BUG_ON(type == XQM_MAXQUOTAS); | ||
405 | fqs->qs_btimelimit = state.s_state[type].spc_timelimit; | ||
406 | fqs->qs_itimelimit = state.s_state[type].ino_timelimit; | ||
407 | fqs->qs_rtbtimelimit = state.s_state[type].rt_spc_timelimit; | ||
408 | fqs->qs_bwarnlimit = state.s_state[type].spc_warnlimit; | ||
409 | fqs->qs_iwarnlimit = state.s_state[type].ino_warnlimit; | ||
410 | if (state.s_state[USRQUOTA].flags & QCI_ACCT_ENABLED) { | ||
411 | fqs->qs_uquota.qfs_ino = state.s_state[USRQUOTA].ino; | ||
412 | fqs->qs_uquota.qfs_nblks = state.s_state[USRQUOTA].blocks; | ||
413 | fqs->qs_uquota.qfs_nextents = state.s_state[USRQUOTA].nextents; | ||
414 | } | ||
415 | if (state.s_state[GRPQUOTA].flags & QCI_ACCT_ENABLED) { | ||
416 | fqs->qs_gquota.qfs_ino = state.s_state[GRPQUOTA].ino; | ||
417 | fqs->qs_gquota.qfs_nblks = state.s_state[GRPQUOTA].blocks; | ||
418 | fqs->qs_gquota.qfs_nextents = state.s_state[GRPQUOTA].nextents; | ||
419 | } | ||
420 | if (state.s_state[PRJQUOTA].flags & QCI_ACCT_ENABLED) { | ||
421 | fqs->qs_pquota.qfs_ino = state.s_state[PRJQUOTA].ino; | ||
422 | fqs->qs_pquota.qfs_nblks = state.s_state[PRJQUOTA].blocks; | ||
423 | fqs->qs_pquota.qfs_nextents = state.s_state[PRJQUOTA].nextents; | ||
424 | } | ||
425 | return 0; | ||
426 | } | ||
427 | |||
268 | static int quota_getxstatev(struct super_block *sb, void __user *addr) | 428 | static int quota_getxstatev(struct super_block *sb, void __user *addr) |
269 | { | 429 | { |
270 | struct fs_quota_statv fqs; | 430 | struct fs_quota_statv fqs; |
271 | int ret; | 431 | int ret; |
272 | 432 | ||
273 | if (!sb->s_qcop->get_xstatev) | 433 | if (!sb->s_qcop->get_state) |
274 | return -ENOSYS; | 434 | return -ENOSYS; |
275 | 435 | ||
276 | memset(&fqs, 0, sizeof(fqs)); | 436 | memset(&fqs, 0, sizeof(fqs)); |
@@ -284,7 +444,7 @@ static int quota_getxstatev(struct super_block *sb, void __user *addr) | |||
284 | default: | 444 | default: |
285 | return -EINVAL; | 445 | return -EINVAL; |
286 | } | 446 | } |
287 | ret = sb->s_qcop->get_xstatev(sb, &fqs); | 447 | ret = quota_getstatev(sb, &fqs); |
288 | if (!ret && copy_to_user(addr, &fqs, sizeof(fqs))) | 448 | if (!ret && copy_to_user(addr, &fqs, sizeof(fqs))) |
289 | return -EFAULT; | 449 | return -EFAULT; |
290 | return ret; | 450 | return ret; |
@@ -357,6 +517,30 @@ static void copy_from_xfs_dqblk(struct qc_dqblk *dst, struct fs_disk_quota *src) | |||
357 | dst->d_fieldmask |= QC_RT_SPACE; | 517 | dst->d_fieldmask |= QC_RT_SPACE; |
358 | } | 518 | } |
359 | 519 | ||
520 | static void copy_qcinfo_from_xfs_dqblk(struct qc_info *dst, | ||
521 | struct fs_disk_quota *src) | ||
522 | { | ||
523 | memset(dst, 0, sizeof(*dst)); | ||
524 | dst->i_spc_timelimit = src->d_btimer; | ||
525 | dst->i_ino_timelimit = src->d_itimer; | ||
526 | dst->i_rt_spc_timelimit = src->d_rtbtimer; | ||
527 | dst->i_ino_warnlimit = src->d_iwarns; | ||
528 | dst->i_spc_warnlimit = src->d_bwarns; | ||
529 | dst->i_rt_spc_warnlimit = src->d_rtbwarns; | ||
530 | if (src->d_fieldmask & FS_DQ_BWARNS) | ||
531 | dst->i_fieldmask |= QC_SPC_WARNS; | ||
532 | if (src->d_fieldmask & FS_DQ_IWARNS) | ||
533 | dst->i_fieldmask |= QC_INO_WARNS; | ||
534 | if (src->d_fieldmask & FS_DQ_RTBWARNS) | ||
535 | dst->i_fieldmask |= QC_RT_SPC_WARNS; | ||
536 | if (src->d_fieldmask & FS_DQ_BTIMER) | ||
537 | dst->i_fieldmask |= QC_SPC_TIMER; | ||
538 | if (src->d_fieldmask & FS_DQ_ITIMER) | ||
539 | dst->i_fieldmask |= QC_INO_TIMER; | ||
540 | if (src->d_fieldmask & FS_DQ_RTBTIMER) | ||
541 | dst->i_fieldmask |= QC_RT_SPC_TIMER; | ||
542 | } | ||
543 | |||
360 | static int quota_setxquota(struct super_block *sb, int type, qid_t id, | 544 | static int quota_setxquota(struct super_block *sb, int type, qid_t id, |
361 | void __user *addr) | 545 | void __user *addr) |
362 | { | 546 | { |
@@ -371,6 +555,21 @@ static int quota_setxquota(struct super_block *sb, int type, qid_t id, | |||
371 | qid = make_kqid(current_user_ns(), type, id); | 555 | qid = make_kqid(current_user_ns(), type, id); |
372 | if (!qid_valid(qid)) | 556 | if (!qid_valid(qid)) |
373 | return -EINVAL; | 557 | return -EINVAL; |
558 | /* Are we actually setting timer / warning limits for all users? */ | ||
559 | if (from_kqid(&init_user_ns, qid) == 0 && | ||
560 | fdq.d_fieldmask & (FS_DQ_WARNS_MASK | FS_DQ_TIMER_MASK)) { | ||
561 | struct qc_info qinfo; | ||
562 | int ret; | ||
563 | |||
564 | if (!sb->s_qcop->set_info) | ||
565 | return -EINVAL; | ||
566 | copy_qcinfo_from_xfs_dqblk(&qinfo, &fdq); | ||
567 | ret = sb->s_qcop->set_info(sb, type, &qinfo); | ||
568 | if (ret) | ||
569 | return ret; | ||
570 | /* These are already done */ | ||
571 | fdq.d_fieldmask &= ~(FS_DQ_WARNS_MASK | FS_DQ_TIMER_MASK); | ||
572 | } | ||
374 | copy_from_xfs_dqblk(&qdq, &fdq); | 573 | copy_from_xfs_dqblk(&qdq, &fdq); |
375 | return sb->s_qcop->set_dqblk(sb, qid, &qdq); | 574 | return sb->s_qcop->set_dqblk(sb, qid, &qdq); |
376 | } | 575 | } |
diff --git a/fs/quota/quota_tree.c b/fs/quota/quota_tree.c index d65877fbe8f4..58efb83dec1c 100644 --- a/fs/quota/quota_tree.c +++ b/fs/quota/quota_tree.c | |||
@@ -349,6 +349,13 @@ static inline int dq_insert_tree(struct qtree_mem_dqinfo *info, | |||
349 | struct dquot *dquot) | 349 | struct dquot *dquot) |
350 | { | 350 | { |
351 | int tmp = QT_TREEOFF; | 351 | int tmp = QT_TREEOFF; |
352 | |||
353 | #ifdef __QUOTA_QT_PARANOIA | ||
354 | if (info->dqi_blocks <= QT_TREEOFF) { | ||
355 | quota_error(dquot->dq_sb, "Quota tree root isn't allocated!"); | ||
356 | return -EIO; | ||
357 | } | ||
358 | #endif | ||
352 | return do_insert_tree(info, dquot, &tmp, 0); | 359 | return do_insert_tree(info, dquot, &tmp, 0); |
353 | } | 360 | } |
354 | 361 | ||
diff --git a/fs/quota/quota_v2.c b/fs/quota/quota_v2.c index 9cb10d7197f7..2aa012a68e90 100644 --- a/fs/quota/quota_v2.c +++ b/fs/quota/quota_v2.c | |||
@@ -117,12 +117,16 @@ static int v2_read_file_info(struct super_block *sb, int type) | |||
117 | qinfo = info->dqi_priv; | 117 | qinfo = info->dqi_priv; |
118 | if (version == 0) { | 118 | if (version == 0) { |
119 | /* limits are stored as unsigned 32-bit data */ | 119 | /* limits are stored as unsigned 32-bit data */ |
120 | info->dqi_max_spc_limit = 0xffffffffULL << QUOTABLOCK_BITS; | 120 | info->dqi_max_spc_limit = 0xffffffffLL << QUOTABLOCK_BITS; |
121 | info->dqi_max_ino_limit = 0xffffffff; | 121 | info->dqi_max_ino_limit = 0xffffffff; |
122 | } else { | 122 | } else { |
123 | /* used space is stored as unsigned 64-bit value in bytes */ | 123 | /* |
124 | info->dqi_max_spc_limit = 0xffffffffffffffffULL; /* 2^64-1 */ | 124 | * Used space is stored as unsigned 64-bit value in bytes but |
125 | info->dqi_max_ino_limit = 0xffffffffffffffffULL; | 125 | * quota core supports only signed 64-bit values so use that |
126 | * as a limit | ||
127 | */ | ||
128 | info->dqi_max_spc_limit = 0x7fffffffffffffffLL; /* 2^63-1 */ | ||
129 | info->dqi_max_ino_limit = 0x7fffffffffffffffLL; | ||
126 | } | 130 | } |
127 | info->dqi_bgrace = le32_to_cpu(dinfo.dqi_bgrace); | 131 | info->dqi_bgrace = le32_to_cpu(dinfo.dqi_bgrace); |
128 | info->dqi_igrace = le32_to_cpu(dinfo.dqi_igrace); | 132 | info->dqi_igrace = le32_to_cpu(dinfo.dqi_igrace); |
diff --git a/fs/quota/quotaio_v2.h b/fs/quota/quotaio_v2.h index f1966b42c2fd..4e95430093d9 100644 --- a/fs/quota/quotaio_v2.h +++ b/fs/quota/quotaio_v2.h | |||
@@ -13,12 +13,14 @@ | |||
13 | */ | 13 | */ |
14 | #define V2_INITQMAGICS {\ | 14 | #define V2_INITQMAGICS {\ |
15 | 0xd9c01f11, /* USRQUOTA */\ | 15 | 0xd9c01f11, /* USRQUOTA */\ |
16 | 0xd9c01927 /* GRPQUOTA */\ | 16 | 0xd9c01927, /* GRPQUOTA */\ |
17 | 0xd9c03f14, /* PRJQUOTA */\ | ||
17 | } | 18 | } |
18 | 19 | ||
19 | #define V2_INITQVERSIONS {\ | 20 | #define V2_INITQVERSIONS {\ |
20 | 1, /* USRQUOTA */\ | 21 | 1, /* USRQUOTA */\ |
21 | 1 /* GRPQUOTA */\ | 22 | 1, /* GRPQUOTA */\ |
23 | 1, /* PRJQUOTA */\ | ||
22 | } | 24 | } |
23 | 25 | ||
24 | /* First generic header */ | 26 | /* First generic header */ |
diff --git a/fs/reiserfs/reiserfs.h b/fs/reiserfs/reiserfs.h index bb79cddf0a1f..2adcde137c3f 100644 --- a/fs/reiserfs/reiserfs.h +++ b/fs/reiserfs/reiserfs.h | |||
@@ -910,7 +910,6 @@ do { \ | |||
910 | if (!(cond)) \ | 910 | if (!(cond)) \ |
911 | reiserfs_panic(NULL, "assertion failure", "(" #cond ") at " \ | 911 | reiserfs_panic(NULL, "assertion failure", "(" #cond ") at " \ |
912 | __FILE__ ":%i:%s: " format "\n", \ | 912 | __FILE__ ":%i:%s: " format "\n", \ |
913 | in_interrupt() ? -1 : task_pid_nr(current), \ | ||
914 | __LINE__, __func__ , ##args); \ | 913 | __LINE__, __func__ , ##args); \ |
915 | } while (0) | 914 | } while (0) |
916 | 915 | ||
diff --git a/fs/reiserfs/super.c b/fs/reiserfs/super.c index 71fbbe3e2dab..68b5f182984e 100644 --- a/fs/reiserfs/super.c +++ b/fs/reiserfs/super.c | |||
@@ -805,7 +805,7 @@ static const struct quotactl_ops reiserfs_qctl_operations = { | |||
805 | .quota_on = reiserfs_quota_on, | 805 | .quota_on = reiserfs_quota_on, |
806 | .quota_off = dquot_quota_off, | 806 | .quota_off = dquot_quota_off, |
807 | .quota_sync = dquot_quota_sync, | 807 | .quota_sync = dquot_quota_sync, |
808 | .get_info = dquot_get_dqinfo, | 808 | .get_state = dquot_get_state, |
809 | .set_info = dquot_set_dqinfo, | 809 | .set_info = dquot_set_dqinfo, |
810 | .get_dqblk = dquot_get_dqblk, | 810 | .get_dqblk = dquot_get_dqblk, |
811 | .set_dqblk = dquot_set_dqblk, | 811 | .set_dqblk = dquot_set_dqblk, |
diff --git a/fs/udf/balloc.c b/fs/udf/balloc.c index 1ba2baaf4367..6d6a96b4e73f 100644 --- a/fs/udf/balloc.c +++ b/fs/udf/balloc.c | |||
@@ -21,7 +21,6 @@ | |||
21 | 21 | ||
22 | #include "udfdecl.h" | 22 | #include "udfdecl.h" |
23 | 23 | ||
24 | #include <linux/buffer_head.h> | ||
25 | #include <linux/bitops.h> | 24 | #include <linux/bitops.h> |
26 | 25 | ||
27 | #include "udf_i.h" | 26 | #include "udf_i.h" |
@@ -63,15 +62,14 @@ static int __load_block_bitmap(struct super_block *sb, | |||
63 | block_group, nr_groups); | 62 | block_group, nr_groups); |
64 | } | 63 | } |
65 | 64 | ||
66 | if (bitmap->s_block_bitmap[block_group]) { | 65 | if (bitmap->s_block_bitmap[block_group]) |
67 | return block_group; | 66 | return block_group; |
68 | } else { | 67 | |
69 | retval = read_block_bitmap(sb, bitmap, block_group, | 68 | retval = read_block_bitmap(sb, bitmap, block_group, block_group); |
70 | block_group); | 69 | if (retval < 0) |
71 | if (retval < 0) | 70 | return retval; |
72 | return retval; | 71 | |
73 | return block_group; | 72 | return block_group; |
74 | } | ||
75 | } | 73 | } |
76 | 74 | ||
77 | static inline int load_block_bitmap(struct super_block *sb, | 75 | static inline int load_block_bitmap(struct super_block *sb, |
@@ -358,7 +356,6 @@ static void udf_table_free_blocks(struct super_block *sb, | |||
358 | struct kernel_lb_addr eloc; | 356 | struct kernel_lb_addr eloc; |
359 | struct extent_position oepos, epos; | 357 | struct extent_position oepos, epos; |
360 | int8_t etype; | 358 | int8_t etype; |
361 | int i; | ||
362 | struct udf_inode_info *iinfo; | 359 | struct udf_inode_info *iinfo; |
363 | 360 | ||
364 | mutex_lock(&sbi->s_alloc_mutex); | 361 | mutex_lock(&sbi->s_alloc_mutex); |
@@ -425,7 +422,6 @@ static void udf_table_free_blocks(struct super_block *sb, | |||
425 | } | 422 | } |
426 | 423 | ||
427 | if (epos.bh != oepos.bh) { | 424 | if (epos.bh != oepos.bh) { |
428 | i = -1; | ||
429 | oepos.block = epos.block; | 425 | oepos.block = epos.block; |
430 | brelse(oepos.bh); | 426 | brelse(oepos.bh); |
431 | get_bh(epos.bh); | 427 | get_bh(epos.bh); |
@@ -762,7 +758,7 @@ inline int udf_prealloc_blocks(struct super_block *sb, | |||
762 | uint32_t block_count) | 758 | uint32_t block_count) |
763 | { | 759 | { |
764 | struct udf_part_map *map = &UDF_SB(sb)->s_partmaps[partition]; | 760 | struct udf_part_map *map = &UDF_SB(sb)->s_partmaps[partition]; |
765 | sector_t allocated; | 761 | int allocated; |
766 | 762 | ||
767 | if (map->s_partition_flags & UDF_PART_FLAG_UNALLOC_BITMAP) | 763 | if (map->s_partition_flags & UDF_PART_FLAG_UNALLOC_BITMAP) |
768 | allocated = udf_bitmap_prealloc_blocks(sb, | 764 | allocated = udf_bitmap_prealloc_blocks(sb, |
diff --git a/fs/udf/dir.c b/fs/udf/dir.c index 05e90edd1992..541a12b5792d 100644 --- a/fs/udf/dir.c +++ b/fs/udf/dir.c | |||
@@ -30,7 +30,6 @@ | |||
30 | #include <linux/errno.h> | 30 | #include <linux/errno.h> |
31 | #include <linux/mm.h> | 31 | #include <linux/mm.h> |
32 | #include <linux/slab.h> | 32 | #include <linux/slab.h> |
33 | #include <linux/buffer_head.h> | ||
34 | 33 | ||
35 | #include "udf_i.h" | 34 | #include "udf_i.h" |
36 | #include "udf_sb.h" | 35 | #include "udf_sb.h" |
diff --git a/fs/udf/directory.c b/fs/udf/directory.c index 3e44f575fb9c..c763fda257bf 100644 --- a/fs/udf/directory.c +++ b/fs/udf/directory.c | |||
@@ -16,7 +16,6 @@ | |||
16 | 16 | ||
17 | #include <linux/fs.h> | 17 | #include <linux/fs.h> |
18 | #include <linux/string.h> | 18 | #include <linux/string.h> |
19 | #include <linux/buffer_head.h> | ||
20 | 19 | ||
21 | struct fileIdentDesc *udf_fileident_read(struct inode *dir, loff_t *nf_pos, | 20 | struct fileIdentDesc *udf_fileident_read(struct inode *dir, loff_t *nf_pos, |
22 | struct udf_fileident_bh *fibh, | 21 | struct udf_fileident_bh *fibh, |
diff --git a/fs/udf/file.c b/fs/udf/file.c index 74050bff64f4..f77f7681288f 100644 --- a/fs/udf/file.c +++ b/fs/udf/file.c | |||
@@ -33,7 +33,6 @@ | |||
33 | #include <linux/capability.h> | 33 | #include <linux/capability.h> |
34 | #include <linux/errno.h> | 34 | #include <linux/errno.h> |
35 | #include <linux/pagemap.h> | 35 | #include <linux/pagemap.h> |
36 | #include <linux/buffer_head.h> | ||
37 | #include <linux/uio.h> | 36 | #include <linux/uio.h> |
38 | 37 | ||
39 | #include "udf_i.h" | 38 | #include "udf_i.h" |
diff --git a/fs/udf/inode.c b/fs/udf/inode.c index 9c1fbd23913d..9e3d780e5eff 100644 --- a/fs/udf/inode.c +++ b/fs/udf/inode.c | |||
@@ -33,7 +33,6 @@ | |||
33 | #include <linux/mm.h> | 33 | #include <linux/mm.h> |
34 | #include <linux/module.h> | 34 | #include <linux/module.h> |
35 | #include <linux/pagemap.h> | 35 | #include <linux/pagemap.h> |
36 | #include <linux/buffer_head.h> | ||
37 | #include <linux/writeback.h> | 36 | #include <linux/writeback.h> |
38 | #include <linux/slab.h> | 37 | #include <linux/slab.h> |
39 | #include <linux/crc-itu-t.h> | 38 | #include <linux/crc-itu-t.h> |
@@ -1637,7 +1636,7 @@ static int udf_update_inode(struct inode *inode, int do_sync) | |||
1637 | udf_get_lb_pblock(inode->i_sb, &iinfo->i_location, 0)); | 1636 | udf_get_lb_pblock(inode->i_sb, &iinfo->i_location, 0)); |
1638 | if (!bh) { | 1637 | if (!bh) { |
1639 | udf_debug("getblk failure\n"); | 1638 | udf_debug("getblk failure\n"); |
1640 | return -ENOMEM; | 1639 | return -EIO; |
1641 | } | 1640 | } |
1642 | 1641 | ||
1643 | lock_buffer(bh); | 1642 | lock_buffer(bh); |
diff --git a/fs/udf/misc.c b/fs/udf/misc.c index c175b4dabc14..71d1c25f360d 100644 --- a/fs/udf/misc.c +++ b/fs/udf/misc.c | |||
@@ -23,7 +23,6 @@ | |||
23 | 23 | ||
24 | #include <linux/fs.h> | 24 | #include <linux/fs.h> |
25 | #include <linux/string.h> | 25 | #include <linux/string.h> |
26 | #include <linux/buffer_head.h> | ||
27 | #include <linux/crc-itu-t.h> | 26 | #include <linux/crc-itu-t.h> |
28 | 27 | ||
29 | #include "udf_i.h" | 28 | #include "udf_i.h" |
diff --git a/fs/udf/namei.c b/fs/udf/namei.c index 33b246b82c98..39661977c89c 100644 --- a/fs/udf/namei.c +++ b/fs/udf/namei.c | |||
@@ -27,7 +27,6 @@ | |||
27 | #include <linux/errno.h> | 27 | #include <linux/errno.h> |
28 | #include <linux/mm.h> | 28 | #include <linux/mm.h> |
29 | #include <linux/slab.h> | 29 | #include <linux/slab.h> |
30 | #include <linux/buffer_head.h> | ||
31 | #include <linux/sched.h> | 30 | #include <linux/sched.h> |
32 | #include <linux/crc-itu-t.h> | 31 | #include <linux/crc-itu-t.h> |
33 | #include <linux/exportfs.h> | 32 | #include <linux/exportfs.h> |
@@ -569,8 +568,8 @@ static int udf_add_nondir(struct dentry *dentry, struct inode *inode) | |||
569 | *(__le32 *)((struct allocDescImpUse *)cfi.icb.impUse)->impUse = | 568 | *(__le32 *)((struct allocDescImpUse *)cfi.icb.impUse)->impUse = |
570 | cpu_to_le32(iinfo->i_unique & 0x00000000FFFFFFFFUL); | 569 | cpu_to_le32(iinfo->i_unique & 0x00000000FFFFFFFFUL); |
571 | udf_write_fi(dir, &cfi, fi, &fibh, NULL, NULL); | 570 | udf_write_fi(dir, &cfi, fi, &fibh, NULL, NULL); |
572 | if (UDF_I(dir)->i_alloc_type == ICBTAG_FLAG_AD_IN_ICB) | 571 | dir->i_ctime = dir->i_mtime = current_fs_time(dir->i_sb); |
573 | mark_inode_dirty(dir); | 572 | mark_inode_dirty(dir); |
574 | if (fibh.sbh != fibh.ebh) | 573 | if (fibh.sbh != fibh.ebh) |
575 | brelse(fibh.ebh); | 574 | brelse(fibh.ebh); |
576 | brelse(fibh.sbh); | 575 | brelse(fibh.sbh); |
@@ -683,6 +682,7 @@ static int udf_mkdir(struct inode *dir, struct dentry *dentry, umode_t mode) | |||
683 | cfi.fileCharacteristics |= FID_FILE_CHAR_DIRECTORY; | 682 | cfi.fileCharacteristics |= FID_FILE_CHAR_DIRECTORY; |
684 | udf_write_fi(dir, &cfi, fi, &fibh, NULL, NULL); | 683 | udf_write_fi(dir, &cfi, fi, &fibh, NULL, NULL); |
685 | inc_nlink(dir); | 684 | inc_nlink(dir); |
685 | dir->i_ctime = dir->i_mtime = current_fs_time(dir->i_sb); | ||
686 | mark_inode_dirty(dir); | 686 | mark_inode_dirty(dir); |
687 | unlock_new_inode(inode); | 687 | unlock_new_inode(inode); |
688 | d_instantiate(dentry, inode); | 688 | d_instantiate(dentry, inode); |
@@ -1024,6 +1024,8 @@ static int udf_link(struct dentry *old_dentry, struct inode *dir, | |||
1024 | inc_nlink(inode); | 1024 | inc_nlink(inode); |
1025 | inode->i_ctime = current_fs_time(inode->i_sb); | 1025 | inode->i_ctime = current_fs_time(inode->i_sb); |
1026 | mark_inode_dirty(inode); | 1026 | mark_inode_dirty(inode); |
1027 | dir->i_ctime = dir->i_mtime = current_fs_time(dir->i_sb); | ||
1028 | mark_inode_dirty(dir); | ||
1027 | ihold(inode); | 1029 | ihold(inode); |
1028 | d_instantiate(dentry, inode); | 1030 | d_instantiate(dentry, inode); |
1029 | 1031 | ||
@@ -1127,7 +1129,9 @@ static int udf_rename(struct inode *old_dir, struct dentry *old_dentry, | |||
1127 | inode_dec_link_count(new_inode); | 1129 | inode_dec_link_count(new_inode); |
1128 | } | 1130 | } |
1129 | old_dir->i_ctime = old_dir->i_mtime = current_fs_time(old_dir->i_sb); | 1131 | old_dir->i_ctime = old_dir->i_mtime = current_fs_time(old_dir->i_sb); |
1132 | new_dir->i_ctime = new_dir->i_mtime = current_fs_time(new_dir->i_sb); | ||
1130 | mark_inode_dirty(old_dir); | 1133 | mark_inode_dirty(old_dir); |
1134 | mark_inode_dirty(new_dir); | ||
1131 | 1135 | ||
1132 | if (dir_fi) { | 1136 | if (dir_fi) { |
1133 | dir_fi->icb.extLocation = cpu_to_lelb(UDF_I(new_dir)->i_location); | 1137 | dir_fi->icb.extLocation = cpu_to_lelb(UDF_I(new_dir)->i_location); |
diff --git a/fs/udf/partition.c b/fs/udf/partition.c index d6caf01a2097..5f861ed287c3 100644 --- a/fs/udf/partition.c +++ b/fs/udf/partition.c | |||
@@ -24,7 +24,6 @@ | |||
24 | 24 | ||
25 | #include <linux/fs.h> | 25 | #include <linux/fs.h> |
26 | #include <linux/string.h> | 26 | #include <linux/string.h> |
27 | #include <linux/buffer_head.h> | ||
28 | #include <linux/mutex.h> | 27 | #include <linux/mutex.h> |
29 | 28 | ||
30 | uint32_t udf_get_pblock(struct super_block *sb, uint32_t block, | 29 | uint32_t udf_get_pblock(struct super_block *sb, uint32_t block, |
diff --git a/fs/udf/super.c b/fs/udf/super.c index f169411c4ea0..6299f341967b 100644 --- a/fs/udf/super.c +++ b/fs/udf/super.c | |||
@@ -48,7 +48,6 @@ | |||
48 | #include <linux/stat.h> | 48 | #include <linux/stat.h> |
49 | #include <linux/cdrom.h> | 49 | #include <linux/cdrom.h> |
50 | #include <linux/nls.h> | 50 | #include <linux/nls.h> |
51 | #include <linux/buffer_head.h> | ||
52 | #include <linux/vfs.h> | 51 | #include <linux/vfs.h> |
53 | #include <linux/vmalloc.h> | 52 | #include <linux/vmalloc.h> |
54 | #include <linux/errno.h> | 53 | #include <linux/errno.h> |
diff --git a/fs/udf/symlink.c b/fs/udf/symlink.c index ac10ca939f26..8dfbc4025e2f 100644 --- a/fs/udf/symlink.c +++ b/fs/udf/symlink.c | |||
@@ -27,7 +27,6 @@ | |||
27 | #include <linux/mm.h> | 27 | #include <linux/mm.h> |
28 | #include <linux/stat.h> | 28 | #include <linux/stat.h> |
29 | #include <linux/pagemap.h> | 29 | #include <linux/pagemap.h> |
30 | #include <linux/buffer_head.h> | ||
31 | #include "udf_i.h" | 30 | #include "udf_i.h" |
32 | 31 | ||
33 | static int udf_pc_to_char(struct super_block *sb, unsigned char *from, | 32 | static int udf_pc_to_char(struct super_block *sb, unsigned char *from, |
diff --git a/fs/udf/truncate.c b/fs/udf/truncate.c index 8a9657d7f7c6..42b8c57795cb 100644 --- a/fs/udf/truncate.c +++ b/fs/udf/truncate.c | |||
@@ -22,7 +22,6 @@ | |||
22 | #include "udfdecl.h" | 22 | #include "udfdecl.h" |
23 | #include <linux/fs.h> | 23 | #include <linux/fs.h> |
24 | #include <linux/mm.h> | 24 | #include <linux/mm.h> |
25 | #include <linux/buffer_head.h> | ||
26 | 25 | ||
27 | #include "udf_i.h" | 26 | #include "udf_i.h" |
28 | #include "udf_sb.h" | 27 | #include "udf_sb.h" |
diff --git a/fs/xfs/xfs_qm.h b/fs/xfs/xfs_qm.h index 0d4d3590cf85..996a04064894 100644 --- a/fs/xfs/xfs_qm.h +++ b/fs/xfs/xfs_qm.h | |||
@@ -168,10 +168,6 @@ extern int xfs_qm_scall_getquota(struct xfs_mount *, xfs_dqid_t, | |||
168 | uint, struct qc_dqblk *); | 168 | uint, struct qc_dqblk *); |
169 | extern int xfs_qm_scall_setqlim(struct xfs_mount *, xfs_dqid_t, uint, | 169 | extern int xfs_qm_scall_setqlim(struct xfs_mount *, xfs_dqid_t, uint, |
170 | struct qc_dqblk *); | 170 | struct qc_dqblk *); |
171 | extern int xfs_qm_scall_getqstat(struct xfs_mount *, | ||
172 | struct fs_quota_stat *); | ||
173 | extern int xfs_qm_scall_getqstatv(struct xfs_mount *, | ||
174 | struct fs_quota_statv *); | ||
175 | extern int xfs_qm_scall_quotaon(struct xfs_mount *, uint); | 171 | extern int xfs_qm_scall_quotaon(struct xfs_mount *, uint); |
176 | extern int xfs_qm_scall_quotaoff(struct xfs_mount *, uint); | 172 | extern int xfs_qm_scall_quotaoff(struct xfs_mount *, uint); |
177 | 173 | ||
diff --git a/fs/xfs/xfs_qm_syscalls.c b/fs/xfs/xfs_qm_syscalls.c index 9b965db45800..9a25c9275fb3 100644 --- a/fs/xfs/xfs_qm_syscalls.c +++ b/fs/xfs/xfs_qm_syscalls.c | |||
@@ -38,7 +38,6 @@ | |||
38 | STATIC int xfs_qm_log_quotaoff(xfs_mount_t *, xfs_qoff_logitem_t **, uint); | 38 | STATIC int xfs_qm_log_quotaoff(xfs_mount_t *, xfs_qoff_logitem_t **, uint); |
39 | STATIC int xfs_qm_log_quotaoff_end(xfs_mount_t *, xfs_qoff_logitem_t *, | 39 | STATIC int xfs_qm_log_quotaoff_end(xfs_mount_t *, xfs_qoff_logitem_t *, |
40 | uint); | 40 | uint); |
41 | STATIC uint xfs_qm_export_flags(uint); | ||
42 | 41 | ||
43 | /* | 42 | /* |
44 | * Turn off quota accounting and/or enforcement for all udquots and/or | 43 | * Turn off quota accounting and/or enforcement for all udquots and/or |
@@ -389,159 +388,6 @@ xfs_qm_scall_quotaon( | |||
389 | return 0; | 388 | return 0; |
390 | } | 389 | } |
391 | 390 | ||
392 | |||
393 | /* | ||
394 | * Return quota status information, such as uquota-off, enforcements, etc. | ||
395 | * for Q_XGETQSTAT command. | ||
396 | */ | ||
397 | int | ||
398 | xfs_qm_scall_getqstat( | ||
399 | struct xfs_mount *mp, | ||
400 | struct fs_quota_stat *out) | ||
401 | { | ||
402 | struct xfs_quotainfo *q = mp->m_quotainfo; | ||
403 | struct xfs_inode *uip = NULL; | ||
404 | struct xfs_inode *gip = NULL; | ||
405 | struct xfs_inode *pip = NULL; | ||
406 | bool tempuqip = false; | ||
407 | bool tempgqip = false; | ||
408 | bool temppqip = false; | ||
409 | |||
410 | memset(out, 0, sizeof(fs_quota_stat_t)); | ||
411 | |||
412 | out->qs_version = FS_QSTAT_VERSION; | ||
413 | out->qs_flags = (__uint16_t) xfs_qm_export_flags(mp->m_qflags & | ||
414 | (XFS_ALL_QUOTA_ACCT| | ||
415 | XFS_ALL_QUOTA_ENFD)); | ||
416 | uip = q->qi_uquotaip; | ||
417 | gip = q->qi_gquotaip; | ||
418 | pip = q->qi_pquotaip; | ||
419 | if (!uip && mp->m_sb.sb_uquotino != NULLFSINO) { | ||
420 | if (xfs_iget(mp, NULL, mp->m_sb.sb_uquotino, | ||
421 | 0, 0, &uip) == 0) | ||
422 | tempuqip = true; | ||
423 | } | ||
424 | if (!gip && mp->m_sb.sb_gquotino != NULLFSINO) { | ||
425 | if (xfs_iget(mp, NULL, mp->m_sb.sb_gquotino, | ||
426 | 0, 0, &gip) == 0) | ||
427 | tempgqip = true; | ||
428 | } | ||
429 | /* | ||
430 | * Q_XGETQSTAT doesn't have room for both group and project quotas. | ||
431 | * So, allow the project quota values to be copied out only if | ||
432 | * there is no group quota information available. | ||
433 | */ | ||
434 | if (!gip) { | ||
435 | if (!pip && mp->m_sb.sb_pquotino != NULLFSINO) { | ||
436 | if (xfs_iget(mp, NULL, mp->m_sb.sb_pquotino, | ||
437 | 0, 0, &pip) == 0) | ||
438 | temppqip = true; | ||
439 | } | ||
440 | } else | ||
441 | pip = NULL; | ||
442 | if (uip) { | ||
443 | out->qs_uquota.qfs_ino = mp->m_sb.sb_uquotino; | ||
444 | out->qs_uquota.qfs_nblks = uip->i_d.di_nblocks; | ||
445 | out->qs_uquota.qfs_nextents = uip->i_d.di_nextents; | ||
446 | if (tempuqip) | ||
447 | IRELE(uip); | ||
448 | } | ||
449 | |||
450 | if (gip) { | ||
451 | out->qs_gquota.qfs_ino = mp->m_sb.sb_gquotino; | ||
452 | out->qs_gquota.qfs_nblks = gip->i_d.di_nblocks; | ||
453 | out->qs_gquota.qfs_nextents = gip->i_d.di_nextents; | ||
454 | if (tempgqip) | ||
455 | IRELE(gip); | ||
456 | } | ||
457 | if (pip) { | ||
458 | out->qs_gquota.qfs_ino = mp->m_sb.sb_gquotino; | ||
459 | out->qs_gquota.qfs_nblks = pip->i_d.di_nblocks; | ||
460 | out->qs_gquota.qfs_nextents = pip->i_d.di_nextents; | ||
461 | if (temppqip) | ||
462 | IRELE(pip); | ||
463 | } | ||
464 | out->qs_incoredqs = q->qi_dquots; | ||
465 | out->qs_btimelimit = q->qi_btimelimit; | ||
466 | out->qs_itimelimit = q->qi_itimelimit; | ||
467 | out->qs_rtbtimelimit = q->qi_rtbtimelimit; | ||
468 | out->qs_bwarnlimit = q->qi_bwarnlimit; | ||
469 | out->qs_iwarnlimit = q->qi_iwarnlimit; | ||
470 | |||
471 | return 0; | ||
472 | } | ||
473 | |||
474 | /* | ||
475 | * Return quota status information, such as uquota-off, enforcements, etc. | ||
476 | * for Q_XGETQSTATV command, to support separate project quota field. | ||
477 | */ | ||
478 | int | ||
479 | xfs_qm_scall_getqstatv( | ||
480 | struct xfs_mount *mp, | ||
481 | struct fs_quota_statv *out) | ||
482 | { | ||
483 | struct xfs_quotainfo *q = mp->m_quotainfo; | ||
484 | struct xfs_inode *uip = NULL; | ||
485 | struct xfs_inode *gip = NULL; | ||
486 | struct xfs_inode *pip = NULL; | ||
487 | bool tempuqip = false; | ||
488 | bool tempgqip = false; | ||
489 | bool temppqip = false; | ||
490 | |||
491 | out->qs_flags = (__uint16_t) xfs_qm_export_flags(mp->m_qflags & | ||
492 | (XFS_ALL_QUOTA_ACCT| | ||
493 | XFS_ALL_QUOTA_ENFD)); | ||
494 | out->qs_uquota.qfs_ino = mp->m_sb.sb_uquotino; | ||
495 | out->qs_gquota.qfs_ino = mp->m_sb.sb_gquotino; | ||
496 | out->qs_pquota.qfs_ino = mp->m_sb.sb_pquotino; | ||
497 | |||
498 | uip = q->qi_uquotaip; | ||
499 | gip = q->qi_gquotaip; | ||
500 | pip = q->qi_pquotaip; | ||
501 | if (!uip && mp->m_sb.sb_uquotino != NULLFSINO) { | ||
502 | if (xfs_iget(mp, NULL, mp->m_sb.sb_uquotino, | ||
503 | 0, 0, &uip) == 0) | ||
504 | tempuqip = true; | ||
505 | } | ||
506 | if (!gip && mp->m_sb.sb_gquotino != NULLFSINO) { | ||
507 | if (xfs_iget(mp, NULL, mp->m_sb.sb_gquotino, | ||
508 | 0, 0, &gip) == 0) | ||
509 | tempgqip = true; | ||
510 | } | ||
511 | if (!pip && mp->m_sb.sb_pquotino != NULLFSINO) { | ||
512 | if (xfs_iget(mp, NULL, mp->m_sb.sb_pquotino, | ||
513 | 0, 0, &pip) == 0) | ||
514 | temppqip = true; | ||
515 | } | ||
516 | if (uip) { | ||
517 | out->qs_uquota.qfs_nblks = uip->i_d.di_nblocks; | ||
518 | out->qs_uquota.qfs_nextents = uip->i_d.di_nextents; | ||
519 | if (tempuqip) | ||
520 | IRELE(uip); | ||
521 | } | ||
522 | |||
523 | if (gip) { | ||
524 | out->qs_gquota.qfs_nblks = gip->i_d.di_nblocks; | ||
525 | out->qs_gquota.qfs_nextents = gip->i_d.di_nextents; | ||
526 | if (tempgqip) | ||
527 | IRELE(gip); | ||
528 | } | ||
529 | if (pip) { | ||
530 | out->qs_pquota.qfs_nblks = pip->i_d.di_nblocks; | ||
531 | out->qs_pquota.qfs_nextents = pip->i_d.di_nextents; | ||
532 | if (temppqip) | ||
533 | IRELE(pip); | ||
534 | } | ||
535 | out->qs_incoredqs = q->qi_dquots; | ||
536 | out->qs_btimelimit = q->qi_btimelimit; | ||
537 | out->qs_itimelimit = q->qi_itimelimit; | ||
538 | out->qs_rtbtimelimit = q->qi_rtbtimelimit; | ||
539 | out->qs_bwarnlimit = q->qi_bwarnlimit; | ||
540 | out->qs_iwarnlimit = q->qi_iwarnlimit; | ||
541 | |||
542 | return 0; | ||
543 | } | ||
544 | |||
545 | #define XFS_QC_MASK \ | 391 | #define XFS_QC_MASK \ |
546 | (QC_LIMIT_MASK | QC_TIMER_MASK | QC_WARNS_MASK) | 392 | (QC_LIMIT_MASK | QC_TIMER_MASK | QC_WARNS_MASK) |
547 | 393 | ||
@@ -873,28 +719,6 @@ out_put: | |||
873 | return error; | 719 | return error; |
874 | } | 720 | } |
875 | 721 | ||
876 | STATIC uint | ||
877 | xfs_qm_export_flags( | ||
878 | uint flags) | ||
879 | { | ||
880 | uint uflags; | ||
881 | |||
882 | uflags = 0; | ||
883 | if (flags & XFS_UQUOTA_ACCT) | ||
884 | uflags |= FS_QUOTA_UDQ_ACCT; | ||
885 | if (flags & XFS_GQUOTA_ACCT) | ||
886 | uflags |= FS_QUOTA_GDQ_ACCT; | ||
887 | if (flags & XFS_PQUOTA_ACCT) | ||
888 | uflags |= FS_QUOTA_PDQ_ACCT; | ||
889 | if (flags & XFS_UQUOTA_ENFD) | ||
890 | uflags |= FS_QUOTA_UDQ_ENFD; | ||
891 | if (flags & XFS_GQUOTA_ENFD) | ||
892 | uflags |= FS_QUOTA_GDQ_ENFD; | ||
893 | if (flags & XFS_PQUOTA_ENFD) | ||
894 | uflags |= FS_QUOTA_PDQ_ENFD; | ||
895 | return uflags; | ||
896 | } | ||
897 | |||
898 | 722 | ||
899 | STATIC int | 723 | STATIC int |
900 | xfs_dqrele_inode( | 724 | xfs_dqrele_inode( |
diff --git a/fs/xfs/xfs_quotaops.c b/fs/xfs/xfs_quotaops.c index 6923905ab33d..7795e0d01382 100644 --- a/fs/xfs/xfs_quotaops.c +++ b/fs/xfs/xfs_quotaops.c | |||
@@ -23,10 +23,81 @@ | |||
23 | #include "xfs_inode.h" | 23 | #include "xfs_inode.h" |
24 | #include "xfs_quota.h" | 24 | #include "xfs_quota.h" |
25 | #include "xfs_trans.h" | 25 | #include "xfs_trans.h" |
26 | #include "xfs_trace.h" | ||
27 | #include "xfs_icache.h" | ||
26 | #include "xfs_qm.h" | 28 | #include "xfs_qm.h" |
27 | #include <linux/quota.h> | 29 | #include <linux/quota.h> |
28 | 30 | ||
29 | 31 | ||
32 | static void | ||
33 | xfs_qm_fill_state( | ||
34 | struct qc_type_state *tstate, | ||
35 | struct xfs_mount *mp, | ||
36 | struct xfs_inode *ip, | ||
37 | xfs_ino_t ino) | ||
38 | { | ||
39 | struct xfs_quotainfo *q = mp->m_quotainfo; | ||
40 | bool tempqip = false; | ||
41 | |||
42 | tstate->ino = ino; | ||
43 | if (!ip && ino == NULLFSINO) | ||
44 | return; | ||
45 | if (!ip) { | ||
46 | if (xfs_iget(mp, NULL, ino, 0, 0, &ip)) | ||
47 | return; | ||
48 | tempqip = true; | ||
49 | } | ||
50 | tstate->flags |= QCI_SYSFILE; | ||
51 | tstate->blocks = ip->i_d.di_nblocks; | ||
52 | tstate->nextents = ip->i_d.di_nextents; | ||
53 | tstate->spc_timelimit = q->qi_btimelimit; | ||
54 | tstate->ino_timelimit = q->qi_itimelimit; | ||
55 | tstate->rt_spc_timelimit = q->qi_rtbtimelimit; | ||
56 | tstate->spc_warnlimit = q->qi_bwarnlimit; | ||
57 | tstate->ino_warnlimit = q->qi_iwarnlimit; | ||
58 | tstate->rt_spc_warnlimit = q->qi_rtbwarnlimit; | ||
59 | if (tempqip) | ||
60 | IRELE(ip); | ||
61 | } | ||
62 | |||
63 | /* | ||
64 | * Return quota status information, such as enforcements, quota file inode | ||
65 | * numbers etc. | ||
66 | */ | ||
67 | static int | ||
68 | xfs_fs_get_quota_state( | ||
69 | struct super_block *sb, | ||
70 | struct qc_state *state) | ||
71 | { | ||
72 | struct xfs_mount *mp = XFS_M(sb); | ||
73 | struct xfs_quotainfo *q = mp->m_quotainfo; | ||
74 | |||
75 | memset(state, 0, sizeof(*state)); | ||
76 | if (!XFS_IS_QUOTA_RUNNING(mp)) | ||
77 | return 0; | ||
78 | state->s_incoredqs = q->qi_dquots; | ||
79 | if (XFS_IS_UQUOTA_RUNNING(mp)) | ||
80 | state->s_state[USRQUOTA].flags |= QCI_ACCT_ENABLED; | ||
81 | if (XFS_IS_UQUOTA_ENFORCED(mp)) | ||
82 | state->s_state[USRQUOTA].flags |= QCI_LIMITS_ENFORCED; | ||
83 | if (XFS_IS_GQUOTA_RUNNING(mp)) | ||
84 | state->s_state[GRPQUOTA].flags |= QCI_ACCT_ENABLED; | ||
85 | if (XFS_IS_GQUOTA_ENFORCED(mp)) | ||
86 | state->s_state[GRPQUOTA].flags |= QCI_LIMITS_ENFORCED; | ||
87 | if (XFS_IS_PQUOTA_RUNNING(mp)) | ||
88 | state->s_state[PRJQUOTA].flags |= QCI_ACCT_ENABLED; | ||
89 | if (XFS_IS_PQUOTA_ENFORCED(mp)) | ||
90 | state->s_state[PRJQUOTA].flags |= QCI_LIMITS_ENFORCED; | ||
91 | |||
92 | xfs_qm_fill_state(&state->s_state[USRQUOTA], mp, q->qi_uquotaip, | ||
93 | mp->m_sb.sb_uquotino); | ||
94 | xfs_qm_fill_state(&state->s_state[GRPQUOTA], mp, q->qi_gquotaip, | ||
95 | mp->m_sb.sb_gquotino); | ||
96 | xfs_qm_fill_state(&state->s_state[PRJQUOTA], mp, q->qi_pquotaip, | ||
97 | mp->m_sb.sb_pquotino); | ||
98 | return 0; | ||
99 | } | ||
100 | |||
30 | STATIC int | 101 | STATIC int |
31 | xfs_quota_type(int type) | 102 | xfs_quota_type(int type) |
32 | { | 103 | { |
@@ -40,28 +111,40 @@ xfs_quota_type(int type) | |||
40 | } | 111 | } |
41 | } | 112 | } |
42 | 113 | ||
43 | STATIC int | 114 | #define XFS_QC_SETINFO_MASK (QC_TIMER_MASK | QC_WARNS_MASK) |
44 | xfs_fs_get_xstate( | 115 | |
116 | /* | ||
117 | * Adjust quota timers & warnings | ||
118 | */ | ||
119 | static int | ||
120 | xfs_fs_set_info( | ||
45 | struct super_block *sb, | 121 | struct super_block *sb, |
46 | struct fs_quota_stat *fqs) | 122 | int type, |
123 | struct qc_info *info) | ||
47 | { | 124 | { |
48 | struct xfs_mount *mp = XFS_M(sb); | 125 | struct xfs_mount *mp = XFS_M(sb); |
126 | struct qc_dqblk newlim; | ||
49 | 127 | ||
128 | if (sb->s_flags & MS_RDONLY) | ||
129 | return -EROFS; | ||
50 | if (!XFS_IS_QUOTA_RUNNING(mp)) | 130 | if (!XFS_IS_QUOTA_RUNNING(mp)) |
51 | return -ENOSYS; | 131 | return -ENOSYS; |
52 | return xfs_qm_scall_getqstat(mp, fqs); | 132 | if (!XFS_IS_QUOTA_ON(mp)) |
53 | } | 133 | return -ESRCH; |
134 | if (info->i_fieldmask & ~XFS_QC_SETINFO_MASK) | ||
135 | return -EINVAL; | ||
136 | if ((info->i_fieldmask & XFS_QC_SETINFO_MASK) == 0) | ||
137 | return 0; | ||
54 | 138 | ||
55 | STATIC int | 139 | newlim.d_fieldmask = info->i_fieldmask; |
56 | xfs_fs_get_xstatev( | 140 | newlim.d_spc_timer = info->i_spc_timelimit; |
57 | struct super_block *sb, | 141 | newlim.d_ino_timer = info->i_ino_timelimit; |
58 | struct fs_quota_statv *fqs) | 142 | newlim.d_rt_spc_timer = info->i_rt_spc_timelimit; |
59 | { | 143 | newlim.d_ino_warns = info->i_ino_warnlimit; |
60 | struct xfs_mount *mp = XFS_M(sb); | 144 | newlim.d_spc_warns = info->i_spc_warnlimit; |
145 | newlim.d_rt_spc_warns = info->i_rt_spc_warnlimit; | ||
61 | 146 | ||
62 | if (!XFS_IS_QUOTA_RUNNING(mp)) | 147 | return xfs_qm_scall_setqlim(mp, 0, xfs_quota_type(type), &newlim); |
63 | return -ENOSYS; | ||
64 | return xfs_qm_scall_getqstatv(mp, fqs); | ||
65 | } | 148 | } |
66 | 149 | ||
67 | static unsigned int | 150 | static unsigned int |
@@ -178,8 +261,8 @@ xfs_fs_set_dqblk( | |||
178 | } | 261 | } |
179 | 262 | ||
180 | const struct quotactl_ops xfs_quotactl_operations = { | 263 | const struct quotactl_ops xfs_quotactl_operations = { |
181 | .get_xstatev = xfs_fs_get_xstatev, | 264 | .get_state = xfs_fs_get_quota_state, |
182 | .get_xstate = xfs_fs_get_xstate, | 265 | .set_info = xfs_fs_set_info, |
183 | .quota_enable = xfs_quota_enable, | 266 | .quota_enable = xfs_quota_enable, |
184 | .quota_disable = xfs_quota_disable, | 267 | .quota_disable = xfs_quota_disable, |
185 | .rm_xquota = xfs_fs_rm_xquota, | 268 | .rm_xquota = xfs_fs_rm_xquota, |