aboutsummaryrefslogtreecommitdiffstats
path: root/fs
diff options
context:
space:
mode:
authorChandra Seetharaman <sekharan@us.ibm.com>2013-08-06 18:27:07 -0400
committerBen Myers <bpm@sgi.com>2013-08-20 17:53:58 -0400
commitaf30cb446dd5f4ad5b93d7d4188c49a864c0d643 (patch)
tree44e7d582ecffbcb91310a271ba80b218efdce9eb /fs
parentc2bfbc9b485a750b6af4a97ff3ad22b576e74d20 (diff)
quota: Add a new quotactl command Q_XGETQSTATV
XFS now supports three types of quotas (user, group and project). Current version of Q_XGETSTAT has support for only two types of quotas. In order to support three types of quotas, the interface, specifically struct fs_quota_stat, need to be expanded. Current version of fs_quota_stat does not allow expansion without breaking backward compatibility. So, a quotactl command and new fs_quota_stat structure need to be added. This patch adds a new command Q_XGETQSTATV to quotactl() which takes a new data structure fs_quota_statv. This new data structure provides support for future expansion and backward compatibility. Callers of the new quotactl command have to set the version of the data structure being passed, and kernel will fill as much data as requested. If the kernel does not support the user-space provided version, EINVAL will be returned. User-space can reduce the version number and call the same quotactl again. Signed-off-by: Chandra Seetharaman <sekharan@us.ibm.com> Reviewed-by: Jan Kara <jack@suse.cz> Reviewed-by: Rich Johnston <rjohnston@sgi.com> Signed-off-by: Ben Myers <bpm@sgi.com> [v2: Applied rjohnston's suggestions as per Chandra's request. -bpm]
Diffstat (limited to 'fs')
-rw-r--r--fs/quota/quota.c29
1 files changed, 29 insertions, 0 deletions
diff --git a/fs/quota/quota.c b/fs/quota/quota.c
index c7314f1771f5..dea86e8967ee 100644
--- a/fs/quota/quota.c
+++ b/fs/quota/quota.c
@@ -27,6 +27,7 @@ static int check_quotactl_permission(struct super_block *sb, int type, int cmd,
27 case Q_SYNC: 27 case Q_SYNC:
28 case Q_GETINFO: 28 case Q_GETINFO:
29 case Q_XGETQSTAT: 29 case Q_XGETQSTAT:
30 case Q_XGETQSTATV:
30 case Q_XQUOTASYNC: 31 case Q_XQUOTASYNC:
31 break; 32 break;
32 /* allow to query information for dquots we "own" */ 33 /* allow to query information for dquots we "own" */
@@ -217,6 +218,31 @@ static int quota_getxstate(struct super_block *sb, void __user *addr)
217 return ret; 218 return ret;
218} 219}
219 220
221static int quota_getxstatev(struct super_block *sb, void __user *addr)
222{
223 struct fs_quota_statv fqs;
224 int ret;
225
226 if (!sb->s_qcop->get_xstatev)
227 return -ENOSYS;
228
229 memset(&fqs, 0, sizeof(fqs));
230 if (copy_from_user(&fqs, addr, 1)) /* Just read qs_version */
231 return -EFAULT;
232
233 /* If this kernel doesn't support user specified version, fail */
234 switch (fqs.qs_version) {
235 case FS_QSTATV_VERSION1:
236 break;
237 default:
238 return -EINVAL;
239 }
240 ret = sb->s_qcop->get_xstatev(sb, &fqs);
241 if (!ret && copy_to_user(addr, &fqs, sizeof(fqs)))
242 return -EFAULT;
243 return ret;
244}
245
220static int quota_setxquota(struct super_block *sb, int type, qid_t id, 246static int quota_setxquota(struct super_block *sb, int type, qid_t id,
221 void __user *addr) 247 void __user *addr)
222{ 248{
@@ -293,6 +319,8 @@ static int do_quotactl(struct super_block *sb, int type, int cmd, qid_t id,
293 return quota_setxstate(sb, cmd, addr); 319 return quota_setxstate(sb, cmd, addr);
294 case Q_XGETQSTAT: 320 case Q_XGETQSTAT:
295 return quota_getxstate(sb, addr); 321 return quota_getxstate(sb, addr);
322 case Q_XGETQSTATV:
323 return quota_getxstatev(sb, addr);
296 case Q_XSETQLIM: 324 case Q_XSETQLIM:
297 return quota_setxquota(sb, type, id, addr); 325 return quota_setxquota(sb, type, id, addr);
298 case Q_XGETQUOTA: 326 case Q_XGETQUOTA:
@@ -317,6 +345,7 @@ static int quotactl_cmd_write(int cmd)
317 case Q_GETINFO: 345 case Q_GETINFO:
318 case Q_SYNC: 346 case Q_SYNC:
319 case Q_XGETQSTAT: 347 case Q_XGETQSTAT:
348 case Q_XGETQSTATV:
320 case Q_XGETQUOTA: 349 case Q_XGETQUOTA:
321 case Q_XQUOTASYNC: 350 case Q_XQUOTASYNC:
322 return 0; 351 return 0;