xfs: fix Q_XQUOTARM ioctl
The Q_XQUOTARM quotactl was not working properly, because we weren't passing around proper flags. The xfs_fs_set_xstate() ioctl handler used the same flags for Q_XQUOTAON/OFF as well as for Q_XQUOTARM, but Q_XQUOTAON/OFF look for XFS_UQUOTA_ACCT, XFS_UQUOTA_ENFD, XFS_GQUOTA_ACCT etc, i.e. quota type + state, while Q_XQUOTARM looks only for the type of quota, i.e. XFS_DQ_USER, XFS_DQ_GROUP etc. Unfortunately these flag spaces overlap a bit, so we got semi-random results for Q_XQUOTARM; i.e. the value for XFS_DQ_USER == XFS_UQUOTA_ACCT, etc. yeargh. Add a new quotactl op vector specifically for the QUOTARM operation, since it operates with a different flag space. This has been broken more or less forever, AFAICT. Signed-off-by: Eric Sandeen <sandeen@redhat.com> Acked-by: Jan Kara <jack@suse.cz> Reviewed-by: Christoph Hellwig <hch@lst.de> Signed-off-by: Dave Chinner <david@fromorbit.com>
This commit is contained in:

committed by
Dave Chinner

parent
c9eaa447e7
commit
9da93f9b7c
@@ -278,6 +278,17 @@ static int quota_getxquota(struct super_block *sb, int type, qid_t id,
|
||||
return ret;
|
||||
}
|
||||
|
||||
static int quota_rmxquota(struct super_block *sb, void __user *addr)
|
||||
{
|
||||
__u32 flags;
|
||||
|
||||
if (copy_from_user(&flags, addr, sizeof(flags)))
|
||||
return -EFAULT;
|
||||
if (!sb->s_qcop->rm_xquota)
|
||||
return -ENOSYS;
|
||||
return sb->s_qcop->rm_xquota(sb, flags);
|
||||
}
|
||||
|
||||
/* Copy parameters and call proper function */
|
||||
static int do_quotactl(struct super_block *sb, int type, int cmd, qid_t id,
|
||||
void __user *addr, struct path *path)
|
||||
@@ -316,8 +327,9 @@ static int do_quotactl(struct super_block *sb, int type, int cmd, qid_t id,
|
||||
return sb->s_qcop->quota_sync(sb, type);
|
||||
case Q_XQUOTAON:
|
||||
case Q_XQUOTAOFF:
|
||||
case Q_XQUOTARM:
|
||||
return quota_setxstate(sb, cmd, addr);
|
||||
case Q_XQUOTARM:
|
||||
return quota_rmxquota(sb, addr);
|
||||
case Q_XGETQSTAT:
|
||||
return quota_getxstate(sb, addr);
|
||||
case Q_XGETQSTATV:
|
||||
|
Reference in New Issue
Block a user