LCOV - code coverage report
Current view: top level - fs/sysfs - file.c (source / functions) Hit Total Coverage
Test: combined.info Lines: 93 201 46.3 %
Date: 2022-03-28 16:04:14 Functions: 9 20 45.0 %
Branches: 52 138 37.7 %

           Branch data     Line data    Source code
       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.txt 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                 :            : 
      19                 :            : #include "sysfs.h"
      20                 :            : 
      21                 :            : /*
      22                 :            :  * Determine ktype->sysfs_ops for the given kernfs_node.  This function
      23                 :            :  * must be called while holding an active reference.
      24                 :            :  */
      25                 :      19065 : static const struct sysfs_ops *sysfs_file_ops(struct kernfs_node *kn)
      26                 :            : {
      27                 :      19065 :         struct kobject *kobj = kn->parent->priv;
      28                 :            : 
      29                 :      19065 :         if (kn->flags & KERNFS_LOCKDEP)
      30                 :      19065 :                 lockdep_assert_held(kn);
      31                 :      19065 :         return kobj->ktype ? kobj->ktype->sysfs_ops : NULL;
      32                 :            : }
      33                 :            : 
      34                 :            : /*
      35                 :            :  * Reads on sysfs are handled through seq_file, which takes care of hairy
      36                 :            :  * details like buffering and seeking.  The following function pipes
      37                 :            :  * sysfs_ops->show() result through seq_file.
      38                 :            :  */
      39                 :      12019 : static int sysfs_kf_seq_show(struct seq_file *sf, void *v)
      40                 :            : {
      41                 :      12019 :         struct kernfs_open_file *of = sf->private;
      42                 :      12019 :         struct kobject *kobj = of->kn->parent->priv;
      43         [ +  - ]:      12019 :         const struct sysfs_ops *ops = sysfs_file_ops(of->kn);
      44                 :      12019 :         ssize_t count;
      45                 :      12019 :         char *buf;
      46                 :            : 
      47                 :            :         /* acquire buffer and ensure that it's >= PAGE_SIZE and clear */
      48         [ -  + ]:      12019 :         count = seq_get_buf(sf, &buf);
      49         [ -  + ]:      12019 :         if (count < PAGE_SIZE) {
      50                 :          0 :                 seq_commit(sf, -1);
      51                 :          0 :                 return 0;
      52                 :            :         }
      53                 :      12019 :         memset(buf, 0, PAGE_SIZE);
      54                 :            : 
      55                 :            :         /*
      56                 :            :          * Invoke show().  Control may reach here via seq file lseek even
      57                 :            :          * if @ops->show() isn't implemented.
      58                 :            :          */
      59         [ +  - ]:      12019 :         if (ops->show) {
      60                 :      12019 :                 count = ops->show(kobj, of->kn->priv, buf);
      61         [ +  + ]:      12019 :                 if (count < 0)
      62                 :         52 :                         return count;
      63                 :            :         }
      64                 :            : 
      65                 :            :         /*
      66                 :            :          * The code works fine with PAGE_SIZE return but it's likely to
      67                 :            :          * indicate truncated result or overflow in normal use cases.
      68                 :            :          */
      69         [ -  + ]:      11967 :         if (count >= (ssize_t)PAGE_SIZE) {
      70                 :          0 :                 printk("fill_read_buffer: %pS returned bad count\n",
      71                 :            :                                 ops->show);
      72                 :            :                 /* Try to struggle along */
      73                 :          0 :                 count = PAGE_SIZE - 1;
      74                 :            :         }
      75         [ -  + ]:      11967 :         seq_commit(sf, count);
      76                 :            :         return 0;
      77                 :            : }
      78                 :            : 
      79                 :          0 : static ssize_t sysfs_kf_bin_read(struct kernfs_open_file *of, char *buf,
      80                 :            :                                  size_t count, loff_t pos)
      81                 :            : {
      82                 :          0 :         struct bin_attribute *battr = of->kn->priv;
      83                 :          0 :         struct kobject *kobj = of->kn->parent->priv;
      84         [ #  # ]:          0 :         loff_t size = file_inode(of->file)->i_size;
      85                 :            : 
      86         [ #  # ]:          0 :         if (!count)
      87                 :            :                 return 0;
      88                 :            : 
      89         [ #  # ]:          0 :         if (size) {
      90         [ #  # ]:          0 :                 if (pos >= size)
      91                 :            :                         return 0;
      92         [ #  # ]:          0 :                 if (pos + count > size)
      93                 :          0 :                         count = size - pos;
      94                 :            :         }
      95                 :            : 
      96         [ #  # ]:          0 :         if (!battr->read)
      97                 :            :                 return -EIO;
      98                 :            : 
      99                 :          0 :         return battr->read(of->file, kobj, battr, buf, pos, count);
     100                 :            : }
     101                 :            : 
     102                 :            : /* kernfs read callback for regular sysfs files with pre-alloc */
     103                 :         26 : static ssize_t sysfs_kf_read(struct kernfs_open_file *of, char *buf,
     104                 :            :                              size_t count, loff_t pos)
     105                 :            : {
     106         [ +  - ]:         26 :         const struct sysfs_ops *ops = sysfs_file_ops(of->kn);
     107                 :         26 :         struct kobject *kobj = of->kn->parent->priv;
     108                 :         26 :         ssize_t len;
     109                 :            : 
     110                 :            :         /*
     111                 :            :          * If buf != of->prealloc_buf, we don't know how
     112                 :            :          * large it is, so cannot safely pass it to ->show
     113                 :            :          */
     114   [ -  +  +  - ]:         26 :         if (WARN_ON_ONCE(buf != of->prealloc_buf))
     115                 :            :                 return 0;
     116                 :         26 :         len = ops->show(kobj, of->kn->priv, buf);
     117         [ +  - ]:         26 :         if (len < 0)
     118                 :            :                 return len;
     119         [ +  + ]:         26 :         if (pos) {
     120         [ -  + ]:         13 :                 if (len <= pos)
     121                 :            :                         return 0;
     122                 :          0 :                 len -= pos;
     123                 :          0 :                 memmove(buf, buf + pos, len);
     124                 :            :         }
     125                 :         13 :         return min_t(ssize_t, count, len);
     126                 :            : }
     127                 :            : 
     128                 :            : /* kernfs write callback for regular sysfs files */
     129                 :       7020 : static ssize_t sysfs_kf_write(struct kernfs_open_file *of, char *buf,
     130                 :            :                               size_t count, loff_t pos)
     131                 :            : {
     132         [ +  - ]:       7020 :         const struct sysfs_ops *ops = sysfs_file_ops(of->kn);
     133                 :       7020 :         struct kobject *kobj = of->kn->parent->priv;
     134                 :            : 
     135         [ +  - ]:       7020 :         if (!count)
     136                 :            :                 return 0;
     137                 :            : 
     138                 :       7020 :         return ops->store(kobj, of->kn->priv, buf, count);
     139                 :            : }
     140                 :            : 
     141                 :            : /* kernfs write callback for bin sysfs files */
     142                 :          0 : static ssize_t sysfs_kf_bin_write(struct kernfs_open_file *of, char *buf,
     143                 :            :                                   size_t count, loff_t pos)
     144                 :            : {
     145                 :          0 :         struct bin_attribute *battr = of->kn->priv;
     146                 :          0 :         struct kobject *kobj = of->kn->parent->priv;
     147         [ #  # ]:          0 :         loff_t size = file_inode(of->file)->i_size;
     148                 :            : 
     149         [ #  # ]:          0 :         if (size) {
     150         [ #  # ]:          0 :                 if (size <= pos)
     151                 :            :                         return -EFBIG;
     152                 :          0 :                 count = min_t(ssize_t, count, size - pos);
     153                 :            :         }
     154         [ #  # ]:          0 :         if (!count)
     155                 :            :                 return 0;
     156                 :            : 
     157         [ #  # ]:          0 :         if (!battr->write)
     158                 :            :                 return -EIO;
     159                 :            : 
     160                 :          0 :         return battr->write(of->file, kobj, battr, buf, pos, count);
     161                 :            : }
     162                 :            : 
     163                 :          0 : static int sysfs_kf_bin_mmap(struct kernfs_open_file *of,
     164                 :            :                              struct vm_area_struct *vma)
     165                 :            : {
     166                 :          0 :         struct bin_attribute *battr = of->kn->priv;
     167                 :          0 :         struct kobject *kobj = of->kn->parent->priv;
     168                 :            : 
     169                 :          0 :         return battr->mmap(of->file, kobj, battr, vma);
     170                 :            : }
     171                 :            : 
     172                 :         13 : void sysfs_notify(struct kobject *kobj, const char *dir, const char *attr)
     173                 :            : {
     174                 :         13 :         struct kernfs_node *kn = kobj->sd, *tmp;
     175                 :            : 
     176         [ -  + ]:         13 :         if (kn && dir)
     177                 :          0 :                 kn = kernfs_find_and_get(kn, dir);
     178                 :            :         else
     179                 :         13 :                 kernfs_get(kn);
     180                 :            : 
     181         [ +  - ]:         13 :         if (kn && attr) {
     182                 :         13 :                 tmp = kernfs_find_and_get(kn, attr);
     183                 :         13 :                 kernfs_put(kn);
     184                 :         13 :                 kn = tmp;
     185                 :            :         }
     186                 :            : 
     187         [ +  - ]:         13 :         if (kn) {
     188                 :         13 :                 kernfs_notify(kn);
     189                 :         13 :                 kernfs_put(kn);
     190                 :            :         }
     191                 :         13 : }
     192                 :            : EXPORT_SYMBOL_GPL(sysfs_notify);
     193                 :            : 
     194                 :            : static const struct kernfs_ops sysfs_file_kfops_empty = {
     195                 :            : };
     196                 :            : 
     197                 :            : static const struct kernfs_ops sysfs_file_kfops_ro = {
     198                 :            :         .seq_show       = sysfs_kf_seq_show,
     199                 :            : };
     200                 :            : 
     201                 :            : static const struct kernfs_ops sysfs_file_kfops_wo = {
     202                 :            :         .write          = sysfs_kf_write,
     203                 :            : };
     204                 :            : 
     205                 :            : static const struct kernfs_ops sysfs_file_kfops_rw = {
     206                 :            :         .seq_show       = sysfs_kf_seq_show,
     207                 :            :         .write          = sysfs_kf_write,
     208                 :            : };
     209                 :            : 
     210                 :            : static const struct kernfs_ops sysfs_prealloc_kfops_ro = {
     211                 :            :         .read           = sysfs_kf_read,
     212                 :            :         .prealloc       = true,
     213                 :            : };
     214                 :            : 
     215                 :            : static const struct kernfs_ops sysfs_prealloc_kfops_wo = {
     216                 :            :         .write          = sysfs_kf_write,
     217                 :            :         .prealloc       = true,
     218                 :            : };
     219                 :            : 
     220                 :            : static const struct kernfs_ops sysfs_prealloc_kfops_rw = {
     221                 :            :         .read           = sysfs_kf_read,
     222                 :            :         .write          = sysfs_kf_write,
     223                 :            :         .prealloc       = true,
     224                 :            : };
     225                 :            : 
     226                 :            : static const struct kernfs_ops sysfs_bin_kfops_ro = {
     227                 :            :         .read           = sysfs_kf_bin_read,
     228                 :            : };
     229                 :            : 
     230                 :            : static const struct kernfs_ops sysfs_bin_kfops_wo = {
     231                 :            :         .write          = sysfs_kf_bin_write,
     232                 :            : };
     233                 :            : 
     234                 :            : static const struct kernfs_ops sysfs_bin_kfops_rw = {
     235                 :            :         .read           = sysfs_kf_bin_read,
     236                 :            :         .write          = sysfs_kf_bin_write,
     237                 :            : };
     238                 :            : 
     239                 :            : static const struct kernfs_ops sysfs_bin_kfops_mmap = {
     240                 :            :         .read           = sysfs_kf_bin_read,
     241                 :            :         .write          = sysfs_kf_bin_write,
     242                 :            :         .mmap           = sysfs_kf_bin_mmap,
     243                 :            : };
     244                 :            : 
     245                 :     181701 : int sysfs_add_file_mode_ns(struct kernfs_node *parent,
     246                 :            :                            const struct attribute *attr, bool is_bin,
     247                 :            :                            umode_t mode, kuid_t uid, kgid_t gid, const void *ns)
     248                 :            : {
     249                 :     181701 :         struct lock_class_key *key = NULL;
     250                 :     181701 :         const struct kernfs_ops *ops;
     251                 :     181701 :         struct kernfs_node *kn;
     252                 :     181701 :         loff_t size;
     253                 :            : 
     254         [ +  + ]:     181701 :         if (!is_bin) {
     255                 :     181038 :                 struct kobject *kobj = parent->priv;
     256                 :     181038 :                 const struct sysfs_ops *sysfs_ops = kobj->ktype->sysfs_ops;
     257                 :            : 
     258                 :            :                 /* every kobject with an attribute needs a ktype assigned */
     259   [ -  +  +  - ]:     181038 :                 if (WARN(!sysfs_ops, KERN_ERR
     260                 :            :                          "missing sysfs attribute operations for kobject: %s\n",
     261                 :            :                          kobject_name(kobj)))
     262                 :            :                         return -EINVAL;
     263                 :            : 
     264   [ +  -  +  + ]:     181038 :                 if (sysfs_ops->show && sysfs_ops->store) {
     265         [ +  + ]:     180765 :                         if (mode & SYSFS_PREALLOC)
     266                 :            :                                 ops = &sysfs_prealloc_kfops_rw;
     267                 :            :                         else
     268                 :     180726 :                                 ops = &sysfs_file_kfops_rw;
     269         [ +  - ]:        273 :                 } else if (sysfs_ops->show) {
     270         [ +  - ]:        273 :                         if (mode & SYSFS_PREALLOC)
     271                 :            :                                 ops = &sysfs_prealloc_kfops_ro;
     272                 :            :                         else
     273                 :        273 :                                 ops = &sysfs_file_kfops_ro;
     274         [ #  # ]:          0 :                 } else if (sysfs_ops->store) {
     275         [ #  # ]:          0 :                         if (mode & SYSFS_PREALLOC)
     276                 :            :                                 ops = &sysfs_prealloc_kfops_wo;
     277                 :            :                         else
     278                 :          0 :                                 ops = &sysfs_file_kfops_wo;
     279                 :            :                 } else
     280                 :            :                         ops = &sysfs_file_kfops_empty;
     281                 :            : 
     282                 :            :                 size = PAGE_SIZE;
     283                 :            :         } else {
     284                 :        663 :                 struct bin_attribute *battr = (void *)attr;
     285                 :            : 
     286         [ +  + ]:        663 :                 if (battr->mmap)
     287                 :            :                         ops = &sysfs_bin_kfops_mmap;
     288   [ +  -  +  + ]:        572 :                 else if (battr->read && battr->write)
     289                 :            :                         ops = &sysfs_bin_kfops_rw;
     290         [ -  + ]:        338 :                 else if (battr->read)
     291                 :            :                         ops = &sysfs_bin_kfops_ro;
     292         [ #  # ]:          0 :                 else if (battr->write)
     293                 :            :                         ops = &sysfs_bin_kfops_wo;
     294                 :            :                 else
     295                 :          0 :                         ops = &sysfs_file_kfops_empty;
     296                 :            : 
     297                 :        663 :                 size = battr->size;
     298                 :            :         }
     299                 :            : 
     300                 :            : #ifdef CONFIG_DEBUG_LOCK_ALLOC
     301                 :            :         if (!attr->ignore_lockdep)
     302                 :            :                 key = attr->key ?: (struct lock_class_key *)&attr->skey;
     303                 :            : #endif
     304                 :            : 
     305                 :     181701 :         kn = __kernfs_create_file(parent, attr->name, mode & 0777, uid, gid,
     306                 :            :                                   size, ops, (void *)attr, ns, key);
     307         [ -  + ]:     181701 :         if (IS_ERR(kn)) {
     308         [ #  # ]:          0 :                 if (PTR_ERR(kn) == -EEXIST)
     309                 :          0 :                         sysfs_warn_dup(parent, attr->name);
     310                 :          0 :                 return PTR_ERR(kn);
     311                 :            :         }
     312                 :            :         return 0;
     313                 :            : }
     314                 :            : 
     315                 :            : /**
     316                 :            :  * sysfs_create_file_ns - create an attribute file for an object with custom ns
     317                 :            :  * @kobj: object we're creating for
     318                 :            :  * @attr: attribute descriptor
     319                 :            :  * @ns: namespace the new file should belong to
     320                 :            :  */
     321                 :      21788 : int sysfs_create_file_ns(struct kobject *kobj, const struct attribute *attr,
     322                 :            :                          const void *ns)
     323                 :            : {
     324                 :      21788 :         kuid_t uid;
     325                 :      21788 :         kgid_t gid;
     326                 :            : 
     327   [ +  -  +  -  :      43576 :         if (WARN_ON(!kobj || !kobj->sd || !attr))
          +  -  -  +  +  
                      - ]
     328                 :            :                 return -EINVAL;
     329                 :            : 
     330                 :      21788 :         kobject_get_ownership(kobj, &uid, &gid);
     331                 :      21788 :         return sysfs_add_file_mode_ns(kobj->sd, attr, false, attr->mode,
     332                 :            :                                       uid, gid, ns);
     333                 :            : 
     334                 :            : }
     335                 :            : EXPORT_SYMBOL_GPL(sysfs_create_file_ns);
     336                 :            : 
     337                 :        156 : int sysfs_create_files(struct kobject *kobj, const struct attribute * const *ptr)
     338                 :            : {
     339                 :        156 :         int err = 0;
     340                 :        156 :         int i;
     341                 :            : 
     342   [ +  +  +  - ]:        624 :         for (i = 0; ptr[i] && !err; i++)
     343                 :        468 :                 err = sysfs_create_file(kobj, ptr[i]);
     344         [ -  + ]:        156 :         if (err)
     345         [ #  # ]:          0 :                 while (--i >= 0)
     346                 :          0 :                         sysfs_remove_file(kobj, ptr[i]);
     347                 :        156 :         return err;
     348                 :            : }
     349                 :            : EXPORT_SYMBOL_GPL(sysfs_create_files);
     350                 :            : 
     351                 :            : /**
     352                 :            :  * sysfs_add_file_to_group - add an attribute file to a pre-existing group.
     353                 :            :  * @kobj: object we're acting for.
     354                 :            :  * @attr: attribute descriptor.
     355                 :            :  * @group: group name.
     356                 :            :  */
     357                 :          0 : int sysfs_add_file_to_group(struct kobject *kobj,
     358                 :            :                 const struct attribute *attr, const char *group)
     359                 :            : {
     360                 :          0 :         struct kernfs_node *parent;
     361                 :          0 :         kuid_t uid;
     362                 :          0 :         kgid_t gid;
     363                 :          0 :         int error;
     364                 :            : 
     365         [ #  # ]:          0 :         if (group) {
     366                 :          0 :                 parent = kernfs_find_and_get(kobj->sd, group);
     367                 :            :         } else {
     368                 :          0 :                 parent = kobj->sd;
     369                 :          0 :                 kernfs_get(parent);
     370                 :            :         }
     371                 :            : 
     372         [ #  # ]:          0 :         if (!parent)
     373                 :            :                 return -ENOENT;
     374                 :            : 
     375                 :          0 :         kobject_get_ownership(kobj, &uid, &gid);
     376                 :          0 :         error = sysfs_add_file_mode_ns(parent, attr, false,
     377                 :          0 :                                        attr->mode, uid, gid, NULL);
     378                 :          0 :         kernfs_put(parent);
     379                 :            : 
     380                 :          0 :         return error;
     381                 :            : }
     382                 :            : EXPORT_SYMBOL_GPL(sysfs_add_file_to_group);
     383                 :            : 
     384                 :            : /**
     385                 :            :  * sysfs_chmod_file - update the modified mode value on an object attribute.
     386                 :            :  * @kobj: object we're acting for.
     387                 :            :  * @attr: attribute descriptor.
     388                 :            :  * @mode: file permissions.
     389                 :            :  *
     390                 :            :  */
     391                 :          0 : int sysfs_chmod_file(struct kobject *kobj, const struct attribute *attr,
     392                 :            :                      umode_t mode)
     393                 :            : {
     394                 :          0 :         struct kernfs_node *kn;
     395                 :          0 :         struct iattr newattrs;
     396                 :          0 :         int rc;
     397                 :            : 
     398                 :          0 :         kn = kernfs_find_and_get(kobj->sd, attr->name);
     399         [ #  # ]:          0 :         if (!kn)
     400                 :            :                 return -ENOENT;
     401                 :            : 
     402                 :          0 :         newattrs.ia_mode = (mode & S_IALLUGO) | (kn->mode & ~S_IALLUGO);
     403                 :          0 :         newattrs.ia_valid = ATTR_MODE;
     404                 :            : 
     405                 :          0 :         rc = kernfs_setattr(kn, &newattrs);
     406                 :            : 
     407                 :          0 :         kernfs_put(kn);
     408                 :          0 :         return rc;
     409                 :            : }
     410                 :            : EXPORT_SYMBOL_GPL(sysfs_chmod_file);
     411                 :            : 
     412                 :            : /**
     413                 :            :  * sysfs_break_active_protection - break "active" protection
     414                 :            :  * @kobj: The kernel object @attr is associated with.
     415                 :            :  * @attr: The attribute to break the "active" protection for.
     416                 :            :  *
     417                 :            :  * With sysfs, just like kernfs, deletion of an attribute is postponed until
     418                 :            :  * all active .show() and .store() callbacks have finished unless this function
     419                 :            :  * is called. Hence this function is useful in methods that implement self
     420                 :            :  * deletion.
     421                 :            :  */
     422                 :          0 : struct kernfs_node *sysfs_break_active_protection(struct kobject *kobj,
     423                 :            :                                                   const struct attribute *attr)
     424                 :            : {
     425                 :          0 :         struct kernfs_node *kn;
     426                 :            : 
     427                 :          0 :         kobject_get(kobj);
     428                 :          0 :         kn = kernfs_find_and_get(kobj->sd, attr->name);
     429         [ #  # ]:          0 :         if (kn)
     430                 :          0 :                 kernfs_break_active_protection(kn);
     431                 :          0 :         return kn;
     432                 :            : }
     433                 :            : EXPORT_SYMBOL_GPL(sysfs_break_active_protection);
     434                 :            : 
     435                 :            : /**
     436                 :            :  * sysfs_unbreak_active_protection - restore "active" protection
     437                 :            :  * @kn: Pointer returned by sysfs_break_active_protection().
     438                 :            :  *
     439                 :            :  * Undo the effects of sysfs_break_active_protection(). Since this function
     440                 :            :  * calls kernfs_put() on the kernfs node that corresponds to the 'attr'
     441                 :            :  * argument passed to sysfs_break_active_protection() that attribute may have
     442                 :            :  * been removed between the sysfs_break_active_protection() and
     443                 :            :  * sysfs_unbreak_active_protection() calls, it is not safe to access @kn after
     444                 :            :  * this function has returned.
     445                 :            :  */
     446                 :          0 : void sysfs_unbreak_active_protection(struct kernfs_node *kn)
     447                 :            : {
     448                 :          0 :         struct kobject *kobj = kn->parent->priv;
     449                 :            : 
     450                 :          0 :         kernfs_unbreak_active_protection(kn);
     451                 :          0 :         kernfs_put(kn);
     452                 :          0 :         kobject_put(kobj);
     453                 :          0 : }
     454                 :            : EXPORT_SYMBOL_GPL(sysfs_unbreak_active_protection);
     455                 :            : 
     456                 :            : /**
     457                 :            :  * sysfs_remove_file_ns - remove an object attribute with a custom ns tag
     458                 :            :  * @kobj: object we're acting for
     459                 :            :  * @attr: attribute descriptor
     460                 :            :  * @ns: namespace tag of the file to remove
     461                 :            :  *
     462                 :            :  * Hash the attribute name and namespace tag and kill the victim.
     463                 :            :  */
     464                 :        143 : void sysfs_remove_file_ns(struct kobject *kobj, const struct attribute *attr,
     465                 :            :                           const void *ns)
     466                 :            : {
     467                 :        143 :         struct kernfs_node *parent = kobj->sd;
     468                 :            : 
     469                 :        143 :         kernfs_remove_by_name_ns(parent, attr->name, ns);
     470                 :        143 : }
     471                 :            : EXPORT_SYMBOL_GPL(sysfs_remove_file_ns);
     472                 :            : 
     473                 :            : /**
     474                 :            :  * sysfs_remove_file_self - remove an object attribute from its own method
     475                 :            :  * @kobj: object we're acting for
     476                 :            :  * @attr: attribute descriptor
     477                 :            :  *
     478                 :            :  * See kernfs_remove_self() for details.
     479                 :            :  */
     480                 :          0 : bool sysfs_remove_file_self(struct kobject *kobj, const struct attribute *attr)
     481                 :            : {
     482                 :          0 :         struct kernfs_node *parent = kobj->sd;
     483                 :          0 :         struct kernfs_node *kn;
     484                 :          0 :         bool ret;
     485                 :            : 
     486                 :          0 :         kn = kernfs_find_and_get(parent, attr->name);
     487   [ #  #  #  # ]:          0 :         if (WARN_ON_ONCE(!kn))
     488                 :            :                 return false;
     489                 :            : 
     490                 :          0 :         ret = kernfs_remove_self(kn);
     491                 :            : 
     492                 :          0 :         kernfs_put(kn);
     493                 :          0 :         return ret;
     494                 :            : }
     495                 :            : 
     496                 :          0 : void sysfs_remove_files(struct kobject *kobj, const struct attribute * const *ptr)
     497                 :            : {
     498                 :          0 :         int i;
     499                 :            : 
     500         [ #  # ]:          0 :         for (i = 0; ptr[i]; i++)
     501                 :          0 :                 sysfs_remove_file(kobj, ptr[i]);
     502                 :          0 : }
     503                 :            : EXPORT_SYMBOL_GPL(sysfs_remove_files);
     504                 :            : 
     505                 :            : /**
     506                 :            :  * sysfs_remove_file_from_group - remove an attribute file from a group.
     507                 :            :  * @kobj: object we're acting for.
     508                 :            :  * @attr: attribute descriptor.
     509                 :            :  * @group: group name.
     510                 :            :  */
     511                 :          0 : void sysfs_remove_file_from_group(struct kobject *kobj,
     512                 :            :                 const struct attribute *attr, const char *group)
     513                 :            : {
     514                 :          0 :         struct kernfs_node *parent;
     515                 :            : 
     516         [ #  # ]:          0 :         if (group) {
     517                 :          0 :                 parent = kernfs_find_and_get(kobj->sd, group);
     518                 :            :         } else {
     519                 :          0 :                 parent = kobj->sd;
     520                 :          0 :                 kernfs_get(parent);
     521                 :            :         }
     522                 :            : 
     523         [ #  # ]:          0 :         if (parent) {
     524                 :          0 :                 kernfs_remove_by_name(parent, attr->name);
     525                 :          0 :                 kernfs_put(parent);
     526                 :            :         }
     527                 :          0 : }
     528                 :            : EXPORT_SYMBOL_GPL(sysfs_remove_file_from_group);
     529                 :            : 
     530                 :            : /**
     531                 :            :  *      sysfs_create_bin_file - create binary file for object.
     532                 :            :  *      @kobj:  object.
     533                 :            :  *      @attr:  attribute descriptor.
     534                 :            :  */
     535                 :        429 : int sysfs_create_bin_file(struct kobject *kobj,
     536                 :            :                           const struct bin_attribute *attr)
     537                 :            : {
     538                 :        429 :         kuid_t uid;
     539                 :        429 :         kgid_t gid;
     540                 :            : 
     541   [ +  -  +  -  :        858 :         if (WARN_ON(!kobj || !kobj->sd || !attr))
          +  -  -  +  +  
                      - ]
     542                 :            :                 return -EINVAL;
     543                 :            : 
     544                 :        429 :         kobject_get_ownership(kobj, &uid, &gid);
     545                 :        429 :         return sysfs_add_file_mode_ns(kobj->sd, &attr->attr, true,
     546                 :        429 :                                       attr->attr.mode, uid, gid, NULL);
     547                 :            : }
     548                 :            : EXPORT_SYMBOL_GPL(sysfs_create_bin_file);
     549                 :            : 
     550                 :            : /**
     551                 :            :  *      sysfs_remove_bin_file - remove binary file for object.
     552                 :            :  *      @kobj:  object.
     553                 :            :  *      @attr:  attribute descriptor.
     554                 :            :  */
     555                 :          0 : void sysfs_remove_bin_file(struct kobject *kobj,
     556                 :            :                            const struct bin_attribute *attr)
     557                 :            : {
     558                 :          0 :         kernfs_remove_by_name(kobj->sd, attr->attr.name);
     559                 :          0 : }
     560                 :            : EXPORT_SYMBOL_GPL(sysfs_remove_bin_file);

Generated by: LCOV version 1.14