diff options
Diffstat (limited to 'fs/quota/dquot.c')
-rw-r--r-- | fs/quota/dquot.c | 130 |
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 */ | ||
1077 | static 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 */ | ||
1086 | static 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 | "a_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; | ||
1135 | attr_err_out: | ||
1136 | printk(KERN_ERR "VFS: Not enough space to compose quota message!\n"); | ||
1137 | err_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 | */ |
1146 | static void flush_warnings(struct dquot *const *dquots, char *warntype) | 1075 | static 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 | ||
1162 | static int ignore_hardlimit(struct dquot *dquot) | 1093 | static 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 | ||
2474 | static ctl_table fs_dqstats_table[] = { | 2407 | static 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 | ||
2552 | static ctl_table fs_table[] = { | 2476 | static 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 | ||
2562 | static ctl_table sys_table[] = { | 2485 | static 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 | ||
2572 | static int __init dquot_init(void) | 2494 | static 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("a_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 | } |
2618 | module_init(dquot_init); | 2534 | module_init(dquot_init); |