at v6.16-rc2 832 lines 21 kB view raw
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 22static 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 */ 32static 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 */ 46static 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 83static 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 */ 110static 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 */ 136static 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 */ 149static 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 173static 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 182static 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 194static 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 204void 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} 224EXPORT_SYMBOL_GPL(sysfs_notify); 225 226static const struct kernfs_ops sysfs_file_kfops_empty = { 227}; 228 229static const struct kernfs_ops sysfs_file_kfops_ro = { 230 .seq_show = sysfs_kf_seq_show, 231}; 232 233static const struct kernfs_ops sysfs_file_kfops_wo = { 234 .write = sysfs_kf_write, 235}; 236 237static const struct kernfs_ops sysfs_file_kfops_rw = { 238 .seq_show = sysfs_kf_seq_show, 239 .write = sysfs_kf_write, 240}; 241 242static const struct kernfs_ops sysfs_prealloc_kfops_ro = { 243 .read = sysfs_kf_read, 244 .prealloc = true, 245}; 246 247static const struct kernfs_ops sysfs_prealloc_kfops_wo = { 248 .write = sysfs_kf_write, 249 .prealloc = true, 250}; 251 252static const struct kernfs_ops sysfs_prealloc_kfops_rw = { 253 .read = sysfs_kf_read, 254 .write = sysfs_kf_write, 255 .prealloc = true, 256}; 257 258static const struct kernfs_ops sysfs_bin_kfops_ro = { 259 .read = sysfs_kf_bin_read, 260}; 261 262static const struct kernfs_ops sysfs_bin_kfops_wo = { 263 .write = sysfs_kf_bin_write, 264}; 265 266static const struct kernfs_ops sysfs_bin_kfops_rw = { 267 .read = sysfs_kf_bin_read, 268 .write = sysfs_kf_bin_write, 269}; 270 271static 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 279int 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 329int 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 */ 376int 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} 388EXPORT_SYMBOL_GPL(sysfs_create_file_ns); 389 390int 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} 402EXPORT_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 */ 410int 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} 435EXPORT_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 */ 444int 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} 463EXPORT_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 */ 475struct 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} 488EXPORT_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 */ 501void 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} 509EXPORT_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 */ 519void 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} 526EXPORT_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 */ 535bool 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} 550EXPORT_SYMBOL_GPL(sysfs_remove_file_self); 551 552void 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} 559EXPORT_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 */ 567void 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} 584EXPORT_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 */ 591int 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} 604EXPORT_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 */ 611void 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} 616EXPORT_SYMBOL_GPL(sysfs_remove_bin_file); 617 618static 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 */ 643int 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 665out: 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 */ 682int 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} 704EXPORT_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 */ 724int 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} 751EXPORT_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 */ 762int 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} 777EXPORT_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 */ 790int 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} 805EXPORT_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 */ 825ssize_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} 832EXPORT_SYMBOL_GPL(sysfs_bin_attr_simple_read);