aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorChristoph Hellwig <hch@infradead.org>2010-02-16 03:44:47 -0500
committerJan Kara <jack@suse.cz>2010-03-04 18:20:21 -0500
commitc411e5f66a5dd36827a5f9d1392a1afdf69ff075 (patch)
treeec15fda09302f281785675f4b9878e5360a49788
parent0a5a9c725512461d19397490f3adf29931dca1f2 (diff)
quota: split do_quotactl
Split out a helper for each non-trivial command from do_quotactl. Signed-off-by: Christoph Hellwig <hch@lst.de> Signed-off-by: Jan Kara <jack@suse.cz>
-rw-r--r--fs/quota/quota.c250
1 files changed, 146 insertions, 104 deletions
diff --git a/fs/quota/quota.c b/fs/quota/quota.c
index ee91e2756950..4d7fdc4443b9 100644
--- a/fs/quota/quota.c
+++ b/fs/quota/quota.c
@@ -234,122 +234,164 @@ restart:
234 spin_unlock(&sb_lock); 234 spin_unlock(&sb_lock);
235} 235}
236 236
237/* Copy parameters and call proper function */ 237static int quota_quotaon(struct super_block *sb, int type, int cmd, qid_t id,
238static int do_quotactl(struct super_block *sb, int type, int cmd, qid_t id, 238 void __user *addr)
239 void __user *addr)
240{ 239{
240 char *pathname;
241 int ret; 241 int ret;
242 242
243 switch (cmd) { 243 pathname = getname(addr);
244 case Q_QUOTAON: { 244 if (IS_ERR(pathname))
245 char *pathname; 245 return PTR_ERR(pathname);
246 246 ret = sb->s_qcop->quota_on(sb, type, id, pathname, 0);
247 pathname = getname(addr); 247 putname(pathname);
248 if (IS_ERR(pathname)) 248 return ret;
249 return PTR_ERR(pathname); 249}
250 ret = sb->s_qcop->quota_on(sb, type, id, pathname, 0);
251 putname(pathname);
252 return ret;
253 }
254 case Q_QUOTAOFF:
255 return sb->s_qcop->quota_off(sb, type, 0);
256 250
257 case Q_GETFMT: { 251static int quota_getfmt(struct super_block *sb, int type, void __user *addr)
258 __u32 fmt; 252{
253 __u32 fmt;
259 254
260 down_read(&sb_dqopt(sb)->dqptr_sem); 255 down_read(&sb_dqopt(sb)->dqptr_sem);
261 if (!sb_has_quota_active(sb, type)) { 256 if (!sb_has_quota_active(sb, type)) {
262 up_read(&sb_dqopt(sb)->dqptr_sem); 257 up_read(&sb_dqopt(sb)->dqptr_sem);
263 return -ESRCH; 258 return -ESRCH;
264 } 259 }
265 fmt = sb_dqopt(sb)->info[type].dqi_format->qf_fmt_id; 260 fmt = sb_dqopt(sb)->info[type].dqi_format->qf_fmt_id;
266 up_read(&sb_dqopt(sb)->dqptr_sem); 261 up_read(&sb_dqopt(sb)->dqptr_sem);
267 if (copy_to_user(addr, &fmt, sizeof(fmt))) 262 if (copy_to_user(addr, &fmt, sizeof(fmt)))
268 return -EFAULT; 263 return -EFAULT;
269 return 0; 264 return 0;
270 } 265}
271 case Q_GETINFO: {
272 struct if_dqinfo info;
273
274 ret = sb->s_qcop->get_info(sb, type, &info);
275 if (ret)
276 return ret;
277 if (copy_to_user(addr, &info, sizeof(info)))
278 return -EFAULT;
279 return 0;
280 }
281 case Q_SETINFO: {
282 struct if_dqinfo info;
283 266
284 if (copy_from_user(&info, addr, sizeof(info))) 267static int quota_getinfo(struct super_block *sb, int type, void __user *addr)
285 return -EFAULT; 268{
286 return sb->s_qcop->set_info(sb, type, &info); 269 struct if_dqinfo info;
287 } 270 int ret;
288 case Q_GETQUOTA: {
289 struct if_dqblk idq;
290
291 ret = sb->s_qcop->get_dqblk(sb, type, id, &idq);
292 if (ret)
293 return ret;
294 if (copy_to_user(addr, &idq, sizeof(idq)))
295 return -EFAULT;
296 return 0;
297 }
298 case Q_SETQUOTA: {
299 struct if_dqblk idq;
300 271
301 if (copy_from_user(&idq, addr, sizeof(idq))) 272 ret = sb->s_qcop->get_info(sb, type, &info);
302 return -EFAULT; 273 if (!ret && copy_to_user(addr, &info, sizeof(info)))
303 return sb->s_qcop->set_dqblk(sb, type, id, &idq); 274 return -EFAULT;
304 } 275 return ret;
305 case Q_SYNC: 276}
306 if (sb)
307 sync_quota_sb(sb, type);
308 else
309 sync_dquots(type);
310 return 0;
311 277
312 case Q_XQUOTAON: 278static int quota_setinfo(struct super_block *sb, int type, void __user *addr)
313 case Q_XQUOTAOFF: 279{
314 case Q_XQUOTARM: { 280 struct if_dqinfo info;
315 __u32 flags;
316 281
317 if (copy_from_user(&flags, addr, sizeof(flags))) 282 if (copy_from_user(&info, addr, sizeof(info)))
318 return -EFAULT; 283 return -EFAULT;
319 return sb->s_qcop->set_xstate(sb, flags, cmd); 284 return sb->s_qcop->set_info(sb, type, &info);
320 } 285}
321 case Q_XGETQSTAT: { 286
322 struct fs_quota_stat fqs; 287static int quota_getquota(struct super_block *sb, int type, qid_t id,
288 void __user *addr)
289{
290 struct if_dqblk idq;
291 int ret;
292
293 ret = sb->s_qcop->get_dqblk(sb, type, id, &idq);
294 if (ret)
295 return ret;
296 if (copy_to_user(addr, &idq, sizeof(idq)))
297 return -EFAULT;
298 return 0;
299}
300
301static int quota_setquota(struct super_block *sb, int type, qid_t id,
302 void __user *addr)
303{
304 struct if_dqblk idq;
305
306 if (copy_from_user(&idq, addr, sizeof(idq)))
307 return -EFAULT;
308 return sb->s_qcop->set_dqblk(sb, type, id, &idq);
309}
310
311static int quota_setxstate(struct super_block *sb, int cmd, void __user *addr)
312{
313 __u32 flags;
314
315 if (copy_from_user(&flags, addr, sizeof(flags)))
316 return -EFAULT;
317 return sb->s_qcop->set_xstate(sb, flags, cmd);
318}
319
320static int quota_getxstate(struct super_block *sb, void __user *addr)
321{
322 struct fs_quota_stat fqs;
323 int ret;
323 324
324 if ((ret = sb->s_qcop->get_xstate(sb, &fqs))) 325 ret = sb->s_qcop->get_xstate(sb, &fqs);
325 return ret; 326 if (!ret && copy_to_user(addr, &fqs, sizeof(fqs)))
326 if (copy_to_user(addr, &fqs, sizeof(fqs))) 327 return -EFAULT;
327 return -EFAULT; 328 return ret;
328 return 0; 329}
329 }
330 case Q_XSETQLIM: {
331 struct fs_disk_quota fdq;
332 330
333 if (copy_from_user(&fdq, addr, sizeof(fdq))) 331static int quota_setxquota(struct super_block *sb, int type, qid_t id,
334 return -EFAULT; 332 void __user *addr)
335 return sb->s_qcop->set_xquota(sb, type, id, &fdq); 333{
336 } 334 struct fs_disk_quota fdq;
337 case Q_XGETQUOTA: { 335
338 struct fs_disk_quota fdq; 336 if (copy_from_user(&fdq, addr, sizeof(fdq)))
339 337 return -EFAULT;
340 ret = sb->s_qcop->get_xquota(sb, type, id, &fdq); 338 return sb->s_qcop->set_xquota(sb, type, id, &fdq);
341 if (ret) 339}
342 return ret; 340
343 if (copy_to_user(addr, &fdq, sizeof(fdq))) 341static int quota_getxquota(struct super_block *sb, int type, qid_t id,
344 return -EFAULT; 342 void __user *addr)
345 return 0; 343{
346 } 344 struct fs_disk_quota fdq;
347 case Q_XQUOTASYNC: 345 int ret;
348 return sb->s_qcop->quota_sync(sb, type); 346
349 /* We never reach here unless validity check is broken */ 347 ret = sb->s_qcop->get_xquota(sb, type, id, &fdq);
350 default: 348 if (!ret && copy_to_user(addr, &fdq, sizeof(fdq)))
351 BUG(); 349 return -EFAULT;
350 return ret;
351}
352
353/* Copy parameters and call proper function */
354static int do_quotactl(struct super_block *sb, int type, int cmd, qid_t id,
355 void __user *addr)
356{
357 switch (cmd) {
358 case Q_QUOTAON:
359 return quota_quotaon(sb, type, cmd, id, addr);
360 case Q_QUOTAOFF:
361 return sb->s_qcop->quota_off(sb, type, 0);
362 case Q_GETFMT:
363 return quota_getfmt(sb, type, addr);
364 case Q_GETINFO:
365 return quota_getinfo(sb, type, addr);
366 case Q_SETINFO:
367 return quota_setinfo(sb, type, addr);
368 case Q_GETQUOTA:
369 return quota_getquota(sb, type, id, addr);
370 case Q_SETQUOTA:
371 return quota_setquota(sb, type, id, addr);
372 case Q_SYNC:
373 if (sb)
374 sync_quota_sb(sb, type);
375 else
376 sync_dquots(type);
377 return 0;
378 case Q_XQUOTAON:
379 case Q_XQUOTAOFF:
380 case Q_XQUOTARM:
381 return quota_setxstate(sb, cmd, addr);
382 case Q_XGETQSTAT:
383 return quota_getxstate(sb, addr);
384 case Q_XSETQLIM:
385 return quota_setxquota(sb, type, id, addr);
386 case Q_XGETQUOTA:
387 return quota_getxquota(sb, type, id, addr);
388 case Q_XQUOTASYNC:
389 return sb->s_qcop->quota_sync(sb, type);
390 /* We never reach here unless validity check is broken */
391 default:
392 BUG();
352 } 393 }
394
353 return 0; 395 return 0;
354} 396}
355 397