Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

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>

authored by

Christoph Hellwig and committed by
Nicholas Bellinger
ea9ed9cf 2eafd729

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