aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorLinus Torvalds <torvalds@linux-foundation.org>2015-02-10 18:52:38 -0500
committerLinus Torvalds <torvalds@linux-foundation.org>2015-02-10 18:52:38 -0500
commitc5452a58db9bbcb331ee92afa99a6f42e39085c7 (patch)
tree90d3749e9103b0582079b40f64743959767df268
parent4b4f8580a4b77126733db8072862793d4deae66a (diff)
parent6981498d7956e3177b6f74926aa4a5c2a45b4edb (diff)
Merge branch 'for_linus' of git://git.kernel.org/pub/scm/linux/kernel/git/jack/linux-fs
Pull quota interface unification and misc cleanups from Jan Kara: "The first part of the series unifying XFS and VFS quota interfaces. This part unifies turning quotas on and off so quota-tools and xfs_quota can be used to manage any filesystem. This is useful so that userspace doesn't have to distinguish which filesystem it is working with. As a result we can then easily reuse tests for project quotas in XFS for ext4. This also contains minor cleanups and fixes for udf, isofs, and ext3" * 'for_linus' of git://git.kernel.org/pub/scm/linux/kernel/git/jack/linux-fs: (23 commits) udf: remove bool assignment to 0/1 udf: use bool for done quota: Store maximum space limit in bytes quota: Remove quota_on_meta callback ocfs2: Use generic helpers for quotaon and quotaoff ext4: Use generic helpers for quotaon and quotaoff quota: Add ->quota_{enable,disable} callbacks for VFS quotas quota: Wire up ->quota_{enable,disable} callbacks into Q_QUOTA{ON,OFF} quota: Split ->set_xstate callback into two xfs: Remove some pointless quota checks xfs: Remove some useless flags tests xfs: Remove useless test quota: Verify flags passed to Q_SETINFO quota: Cleanup flags definitions ocfs2: Move OLQF_CLEAN flag out of generic quota flags quota: Don't store flags for v2 quota format jbd: drop jbd_ENOSYS debug udf: destroy sbi mutex in put_super udf: Check length of extended attributes and allocation descriptors udf: Remove repeated loads blocksize ...
-rw-r--r--fs/ext3/super.c2
-rw-r--r--fs/ext4/super.c42
-rw-r--r--fs/isofs/util.c18
-rw-r--r--fs/ocfs2/quota.h1
-rw-r--r--fs/ocfs2/quota_local.c14
-rw-r--r--fs/ocfs2/super.c32
-rw-r--r--fs/quota/dquot.c107
-rw-r--r--fs/quota/quota.c52
-rw-r--r--fs/quota/quota_v1.c4
-rw-r--r--fs/quota/quota_v2.c16
-rw-r--r--fs/udf/Kconfig10
-rw-r--r--fs/udf/inode.c32
-rw-r--r--fs/udf/super.c5
-rw-r--r--fs/xfs/xfs_qm_syscalls.c74
-rw-r--r--fs/xfs/xfs_quotaops.c59
-rw-r--r--include/linux/dqblk_v1.h3
-rw-r--r--include/linux/jbd.h9
-rw-r--r--include/linux/jbd2.h9
-rw-r--r--include/linux/quota.h22
-rw-r--r--include/linux/quotaops.h3
-rw-r--r--include/uapi/linux/quota.h14
21 files changed, 284 insertions, 244 deletions
diff --git a/fs/ext3/super.c b/fs/ext3/super.c
index 9b4e7d750d4f..d4dbf3c259b3 100644
--- a/fs/ext3/super.c
+++ b/fs/ext3/super.c
@@ -466,6 +466,8 @@ static void ext3_put_super (struct super_block * sb)
466 } 466 }
467 sb->s_fs_info = NULL; 467 sb->s_fs_info = NULL;
468 kfree(sbi->s_blockgroup_lock); 468 kfree(sbi->s_blockgroup_lock);
469 mutex_destroy(&sbi->s_orphan_lock);
470 mutex_destroy(&sbi->s_resize_lock);
469 kfree(sbi); 471 kfree(sbi);
470} 472}
471 473
diff --git a/fs/ext4/super.c b/fs/ext4/super.c
index 74c5f53595fb..ac64edbe501d 100644
--- a/fs/ext4/super.c
+++ b/fs/ext4/super.c
@@ -1046,10 +1046,7 @@ static int ext4_mark_dquot_dirty(struct dquot *dquot);
1046static int ext4_write_info(struct super_block *sb, int type); 1046static int ext4_write_info(struct super_block *sb, int type);
1047static int ext4_quota_on(struct super_block *sb, int type, int format_id, 1047static int ext4_quota_on(struct super_block *sb, int type, int format_id,
1048 struct path *path); 1048 struct path *path);
1049static int ext4_quota_on_sysfile(struct super_block *sb, int type,
1050 int format_id);
1051static int ext4_quota_off(struct super_block *sb, int type); 1049static int ext4_quota_off(struct super_block *sb, int type);
1052static int ext4_quota_off_sysfile(struct super_block *sb, int type);
1053static int ext4_quota_on_mount(struct super_block *sb, int type); 1050static int ext4_quota_on_mount(struct super_block *sb, int type);
1054static ssize_t ext4_quota_read(struct super_block *sb, int type, char *data, 1051static ssize_t ext4_quota_read(struct super_block *sb, int type, char *data,
1055 size_t len, loff_t off); 1052 size_t len, loff_t off);
@@ -1084,16 +1081,6 @@ static const struct quotactl_ops ext4_qctl_operations = {
1084 .get_dqblk = dquot_get_dqblk, 1081 .get_dqblk = dquot_get_dqblk,
1085 .set_dqblk = dquot_set_dqblk 1082 .set_dqblk = dquot_set_dqblk
1086}; 1083};
1087
1088static const struct quotactl_ops ext4_qctl_sysfile_operations = {
1089 .quota_on_meta = ext4_quota_on_sysfile,
1090 .quota_off = ext4_quota_off_sysfile,
1091 .quota_sync = dquot_quota_sync,
1092 .get_info = dquot_get_dqinfo,
1093 .set_info = dquot_set_dqinfo,
1094 .get_dqblk = dquot_get_dqblk,
1095 .set_dqblk = dquot_set_dqblk
1096};
1097#endif 1084#endif
1098 1085
1099static const struct super_operations ext4_sops = { 1086static const struct super_operations ext4_sops = {
@@ -3935,7 +3922,7 @@ static int ext4_fill_super(struct super_block *sb, void *data, int silent)
3935#ifdef CONFIG_QUOTA 3922#ifdef CONFIG_QUOTA
3936 sb->dq_op = &ext4_quota_operations; 3923 sb->dq_op = &ext4_quota_operations;
3937 if (EXT4_HAS_RO_COMPAT_FEATURE(sb, EXT4_FEATURE_RO_COMPAT_QUOTA)) 3924 if (EXT4_HAS_RO_COMPAT_FEATURE(sb, EXT4_FEATURE_RO_COMPAT_QUOTA))
3938 sb->s_qcop = &ext4_qctl_sysfile_operations; 3925 sb->s_qcop = &dquot_quotactl_sysfile_ops;
3939 else 3926 else
3940 sb->s_qcop = &ext4_qctl_operations; 3927 sb->s_qcop = &ext4_qctl_operations;
3941 sb->s_quota_types = QTYPE_MASK_USR | QTYPE_MASK_GRP; 3928 sb->s_quota_types = QTYPE_MASK_USR | QTYPE_MASK_GRP;
@@ -5288,21 +5275,6 @@ static int ext4_enable_quotas(struct super_block *sb)
5288 return 0; 5275 return 0;
5289} 5276}
5290 5277
5291/*
5292 * quota_on function that is used when QUOTA feature is set.
5293 */
5294static int ext4_quota_on_sysfile(struct super_block *sb, int type,
5295 int format_id)
5296{
5297 if (!EXT4_HAS_RO_COMPAT_FEATURE(sb, EXT4_FEATURE_RO_COMPAT_QUOTA))
5298 return -EINVAL;
5299
5300 /*
5301 * USAGE was enabled at mount time. Only need to enable LIMITS now.
5302 */
5303 return ext4_quota_enable(sb, type, format_id, DQUOT_LIMITS_ENABLED);
5304}
5305
5306static int ext4_quota_off(struct super_block *sb, int type) 5278static int ext4_quota_off(struct super_block *sb, int type)
5307{ 5279{
5308 struct inode *inode = sb_dqopt(sb)->files[type]; 5280 struct inode *inode = sb_dqopt(sb)->files[type];
@@ -5329,18 +5301,6 @@ out:
5329 return dquot_quota_off(sb, type); 5301 return dquot_quota_off(sb, type);
5330} 5302}
5331 5303
5332/*
5333 * quota_off function that is used when QUOTA feature is set.
5334 */
5335static int ext4_quota_off_sysfile(struct super_block *sb, int type)
5336{
5337 if (!EXT4_HAS_RO_COMPAT_FEATURE(sb, EXT4_FEATURE_RO_COMPAT_QUOTA))
5338 return -EINVAL;
5339
5340 /* Disable only the limits. */
5341 return dquot_disable(sb, type, DQUOT_LIMITS_ENABLED);
5342}
5343
5344/* Read data from quotafile - avoid pagecache and such because we cannot afford 5304/* Read data from quotafile - avoid pagecache and such because we cannot afford
5345 * acquiring the locks... As quota files are never truncated and quota code 5305 * acquiring the locks... As quota files are never truncated and quota code
5346 * itself serializes the operations (and no one else should touch the files) 5306 * itself serializes the operations (and no one else should touch the files)
diff --git a/fs/isofs/util.c b/fs/isofs/util.c
index 01e1ee7a998b..005a15cfd30a 100644
--- a/fs/isofs/util.c
+++ b/fs/isofs/util.c
@@ -2,6 +2,7 @@
2 * linux/fs/isofs/util.c 2 * linux/fs/isofs/util.c
3 */ 3 */
4 4
5#include <linux/time.h>
5#include "isofs.h" 6#include "isofs.h"
6 7
7/* 8/*
@@ -17,9 +18,9 @@
17int iso_date(char * p, int flag) 18int iso_date(char * p, int flag)
18{ 19{
19 int year, month, day, hour, minute, second, tz; 20 int year, month, day, hour, minute, second, tz;
20 int crtime, days, i; 21 int crtime;
21 22
22 year = p[0] - 70; 23 year = p[0];
23 month = p[1]; 24 month = p[1];
24 day = p[2]; 25 day = p[2];
25 hour = p[3]; 26 hour = p[3];
@@ -31,18 +32,7 @@ int iso_date(char * p, int flag)
31 if (year < 0) { 32 if (year < 0) {
32 crtime = 0; 33 crtime = 0;
33 } else { 34 } else {
34 int monlen[12] = {31,28,31,30,31,30,31,31,30,31,30,31}; 35 crtime = mktime64(year+1900, month, day, hour, minute, second);
35
36 days = year * 365;
37 if (year > 2)
38 days += (year+1) / 4;
39 for (i = 1; i < month; i++)
40 days += monlen[i-1];
41 if (((year+2) % 4) == 0 && month > 2)
42 days++;
43 days += day - 1;
44 crtime = ((((days * 24) + hour) * 60 + minute) * 60)
45 + second;
46 36
47 /* sign extend */ 37 /* sign extend */
48 if (tz & 0x80) 38 if (tz & 0x80)
diff --git a/fs/ocfs2/quota.h b/fs/ocfs2/quota.h
index 1eae330193a6..b6d51333ad02 100644
--- a/fs/ocfs2/quota.h
+++ b/fs/ocfs2/quota.h
@@ -48,6 +48,7 @@ struct ocfs2_quota_recovery {
48/* In-memory structure with quota header information */ 48/* In-memory structure with quota header information */
49struct ocfs2_mem_dqinfo { 49struct ocfs2_mem_dqinfo {
50 unsigned int dqi_type; /* Quota type this structure describes */ 50 unsigned int dqi_type; /* Quota type this structure describes */
51 unsigned int dqi_flags; /* Flags OLQF_* */
51 unsigned int dqi_chunks; /* Number of chunks in local quota file */ 52 unsigned int dqi_chunks; /* Number of chunks in local quota file */
52 unsigned int dqi_blocks; /* Number of blocks allocated for local quota file */ 53 unsigned int dqi_blocks; /* Number of blocks allocated for local quota file */
53 unsigned int dqi_syncms; /* How often should we sync with other nodes */ 54 unsigned int dqi_syncms; /* How often should we sync with other nodes */
diff --git a/fs/ocfs2/quota_local.c b/fs/ocfs2/quota_local.c
index 10b653930ee2..89c0b2620814 100644
--- a/fs/ocfs2/quota_local.c
+++ b/fs/ocfs2/quota_local.c
@@ -292,7 +292,7 @@ static void olq_update_info(struct buffer_head *bh, void *private)
292 ldinfo = (struct ocfs2_local_disk_dqinfo *)(bh->b_data + 292 ldinfo = (struct ocfs2_local_disk_dqinfo *)(bh->b_data +
293 OCFS2_LOCAL_INFO_OFF); 293 OCFS2_LOCAL_INFO_OFF);
294 spin_lock(&dq_data_lock); 294 spin_lock(&dq_data_lock);
295 ldinfo->dqi_flags = cpu_to_le32(info->dqi_flags & DQF_MASK); 295 ldinfo->dqi_flags = cpu_to_le32(oinfo->dqi_flags);
296 ldinfo->dqi_chunks = cpu_to_le32(oinfo->dqi_chunks); 296 ldinfo->dqi_chunks = cpu_to_le32(oinfo->dqi_chunks);
297 ldinfo->dqi_blocks = cpu_to_le32(oinfo->dqi_blocks); 297 ldinfo->dqi_blocks = cpu_to_le32(oinfo->dqi_blocks);
298 spin_unlock(&dq_data_lock); 298 spin_unlock(&dq_data_lock);
@@ -701,8 +701,8 @@ static int ocfs2_local_read_info(struct super_block *sb, int type)
701 /* We don't need the lock and we have to acquire quota file locks 701 /* We don't need the lock and we have to acquire quota file locks
702 * which will later depend on this lock */ 702 * which will later depend on this lock */
703 mutex_unlock(&sb_dqopt(sb)->dqio_mutex); 703 mutex_unlock(&sb_dqopt(sb)->dqio_mutex);
704 info->dqi_maxblimit = 0x7fffffffffffffffLL; 704 info->dqi_max_spc_limit = 0x7fffffffffffffffLL;
705 info->dqi_maxilimit = 0x7fffffffffffffffLL; 705 info->dqi_max_ino_limit = 0x7fffffffffffffffLL;
706 oinfo = kmalloc(sizeof(struct ocfs2_mem_dqinfo), GFP_NOFS); 706 oinfo = kmalloc(sizeof(struct ocfs2_mem_dqinfo), GFP_NOFS);
707 if (!oinfo) { 707 if (!oinfo) {
708 mlog(ML_ERROR, "failed to allocate memory for ocfs2 quota" 708 mlog(ML_ERROR, "failed to allocate memory for ocfs2 quota"
@@ -737,13 +737,13 @@ static int ocfs2_local_read_info(struct super_block *sb, int type)
737 } 737 }
738 ldinfo = (struct ocfs2_local_disk_dqinfo *)(bh->b_data + 738 ldinfo = (struct ocfs2_local_disk_dqinfo *)(bh->b_data +
739 OCFS2_LOCAL_INFO_OFF); 739 OCFS2_LOCAL_INFO_OFF);
740 info->dqi_flags = le32_to_cpu(ldinfo->dqi_flags); 740 oinfo->dqi_flags = le32_to_cpu(ldinfo->dqi_flags);
741 oinfo->dqi_chunks = le32_to_cpu(ldinfo->dqi_chunks); 741 oinfo->dqi_chunks = le32_to_cpu(ldinfo->dqi_chunks);
742 oinfo->dqi_blocks = le32_to_cpu(ldinfo->dqi_blocks); 742 oinfo->dqi_blocks = le32_to_cpu(ldinfo->dqi_blocks);
743 oinfo->dqi_libh = bh; 743 oinfo->dqi_libh = bh;
744 744
745 /* We crashed when using local quota file? */ 745 /* We crashed when using local quota file? */
746 if (!(info->dqi_flags & OLQF_CLEAN)) { 746 if (!(oinfo->dqi_flags & OLQF_CLEAN)) {
747 rec = OCFS2_SB(sb)->quota_rec; 747 rec = OCFS2_SB(sb)->quota_rec;
748 if (!rec) { 748 if (!rec) {
749 rec = ocfs2_alloc_quota_recovery(); 749 rec = ocfs2_alloc_quota_recovery();
@@ -772,7 +772,7 @@ static int ocfs2_local_read_info(struct super_block *sb, int type)
772 } 772 }
773 773
774 /* Now mark quota file as used */ 774 /* Now mark quota file as used */
775 info->dqi_flags &= ~OLQF_CLEAN; 775 oinfo->dqi_flags &= ~OLQF_CLEAN;
776 status = ocfs2_modify_bh(lqinode, bh, olq_update_info, info); 776 status = ocfs2_modify_bh(lqinode, bh, olq_update_info, info);
777 if (status < 0) { 777 if (status < 0) {
778 mlog_errno(status); 778 mlog_errno(status);
@@ -857,7 +857,7 @@ static int ocfs2_local_free_info(struct super_block *sb, int type)
857 goto out; 857 goto out;
858 858
859 /* Mark local file as clean */ 859 /* Mark local file as clean */
860 info->dqi_flags |= OLQF_CLEAN; 860 oinfo->dqi_flags |= OLQF_CLEAN;
861 status = ocfs2_modify_bh(sb_dqopt(sb)->files[type], 861 status = ocfs2_modify_bh(sb_dqopt(sb)->files[type],
862 oinfo->dqi_libh, 862 oinfo->dqi_libh,
863 olq_update_info, 863 olq_update_info,
diff --git a/fs/ocfs2/super.c b/fs/ocfs2/super.c
index 83723179e1ec..706c71c2955d 100644
--- a/fs/ocfs2/super.c
+++ b/fs/ocfs2/super.c
@@ -1000,36 +1000,6 @@ static void ocfs2_disable_quotas(struct ocfs2_super *osb)
1000 } 1000 }
1001} 1001}
1002 1002
1003/* Handle quota on quotactl */
1004static int ocfs2_quota_on(struct super_block *sb, int type, int format_id)
1005{
1006 unsigned int feature[OCFS2_MAXQUOTAS] = {
1007 OCFS2_FEATURE_RO_COMPAT_USRQUOTA,
1008 OCFS2_FEATURE_RO_COMPAT_GRPQUOTA};
1009
1010 if (!OCFS2_HAS_RO_COMPAT_FEATURE(sb, feature[type]))
1011 return -EINVAL;
1012
1013 return dquot_enable(sb_dqopt(sb)->files[type], type,
1014 format_id, DQUOT_LIMITS_ENABLED);
1015}
1016
1017/* Handle quota off quotactl */
1018static int ocfs2_quota_off(struct super_block *sb, int type)
1019{
1020 return dquot_disable(sb, type, DQUOT_LIMITS_ENABLED);
1021}
1022
1023static const struct quotactl_ops ocfs2_quotactl_ops = {
1024 .quota_on_meta = ocfs2_quota_on,
1025 .quota_off = ocfs2_quota_off,
1026 .quota_sync = dquot_quota_sync,
1027 .get_info = dquot_get_dqinfo,
1028 .set_info = dquot_set_dqinfo,
1029 .get_dqblk = dquot_get_dqblk,
1030 .set_dqblk = dquot_set_dqblk,
1031};
1032
1033static int ocfs2_fill_super(struct super_block *sb, void *data, int silent) 1003static int ocfs2_fill_super(struct super_block *sb, void *data, int silent)
1034{ 1004{
1035 struct dentry *root; 1005 struct dentry *root;
@@ -2079,7 +2049,7 @@ static int ocfs2_initialize_super(struct super_block *sb,
2079 sb->s_op = &ocfs2_sops; 2049 sb->s_op = &ocfs2_sops;
2080 sb->s_d_op = &ocfs2_dentry_ops; 2050 sb->s_d_op = &ocfs2_dentry_ops;
2081 sb->s_export_op = &ocfs2_export_ops; 2051 sb->s_export_op = &ocfs2_export_ops;
2082 sb->s_qcop = &ocfs2_quotactl_ops; 2052 sb->s_qcop = &dquot_quotactl_sysfile_ops;
2083 sb->dq_op = &ocfs2_quota_operations; 2053 sb->dq_op = &ocfs2_quota_operations;
2084 sb->s_quota_types = QTYPE_MASK_USR | QTYPE_MASK_GRP; 2054 sb->s_quota_types = QTYPE_MASK_USR | QTYPE_MASK_GRP;
2085 sb->s_xattr = ocfs2_xattr_handlers; 2055 sb->s_xattr = ocfs2_xattr_handlers;
diff --git a/fs/quota/dquot.c b/fs/quota/dquot.c
index 69df5b239844..0ccd4ba3a246 100644
--- a/fs/quota/dquot.c
+++ b/fs/quota/dquot.c
@@ -1248,7 +1248,7 @@ static int ignore_hardlimit(struct dquot *dquot)
1248 1248
1249 return capable(CAP_SYS_RESOURCE) && 1249 return capable(CAP_SYS_RESOURCE) &&
1250 (info->dqi_format->qf_fmt_id != QFMT_VFS_OLD || 1250 (info->dqi_format->qf_fmt_id != QFMT_VFS_OLD ||
1251 !(info->dqi_flags & V1_DQF_RSQUASH)); 1251 !(info->dqi_flags & DQF_ROOT_SQUASH));
1252} 1252}
1253 1253
1254/* needs dq_data_lock */ 1254/* needs dq_data_lock */
@@ -2385,14 +2385,84 @@ out:
2385} 2385}
2386EXPORT_SYMBOL(dquot_quota_on_mount); 2386EXPORT_SYMBOL(dquot_quota_on_mount);
2387 2387
2388static inline qsize_t qbtos(qsize_t blocks) 2388static int dquot_quota_enable(struct super_block *sb, unsigned int flags)
2389{ 2389{
2390 return blocks << QIF_DQBLKSIZE_BITS; 2390 int ret;
2391 int type;
2392 struct quota_info *dqopt = sb_dqopt(sb);
2393
2394 if (!(dqopt->flags & DQUOT_QUOTA_SYS_FILE))
2395 return -ENOSYS;
2396 /* Accounting cannot be turned on while fs is mounted */
2397 flags &= ~(FS_QUOTA_UDQ_ACCT | FS_QUOTA_GDQ_ACCT | FS_QUOTA_PDQ_ACCT);
2398 if (!flags)
2399 return -EINVAL;
2400 for (type = 0; type < MAXQUOTAS; type++) {
2401 if (!(flags & qtype_enforce_flag(type)))
2402 continue;
2403 /* Can't enforce without accounting */
2404 if (!sb_has_quota_usage_enabled(sb, type))
2405 return -EINVAL;
2406 ret = dquot_enable(dqopt->files[type], type,
2407 dqopt->info[type].dqi_fmt_id,
2408 DQUOT_LIMITS_ENABLED);
2409 if (ret < 0)
2410 goto out_err;
2411 }
2412 return 0;
2413out_err:
2414 /* Backout enforcement enablement we already did */
2415 for (type--; type >= 0; type--) {
2416 if (flags & qtype_enforce_flag(type))
2417 dquot_disable(sb, type, DQUOT_LIMITS_ENABLED);
2418 }
2419 /* Error code translation for better compatibility with XFS */
2420 if (ret == -EBUSY)
2421 ret = -EEXIST;
2422 return ret;
2391} 2423}
2392 2424
2393static inline qsize_t stoqb(qsize_t space) 2425static int dquot_quota_disable(struct super_block *sb, unsigned int flags)
2394{ 2426{
2395 return (space + QIF_DQBLKSIZE - 1) >> QIF_DQBLKSIZE_BITS; 2427 int ret;
2428 int type;
2429 struct quota_info *dqopt = sb_dqopt(sb);
2430
2431 if (!(dqopt->flags & DQUOT_QUOTA_SYS_FILE))
2432 return -ENOSYS;
2433 /*
2434 * We don't support turning off accounting via quotactl. In principle
2435 * quota infrastructure can do this but filesystems don't expect
2436 * userspace to be able to do it.
2437 */
2438 if (flags &
2439 (FS_QUOTA_UDQ_ACCT | FS_QUOTA_GDQ_ACCT | FS_QUOTA_PDQ_ACCT))
2440 return -EOPNOTSUPP;
2441
2442 /* Filter out limits not enabled */
2443 for (type = 0; type < MAXQUOTAS; type++)
2444 if (!sb_has_quota_limits_enabled(sb, type))
2445 flags &= ~qtype_enforce_flag(type);
2446 /* Nothing left? */
2447 if (!flags)
2448 return -EEXIST;
2449 for (type = 0; type < MAXQUOTAS; type++) {
2450 if (flags & qtype_enforce_flag(type)) {
2451 ret = dquot_disable(sb, type, DQUOT_LIMITS_ENABLED);
2452 if (ret < 0)
2453 goto out_err;
2454 }
2455 }
2456 return 0;
2457out_err:
2458 /* Backout enforcement disabling we already did */
2459 for (type--; type >= 0; type--) {
2460 if (flags & qtype_enforce_flag(type))
2461 dquot_enable(dqopt->files[type], type,
2462 dqopt->info[type].dqi_fmt_id,
2463 DQUOT_LIMITS_ENABLED);
2464 }
2465 return ret;
2396} 2466}
2397 2467
2398/* Generic routine for getting common part of quota structure */ 2468/* Generic routine for getting common part of quota structure */
@@ -2444,13 +2514,13 @@ static int do_set_dqblk(struct dquot *dquot, struct qc_dqblk *di)
2444 return -EINVAL; 2514 return -EINVAL;
2445 2515
2446 if (((di->d_fieldmask & QC_SPC_SOFT) && 2516 if (((di->d_fieldmask & QC_SPC_SOFT) &&
2447 stoqb(di->d_spc_softlimit) > dqi->dqi_maxblimit) || 2517 di->d_spc_softlimit > dqi->dqi_max_spc_limit) ||
2448 ((di->d_fieldmask & QC_SPC_HARD) && 2518 ((di->d_fieldmask & QC_SPC_HARD) &&
2449 stoqb(di->d_spc_hardlimit) > dqi->dqi_maxblimit) || 2519 di->d_spc_hardlimit > dqi->dqi_max_spc_limit) ||
2450 ((di->d_fieldmask & QC_INO_SOFT) && 2520 ((di->d_fieldmask & QC_INO_SOFT) &&
2451 (di->d_ino_softlimit > dqi->dqi_maxilimit)) || 2521 (di->d_ino_softlimit > dqi->dqi_max_ino_limit)) ||
2452 ((di->d_fieldmask & QC_INO_HARD) && 2522 ((di->d_fieldmask & QC_INO_HARD) &&
2453 (di->d_ino_hardlimit > dqi->dqi_maxilimit))) 2523 (di->d_ino_hardlimit > dqi->dqi_max_ino_limit)))
2454 return -ERANGE; 2524 return -ERANGE;
2455 2525
2456 spin_lock(&dq_data_lock); 2526 spin_lock(&dq_data_lock);
@@ -2577,6 +2647,14 @@ int dquot_set_dqinfo(struct super_block *sb, int type, struct if_dqinfo *ii)
2577 goto out; 2647 goto out;
2578 } 2648 }
2579 mi = sb_dqopt(sb)->info + type; 2649 mi = sb_dqopt(sb)->info + type;
2650 if (ii->dqi_valid & IIF_FLAGS) {
2651 if (ii->dqi_flags & ~DQF_SETINFO_MASK ||
2652 (ii->dqi_flags & DQF_ROOT_SQUASH &&
2653 mi->dqi_format->qf_fmt_id != QFMT_VFS_OLD)) {
2654 err = -EINVAL;
2655 goto out;
2656 }
2657 }
2580 spin_lock(&dq_data_lock); 2658 spin_lock(&dq_data_lock);
2581 if (ii->dqi_valid & IIF_BGRACE) 2659 if (ii->dqi_valid & IIF_BGRACE)
2582 mi->dqi_bgrace = ii->dqi_bgrace; 2660 mi->dqi_bgrace = ii->dqi_bgrace;
@@ -2606,6 +2684,17 @@ const struct quotactl_ops dquot_quotactl_ops = {
2606}; 2684};
2607EXPORT_SYMBOL(dquot_quotactl_ops); 2685EXPORT_SYMBOL(dquot_quotactl_ops);
2608 2686
2687const struct quotactl_ops dquot_quotactl_sysfile_ops = {
2688 .quota_enable = dquot_quota_enable,
2689 .quota_disable = dquot_quota_disable,
2690 .quota_sync = dquot_quota_sync,
2691 .get_info = dquot_get_dqinfo,
2692 .set_info = dquot_set_dqinfo,
2693 .get_dqblk = dquot_get_dqblk,
2694 .set_dqblk = dquot_set_dqblk
2695};
2696EXPORT_SYMBOL(dquot_quotactl_sysfile_ops);
2697
2609static int do_proc_dqstats(struct ctl_table *table, int write, 2698static int do_proc_dqstats(struct ctl_table *table, int write,
2610 void __user *buffer, size_t *lenp, loff_t *ppos) 2699 void __user *buffer, size_t *lenp, loff_t *ppos)
2611{ 2700{
diff --git a/fs/quota/quota.c b/fs/quota/quota.c
index 6f3856328eea..d14a799c7785 100644
--- a/fs/quota/quota.c
+++ b/fs/quota/quota.c
@@ -66,18 +66,40 @@ static int quota_sync_all(int type)
66 return ret; 66 return ret;
67} 67}
68 68
69unsigned int qtype_enforce_flag(int type)
70{
71 switch (type) {
72 case USRQUOTA:
73 return FS_QUOTA_UDQ_ENFD;
74 case GRPQUOTA:
75 return FS_QUOTA_GDQ_ENFD;
76 case PRJQUOTA:
77 return FS_QUOTA_PDQ_ENFD;
78 }
79 return 0;
80}
81
69static int quota_quotaon(struct super_block *sb, int type, int cmd, qid_t id, 82static int quota_quotaon(struct super_block *sb, int type, int cmd, qid_t id,
70 struct path *path) 83 struct path *path)
71{ 84{
72 if (!sb->s_qcop->quota_on && !sb->s_qcop->quota_on_meta) 85 if (!sb->s_qcop->quota_on && !sb->s_qcop->quota_enable)
73 return -ENOSYS; 86 return -ENOSYS;
74 if (sb->s_qcop->quota_on_meta) 87 if (sb->s_qcop->quota_enable)
75 return sb->s_qcop->quota_on_meta(sb, type, id); 88 return sb->s_qcop->quota_enable(sb, qtype_enforce_flag(type));
76 if (IS_ERR(path)) 89 if (IS_ERR(path))
77 return PTR_ERR(path); 90 return PTR_ERR(path);
78 return sb->s_qcop->quota_on(sb, type, id, path); 91 return sb->s_qcop->quota_on(sb, type, id, path);
79} 92}
80 93
94static int quota_quotaoff(struct super_block *sb, int type)
95{
96 if (!sb->s_qcop->quota_off && !sb->s_qcop->quota_disable)
97 return -ENOSYS;
98 if (sb->s_qcop->quota_disable)
99 return sb->s_qcop->quota_disable(sb, qtype_enforce_flag(type));
100 return sb->s_qcop->quota_off(sb, type);
101}
102
81static int quota_getfmt(struct super_block *sb, int type, void __user *addr) 103static int quota_getfmt(struct super_block *sb, int type, void __user *addr)
82{ 104{
83 __u32 fmt; 105 __u32 fmt;
@@ -208,15 +230,26 @@ static int quota_setquota(struct super_block *sb, int type, qid_t id,
208 return sb->s_qcop->set_dqblk(sb, qid, &fdq); 230 return sb->s_qcop->set_dqblk(sb, qid, &fdq);
209} 231}
210 232
211static int quota_setxstate(struct super_block *sb, int cmd, void __user *addr) 233static int quota_enable(struct super_block *sb, void __user *addr)
212{ 234{
213 __u32 flags; 235 __u32 flags;
214 236
215 if (copy_from_user(&flags, addr, sizeof(flags))) 237 if (copy_from_user(&flags, addr, sizeof(flags)))
216 return -EFAULT; 238 return -EFAULT;
217 if (!sb->s_qcop->set_xstate) 239 if (!sb->s_qcop->quota_enable)
218 return -ENOSYS; 240 return -ENOSYS;
219 return sb->s_qcop->set_xstate(sb, flags, cmd); 241 return sb->s_qcop->quota_enable(sb, flags);
242}
243
244static int quota_disable(struct super_block *sb, void __user *addr)
245{
246 __u32 flags;
247
248 if (copy_from_user(&flags, addr, sizeof(flags)))
249 return -EFAULT;
250 if (!sb->s_qcop->quota_disable)
251 return -ENOSYS;
252 return sb->s_qcop->quota_disable(sb, flags);
220} 253}
221 254
222static int quota_getxstate(struct super_block *sb, void __user *addr) 255static int quota_getxstate(struct super_block *sb, void __user *addr)
@@ -429,9 +462,7 @@ static int do_quotactl(struct super_block *sb, int type, int cmd, qid_t id,
429 case Q_QUOTAON: 462 case Q_QUOTAON:
430 return quota_quotaon(sb, type, cmd, id, path); 463 return quota_quotaon(sb, type, cmd, id, path);
431 case Q_QUOTAOFF: 464 case Q_QUOTAOFF:
432 if (!sb->s_qcop->quota_off) 465 return quota_quotaoff(sb, type);
433 return -ENOSYS;
434 return sb->s_qcop->quota_off(sb, type);
435 case Q_GETFMT: 466 case Q_GETFMT:
436 return quota_getfmt(sb, type, addr); 467 return quota_getfmt(sb, type, addr);
437 case Q_GETINFO: 468 case Q_GETINFO:
@@ -447,8 +478,9 @@ static int do_quotactl(struct super_block *sb, int type, int cmd, qid_t id,
447 return -ENOSYS; 478 return -ENOSYS;
448 return sb->s_qcop->quota_sync(sb, type); 479 return sb->s_qcop->quota_sync(sb, type);
449 case Q_XQUOTAON: 480 case Q_XQUOTAON:
481 return quota_enable(sb, addr);
450 case Q_XQUOTAOFF: 482 case Q_XQUOTAOFF:
451 return quota_setxstate(sb, cmd, addr); 483 return quota_disable(sb, addr);
452 case Q_XQUOTARM: 484 case Q_XQUOTARM:
453 return quota_rmxquota(sb, addr); 485 return quota_rmxquota(sb, addr);
454 case Q_XGETQSTAT: 486 case Q_XGETQSTAT:
diff --git a/fs/quota/quota_v1.c b/fs/quota/quota_v1.c
index 469c6848b322..8fe79beced5c 100644
--- a/fs/quota/quota_v1.c
+++ b/fs/quota/quota_v1.c
@@ -169,8 +169,8 @@ static int v1_read_file_info(struct super_block *sb, int type)
169 } 169 }
170 ret = 0; 170 ret = 0;
171 /* limits are stored as unsigned 32-bit data */ 171 /* limits are stored as unsigned 32-bit data */
172 dqopt->info[type].dqi_maxblimit = 0xffffffff; 172 dqopt->info[type].dqi_max_spc_limit = 0xffffffffULL << QUOTABLOCK_BITS;
173 dqopt->info[type].dqi_maxilimit = 0xffffffff; 173 dqopt->info[type].dqi_max_ino_limit = 0xffffffff;
174 dqopt->info[type].dqi_igrace = 174 dqopt->info[type].dqi_igrace =
175 dqblk.dqb_itime ? dqblk.dqb_itime : MAX_IQ_TIME; 175 dqblk.dqb_itime ? dqblk.dqb_itime : MAX_IQ_TIME;
176 dqopt->info[type].dqi_bgrace = 176 dqopt->info[type].dqi_bgrace =
diff --git a/fs/quota/quota_v2.c b/fs/quota/quota_v2.c
index 02751ec695c5..9cb10d7197f7 100644
--- a/fs/quota/quota_v2.c
+++ b/fs/quota/quota_v2.c
@@ -117,16 +117,17 @@ 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_maxblimit = 0xffffffff; 120 info->dqi_max_spc_limit = 0xffffffffULL << QUOTABLOCK_BITS;
121 info->dqi_maxilimit = 0xffffffff; 121 info->dqi_max_ino_limit = 0xffffffff;
122 } else { 122 } else {
123 /* used space is stored as unsigned 64-bit value */ 123 /* used space is stored as unsigned 64-bit value in bytes */
124 info->dqi_maxblimit = 0xffffffffffffffffULL; /* 2^64-1 */ 124 info->dqi_max_spc_limit = 0xffffffffffffffffULL; /* 2^64-1 */
125 info->dqi_maxilimit = 0xffffffffffffffffULL; 125 info->dqi_max_ino_limit = 0xffffffffffffffffULL;
126 } 126 }
127 info->dqi_bgrace = le32_to_cpu(dinfo.dqi_bgrace); 127 info->dqi_bgrace = le32_to_cpu(dinfo.dqi_bgrace);
128 info->dqi_igrace = le32_to_cpu(dinfo.dqi_igrace); 128 info->dqi_igrace = le32_to_cpu(dinfo.dqi_igrace);
129 info->dqi_flags = le32_to_cpu(dinfo.dqi_flags); 129 /* No flags currently supported */
130 info->dqi_flags = 0;
130 qinfo->dqi_sb = sb; 131 qinfo->dqi_sb = sb;
131 qinfo->dqi_type = type; 132 qinfo->dqi_type = type;
132 qinfo->dqi_blocks = le32_to_cpu(dinfo.dqi_blocks); 133 qinfo->dqi_blocks = le32_to_cpu(dinfo.dqi_blocks);
@@ -157,7 +158,8 @@ static int v2_write_file_info(struct super_block *sb, int type)
157 info->dqi_flags &= ~DQF_INFO_DIRTY; 158 info->dqi_flags &= ~DQF_INFO_DIRTY;
158 dinfo.dqi_bgrace = cpu_to_le32(info->dqi_bgrace); 159 dinfo.dqi_bgrace = cpu_to_le32(info->dqi_bgrace);
159 dinfo.dqi_igrace = cpu_to_le32(info->dqi_igrace); 160 dinfo.dqi_igrace = cpu_to_le32(info->dqi_igrace);
160 dinfo.dqi_flags = cpu_to_le32(info->dqi_flags & DQF_MASK); 161 /* No flags currently supported */
162 dinfo.dqi_flags = cpu_to_le32(0);
161 spin_unlock(&dq_data_lock); 163 spin_unlock(&dq_data_lock);
162 dinfo.dqi_blocks = cpu_to_le32(qinfo->dqi_blocks); 164 dinfo.dqi_blocks = cpu_to_le32(qinfo->dqi_blocks);
163 dinfo.dqi_free_blk = cpu_to_le32(qinfo->dqi_free_blk); 165 dinfo.dqi_free_blk = cpu_to_le32(qinfo->dqi_free_blk);
diff --git a/fs/udf/Kconfig b/fs/udf/Kconfig
index 0e0e99bd6bce..c6e17a744c3b 100644
--- a/fs/udf/Kconfig
+++ b/fs/udf/Kconfig
@@ -2,10 +2,12 @@ config UDF_FS
2 tristate "UDF file system support" 2 tristate "UDF file system support"
3 select CRC_ITU_T 3 select CRC_ITU_T
4 help 4 help
5 This is the new file system used on some CD-ROMs and DVDs. Say Y if 5 This is a file system used on some CD-ROMs and DVDs. Since the
6 you intend to mount DVD discs or CDRW's written in packet mode, or 6 file system is supported by multiple operating systems and is more
7 if written to by other UDF utilities, such as DirectCD. 7 compatible with standard unix file systems, it is also suitable for
8 Please read <file:Documentation/filesystems/udf.txt>. 8 removable USB disks. Say Y if you intend to mount DVD discs or CDRW's
9 written in packet mode, or if you want to use UDF for removable USB
10 disks. Please read <file:Documentation/filesystems/udf.txt>.
9 11
10 To compile this file system support as a module, choose M here: the 12 To compile this file system support as a module, choose M here: the
11 module will be called udf. 13 module will be called udf.
diff --git a/fs/udf/inode.c b/fs/udf/inode.c
index 5bc71d9a674a..a445d599098d 100644
--- a/fs/udf/inode.c
+++ b/fs/udf/inode.c
@@ -750,7 +750,7 @@ static sector_t inode_getblk(struct inode *inode, sector_t block,
750 /* Are we beyond EOF? */ 750 /* Are we beyond EOF? */
751 if (etype == -1) { 751 if (etype == -1) {
752 int ret; 752 int ret;
753 isBeyondEOF = 1; 753 isBeyondEOF = true;
754 if (count) { 754 if (count) {
755 if (c) 755 if (c)
756 laarr[0] = laarr[1]; 756 laarr[0] = laarr[1];
@@ -792,7 +792,7 @@ static sector_t inode_getblk(struct inode *inode, sector_t block,
792 endnum = c + 1; 792 endnum = c + 1;
793 lastblock = 1; 793 lastblock = 1;
794 } else { 794 } else {
795 isBeyondEOF = 0; 795 isBeyondEOF = false;
796 endnum = startnum = ((count > 2) ? 2 : count); 796 endnum = startnum = ((count > 2) ? 2 : count);
797 797
798 /* if the current extent is in position 0, 798 /* if the current extent is in position 0,
@@ -1288,6 +1288,7 @@ static int udf_read_inode(struct inode *inode, bool hidden_inode)
1288 struct kernel_lb_addr *iloc = &iinfo->i_location; 1288 struct kernel_lb_addr *iloc = &iinfo->i_location;
1289 unsigned int link_count; 1289 unsigned int link_count;
1290 unsigned int indirections = 0; 1290 unsigned int indirections = 0;
1291 int bs = inode->i_sb->s_blocksize;
1291 int ret = -EIO; 1292 int ret = -EIO;
1292 1293
1293reread: 1294reread:
@@ -1374,38 +1375,35 @@ reread:
1374 if (fe->descTag.tagIdent == cpu_to_le16(TAG_IDENT_EFE)) { 1375 if (fe->descTag.tagIdent == cpu_to_le16(TAG_IDENT_EFE)) {
1375 iinfo->i_efe = 1; 1376 iinfo->i_efe = 1;
1376 iinfo->i_use = 0; 1377 iinfo->i_use = 0;
1377 ret = udf_alloc_i_data(inode, inode->i_sb->s_blocksize - 1378 ret = udf_alloc_i_data(inode, bs -
1378 sizeof(struct extendedFileEntry)); 1379 sizeof(struct extendedFileEntry));
1379 if (ret) 1380 if (ret)
1380 goto out; 1381 goto out;
1381 memcpy(iinfo->i_ext.i_data, 1382 memcpy(iinfo->i_ext.i_data,
1382 bh->b_data + sizeof(struct extendedFileEntry), 1383 bh->b_data + sizeof(struct extendedFileEntry),
1383 inode->i_sb->s_blocksize - 1384 bs - sizeof(struct extendedFileEntry));
1384 sizeof(struct extendedFileEntry));
1385 } else if (fe->descTag.tagIdent == cpu_to_le16(TAG_IDENT_FE)) { 1385 } else if (fe->descTag.tagIdent == cpu_to_le16(TAG_IDENT_FE)) {
1386 iinfo->i_efe = 0; 1386 iinfo->i_efe = 0;
1387 iinfo->i_use = 0; 1387 iinfo->i_use = 0;
1388 ret = udf_alloc_i_data(inode, inode->i_sb->s_blocksize - 1388 ret = udf_alloc_i_data(inode, bs - sizeof(struct fileEntry));
1389 sizeof(struct fileEntry));
1390 if (ret) 1389 if (ret)
1391 goto out; 1390 goto out;
1392 memcpy(iinfo->i_ext.i_data, 1391 memcpy(iinfo->i_ext.i_data,
1393 bh->b_data + sizeof(struct fileEntry), 1392 bh->b_data + sizeof(struct fileEntry),
1394 inode->i_sb->s_blocksize - sizeof(struct fileEntry)); 1393 bs - sizeof(struct fileEntry));
1395 } else if (fe->descTag.tagIdent == cpu_to_le16(TAG_IDENT_USE)) { 1394 } else if (fe->descTag.tagIdent == cpu_to_le16(TAG_IDENT_USE)) {
1396 iinfo->i_efe = 0; 1395 iinfo->i_efe = 0;
1397 iinfo->i_use = 1; 1396 iinfo->i_use = 1;
1398 iinfo->i_lenAlloc = le32_to_cpu( 1397 iinfo->i_lenAlloc = le32_to_cpu(
1399 ((struct unallocSpaceEntry *)bh->b_data)-> 1398 ((struct unallocSpaceEntry *)bh->b_data)->
1400 lengthAllocDescs); 1399 lengthAllocDescs);
1401 ret = udf_alloc_i_data(inode, inode->i_sb->s_blocksize - 1400 ret = udf_alloc_i_data(inode, bs -
1402 sizeof(struct unallocSpaceEntry)); 1401 sizeof(struct unallocSpaceEntry));
1403 if (ret) 1402 if (ret)
1404 goto out; 1403 goto out;
1405 memcpy(iinfo->i_ext.i_data, 1404 memcpy(iinfo->i_ext.i_data,
1406 bh->b_data + sizeof(struct unallocSpaceEntry), 1405 bh->b_data + sizeof(struct unallocSpaceEntry),
1407 inode->i_sb->s_blocksize - 1406 bs - sizeof(struct unallocSpaceEntry));
1408 sizeof(struct unallocSpaceEntry));
1409 return 0; 1407 return 0;
1410 } 1408 }
1411 1409
@@ -1489,6 +1487,15 @@ reread:
1489 } 1487 }
1490 inode->i_generation = iinfo->i_unique; 1488 inode->i_generation = iinfo->i_unique;
1491 1489
1490 /*
1491 * Sanity check length of allocation descriptors and extended attrs to
1492 * avoid integer overflows
1493 */
1494 if (iinfo->i_lenEAttr > bs || iinfo->i_lenAlloc > bs)
1495 goto out;
1496 /* Now do exact checks */
1497 if (udf_file_entry_alloc_offset(inode) + iinfo->i_lenAlloc > bs)
1498 goto out;
1492 /* Sanity checks for files in ICB so that we don't get confused later */ 1499 /* Sanity checks for files in ICB so that we don't get confused later */
1493 if (iinfo->i_alloc_type == ICBTAG_FLAG_AD_IN_ICB) { 1500 if (iinfo->i_alloc_type == ICBTAG_FLAG_AD_IN_ICB) {
1494 /* 1501 /*
@@ -1498,8 +1505,7 @@ reread:
1498 if (iinfo->i_lenAlloc != inode->i_size) 1505 if (iinfo->i_lenAlloc != inode->i_size)
1499 goto out; 1506 goto out;
1500 /* File in ICB has to fit in there... */ 1507 /* File in ICB has to fit in there... */
1501 if (inode->i_size > inode->i_sb->s_blocksize - 1508 if (inode->i_size > bs - udf_file_entry_alloc_offset(inode))
1502 udf_file_entry_alloc_offset(inode))
1503 goto out; 1509 goto out;
1504 } 1510 }
1505 1511
diff --git a/fs/udf/super.c b/fs/udf/super.c
index 3ccb2f11fc76..f169411c4ea0 100644
--- a/fs/udf/super.c
+++ b/fs/udf/super.c
@@ -1599,7 +1599,7 @@ static noinline int udf_process_sequence(
1599 struct udf_vds_record *curr; 1599 struct udf_vds_record *curr;
1600 struct generic_desc *gd; 1600 struct generic_desc *gd;
1601 struct volDescPtr *vdp; 1601 struct volDescPtr *vdp;
1602 int done = 0; 1602 bool done = false;
1603 uint32_t vdsn; 1603 uint32_t vdsn;
1604 uint16_t ident; 1604 uint16_t ident;
1605 long next_s = 0, next_e = 0; 1605 long next_s = 0, next_e = 0;
@@ -1680,7 +1680,7 @@ static noinline int udf_process_sequence(
1680 lastblock = next_e; 1680 lastblock = next_e;
1681 next_s = next_e = 0; 1681 next_s = next_e = 0;
1682 } else 1682 } else
1683 done = 1; 1683 done = true;
1684 break; 1684 break;
1685 } 1685 }
1686 brelse(bh); 1686 brelse(bh);
@@ -2300,6 +2300,7 @@ static void udf_put_super(struct super_block *sb)
2300 udf_close_lvid(sb); 2300 udf_close_lvid(sb);
2301 brelse(sbi->s_lvid_bh); 2301 brelse(sbi->s_lvid_bh);
2302 udf_sb_free_partitions(sb); 2302 udf_sb_free_partitions(sb);
2303 mutex_destroy(&sbi->s_alloc_mutex);
2303 kfree(sb->s_fs_info); 2304 kfree(sb->s_fs_info);
2304 sb->s_fs_info = NULL; 2305 sb->s_fs_info = NULL;
2305} 2306}
diff --git a/fs/xfs/xfs_qm_syscalls.c b/fs/xfs/xfs_qm_syscalls.c
index cb6168ec92c9..d56a4f5155d5 100644
--- a/fs/xfs/xfs_qm_syscalls.c
+++ b/fs/xfs/xfs_qm_syscalls.c
@@ -329,22 +329,16 @@ xfs_qm_scall_quotaon(
329 return -EINVAL; 329 return -EINVAL;
330 } 330 }
331 331
332 /* No fs can turn on quotas with a delayed effect */
333 ASSERT((flags & XFS_ALL_QUOTA_ACCT) == 0);
334
335 /* 332 /*
336 * Can't enforce without accounting. We check the superblock 333 * Can't enforce without accounting. We check the superblock
337 * qflags here instead of m_qflags because rootfs can have 334 * qflags here instead of m_qflags because rootfs can have
338 * quota acct on ondisk without m_qflags' knowing. 335 * quota acct on ondisk without m_qflags' knowing.
339 */ 336 */
340 if (((flags & XFS_UQUOTA_ACCT) == 0 && 337 if (((mp->m_sb.sb_qflags & XFS_UQUOTA_ACCT) == 0 &&
341 (mp->m_sb.sb_qflags & XFS_UQUOTA_ACCT) == 0 &&
342 (flags & XFS_UQUOTA_ENFD)) || 338 (flags & XFS_UQUOTA_ENFD)) ||
343 ((flags & XFS_GQUOTA_ACCT) == 0 && 339 ((mp->m_sb.sb_qflags & XFS_GQUOTA_ACCT) == 0 &&
344 (mp->m_sb.sb_qflags & XFS_GQUOTA_ACCT) == 0 &&
345 (flags & XFS_GQUOTA_ENFD)) || 340 (flags & XFS_GQUOTA_ENFD)) ||
346 ((flags & XFS_PQUOTA_ACCT) == 0 && 341 ((mp->m_sb.sb_qflags & XFS_PQUOTA_ACCT) == 0 &&
347 (mp->m_sb.sb_qflags & XFS_PQUOTA_ACCT) == 0 &&
348 (flags & XFS_PQUOTA_ENFD))) { 342 (flags & XFS_PQUOTA_ENFD))) {
349 xfs_debug(mp, 343 xfs_debug(mp,
350 "%s: Can't enforce without acct, flags=%x sbflags=%x", 344 "%s: Can't enforce without acct, flags=%x sbflags=%x",
@@ -383,8 +377,7 @@ xfs_qm_scall_quotaon(
383 ((mp->m_sb.sb_qflags & XFS_PQUOTA_ACCT) != 377 ((mp->m_sb.sb_qflags & XFS_PQUOTA_ACCT) !=
384 (mp->m_qflags & XFS_PQUOTA_ACCT)) || 378 (mp->m_qflags & XFS_PQUOTA_ACCT)) ||
385 ((mp->m_sb.sb_qflags & XFS_GQUOTA_ACCT) != 379 ((mp->m_sb.sb_qflags & XFS_GQUOTA_ACCT) !=
386 (mp->m_qflags & XFS_GQUOTA_ACCT)) || 380 (mp->m_qflags & XFS_GQUOTA_ACCT)))
387 (flags & XFS_ALL_QUOTA_ENFD) == 0)
388 return 0; 381 return 0;
389 382
390 if (! XFS_IS_QUOTA_RUNNING(mp)) 383 if (! XFS_IS_QUOTA_RUNNING(mp))
@@ -421,20 +414,12 @@ xfs_qm_scall_getqstat(
421 memset(out, 0, sizeof(fs_quota_stat_t)); 414 memset(out, 0, sizeof(fs_quota_stat_t));
422 415
423 out->qs_version = FS_QSTAT_VERSION; 416 out->qs_version = FS_QSTAT_VERSION;
424 if (!xfs_sb_version_hasquota(&mp->m_sb)) {
425 out->qs_uquota.qfs_ino = NULLFSINO;
426 out->qs_gquota.qfs_ino = NULLFSINO;
427 return 0;
428 }
429
430 out->qs_flags = (__uint16_t) xfs_qm_export_flags(mp->m_qflags & 417 out->qs_flags = (__uint16_t) xfs_qm_export_flags(mp->m_qflags &
431 (XFS_ALL_QUOTA_ACCT| 418 (XFS_ALL_QUOTA_ACCT|
432 XFS_ALL_QUOTA_ENFD)); 419 XFS_ALL_QUOTA_ENFD));
433 if (q) { 420 uip = q->qi_uquotaip;
434 uip = q->qi_uquotaip; 421 gip = q->qi_gquotaip;
435 gip = q->qi_gquotaip; 422 pip = q->qi_pquotaip;
436 pip = q->qi_pquotaip;
437 }
438 if (!uip && mp->m_sb.sb_uquotino != NULLFSINO) { 423 if (!uip && mp->m_sb.sb_uquotino != NULLFSINO) {
439 if (xfs_iget(mp, NULL, mp->m_sb.sb_uquotino, 424 if (xfs_iget(mp, NULL, mp->m_sb.sb_uquotino,
440 0, 0, &uip) == 0) 425 0, 0, &uip) == 0)
@@ -480,14 +465,13 @@ xfs_qm_scall_getqstat(
480 if (temppqip) 465 if (temppqip)
481 IRELE(pip); 466 IRELE(pip);
482 } 467 }
483 if (q) { 468 out->qs_incoredqs = q->qi_dquots;
484 out->qs_incoredqs = q->qi_dquots; 469 out->qs_btimelimit = q->qi_btimelimit;
485 out->qs_btimelimit = q->qi_btimelimit; 470 out->qs_itimelimit = q->qi_itimelimit;
486 out->qs_itimelimit = q->qi_itimelimit; 471 out->qs_rtbtimelimit = q->qi_rtbtimelimit;
487 out->qs_rtbtimelimit = q->qi_rtbtimelimit; 472 out->qs_bwarnlimit = q->qi_bwarnlimit;
488 out->qs_bwarnlimit = q->qi_bwarnlimit; 473 out->qs_iwarnlimit = q->qi_iwarnlimit;
489 out->qs_iwarnlimit = q->qi_iwarnlimit; 474
490 }
491 return 0; 475 return 0;
492} 476}
493 477
@@ -508,13 +492,6 @@ xfs_qm_scall_getqstatv(
508 bool tempgqip = false; 492 bool tempgqip = false;
509 bool temppqip = false; 493 bool temppqip = false;
510 494
511 if (!xfs_sb_version_hasquota(&mp->m_sb)) {
512 out->qs_uquota.qfs_ino = NULLFSINO;
513 out->qs_gquota.qfs_ino = NULLFSINO;
514 out->qs_pquota.qfs_ino = NULLFSINO;
515 return 0;
516 }
517
518 out->qs_flags = (__uint16_t) xfs_qm_export_flags(mp->m_qflags & 495 out->qs_flags = (__uint16_t) xfs_qm_export_flags(mp->m_qflags &
519 (XFS_ALL_QUOTA_ACCT| 496 (XFS_ALL_QUOTA_ACCT|
520 XFS_ALL_QUOTA_ENFD)); 497 XFS_ALL_QUOTA_ENFD));
@@ -522,11 +499,9 @@ xfs_qm_scall_getqstatv(
522 out->qs_gquota.qfs_ino = mp->m_sb.sb_gquotino; 499 out->qs_gquota.qfs_ino = mp->m_sb.sb_gquotino;
523 out->qs_pquota.qfs_ino = mp->m_sb.sb_pquotino; 500 out->qs_pquota.qfs_ino = mp->m_sb.sb_pquotino;
524 501
525 if (q) { 502 uip = q->qi_uquotaip;
526 uip = q->qi_uquotaip; 503 gip = q->qi_gquotaip;
527 gip = q->qi_gquotaip; 504 pip = q->qi_pquotaip;
528 pip = q->qi_pquotaip;
529 }
530 if (!uip && mp->m_sb.sb_uquotino != NULLFSINO) { 505 if (!uip && mp->m_sb.sb_uquotino != NULLFSINO) {
531 if (xfs_iget(mp, NULL, mp->m_sb.sb_uquotino, 506 if (xfs_iget(mp, NULL, mp->m_sb.sb_uquotino,
532 0, 0, &uip) == 0) 507 0, 0, &uip) == 0)
@@ -561,14 +536,13 @@ xfs_qm_scall_getqstatv(
561 if (temppqip) 536 if (temppqip)
562 IRELE(pip); 537 IRELE(pip);
563 } 538 }
564 if (q) { 539 out->qs_incoredqs = q->qi_dquots;
565 out->qs_incoredqs = q->qi_dquots; 540 out->qs_btimelimit = q->qi_btimelimit;
566 out->qs_btimelimit = q->qi_btimelimit; 541 out->qs_itimelimit = q->qi_itimelimit;
567 out->qs_itimelimit = q->qi_itimelimit; 542 out->qs_rtbtimelimit = q->qi_rtbtimelimit;
568 out->qs_rtbtimelimit = q->qi_rtbtimelimit; 543 out->qs_bwarnlimit = q->qi_bwarnlimit;
569 out->qs_bwarnlimit = q->qi_bwarnlimit; 544 out->qs_iwarnlimit = q->qi_iwarnlimit;
570 out->qs_iwarnlimit = q->qi_iwarnlimit; 545
571 }
572 return 0; 546 return 0;
573} 547}
574 548
diff --git a/fs/xfs/xfs_quotaops.c b/fs/xfs/xfs_quotaops.c
index 801a84c1cdc3..6923905ab33d 100644
--- a/fs/xfs/xfs_quotaops.c
+++ b/fs/xfs/xfs_quotaops.c
@@ -64,19 +64,10 @@ xfs_fs_get_xstatev(
64 return xfs_qm_scall_getqstatv(mp, fqs); 64 return xfs_qm_scall_getqstatv(mp, fqs);
65} 65}
66 66
67STATIC int 67static unsigned int
68xfs_fs_set_xstate( 68xfs_quota_flags(unsigned int uflags)
69 struct super_block *sb,
70 unsigned int uflags,
71 int op)
72{ 69{
73 struct xfs_mount *mp = XFS_M(sb); 70 unsigned int flags = 0;
74 unsigned int flags = 0;
75
76 if (sb->s_flags & MS_RDONLY)
77 return -EROFS;
78 if (op != Q_XQUOTARM && !XFS_IS_QUOTA_RUNNING(mp))
79 return -ENOSYS;
80 71
81 if (uflags & FS_QUOTA_UDQ_ACCT) 72 if (uflags & FS_QUOTA_UDQ_ACCT)
82 flags |= XFS_UQUOTA_ACCT; 73 flags |= XFS_UQUOTA_ACCT;
@@ -91,16 +82,39 @@ xfs_fs_set_xstate(
91 if (uflags & FS_QUOTA_PDQ_ENFD) 82 if (uflags & FS_QUOTA_PDQ_ENFD)
92 flags |= XFS_PQUOTA_ENFD; 83 flags |= XFS_PQUOTA_ENFD;
93 84
94 switch (op) { 85 return flags;
95 case Q_XQUOTAON: 86}
96 return xfs_qm_scall_quotaon(mp, flags); 87
97 case Q_XQUOTAOFF: 88STATIC int
98 if (!XFS_IS_QUOTA_ON(mp)) 89xfs_quota_enable(
99 return -EINVAL; 90 struct super_block *sb,
100 return xfs_qm_scall_quotaoff(mp, flags); 91 unsigned int uflags)
101 } 92{
93 struct xfs_mount *mp = XFS_M(sb);
94
95 if (sb->s_flags & MS_RDONLY)
96 return -EROFS;
97 if (!XFS_IS_QUOTA_RUNNING(mp))
98 return -ENOSYS;
99
100 return xfs_qm_scall_quotaon(mp, xfs_quota_flags(uflags));
101}
102
103STATIC int
104xfs_quota_disable(
105 struct super_block *sb,
106 unsigned int uflags)
107{
108 struct xfs_mount *mp = XFS_M(sb);
109
110 if (sb->s_flags & MS_RDONLY)
111 return -EROFS;
112 if (!XFS_IS_QUOTA_RUNNING(mp))
113 return -ENOSYS;
114 if (!XFS_IS_QUOTA_ON(mp))
115 return -EINVAL;
102 116
103 return -EINVAL; 117 return xfs_qm_scall_quotaoff(mp, xfs_quota_flags(uflags));
104} 118}
105 119
106STATIC int 120STATIC int
@@ -166,7 +180,8 @@ xfs_fs_set_dqblk(
166const struct quotactl_ops xfs_quotactl_operations = { 180const struct quotactl_ops xfs_quotactl_operations = {
167 .get_xstatev = xfs_fs_get_xstatev, 181 .get_xstatev = xfs_fs_get_xstatev,
168 .get_xstate = xfs_fs_get_xstate, 182 .get_xstate = xfs_fs_get_xstate,
169 .set_xstate = xfs_fs_set_xstate, 183 .quota_enable = xfs_quota_enable,
184 .quota_disable = xfs_quota_disable,
170 .rm_xquota = xfs_fs_rm_xquota, 185 .rm_xquota = xfs_fs_rm_xquota,
171 .get_dqblk = xfs_fs_get_dqblk, 186 .get_dqblk = xfs_fs_get_dqblk,
172 .set_dqblk = xfs_fs_set_dqblk, 187 .set_dqblk = xfs_fs_set_dqblk,
diff --git a/include/linux/dqblk_v1.h b/include/linux/dqblk_v1.h
index 3713a7232dd8..c0d4d1e2a45c 100644
--- a/include/linux/dqblk_v1.h
+++ b/include/linux/dqblk_v1.h
@@ -5,9 +5,6 @@
5#ifndef _LINUX_DQBLK_V1_H 5#ifndef _LINUX_DQBLK_V1_H
6#define _LINUX_DQBLK_V1_H 6#define _LINUX_DQBLK_V1_H
7 7
8/* Root squash turned on */
9#define V1_DQF_RSQUASH 1
10
11/* Numbers of blocks needed for updates */ 8/* Numbers of blocks needed for updates */
12#define V1_INIT_ALLOC 1 9#define V1_INIT_ALLOC 1
13#define V1_INIT_REWRITE 1 10#define V1_INIT_REWRITE 1
diff --git a/include/linux/jbd.h b/include/linux/jbd.h
index 31229e0be90b..d32615280be9 100644
--- a/include/linux/jbd.h
+++ b/include/linux/jbd.h
@@ -956,15 +956,6 @@ void __log_wait_for_space(journal_t *journal);
956extern void __journal_drop_transaction(journal_t *, transaction_t *); 956extern void __journal_drop_transaction(journal_t *, transaction_t *);
957extern int cleanup_journal_tail(journal_t *); 957extern int cleanup_journal_tail(journal_t *);
958 958
959/* Debugging code only: */
960
961#define jbd_ENOSYS() \
962do { \
963 printk (KERN_ERR "JBD unimplemented function %s\n", __func__); \
964 current->state = TASK_UNINTERRUPTIBLE; \
965 schedule(); \
966} while (1)
967
968/* 959/*
969 * is_journal_abort 960 * is_journal_abort
970 * 961 *
diff --git a/include/linux/jbd2.h b/include/linux/jbd2.h
index 704b9a599b26..20e7f78041c8 100644
--- a/include/linux/jbd2.h
+++ b/include/linux/jbd2.h
@@ -1251,15 +1251,6 @@ void __jbd2_log_wait_for_space(journal_t *journal);
1251extern void __jbd2_journal_drop_transaction(journal_t *, transaction_t *); 1251extern void __jbd2_journal_drop_transaction(journal_t *, transaction_t *);
1252extern int jbd2_cleanup_journal_tail(journal_t *); 1252extern int jbd2_cleanup_journal_tail(journal_t *);
1253 1253
1254/* Debugging code only: */
1255
1256#define jbd_ENOSYS() \
1257do { \
1258 printk (KERN_ERR "JBD unimplemented function %s\n", __func__); \
1259 current->state = TASK_UNINTERRUPTIBLE; \
1260 schedule(); \
1261} while (1)
1262
1263/* 1254/*
1264 * is_journal_abort 1255 * is_journal_abort
1265 * 1256 *
diff --git a/include/linux/quota.h b/include/linux/quota.h
index 097d7eb2441e..d534e8ed308a 100644
--- a/include/linux/quota.h
+++ b/include/linux/quota.h
@@ -216,19 +216,21 @@ struct mem_dqinfo {
216 unsigned long dqi_flags; 216 unsigned long dqi_flags;
217 unsigned int dqi_bgrace; 217 unsigned int dqi_bgrace;
218 unsigned int dqi_igrace; 218 unsigned int dqi_igrace;
219 qsize_t dqi_maxblimit; 219 qsize_t dqi_max_spc_limit;
220 qsize_t dqi_maxilimit; 220 qsize_t dqi_max_ino_limit;
221 void *dqi_priv; 221 void *dqi_priv;
222}; 222};
223 223
224struct super_block; 224struct super_block;
225 225
226#define DQF_MASK 0xffff /* Mask for format specific flags */ 226/* Mask for flags passed to userspace */
227#define DQF_GETINFO_MASK 0x1ffff /* Mask for flags passed to userspace */ 227#define DQF_GETINFO_MASK (DQF_ROOT_SQUASH | DQF_SYS_FILE)
228#define DQF_SETINFO_MASK 0xffff /* Mask for flags modifiable from userspace */ 228/* Mask for flags modifiable from userspace */
229#define DQF_SYS_FILE_B 16 229#define DQF_SETINFO_MASK DQF_ROOT_SQUASH
230#define DQF_SYS_FILE (1 << DQF_SYS_FILE_B) /* Quota file stored as system file */ 230
231#define DQF_INFO_DIRTY_B 31 231enum {
232 DQF_INFO_DIRTY_B = DQF_PRIVATE,
233};
232#define DQF_INFO_DIRTY (1 << DQF_INFO_DIRTY_B) /* Is info dirty? */ 234#define DQF_INFO_DIRTY (1 << DQF_INFO_DIRTY_B) /* Is info dirty? */
233 235
234extern void mark_info_dirty(struct super_block *sb, int type); 236extern void mark_info_dirty(struct super_block *sb, int type);
@@ -367,15 +369,15 @@ struct qc_dqblk {
367/* Operations handling requests from userspace */ 369/* Operations handling requests from userspace */
368struct quotactl_ops { 370struct quotactl_ops {
369 int (*quota_on)(struct super_block *, int, int, struct path *); 371 int (*quota_on)(struct super_block *, int, int, struct path *);
370 int (*quota_on_meta)(struct super_block *, int, int);
371 int (*quota_off)(struct super_block *, int); 372 int (*quota_off)(struct super_block *, int);
373 int (*quota_enable)(struct super_block *, unsigned int);
374 int (*quota_disable)(struct super_block *, unsigned int);
372 int (*quota_sync)(struct super_block *, int); 375 int (*quota_sync)(struct super_block *, int);
373 int (*get_info)(struct super_block *, int, struct if_dqinfo *); 376 int (*get_info)(struct super_block *, int, struct if_dqinfo *);
374 int (*set_info)(struct super_block *, int, struct if_dqinfo *); 377 int (*set_info)(struct super_block *, int, struct if_dqinfo *);
375 int (*get_dqblk)(struct super_block *, struct kqid, struct qc_dqblk *); 378 int (*get_dqblk)(struct super_block *, struct kqid, struct qc_dqblk *);
376 int (*set_dqblk)(struct super_block *, struct kqid, struct qc_dqblk *); 379 int (*set_dqblk)(struct super_block *, struct kqid, struct qc_dqblk *);
377 int (*get_xstate)(struct super_block *, struct fs_quota_stat *); 380 int (*get_xstate)(struct super_block *, struct fs_quota_stat *);
378 int (*set_xstate)(struct super_block *, unsigned int, int);
379 int (*get_xstatev)(struct super_block *, struct fs_quota_statv *); 381 int (*get_xstatev)(struct super_block *, struct fs_quota_statv *);
380 int (*rm_xquota)(struct super_block *, unsigned int); 382 int (*rm_xquota)(struct super_block *, unsigned int);
381}; 383};
diff --git a/include/linux/quotaops.h b/include/linux/quotaops.h
index 29e3455f7d41..df73258cca47 100644
--- a/include/linux/quotaops.h
+++ b/include/linux/quotaops.h
@@ -166,6 +166,7 @@ static inline bool sb_has_quota_active(struct super_block *sb, int type)
166 */ 166 */
167extern const struct dquot_operations dquot_operations; 167extern const struct dquot_operations dquot_operations;
168extern const struct quotactl_ops dquot_quotactl_ops; 168extern const struct quotactl_ops dquot_quotactl_ops;
169extern const struct quotactl_ops dquot_quotactl_sysfile_ops;
169 170
170#else 171#else
171 172
@@ -386,4 +387,6 @@ static inline void dquot_release_reservation_block(struct inode *inode,
386 __dquot_free_space(inode, nr << inode->i_blkbits, DQUOT_SPACE_RESERVE); 387 __dquot_free_space(inode, nr << inode->i_blkbits, DQUOT_SPACE_RESERVE);
387} 388}
388 389
390unsigned int qtype_enforce_flag(int type);
391
389#endif /* _LINUX_QUOTAOPS_ */ 392#endif /* _LINUX_QUOTAOPS_ */
diff --git a/include/uapi/linux/quota.h b/include/uapi/linux/quota.h
index 3b6cfbeb086d..1f49b8341c99 100644
--- a/include/uapi/linux/quota.h
+++ b/include/uapi/linux/quota.h
@@ -126,10 +126,22 @@ struct if_dqblk {
126#define IIF_FLAGS 4 126#define IIF_FLAGS 4
127#define IIF_ALL (IIF_BGRACE | IIF_IGRACE | IIF_FLAGS) 127#define IIF_ALL (IIF_BGRACE | IIF_IGRACE | IIF_FLAGS)
128 128
129enum {
130 DQF_ROOT_SQUASH_B = 0,
131 DQF_SYS_FILE_B = 16,
132 /* Kernel internal flags invisible to userspace */
133 DQF_PRIVATE
134};
135
136/* Root squash enabled (for v1 quota format) */
137#define DQF_ROOT_SQUASH (1 << DQF_ROOT_SQUASH_B)
138/* Quota stored in a system file */
139#define DQF_SYS_FILE (1 << DQF_SYS_FILE_B)
140
129struct if_dqinfo { 141struct if_dqinfo {
130 __u64 dqi_bgrace; 142 __u64 dqi_bgrace;
131 __u64 dqi_igrace; 143 __u64 dqi_igrace;
132 __u32 dqi_flags; 144 __u32 dqi_flags; /* DFQ_* */
133 __u32 dqi_valid; 145 __u32 dqi_valid;
134}; 146};
135 147