file.c 20 KB

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