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
  ...
	
	
This commit is contained in:
		
				commit
				
					
						c5452a58db
					
				
			
		
					 21 changed files with 284 additions and 244 deletions
				
			
		| 
						 | 
					@ -466,6 +466,8 @@ static void ext3_put_super (struct super_block * sb)
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
	sb->s_fs_info = NULL;
 | 
						sb->s_fs_info = NULL;
 | 
				
			||||||
	kfree(sbi->s_blockgroup_lock);
 | 
						kfree(sbi->s_blockgroup_lock);
 | 
				
			||||||
 | 
						mutex_destroy(&sbi->s_orphan_lock);
 | 
				
			||||||
 | 
						mutex_destroy(&sbi->s_resize_lock);
 | 
				
			||||||
	kfree(sbi);
 | 
						kfree(sbi);
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -1046,10 +1046,7 @@ static int ext4_mark_dquot_dirty(struct dquot *dquot);
 | 
				
			||||||
static int ext4_write_info(struct super_block *sb, int type);
 | 
					static int ext4_write_info(struct super_block *sb, int type);
 | 
				
			||||||
static int ext4_quota_on(struct super_block *sb, int type, int format_id,
 | 
					static int ext4_quota_on(struct super_block *sb, int type, int format_id,
 | 
				
			||||||
			 struct path *path);
 | 
								 struct path *path);
 | 
				
			||||||
static int ext4_quota_on_sysfile(struct super_block *sb, int type,
 | 
					 | 
				
			||||||
				 int format_id);
 | 
					 | 
				
			||||||
static int ext4_quota_off(struct super_block *sb, int type);
 | 
					static int ext4_quota_off(struct super_block *sb, int type);
 | 
				
			||||||
static int ext4_quota_off_sysfile(struct super_block *sb, int type);
 | 
					 | 
				
			||||||
static int ext4_quota_on_mount(struct super_block *sb, int type);
 | 
					static int ext4_quota_on_mount(struct super_block *sb, int type);
 | 
				
			||||||
static ssize_t ext4_quota_read(struct super_block *sb, int type, char *data,
 | 
					static ssize_t ext4_quota_read(struct super_block *sb, int type, char *data,
 | 
				
			||||||
			       size_t len, loff_t off);
 | 
								       size_t len, loff_t off);
 | 
				
			||||||
| 
						 | 
					@ -1084,16 +1081,6 @@ static const struct quotactl_ops ext4_qctl_operations = {
 | 
				
			||||||
	.get_dqblk	= dquot_get_dqblk,
 | 
						.get_dqblk	= dquot_get_dqblk,
 | 
				
			||||||
	.set_dqblk	= dquot_set_dqblk
 | 
						.set_dqblk	= dquot_set_dqblk
 | 
				
			||||||
};
 | 
					};
 | 
				
			||||||
 | 
					 | 
				
			||||||
static const struct quotactl_ops ext4_qctl_sysfile_operations = {
 | 
					 | 
				
			||||||
	.quota_on_meta	= ext4_quota_on_sysfile,
 | 
					 | 
				
			||||||
	.quota_off	= ext4_quota_off_sysfile,
 | 
					 | 
				
			||||||
	.quota_sync	= dquot_quota_sync,
 | 
					 | 
				
			||||||
	.get_info	= dquot_get_dqinfo,
 | 
					 | 
				
			||||||
	.set_info	= dquot_set_dqinfo,
 | 
					 | 
				
			||||||
	.get_dqblk	= dquot_get_dqblk,
 | 
					 | 
				
			||||||
	.set_dqblk	= dquot_set_dqblk
 | 
					 | 
				
			||||||
};
 | 
					 | 
				
			||||||
#endif
 | 
					#endif
 | 
				
			||||||
 | 
					
 | 
				
			||||||
static const struct super_operations ext4_sops = {
 | 
					static const struct super_operations ext4_sops = {
 | 
				
			||||||
| 
						 | 
					@ -3935,7 +3922,7 @@ static int ext4_fill_super(struct super_block *sb, void *data, int silent)
 | 
				
			||||||
#ifdef CONFIG_QUOTA
 | 
					#ifdef CONFIG_QUOTA
 | 
				
			||||||
	sb->dq_op = &ext4_quota_operations;
 | 
						sb->dq_op = &ext4_quota_operations;
 | 
				
			||||||
	if (EXT4_HAS_RO_COMPAT_FEATURE(sb, EXT4_FEATURE_RO_COMPAT_QUOTA))
 | 
						if (EXT4_HAS_RO_COMPAT_FEATURE(sb, EXT4_FEATURE_RO_COMPAT_QUOTA))
 | 
				
			||||||
		sb->s_qcop = &ext4_qctl_sysfile_operations;
 | 
							sb->s_qcop = &dquot_quotactl_sysfile_ops;
 | 
				
			||||||
	else
 | 
						else
 | 
				
			||||||
		sb->s_qcop = &ext4_qctl_operations;
 | 
							sb->s_qcop = &ext4_qctl_operations;
 | 
				
			||||||
	sb->s_quota_types = QTYPE_MASK_USR | QTYPE_MASK_GRP;
 | 
						sb->s_quota_types = QTYPE_MASK_USR | QTYPE_MASK_GRP;
 | 
				
			||||||
| 
						 | 
					@ -5288,21 +5275,6 @@ static int ext4_enable_quotas(struct super_block *sb)
 | 
				
			||||||
	return 0;
 | 
						return 0;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
/*
 | 
					 | 
				
			||||||
 * quota_on function that is used when QUOTA feature is set.
 | 
					 | 
				
			||||||
 */
 | 
					 | 
				
			||||||
static int ext4_quota_on_sysfile(struct super_block *sb, int type,
 | 
					 | 
				
			||||||
				 int format_id)
 | 
					 | 
				
			||||||
{
 | 
					 | 
				
			||||||
	if (!EXT4_HAS_RO_COMPAT_FEATURE(sb, EXT4_FEATURE_RO_COMPAT_QUOTA))
 | 
					 | 
				
			||||||
		return -EINVAL;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	/*
 | 
					 | 
				
			||||||
	 * USAGE was enabled at mount time. Only need to enable LIMITS now.
 | 
					 | 
				
			||||||
	 */
 | 
					 | 
				
			||||||
	return ext4_quota_enable(sb, type, format_id, DQUOT_LIMITS_ENABLED);
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
static int ext4_quota_off(struct super_block *sb, int type)
 | 
					static int ext4_quota_off(struct super_block *sb, int type)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
	struct inode *inode = sb_dqopt(sb)->files[type];
 | 
						struct inode *inode = sb_dqopt(sb)->files[type];
 | 
				
			||||||
| 
						 | 
					@ -5329,18 +5301,6 @@ out:
 | 
				
			||||||
	return dquot_quota_off(sb, type);
 | 
						return dquot_quota_off(sb, type);
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
/*
 | 
					 | 
				
			||||||
 * quota_off function that is used when QUOTA feature is set.
 | 
					 | 
				
			||||||
 */
 | 
					 | 
				
			||||||
static int ext4_quota_off_sysfile(struct super_block *sb, int type)
 | 
					 | 
				
			||||||
{
 | 
					 | 
				
			||||||
	if (!EXT4_HAS_RO_COMPAT_FEATURE(sb, EXT4_FEATURE_RO_COMPAT_QUOTA))
 | 
					 | 
				
			||||||
		return -EINVAL;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	/* Disable only the limits. */
 | 
					 | 
				
			||||||
	return dquot_disable(sb, type, DQUOT_LIMITS_ENABLED);
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
/* Read data from quotafile - avoid pagecache and such because we cannot afford
 | 
					/* Read data from quotafile - avoid pagecache and such because we cannot afford
 | 
				
			||||||
 * acquiring the locks... As quota files are never truncated and quota code
 | 
					 * acquiring the locks... As quota files are never truncated and quota code
 | 
				
			||||||
 * itself serializes the operations (and no one else should touch the files)
 | 
					 * itself serializes the operations (and no one else should touch the files)
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -2,6 +2,7 @@
 | 
				
			||||||
 *  linux/fs/isofs/util.c
 | 
					 *  linux/fs/isofs/util.c
 | 
				
			||||||
 */
 | 
					 */
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#include <linux/time.h>
 | 
				
			||||||
#include "isofs.h"
 | 
					#include "isofs.h"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
/* 
 | 
					/* 
 | 
				
			||||||
| 
						 | 
					@ -17,9 +18,9 @@
 | 
				
			||||||
int iso_date(char * p, int flag)
 | 
					int iso_date(char * p, int flag)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
	int year, month, day, hour, minute, second, tz;
 | 
						int year, month, day, hour, minute, second, tz;
 | 
				
			||||||
	int crtime, days, i;
 | 
						int crtime;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	year = p[0] - 70;
 | 
						year = p[0];
 | 
				
			||||||
	month = p[1];
 | 
						month = p[1];
 | 
				
			||||||
	day = p[2];
 | 
						day = p[2];
 | 
				
			||||||
	hour = p[3];
 | 
						hour = p[3];
 | 
				
			||||||
| 
						 | 
					@ -31,18 +32,7 @@ int iso_date(char * p, int flag)
 | 
				
			||||||
	if (year < 0) {
 | 
						if (year < 0) {
 | 
				
			||||||
		crtime = 0;
 | 
							crtime = 0;
 | 
				
			||||||
	} else {
 | 
						} else {
 | 
				
			||||||
		int monlen[12] = {31,28,31,30,31,30,31,31,30,31,30,31};
 | 
							crtime = mktime64(year+1900, month, day, hour, minute, second);
 | 
				
			||||||
 | 
					 | 
				
			||||||
		days = year * 365;
 | 
					 | 
				
			||||||
		if (year > 2)
 | 
					 | 
				
			||||||
			days += (year+1) / 4;
 | 
					 | 
				
			||||||
		for (i = 1; i < month; i++)
 | 
					 | 
				
			||||||
			days += monlen[i-1];
 | 
					 | 
				
			||||||
		if (((year+2) % 4) == 0 && month > 2)
 | 
					 | 
				
			||||||
			days++;
 | 
					 | 
				
			||||||
		days += day - 1;
 | 
					 | 
				
			||||||
		crtime = ((((days * 24) + hour) * 60 + minute) * 60)
 | 
					 | 
				
			||||||
			+ second;
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
		/* sign extend */
 | 
							/* sign extend */
 | 
				
			||||||
		if (tz & 0x80)
 | 
							if (tz & 0x80)
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -48,6 +48,7 @@ struct ocfs2_quota_recovery {
 | 
				
			||||||
/* In-memory structure with quota header information */
 | 
					/* In-memory structure with quota header information */
 | 
				
			||||||
struct ocfs2_mem_dqinfo {
 | 
					struct ocfs2_mem_dqinfo {
 | 
				
			||||||
	unsigned int dqi_type;		/* Quota type this structure describes */
 | 
						unsigned int dqi_type;		/* Quota type this structure describes */
 | 
				
			||||||
 | 
						unsigned int dqi_flags;		/* Flags OLQF_* */
 | 
				
			||||||
	unsigned int dqi_chunks;	/* Number of chunks in local quota file */
 | 
						unsigned int dqi_chunks;	/* Number of chunks in local quota file */
 | 
				
			||||||
	unsigned int dqi_blocks;	/* Number of blocks allocated for local quota file */
 | 
						unsigned int dqi_blocks;	/* Number of blocks allocated for local quota file */
 | 
				
			||||||
	unsigned int dqi_syncms;	/* How often should we sync with other nodes */
 | 
						unsigned int dqi_syncms;	/* How often should we sync with other nodes */
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -292,7 +292,7 @@ static void olq_update_info(struct buffer_head *bh, void *private)
 | 
				
			||||||
	ldinfo = (struct ocfs2_local_disk_dqinfo *)(bh->b_data +
 | 
						ldinfo = (struct ocfs2_local_disk_dqinfo *)(bh->b_data +
 | 
				
			||||||
						OCFS2_LOCAL_INFO_OFF);
 | 
											OCFS2_LOCAL_INFO_OFF);
 | 
				
			||||||
	spin_lock(&dq_data_lock);
 | 
						spin_lock(&dq_data_lock);
 | 
				
			||||||
	ldinfo->dqi_flags = cpu_to_le32(info->dqi_flags & DQF_MASK);
 | 
						ldinfo->dqi_flags = cpu_to_le32(oinfo->dqi_flags);
 | 
				
			||||||
	ldinfo->dqi_chunks = cpu_to_le32(oinfo->dqi_chunks);
 | 
						ldinfo->dqi_chunks = cpu_to_le32(oinfo->dqi_chunks);
 | 
				
			||||||
	ldinfo->dqi_blocks = cpu_to_le32(oinfo->dqi_blocks);
 | 
						ldinfo->dqi_blocks = cpu_to_le32(oinfo->dqi_blocks);
 | 
				
			||||||
	spin_unlock(&dq_data_lock);
 | 
						spin_unlock(&dq_data_lock);
 | 
				
			||||||
| 
						 | 
					@ -701,8 +701,8 @@ static int ocfs2_local_read_info(struct super_block *sb, int type)
 | 
				
			||||||
	/* We don't need the lock and we have to acquire quota file locks
 | 
						/* We don't need the lock and we have to acquire quota file locks
 | 
				
			||||||
	 * which will later depend on this lock */
 | 
						 * which will later depend on this lock */
 | 
				
			||||||
	mutex_unlock(&sb_dqopt(sb)->dqio_mutex);
 | 
						mutex_unlock(&sb_dqopt(sb)->dqio_mutex);
 | 
				
			||||||
	info->dqi_maxblimit = 0x7fffffffffffffffLL;
 | 
						info->dqi_max_spc_limit = 0x7fffffffffffffffLL;
 | 
				
			||||||
	info->dqi_maxilimit = 0x7fffffffffffffffLL;
 | 
						info->dqi_max_ino_limit = 0x7fffffffffffffffLL;
 | 
				
			||||||
	oinfo = kmalloc(sizeof(struct ocfs2_mem_dqinfo), GFP_NOFS);
 | 
						oinfo = kmalloc(sizeof(struct ocfs2_mem_dqinfo), GFP_NOFS);
 | 
				
			||||||
	if (!oinfo) {
 | 
						if (!oinfo) {
 | 
				
			||||||
		mlog(ML_ERROR, "failed to allocate memory for ocfs2 quota"
 | 
							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)
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
	ldinfo = (struct ocfs2_local_disk_dqinfo *)(bh->b_data +
 | 
						ldinfo = (struct ocfs2_local_disk_dqinfo *)(bh->b_data +
 | 
				
			||||||
						OCFS2_LOCAL_INFO_OFF);
 | 
											OCFS2_LOCAL_INFO_OFF);
 | 
				
			||||||
	info->dqi_flags = le32_to_cpu(ldinfo->dqi_flags);
 | 
						oinfo->dqi_flags = le32_to_cpu(ldinfo->dqi_flags);
 | 
				
			||||||
	oinfo->dqi_chunks = le32_to_cpu(ldinfo->dqi_chunks);
 | 
						oinfo->dqi_chunks = le32_to_cpu(ldinfo->dqi_chunks);
 | 
				
			||||||
	oinfo->dqi_blocks = le32_to_cpu(ldinfo->dqi_blocks);
 | 
						oinfo->dqi_blocks = le32_to_cpu(ldinfo->dqi_blocks);
 | 
				
			||||||
	oinfo->dqi_libh = bh;
 | 
						oinfo->dqi_libh = bh;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	/* We crashed when using local quota file? */
 | 
						/* We crashed when using local quota file? */
 | 
				
			||||||
	if (!(info->dqi_flags & OLQF_CLEAN)) {
 | 
						if (!(oinfo->dqi_flags & OLQF_CLEAN)) {
 | 
				
			||||||
		rec = OCFS2_SB(sb)->quota_rec;
 | 
							rec = OCFS2_SB(sb)->quota_rec;
 | 
				
			||||||
		if (!rec) {
 | 
							if (!rec) {
 | 
				
			||||||
			rec = ocfs2_alloc_quota_recovery();
 | 
								rec = ocfs2_alloc_quota_recovery();
 | 
				
			||||||
| 
						 | 
					@ -772,7 +772,7 @@ static int ocfs2_local_read_info(struct super_block *sb, int type)
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	/* Now mark quota file as used */
 | 
						/* Now mark quota file as used */
 | 
				
			||||||
	info->dqi_flags &= ~OLQF_CLEAN;
 | 
						oinfo->dqi_flags &= ~OLQF_CLEAN;
 | 
				
			||||||
	status = ocfs2_modify_bh(lqinode, bh, olq_update_info, info);
 | 
						status = ocfs2_modify_bh(lqinode, bh, olq_update_info, info);
 | 
				
			||||||
	if (status < 0) {
 | 
						if (status < 0) {
 | 
				
			||||||
		mlog_errno(status);
 | 
							mlog_errno(status);
 | 
				
			||||||
| 
						 | 
					@ -857,7 +857,7 @@ static int ocfs2_local_free_info(struct super_block *sb, int type)
 | 
				
			||||||
		goto out;
 | 
							goto out;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	/* Mark local file as clean */
 | 
						/* Mark local file as clean */
 | 
				
			||||||
	info->dqi_flags |= OLQF_CLEAN;
 | 
						oinfo->dqi_flags |= OLQF_CLEAN;
 | 
				
			||||||
	status = ocfs2_modify_bh(sb_dqopt(sb)->files[type],
 | 
						status = ocfs2_modify_bh(sb_dqopt(sb)->files[type],
 | 
				
			||||||
				 oinfo->dqi_libh,
 | 
									 oinfo->dqi_libh,
 | 
				
			||||||
				 olq_update_info,
 | 
									 olq_update_info,
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -1000,36 +1000,6 @@ static void ocfs2_disable_quotas(struct ocfs2_super *osb)
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
/* Handle quota on quotactl */
 | 
					 | 
				
			||||||
static int ocfs2_quota_on(struct super_block *sb, int type, int format_id)
 | 
					 | 
				
			||||||
{
 | 
					 | 
				
			||||||
	unsigned int feature[OCFS2_MAXQUOTAS] = {
 | 
					 | 
				
			||||||
					OCFS2_FEATURE_RO_COMPAT_USRQUOTA,
 | 
					 | 
				
			||||||
					OCFS2_FEATURE_RO_COMPAT_GRPQUOTA};
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	if (!OCFS2_HAS_RO_COMPAT_FEATURE(sb, feature[type]))
 | 
					 | 
				
			||||||
		return -EINVAL;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	return dquot_enable(sb_dqopt(sb)->files[type], type,
 | 
					 | 
				
			||||||
			    format_id, DQUOT_LIMITS_ENABLED);
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
/* Handle quota off quotactl */
 | 
					 | 
				
			||||||
static int ocfs2_quota_off(struct super_block *sb, int type)
 | 
					 | 
				
			||||||
{
 | 
					 | 
				
			||||||
	return dquot_disable(sb, type, DQUOT_LIMITS_ENABLED);
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
static const struct quotactl_ops ocfs2_quotactl_ops = {
 | 
					 | 
				
			||||||
	.quota_on_meta	= ocfs2_quota_on,
 | 
					 | 
				
			||||||
	.quota_off	= ocfs2_quota_off,
 | 
					 | 
				
			||||||
	.quota_sync	= dquot_quota_sync,
 | 
					 | 
				
			||||||
	.get_info	= dquot_get_dqinfo,
 | 
					 | 
				
			||||||
	.set_info	= dquot_set_dqinfo,
 | 
					 | 
				
			||||||
	.get_dqblk	= dquot_get_dqblk,
 | 
					 | 
				
			||||||
	.set_dqblk	= dquot_set_dqblk,
 | 
					 | 
				
			||||||
};
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
static int ocfs2_fill_super(struct super_block *sb, void *data, int silent)
 | 
					static int ocfs2_fill_super(struct super_block *sb, void *data, int silent)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
	struct dentry *root;
 | 
						struct dentry *root;
 | 
				
			||||||
| 
						 | 
					@ -2079,7 +2049,7 @@ static int ocfs2_initialize_super(struct super_block *sb,
 | 
				
			||||||
	sb->s_op = &ocfs2_sops;
 | 
						sb->s_op = &ocfs2_sops;
 | 
				
			||||||
	sb->s_d_op = &ocfs2_dentry_ops;
 | 
						sb->s_d_op = &ocfs2_dentry_ops;
 | 
				
			||||||
	sb->s_export_op = &ocfs2_export_ops;
 | 
						sb->s_export_op = &ocfs2_export_ops;
 | 
				
			||||||
	sb->s_qcop = &ocfs2_quotactl_ops;
 | 
						sb->s_qcop = &dquot_quotactl_sysfile_ops;
 | 
				
			||||||
	sb->dq_op = &ocfs2_quota_operations;
 | 
						sb->dq_op = &ocfs2_quota_operations;
 | 
				
			||||||
	sb->s_quota_types = QTYPE_MASK_USR | QTYPE_MASK_GRP;
 | 
						sb->s_quota_types = QTYPE_MASK_USR | QTYPE_MASK_GRP;
 | 
				
			||||||
	sb->s_xattr = ocfs2_xattr_handlers;
 | 
						sb->s_xattr = ocfs2_xattr_handlers;
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
							
								
								
									
										107
									
								
								fs/quota/dquot.c
									
										
									
									
									
								
							
							
						
						
									
										107
									
								
								fs/quota/dquot.c
									
										
									
									
									
								
							| 
						 | 
					@ -1248,7 +1248,7 @@ static int ignore_hardlimit(struct dquot *dquot)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	return capable(CAP_SYS_RESOURCE) &&
 | 
						return capable(CAP_SYS_RESOURCE) &&
 | 
				
			||||||
	       (info->dqi_format->qf_fmt_id != QFMT_VFS_OLD ||
 | 
						       (info->dqi_format->qf_fmt_id != QFMT_VFS_OLD ||
 | 
				
			||||||
		!(info->dqi_flags & V1_DQF_RSQUASH));
 | 
							!(info->dqi_flags & DQF_ROOT_SQUASH));
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
/* needs dq_data_lock */
 | 
					/* needs dq_data_lock */
 | 
				
			||||||
| 
						 | 
					@ -2385,14 +2385,84 @@ out:
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
EXPORT_SYMBOL(dquot_quota_on_mount);
 | 
					EXPORT_SYMBOL(dquot_quota_on_mount);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
static inline qsize_t qbtos(qsize_t blocks)
 | 
					static int dquot_quota_enable(struct super_block *sb, unsigned int flags)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
	return blocks << QIF_DQBLKSIZE_BITS;
 | 
						int ret;
 | 
				
			||||||
 | 
						int type;
 | 
				
			||||||
 | 
						struct quota_info *dqopt = sb_dqopt(sb);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						if (!(dqopt->flags & DQUOT_QUOTA_SYS_FILE))
 | 
				
			||||||
 | 
							return -ENOSYS;
 | 
				
			||||||
 | 
						/* Accounting cannot be turned on while fs is mounted */
 | 
				
			||||||
 | 
						flags &= ~(FS_QUOTA_UDQ_ACCT | FS_QUOTA_GDQ_ACCT | FS_QUOTA_PDQ_ACCT);
 | 
				
			||||||
 | 
						if (!flags)
 | 
				
			||||||
 | 
							return -EINVAL;
 | 
				
			||||||
 | 
						for (type = 0; type < MAXQUOTAS; type++) {
 | 
				
			||||||
 | 
							if (!(flags & qtype_enforce_flag(type)))
 | 
				
			||||||
 | 
								continue;
 | 
				
			||||||
 | 
							/* Can't enforce without accounting */
 | 
				
			||||||
 | 
							if (!sb_has_quota_usage_enabled(sb, type))
 | 
				
			||||||
 | 
								return -EINVAL;
 | 
				
			||||||
 | 
							ret = dquot_enable(dqopt->files[type], type,
 | 
				
			||||||
 | 
									   dqopt->info[type].dqi_fmt_id,
 | 
				
			||||||
 | 
									   DQUOT_LIMITS_ENABLED);
 | 
				
			||||||
 | 
							if (ret < 0)
 | 
				
			||||||
 | 
								goto out_err;
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						return 0;
 | 
				
			||||||
 | 
					out_err:
 | 
				
			||||||
 | 
						/* Backout enforcement enablement we already did */
 | 
				
			||||||
 | 
						for (type--; type >= 0; type--)  {
 | 
				
			||||||
 | 
							if (flags & qtype_enforce_flag(type))
 | 
				
			||||||
 | 
								dquot_disable(sb, type, DQUOT_LIMITS_ENABLED);
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						/* Error code translation for better compatibility with XFS */
 | 
				
			||||||
 | 
						if (ret == -EBUSY)
 | 
				
			||||||
 | 
							ret = -EEXIST;
 | 
				
			||||||
 | 
						return ret;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
static inline qsize_t stoqb(qsize_t space)
 | 
					static int dquot_quota_disable(struct super_block *sb, unsigned int flags)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
	return (space + QIF_DQBLKSIZE - 1) >> QIF_DQBLKSIZE_BITS;
 | 
						int ret;
 | 
				
			||||||
 | 
						int type;
 | 
				
			||||||
 | 
						struct quota_info *dqopt = sb_dqopt(sb);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						if (!(dqopt->flags & DQUOT_QUOTA_SYS_FILE))
 | 
				
			||||||
 | 
							return -ENOSYS;
 | 
				
			||||||
 | 
						/*
 | 
				
			||||||
 | 
						 * We don't support turning off accounting via quotactl. In principle
 | 
				
			||||||
 | 
						 * quota infrastructure can do this but filesystems don't expect
 | 
				
			||||||
 | 
						 * userspace to be able to do it.
 | 
				
			||||||
 | 
						 */
 | 
				
			||||||
 | 
						if (flags &
 | 
				
			||||||
 | 
							  (FS_QUOTA_UDQ_ACCT | FS_QUOTA_GDQ_ACCT | FS_QUOTA_PDQ_ACCT))
 | 
				
			||||||
 | 
							return -EOPNOTSUPP;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						/* Filter out limits not enabled */
 | 
				
			||||||
 | 
						for (type = 0; type < MAXQUOTAS; type++)
 | 
				
			||||||
 | 
							if (!sb_has_quota_limits_enabled(sb, type))
 | 
				
			||||||
 | 
								flags &= ~qtype_enforce_flag(type);
 | 
				
			||||||
 | 
						/* Nothing left? */
 | 
				
			||||||
 | 
						if (!flags)
 | 
				
			||||||
 | 
							return -EEXIST;
 | 
				
			||||||
 | 
						for (type = 0; type < MAXQUOTAS; type++) {
 | 
				
			||||||
 | 
							if (flags & qtype_enforce_flag(type)) {
 | 
				
			||||||
 | 
								ret = dquot_disable(sb, type, DQUOT_LIMITS_ENABLED);
 | 
				
			||||||
 | 
								if (ret < 0)
 | 
				
			||||||
 | 
									goto out_err;
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						return 0;
 | 
				
			||||||
 | 
					out_err:
 | 
				
			||||||
 | 
						/* Backout enforcement disabling we already did */
 | 
				
			||||||
 | 
						for (type--; type >= 0; type--)  {
 | 
				
			||||||
 | 
							if (flags & qtype_enforce_flag(type))
 | 
				
			||||||
 | 
								dquot_enable(dqopt->files[type], type,
 | 
				
			||||||
 | 
									     dqopt->info[type].dqi_fmt_id,
 | 
				
			||||||
 | 
									     DQUOT_LIMITS_ENABLED);
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						return ret;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
/* Generic routine for getting common part of quota structure */
 | 
					/* 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)
 | 
				
			||||||
		return -EINVAL;
 | 
							return -EINVAL;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	if (((di->d_fieldmask & QC_SPC_SOFT) &&
 | 
						if (((di->d_fieldmask & QC_SPC_SOFT) &&
 | 
				
			||||||
	     stoqb(di->d_spc_softlimit) > dqi->dqi_maxblimit) ||
 | 
						     di->d_spc_softlimit > dqi->dqi_max_spc_limit) ||
 | 
				
			||||||
	    ((di->d_fieldmask & QC_SPC_HARD) &&
 | 
						    ((di->d_fieldmask & QC_SPC_HARD) &&
 | 
				
			||||||
	     stoqb(di->d_spc_hardlimit) > dqi->dqi_maxblimit) ||
 | 
						     di->d_spc_hardlimit > dqi->dqi_max_spc_limit) ||
 | 
				
			||||||
	    ((di->d_fieldmask & QC_INO_SOFT) &&
 | 
						    ((di->d_fieldmask & QC_INO_SOFT) &&
 | 
				
			||||||
	     (di->d_ino_softlimit > dqi->dqi_maxilimit)) ||
 | 
						     (di->d_ino_softlimit > dqi->dqi_max_ino_limit)) ||
 | 
				
			||||||
	    ((di->d_fieldmask & QC_INO_HARD) &&
 | 
						    ((di->d_fieldmask & QC_INO_HARD) &&
 | 
				
			||||||
	     (di->d_ino_hardlimit > dqi->dqi_maxilimit)))
 | 
						     (di->d_ino_hardlimit > dqi->dqi_max_ino_limit)))
 | 
				
			||||||
		return -ERANGE;
 | 
							return -ERANGE;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	spin_lock(&dq_data_lock);
 | 
						spin_lock(&dq_data_lock);
 | 
				
			||||||
| 
						 | 
					@ -2577,6 +2647,14 @@ int dquot_set_dqinfo(struct super_block *sb, int type, struct if_dqinfo *ii)
 | 
				
			||||||
		goto out;
 | 
							goto out;
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
	mi = sb_dqopt(sb)->info + type;
 | 
						mi = sb_dqopt(sb)->info + type;
 | 
				
			||||||
 | 
						if (ii->dqi_valid & IIF_FLAGS) {
 | 
				
			||||||
 | 
							if (ii->dqi_flags & ~DQF_SETINFO_MASK ||
 | 
				
			||||||
 | 
							    (ii->dqi_flags & DQF_ROOT_SQUASH &&
 | 
				
			||||||
 | 
							     mi->dqi_format->qf_fmt_id != QFMT_VFS_OLD)) {
 | 
				
			||||||
 | 
								err = -EINVAL;
 | 
				
			||||||
 | 
								goto out;
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
	spin_lock(&dq_data_lock);
 | 
						spin_lock(&dq_data_lock);
 | 
				
			||||||
	if (ii->dqi_valid & IIF_BGRACE)
 | 
						if (ii->dqi_valid & IIF_BGRACE)
 | 
				
			||||||
		mi->dqi_bgrace = ii->dqi_bgrace;
 | 
							mi->dqi_bgrace = ii->dqi_bgrace;
 | 
				
			||||||
| 
						 | 
					@ -2606,6 +2684,17 @@ const struct quotactl_ops dquot_quotactl_ops = {
 | 
				
			||||||
};
 | 
					};
 | 
				
			||||||
EXPORT_SYMBOL(dquot_quotactl_ops);
 | 
					EXPORT_SYMBOL(dquot_quotactl_ops);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					const struct quotactl_ops dquot_quotactl_sysfile_ops = {
 | 
				
			||||||
 | 
						.quota_enable	= dquot_quota_enable,
 | 
				
			||||||
 | 
						.quota_disable	= dquot_quota_disable,
 | 
				
			||||||
 | 
						.quota_sync	= dquot_quota_sync,
 | 
				
			||||||
 | 
						.get_info	= dquot_get_dqinfo,
 | 
				
			||||||
 | 
						.set_info	= dquot_set_dqinfo,
 | 
				
			||||||
 | 
						.get_dqblk	= dquot_get_dqblk,
 | 
				
			||||||
 | 
						.set_dqblk	= dquot_set_dqblk
 | 
				
			||||||
 | 
					};
 | 
				
			||||||
 | 
					EXPORT_SYMBOL(dquot_quotactl_sysfile_ops);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
static int do_proc_dqstats(struct ctl_table *table, int write,
 | 
					static int do_proc_dqstats(struct ctl_table *table, int write,
 | 
				
			||||||
		     void __user *buffer, size_t *lenp, loff_t *ppos)
 | 
							     void __user *buffer, size_t *lenp, loff_t *ppos)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -66,18 +66,40 @@ static int quota_sync_all(int type)
 | 
				
			||||||
	return ret;
 | 
						return ret;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					unsigned int qtype_enforce_flag(int type)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						switch (type) {
 | 
				
			||||||
 | 
						case USRQUOTA:
 | 
				
			||||||
 | 
							return FS_QUOTA_UDQ_ENFD;
 | 
				
			||||||
 | 
						case GRPQUOTA:
 | 
				
			||||||
 | 
							return FS_QUOTA_GDQ_ENFD;
 | 
				
			||||||
 | 
						case PRJQUOTA:
 | 
				
			||||||
 | 
							return FS_QUOTA_PDQ_ENFD;
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						return 0;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
static int quota_quotaon(struct super_block *sb, int type, int cmd, qid_t id,
 | 
					static int quota_quotaon(struct super_block *sb, int type, int cmd, qid_t id,
 | 
				
			||||||
		         struct path *path)
 | 
							         struct path *path)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
	if (!sb->s_qcop->quota_on && !sb->s_qcop->quota_on_meta)
 | 
						if (!sb->s_qcop->quota_on && !sb->s_qcop->quota_enable)
 | 
				
			||||||
		return -ENOSYS;
 | 
							return -ENOSYS;
 | 
				
			||||||
	if (sb->s_qcop->quota_on_meta)
 | 
						if (sb->s_qcop->quota_enable)
 | 
				
			||||||
		return sb->s_qcop->quota_on_meta(sb, type, id);
 | 
							return sb->s_qcop->quota_enable(sb, qtype_enforce_flag(type));
 | 
				
			||||||
	if (IS_ERR(path))
 | 
						if (IS_ERR(path))
 | 
				
			||||||
		return PTR_ERR(path);
 | 
							return PTR_ERR(path);
 | 
				
			||||||
	return sb->s_qcop->quota_on(sb, type, id, path);
 | 
						return sb->s_qcop->quota_on(sb, type, id, path);
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					static int quota_quotaoff(struct super_block *sb, int type)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						if (!sb->s_qcop->quota_off && !sb->s_qcop->quota_disable)
 | 
				
			||||||
 | 
							return -ENOSYS;
 | 
				
			||||||
 | 
						if (sb->s_qcop->quota_disable)
 | 
				
			||||||
 | 
							return sb->s_qcop->quota_disable(sb, qtype_enforce_flag(type));
 | 
				
			||||||
 | 
						return sb->s_qcop->quota_off(sb, type);
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
static int quota_getfmt(struct super_block *sb, int type, void __user *addr)
 | 
					static int quota_getfmt(struct super_block *sb, int type, void __user *addr)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
	__u32 fmt;
 | 
						__u32 fmt;
 | 
				
			||||||
| 
						 | 
					@ -208,15 +230,26 @@ static int quota_setquota(struct super_block *sb, int type, qid_t id,
 | 
				
			||||||
	return sb->s_qcop->set_dqblk(sb, qid, &fdq);
 | 
						return sb->s_qcop->set_dqblk(sb, qid, &fdq);
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
static int quota_setxstate(struct super_block *sb, int cmd, void __user *addr)
 | 
					static int quota_enable(struct super_block *sb, void __user *addr)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
	__u32 flags;
 | 
						__u32 flags;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	if (copy_from_user(&flags, addr, sizeof(flags)))
 | 
						if (copy_from_user(&flags, addr, sizeof(flags)))
 | 
				
			||||||
		return -EFAULT;
 | 
							return -EFAULT;
 | 
				
			||||||
	if (!sb->s_qcop->set_xstate)
 | 
						if (!sb->s_qcop->quota_enable)
 | 
				
			||||||
		return -ENOSYS;
 | 
							return -ENOSYS;
 | 
				
			||||||
	return sb->s_qcop->set_xstate(sb, flags, cmd);
 | 
						return sb->s_qcop->quota_enable(sb, flags);
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					static int quota_disable(struct super_block *sb, void __user *addr)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						__u32 flags;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						if (copy_from_user(&flags, addr, sizeof(flags)))
 | 
				
			||||||
 | 
							return -EFAULT;
 | 
				
			||||||
 | 
						if (!sb->s_qcop->quota_disable)
 | 
				
			||||||
 | 
							return -ENOSYS;
 | 
				
			||||||
 | 
						return sb->s_qcop->quota_disable(sb, flags);
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
static int quota_getxstate(struct super_block *sb, void __user *addr)
 | 
					static 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,
 | 
				
			||||||
	case Q_QUOTAON:
 | 
						case Q_QUOTAON:
 | 
				
			||||||
		return quota_quotaon(sb, type, cmd, id, path);
 | 
							return quota_quotaon(sb, type, cmd, id, path);
 | 
				
			||||||
	case Q_QUOTAOFF:
 | 
						case Q_QUOTAOFF:
 | 
				
			||||||
		if (!sb->s_qcop->quota_off)
 | 
							return quota_quotaoff(sb, type);
 | 
				
			||||||
			return -ENOSYS;
 | 
					 | 
				
			||||||
		return sb->s_qcop->quota_off(sb, type);
 | 
					 | 
				
			||||||
	case Q_GETFMT:
 | 
						case Q_GETFMT:
 | 
				
			||||||
		return quota_getfmt(sb, type, addr);
 | 
							return quota_getfmt(sb, type, addr);
 | 
				
			||||||
	case Q_GETINFO:
 | 
						case Q_GETINFO:
 | 
				
			||||||
| 
						 | 
					@ -447,8 +478,9 @@ static int do_quotactl(struct super_block *sb, int type, int cmd, qid_t id,
 | 
				
			||||||
			return -ENOSYS;
 | 
								return -ENOSYS;
 | 
				
			||||||
		return sb->s_qcop->quota_sync(sb, type);
 | 
							return sb->s_qcop->quota_sync(sb, type);
 | 
				
			||||||
	case Q_XQUOTAON:
 | 
						case Q_XQUOTAON:
 | 
				
			||||||
 | 
							return quota_enable(sb, addr);
 | 
				
			||||||
	case Q_XQUOTAOFF:
 | 
						case Q_XQUOTAOFF:
 | 
				
			||||||
		return quota_setxstate(sb, cmd, addr);
 | 
							return quota_disable(sb, addr);
 | 
				
			||||||
	case Q_XQUOTARM:
 | 
						case Q_XQUOTARM:
 | 
				
			||||||
		return quota_rmxquota(sb, addr);
 | 
							return quota_rmxquota(sb, addr);
 | 
				
			||||||
	case Q_XGETQSTAT:
 | 
						case Q_XGETQSTAT:
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -169,8 +169,8 @@ static int v1_read_file_info(struct super_block *sb, int type)
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
	ret = 0;
 | 
						ret = 0;
 | 
				
			||||||
	/* limits are stored as unsigned 32-bit data */
 | 
						/* limits are stored as unsigned 32-bit data */
 | 
				
			||||||
	dqopt->info[type].dqi_maxblimit = 0xffffffff;
 | 
						dqopt->info[type].dqi_max_spc_limit = 0xffffffffULL << QUOTABLOCK_BITS;
 | 
				
			||||||
	dqopt->info[type].dqi_maxilimit = 0xffffffff;
 | 
						dqopt->info[type].dqi_max_ino_limit = 0xffffffff;
 | 
				
			||||||
	dqopt->info[type].dqi_igrace =
 | 
						dqopt->info[type].dqi_igrace =
 | 
				
			||||||
			dqblk.dqb_itime ? dqblk.dqb_itime : MAX_IQ_TIME;
 | 
								dqblk.dqb_itime ? dqblk.dqb_itime : MAX_IQ_TIME;
 | 
				
			||||||
	dqopt->info[type].dqi_bgrace =
 | 
						dqopt->info[type].dqi_bgrace =
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -117,16 +117,17 @@ static int v2_read_file_info(struct super_block *sb, int type)
 | 
				
			||||||
	qinfo = info->dqi_priv;
 | 
						qinfo = info->dqi_priv;
 | 
				
			||||||
	if (version == 0) {
 | 
						if (version == 0) {
 | 
				
			||||||
		/* limits are stored as unsigned 32-bit data */
 | 
							/* limits are stored as unsigned 32-bit data */
 | 
				
			||||||
		info->dqi_maxblimit = 0xffffffff;
 | 
							info->dqi_max_spc_limit = 0xffffffffULL << QUOTABLOCK_BITS;
 | 
				
			||||||
		info->dqi_maxilimit = 0xffffffff;
 | 
							info->dqi_max_ino_limit = 0xffffffff;
 | 
				
			||||||
	} else {
 | 
						} else {
 | 
				
			||||||
		/* used space is stored as unsigned 64-bit value */
 | 
							/* used space is stored as unsigned 64-bit value in bytes */
 | 
				
			||||||
		info->dqi_maxblimit = 0xffffffffffffffffULL;	/* 2^64-1 */
 | 
							info->dqi_max_spc_limit = 0xffffffffffffffffULL; /* 2^64-1 */
 | 
				
			||||||
		info->dqi_maxilimit = 0xffffffffffffffffULL;
 | 
							info->dqi_max_ino_limit = 0xffffffffffffffffULL;
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
	info->dqi_bgrace = le32_to_cpu(dinfo.dqi_bgrace);
 | 
						info->dqi_bgrace = le32_to_cpu(dinfo.dqi_bgrace);
 | 
				
			||||||
	info->dqi_igrace = le32_to_cpu(dinfo.dqi_igrace);
 | 
						info->dqi_igrace = le32_to_cpu(dinfo.dqi_igrace);
 | 
				
			||||||
	info->dqi_flags = le32_to_cpu(dinfo.dqi_flags);
 | 
						/* No flags currently supported */
 | 
				
			||||||
 | 
						info->dqi_flags = 0;
 | 
				
			||||||
	qinfo->dqi_sb = sb;
 | 
						qinfo->dqi_sb = sb;
 | 
				
			||||||
	qinfo->dqi_type = type;
 | 
						qinfo->dqi_type = type;
 | 
				
			||||||
	qinfo->dqi_blocks = le32_to_cpu(dinfo.dqi_blocks);
 | 
						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)
 | 
				
			||||||
	info->dqi_flags &= ~DQF_INFO_DIRTY;
 | 
						info->dqi_flags &= ~DQF_INFO_DIRTY;
 | 
				
			||||||
	dinfo.dqi_bgrace = cpu_to_le32(info->dqi_bgrace);
 | 
						dinfo.dqi_bgrace = cpu_to_le32(info->dqi_bgrace);
 | 
				
			||||||
	dinfo.dqi_igrace = cpu_to_le32(info->dqi_igrace);
 | 
						dinfo.dqi_igrace = cpu_to_le32(info->dqi_igrace);
 | 
				
			||||||
	dinfo.dqi_flags = cpu_to_le32(info->dqi_flags & DQF_MASK);
 | 
						/* No flags currently supported */
 | 
				
			||||||
 | 
						dinfo.dqi_flags = cpu_to_le32(0);
 | 
				
			||||||
	spin_unlock(&dq_data_lock);
 | 
						spin_unlock(&dq_data_lock);
 | 
				
			||||||
	dinfo.dqi_blocks = cpu_to_le32(qinfo->dqi_blocks);
 | 
						dinfo.dqi_blocks = cpu_to_le32(qinfo->dqi_blocks);
 | 
				
			||||||
	dinfo.dqi_free_blk = cpu_to_le32(qinfo->dqi_free_blk);
 | 
						dinfo.dqi_free_blk = cpu_to_le32(qinfo->dqi_free_blk);
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -2,10 +2,12 @@ config UDF_FS
 | 
				
			||||||
	tristate "UDF file system support"
 | 
						tristate "UDF file system support"
 | 
				
			||||||
	select CRC_ITU_T
 | 
						select CRC_ITU_T
 | 
				
			||||||
	help
 | 
						help
 | 
				
			||||||
	  This is the new file system used on some CD-ROMs and DVDs. Say Y if
 | 
						  This is a file system used on some CD-ROMs and DVDs. Since the
 | 
				
			||||||
	  you intend to mount DVD discs or CDRW's written in packet mode, or
 | 
						  file system is supported by multiple operating systems and is more
 | 
				
			||||||
	  if written to by other UDF utilities, such as DirectCD.
 | 
						  compatible with standard unix file systems, it is also suitable for
 | 
				
			||||||
	  Please read <file:Documentation/filesystems/udf.txt>.
 | 
						  removable USB disks. Say Y if you intend to mount DVD discs or CDRW's
 | 
				
			||||||
 | 
						  written in packet mode, or if you want to use UDF for removable USB
 | 
				
			||||||
 | 
						  disks. Please read <file:Documentation/filesystems/udf.txt>.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	  To compile this file system support as a module, choose M here: the
 | 
						  To compile this file system support as a module, choose M here: the
 | 
				
			||||||
	  module will be called udf.
 | 
						  module will be called udf.
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -750,7 +750,7 @@ static sector_t inode_getblk(struct inode *inode, sector_t block,
 | 
				
			||||||
	/* Are we beyond EOF? */
 | 
						/* Are we beyond EOF? */
 | 
				
			||||||
	if (etype == -1) {
 | 
						if (etype == -1) {
 | 
				
			||||||
		int ret;
 | 
							int ret;
 | 
				
			||||||
		isBeyondEOF = 1;
 | 
							isBeyondEOF = true;
 | 
				
			||||||
		if (count) {
 | 
							if (count) {
 | 
				
			||||||
			if (c)
 | 
								if (c)
 | 
				
			||||||
				laarr[0] = laarr[1];
 | 
									laarr[0] = laarr[1];
 | 
				
			||||||
| 
						 | 
					@ -792,7 +792,7 @@ static sector_t inode_getblk(struct inode *inode, sector_t block,
 | 
				
			||||||
		endnum = c + 1;
 | 
							endnum = c + 1;
 | 
				
			||||||
		lastblock = 1;
 | 
							lastblock = 1;
 | 
				
			||||||
	} else {
 | 
						} else {
 | 
				
			||||||
		isBeyondEOF = 0;
 | 
							isBeyondEOF = false;
 | 
				
			||||||
		endnum = startnum = ((count > 2) ? 2 : count);
 | 
							endnum = startnum = ((count > 2) ? 2 : count);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		/* if the current extent is in position 0,
 | 
							/* if the current extent is in position 0,
 | 
				
			||||||
| 
						 | 
					@ -1288,6 +1288,7 @@ static int udf_read_inode(struct inode *inode, bool hidden_inode)
 | 
				
			||||||
	struct kernel_lb_addr *iloc = &iinfo->i_location;
 | 
						struct kernel_lb_addr *iloc = &iinfo->i_location;
 | 
				
			||||||
	unsigned int link_count;
 | 
						unsigned int link_count;
 | 
				
			||||||
	unsigned int indirections = 0;
 | 
						unsigned int indirections = 0;
 | 
				
			||||||
 | 
						int bs = inode->i_sb->s_blocksize;
 | 
				
			||||||
	int ret = -EIO;
 | 
						int ret = -EIO;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
reread:
 | 
					reread:
 | 
				
			||||||
| 
						 | 
					@ -1374,38 +1375,35 @@ reread:
 | 
				
			||||||
	if (fe->descTag.tagIdent == cpu_to_le16(TAG_IDENT_EFE)) {
 | 
						if (fe->descTag.tagIdent == cpu_to_le16(TAG_IDENT_EFE)) {
 | 
				
			||||||
		iinfo->i_efe = 1;
 | 
							iinfo->i_efe = 1;
 | 
				
			||||||
		iinfo->i_use = 0;
 | 
							iinfo->i_use = 0;
 | 
				
			||||||
		ret = udf_alloc_i_data(inode, inode->i_sb->s_blocksize -
 | 
							ret = udf_alloc_i_data(inode, bs -
 | 
				
			||||||
					sizeof(struct extendedFileEntry));
 | 
										sizeof(struct extendedFileEntry));
 | 
				
			||||||
		if (ret)
 | 
							if (ret)
 | 
				
			||||||
			goto out;
 | 
								goto out;
 | 
				
			||||||
		memcpy(iinfo->i_ext.i_data,
 | 
							memcpy(iinfo->i_ext.i_data,
 | 
				
			||||||
		       bh->b_data + sizeof(struct extendedFileEntry),
 | 
							       bh->b_data + sizeof(struct extendedFileEntry),
 | 
				
			||||||
		       inode->i_sb->s_blocksize -
 | 
							       bs - sizeof(struct extendedFileEntry));
 | 
				
			||||||
					sizeof(struct extendedFileEntry));
 | 
					 | 
				
			||||||
	} else if (fe->descTag.tagIdent == cpu_to_le16(TAG_IDENT_FE)) {
 | 
						} else if (fe->descTag.tagIdent == cpu_to_le16(TAG_IDENT_FE)) {
 | 
				
			||||||
		iinfo->i_efe = 0;
 | 
							iinfo->i_efe = 0;
 | 
				
			||||||
		iinfo->i_use = 0;
 | 
							iinfo->i_use = 0;
 | 
				
			||||||
		ret = udf_alloc_i_data(inode, inode->i_sb->s_blocksize -
 | 
							ret = udf_alloc_i_data(inode, bs - sizeof(struct fileEntry));
 | 
				
			||||||
						sizeof(struct fileEntry));
 | 
					 | 
				
			||||||
		if (ret)
 | 
							if (ret)
 | 
				
			||||||
			goto out;
 | 
								goto out;
 | 
				
			||||||
		memcpy(iinfo->i_ext.i_data,
 | 
							memcpy(iinfo->i_ext.i_data,
 | 
				
			||||||
		       bh->b_data + sizeof(struct fileEntry),
 | 
							       bh->b_data + sizeof(struct fileEntry),
 | 
				
			||||||
		       inode->i_sb->s_blocksize - sizeof(struct fileEntry));
 | 
							       bs - sizeof(struct fileEntry));
 | 
				
			||||||
	} else if (fe->descTag.tagIdent == cpu_to_le16(TAG_IDENT_USE)) {
 | 
						} else if (fe->descTag.tagIdent == cpu_to_le16(TAG_IDENT_USE)) {
 | 
				
			||||||
		iinfo->i_efe = 0;
 | 
							iinfo->i_efe = 0;
 | 
				
			||||||
		iinfo->i_use = 1;
 | 
							iinfo->i_use = 1;
 | 
				
			||||||
		iinfo->i_lenAlloc = le32_to_cpu(
 | 
							iinfo->i_lenAlloc = le32_to_cpu(
 | 
				
			||||||
				((struct unallocSpaceEntry *)bh->b_data)->
 | 
									((struct unallocSpaceEntry *)bh->b_data)->
 | 
				
			||||||
				 lengthAllocDescs);
 | 
									 lengthAllocDescs);
 | 
				
			||||||
		ret = udf_alloc_i_data(inode, inode->i_sb->s_blocksize -
 | 
							ret = udf_alloc_i_data(inode, bs -
 | 
				
			||||||
					sizeof(struct unallocSpaceEntry));
 | 
										sizeof(struct unallocSpaceEntry));
 | 
				
			||||||
		if (ret)
 | 
							if (ret)
 | 
				
			||||||
			goto out;
 | 
								goto out;
 | 
				
			||||||
		memcpy(iinfo->i_ext.i_data,
 | 
							memcpy(iinfo->i_ext.i_data,
 | 
				
			||||||
		       bh->b_data + sizeof(struct unallocSpaceEntry),
 | 
							       bh->b_data + sizeof(struct unallocSpaceEntry),
 | 
				
			||||||
		       inode->i_sb->s_blocksize -
 | 
							       bs - sizeof(struct unallocSpaceEntry));
 | 
				
			||||||
					sizeof(struct unallocSpaceEntry));
 | 
					 | 
				
			||||||
		return 0;
 | 
							return 0;
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					@ -1489,6 +1487,15 @@ reread:
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
	inode->i_generation = iinfo->i_unique;
 | 
						inode->i_generation = iinfo->i_unique;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						/*
 | 
				
			||||||
 | 
						 * Sanity check length of allocation descriptors and extended attrs to
 | 
				
			||||||
 | 
						 * avoid integer overflows
 | 
				
			||||||
 | 
						 */
 | 
				
			||||||
 | 
						if (iinfo->i_lenEAttr > bs || iinfo->i_lenAlloc > bs)
 | 
				
			||||||
 | 
							goto out;
 | 
				
			||||||
 | 
						/* Now do exact checks */
 | 
				
			||||||
 | 
						if (udf_file_entry_alloc_offset(inode) + iinfo->i_lenAlloc > bs)
 | 
				
			||||||
 | 
							goto out;
 | 
				
			||||||
	/* Sanity checks for files in ICB so that we don't get confused later */
 | 
						/* Sanity checks for files in ICB so that we don't get confused later */
 | 
				
			||||||
	if (iinfo->i_alloc_type == ICBTAG_FLAG_AD_IN_ICB) {
 | 
						if (iinfo->i_alloc_type == ICBTAG_FLAG_AD_IN_ICB) {
 | 
				
			||||||
		/*
 | 
							/*
 | 
				
			||||||
| 
						 | 
					@ -1498,8 +1505,7 @@ reread:
 | 
				
			||||||
		if (iinfo->i_lenAlloc != inode->i_size)
 | 
							if (iinfo->i_lenAlloc != inode->i_size)
 | 
				
			||||||
			goto out;
 | 
								goto out;
 | 
				
			||||||
		/* File in ICB has to fit in there... */
 | 
							/* File in ICB has to fit in there... */
 | 
				
			||||||
		if (inode->i_size > inode->i_sb->s_blocksize -
 | 
							if (inode->i_size > bs - udf_file_entry_alloc_offset(inode))
 | 
				
			||||||
					udf_file_entry_alloc_offset(inode))
 | 
					 | 
				
			||||||
			goto out;
 | 
								goto out;
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -1599,7 +1599,7 @@ static noinline int udf_process_sequence(
 | 
				
			||||||
	struct udf_vds_record *curr;
 | 
						struct udf_vds_record *curr;
 | 
				
			||||||
	struct generic_desc *gd;
 | 
						struct generic_desc *gd;
 | 
				
			||||||
	struct volDescPtr *vdp;
 | 
						struct volDescPtr *vdp;
 | 
				
			||||||
	int done = 0;
 | 
						bool done = false;
 | 
				
			||||||
	uint32_t vdsn;
 | 
						uint32_t vdsn;
 | 
				
			||||||
	uint16_t ident;
 | 
						uint16_t ident;
 | 
				
			||||||
	long next_s = 0, next_e = 0;
 | 
						long next_s = 0, next_e = 0;
 | 
				
			||||||
| 
						 | 
					@ -1680,7 +1680,7 @@ static noinline int udf_process_sequence(
 | 
				
			||||||
				lastblock = next_e;
 | 
									lastblock = next_e;
 | 
				
			||||||
				next_s = next_e = 0;
 | 
									next_s = next_e = 0;
 | 
				
			||||||
			} else
 | 
								} else
 | 
				
			||||||
				done = 1;
 | 
									done = true;
 | 
				
			||||||
			break;
 | 
								break;
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
		brelse(bh);
 | 
							brelse(bh);
 | 
				
			||||||
| 
						 | 
					@ -2300,6 +2300,7 @@ static void udf_put_super(struct super_block *sb)
 | 
				
			||||||
		udf_close_lvid(sb);
 | 
							udf_close_lvid(sb);
 | 
				
			||||||
	brelse(sbi->s_lvid_bh);
 | 
						brelse(sbi->s_lvid_bh);
 | 
				
			||||||
	udf_sb_free_partitions(sb);
 | 
						udf_sb_free_partitions(sb);
 | 
				
			||||||
 | 
						mutex_destroy(&sbi->s_alloc_mutex);
 | 
				
			||||||
	kfree(sb->s_fs_info);
 | 
						kfree(sb->s_fs_info);
 | 
				
			||||||
	sb->s_fs_info = NULL;
 | 
						sb->s_fs_info = NULL;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -329,22 +329,16 @@ xfs_qm_scall_quotaon(
 | 
				
			||||||
		return -EINVAL;
 | 
							return -EINVAL;
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	/* No fs can turn on quotas with a delayed effect */
 | 
					 | 
				
			||||||
	ASSERT((flags & XFS_ALL_QUOTA_ACCT) == 0);
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	/*
 | 
						/*
 | 
				
			||||||
	 * Can't enforce without accounting. We check the superblock
 | 
						 * Can't enforce without accounting. We check the superblock
 | 
				
			||||||
	 * qflags here instead of m_qflags because rootfs can have
 | 
						 * qflags here instead of m_qflags because rootfs can have
 | 
				
			||||||
	 * quota acct on ondisk without m_qflags' knowing.
 | 
						 * quota acct on ondisk without m_qflags' knowing.
 | 
				
			||||||
	 */
 | 
						 */
 | 
				
			||||||
	if (((flags & XFS_UQUOTA_ACCT) == 0 &&
 | 
						if (((mp->m_sb.sb_qflags & XFS_UQUOTA_ACCT) == 0 &&
 | 
				
			||||||
	     (mp->m_sb.sb_qflags & XFS_UQUOTA_ACCT) == 0 &&
 | 
					 | 
				
			||||||
	     (flags & XFS_UQUOTA_ENFD)) ||
 | 
						     (flags & XFS_UQUOTA_ENFD)) ||
 | 
				
			||||||
	    ((flags & XFS_GQUOTA_ACCT) == 0 &&
 | 
						    ((mp->m_sb.sb_qflags & XFS_GQUOTA_ACCT) == 0 &&
 | 
				
			||||||
	     (mp->m_sb.sb_qflags & XFS_GQUOTA_ACCT) == 0 &&
 | 
					 | 
				
			||||||
	     (flags & XFS_GQUOTA_ENFD)) ||
 | 
						     (flags & XFS_GQUOTA_ENFD)) ||
 | 
				
			||||||
	    ((flags & XFS_PQUOTA_ACCT) == 0 &&
 | 
						    ((mp->m_sb.sb_qflags & XFS_PQUOTA_ACCT) == 0 &&
 | 
				
			||||||
	     (mp->m_sb.sb_qflags & XFS_PQUOTA_ACCT) == 0 &&
 | 
					 | 
				
			||||||
	     (flags & XFS_PQUOTA_ENFD))) {
 | 
						     (flags & XFS_PQUOTA_ENFD))) {
 | 
				
			||||||
		xfs_debug(mp,
 | 
							xfs_debug(mp,
 | 
				
			||||||
			"%s: Can't enforce without acct, flags=%x sbflags=%x",
 | 
								"%s: Can't enforce without acct, flags=%x sbflags=%x",
 | 
				
			||||||
| 
						 | 
					@ -383,8 +377,7 @@ xfs_qm_scall_quotaon(
 | 
				
			||||||
	     ((mp->m_sb.sb_qflags & XFS_PQUOTA_ACCT) !=
 | 
						     ((mp->m_sb.sb_qflags & XFS_PQUOTA_ACCT) !=
 | 
				
			||||||
	     (mp->m_qflags & XFS_PQUOTA_ACCT)) ||
 | 
						     (mp->m_qflags & XFS_PQUOTA_ACCT)) ||
 | 
				
			||||||
	     ((mp->m_sb.sb_qflags & XFS_GQUOTA_ACCT) !=
 | 
						     ((mp->m_sb.sb_qflags & XFS_GQUOTA_ACCT) !=
 | 
				
			||||||
	     (mp->m_qflags & XFS_GQUOTA_ACCT)) ||
 | 
						     (mp->m_qflags & XFS_GQUOTA_ACCT)))
 | 
				
			||||||
	    (flags & XFS_ALL_QUOTA_ENFD) == 0)
 | 
					 | 
				
			||||||
		return 0;
 | 
							return 0;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	if (! XFS_IS_QUOTA_RUNNING(mp))
 | 
						if (! XFS_IS_QUOTA_RUNNING(mp))
 | 
				
			||||||
| 
						 | 
					@ -421,20 +414,12 @@ xfs_qm_scall_getqstat(
 | 
				
			||||||
	memset(out, 0, sizeof(fs_quota_stat_t));
 | 
						memset(out, 0, sizeof(fs_quota_stat_t));
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	out->qs_version = FS_QSTAT_VERSION;
 | 
						out->qs_version = FS_QSTAT_VERSION;
 | 
				
			||||||
	if (!xfs_sb_version_hasquota(&mp->m_sb)) {
 | 
					 | 
				
			||||||
		out->qs_uquota.qfs_ino = NULLFSINO;
 | 
					 | 
				
			||||||
		out->qs_gquota.qfs_ino = NULLFSINO;
 | 
					 | 
				
			||||||
		return 0;
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	out->qs_flags = (__uint16_t) xfs_qm_export_flags(mp->m_qflags &
 | 
						out->qs_flags = (__uint16_t) xfs_qm_export_flags(mp->m_qflags &
 | 
				
			||||||
							(XFS_ALL_QUOTA_ACCT|
 | 
												(XFS_ALL_QUOTA_ACCT|
 | 
				
			||||||
							 XFS_ALL_QUOTA_ENFD));
 | 
												 XFS_ALL_QUOTA_ENFD));
 | 
				
			||||||
	if (q) {
 | 
					 | 
				
			||||||
	uip = q->qi_uquotaip;
 | 
						uip = q->qi_uquotaip;
 | 
				
			||||||
	gip = q->qi_gquotaip;
 | 
						gip = q->qi_gquotaip;
 | 
				
			||||||
	pip = q->qi_pquotaip;
 | 
						pip = q->qi_pquotaip;
 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
	if (!uip && mp->m_sb.sb_uquotino != NULLFSINO) {
 | 
						if (!uip && mp->m_sb.sb_uquotino != NULLFSINO) {
 | 
				
			||||||
		if (xfs_iget(mp, NULL, mp->m_sb.sb_uquotino,
 | 
							if (xfs_iget(mp, NULL, mp->m_sb.sb_uquotino,
 | 
				
			||||||
					0, 0, &uip) == 0)
 | 
										0, 0, &uip) == 0)
 | 
				
			||||||
| 
						 | 
					@ -480,14 +465,13 @@ xfs_qm_scall_getqstat(
 | 
				
			||||||
		if (temppqip)
 | 
							if (temppqip)
 | 
				
			||||||
			IRELE(pip);
 | 
								IRELE(pip);
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
	if (q) {
 | 
					 | 
				
			||||||
	out->qs_incoredqs = q->qi_dquots;
 | 
						out->qs_incoredqs = q->qi_dquots;
 | 
				
			||||||
	out->qs_btimelimit = q->qi_btimelimit;
 | 
						out->qs_btimelimit = q->qi_btimelimit;
 | 
				
			||||||
	out->qs_itimelimit = q->qi_itimelimit;
 | 
						out->qs_itimelimit = q->qi_itimelimit;
 | 
				
			||||||
	out->qs_rtbtimelimit = q->qi_rtbtimelimit;
 | 
						out->qs_rtbtimelimit = q->qi_rtbtimelimit;
 | 
				
			||||||
	out->qs_bwarnlimit = q->qi_bwarnlimit;
 | 
						out->qs_bwarnlimit = q->qi_bwarnlimit;
 | 
				
			||||||
	out->qs_iwarnlimit = q->qi_iwarnlimit;
 | 
						out->qs_iwarnlimit = q->qi_iwarnlimit;
 | 
				
			||||||
	}
 | 
					
 | 
				
			||||||
	return 0;
 | 
						return 0;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					@ -508,13 +492,6 @@ xfs_qm_scall_getqstatv(
 | 
				
			||||||
	bool                    tempgqip = false;
 | 
						bool                    tempgqip = false;
 | 
				
			||||||
	bool                    temppqip = false;
 | 
						bool                    temppqip = false;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	if (!xfs_sb_version_hasquota(&mp->m_sb)) {
 | 
					 | 
				
			||||||
		out->qs_uquota.qfs_ino = NULLFSINO;
 | 
					 | 
				
			||||||
		out->qs_gquota.qfs_ino = NULLFSINO;
 | 
					 | 
				
			||||||
		out->qs_pquota.qfs_ino = NULLFSINO;
 | 
					 | 
				
			||||||
		return 0;
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	out->qs_flags = (__uint16_t) xfs_qm_export_flags(mp->m_qflags &
 | 
						out->qs_flags = (__uint16_t) xfs_qm_export_flags(mp->m_qflags &
 | 
				
			||||||
							(XFS_ALL_QUOTA_ACCT|
 | 
												(XFS_ALL_QUOTA_ACCT|
 | 
				
			||||||
							 XFS_ALL_QUOTA_ENFD));
 | 
												 XFS_ALL_QUOTA_ENFD));
 | 
				
			||||||
| 
						 | 
					@ -522,11 +499,9 @@ xfs_qm_scall_getqstatv(
 | 
				
			||||||
	out->qs_gquota.qfs_ino = mp->m_sb.sb_gquotino;
 | 
						out->qs_gquota.qfs_ino = mp->m_sb.sb_gquotino;
 | 
				
			||||||
	out->qs_pquota.qfs_ino = mp->m_sb.sb_pquotino;
 | 
						out->qs_pquota.qfs_ino = mp->m_sb.sb_pquotino;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	if (q) {
 | 
					 | 
				
			||||||
	uip = q->qi_uquotaip;
 | 
						uip = q->qi_uquotaip;
 | 
				
			||||||
	gip = q->qi_gquotaip;
 | 
						gip = q->qi_gquotaip;
 | 
				
			||||||
	pip = q->qi_pquotaip;
 | 
						pip = q->qi_pquotaip;
 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
	if (!uip && mp->m_sb.sb_uquotino != NULLFSINO) {
 | 
						if (!uip && mp->m_sb.sb_uquotino != NULLFSINO) {
 | 
				
			||||||
		if (xfs_iget(mp, NULL, mp->m_sb.sb_uquotino,
 | 
							if (xfs_iget(mp, NULL, mp->m_sb.sb_uquotino,
 | 
				
			||||||
					0, 0, &uip) == 0)
 | 
										0, 0, &uip) == 0)
 | 
				
			||||||
| 
						 | 
					@ -561,14 +536,13 @@ xfs_qm_scall_getqstatv(
 | 
				
			||||||
		if (temppqip)
 | 
							if (temppqip)
 | 
				
			||||||
			IRELE(pip);
 | 
								IRELE(pip);
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
	if (q) {
 | 
					 | 
				
			||||||
	out->qs_incoredqs = q->qi_dquots;
 | 
						out->qs_incoredqs = q->qi_dquots;
 | 
				
			||||||
	out->qs_btimelimit = q->qi_btimelimit;
 | 
						out->qs_btimelimit = q->qi_btimelimit;
 | 
				
			||||||
	out->qs_itimelimit = q->qi_itimelimit;
 | 
						out->qs_itimelimit = q->qi_itimelimit;
 | 
				
			||||||
	out->qs_rtbtimelimit = q->qi_rtbtimelimit;
 | 
						out->qs_rtbtimelimit = q->qi_rtbtimelimit;
 | 
				
			||||||
	out->qs_bwarnlimit = q->qi_bwarnlimit;
 | 
						out->qs_bwarnlimit = q->qi_bwarnlimit;
 | 
				
			||||||
	out->qs_iwarnlimit = q->qi_iwarnlimit;
 | 
						out->qs_iwarnlimit = q->qi_iwarnlimit;
 | 
				
			||||||
	}
 | 
					
 | 
				
			||||||
	return 0;
 | 
						return 0;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -64,20 +64,11 @@ xfs_fs_get_xstatev(
 | 
				
			||||||
	return xfs_qm_scall_getqstatv(mp, fqs);
 | 
						return xfs_qm_scall_getqstatv(mp, fqs);
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
STATIC int
 | 
					static unsigned int
 | 
				
			||||||
xfs_fs_set_xstate(
 | 
					xfs_quota_flags(unsigned int uflags)
 | 
				
			||||||
	struct super_block	*sb,
 | 
					 | 
				
			||||||
	unsigned int		uflags,
 | 
					 | 
				
			||||||
	int			op)
 | 
					 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
	struct xfs_mount	*mp = XFS_M(sb);
 | 
					 | 
				
			||||||
	unsigned int flags = 0;
 | 
						unsigned int flags = 0;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	if (sb->s_flags & MS_RDONLY)
 | 
					 | 
				
			||||||
		return -EROFS;
 | 
					 | 
				
			||||||
	if (op != Q_XQUOTARM && !XFS_IS_QUOTA_RUNNING(mp))
 | 
					 | 
				
			||||||
		return -ENOSYS;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	if (uflags & FS_QUOTA_UDQ_ACCT)
 | 
						if (uflags & FS_QUOTA_UDQ_ACCT)
 | 
				
			||||||
		flags |= XFS_UQUOTA_ACCT;
 | 
							flags |= XFS_UQUOTA_ACCT;
 | 
				
			||||||
	if (uflags & FS_QUOTA_PDQ_ACCT)
 | 
						if (uflags & FS_QUOTA_PDQ_ACCT)
 | 
				
			||||||
| 
						 | 
					@ -91,16 +82,39 @@ xfs_fs_set_xstate(
 | 
				
			||||||
	if (uflags & FS_QUOTA_PDQ_ENFD)
 | 
						if (uflags & FS_QUOTA_PDQ_ENFD)
 | 
				
			||||||
		flags |= XFS_PQUOTA_ENFD;
 | 
							flags |= XFS_PQUOTA_ENFD;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	switch (op) {
 | 
						return flags;
 | 
				
			||||||
	case Q_XQUOTAON:
 | 
					 | 
				
			||||||
		return xfs_qm_scall_quotaon(mp, flags);
 | 
					 | 
				
			||||||
	case Q_XQUOTAOFF:
 | 
					 | 
				
			||||||
		if (!XFS_IS_QUOTA_ON(mp))
 | 
					 | 
				
			||||||
			return -EINVAL;
 | 
					 | 
				
			||||||
		return xfs_qm_scall_quotaoff(mp, flags);
 | 
					 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					STATIC int
 | 
				
			||||||
 | 
					xfs_quota_enable(
 | 
				
			||||||
 | 
						struct super_block	*sb,
 | 
				
			||||||
 | 
						unsigned int		uflags)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						struct xfs_mount	*mp = XFS_M(sb);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						if (sb->s_flags & MS_RDONLY)
 | 
				
			||||||
 | 
							return -EROFS;
 | 
				
			||||||
 | 
						if (!XFS_IS_QUOTA_RUNNING(mp))
 | 
				
			||||||
 | 
							return -ENOSYS;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						return xfs_qm_scall_quotaon(mp, xfs_quota_flags(uflags));
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					STATIC int
 | 
				
			||||||
 | 
					xfs_quota_disable(
 | 
				
			||||||
 | 
						struct super_block	*sb,
 | 
				
			||||||
 | 
						unsigned int		uflags)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						struct xfs_mount	*mp = XFS_M(sb);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						if (sb->s_flags & MS_RDONLY)
 | 
				
			||||||
 | 
							return -EROFS;
 | 
				
			||||||
 | 
						if (!XFS_IS_QUOTA_RUNNING(mp))
 | 
				
			||||||
 | 
							return -ENOSYS;
 | 
				
			||||||
 | 
						if (!XFS_IS_QUOTA_ON(mp))
 | 
				
			||||||
		return -EINVAL;
 | 
							return -EINVAL;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						return xfs_qm_scall_quotaoff(mp, xfs_quota_flags(uflags));
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
STATIC int
 | 
					STATIC int
 | 
				
			||||||
| 
						 | 
					@ -166,7 +180,8 @@ xfs_fs_set_dqblk(
 | 
				
			||||||
const struct quotactl_ops xfs_quotactl_operations = {
 | 
					const struct quotactl_ops xfs_quotactl_operations = {
 | 
				
			||||||
	.get_xstatev		= xfs_fs_get_xstatev,
 | 
						.get_xstatev		= xfs_fs_get_xstatev,
 | 
				
			||||||
	.get_xstate		= xfs_fs_get_xstate,
 | 
						.get_xstate		= xfs_fs_get_xstate,
 | 
				
			||||||
	.set_xstate		= xfs_fs_set_xstate,
 | 
						.quota_enable		= xfs_quota_enable,
 | 
				
			||||||
 | 
						.quota_disable		= xfs_quota_disable,
 | 
				
			||||||
	.rm_xquota		= xfs_fs_rm_xquota,
 | 
						.rm_xquota		= xfs_fs_rm_xquota,
 | 
				
			||||||
	.get_dqblk		= xfs_fs_get_dqblk,
 | 
						.get_dqblk		= xfs_fs_get_dqblk,
 | 
				
			||||||
	.set_dqblk		= xfs_fs_set_dqblk,
 | 
						.set_dqblk		= xfs_fs_set_dqblk,
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -5,9 +5,6 @@
 | 
				
			||||||
#ifndef _LINUX_DQBLK_V1_H
 | 
					#ifndef _LINUX_DQBLK_V1_H
 | 
				
			||||||
#define _LINUX_DQBLK_V1_H
 | 
					#define _LINUX_DQBLK_V1_H
 | 
				
			||||||
 | 
					
 | 
				
			||||||
/* Root squash turned on */
 | 
					 | 
				
			||||||
#define V1_DQF_RSQUASH 1
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
/* Numbers of blocks needed for updates */
 | 
					/* Numbers of blocks needed for updates */
 | 
				
			||||||
#define V1_INIT_ALLOC 1
 | 
					#define V1_INIT_ALLOC 1
 | 
				
			||||||
#define V1_INIT_REWRITE 1
 | 
					#define V1_INIT_REWRITE 1
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -956,15 +956,6 @@ void __log_wait_for_space(journal_t *journal);
 | 
				
			||||||
extern void	__journal_drop_transaction(journal_t *, transaction_t *);
 | 
					extern void	__journal_drop_transaction(journal_t *, transaction_t *);
 | 
				
			||||||
extern int	cleanup_journal_tail(journal_t *);
 | 
					extern int	cleanup_journal_tail(journal_t *);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
/* Debugging code only: */
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
#define jbd_ENOSYS() \
 | 
					 | 
				
			||||||
do {								           \
 | 
					 | 
				
			||||||
	printk (KERN_ERR "JBD unimplemented function %s\n", __func__); \
 | 
					 | 
				
			||||||
	current->state = TASK_UNINTERRUPTIBLE;			           \
 | 
					 | 
				
			||||||
	schedule();						           \
 | 
					 | 
				
			||||||
} while (1)
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
/*
 | 
					/*
 | 
				
			||||||
 * is_journal_abort
 | 
					 * is_journal_abort
 | 
				
			||||||
 *
 | 
					 *
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -1251,15 +1251,6 @@ void __jbd2_log_wait_for_space(journal_t *journal);
 | 
				
			||||||
extern void __jbd2_journal_drop_transaction(journal_t *, transaction_t *);
 | 
					extern void __jbd2_journal_drop_transaction(journal_t *, transaction_t *);
 | 
				
			||||||
extern int jbd2_cleanup_journal_tail(journal_t *);
 | 
					extern int jbd2_cleanup_journal_tail(journal_t *);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
/* Debugging code only: */
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
#define jbd_ENOSYS() \
 | 
					 | 
				
			||||||
do {								           \
 | 
					 | 
				
			||||||
	printk (KERN_ERR "JBD unimplemented function %s\n", __func__); \
 | 
					 | 
				
			||||||
	current->state = TASK_UNINTERRUPTIBLE;			           \
 | 
					 | 
				
			||||||
	schedule();						           \
 | 
					 | 
				
			||||||
} while (1)
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
/*
 | 
					/*
 | 
				
			||||||
 * is_journal_abort
 | 
					 * is_journal_abort
 | 
				
			||||||
 *
 | 
					 *
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -216,19 +216,21 @@ struct mem_dqinfo {
 | 
				
			||||||
	unsigned long dqi_flags;
 | 
						unsigned long dqi_flags;
 | 
				
			||||||
	unsigned int dqi_bgrace;
 | 
						unsigned int dqi_bgrace;
 | 
				
			||||||
	unsigned int dqi_igrace;
 | 
						unsigned int dqi_igrace;
 | 
				
			||||||
	qsize_t dqi_maxblimit;
 | 
						qsize_t dqi_max_spc_limit;
 | 
				
			||||||
	qsize_t dqi_maxilimit;
 | 
						qsize_t dqi_max_ino_limit;
 | 
				
			||||||
	void *dqi_priv;
 | 
						void *dqi_priv;
 | 
				
			||||||
};
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
struct super_block;
 | 
					struct super_block;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
#define DQF_MASK 0xffff		/* Mask for format specific flags */
 | 
					/* Mask for flags passed to userspace */
 | 
				
			||||||
#define DQF_GETINFO_MASK 0x1ffff	/* Mask for flags passed to userspace */
 | 
					#define DQF_GETINFO_MASK (DQF_ROOT_SQUASH | DQF_SYS_FILE)
 | 
				
			||||||
#define DQF_SETINFO_MASK 0xffff		/* Mask for flags modifiable from userspace */
 | 
					/* Mask for flags modifiable from userspace */
 | 
				
			||||||
#define DQF_SYS_FILE_B		16
 | 
					#define DQF_SETINFO_MASK DQF_ROOT_SQUASH
 | 
				
			||||||
#define DQF_SYS_FILE (1 << DQF_SYS_FILE_B)	/* Quota file stored as system file */
 | 
					
 | 
				
			||||||
#define DQF_INFO_DIRTY_B	31
 | 
					enum {
 | 
				
			||||||
 | 
						DQF_INFO_DIRTY_B = DQF_PRIVATE,
 | 
				
			||||||
 | 
					};
 | 
				
			||||||
#define DQF_INFO_DIRTY (1 << DQF_INFO_DIRTY_B)	/* Is info dirty? */
 | 
					#define DQF_INFO_DIRTY (1 << DQF_INFO_DIRTY_B)	/* Is info dirty? */
 | 
				
			||||||
 | 
					
 | 
				
			||||||
extern void mark_info_dirty(struct super_block *sb, int type);
 | 
					extern void mark_info_dirty(struct super_block *sb, int type);
 | 
				
			||||||
| 
						 | 
					@ -367,15 +369,15 @@ struct qc_dqblk {
 | 
				
			||||||
/* Operations handling requests from userspace */
 | 
					/* Operations handling requests from userspace */
 | 
				
			||||||
struct quotactl_ops {
 | 
					struct quotactl_ops {
 | 
				
			||||||
	int (*quota_on)(struct super_block *, int, int, struct path *);
 | 
						int (*quota_on)(struct super_block *, int, int, struct path *);
 | 
				
			||||||
	int (*quota_on_meta)(struct super_block *, int, int);
 | 
					 | 
				
			||||||
	int (*quota_off)(struct super_block *, int);
 | 
						int (*quota_off)(struct super_block *, int);
 | 
				
			||||||
 | 
						int (*quota_enable)(struct super_block *, unsigned int);
 | 
				
			||||||
 | 
						int (*quota_disable)(struct super_block *, unsigned int);
 | 
				
			||||||
	int (*quota_sync)(struct super_block *, int);
 | 
						int (*quota_sync)(struct super_block *, int);
 | 
				
			||||||
	int (*get_info)(struct super_block *, int, struct if_dqinfo *);
 | 
						int (*get_info)(struct super_block *, int, struct if_dqinfo *);
 | 
				
			||||||
	int (*set_info)(struct super_block *, int, struct if_dqinfo *);
 | 
						int (*set_info)(struct super_block *, int, struct if_dqinfo *);
 | 
				
			||||||
	int (*get_dqblk)(struct super_block *, struct kqid, struct qc_dqblk *);
 | 
						int (*get_dqblk)(struct super_block *, struct kqid, struct qc_dqblk *);
 | 
				
			||||||
	int (*set_dqblk)(struct super_block *, struct kqid, struct qc_dqblk *);
 | 
						int (*set_dqblk)(struct super_block *, struct kqid, struct qc_dqblk *);
 | 
				
			||||||
	int (*get_xstate)(struct super_block *, struct fs_quota_stat *);
 | 
						int (*get_xstate)(struct super_block *, struct fs_quota_stat *);
 | 
				
			||||||
	int (*set_xstate)(struct super_block *, unsigned int, int);
 | 
					 | 
				
			||||||
	int (*get_xstatev)(struct super_block *, struct fs_quota_statv *);
 | 
						int (*get_xstatev)(struct super_block *, struct fs_quota_statv *);
 | 
				
			||||||
	int (*rm_xquota)(struct super_block *, unsigned int);
 | 
						int (*rm_xquota)(struct super_block *, unsigned int);
 | 
				
			||||||
};
 | 
					};
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -166,6 +166,7 @@ static inline bool sb_has_quota_active(struct super_block *sb, int type)
 | 
				
			||||||
 */
 | 
					 */
 | 
				
			||||||
extern const struct dquot_operations dquot_operations;
 | 
					extern const struct dquot_operations dquot_operations;
 | 
				
			||||||
extern const struct quotactl_ops dquot_quotactl_ops;
 | 
					extern const struct quotactl_ops dquot_quotactl_ops;
 | 
				
			||||||
 | 
					extern const struct quotactl_ops dquot_quotactl_sysfile_ops;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
#else
 | 
					#else
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					@ -386,4 +387,6 @@ static inline void dquot_release_reservation_block(struct inode *inode,
 | 
				
			||||||
	__dquot_free_space(inode, nr << inode->i_blkbits, DQUOT_SPACE_RESERVE);
 | 
						__dquot_free_space(inode, nr << inode->i_blkbits, DQUOT_SPACE_RESERVE);
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					unsigned int qtype_enforce_flag(int type);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
#endif /* _LINUX_QUOTAOPS_ */
 | 
					#endif /* _LINUX_QUOTAOPS_ */
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -126,10 +126,22 @@ struct if_dqblk {
 | 
				
			||||||
#define IIF_FLAGS	4
 | 
					#define IIF_FLAGS	4
 | 
				
			||||||
#define IIF_ALL		(IIF_BGRACE | IIF_IGRACE | IIF_FLAGS)
 | 
					#define IIF_ALL		(IIF_BGRACE | IIF_IGRACE | IIF_FLAGS)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					enum {
 | 
				
			||||||
 | 
						DQF_ROOT_SQUASH_B = 0,
 | 
				
			||||||
 | 
						DQF_SYS_FILE_B = 16,
 | 
				
			||||||
 | 
						/* Kernel internal flags invisible to userspace */
 | 
				
			||||||
 | 
						DQF_PRIVATE
 | 
				
			||||||
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/* Root squash enabled (for v1 quota format) */
 | 
				
			||||||
 | 
					#define DQF_ROOT_SQUASH	(1 << DQF_ROOT_SQUASH_B)
 | 
				
			||||||
 | 
					/* Quota stored in a system file */
 | 
				
			||||||
 | 
					#define DQF_SYS_FILE	(1 << DQF_SYS_FILE_B)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
struct if_dqinfo {
 | 
					struct if_dqinfo {
 | 
				
			||||||
	__u64 dqi_bgrace;
 | 
						__u64 dqi_bgrace;
 | 
				
			||||||
	__u64 dqi_igrace;
 | 
						__u64 dqi_igrace;
 | 
				
			||||||
	__u32 dqi_flags;
 | 
						__u32 dqi_flags;	/* DFQ_* */
 | 
				
			||||||
	__u32 dqi_valid;
 | 
						__u32 dqi_valid;
 | 
				
			||||||
};
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue