aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorChristoph Hellwig <hch@lst.de>2015-10-03 09:32:56 -0400
committerNicholas Bellinger <nab@linux-iscsi.org>2015-10-14 01:17:51 -0400
commitea9ed9cff47e7932925982c8fdaf2d4d1708884f (patch)
treea76e9b19182bc590b2bc579ba74aafad0b84c597
parent2eafd72939fda6118e27d3ee859684987f43921b (diff)
netconsole: use per-attribute show and store methods
Note that the old code actually used the store_attributes method to do locking, this is moved into the individual methods. Signed-off-by: Christoph Hellwig <hch@lst.de> Signed-off-by: Nicholas Bellinger <nab@linux-iscsi.org>
-rw-r--r--drivers/net/netconsole.c271
1 files changed, 132 insertions, 139 deletions
diff --git a/drivers/net/netconsole.c b/drivers/net/netconsole.c
index 97f3acd44798..06ee6395117f 100644
--- a/drivers/net/netconsole.c
+++ b/drivers/net/netconsole.c
@@ -244,15 +244,6 @@ static void free_param_target(struct netconsole_target *nt)
244 * <target>/... 244 * <target>/...
245 */ 245 */
246 246
247struct netconsole_target_attr {
248 struct configfs_attribute attr;
249 ssize_t (*show)(struct netconsole_target *nt,
250 char *buf);
251 ssize_t (*store)(struct netconsole_target *nt,
252 const char *buf,
253 size_t count);
254};
255
256static struct netconsole_target *to_target(struct config_item *item) 247static struct netconsole_target *to_target(struct config_item *item)
257{ 248{
258 return item ? 249 return item ?
@@ -264,58 +255,62 @@ static struct netconsole_target *to_target(struct config_item *item)
264 * Attribute operations for netconsole_target. 255 * Attribute operations for netconsole_target.
265 */ 256 */
266 257
267static ssize_t show_enabled(struct netconsole_target *nt, char *buf) 258static ssize_t enabled_show(struct config_item *item, char *buf)
268{ 259{
269 return snprintf(buf, PAGE_SIZE, "%d\n", nt->enabled); 260 return snprintf(buf, PAGE_SIZE, "%d\n", to_target(item)->enabled);
270} 261}
271 262
272static ssize_t show_extended(struct netconsole_target *nt, char *buf) 263static ssize_t extended_show(struct config_item *item, char *buf)
273{ 264{
274 return snprintf(buf, PAGE_SIZE, "%d\n", nt->extended); 265 return snprintf(buf, PAGE_SIZE, "%d\n", to_target(item)->extended);
275} 266}
276 267
277static ssize_t show_dev_name(struct netconsole_target *nt, char *buf) 268static ssize_t dev_name_show(struct config_item *item, char *buf)
278{ 269{
279 return snprintf(buf, PAGE_SIZE, "%s\n", nt->np.dev_name); 270 return snprintf(buf, PAGE_SIZE, "%s\n", to_target(item)->np.dev_name);
280} 271}
281 272
282static ssize_t show_local_port(struct netconsole_target *nt, char *buf) 273static ssize_t local_port_show(struct config_item *item, char *buf)
283{ 274{
284 return snprintf(buf, PAGE_SIZE, "%d\n", nt->np.local_port); 275 return snprintf(buf, PAGE_SIZE, "%d\n", to_target(item)->np.local_port);
285} 276}
286 277
287static ssize_t show_remote_port(struct netconsole_target *nt, char *buf) 278static ssize_t remote_port_show(struct config_item *item, char *buf)
288{ 279{
289 return snprintf(buf, PAGE_SIZE, "%d\n", nt->np.remote_port); 280 return snprintf(buf, PAGE_SIZE, "%d\n", to_target(item)->np.remote_port);
290} 281}
291 282
292static ssize_t show_local_ip(struct netconsole_target *nt, char *buf) 283static ssize_t local_ip_show(struct config_item *item, char *buf)
293{ 284{
285 struct netconsole_target *nt = to_target(item);
286
294 if (nt->np.ipv6) 287 if (nt->np.ipv6)
295 return snprintf(buf, PAGE_SIZE, "%pI6c\n", &nt->np.local_ip.in6); 288 return snprintf(buf, PAGE_SIZE, "%pI6c\n", &nt->np.local_ip.in6);
296 else 289 else
297 return snprintf(buf, PAGE_SIZE, "%pI4\n", &nt->np.local_ip); 290 return snprintf(buf, PAGE_SIZE, "%pI4\n", &nt->np.local_ip);
298} 291}
299 292
300static ssize_t show_remote_ip(struct netconsole_target *nt, char *buf) 293static ssize_t remote_ip_show(struct config_item *item, char *buf)
301{ 294{
295 struct netconsole_target *nt = to_target(item);
296
302 if (nt->np.ipv6) 297 if (nt->np.ipv6)
303 return snprintf(buf, PAGE_SIZE, "%pI6c\n", &nt->np.remote_ip.in6); 298 return snprintf(buf, PAGE_SIZE, "%pI6c\n", &nt->np.remote_ip.in6);
304 else 299 else
305 return snprintf(buf, PAGE_SIZE, "%pI4\n", &nt->np.remote_ip); 300 return snprintf(buf, PAGE_SIZE, "%pI4\n", &nt->np.remote_ip);
306} 301}
307 302
308static ssize_t show_local_mac(struct netconsole_target *nt, char *buf) 303static ssize_t local_mac_show(struct config_item *item, char *buf)
309{ 304{
310 struct net_device *dev = nt->np.dev; 305 struct net_device *dev = to_target(item)->np.dev;
311 static const u8 bcast[ETH_ALEN] = { 0xff, 0xff, 0xff, 0xff, 0xff, 0xff }; 306 static const u8 bcast[ETH_ALEN] = { 0xff, 0xff, 0xff, 0xff, 0xff, 0xff };
312 307
313 return snprintf(buf, PAGE_SIZE, "%pM\n", dev ? dev->dev_addr : bcast); 308 return snprintf(buf, PAGE_SIZE, "%pM\n", dev ? dev->dev_addr : bcast);
314} 309}
315 310
316static ssize_t show_remote_mac(struct netconsole_target *nt, char *buf) 311static ssize_t remote_mac_show(struct config_item *item, char *buf)
317{ 312{
318 return snprintf(buf, PAGE_SIZE, "%pM\n", nt->np.remote_mac); 313 return snprintf(buf, PAGE_SIZE, "%pM\n", to_target(item)->np.remote_mac);
319} 314}
320 315
321/* 316/*
@@ -325,23 +320,26 @@ static ssize_t show_remote_mac(struct netconsole_target *nt, char *buf)
325 * would enable him to dynamically add new netpoll targets for new 320 * would enable him to dynamically add new netpoll targets for new
326 * network interfaces as and when they come up). 321 * network interfaces as and when they come up).
327 */ 322 */
328static ssize_t store_enabled(struct netconsole_target *nt, 323static ssize_t enabled_store(struct config_item *item,
329 const char *buf, 324 const char *buf, size_t count)
330 size_t count)
331{ 325{
326 struct netconsole_target *nt = to_target(item);
332 unsigned long flags; 327 unsigned long flags;
333 int enabled; 328 int enabled;
334 int err; 329 int err;
335 330
331 mutex_lock(&dynamic_netconsole_mutex);
336 err = kstrtoint(buf, 10, &enabled); 332 err = kstrtoint(buf, 10, &enabled);
337 if (err < 0) 333 if (err < 0)
338 return err; 334 goto out_unlock;
335
336 err = -EINVAL;
339 if (enabled < 0 || enabled > 1) 337 if (enabled < 0 || enabled > 1)
340 return -EINVAL; 338 goto out_unlock;
341 if ((bool)enabled == nt->enabled) { 339 if ((bool)enabled == nt->enabled) {
342 pr_info("network logging has already %s\n", 340 pr_info("network logging has already %s\n",
343 nt->enabled ? "started" : "stopped"); 341 nt->enabled ? "started" : "stopped");
344 return -EINVAL; 342 goto out_unlock;
345 } 343 }
346 344
347 if (enabled) { /* true */ 345 if (enabled) { /* true */
@@ -358,7 +356,7 @@ static ssize_t store_enabled(struct netconsole_target *nt,
358 356
359 err = netpoll_setup(&nt->np); 357 err = netpoll_setup(&nt->np);
360 if (err) 358 if (err)
361 return err; 359 goto out_unlock;
362 360
363 pr_info("netconsole: network logging started\n"); 361 pr_info("netconsole: network logging started\n");
364 } else { /* false */ 362 } else { /* false */
@@ -374,42 +372,56 @@ static ssize_t store_enabled(struct netconsole_target *nt,
374 372
375 nt->enabled = enabled; 373 nt->enabled = enabled;
376 374
375 mutex_unlock(&dynamic_netconsole_mutex);
377 return strnlen(buf, count); 376 return strnlen(buf, count);
377out_unlock:
378 mutex_unlock(&dynamic_netconsole_mutex);
379 return err;
378} 380}
379 381
380static ssize_t store_extended(struct netconsole_target *nt, 382static ssize_t extended_store(struct config_item *item, const char *buf,
381 const char *buf, 383 size_t count)
382 size_t count)
383{ 384{
385 struct netconsole_target *nt = to_target(item);
384 int extended; 386 int extended;
385 int err; 387 int err;
386 388
389 mutex_lock(&dynamic_netconsole_mutex);
387 if (nt->enabled) { 390 if (nt->enabled) {
388 pr_err("target (%s) is enabled, disable to update parameters\n", 391 pr_err("target (%s) is enabled, disable to update parameters\n",
389 config_item_name(&nt->item)); 392 config_item_name(&nt->item));
390 return -EINVAL; 393 err = -EINVAL;
394 goto out_unlock;
391 } 395 }
392 396
393 err = kstrtoint(buf, 10, &extended); 397 err = kstrtoint(buf, 10, &extended);
394 if (err < 0) 398 if (err < 0)
395 return err; 399 goto out_unlock;
396 if (extended < 0 || extended > 1) 400 if (extended < 0 || extended > 1) {
397 return -EINVAL; 401 err = -EINVAL;
402 goto out_unlock;
403 }
398 404
399 nt->extended = extended; 405 nt->extended = extended;
400 406
407 mutex_unlock(&dynamic_netconsole_mutex);
401 return strnlen(buf, count); 408 return strnlen(buf, count);
409out_unlock:
410 mutex_unlock(&dynamic_netconsole_mutex);
411 return err;
402} 412}
403 413
404static ssize_t store_dev_name(struct netconsole_target *nt, 414static ssize_t dev_name_store(struct config_item *item, const char *buf,
405 const char *buf, 415 size_t count)
406 size_t count)
407{ 416{
417 struct netconsole_target *nt = to_target(item);
408 size_t len; 418 size_t len;
409 419
420 mutex_lock(&dynamic_netconsole_mutex);
410 if (nt->enabled) { 421 if (nt->enabled) {
411 pr_err("target (%s) is enabled, disable to update parameters\n", 422 pr_err("target (%s) is enabled, disable to update parameters\n",
412 config_item_name(&nt->item)); 423 config_item_name(&nt->item));
424 mutex_unlock(&dynamic_netconsole_mutex);
413 return -EINVAL; 425 return -EINVAL;
414 } 426 }
415 427
@@ -420,53 +432,66 @@ static ssize_t store_dev_name(struct netconsole_target *nt,
420 if (nt->np.dev_name[len - 1] == '\n') 432 if (nt->np.dev_name[len - 1] == '\n')
421 nt->np.dev_name[len - 1] = '\0'; 433 nt->np.dev_name[len - 1] = '\0';
422 434
435 mutex_unlock(&dynamic_netconsole_mutex);
423 return strnlen(buf, count); 436 return strnlen(buf, count);
424} 437}
425 438
426static ssize_t store_local_port(struct netconsole_target *nt, 439static ssize_t local_port_store(struct config_item *item, const char *buf,
427 const char *buf, 440 size_t count)
428 size_t count)
429{ 441{
430 int rv; 442 struct netconsole_target *nt = to_target(item);
443 int rv = -EINVAL;
431 444
445 mutex_lock(&dynamic_netconsole_mutex);
432 if (nt->enabled) { 446 if (nt->enabled) {
433 pr_err("target (%s) is enabled, disable to update parameters\n", 447 pr_err("target (%s) is enabled, disable to update parameters\n",
434 config_item_name(&nt->item)); 448 config_item_name(&nt->item));
435 return -EINVAL; 449 goto out_unlock;
436 } 450 }
437 451
438 rv = kstrtou16(buf, 10, &nt->np.local_port); 452 rv = kstrtou16(buf, 10, &nt->np.local_port);
439 if (rv < 0) 453 if (rv < 0)
440 return rv; 454 goto out_unlock;
455 mutex_unlock(&dynamic_netconsole_mutex);
441 return strnlen(buf, count); 456 return strnlen(buf, count);
457out_unlock:
458 mutex_unlock(&dynamic_netconsole_mutex);
459 return rv;
442} 460}
443 461
444static ssize_t store_remote_port(struct netconsole_target *nt, 462static ssize_t remote_port_store(struct config_item *item,
445 const char *buf, 463 const char *buf, size_t count)
446 size_t count)
447{ 464{
448 int rv; 465 struct netconsole_target *nt = to_target(item);
466 int rv = -EINVAL;
449 467
468 mutex_lock(&dynamic_netconsole_mutex);
450 if (nt->enabled) { 469 if (nt->enabled) {
451 pr_err("target (%s) is enabled, disable to update parameters\n", 470 pr_err("target (%s) is enabled, disable to update parameters\n",
452 config_item_name(&nt->item)); 471 config_item_name(&nt->item));
453 return -EINVAL; 472 goto out_unlock;
454 } 473 }
455 474
456 rv = kstrtou16(buf, 10, &nt->np.remote_port); 475 rv = kstrtou16(buf, 10, &nt->np.remote_port);
457 if (rv < 0) 476 if (rv < 0)
458 return rv; 477 goto out_unlock;
478 mutex_unlock(&dynamic_netconsole_mutex);
459 return strnlen(buf, count); 479 return strnlen(buf, count);
480out_unlock:
481 mutex_unlock(&dynamic_netconsole_mutex);
482 return rv;
460} 483}
461 484
462static ssize_t store_local_ip(struct netconsole_target *nt, 485static ssize_t local_ip_store(struct config_item *item, const char *buf,
463 const char *buf, 486 size_t count)
464 size_t count)
465{ 487{
488 struct netconsole_target *nt = to_target(item);
489
490 mutex_lock(&dynamic_netconsole_mutex);
466 if (nt->enabled) { 491 if (nt->enabled) {
467 pr_err("target (%s) is enabled, disable to update parameters\n", 492 pr_err("target (%s) is enabled, disable to update parameters\n",
468 config_item_name(&nt->item)); 493 config_item_name(&nt->item));
469 return -EINVAL; 494 goto out_unlock;
470 } 495 }
471 496
472 if (strnchr(buf, count, ':')) { 497 if (strnchr(buf, count, ':')) {
@@ -474,29 +499,35 @@ static ssize_t store_local_ip(struct netconsole_target *nt,
474 if (in6_pton(buf, count, nt->np.local_ip.in6.s6_addr, -1, &end) > 0) { 499 if (in6_pton(buf, count, nt->np.local_ip.in6.s6_addr, -1, &end) > 0) {
475 if (*end && *end != '\n') { 500 if (*end && *end != '\n') {
476 pr_err("invalid IPv6 address at: <%c>\n", *end); 501 pr_err("invalid IPv6 address at: <%c>\n", *end);
477 return -EINVAL; 502 goto out_unlock;
478 } 503 }
479 nt->np.ipv6 = true; 504 nt->np.ipv6 = true;
480 } else 505 } else
481 return -EINVAL; 506 goto out_unlock;
482 } else { 507 } else {
483 if (!nt->np.ipv6) { 508 if (!nt->np.ipv6) {
484 nt->np.local_ip.ip = in_aton(buf); 509 nt->np.local_ip.ip = in_aton(buf);
485 } else 510 } else
486 return -EINVAL; 511 goto out_unlock;
487 } 512 }
488 513
514 mutex_unlock(&dynamic_netconsole_mutex);
489 return strnlen(buf, count); 515 return strnlen(buf, count);
516out_unlock:
517 mutex_unlock(&dynamic_netconsole_mutex);
518 return -EINVAL;
490} 519}
491 520
492static ssize_t store_remote_ip(struct netconsole_target *nt, 521static ssize_t remote_ip_store(struct config_item *item, const char *buf,
493 const char *buf, 522 size_t count)
494 size_t count)
495{ 523{
524 struct netconsole_target *nt = to_target(item);
525
526 mutex_lock(&dynamic_netconsole_mutex);
496 if (nt->enabled) { 527 if (nt->enabled) {
497 pr_err("target (%s) is enabled, disable to update parameters\n", 528 pr_err("target (%s) is enabled, disable to update parameters\n",
498 config_item_name(&nt->item)); 529 config_item_name(&nt->item));
499 return -EINVAL; 530 goto out_unlock;
500 } 531 }
501 532
502 if (strnchr(buf, count, ':')) { 533 if (strnchr(buf, count, ':')) {
@@ -504,74 +535,71 @@ static ssize_t store_remote_ip(struct netconsole_target *nt,
504 if (in6_pton(buf, count, nt->np.remote_ip.in6.s6_addr, -1, &end) > 0) { 535 if (in6_pton(buf, count, nt->np.remote_ip.in6.s6_addr, -1, &end) > 0) {
505 if (*end && *end != '\n') { 536 if (*end && *end != '\n') {
506 pr_err("invalid IPv6 address at: <%c>\n", *end); 537 pr_err("invalid IPv6 address at: <%c>\n", *end);
507 return -EINVAL; 538 goto out_unlock;
508 } 539 }
509 nt->np.ipv6 = true; 540 nt->np.ipv6 = true;
510 } else 541 } else
511 return -EINVAL; 542 goto out_unlock;
512 } else { 543 } else {
513 if (!nt->np.ipv6) { 544 if (!nt->np.ipv6) {
514 nt->np.remote_ip.ip = in_aton(buf); 545 nt->np.remote_ip.ip = in_aton(buf);
515 } else 546 } else
516 return -EINVAL; 547 goto out_unlock;
517 } 548 }
518 549
550 mutex_unlock(&dynamic_netconsole_mutex);
519 return strnlen(buf, count); 551 return strnlen(buf, count);
552out_unlock:
553 mutex_unlock(&dynamic_netconsole_mutex);
554 return -EINVAL;
520} 555}
521 556
522static ssize_t store_remote_mac(struct netconsole_target *nt, 557static ssize_t remote_mac_store(struct config_item *item, const char *buf,
523 const char *buf, 558 size_t count)
524 size_t count)
525{ 559{
560 struct netconsole_target *nt = to_target(item);
526 u8 remote_mac[ETH_ALEN]; 561 u8 remote_mac[ETH_ALEN];
527 562
563 mutex_lock(&dynamic_netconsole_mutex);
528 if (nt->enabled) { 564 if (nt->enabled) {
529 pr_err("target (%s) is enabled, disable to update parameters\n", 565 pr_err("target (%s) is enabled, disable to update parameters\n",
530 config_item_name(&nt->item)); 566 config_item_name(&nt->item));
531 return -EINVAL; 567 goto out_unlock;
532 } 568 }
533 569
534 if (!mac_pton(buf, remote_mac)) 570 if (!mac_pton(buf, remote_mac))
535 return -EINVAL; 571 goto out_unlock;
536 if (buf[3 * ETH_ALEN - 1] && buf[3 * ETH_ALEN - 1] != '\n') 572 if (buf[3 * ETH_ALEN - 1] && buf[3 * ETH_ALEN - 1] != '\n')
537 return -EINVAL; 573 goto out_unlock;
538 memcpy(nt->np.remote_mac, remote_mac, ETH_ALEN); 574 memcpy(nt->np.remote_mac, remote_mac, ETH_ALEN);
539 575
576 mutex_unlock(&dynamic_netconsole_mutex);
540 return strnlen(buf, count); 577 return strnlen(buf, count);
578out_unlock:
579 mutex_unlock(&dynamic_netconsole_mutex);
580 return -EINVAL;
541} 581}
542 582
543/* 583CONFIGFS_ATTR(, enabled);
544 * Attribute definitions for netconsole_target. 584CONFIGFS_ATTR(, extended);
545 */ 585CONFIGFS_ATTR(, dev_name);
546 586CONFIGFS_ATTR(, local_port);
547#define NETCONSOLE_TARGET_ATTR_RO(_name) \ 587CONFIGFS_ATTR(, remote_port);
548static struct netconsole_target_attr netconsole_target_##_name = \ 588CONFIGFS_ATTR(, local_ip);
549 __CONFIGFS_ATTR(_name, S_IRUGO, show_##_name, NULL) 589CONFIGFS_ATTR(, remote_ip);
550 590CONFIGFS_ATTR_RO(, local_mac);
551#define NETCONSOLE_TARGET_ATTR_RW(_name) \ 591CONFIGFS_ATTR(, remote_mac);
552static struct netconsole_target_attr netconsole_target_##_name = \
553 __CONFIGFS_ATTR(_name, S_IRUGO | S_IWUSR, show_##_name, store_##_name)
554
555NETCONSOLE_TARGET_ATTR_RW(enabled);
556NETCONSOLE_TARGET_ATTR_RW(extended);
557NETCONSOLE_TARGET_ATTR_RW(dev_name);
558NETCONSOLE_TARGET_ATTR_RW(local_port);
559NETCONSOLE_TARGET_ATTR_RW(remote_port);
560NETCONSOLE_TARGET_ATTR_RW(local_ip);
561NETCONSOLE_TARGET_ATTR_RW(remote_ip);
562NETCONSOLE_TARGET_ATTR_RO(local_mac);
563NETCONSOLE_TARGET_ATTR_RW(remote_mac);
564 592
565static struct configfs_attribute *netconsole_target_attrs[] = { 593static struct configfs_attribute *netconsole_target_attrs[] = {
566 &netconsole_target_enabled.attr, 594 &attr_enabled,
567 &netconsole_target_extended.attr, 595 &attr_extended,
568 &netconsole_target_dev_name.attr, 596 &attr_dev_name,
569 &netconsole_target_local_port.attr, 597 &attr_local_port,
570 &netconsole_target_remote_port.attr, 598 &attr_remote_port,
571 &netconsole_target_local_ip.attr, 599 &attr_local_ip,
572 &netconsole_target_remote_ip.attr, 600 &attr_remote_ip,
573 &netconsole_target_local_mac.attr, 601 &attr_local_mac,
574 &netconsole_target_remote_mac.attr, 602 &attr_remote_mac,
575 NULL, 603 NULL,
576}; 604};
577 605
@@ -584,43 +612,8 @@ static void netconsole_target_release(struct config_item *item)
584 kfree(to_target(item)); 612 kfree(to_target(item));
585} 613}
586 614
587static ssize_t netconsole_target_attr_show(struct config_item *item,
588 struct configfs_attribute *attr,
589 char *buf)
590{
591 ssize_t ret = -EINVAL;
592 struct netconsole_target *nt = to_target(item);
593 struct netconsole_target_attr *na =
594 container_of(attr, struct netconsole_target_attr, attr);
595
596 if (na->show)
597 ret = na->show(nt, buf);
598
599 return ret;
600}
601
602static ssize_t netconsole_target_attr_store(struct config_item *item,
603 struct configfs_attribute *attr,
604 const char *buf,
605 size_t count)
606{
607 ssize_t ret = -EINVAL;
608 struct netconsole_target *nt = to_target(item);
609 struct netconsole_target_attr *na =
610 container_of(attr, struct netconsole_target_attr, attr);
611
612 mutex_lock(&dynamic_netconsole_mutex);
613 if (na->store)
614 ret = na->store(nt, buf, count);
615 mutex_unlock(&dynamic_netconsole_mutex);
616
617 return ret;
618}
619
620static struct configfs_item_operations netconsole_target_item_ops = { 615static struct configfs_item_operations netconsole_target_item_ops = {
621 .release = netconsole_target_release, 616 .release = netconsole_target_release,
622 .show_attribute = netconsole_target_attr_show,
623 .store_attribute = netconsole_target_attr_store,
624}; 617};
625 618
626static struct config_item_type netconsole_target_type = { 619static struct config_item_type netconsole_target_type = {