1 // SPDX-License-Identifier: GPL-2.0 2 /* 3 * fs/sysfs/file.c - sysfs regular (text) file implementation 4 * 5 * Copyright (c) 2001-3 Patrick Mochel 6 * Copyright (c) 2007 SUSE Linux Products GmbH 7 * Copyright (c) 2007 Tejun Heo <teheo@suse.de> 8 * 9 * Please see Documentation/filesystems/sysfs.rst for more information. 10 */ 11 12 #include <linux/module.h> 13 #include <linux/kobject.h> 14 #include <linux/slab.h> 15 #include <linux/list.h> 16 #include <linux/mutex.h> 17 #include <linux/seq_file.h> 18 #include <linux/mm.h> 19 20 #include "sysfs.h" 21 22 static struct kobject *sysfs_file_kobj(struct kernfs_node *kn) 23 { 24 guard(rcu)(); 25 return rcu_dereference(kn->__parent)->priv; 26 } 27 28 /* 29 * Determine ktype->sysfs_ops for the given kernfs_node. This function 30 * must be called while holding an active reference. 31 */ 32 static const struct sysfs_ops *sysfs_file_ops(struct kernfs_node *kn) 33 { 34 struct kobject *kobj = sysfs_file_kobj(kn); 35 36 if (kn->flags & KERNFS_LOCKDEP) 37 lockdep_assert_held(kn); 38 return kobj->ktype ? kobj->ktype->sysfs_ops : NULL; 39 } 40 41 /* 42 * Reads on sysfs are handled through seq_file, which takes care of hairy 43 * details like buffering and seeking. The following function pipes 44 * sysfs_ops->show() result through seq_file. 45 */ 46 static int sysfs_kf_seq_show(struct seq_file *sf, void *v) 47 { 48 struct kernfs_open_file *of = sf->private; 49 struct kobject *kobj = sysfs_file_kobj(of->kn); 50 const struct sysfs_ops *ops = sysfs_file_ops(of->kn); 51 ssize_t count; 52 char *buf; 53 54 if (WARN_ON_ONCE(!ops->show)) 55 return -EINVAL; 56 57 /* acquire buffer and ensure that it's >= PAGE_SIZE and clear */ 58 count = seq_get_buf(sf, &buf); 59 if (count < PAGE_SIZE) { 60 seq_commit(sf, -1); 61 return 0; 62 } 63 memset(buf, 0, PAGE_SIZE); 64 65 count = ops->show(kobj, of->kn->priv, buf); 66 if (count < 0) 67 return count; 68 69 /* 70 * The code works fine with PAGE_SIZE return but it's likely to 71 * indicate truncated result or overflow in normal use cases. 72 */ 73 if (count >= PAGE_SIZE) { 74 WARN(1, "OOB write or bad count %zd at %pS\n", count, ops->show); 75 /* Try to struggle along */ 76 count = PAGE_SIZE - 1; 77 } 78 seq_commit(sf, count); 79 return 0; 80 } 81 82 static ssize_t sysfs_kf_bin_read(struct kernfs_open_file *of, char *buf, 83 size_t count, loff_t pos) 84 { 85 const struct bin_attribute *battr = of->kn->priv; 86 struct kobject *kobj = sysfs_file_kobj(of->kn); 87 loff_t size = file_inode(of->file)->i_size; 88 89 if (!count) 90 return 0; 91 92 if (size) { 93 if (pos >= size) 94 return 0; 95 if (pos + count > size) 96 count = size - pos; 97 } 98 99 if (!battr->read) 100 return -EIO; 101 102 return battr->read(of->file, kobj, battr, buf, pos, count); 103 } 104 105 /* kernfs read callback for regular sysfs files with pre-alloc */ 106 static ssize_t sysfs_kf_read(struct kernfs_open_file *of, char *buf, 107 size_t count, loff_t pos) 108 { 109 const struct sysfs_ops *ops = sysfs_file_ops(of->kn); 110 struct kobject *kobj = sysfs_file_kobj(of->kn); 111 ssize_t len; 112 113 /* 114 * If buf != of->prealloc_buf, we don't know how 115 * large it is, so cannot safely pass it to ->show 116 */ 117 if (WARN_ON_ONCE(buf != of->prealloc_buf)) 118 return 0; 119 len = ops->show(kobj, of->kn->priv, buf); 120 if (len < 0) 121 return len; 122 if (len >= (ssize_t)PAGE_SIZE) { 123 printk("fill_read_buffer: %pS returned bad count\n", ops->show); 124 len = PAGE_SIZE - 1; 125 } 126 if (pos) { 127 if (len <= pos) 128 return 0; 129 len -= pos; 130 memmove(buf, buf + pos, len); 131 } 132 return min_t(ssize_t, count, len); 133 } 134 135 /* kernfs write callback for regular sysfs files */ 136 static ssize_t sysfs_kf_write(struct kernfs_open_file *of, char *buf, 137 size_t count, loff_t pos) 138 { 139 const struct sysfs_ops *ops = sysfs_file_ops(of->kn); 140 struct kobject *kobj = sysfs_file_kobj(of->kn); 141 142 if (!count) 143 return 0; 144 145 return ops->store(kobj, of->kn->priv, buf, count); 146 } 147 148 /* kernfs write callback for bin sysfs files */ 149 static ssize_t sysfs_kf_bin_write(struct kernfs_open_file *of, char *buf, 150 size_t count, loff_t pos) 151 { 152 const struct bin_attribute *battr = of->kn->priv; 153 struct kobject *kobj = sysfs_file_kobj(of->kn); 154 loff_t size = file_inode(of->file)->i_size; 155 156 if (size) { 157 if (size <= pos) 158 return -EFBIG; 159 count = min_t(ssize_t, count, size - pos); 160 } 161 if (!count) 162 return 0; 163 164 if (!battr->write) 165 return -EIO; 166 167 return battr->write(of->file, kobj, battr, buf, pos, count); 168 } 169 170 static int sysfs_kf_bin_mmap(struct kernfs_open_file *of, 171 struct vm_area_struct *vma) 172 { 173 const struct bin_attribute *battr = of->kn->priv; 174 struct kobject *kobj = sysfs_file_kobj(of->kn); 175 176 return battr->mmap(of->file, kobj, battr, vma); 177 } 178 179 static loff_t sysfs_kf_bin_llseek(struct kernfs_open_file *of, loff_t offset, 180 int whence) 181 { 182 const struct bin_attribute *battr = of->kn->priv; 183 struct kobject *kobj = sysfs_file_kobj(of->kn); 184 185 if (battr->llseek) 186 return battr->llseek(of->file, kobj, battr, offset, whence); 187 else 188 return generic_file_llseek(of->file, offset, whence); 189 } 190 191 static int sysfs_kf_bin_open(struct kernfs_open_file *of) 192 { 193 const struct bin_attribute *battr = of->kn->priv; 194 195 if (battr->f_mapping) 196 of->file->f_mapping = battr->f_mapping(); 197 198 return 0; 199 } 200 201 void sysfs_notify(struct kobject *kobj, const char *dir, const char *attr) 202 { 203 struct kernfs_node *kn = kobj->sd, *tmp; 204 205 if (kn && dir) 206 kn = kernfs_find_and_get(kn, dir); 207 else 208 kernfs_get(kn); 209 210 if (kn && attr) { 211 tmp = kernfs_find_and_get(kn, attr); 212 kernfs_put(kn); 213 kn = tmp; 214 } 215 216 if (kn) { 217 kernfs_notify(kn); 218 kernfs_put(kn); 219 } 220 } 221 EXPORT_SYMBOL_GPL(sysfs_notify); 222 223 static const struct kernfs_ops sysfs_file_kfops_empty = { 224 }; 225 226 static const struct kernfs_ops sysfs_file_kfops_ro = { 227 .seq_show = sysfs_kf_seq_show, 228 }; 229 230 static const struct kernfs_ops sysfs_file_kfops_wo = { 231 .write = sysfs_kf_write, 232 }; 233 234 static const struct kernfs_ops sysfs_file_kfops_rw = { 235 .seq_show = sysfs_kf_seq_show, 236 .write = sysfs_kf_write, 237 }; 238 239 static const struct kernfs_ops sysfs_prealloc_kfops_ro = { 240 .read = sysfs_kf_read, 241 .prealloc = true, 242 }; 243 244 static const struct kernfs_ops sysfs_prealloc_kfops_wo = { 245 .write = sysfs_kf_write, 246 .prealloc = true, 247 }; 248 249 static const struct kernfs_ops sysfs_prealloc_kfops_rw = { 250 .read = sysfs_kf_read, 251 .write = sysfs_kf_write, 252 .prealloc = true, 253 }; 254 255 static const struct kernfs_ops sysfs_bin_kfops_ro = { 256 .read = sysfs_kf_bin_read, 257 }; 258 259 static const struct kernfs_ops sysfs_bin_kfops_wo = { 260 .write = sysfs_kf_bin_write, 261 }; 262 263 static const struct kernfs_ops sysfs_bin_kfops_rw = { 264 .read = sysfs_kf_bin_read, 265 .write = sysfs_kf_bin_write, 266 }; 267 268 static const struct kernfs_ops sysfs_bin_kfops_mmap = { 269 .read = sysfs_kf_bin_read, 270 .write = sysfs_kf_bin_write, 271 .mmap = sysfs_kf_bin_mmap, 272 .open = sysfs_kf_bin_open, 273 .llseek = sysfs_kf_bin_llseek, 274 }; 275 276 int sysfs_add_file_mode_ns(struct kernfs_node *parent, 277 const struct attribute *attr, umode_t mode, kuid_t uid, 278 kgid_t gid, const struct ns_common *ns) 279 { 280 struct kobject *kobj = parent->priv; 281 const struct sysfs_ops *sysfs_ops = kobj->ktype->sysfs_ops; 282 struct lock_class_key *key = NULL; 283 const struct kernfs_ops *ops = NULL; 284 struct kernfs_node *kn; 285 286 /* every kobject with an attribute needs a ktype assigned */ 287 if (WARN(!sysfs_ops, KERN_ERR 288 "missing sysfs attribute operations for kobject: %s\n", 289 kobject_name(kobj))) 290 return -EINVAL; 291 292 if (mode & SYSFS_PREALLOC) { 293 if (sysfs_ops->show && sysfs_ops->store) 294 ops = &sysfs_prealloc_kfops_rw; 295 else if (sysfs_ops->show) 296 ops = &sysfs_prealloc_kfops_ro; 297 else if (sysfs_ops->store) 298 ops = &sysfs_prealloc_kfops_wo; 299 } else { 300 if (sysfs_ops->show && sysfs_ops->store) 301 ops = &sysfs_file_kfops_rw; 302 else if (sysfs_ops->show) 303 ops = &sysfs_file_kfops_ro; 304 else if (sysfs_ops->store) 305 ops = &sysfs_file_kfops_wo; 306 } 307 308 if (!ops) 309 ops = &sysfs_file_kfops_empty; 310 311 #ifdef CONFIG_DEBUG_LOCK_ALLOC 312 if (!attr->ignore_lockdep) 313 key = attr->key ?: (struct lock_class_key *)&attr->skey; 314 #endif 315 316 kn = __kernfs_create_file(parent, attr->name, mode & 0777, uid, gid, 317 PAGE_SIZE, ops, (void *)attr, ns, key); 318 if (IS_ERR(kn)) { 319 if (PTR_ERR(kn) == -EEXIST) 320 sysfs_warn_dup(parent, attr->name); 321 return PTR_ERR(kn); 322 } 323 return 0; 324 } 325 326 int sysfs_add_bin_file_mode_ns(struct kernfs_node *parent, 327 const struct bin_attribute *battr, umode_t mode, size_t size, 328 kuid_t uid, kgid_t gid, const struct ns_common *ns) 329 { 330 const struct attribute *attr = &battr->attr; 331 struct lock_class_key *key = NULL; 332 const struct kernfs_ops *ops; 333 struct kernfs_node *kn; 334 335 if (battr->mmap) 336 ops = &sysfs_bin_kfops_mmap; 337 else if (battr->read && battr->write) 338 ops = &sysfs_bin_kfops_rw; 339 else if (battr->read) 340 ops = &sysfs_bin_kfops_ro; 341 else if (battr->write) 342 ops = &sysfs_bin_kfops_wo; 343 else 344 ops = &sysfs_file_kfops_empty; 345 346 #ifdef CONFIG_DEBUG_LOCK_ALLOC 347 if (!attr->ignore_lockdep) 348 key = attr->key ?: (struct lock_class_key *)&attr->skey; 349 #endif 350 351 kn = __kernfs_create_file(parent, attr->name, mode & 0777, uid, gid, 352 size, ops, (void *)attr, ns, key); 353 if (IS_ERR(kn)) { 354 if (PTR_ERR(kn) == -EEXIST) 355 sysfs_warn_dup(parent, attr->name); 356 return PTR_ERR(kn); 357 } 358 return 0; 359 } 360 361 /** 362 * sysfs_create_file_ns - create an attribute file for an object with custom ns 363 * @kobj: object we're creating for 364 * @attr: attribute descriptor 365 * @ns: namespace the new file should belong to 366 */ 367 int sysfs_create_file_ns(struct kobject *kobj, const struct attribute *attr, 368 const struct ns_common *ns) 369 { 370 kuid_t uid; 371 kgid_t gid; 372 373 if (WARN_ON(!kobj || !kobj->sd || !attr)) 374 return -EINVAL; 375 376 kobject_get_ownership(kobj, &uid, &gid); 377 return sysfs_add_file_mode_ns(kobj->sd, attr, attr->mode, uid, gid, ns); 378 } 379 EXPORT_SYMBOL_GPL(sysfs_create_file_ns); 380 381 int sysfs_create_files(struct kobject *kobj, const struct attribute * const *ptr) 382 { 383 int err = 0; 384 int i; 385 386 for (i = 0; ptr[i] && !err; i++) 387 err = sysfs_create_file(kobj, ptr[i]); 388 if (err) 389 while (--i >= 0) 390 sysfs_remove_file(kobj, ptr[i]); 391 return err; 392 } 393 EXPORT_SYMBOL_GPL(sysfs_create_files); 394 395 /** 396 * sysfs_add_file_to_group - add an attribute file to a pre-existing group. 397 * @kobj: object we're acting for. 398 * @attr: attribute descriptor. 399 * @group: group name. 400 */ 401 int sysfs_add_file_to_group(struct kobject *kobj, 402 const struct attribute *attr, const char *group) 403 { 404 struct kernfs_node *parent; 405 kuid_t uid; 406 kgid_t gid; 407 int error; 408 409 if (group) { 410 parent = kernfs_find_and_get(kobj->sd, group); 411 } else { 412 parent = kobj->sd; 413 kernfs_get(parent); 414 } 415 416 if (!parent) 417 return -ENOENT; 418 419 kobject_get_ownership(kobj, &uid, &gid); 420 error = sysfs_add_file_mode_ns(parent, attr, attr->mode, uid, gid, 421 NULL); 422 kernfs_put(parent); 423 424 return error; 425 } 426 EXPORT_SYMBOL_GPL(sysfs_add_file_to_group); 427 428 /** 429 * sysfs_chmod_file - update the modified mode value on an object attribute. 430 * @kobj: object we're acting for. 431 * @attr: attribute descriptor. 432 * @mode: file permissions. 433 * 434 */ 435 int sysfs_chmod_file(struct kobject *kobj, const struct attribute *attr, 436 umode_t mode) 437 { 438 struct kernfs_node *kn; 439 struct iattr newattrs; 440 int rc; 441 442 kn = kernfs_find_and_get(kobj->sd, attr->name); 443 if (!kn) 444 return -ENOENT; 445 446 newattrs.ia_mode = (mode & S_IALLUGO) | (kn->mode & ~S_IALLUGO); 447 newattrs.ia_valid = ATTR_MODE; 448 449 rc = kernfs_setattr(kn, &newattrs); 450 451 kernfs_put(kn); 452 return rc; 453 } 454 EXPORT_SYMBOL_GPL(sysfs_chmod_file); 455 456 /** 457 * sysfs_break_active_protection - break "active" protection 458 * @kobj: The kernel object @attr is associated with. 459 * @attr: The attribute to break the "active" protection for. 460 * 461 * With sysfs, just like kernfs, deletion of an attribute is postponed until 462 * all active .show() and .store() callbacks have finished unless this function 463 * is called. Hence this function is useful in methods that implement self 464 * deletion. 465 */ 466 struct kernfs_node *sysfs_break_active_protection(struct kobject *kobj, 467 const struct attribute *attr) 468 { 469 struct kernfs_node *kn; 470 471 kobject_get(kobj); 472 kn = kernfs_find_and_get(kobj->sd, attr->name); 473 if (kn) 474 kernfs_break_active_protection(kn); 475 else 476 kobject_put(kobj); 477 return kn; 478 } 479 EXPORT_SYMBOL_GPL(sysfs_break_active_protection); 480 481 /** 482 * sysfs_unbreak_active_protection - restore "active" protection 483 * @kn: Pointer returned by sysfs_break_active_protection(). 484 * 485 * Undo the effects of sysfs_break_active_protection(). Since this function 486 * calls kernfs_put() on the kernfs node that corresponds to the 'attr' 487 * argument passed to sysfs_break_active_protection() that attribute may have 488 * been removed between the sysfs_break_active_protection() and 489 * sysfs_unbreak_active_protection() calls, it is not safe to access @kn after 490 * this function has returned. 491 */ 492 void sysfs_unbreak_active_protection(struct kernfs_node *kn) 493 { 494 struct kobject *kobj = sysfs_file_kobj(kn); 495 496 kernfs_unbreak_active_protection(kn); 497 kernfs_put(kn); 498 kobject_put(kobj); 499 } 500 EXPORT_SYMBOL_GPL(sysfs_unbreak_active_protection); 501 502 /** 503 * sysfs_remove_file_ns - remove an object attribute with a custom ns tag 504 * @kobj: object we're acting for 505 * @attr: attribute descriptor 506 * @ns: namespace tag of the file to remove 507 * 508 * Hash the attribute name and namespace tag and kill the victim. 509 */ 510 void sysfs_remove_file_ns(struct kobject *kobj, const struct attribute *attr, 511 const struct ns_common *ns) 512 { 513 struct kernfs_node *parent = kobj->sd; 514 515 kernfs_remove_by_name_ns(parent, attr->name, ns); 516 } 517 EXPORT_SYMBOL_GPL(sysfs_remove_file_ns); 518 519 /** 520 * sysfs_remove_file_self - remove an object attribute from its own method 521 * @kobj: object we're acting for 522 * @attr: attribute descriptor 523 * 524 * See kernfs_remove_self() for details. 525 */ 526 bool sysfs_remove_file_self(struct kobject *kobj, const struct attribute *attr) 527 { 528 struct kernfs_node *parent = kobj->sd; 529 struct kernfs_node *kn; 530 bool ret; 531 532 kn = kernfs_find_and_get(parent, attr->name); 533 if (WARN_ON_ONCE(!kn)) 534 return false; 535 536 ret = kernfs_remove_self(kn); 537 538 kernfs_put(kn); 539 return ret; 540 } 541 EXPORT_SYMBOL_GPL(sysfs_remove_file_self); 542 543 void sysfs_remove_files(struct kobject *kobj, const struct attribute * const *ptr) 544 { 545 int i; 546 547 for (i = 0; ptr[i]; i++) 548 sysfs_remove_file(kobj, ptr[i]); 549 } 550 EXPORT_SYMBOL_GPL(sysfs_remove_files); 551 552 /** 553 * sysfs_remove_file_from_group - remove an attribute file from a group. 554 * @kobj: object we're acting for. 555 * @attr: attribute descriptor. 556 * @group: group name. 557 */ 558 void sysfs_remove_file_from_group(struct kobject *kobj, 559 const struct attribute *attr, const char *group) 560 { 561 struct kernfs_node *parent; 562 563 if (group) { 564 parent = kernfs_find_and_get(kobj->sd, group); 565 } else { 566 parent = kobj->sd; 567 kernfs_get(parent); 568 } 569 570 if (parent) { 571 kernfs_remove_by_name(parent, attr->name); 572 kernfs_put(parent); 573 } 574 } 575 EXPORT_SYMBOL_GPL(sysfs_remove_file_from_group); 576 577 /** 578 * sysfs_create_bin_file - create binary file for object. 579 * @kobj: object. 580 * @attr: attribute descriptor. 581 */ 582 int sysfs_create_bin_file(struct kobject *kobj, 583 const struct bin_attribute *attr) 584 { 585 kuid_t uid; 586 kgid_t gid; 587 588 if (WARN_ON(!kobj || !kobj->sd || !attr)) 589 return -EINVAL; 590 591 kobject_get_ownership(kobj, &uid, &gid); 592 return sysfs_add_bin_file_mode_ns(kobj->sd, attr, attr->attr.mode, 593 attr->size, uid, gid, NULL); 594 } 595 EXPORT_SYMBOL_GPL(sysfs_create_bin_file); 596 597 /** 598 * sysfs_remove_bin_file - remove binary file for object. 599 * @kobj: object. 600 * @attr: attribute descriptor. 601 */ 602 void sysfs_remove_bin_file(struct kobject *kobj, 603 const struct bin_attribute *attr) 604 { 605 kernfs_remove_by_name(kobj->sd, attr->attr.name); 606 } 607 EXPORT_SYMBOL_GPL(sysfs_remove_bin_file); 608 609 static int internal_change_owner(struct kernfs_node *kn, kuid_t kuid, 610 kgid_t kgid) 611 { 612 struct iattr newattrs = { 613 .ia_valid = ATTR_UID | ATTR_GID, 614 .ia_uid = kuid, 615 .ia_gid = kgid, 616 }; 617 return kernfs_setattr(kn, &newattrs); 618 } 619 620 /** 621 * sysfs_link_change_owner - change owner of a sysfs file. 622 * @kobj: object of the kernfs_node the symlink is located in. 623 * @targ: object of the kernfs_node the symlink points to. 624 * @name: name of the link. 625 * @kuid: new owner's kuid 626 * @kgid: new owner's kgid 627 * 628 * This function looks up the sysfs symlink entry @name under @kobj and changes 629 * the ownership to @kuid/@kgid. The symlink is looked up in the namespace of 630 * @targ. 631 * 632 * Returns 0 on success or error code on failure. 633 */ 634 int sysfs_link_change_owner(struct kobject *kobj, struct kobject *targ, 635 const char *name, kuid_t kuid, kgid_t kgid) 636 { 637 struct kernfs_node *kn = NULL; 638 int error; 639 640 if (!name || !kobj->state_in_sysfs || !targ->state_in_sysfs) 641 return -EINVAL; 642 643 error = -ENOENT; 644 kn = kernfs_find_and_get_ns(kobj->sd, name, targ->sd->ns); 645 if (!kn) 646 goto out; 647 648 error = -EINVAL; 649 if (kernfs_type(kn) != KERNFS_LINK) 650 goto out; 651 if (kn->symlink.target_kn->priv != targ) 652 goto out; 653 654 error = internal_change_owner(kn, kuid, kgid); 655 656 out: 657 kernfs_put(kn); 658 return error; 659 } 660 661 /** 662 * sysfs_file_change_owner - change owner of a sysfs file. 663 * @kobj: object. 664 * @name: name of the file to change. 665 * @kuid: new owner's kuid 666 * @kgid: new owner's kgid 667 * 668 * This function looks up the sysfs entry @name under @kobj and changes the 669 * ownership to @kuid/@kgid. 670 * 671 * Returns 0 on success or error code on failure. 672 */ 673 int sysfs_file_change_owner(struct kobject *kobj, const char *name, kuid_t kuid, 674 kgid_t kgid) 675 { 676 struct kernfs_node *kn; 677 int error; 678 679 if (!name) 680 return -EINVAL; 681 682 if (!kobj->state_in_sysfs) 683 return -EINVAL; 684 685 kn = kernfs_find_and_get(kobj->sd, name); 686 if (!kn) 687 return -ENOENT; 688 689 error = internal_change_owner(kn, kuid, kgid); 690 691 kernfs_put(kn); 692 693 return error; 694 } 695 696 /** 697 * sysfs_change_owner - change owner of the given object. 698 * @kobj: object. 699 * @kuid: new owner's kuid 700 * @kgid: new owner's kgid 701 * 702 * Change the owner of the default directory, files, groups, and attributes of 703 * @kobj to @kuid/@kgid. Note that sysfs_change_owner mirrors how the sysfs 704 * entries for a kobject are added by driver core. In summary, 705 * sysfs_change_owner() takes care of the default directory entry for @kobj, 706 * the default attributes associated with the ktype of @kobj and the default 707 * attributes associated with the ktype of @kobj. 708 * Additional properties not added by driver core have to be changed by the 709 * driver or subsystem which created them. This is similar to how 710 * driver/subsystem specific entries are removed. 711 * 712 * Returns 0 on success or error code on failure. 713 */ 714 int sysfs_change_owner(struct kobject *kobj, kuid_t kuid, kgid_t kgid) 715 { 716 int error; 717 const struct kobj_type *ktype; 718 719 if (!kobj->state_in_sysfs) 720 return -EINVAL; 721 722 /* Change the owner of the kobject itself. */ 723 error = internal_change_owner(kobj->sd, kuid, kgid); 724 if (error) 725 return error; 726 727 ktype = get_ktype(kobj); 728 if (ktype) { 729 /* 730 * Change owner of the default groups associated with the 731 * ktype of @kobj. 732 */ 733 error = sysfs_groups_change_owner(kobj, ktype->default_groups, 734 kuid, kgid); 735 if (error) 736 return error; 737 } 738 739 return 0; 740 } 741 742 /** 743 * sysfs_emit - scnprintf equivalent, aware of PAGE_SIZE buffer. 744 * @buf: start of PAGE_SIZE buffer. 745 * @fmt: format 746 * @...: optional arguments to @format 747 * 748 * 749 * Returns number of characters written to @buf. 750 */ 751 int sysfs_emit(char *buf, const char *fmt, ...) 752 { 753 va_list args; 754 int len; 755 756 if (WARN(!buf || offset_in_page(buf), 757 "invalid sysfs_emit: buf:%p\n", buf)) 758 return 0; 759 760 va_start(args, fmt); 761 len = vscnprintf(buf, PAGE_SIZE, fmt, args); 762 va_end(args); 763 764 return len; 765 } 766 EXPORT_SYMBOL_GPL(sysfs_emit); 767 768 /** 769 * sysfs_emit_at - scnprintf equivalent, aware of PAGE_SIZE buffer. 770 * @buf: start of PAGE_SIZE buffer. 771 * @at: offset in @buf to start write in bytes 772 * @at must be >= 0 && < PAGE_SIZE 773 * @fmt: format 774 * @...: optional arguments to @fmt 775 * 776 * 777 * Returns number of characters written starting at &@buf[@at]. 778 */ 779 int sysfs_emit_at(char *buf, int at, const char *fmt, ...) 780 { 781 va_list args; 782 int len; 783 784 if (WARN(!buf || offset_in_page(buf) || at < 0 || at >= PAGE_SIZE, 785 "invalid sysfs_emit_at: buf:%p at:%d\n", buf, at)) 786 return 0; 787 788 va_start(args, fmt); 789 len = vscnprintf(buf + at, PAGE_SIZE - at, fmt, args); 790 va_end(args); 791 792 return len; 793 } 794 EXPORT_SYMBOL_GPL(sysfs_emit_at); 795 796 /** 797 * sysfs_bin_attr_simple_read - read callback to simply copy from memory. 798 * @file: attribute file which is being read. 799 * @kobj: object to which the attribute belongs. 800 * @attr: attribute descriptor. 801 * @buf: destination buffer. 802 * @off: offset in bytes from which to read. 803 * @count: maximum number of bytes to read. 804 * 805 * Simple ->read() callback for bin_attributes backed by a buffer in memory. 806 * The @private and @size members in struct bin_attribute must be set to the 807 * buffer's location and size before the bin_attribute is created in sysfs. 808 * 809 * Bounds check for @off and @count is done in sysfs_kf_bin_read(). 810 * Negative value check for @off is done in vfs_setpos() and default_llseek(). 811 * 812 * Returns number of bytes written to @buf. 813 */ 814 ssize_t sysfs_bin_attr_simple_read(struct file *file, struct kobject *kobj, 815 const struct bin_attribute *attr, char *buf, 816 loff_t off, size_t count) 817 { 818 memcpy(buf, attr->private + off, count); 819 return count; 820 } 821 EXPORT_SYMBOL_GPL(sysfs_bin_attr_simple_read); 822