@@ -2385,6 +2385,86 @@ int dquot_quota_on_mount(struct super_block *sb, char *qf_name,
2385
2385
}
2386
2386
EXPORT_SYMBOL (dquot_quota_on_mount );
2387
2387
2388
+ static int dquot_quota_enable (struct super_block * sb , unsigned int flags )
2389
+ {
2390
+ int ret ;
2391
+ int type ;
2392
+ struct quota_info * dqopt = sb_dqopt (sb );
2393
+
2394
+ if (!(dqopt -> flags & DQUOT_QUOTA_SYS_FILE ))
2395
+ return - ENOSYS ;
2396
+ /* Accounting cannot be turned on while fs is mounted */
2397
+ flags &= ~(FS_QUOTA_UDQ_ACCT | FS_QUOTA_GDQ_ACCT | FS_QUOTA_PDQ_ACCT );
2398
+ if (!flags )
2399
+ return - EINVAL ;
2400
+ for (type = 0 ; type < MAXQUOTAS ; type ++ ) {
2401
+ if (!(flags & qtype_enforce_flag (type )))
2402
+ continue ;
2403
+ /* Can't enforce without accounting */
2404
+ if (!sb_has_quota_usage_enabled (sb , type ))
2405
+ return - EINVAL ;
2406
+ ret = dquot_enable (dqopt -> files [type ], type ,
2407
+ dqopt -> info [type ].dqi_fmt_id ,
2408
+ DQUOT_LIMITS_ENABLED );
2409
+ if (ret < 0 )
2410
+ goto out_err ;
2411
+ }
2412
+ return 0 ;
2413
+ out_err :
2414
+ /* Backout enforcement enablement we already did */
2415
+ for (type -- ; type >= 0 ; type -- ) {
2416
+ if (flags & qtype_enforce_flag (type ))
2417
+ dquot_disable (sb , type , DQUOT_LIMITS_ENABLED );
2418
+ }
2419
+ /* Error code translation for better compatibility with XFS */
2420
+ if (ret == - EBUSY )
2421
+ ret = - EEXIST ;
2422
+ return ret ;
2423
+ }
2424
+
2425
+ static int dquot_quota_disable (struct super_block * sb , unsigned int flags )
2426
+ {
2427
+ int ret ;
2428
+ int type ;
2429
+ struct quota_info * dqopt = sb_dqopt (sb );
2430
+
2431
+ if (!(dqopt -> flags & DQUOT_QUOTA_SYS_FILE ))
2432
+ return - ENOSYS ;
2433
+ /*
2434
+ * We don't support turning off accounting via quotactl. In principle
2435
+ * quota infrastructure can do this but filesystems don't expect
2436
+ * userspace to be able to do it.
2437
+ */
2438
+ if (flags &
2439
+ (FS_QUOTA_UDQ_ACCT | FS_QUOTA_GDQ_ACCT | FS_QUOTA_PDQ_ACCT ))
2440
+ return - EOPNOTSUPP ;
2441
+
2442
+ /* Filter out limits not enabled */
2443
+ for (type = 0 ; type < MAXQUOTAS ; type ++ )
2444
+ if (!sb_has_quota_limits_enabled (sb , type ))
2445
+ flags &= ~qtype_enforce_flag (type );
2446
+ /* Nothing left? */
2447
+ if (!flags )
2448
+ return - EEXIST ;
2449
+ for (type = 0 ; type < MAXQUOTAS ; type ++ ) {
2450
+ if (flags & qtype_enforce_flag (type )) {
2451
+ ret = dquot_disable (sb , type , DQUOT_LIMITS_ENABLED );
2452
+ if (ret < 0 )
2453
+ goto out_err ;
2454
+ }
2455
+ }
2456
+ return 0 ;
2457
+ out_err :
2458
+ /* Backout enforcement disabling we already did */
2459
+ for (type -- ; type >= 0 ; type -- ) {
2460
+ if (flags & qtype_enforce_flag (type ))
2461
+ dquot_enable (dqopt -> files [type ], type ,
2462
+ dqopt -> info [type ].dqi_fmt_id ,
2463
+ DQUOT_LIMITS_ENABLED );
2464
+ }
2465
+ return ret ;
2466
+ }
2467
+
2388
2468
static inline qsize_t qbtos (qsize_t blocks )
2389
2469
{
2390
2470
return blocks << QIF_DQBLKSIZE_BITS ;
@@ -2614,6 +2694,17 @@ const struct quotactl_ops dquot_quotactl_ops = {
2614
2694
};
2615
2695
EXPORT_SYMBOL (dquot_quotactl_ops );
2616
2696
2697
+ const struct quotactl_ops dquot_quotactl_sysfile_ops = {
2698
+ .quota_enable = dquot_quota_enable ,
2699
+ .quota_disable = dquot_quota_disable ,
2700
+ .quota_sync = dquot_quota_sync ,
2701
+ .get_info = dquot_get_dqinfo ,
2702
+ .set_info = dquot_set_dqinfo ,
2703
+ .get_dqblk = dquot_get_dqblk ,
2704
+ .set_dqblk = dquot_set_dqblk
2705
+ };
2706
+ EXPORT_SYMBOL (dquot_quotactl_sysfile_ops );
2707
+
2617
2708
static int do_proc_dqstats (struct ctl_table * table , int write ,
2618
2709
void __user * buffer , size_t * lenp , loff_t * ppos )
2619
2710
{
0 commit comments