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
|
@ -466,6 +466,8 @@ static void ext3_put_super (struct super_block * sb)
|
|||
}
|
||||
sb->s_fs_info = NULL;
|
||||
kfree(sbi->s_blockgroup_lock);
|
||||
mutex_destroy(&sbi->s_orphan_lock);
|
||||
mutex_destroy(&sbi->s_resize_lock);
|
||||
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_quota_on(struct super_block *sb, int type, int format_id,
|
||||
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_sysfile(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,
|
||||
size_t len, loff_t off);
|
||||
|
@ -1084,16 +1081,6 @@ static const struct quotactl_ops ext4_qctl_operations = {
|
|||
.get_dqblk = dquot_get_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
|
||||
|
||||
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
|
||||
sb->dq_op = &ext4_quota_operations;
|
||||
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
|
||||
sb->s_qcop = &ext4_qctl_operations;
|
||||
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;
|
||||
}
|
||||
|
||||
/*
|
||||
* 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)
|
||||
{
|
||||
struct inode *inode = sb_dqopt(sb)->files[type];
|
||||
|
@ -5329,18 +5301,6 @@ out:
|
|||
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
|
||||
* acquiring the locks... As quota files are never truncated and quota code
|
||||
* itself serializes the operations (and no one else should touch the files)
|
||||
|
|
|
@ -2,6 +2,7 @@
|
|||
* linux/fs/isofs/util.c
|
||||
*/
|
||||
|
||||
#include <linux/time.h>
|
||||
#include "isofs.h"
|
||||
|
||||
/*
|
||||
|
@ -17,9 +18,9 @@
|
|||
int iso_date(char * p, int flag)
|
||||
{
|
||||
int year, month, day, hour, minute, second, tz;
|
||||
int crtime, days, i;
|
||||
int crtime;
|
||||
|
||||
year = p[0] - 70;
|
||||
year = p[0];
|
||||
month = p[1];
|
||||
day = p[2];
|
||||
hour = p[3];
|
||||
|
@ -31,18 +32,7 @@ int iso_date(char * p, int flag)
|
|||
if (year < 0) {
|
||||
crtime = 0;
|
||||
} else {
|
||||
int monlen[12] = {31,28,31,30,31,30,31,31,30,31,30,31};
|
||||
|
||||
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;
|
||||
crtime = mktime64(year+1900, month, day, hour, minute, second);
|
||||
|
||||
/* sign extend */
|
||||
if (tz & 0x80)
|
||||
|
|
|
@ -48,6 +48,7 @@ struct ocfs2_quota_recovery {
|
|||
/* In-memory structure with quota header information */
|
||||
struct ocfs2_mem_dqinfo {
|
||||
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_blocks; /* Number of blocks allocated for local quota file */
|
||||
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 +
|
||||
OCFS2_LOCAL_INFO_OFF);
|
||||
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_blocks = cpu_to_le32(oinfo->dqi_blocks);
|
||||
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
|
||||
* which will later depend on this lock */
|
||||
mutex_unlock(&sb_dqopt(sb)->dqio_mutex);
|
||||
info->dqi_maxblimit = 0x7fffffffffffffffLL;
|
||||
info->dqi_maxilimit = 0x7fffffffffffffffLL;
|
||||
info->dqi_max_spc_limit = 0x7fffffffffffffffLL;
|
||||
info->dqi_max_ino_limit = 0x7fffffffffffffffLL;
|
||||
oinfo = kmalloc(sizeof(struct ocfs2_mem_dqinfo), GFP_NOFS);
|
||||
if (!oinfo) {
|
||||
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 +
|
||||
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_blocks = le32_to_cpu(ldinfo->dqi_blocks);
|
||||
oinfo->dqi_libh = bh;
|
||||
|
||||
/* 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;
|
||||
if (!rec) {
|
||||
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 */
|
||||
info->dqi_flags &= ~OLQF_CLEAN;
|
||||
oinfo->dqi_flags &= ~OLQF_CLEAN;
|
||||
status = ocfs2_modify_bh(lqinode, bh, olq_update_info, info);
|
||||
if (status < 0) {
|
||||
mlog_errno(status);
|
||||
|
@ -857,7 +857,7 @@ static int ocfs2_local_free_info(struct super_block *sb, int type)
|
|||
goto out;
|
||||
|
||||
/* Mark local file as clean */
|
||||
info->dqi_flags |= OLQF_CLEAN;
|
||||
oinfo->dqi_flags |= OLQF_CLEAN;
|
||||
status = ocfs2_modify_bh(sb_dqopt(sb)->files[type],
|
||||
oinfo->dqi_libh,
|
||||
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)
|
||||
{
|
||||
struct dentry *root;
|
||||
|
@ -2079,7 +2049,7 @@ static int ocfs2_initialize_super(struct super_block *sb,
|
|||
sb->s_op = &ocfs2_sops;
|
||||
sb->s_d_op = &ocfs2_dentry_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->s_quota_types = QTYPE_MASK_USR | QTYPE_MASK_GRP;
|
||||
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) &&
|
||||
(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 */
|
||||
|
@ -2385,14 +2385,84 @@ out:
|
|||
}
|
||||
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 */
|
||||
|
@ -2444,13 +2514,13 @@ static int do_set_dqblk(struct dquot *dquot, struct qc_dqblk *di)
|
|||
return -EINVAL;
|
||||
|
||||
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) &&
|
||||
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_ino_softlimit > dqi->dqi_maxilimit)) ||
|
||||
(di->d_ino_softlimit > dqi->dqi_max_ino_limit)) ||
|
||||
((di->d_fieldmask & QC_INO_HARD) &&
|
||||
(di->d_ino_hardlimit > dqi->dqi_maxilimit)))
|
||||
(di->d_ino_hardlimit > dqi->dqi_max_ino_limit)))
|
||||
return -ERANGE;
|
||||
|
||||
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;
|
||||
}
|
||||
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);
|
||||
if (ii->dqi_valid & IIF_BGRACE)
|
||||
mi->dqi_bgrace = ii->dqi_bgrace;
|
||||
|
@ -2606,6 +2684,17 @@ const struct quotactl_ops 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,
|
||||
void __user *buffer, size_t *lenp, loff_t *ppos)
|
||||
{
|
||||
|
|
|
@ -66,18 +66,40 @@ static int quota_sync_all(int type)
|
|||
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,
|
||||
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;
|
||||
if (sb->s_qcop->quota_on_meta)
|
||||
return sb->s_qcop->quota_on_meta(sb, type, id);
|
||||
if (sb->s_qcop->quota_enable)
|
||||
return sb->s_qcop->quota_enable(sb, qtype_enforce_flag(type));
|
||||
if (IS_ERR(path))
|
||||
return PTR_ERR(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)
|
||||
{
|
||||
__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);
|
||||
}
|
||||
|
||||
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;
|
||||
|
||||
if (copy_from_user(&flags, addr, sizeof(flags)))
|
||||
return -EFAULT;
|
||||
if (!sb->s_qcop->set_xstate)
|
||||
if (!sb->s_qcop->quota_enable)
|
||||
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)
|
||||
|
@ -429,9 +462,7 @@ static int do_quotactl(struct super_block *sb, int type, int cmd, qid_t id,
|
|||
case Q_QUOTAON:
|
||||
return quota_quotaon(sb, type, cmd, id, path);
|
||||
case Q_QUOTAOFF:
|
||||
if (!sb->s_qcop->quota_off)
|
||||
return -ENOSYS;
|
||||
return sb->s_qcop->quota_off(sb, type);
|
||||
return quota_quotaoff(sb, type);
|
||||
case Q_GETFMT:
|
||||
return quota_getfmt(sb, type, addr);
|
||||
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 sb->s_qcop->quota_sync(sb, type);
|
||||
case Q_XQUOTAON:
|
||||
return quota_enable(sb, addr);
|
||||
case Q_XQUOTAOFF:
|
||||
return quota_setxstate(sb, cmd, addr);
|
||||
return quota_disable(sb, addr);
|
||||
case Q_XQUOTARM:
|
||||
return quota_rmxquota(sb, addr);
|
||||
case Q_XGETQSTAT:
|
||||
|
|
|
@ -169,8 +169,8 @@ static int v1_read_file_info(struct super_block *sb, int type)
|
|||
}
|
||||
ret = 0;
|
||||
/* limits are stored as unsigned 32-bit data */
|
||||
dqopt->info[type].dqi_maxblimit = 0xffffffff;
|
||||
dqopt->info[type].dqi_maxilimit = 0xffffffff;
|
||||
dqopt->info[type].dqi_max_spc_limit = 0xffffffffULL << QUOTABLOCK_BITS;
|
||||
dqopt->info[type].dqi_max_ino_limit = 0xffffffff;
|
||||
dqopt->info[type].dqi_igrace =
|
||||
dqblk.dqb_itime ? dqblk.dqb_itime : MAX_IQ_TIME;
|
||||
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;
|
||||
if (version == 0) {
|
||||
/* limits are stored as unsigned 32-bit data */
|
||||
info->dqi_maxblimit = 0xffffffff;
|
||||
info->dqi_maxilimit = 0xffffffff;
|
||||
info->dqi_max_spc_limit = 0xffffffffULL << QUOTABLOCK_BITS;
|
||||
info->dqi_max_ino_limit = 0xffffffff;
|
||||
} else {
|
||||
/* used space is stored as unsigned 64-bit value */
|
||||
info->dqi_maxblimit = 0xffffffffffffffffULL; /* 2^64-1 */
|
||||
info->dqi_maxilimit = 0xffffffffffffffffULL;
|
||||
/* used space is stored as unsigned 64-bit value in bytes */
|
||||
info->dqi_max_spc_limit = 0xffffffffffffffffULL; /* 2^64-1 */
|
||||
info->dqi_max_ino_limit = 0xffffffffffffffffULL;
|
||||
}
|
||||
info->dqi_bgrace = le32_to_cpu(dinfo.dqi_bgrace);
|
||||
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_type = type;
|
||||
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;
|
||||
dinfo.dqi_bgrace = cpu_to_le32(info->dqi_bgrace);
|
||||
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);
|
||||
dinfo.dqi_blocks = cpu_to_le32(qinfo->dqi_blocks);
|
||||
dinfo.dqi_free_blk = cpu_to_le32(qinfo->dqi_free_blk);
|
||||
|
|
|
@ -2,10 +2,12 @@ config UDF_FS
|
|||
tristate "UDF file system support"
|
||||
select CRC_ITU_T
|
||||
help
|
||||
This is the new file system used on some CD-ROMs and DVDs. Say Y if
|
||||
you intend to mount DVD discs or CDRW's written in packet mode, or
|
||||
if written to by other UDF utilities, such as DirectCD.
|
||||
Please read <file:Documentation/filesystems/udf.txt>.
|
||||
This is a file system used on some CD-ROMs and DVDs. Since the
|
||||
file system is supported by multiple operating systems and is more
|
||||
compatible with standard unix file systems, it is also suitable for
|
||||
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
|
||||
module will be called udf.
|
||||
|
|
|
@ -750,7 +750,7 @@ static sector_t inode_getblk(struct inode *inode, sector_t block,
|
|||
/* Are we beyond EOF? */
|
||||
if (etype == -1) {
|
||||
int ret;
|
||||
isBeyondEOF = 1;
|
||||
isBeyondEOF = true;
|
||||
if (count) {
|
||||
if (c)
|
||||
laarr[0] = laarr[1];
|
||||
|
@ -792,7 +792,7 @@ static sector_t inode_getblk(struct inode *inode, sector_t block,
|
|||
endnum = c + 1;
|
||||
lastblock = 1;
|
||||
} else {
|
||||
isBeyondEOF = 0;
|
||||
isBeyondEOF = false;
|
||||
endnum = startnum = ((count > 2) ? 2 : count);
|
||||
|
||||
/* 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;
|
||||
unsigned int link_count;
|
||||
unsigned int indirections = 0;
|
||||
int bs = inode->i_sb->s_blocksize;
|
||||
int ret = -EIO;
|
||||
|
||||
reread:
|
||||
|
@ -1374,38 +1375,35 @@ reread:
|
|||
if (fe->descTag.tagIdent == cpu_to_le16(TAG_IDENT_EFE)) {
|
||||
iinfo->i_efe = 1;
|
||||
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));
|
||||
if (ret)
|
||||
goto out;
|
||||
memcpy(iinfo->i_ext.i_data,
|
||||
bh->b_data + sizeof(struct extendedFileEntry),
|
||||
inode->i_sb->s_blocksize -
|
||||
sizeof(struct extendedFileEntry));
|
||||
bs - sizeof(struct extendedFileEntry));
|
||||
} else if (fe->descTag.tagIdent == cpu_to_le16(TAG_IDENT_FE)) {
|
||||
iinfo->i_efe = 0;
|
||||
iinfo->i_use = 0;
|
||||
ret = udf_alloc_i_data(inode, inode->i_sb->s_blocksize -
|
||||
sizeof(struct fileEntry));
|
||||
ret = udf_alloc_i_data(inode, bs - sizeof(struct fileEntry));
|
||||
if (ret)
|
||||
goto out;
|
||||
memcpy(iinfo->i_ext.i_data,
|
||||
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)) {
|
||||
iinfo->i_efe = 0;
|
||||
iinfo->i_use = 1;
|
||||
iinfo->i_lenAlloc = le32_to_cpu(
|
||||
((struct unallocSpaceEntry *)bh->b_data)->
|
||||
lengthAllocDescs);
|
||||
ret = udf_alloc_i_data(inode, inode->i_sb->s_blocksize -
|
||||
ret = udf_alloc_i_data(inode, bs -
|
||||
sizeof(struct unallocSpaceEntry));
|
||||
if (ret)
|
||||
goto out;
|
||||
memcpy(iinfo->i_ext.i_data,
|
||||
bh->b_data + sizeof(struct unallocSpaceEntry),
|
||||
inode->i_sb->s_blocksize -
|
||||
sizeof(struct unallocSpaceEntry));
|
||||
bs - sizeof(struct unallocSpaceEntry));
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
@ -1489,6 +1487,15 @@ reread:
|
|||
}
|
||||
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 */
|
||||
if (iinfo->i_alloc_type == ICBTAG_FLAG_AD_IN_ICB) {
|
||||
/*
|
||||
|
@ -1498,8 +1505,7 @@ reread:
|
|||
if (iinfo->i_lenAlloc != inode->i_size)
|
||||
goto out;
|
||||
/* File in ICB has to fit in there... */
|
||||
if (inode->i_size > inode->i_sb->s_blocksize -
|
||||
udf_file_entry_alloc_offset(inode))
|
||||
if (inode->i_size > bs - udf_file_entry_alloc_offset(inode))
|
||||
goto out;
|
||||
}
|
||||
|
||||
|
|
|
@ -1599,7 +1599,7 @@ static noinline int udf_process_sequence(
|
|||
struct udf_vds_record *curr;
|
||||
struct generic_desc *gd;
|
||||
struct volDescPtr *vdp;
|
||||
int done = 0;
|
||||
bool done = false;
|
||||
uint32_t vdsn;
|
||||
uint16_t ident;
|
||||
long next_s = 0, next_e = 0;
|
||||
|
@ -1680,7 +1680,7 @@ static noinline int udf_process_sequence(
|
|||
lastblock = next_e;
|
||||
next_s = next_e = 0;
|
||||
} else
|
||||
done = 1;
|
||||
done = true;
|
||||
break;
|
||||
}
|
||||
brelse(bh);
|
||||
|
@ -2300,6 +2300,7 @@ static void udf_put_super(struct super_block *sb)
|
|||
udf_close_lvid(sb);
|
||||
brelse(sbi->s_lvid_bh);
|
||||
udf_sb_free_partitions(sb);
|
||||
mutex_destroy(&sbi->s_alloc_mutex);
|
||||
kfree(sb->s_fs_info);
|
||||
sb->s_fs_info = NULL;
|
||||
}
|
||||
|
|
|
@ -329,22 +329,16 @@ xfs_qm_scall_quotaon(
|
|||
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
|
||||
* qflags here instead of m_qflags because rootfs can have
|
||||
* quota acct on ondisk without m_qflags' knowing.
|
||||
*/
|
||||
if (((flags & XFS_UQUOTA_ACCT) == 0 &&
|
||||
(mp->m_sb.sb_qflags & XFS_UQUOTA_ACCT) == 0 &&
|
||||
if (((mp->m_sb.sb_qflags & XFS_UQUOTA_ACCT) == 0 &&
|
||||
(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_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))) {
|
||||
xfs_debug(mp,
|
||||
"%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_qflags & XFS_PQUOTA_ACCT)) ||
|
||||
((mp->m_sb.sb_qflags & XFS_GQUOTA_ACCT) !=
|
||||
(mp->m_qflags & XFS_GQUOTA_ACCT)) ||
|
||||
(flags & XFS_ALL_QUOTA_ENFD) == 0)
|
||||
(mp->m_qflags & XFS_GQUOTA_ACCT)))
|
||||
return 0;
|
||||
|
||||
if (! XFS_IS_QUOTA_RUNNING(mp))
|
||||
|
@ -421,20 +414,12 @@ xfs_qm_scall_getqstat(
|
|||
memset(out, 0, sizeof(fs_quota_stat_t));
|
||||
|
||||
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 &
|
||||
(XFS_ALL_QUOTA_ACCT|
|
||||
XFS_ALL_QUOTA_ENFD));
|
||||
if (q) {
|
||||
uip = q->qi_uquotaip;
|
||||
gip = q->qi_gquotaip;
|
||||
pip = q->qi_pquotaip;
|
||||
}
|
||||
uip = q->qi_uquotaip;
|
||||
gip = q->qi_gquotaip;
|
||||
pip = q->qi_pquotaip;
|
||||
if (!uip && mp->m_sb.sb_uquotino != NULLFSINO) {
|
||||
if (xfs_iget(mp, NULL, mp->m_sb.sb_uquotino,
|
||||
0, 0, &uip) == 0)
|
||||
|
@ -480,14 +465,13 @@ xfs_qm_scall_getqstat(
|
|||
if (temppqip)
|
||||
IRELE(pip);
|
||||
}
|
||||
if (q) {
|
||||
out->qs_incoredqs = q->qi_dquots;
|
||||
out->qs_btimelimit = q->qi_btimelimit;
|
||||
out->qs_itimelimit = q->qi_itimelimit;
|
||||
out->qs_rtbtimelimit = q->qi_rtbtimelimit;
|
||||
out->qs_bwarnlimit = q->qi_bwarnlimit;
|
||||
out->qs_iwarnlimit = q->qi_iwarnlimit;
|
||||
}
|
||||
out->qs_incoredqs = q->qi_dquots;
|
||||
out->qs_btimelimit = q->qi_btimelimit;
|
||||
out->qs_itimelimit = q->qi_itimelimit;
|
||||
out->qs_rtbtimelimit = q->qi_rtbtimelimit;
|
||||
out->qs_bwarnlimit = q->qi_bwarnlimit;
|
||||
out->qs_iwarnlimit = q->qi_iwarnlimit;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
@ -508,13 +492,6 @@ xfs_qm_scall_getqstatv(
|
|||
bool tempgqip = 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 &
|
||||
(XFS_ALL_QUOTA_ACCT|
|
||||
XFS_ALL_QUOTA_ENFD));
|
||||
|
@ -522,11 +499,9 @@ xfs_qm_scall_getqstatv(
|
|||
out->qs_gquota.qfs_ino = mp->m_sb.sb_gquotino;
|
||||
out->qs_pquota.qfs_ino = mp->m_sb.sb_pquotino;
|
||||
|
||||
if (q) {
|
||||
uip = q->qi_uquotaip;
|
||||
gip = q->qi_gquotaip;
|
||||
pip = q->qi_pquotaip;
|
||||
}
|
||||
uip = q->qi_uquotaip;
|
||||
gip = q->qi_gquotaip;
|
||||
pip = q->qi_pquotaip;
|
||||
if (!uip && mp->m_sb.sb_uquotino != NULLFSINO) {
|
||||
if (xfs_iget(mp, NULL, mp->m_sb.sb_uquotino,
|
||||
0, 0, &uip) == 0)
|
||||
|
@ -561,14 +536,13 @@ xfs_qm_scall_getqstatv(
|
|||
if (temppqip)
|
||||
IRELE(pip);
|
||||
}
|
||||
if (q) {
|
||||
out->qs_incoredqs = q->qi_dquots;
|
||||
out->qs_btimelimit = q->qi_btimelimit;
|
||||
out->qs_itimelimit = q->qi_itimelimit;
|
||||
out->qs_rtbtimelimit = q->qi_rtbtimelimit;
|
||||
out->qs_bwarnlimit = q->qi_bwarnlimit;
|
||||
out->qs_iwarnlimit = q->qi_iwarnlimit;
|
||||
}
|
||||
out->qs_incoredqs = q->qi_dquots;
|
||||
out->qs_btimelimit = q->qi_btimelimit;
|
||||
out->qs_itimelimit = q->qi_itimelimit;
|
||||
out->qs_rtbtimelimit = q->qi_rtbtimelimit;
|
||||
out->qs_bwarnlimit = q->qi_bwarnlimit;
|
||||
out->qs_iwarnlimit = q->qi_iwarnlimit;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
|
|
@ -64,19 +64,10 @@ xfs_fs_get_xstatev(
|
|||
return xfs_qm_scall_getqstatv(mp, fqs);
|
||||
}
|
||||
|
||||
STATIC int
|
||||
xfs_fs_set_xstate(
|
||||
struct super_block *sb,
|
||||
unsigned int uflags,
|
||||
int op)
|
||||
static unsigned int
|
||||
xfs_quota_flags(unsigned int uflags)
|
||||
{
|
||||
struct xfs_mount *mp = XFS_M(sb);
|
||||
unsigned int flags = 0;
|
||||
|
||||
if (sb->s_flags & MS_RDONLY)
|
||||
return -EROFS;
|
||||
if (op != Q_XQUOTARM && !XFS_IS_QUOTA_RUNNING(mp))
|
||||
return -ENOSYS;
|
||||
unsigned int flags = 0;
|
||||
|
||||
if (uflags & FS_QUOTA_UDQ_ACCT)
|
||||
flags |= XFS_UQUOTA_ACCT;
|
||||
|
@ -91,16 +82,39 @@ xfs_fs_set_xstate(
|
|||
if (uflags & FS_QUOTA_PDQ_ENFD)
|
||||
flags |= XFS_PQUOTA_ENFD;
|
||||
|
||||
switch (op) {
|
||||
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);
|
||||
}
|
||||
return flags;
|
||||
}
|
||||
|
||||
return -EINVAL;
|
||||
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 xfs_qm_scall_quotaoff(mp, xfs_quota_flags(uflags));
|
||||
}
|
||||
|
||||
STATIC int
|
||||
|
@ -166,7 +180,8 @@ xfs_fs_set_dqblk(
|
|||
const struct quotactl_ops xfs_quotactl_operations = {
|
||||
.get_xstatev = xfs_fs_get_xstatev,
|
||||
.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,
|
||||
.get_dqblk = xfs_fs_get_dqblk,
|
||||
.set_dqblk = xfs_fs_set_dqblk,
|
||||
|
|
|
@ -5,9 +5,6 @@
|
|||
#ifndef _LINUX_DQBLK_V1_H
|
||||
#define _LINUX_DQBLK_V1_H
|
||||
|
||||
/* Root squash turned on */
|
||||
#define V1_DQF_RSQUASH 1
|
||||
|
||||
/* Numbers of blocks needed for updates */
|
||||
#define V1_INIT_ALLOC 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 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
|
||||
*
|
||||
|
|
|
@ -1251,15 +1251,6 @@ void __jbd2_log_wait_for_space(journal_t *journal);
|
|||
extern void __jbd2_journal_drop_transaction(journal_t *, transaction_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
|
||||
*
|
||||
|
|
|
@ -216,19 +216,21 @@ struct mem_dqinfo {
|
|||
unsigned long dqi_flags;
|
||||
unsigned int dqi_bgrace;
|
||||
unsigned int dqi_igrace;
|
||||
qsize_t dqi_maxblimit;
|
||||
qsize_t dqi_maxilimit;
|
||||
qsize_t dqi_max_spc_limit;
|
||||
qsize_t dqi_max_ino_limit;
|
||||
void *dqi_priv;
|
||||
};
|
||||
|
||||
struct super_block;
|
||||
|
||||
#define DQF_MASK 0xffff /* Mask for format specific flags */
|
||||
#define DQF_GETINFO_MASK 0x1ffff /* Mask for flags passed to userspace */
|
||||
#define DQF_SETINFO_MASK 0xffff /* Mask for flags modifiable from userspace */
|
||||
#define DQF_SYS_FILE_B 16
|
||||
#define DQF_SYS_FILE (1 << DQF_SYS_FILE_B) /* Quota file stored as system file */
|
||||
#define DQF_INFO_DIRTY_B 31
|
||||
/* Mask for flags passed to userspace */
|
||||
#define DQF_GETINFO_MASK (DQF_ROOT_SQUASH | DQF_SYS_FILE)
|
||||
/* Mask for flags modifiable from userspace */
|
||||
#define DQF_SETINFO_MASK DQF_ROOT_SQUASH
|
||||
|
||||
enum {
|
||||
DQF_INFO_DIRTY_B = DQF_PRIVATE,
|
||||
};
|
||||
#define DQF_INFO_DIRTY (1 << DQF_INFO_DIRTY_B) /* Is info dirty? */
|
||||
|
||||
extern void mark_info_dirty(struct super_block *sb, int type);
|
||||
|
@ -367,15 +369,15 @@ struct qc_dqblk {
|
|||
/* Operations handling requests from userspace */
|
||||
struct quotactl_ops {
|
||||
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_enable)(struct super_block *, unsigned int);
|
||||
int (*quota_disable)(struct super_block *, unsigned int);
|
||||
int (*quota_sync)(struct super_block *, int);
|
||||
int (*get_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 (*set_dqblk)(struct super_block *, struct kqid, struct qc_dqblk *);
|
||||
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 (*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 quotactl_ops dquot_quotactl_ops;
|
||||
extern const struct quotactl_ops dquot_quotactl_sysfile_ops;
|
||||
|
||||
#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);
|
||||
}
|
||||
|
||||
unsigned int qtype_enforce_flag(int type);
|
||||
|
||||
#endif /* _LINUX_QUOTAOPS_ */
|
||||
|
|
|
@ -126,10 +126,22 @@ struct if_dqblk {
|
|||
#define IIF_FLAGS 4
|
||||
#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 {
|
||||
__u64 dqi_bgrace;
|
||||
__u64 dqi_igrace;
|
||||
__u32 dqi_flags;
|
||||
__u32 dqi_flags; /* DFQ_* */
|
||||
__u32 dqi_valid;
|
||||
};
|
||||
|
||||
|
|
Loading…
Reference in New Issue