Merge branch 'for_linus' of git://git.kernel.org/pub/scm/linux/kernel/git/jack/linux-fs
Pull UDF and quota updates from Jan Kara: "This contains a rewrite of UDF handling of filename encoding to fix remaining overflow issues from Andrew Gabbasov and quota changes to support new Q_[X]GETNEXTQUOTA quotactl for VFS quota formats" * 'for_linus' of git://git.kernel.org/pub/scm/linux/kernel/git/jack/linux-fs: quota: Fix possible GPF due to uninitialised pointers ext4: Make Q_GETNEXTQUOTA work for quota in hidden inodes quota: Forbid Q_GETQUOTA and Q_GETNEXTQUOTA for frozen filesystem quota: Fix possible races during quota loading ocfs2: Implement get_next_id() quota_v2: Implement get_next_id() for V2 quota format quota: Add support for ->get_nextdqblk() for VFS quota udf: Merge linux specific translation into CS0 conversion function udf: Remove struct ustr as non-needed intermediate storage udf: Use separate buffer for copying split names udf: Adjust UDF_NAME_LEN to better reflect actual restrictions udf: Join functions for UTF8 and NLS conversions udf: Parameterize output length in udf_put_filename quota: Allow Q_GETQUOTA for frozen filesystem quota: Fixup comments about return value of Q_[X]GETNEXTQUOTA
This commit is contained in:
@@ -411,6 +411,8 @@ int dquot_acquire(struct dquot *dquot)
|
||||
ret = dqopt->ops[dquot->dq_id.type]->read_dqblk(dquot);
|
||||
if (ret < 0)
|
||||
goto out_iolock;
|
||||
/* Make sure flags update is visible after dquot has been filled */
|
||||
smp_mb__before_atomic();
|
||||
set_bit(DQ_READ_B, &dquot->dq_flags);
|
||||
/* Instantiate dquot if needed */
|
||||
if (!test_bit(DQ_ACTIVE_B, &dquot->dq_flags) && !dquot->dq_off) {
|
||||
@@ -427,6 +429,11 @@ int dquot_acquire(struct dquot *dquot)
|
||||
goto out_iolock;
|
||||
}
|
||||
}
|
||||
/*
|
||||
* Make sure flags update is visible after on-disk struct has been
|
||||
* allocated. Paired with smp_rmb() in dqget().
|
||||
*/
|
||||
smp_mb__before_atomic();
|
||||
set_bit(DQ_ACTIVE_B, &dquot->dq_flags);
|
||||
out_iolock:
|
||||
mutex_unlock(&dqopt->dqio_mutex);
|
||||
@@ -887,6 +894,11 @@ we_slept:
|
||||
goto out;
|
||||
}
|
||||
}
|
||||
/*
|
||||
* Make sure following reads see filled structure - paired with
|
||||
* smp_mb__before_atomic() in dquot_acquire().
|
||||
*/
|
||||
smp_rmb();
|
||||
#ifdef CONFIG_QUOTA_DEBUG
|
||||
BUG_ON(!dquot->dq_sb); /* Has somebody invalidated entry under us? */
|
||||
#endif
|
||||
@@ -1398,7 +1410,7 @@ static int dquot_active(const struct inode *inode)
|
||||
static int __dquot_initialize(struct inode *inode, int type)
|
||||
{
|
||||
int cnt, init_needed = 0;
|
||||
struct dquot **dquots, *got[MAXQUOTAS];
|
||||
struct dquot **dquots, *got[MAXQUOTAS] = {};
|
||||
struct super_block *sb = inode->i_sb;
|
||||
qsize_t rsv;
|
||||
int ret = 0;
|
||||
@@ -1415,7 +1427,6 @@ static int __dquot_initialize(struct inode *inode, int type)
|
||||
int rc;
|
||||
struct dquot *dquot;
|
||||
|
||||
got[cnt] = NULL;
|
||||
if (type != -1 && cnt != type)
|
||||
continue;
|
||||
/*
|
||||
@@ -2031,6 +2042,21 @@ int dquot_commit_info(struct super_block *sb, int type)
|
||||
}
|
||||
EXPORT_SYMBOL(dquot_commit_info);
|
||||
|
||||
int dquot_get_next_id(struct super_block *sb, struct kqid *qid)
|
||||
{
|
||||
struct quota_info *dqopt = sb_dqopt(sb);
|
||||
int err;
|
||||
|
||||
if (!dqopt->ops[qid->type]->get_next_id)
|
||||
return -ENOSYS;
|
||||
mutex_lock(&dqopt->dqio_mutex);
|
||||
err = dqopt->ops[qid->type]->get_next_id(sb, qid);
|
||||
mutex_unlock(&dqopt->dqio_mutex);
|
||||
|
||||
return err;
|
||||
}
|
||||
EXPORT_SYMBOL(dquot_get_next_id);
|
||||
|
||||
/*
|
||||
* Definitions of diskquota operations.
|
||||
*/
|
||||
@@ -2042,6 +2068,7 @@ const struct dquot_operations dquot_operations = {
|
||||
.write_info = dquot_commit_info,
|
||||
.alloc_dquot = dquot_alloc,
|
||||
.destroy_dquot = dquot_destroy,
|
||||
.get_next_id = dquot_get_next_id,
|
||||
};
|
||||
EXPORT_SYMBOL(dquot_operations);
|
||||
|
||||
@@ -2563,6 +2590,27 @@ int dquot_get_dqblk(struct super_block *sb, struct kqid qid,
|
||||
}
|
||||
EXPORT_SYMBOL(dquot_get_dqblk);
|
||||
|
||||
int dquot_get_next_dqblk(struct super_block *sb, struct kqid *qid,
|
||||
struct qc_dqblk *di)
|
||||
{
|
||||
struct dquot *dquot;
|
||||
int err;
|
||||
|
||||
if (!sb->dq_op->get_next_id)
|
||||
return -ENOSYS;
|
||||
err = sb->dq_op->get_next_id(sb, qid);
|
||||
if (err < 0)
|
||||
return err;
|
||||
dquot = dqget(sb, *qid);
|
||||
if (IS_ERR(dquot))
|
||||
return PTR_ERR(dquot);
|
||||
do_get_dqblk(dquot, di);
|
||||
dqput(dquot);
|
||||
|
||||
return 0;
|
||||
}
|
||||
EXPORT_SYMBOL(dquot_get_next_dqblk);
|
||||
|
||||
#define VFS_QC_MASK \
|
||||
(QC_SPACE | QC_SPC_SOFT | QC_SPC_HARD | \
|
||||
QC_INO_COUNT | QC_INO_SOFT | QC_INO_HARD | \
|
||||
@@ -2763,6 +2811,7 @@ const struct quotactl_ops dquot_quotactl_ops = {
|
||||
.get_state = dquot_get_state,
|
||||
.set_info = dquot_set_dqinfo,
|
||||
.get_dqblk = dquot_get_dqblk,
|
||||
.get_nextdqblk = dquot_get_next_dqblk,
|
||||
.set_dqblk = dquot_set_dqblk
|
||||
};
|
||||
EXPORT_SYMBOL(dquot_quotactl_ops);
|
||||
@@ -2774,6 +2823,7 @@ const struct quotactl_ops dquot_quotactl_sysfile_ops = {
|
||||
.get_state = dquot_get_state,
|
||||
.set_info = dquot_set_dqinfo,
|
||||
.get_dqblk = dquot_get_dqblk,
|
||||
.get_nextdqblk = dquot_get_next_dqblk,
|
||||
.set_dqblk = dquot_set_dqblk
|
||||
};
|
||||
EXPORT_SYMBOL(dquot_quotactl_sysfile_ops);
|
||||
|
Reference in New Issue
Block a user