aboutsummaryrefslogtreecommitdiffstats
path: root/fs/quota/dquot.c
diff options
context:
space:
mode:
Diffstat (limited to 'fs/quota/dquot.c')
-rw-r--r--fs/quota/dquot.c130
1 files changed, 23 insertions, 107 deletions
diff --git a/fs/quota/dquot.c b/fs/quota/dquot.c
index 39b49c42a7ed..cd6bb9a33c13 100644
--- a/fs/quota/dquot.c
+++ b/fs/quota/dquot.c
@@ -77,10 +77,6 @@
77#include <linux/capability.h> 77#include <linux/capability.h>
78#include <linux/quotaops.h> 78#include <linux/quotaops.h>
79#include <linux/writeback.h> /* for inode_lock, oddly enough.. */ 79#include <linux/writeback.h> /* for inode_lock, oddly enough.. */
80#ifdef CONFIG_QUOTA_NETLINK_INTERFACE
81#include <net/netlink.h>
82#include <net/genetlink.h>
83#endif
84 80
85#include <asm/uaccess.h> 81#include <asm/uaccess.h>
86 82
@@ -1071,73 +1067,6 @@ static void print_warning(struct dquot *dquot, const int warntype)
1071} 1067}
1072#endif 1068#endif
1073 1069
1074#ifdef CONFIG_QUOTA_NETLINK_INTERFACE
1075
1076/* Netlink family structure for quota */
1077static struct genl_family quota_genl_family = {
1078 .id = GENL_ID_GENERATE,
1079 .hdrsize = 0,
1080 .name = "VFS_DQUOT",
1081 .version = 1,
1082 .maxattr = QUOTA_NL_A_MAX,
1083};
1084
1085/* Send warning to userspace about user which exceeded quota */
1086static void send_warning(const struct dquot *dquot, const char warntype)
1087{
1088 static atomic_t seq;
1089 struct sk_buff *skb;
1090 void *msg_head;
1091 int ret;
1092 int msg_size = 4 * nla_total_size(sizeof(u32)) +
1093 2 * nla_total_size(sizeof(u64));
1094
1095 /* We have to allocate using GFP_NOFS as we are called from a
1096 * filesystem performing write and thus further recursion into
1097 * the fs to free some data could cause deadlocks. */
1098 skb = genlmsg_new(msg_size, GFP_NOFS);
1099 if (!skb) {
1100 printk(KERN_ERR
1101 "VFS: Not enough memory to send quota warning.\n");
1102 return;
1103 }
1104 msg_head = genlmsg_put(skb, 0, atomic_add_return(1, &seq),
1105 &quota_genl_family, 0, QUOTA_NL_C_WARNING);
1106 if (!msg_head) {
1107 printk(KERN_ERR
1108 "VFS: Cannot store netlink header in quota warning.\n");
1109 goto err_out;
1110 }
1111 ret = nla_put_u32(skb, QUOTA_NL_A_QTYPE, dquot->dq_type);
1112 if (ret)
1113 goto attr_err_out;
1114 ret = nla_put_u64(skb, QUOTA_NL_A_EXCESS_ID, dquot->dq_id);
1115 if (ret)
1116 goto attr_err_out;
1117 ret = nla_put_u32(skb, QUOTA_NL_A_WARNING, warntype);
1118 if (ret)
1119 goto attr_err_out;
1120 ret = nla_put_u32(skb, QUOTA_NL_A_DEV_MAJOR,
1121 MAJOR(dquot->dq_sb->s_dev));
1122 if (ret)
1123 goto attr_err_out;
1124 ret = nla_put_u32(skb, QUOTA_NL_A_DEV_MINOR,
1125 MINOR(dquot->dq_sb->s_dev));
1126 if (ret)
1127 goto attr_err_out;
1128 ret = nla_put_u64(skb, QUOTA_NL_A_CAUSED_ID, current_uid());
1129 if (ret)
1130 goto attr_err_out;
1131 genlmsg_end(skb, msg_head);
1132
1133 genlmsg_multicast(skb, 0, quota_genl_family.id, GFP_NOFS);
1134 return;
1135attr_err_out:
1136 printk(KERN_ERR "VFS: Not enough space to compose quota message!\n");
1137err_out:
1138 kfree_skb(skb);
1139}
1140#endif
1141/* 1070/*
1142 * Write warnings to the console and send warning messages over netlink. 1071 * Write warnings to the console and send warning messages over netlink.
1143 * 1072 *
@@ -1145,18 +1074,20 @@ err_out:
1145 */ 1074 */
1146static void flush_warnings(struct dquot *const *dquots, char *warntype) 1075static void flush_warnings(struct dquot *const *dquots, char *warntype)
1147{ 1076{
1077 struct dquot *dq;
1148 int i; 1078 int i;
1149 1079
1150 for (i = 0; i < MAXQUOTAS; i++) 1080 for (i = 0; i < MAXQUOTAS; i++) {
1151 if (dquots[i] && warntype[i] != QUOTA_NL_NOWARN && 1081 dq = dquots[i];
1152 !warning_issued(dquots[i], warntype[i])) { 1082 if (dq && warntype[i] != QUOTA_NL_NOWARN &&
1083 !warning_issued(dq, warntype[i])) {
1153#ifdef CONFIG_PRINT_QUOTA_WARNING 1084#ifdef CONFIG_PRINT_QUOTA_WARNING
1154 print_warning(dquots[i], warntype[i]); 1085 print_warning(dq, warntype[i]);
1155#endif
1156#ifdef CONFIG_QUOTA_NETLINK_INTERFACE
1157 send_warning(dquots[i], warntype[i]);
1158#endif 1086#endif
1087 quota_send_warning(dq->dq_type, dq->dq_id,
1088 dq->dq_sb->s_dev, warntype[i]);
1159 } 1089 }
1090 }
1160} 1091}
1161 1092
1162static int ignore_hardlimit(struct dquot *dquot) 1093static int ignore_hardlimit(struct dquot *dquot)
@@ -2233,7 +2164,9 @@ int vfs_quota_on_mount(struct super_block *sb, char *qf_name,
2233 struct dentry *dentry; 2164 struct dentry *dentry;
2234 int error; 2165 int error;
2235 2166
2167 mutex_lock(&sb->s_root->d_inode->i_mutex);
2236 dentry = lookup_one_len(qf_name, sb->s_root, strlen(qf_name)); 2168 dentry = lookup_one_len(qf_name, sb->s_root, strlen(qf_name));
2169 mutex_unlock(&sb->s_root->d_inode->i_mutex);
2237 if (IS_ERR(dentry)) 2170 if (IS_ERR(dentry))
2238 return PTR_ERR(dentry); 2171 return PTR_ERR(dentry);
2239 2172
@@ -2473,100 +2406,89 @@ const struct quotactl_ops vfs_quotactl_ops = {
2473 2406
2474static ctl_table fs_dqstats_table[] = { 2407static ctl_table fs_dqstats_table[] = {
2475 { 2408 {
2476 .ctl_name = FS_DQ_LOOKUPS,
2477 .procname = "lookups", 2409 .procname = "lookups",
2478 .data = &dqstats.lookups, 2410 .data = &dqstats.lookups,
2479 .maxlen = sizeof(int), 2411 .maxlen = sizeof(int),
2480 .mode = 0444, 2412 .mode = 0444,
2481 .proc_handler = &proc_dointvec, 2413 .proc_handler = proc_dointvec,
2482 }, 2414 },
2483 { 2415 {
2484 .ctl_name = FS_DQ_DROPS,
2485 .procname = "drops", 2416 .procname = "drops",
2486 .data = &dqstats.drops, 2417 .data = &dqstats.drops,
2487 .maxlen = sizeof(int), 2418 .maxlen = sizeof(int),
2488 .mode = 0444, 2419 .mode = 0444,
2489 .proc_handler = &proc_dointvec, 2420 .proc_handler = proc_dointvec,
2490 }, 2421 },
2491 { 2422 {
2492 .ctl_name = FS_DQ_READS,
2493 .procname = "reads", 2423 .procname = "reads",
2494 .data = &dqstats.reads, 2424 .data = &dqstats.reads,
2495 .maxlen = sizeof(int), 2425 .maxlen = sizeof(int),
2496 .mode = 0444, 2426 .mode = 0444,
2497 .proc_handler = &proc_dointvec, 2427 .proc_handler = proc_dointvec,
2498 }, 2428 },
2499 { 2429 {
2500 .ctl_name = FS_DQ_WRITES,
2501 .procname = "writes", 2430 .procname = "writes",
2502 .data = &dqstats.writes, 2431 .data = &dqstats.writes,
2503 .maxlen = sizeof(int), 2432 .maxlen = sizeof(int),
2504 .mode = 0444, 2433 .mode = 0444,
2505 .proc_handler = &proc_dointvec, 2434 .proc_handler = proc_dointvec,
2506 }, 2435 },
2507 { 2436 {
2508 .ctl_name = FS_DQ_CACHE_HITS,
2509 .procname = "cache_hits", 2437 .procname = "cache_hits",
2510 .data = &dqstats.cache_hits, 2438 .data = &dqstats.cache_hits,
2511 .maxlen = sizeof(int), 2439 .maxlen = sizeof(int),
2512 .mode = 0444, 2440 .mode = 0444,
2513 .proc_handler = &proc_dointvec, 2441 .proc_handler = proc_dointvec,
2514 }, 2442 },
2515 { 2443 {
2516 .ctl_name = FS_DQ_ALLOCATED,
2517 .procname = "allocated_dquots", 2444 .procname = "allocated_dquots",
2518 .data = &dqstats.allocated_dquots, 2445 .data = &dqstats.allocated_dquots,
2519 .maxlen = sizeof(int), 2446 .maxlen = sizeof(int),
2520 .mode = 0444, 2447 .mode = 0444,
2521 .proc_handler = &proc_dointvec, 2448 .proc_handler = proc_dointvec,
2522 }, 2449 },
2523 { 2450 {
2524 .ctl_name = FS_DQ_FREE,
2525 .procname = "free_dquots", 2451 .procname = "free_dquots",
2526 .data = &dqstats.free_dquots, 2452 .data = &dqstats.free_dquots,
2527 .maxlen = sizeof(int), 2453 .maxlen = sizeof(int),
2528 .mode = 0444, 2454 .mode = 0444,
2529 .proc_handler = &proc_dointvec, 2455 .proc_handler = proc_dointvec,
2530 }, 2456 },
2531 { 2457 {
2532 .ctl_name = FS_DQ_SYNCS,
2533 .procname = "syncs", 2458 .procname = "syncs",
2534 .data = &dqstats.syncs, 2459 .data = &dqstats.syncs,
2535 .maxlen = sizeof(int), 2460 .maxlen = sizeof(int),
2536 .mode = 0444, 2461 .mode = 0444,
2537 .proc_handler = &proc_dointvec, 2462 .proc_handler = proc_dointvec,
2538 }, 2463 },
2539#ifdef CONFIG_PRINT_QUOTA_WARNING 2464#ifdef CONFIG_PRINT_QUOTA_WARNING
2540 { 2465 {
2541 .ctl_name = FS_DQ_WARNINGS,
2542 .procname = "warnings", 2466 .procname = "warnings",
2543 .data = &flag_print_warnings, 2467 .data = &flag_print_warnings,
2544 .maxlen = sizeof(int), 2468 .maxlen = sizeof(int),
2545 .mode = 0644, 2469 .mode = 0644,
2546 .proc_handler = &proc_dointvec, 2470 .proc_handler = proc_dointvec,
2547 }, 2471 },
2548#endif 2472#endif
2549 { .ctl_name = 0 }, 2473 { },
2550}; 2474};
2551 2475
2552static ctl_table fs_table[] = { 2476static ctl_table fs_table[] = {
2553 { 2477 {
2554 .ctl_name = FS_DQSTATS,
2555 .procname = "quota", 2478 .procname = "quota",
2556 .mode = 0555, 2479 .mode = 0555,
2557 .child = fs_dqstats_table, 2480 .child = fs_dqstats_table,
2558 }, 2481 },
2559 { .ctl_name = 0 }, 2482 { },
2560}; 2483};
2561 2484
2562static ctl_table sys_table[] = { 2485static ctl_table sys_table[] = {
2563 { 2486 {
2564 .ctl_name = CTL_FS,
2565 .procname = "fs", 2487 .procname = "fs",
2566 .mode = 0555, 2488 .mode = 0555,
2567 .child = fs_table, 2489 .child = fs_table,
2568 }, 2490 },
2569 { .ctl_name = 0 }, 2491 { },
2570}; 2492};
2571 2493
2572static int __init dquot_init(void) 2494static int __init dquot_init(void)
@@ -2607,12 +2529,6 @@ static int __init dquot_init(void)
2607 2529
2608 register_shrinker(&dqcache_shrinker); 2530 register_shrinker(&dqcache_shrinker);
2609 2531
2610#ifdef CONFIG_QUOTA_NETLINK_INTERFACE
2611 if (genl_register_family(&quota_genl_family) != 0)
2612 printk(KERN_ERR
2613 "VFS: Failed to create quota netlink interface.\n");
2614#endif
2615
2616 return 0; 2532 return 0;
2617} 2533}
2618module_init(dquot_init); 2534module_init(dquot_init);