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