root/fs/configfs/file.c

/* [<][>][^][v][top][bottom][index][help] */

DEFINITIONS

This source file includes following definitions.
  1. to_frag
  2. fill_read_buffer
  3. configfs_read_file
  4. configfs_read_bin_file
  5. fill_write_buffer
  6. flush_write_buffer
  7. configfs_write_file
  8. configfs_write_bin_file
  9. __configfs_open_file
  10. configfs_release
  11. configfs_open_file
  12. configfs_open_bin_file
  13. configfs_release_bin_file
  14. configfs_create_file
  15. configfs_create_bin_file

   1 // SPDX-License-Identifier: GPL-2.0-or-later
   2 /* -*- mode: c; c-basic-offset: 8; -*-
   3  * vim: noexpandtab sw=8 ts=8 sts=0:
   4  *
   5  * file.c - operations for regular (text) files.
   6  *
   7  * Based on sysfs:
   8  *      sysfs is Copyright (C) 2001, 2002, 2003 Patrick Mochel
   9  *
  10  * configfs Copyright (C) 2005 Oracle.  All rights reserved.
  11  */
  12 
  13 #include <linux/fs.h>
  14 #include <linux/module.h>
  15 #include <linux/slab.h>
  16 #include <linux/mutex.h>
  17 #include <linux/vmalloc.h>
  18 #include <linux/uaccess.h>
  19 
  20 #include <linux/configfs.h>
  21 #include "configfs_internal.h"
  22 
  23 /*
  24  * A simple attribute can only be 4096 characters.  Why 4k?  Because the
  25  * original code limited it to PAGE_SIZE.  That's a bad idea, though,
  26  * because an attribute of 16k on ia64 won't work on x86.  So we limit to
  27  * 4k, our minimum common page size.
  28  */
  29 #define SIMPLE_ATTR_SIZE 4096
  30 
  31 struct configfs_buffer {
  32         size_t                  count;
  33         loff_t                  pos;
  34         char                    * page;
  35         struct configfs_item_operations * ops;
  36         struct mutex            mutex;
  37         int                     needs_read_fill;
  38         bool                    read_in_progress;
  39         bool                    write_in_progress;
  40         char                    *bin_buffer;
  41         int                     bin_buffer_size;
  42         int                     cb_max_size;
  43         struct config_item      *item;
  44         struct module           *owner;
  45         union {
  46                 struct configfs_attribute       *attr;
  47                 struct configfs_bin_attribute   *bin_attr;
  48         };
  49 };
  50 
  51 static inline struct configfs_fragment *to_frag(struct file *file)
  52 {
  53         struct configfs_dirent *sd = file->f_path.dentry->d_fsdata;
  54 
  55         return sd->s_frag;
  56 }
  57 
  58 static int fill_read_buffer(struct file *file, struct configfs_buffer *buffer)
  59 {
  60         struct configfs_fragment *frag = to_frag(file);
  61         ssize_t count = -ENOENT;
  62 
  63         if (!buffer->page)
  64                 buffer->page = (char *) get_zeroed_page(GFP_KERNEL);
  65         if (!buffer->page)
  66                 return -ENOMEM;
  67 
  68         down_read(&frag->frag_sem);
  69         if (!frag->frag_dead)
  70                 count = buffer->attr->show(buffer->item, buffer->page);
  71         up_read(&frag->frag_sem);
  72 
  73         if (count < 0)
  74                 return count;
  75         if (WARN_ON_ONCE(count > (ssize_t)SIMPLE_ATTR_SIZE))
  76                 return -EIO;
  77         buffer->needs_read_fill = 0;
  78         buffer->count = count;
  79         return 0;
  80 }
  81 
  82 /**
  83  *      configfs_read_file - read an attribute.
  84  *      @file:  file pointer.
  85  *      @buf:   buffer to fill.
  86  *      @count: number of bytes to read.
  87  *      @ppos:  starting offset in file.
  88  *
  89  *      Userspace wants to read an attribute file. The attribute descriptor
  90  *      is in the file's ->d_fsdata. The target item is in the directory's
  91  *      ->d_fsdata.
  92  *
  93  *      We call fill_read_buffer() to allocate and fill the buffer from the
  94  *      item's show() method exactly once (if the read is happening from
  95  *      the beginning of the file). That should fill the entire buffer with
  96  *      all the data the item has to offer for that attribute.
  97  *      We then call flush_read_buffer() to copy the buffer to userspace
  98  *      in the increments specified.
  99  */
 100 
 101 static ssize_t
 102 configfs_read_file(struct file *file, char __user *buf, size_t count, loff_t *ppos)
 103 {
 104         struct configfs_buffer *buffer = file->private_data;
 105         ssize_t retval = 0;
 106 
 107         mutex_lock(&buffer->mutex);
 108         if (buffer->needs_read_fill) {
 109                 retval = fill_read_buffer(file, buffer);
 110                 if (retval)
 111                         goto out;
 112         }
 113         pr_debug("%s: count = %zd, ppos = %lld, buf = %s\n",
 114                  __func__, count, *ppos, buffer->page);
 115         retval = simple_read_from_buffer(buf, count, ppos, buffer->page,
 116                                          buffer->count);
 117 out:
 118         mutex_unlock(&buffer->mutex);
 119         return retval;
 120 }
 121 
 122 /**
 123  *      configfs_read_bin_file - read a binary attribute.
 124  *      @file:  file pointer.
 125  *      @buf:   buffer to fill.
 126  *      @count: number of bytes to read.
 127  *      @ppos:  starting offset in file.
 128  *
 129  *      Userspace wants to read a binary attribute file. The attribute
 130  *      descriptor is in the file's ->d_fsdata. The target item is in the
 131  *      directory's ->d_fsdata.
 132  *
 133  *      We check whether we need to refill the buffer. If so we will
 134  *      call the attributes' attr->read() twice. The first time we
 135  *      will pass a NULL as a buffer pointer, which the attributes' method
 136  *      will use to return the size of the buffer required. If no error
 137  *      occurs we will allocate the buffer using vmalloc and call
 138  *      attr->read() again passing that buffer as an argument.
 139  *      Then we just copy to user-space using simple_read_from_buffer.
 140  */
 141 
 142 static ssize_t
 143 configfs_read_bin_file(struct file *file, char __user *buf,
 144                        size_t count, loff_t *ppos)
 145 {
 146         struct configfs_fragment *frag = to_frag(file);
 147         struct configfs_buffer *buffer = file->private_data;
 148         ssize_t retval = 0;
 149         ssize_t len = min_t(size_t, count, PAGE_SIZE);
 150 
 151         mutex_lock(&buffer->mutex);
 152 
 153         /* we don't support switching read/write modes */
 154         if (buffer->write_in_progress) {
 155                 retval = -ETXTBSY;
 156                 goto out;
 157         }
 158         buffer->read_in_progress = true;
 159 
 160         if (buffer->needs_read_fill) {
 161                 /* perform first read with buf == NULL to get extent */
 162                 down_read(&frag->frag_sem);
 163                 if (!frag->frag_dead)
 164                         len = buffer->bin_attr->read(buffer->item, NULL, 0);
 165                 else
 166                         len = -ENOENT;
 167                 up_read(&frag->frag_sem);
 168                 if (len <= 0) {
 169                         retval = len;
 170                         goto out;
 171                 }
 172 
 173                 /* do not exceed the maximum value */
 174                 if (buffer->cb_max_size && len > buffer->cb_max_size) {
 175                         retval = -EFBIG;
 176                         goto out;
 177                 }
 178 
 179                 buffer->bin_buffer = vmalloc(len);
 180                 if (buffer->bin_buffer == NULL) {
 181                         retval = -ENOMEM;
 182                         goto out;
 183                 }
 184                 buffer->bin_buffer_size = len;
 185 
 186                 /* perform second read to fill buffer */
 187                 down_read(&frag->frag_sem);
 188                 if (!frag->frag_dead)
 189                         len = buffer->bin_attr->read(buffer->item,
 190                                                      buffer->bin_buffer, len);
 191                 else
 192                         len = -ENOENT;
 193                 up_read(&frag->frag_sem);
 194                 if (len < 0) {
 195                         retval = len;
 196                         vfree(buffer->bin_buffer);
 197                         buffer->bin_buffer_size = 0;
 198                         buffer->bin_buffer = NULL;
 199                         goto out;
 200                 }
 201 
 202                 buffer->needs_read_fill = 0;
 203         }
 204 
 205         retval = simple_read_from_buffer(buf, count, ppos, buffer->bin_buffer,
 206                                         buffer->bin_buffer_size);
 207 out:
 208         mutex_unlock(&buffer->mutex);
 209         return retval;
 210 }
 211 
 212 
 213 /**
 214  *      fill_write_buffer - copy buffer from userspace.
 215  *      @buffer:        data buffer for file.
 216  *      @buf:           data from user.
 217  *      @count:         number of bytes in @userbuf.
 218  *
 219  *      Allocate @buffer->page if it hasn't been already, then
 220  *      copy the user-supplied buffer into it.
 221  */
 222 
 223 static int
 224 fill_write_buffer(struct configfs_buffer * buffer, const char __user * buf, size_t count)
 225 {
 226         int error;
 227 
 228         if (!buffer->page)
 229                 buffer->page = (char *)__get_free_pages(GFP_KERNEL, 0);
 230         if (!buffer->page)
 231                 return -ENOMEM;
 232 
 233         if (count >= SIMPLE_ATTR_SIZE)
 234                 count = SIMPLE_ATTR_SIZE - 1;
 235         error = copy_from_user(buffer->page,buf,count);
 236         buffer->needs_read_fill = 1;
 237         /* if buf is assumed to contain a string, terminate it by \0,
 238          * so e.g. sscanf() can scan the string easily */
 239         buffer->page[count] = 0;
 240         return error ? -EFAULT : count;
 241 }
 242 
 243 static int
 244 flush_write_buffer(struct file *file, struct configfs_buffer *buffer, size_t count)
 245 {
 246         struct configfs_fragment *frag = to_frag(file);
 247         int res = -ENOENT;
 248 
 249         down_read(&frag->frag_sem);
 250         if (!frag->frag_dead)
 251                 res = buffer->attr->store(buffer->item, buffer->page, count);
 252         up_read(&frag->frag_sem);
 253         return res;
 254 }
 255 
 256 
 257 /**
 258  *      configfs_write_file - write an attribute.
 259  *      @file:  file pointer
 260  *      @buf:   data to write
 261  *      @count: number of bytes
 262  *      @ppos:  starting offset
 263  *
 264  *      Similar to configfs_read_file(), though working in the opposite direction.
 265  *      We allocate and fill the data from the user in fill_write_buffer(),
 266  *      then push it to the config_item in flush_write_buffer().
 267  *      There is no easy way for us to know if userspace is only doing a partial
 268  *      write, so we don't support them. We expect the entire buffer to come
 269  *      on the first write.
 270  *      Hint: if you're writing a value, first read the file, modify only the
 271  *      the value you're changing, then write entire buffer back.
 272  */
 273 
 274 static ssize_t
 275 configfs_write_file(struct file *file, const char __user *buf, size_t count, loff_t *ppos)
 276 {
 277         struct configfs_buffer *buffer = file->private_data;
 278         ssize_t len;
 279 
 280         mutex_lock(&buffer->mutex);
 281         len = fill_write_buffer(buffer, buf, count);
 282         if (len > 0)
 283                 len = flush_write_buffer(file, buffer, len);
 284         if (len > 0)
 285                 *ppos += len;
 286         mutex_unlock(&buffer->mutex);
 287         return len;
 288 }
 289 
 290 /**
 291  *      configfs_write_bin_file - write a binary attribute.
 292  *      @file:  file pointer
 293  *      @buf:   data to write
 294  *      @count: number of bytes
 295  *      @ppos:  starting offset
 296  *
 297  *      Writing to a binary attribute file is similar to a normal read.
 298  *      We buffer the consecutive writes (binary attribute files do not
 299  *      support lseek) in a continuously growing buffer, but we don't
 300  *      commit until the close of the file.
 301  */
 302 
 303 static ssize_t
 304 configfs_write_bin_file(struct file *file, const char __user *buf,
 305                         size_t count, loff_t *ppos)
 306 {
 307         struct configfs_buffer *buffer = file->private_data;
 308         void *tbuf = NULL;
 309         ssize_t len;
 310 
 311         mutex_lock(&buffer->mutex);
 312 
 313         /* we don't support switching read/write modes */
 314         if (buffer->read_in_progress) {
 315                 len = -ETXTBSY;
 316                 goto out;
 317         }
 318         buffer->write_in_progress = true;
 319 
 320         /* buffer grows? */
 321         if (*ppos + count > buffer->bin_buffer_size) {
 322 
 323                 if (buffer->cb_max_size &&
 324                         *ppos + count > buffer->cb_max_size) {
 325                         len = -EFBIG;
 326                         goto out;
 327                 }
 328 
 329                 tbuf = vmalloc(*ppos + count);
 330                 if (tbuf == NULL) {
 331                         len = -ENOMEM;
 332                         goto out;
 333                 }
 334 
 335                 /* copy old contents */
 336                 if (buffer->bin_buffer) {
 337                         memcpy(tbuf, buffer->bin_buffer,
 338                                 buffer->bin_buffer_size);
 339                         vfree(buffer->bin_buffer);
 340                 }
 341 
 342                 /* clear the new area */
 343                 memset(tbuf + buffer->bin_buffer_size, 0,
 344                         *ppos + count - buffer->bin_buffer_size);
 345                 buffer->bin_buffer = tbuf;
 346                 buffer->bin_buffer_size = *ppos + count;
 347         }
 348 
 349         len = simple_write_to_buffer(buffer->bin_buffer,
 350                         buffer->bin_buffer_size, ppos, buf, count);
 351 out:
 352         mutex_unlock(&buffer->mutex);
 353         return len;
 354 }
 355 
 356 static int __configfs_open_file(struct inode *inode, struct file *file, int type)
 357 {
 358         struct dentry *dentry = file->f_path.dentry;
 359         struct configfs_fragment *frag = to_frag(file);
 360         struct configfs_attribute *attr;
 361         struct configfs_buffer *buffer;
 362         int error;
 363 
 364         error = -ENOMEM;
 365         buffer = kzalloc(sizeof(struct configfs_buffer), GFP_KERNEL);
 366         if (!buffer)
 367                 goto out;
 368 
 369         error = -ENOENT;
 370         down_read(&frag->frag_sem);
 371         if (unlikely(frag->frag_dead))
 372                 goto out_free_buffer;
 373 
 374         error = -EINVAL;
 375         buffer->item = to_item(dentry->d_parent);
 376         if (!buffer->item)
 377                 goto out_free_buffer;
 378 
 379         attr = to_attr(dentry);
 380         if (!attr)
 381                 goto out_put_item;
 382 
 383         if (type & CONFIGFS_ITEM_BIN_ATTR) {
 384                 buffer->bin_attr = to_bin_attr(dentry);
 385                 buffer->cb_max_size = buffer->bin_attr->cb_max_size;
 386         } else {
 387                 buffer->attr = attr;
 388         }
 389 
 390         buffer->owner = attr->ca_owner;
 391         /* Grab the module reference for this attribute if we have one */
 392         error = -ENODEV;
 393         if (!try_module_get(buffer->owner))
 394                 goto out_put_item;
 395 
 396         error = -EACCES;
 397         if (!buffer->item->ci_type)
 398                 goto out_put_module;
 399 
 400         buffer->ops = buffer->item->ci_type->ct_item_ops;
 401 
 402         /* File needs write support.
 403          * The inode's perms must say it's ok,
 404          * and we must have a store method.
 405          */
 406         if (file->f_mode & FMODE_WRITE) {
 407                 if (!(inode->i_mode & S_IWUGO))
 408                         goto out_put_module;
 409                 if ((type & CONFIGFS_ITEM_ATTR) && !attr->store)
 410                         goto out_put_module;
 411                 if ((type & CONFIGFS_ITEM_BIN_ATTR) && !buffer->bin_attr->write)
 412                         goto out_put_module;
 413         }
 414 
 415         /* File needs read support.
 416          * The inode's perms must say it's ok, and we there
 417          * must be a show method for it.
 418          */
 419         if (file->f_mode & FMODE_READ) {
 420                 if (!(inode->i_mode & S_IRUGO))
 421                         goto out_put_module;
 422                 if ((type & CONFIGFS_ITEM_ATTR) && !attr->show)
 423                         goto out_put_module;
 424                 if ((type & CONFIGFS_ITEM_BIN_ATTR) && !buffer->bin_attr->read)
 425                         goto out_put_module;
 426         }
 427 
 428         mutex_init(&buffer->mutex);
 429         buffer->needs_read_fill = 1;
 430         buffer->read_in_progress = false;
 431         buffer->write_in_progress = false;
 432         file->private_data = buffer;
 433         up_read(&frag->frag_sem);
 434         return 0;
 435 
 436 out_put_module:
 437         module_put(buffer->owner);
 438 out_put_item:
 439         config_item_put(buffer->item);
 440 out_free_buffer:
 441         up_read(&frag->frag_sem);
 442         kfree(buffer);
 443 out:
 444         return error;
 445 }
 446 
 447 static int configfs_release(struct inode *inode, struct file *filp)
 448 {
 449         struct configfs_buffer *buffer = filp->private_data;
 450 
 451         module_put(buffer->owner);
 452         if (buffer->page)
 453                 free_page((unsigned long)buffer->page);
 454         mutex_destroy(&buffer->mutex);
 455         kfree(buffer);
 456         return 0;
 457 }
 458 
 459 static int configfs_open_file(struct inode *inode, struct file *filp)
 460 {
 461         return __configfs_open_file(inode, filp, CONFIGFS_ITEM_ATTR);
 462 }
 463 
 464 static int configfs_open_bin_file(struct inode *inode, struct file *filp)
 465 {
 466         return __configfs_open_file(inode, filp, CONFIGFS_ITEM_BIN_ATTR);
 467 }
 468 
 469 static int configfs_release_bin_file(struct inode *inode, struct file *file)
 470 {
 471         struct configfs_buffer *buffer = file->private_data;
 472 
 473         buffer->read_in_progress = false;
 474 
 475         if (buffer->write_in_progress) {
 476                 struct configfs_fragment *frag = to_frag(file);
 477                 buffer->write_in_progress = false;
 478 
 479                 down_read(&frag->frag_sem);
 480                 if (!frag->frag_dead) {
 481                         /* result of ->release() is ignored */
 482                         buffer->bin_attr->write(buffer->item,
 483                                         buffer->bin_buffer,
 484                                         buffer->bin_buffer_size);
 485                 }
 486                 up_read(&frag->frag_sem);
 487                 /* vfree on NULL is safe */
 488                 vfree(buffer->bin_buffer);
 489                 buffer->bin_buffer = NULL;
 490                 buffer->bin_buffer_size = 0;
 491                 buffer->needs_read_fill = 1;
 492         }
 493 
 494         configfs_release(inode, file);
 495         return 0;
 496 }
 497 
 498 
 499 const struct file_operations configfs_file_operations = {
 500         .read           = configfs_read_file,
 501         .write          = configfs_write_file,
 502         .llseek         = generic_file_llseek,
 503         .open           = configfs_open_file,
 504         .release        = configfs_release,
 505 };
 506 
 507 const struct file_operations configfs_bin_file_operations = {
 508         .read           = configfs_read_bin_file,
 509         .write          = configfs_write_bin_file,
 510         .llseek         = NULL,         /* bin file is not seekable */
 511         .open           = configfs_open_bin_file,
 512         .release        = configfs_release_bin_file,
 513 };
 514 
 515 /**
 516  *      configfs_create_file - create an attribute file for an item.
 517  *      @item:  item we're creating for.
 518  *      @attr:  atrribute descriptor.
 519  */
 520 
 521 int configfs_create_file(struct config_item * item, const struct configfs_attribute * attr)
 522 {
 523         struct dentry *dir = item->ci_dentry;
 524         struct configfs_dirent *parent_sd = dir->d_fsdata;
 525         umode_t mode = (attr->ca_mode & S_IALLUGO) | S_IFREG;
 526         int error = 0;
 527 
 528         inode_lock_nested(d_inode(dir), I_MUTEX_NORMAL);
 529         error = configfs_make_dirent(parent_sd, NULL, (void *) attr, mode,
 530                                      CONFIGFS_ITEM_ATTR, parent_sd->s_frag);
 531         inode_unlock(d_inode(dir));
 532 
 533         return error;
 534 }
 535 
 536 /**
 537  *      configfs_create_bin_file - create a binary attribute file for an item.
 538  *      @item:  item we're creating for.
 539  *      @attr:  atrribute descriptor.
 540  */
 541 
 542 int configfs_create_bin_file(struct config_item *item,
 543                 const struct configfs_bin_attribute *bin_attr)
 544 {
 545         struct dentry *dir = item->ci_dentry;
 546         struct configfs_dirent *parent_sd = dir->d_fsdata;
 547         umode_t mode = (bin_attr->cb_attr.ca_mode & S_IALLUGO) | S_IFREG;
 548         int error = 0;
 549 
 550         inode_lock_nested(dir->d_inode, I_MUTEX_NORMAL);
 551         error = configfs_make_dirent(parent_sd, NULL, (void *) bin_attr, mode,
 552                                      CONFIGFS_ITEM_BIN_ATTR, parent_sd->s_frag);
 553         inode_unlock(dir->d_inode);
 554 
 555         return error;
 556 }

/* [<][>][^][v][top][bottom][index][help] */