LCOV - code coverage report
Current view: top level - fs - ioctl.c (source / functions) Hit Total Coverage
Test: coverage.info Lines: 63 170 37.1 %
Date: 2014-02-18 Functions: 7 14 50.0 %
Branches: 38 140 27.1 %

           Branch data     Line data    Source code
       1                 :            : /*
       2                 :            :  *  linux/fs/ioctl.c
       3                 :            :  *
       4                 :            :  *  Copyright (C) 1991, 1992  Linus Torvalds
       5                 :            :  */
       6                 :            : 
       7                 :            : #include <linux/syscalls.h>
       8                 :            : #include <linux/mm.h>
       9                 :            : #include <linux/capability.h>
      10                 :            : #include <linux/file.h>
      11                 :            : #include <linux/fs.h>
      12                 :            : #include <linux/security.h>
      13                 :            : #include <linux/export.h>
      14                 :            : #include <linux/uaccess.h>
      15                 :            : #include <linux/writeback.h>
      16                 :            : #include <linux/buffer_head.h>
      17                 :            : #include <linux/falloc.h>
      18                 :            : 
      19                 :            : #include <asm/ioctls.h>
      20                 :            : 
      21                 :            : /* So that the fiemap access checks can't overflow on 32 bit machines. */
      22                 :            : #define FIEMAP_MAX_EXTENTS      (UINT_MAX / sizeof(struct fiemap_extent))
      23                 :            : 
      24                 :            : /**
      25                 :            :  * vfs_ioctl - call filesystem specific ioctl methods
      26                 :            :  * @filp:       open file to invoke ioctl method on
      27                 :            :  * @cmd:        ioctl command to execute
      28                 :            :  * @arg:        command-specific argument for ioctl
      29                 :            :  *
      30                 :            :  * Invokes filesystem specific ->unlocked_ioctl, if one exists; otherwise
      31                 :            :  * returns -ENOTTY.
      32                 :            :  *
      33                 :            :  * Returns 0 on success, -errno on error.
      34                 :            :  */
      35                 :            : static long vfs_ioctl(struct file *filp, unsigned int cmd,
      36                 :            :                       unsigned long arg)
      37                 :            : {
      38                 :            :         int error = -ENOTTY;
      39                 :            : 
      40 [ +  + ][ +  + ]:     105502 :         if (!filp->f_op->unlocked_ioctl)
      41                 :            :                 goto out;
      42                 :            : 
      43                 :      90553 :         error = filp->f_op->unlocked_ioctl(filp, cmd, arg);
      44 [ +  + ][ -  + ]:      99705 :         if (error == -ENOIOCTLCMD)
      45                 :            :                 error = -ENOTTY;
      46                 :            :  out:
      47                 :            :         return error;
      48                 :            : }
      49                 :            : 
      50                 :          0 : static int ioctl_fibmap(struct file *filp, int __user *p)
      51                 :            : {
      52                 :          0 :         struct address_space *mapping = filp->f_mapping;
      53                 :            :         int res, block;
      54                 :            : 
      55                 :            :         /* do we support this mess? */
      56         [ #  # ]:          0 :         if (!mapping->a_ops->bmap)
      57                 :            :                 return -EINVAL;
      58         [ #  # ]:          0 :         if (!capable(CAP_SYS_RAWIO))
      59                 :            :                 return -EPERM;
      60                 :          0 :         res = get_user(block, p);
      61         [ #  # ]:          0 :         if (res)
      62                 :            :                 return res;
      63                 :          0 :         res = mapping->a_ops->bmap(mapping, block);
      64                 :          0 :         return put_user(res, p);
      65                 :            : }
      66                 :            : 
      67                 :            : /**
      68                 :            :  * fiemap_fill_next_extent - Fiemap helper function
      69                 :            :  * @fieinfo:    Fiemap context passed into ->fiemap
      70                 :            :  * @logical:    Extent logical start offset, in bytes
      71                 :            :  * @phys:       Extent physical start offset, in bytes
      72                 :            :  * @len:        Extent length, in bytes
      73                 :            :  * @flags:      FIEMAP_EXTENT flags that describe this extent
      74                 :            :  *
      75                 :            :  * Called from file system ->fiemap callback. Will populate extent
      76                 :            :  * info as passed in via arguments and copy to user memory. On
      77                 :            :  * success, extent count on fieinfo is incremented.
      78                 :            :  *
      79                 :            :  * Returns 0 on success, -errno on error, 1 if this was the last
      80                 :            :  * extent that will fit in user array.
      81                 :            :  */
      82                 :            : #define SET_UNKNOWN_FLAGS       (FIEMAP_EXTENT_DELALLOC)
      83                 :            : #define SET_NO_UNMOUNTED_IO_FLAGS       (FIEMAP_EXTENT_DATA_ENCRYPTED)
      84                 :            : #define SET_NOT_ALIGNED_FLAGS   (FIEMAP_EXTENT_DATA_TAIL|FIEMAP_EXTENT_DATA_INLINE)
      85                 :          0 : int fiemap_fill_next_extent(struct fiemap_extent_info *fieinfo, u64 logical,
      86                 :            :                             u64 phys, u64 len, u32 flags)
      87                 :            : {
      88                 :            :         struct fiemap_extent extent;
      89                 :        413 :         struct fiemap_extent __user *dest = fieinfo->fi_extents_start;
      90                 :            : 
      91                 :            :         /* only count the extents */
      92         [ -  + ]:        413 :         if (fieinfo->fi_extents_max == 0) {
      93                 :          0 :                 fieinfo->fi_extents_mapped++;
      94                 :          0 :                 return (flags & FIEMAP_EXTENT_LAST) ? 1 : 0;
      95                 :            :         }
      96                 :            : 
      97         [ +  - ]:        413 :         if (fieinfo->fi_extents_mapped >= fieinfo->fi_extents_max)
      98                 :            :                 return 1;
      99                 :            : 
     100         [ -  + ]:        413 :         if (flags & SET_UNKNOWN_FLAGS)
     101                 :          0 :                 flags |= FIEMAP_EXTENT_UNKNOWN;
     102         [ -  + ]:        413 :         if (flags & SET_NO_UNMOUNTED_IO_FLAGS)
     103                 :          0 :                 flags |= FIEMAP_EXTENT_ENCODED;
     104         [ -  + ]:        413 :         if (flags & SET_NOT_ALIGNED_FLAGS)
     105                 :          0 :                 flags |= FIEMAP_EXTENT_NOT_ALIGNED;
     106                 :            : 
     107                 :        413 :         memset(&extent, 0, sizeof(extent));
     108                 :        413 :         extent.fe_logical = logical;
     109                 :        413 :         extent.fe_physical = phys;
     110                 :        413 :         extent.fe_length = len;
     111                 :        413 :         extent.fe_flags = flags;
     112                 :            : 
     113                 :        413 :         dest += fieinfo->fi_extents_mapped;
     114         [ +  - ]:        413 :         if (copy_to_user(dest, &extent, sizeof(extent)))
     115                 :            :                 return -EFAULT;
     116                 :            : 
     117                 :        413 :         fieinfo->fi_extents_mapped++;
     118         [ -  + ]:        413 :         if (fieinfo->fi_extents_mapped == fieinfo->fi_extents_max)
     119                 :            :                 return 1;
     120                 :          0 :         return (flags & FIEMAP_EXTENT_LAST) ? 1 : 0;
     121                 :            : }
     122                 :            : EXPORT_SYMBOL(fiemap_fill_next_extent);
     123                 :            : 
     124                 :            : /**
     125                 :            :  * fiemap_check_flags - check validity of requested flags for fiemap
     126                 :            :  * @fieinfo:    Fiemap context passed into ->fiemap
     127                 :            :  * @fs_flags:   Set of fiemap flags that the file system understands
     128                 :            :  *
     129                 :            :  * Called from file system ->fiemap callback. This will compute the
     130                 :            :  * intersection of valid fiemap flags and those that the fs supports. That
     131                 :            :  * value is then compared against the user supplied flags. In case of bad user
     132                 :            :  * flags, the invalid values will be written into the fieinfo structure, and
     133                 :            :  * -EBADR is returned, which tells ioctl_fiemap() to return those values to
     134                 :            :  * userspace. For this reason, a return code of -EBADR should be preserved.
     135                 :            :  *
     136                 :            :  * Returns 0 on success, -EBADR on bad flags.
     137                 :            :  */
     138                 :          0 : int fiemap_check_flags(struct fiemap_extent_info *fieinfo, u32 fs_flags)
     139                 :            : {
     140                 :            :         u32 incompat_flags;
     141                 :            : 
     142                 :        413 :         incompat_flags = fieinfo->fi_flags & ~(FIEMAP_FLAGS_COMPAT & fs_flags);
     143 [ #  # ][ -  + ]:        413 :         if (incompat_flags) {
     144                 :          0 :                 fieinfo->fi_flags = incompat_flags;
     145                 :          0 :                 return -EBADR;
     146                 :            :         }
     147                 :            :         return 0;
     148                 :            : }
     149                 :            : EXPORT_SYMBOL(fiemap_check_flags);
     150                 :            : 
     151                 :            : static int fiemap_check_ranges(struct super_block *sb,
     152                 :            :                                u64 start, u64 len, u64 *new_len)
     153                 :            : {
     154                 :        413 :         u64 maxbytes = (u64) sb->s_maxbytes;
     155                 :            : 
     156                 :            :         *new_len = len;
     157                 :            : 
     158         [ +  - ]:        413 :         if (len == 0)
     159                 :            :                 return -EINVAL;
     160                 :            : 
     161         [ +  - ]:        413 :         if (start > maxbytes)
     162                 :            :                 return -EFBIG;
     163                 :            : 
     164                 :            :         /*
     165                 :            :          * Shrink request scope to what the fs can actually handle.
     166                 :            :          */
     167 [ +  - ][ -  + ]:        413 :         if (len > maxbytes || (maxbytes - len) < start)
     168                 :          0 :                 *new_len = maxbytes - start;
     169                 :            : 
     170                 :            :         return 0;
     171                 :            : }
     172                 :            : 
     173                 :          0 : static int ioctl_fiemap(struct file *filp, unsigned long arg)
     174                 :            : {
     175                 :            :         struct fiemap fiemap;
     176                 :        413 :         struct fiemap __user *ufiemap = (struct fiemap __user *) arg;
     177                 :        413 :         struct fiemap_extent_info fieinfo = { 0, };
     178                 :            :         struct inode *inode = file_inode(filp);
     179                 :        826 :         struct super_block *sb = inode->i_sb;
     180                 :            :         u64 len;
     181                 :            :         int error;
     182                 :            : 
     183         [ +  - ]:        413 :         if (!inode->i_op->fiemap)
     184                 :            :                 return -EOPNOTSUPP;
     185                 :            : 
     186         [ +  - ]:        413 :         if (copy_from_user(&fiemap, ufiemap, sizeof(fiemap)))
     187                 :            :                 return -EFAULT;
     188                 :            : 
     189         [ +  - ]:        413 :         if (fiemap.fm_extent_count > FIEMAP_MAX_EXTENTS)
     190                 :            :                 return -EINVAL;
     191                 :            : 
     192                 :        413 :         error = fiemap_check_ranges(sb, fiemap.fm_start, fiemap.fm_length,
     193                 :            :                                     &len);
     194         [ +  - ]:        413 :         if (error)
     195                 :            :                 return error;
     196                 :            : 
     197                 :        413 :         fieinfo.fi_flags = fiemap.fm_flags;
     198                 :        413 :         fieinfo.fi_extents_max = fiemap.fm_extent_count;
     199                 :        413 :         fieinfo.fi_extents_start = ufiemap->fm_extents;
     200                 :            : 
     201 [ +  - ][ +  - ]:        413 :         if (fiemap.fm_extent_count != 0 &&
     202                 :        826 :             !access_ok(VERIFY_WRITE, fieinfo.fi_extents_start,
     203                 :            :                        fieinfo.fi_extents_max * sizeof(struct fiemap_extent)))
     204                 :            :                 return -EFAULT;
     205                 :            : 
     206         [ -  + ]:        413 :         if (fieinfo.fi_flags & FIEMAP_FLAG_SYNC)
     207                 :          0 :                 filemap_write_and_wait(inode->i_mapping);
     208                 :            : 
     209                 :        413 :         error = inode->i_op->fiemap(inode, &fieinfo, fiemap.fm_start, len);
     210                 :        413 :         fiemap.fm_flags = fieinfo.fi_flags;
     211                 :        413 :         fiemap.fm_mapped_extents = fieinfo.fi_extents_mapped;
     212         [ -  + ]:        413 :         if (copy_to_user(ufiemap, &fiemap, sizeof(fiemap)))
     213                 :            :                 error = -EFAULT;
     214                 :            : 
     215                 :        413 :         return error;
     216                 :            : }
     217                 :            : 
     218                 :            : #ifdef CONFIG_BLOCK
     219                 :            : 
     220                 :            : static inline sector_t logical_to_blk(struct inode *inode, loff_t offset)
     221                 :            : {
     222                 :          0 :         return (offset >> inode->i_blkbits);
     223                 :            : }
     224                 :            : 
     225                 :            : static inline loff_t blk_to_logical(struct inode *inode, sector_t blk)
     226                 :            : {
     227                 :          0 :         return (blk << inode->i_blkbits);
     228                 :            : }
     229                 :            : 
     230                 :            : /**
     231                 :            :  * __generic_block_fiemap - FIEMAP for block based inodes (no locking)
     232                 :            :  * @inode: the inode to map
     233                 :            :  * @fieinfo: the fiemap info struct that will be passed back to userspace
     234                 :            :  * @start: where to start mapping in the inode
     235                 :            :  * @len: how much space to map
     236                 :            :  * @get_block: the fs's get_block function
     237                 :            :  *
     238                 :            :  * This does FIEMAP for block based inodes.  Basically it will just loop
     239                 :            :  * through get_block until we hit the number of extents we want to map, or we
     240                 :            :  * go past the end of the file and hit a hole.
     241                 :            :  *
     242                 :            :  * If it is possible to have data blocks beyond a hole past @inode->i_size, then
     243                 :            :  * please do not use this function, it will stop at the first unmapped block
     244                 :            :  * beyond i_size.
     245                 :            :  *
     246                 :            :  * If you use this function directly, you need to do your own locking. Use
     247                 :            :  * generic_block_fiemap if you want the locking done for you.
     248                 :            :  */
     249                 :            : 
     250                 :          0 : int __generic_block_fiemap(struct inode *inode,
     251                 :            :                            struct fiemap_extent_info *fieinfo, loff_t start,
     252                 :            :                            loff_t len, get_block_t *get_block)
     253                 :            : {
     254                 :            :         struct buffer_head map_bh;
     255                 :            :         sector_t start_blk, last_blk;
     256                 :            :         loff_t isize = i_size_read(inode);
     257                 :            :         u64 logical = 0, phys = 0, size = 0;
     258                 :            :         u32 flags = FIEMAP_EXTENT_MERGED;
     259                 :            :         bool past_eof = false, whole_file = false;
     260                 :            :         int ret = 0;
     261                 :            : 
     262                 :            :         ret = fiemap_check_flags(fieinfo, FIEMAP_FLAG_SYNC);
     263         [ #  # ]:          0 :         if (ret)
     264                 :            :                 return ret;
     265                 :            : 
     266                 :            :         /*
     267                 :            :          * Either the i_mutex or other appropriate locking needs to be held
     268                 :            :          * since we expect isize to not change at all through the duration of
     269                 :            :          * this call.
     270                 :            :          */
     271         [ #  # ]:          0 :         if (len >= isize) {
     272                 :            :                 whole_file = true;
     273                 :            :                 len = isize;
     274                 :            :         }
     275                 :            : 
     276                 :            :         /*
     277                 :            :          * Some filesystems can't deal with being asked to map less than
     278                 :            :          * blocksize, so make sure our len is at least block length.
     279                 :            :          */
     280         [ #  # ]:          0 :         if (logical_to_blk(inode, len) == 0)
     281                 :            :                 len = blk_to_logical(inode, 1);
     282                 :            : 
     283                 :            :         start_blk = logical_to_blk(inode, start);
     284                 :          0 :         last_blk = logical_to_blk(inode, start + len - 1);
     285                 :            : 
     286                 :            :         do {
     287                 :            :                 /*
     288                 :            :                  * we set b_size to the total size we want so it will map as
     289                 :            :                  * many contiguous blocks as possible at once
     290                 :            :                  */
     291                 :          0 :                 memset(&map_bh, 0, sizeof(struct buffer_head));
     292                 :          0 :                 map_bh.b_size = len;
     293                 :            : 
     294                 :          0 :                 ret = get_block(inode, start_blk, &map_bh, 0);
     295         [ #  # ]:          0 :                 if (ret)
     296                 :            :                         break;
     297                 :            : 
     298                 :            :                 /* HOLE */
     299         [ #  # ]:          0 :                 if (!buffer_mapped(&map_bh)) {
     300                 :          0 :                         start_blk++;
     301                 :            : 
     302                 :            :                         /*
     303                 :            :                          * We want to handle the case where there is an
     304                 :            :                          * allocated block at the front of the file, and then
     305                 :            :                          * nothing but holes up to the end of the file properly,
     306                 :            :                          * to make sure that extent at the front gets properly
     307                 :            :                          * marked with FIEMAP_EXTENT_LAST
     308                 :            :                          */
     309 [ #  # ][ #  # ]:          0 :                         if (!past_eof &&
     310                 :            :                             blk_to_logical(inode, start_blk) >= isize)
     311                 :            :                                 past_eof = 1;
     312                 :            : 
     313                 :            :                         /*
     314                 :            :                          * First hole after going past the EOF, this is our
     315                 :            :                          * last extent
     316                 :            :                          */
     317         [ #  # ]:          0 :                         if (past_eof && size) {
     318                 :            :                                 flags = FIEMAP_EXTENT_MERGED|FIEMAP_EXTENT_LAST;
     319                 :          0 :                                 ret = fiemap_fill_next_extent(fieinfo, logical,
     320                 :            :                                                               phys, size,
     321                 :            :                                                               flags);
     322         [ #  # ]:          0 :                         } else if (size) {
     323                 :          0 :                                 ret = fiemap_fill_next_extent(fieinfo, logical,
     324                 :            :                                                               phys, size, flags);
     325                 :            :                                 size = 0;
     326                 :            :                         }
     327                 :            : 
     328                 :            :                         /* if we have holes up to/past EOF then we're done */
     329 [ #  # ][ #  # ]:          0 :                         if (start_blk > last_blk || past_eof || ret)
     330                 :            :                                 break;
     331                 :            :                 } else {
     332                 :            :                         /*
     333                 :            :                          * We have gone over the length of what we wanted to
     334                 :            :                          * map, and it wasn't the entire file, so add the extent
     335                 :            :                          * we got last time and exit.
     336                 :            :                          *
     337                 :            :                          * This is for the case where say we want to map all the
     338                 :            :                          * way up to the second to the last block in a file, but
     339                 :            :                          * the last block is a hole, making the second to last
     340                 :            :                          * block FIEMAP_EXTENT_LAST.  In this case we want to
     341                 :            :                          * see if there is a hole after the second to last block
     342                 :            :                          * so we can mark it properly.  If we found data after
     343                 :            :                          * we exceeded the length we were requesting, then we
     344                 :            :                          * are good to go, just add the extent to the fieinfo
     345                 :            :                          * and break
     346                 :            :                          */
     347         [ #  # ]:          0 :                         if (start_blk > last_blk && !whole_file) {
     348                 :          0 :                                 ret = fiemap_fill_next_extent(fieinfo, logical,
     349                 :            :                                                               phys, size,
     350                 :            :                                                               flags);
     351                 :          0 :                                 break;
     352                 :            :                         }
     353                 :            : 
     354                 :            :                         /*
     355                 :            :                          * if size != 0 then we know we already have an extent
     356                 :            :                          * to add, so add it.
     357                 :            :                          */
     358         [ #  # ]:          0 :                         if (size) {
     359                 :          0 :                                 ret = fiemap_fill_next_extent(fieinfo, logical,
     360                 :            :                                                               phys, size,
     361                 :            :                                                               flags);
     362         [ #  # ]:          0 :                                 if (ret)
     363                 :            :                                         break;
     364                 :            :                         }
     365                 :            : 
     366                 :            :                         logical = blk_to_logical(inode, start_blk);
     367                 :          0 :                         phys = blk_to_logical(inode, map_bh.b_blocknr);
     368                 :          0 :                         size = map_bh.b_size;
     369                 :            :                         flags = FIEMAP_EXTENT_MERGED;
     370                 :            : 
     371                 :          0 :                         start_blk += logical_to_blk(inode, size);
     372                 :            : 
     373                 :            :                         /*
     374                 :            :                          * If we are past the EOF, then we need to make sure as
     375                 :            :                          * soon as we find a hole that the last extent we found
     376                 :            :                          * is marked with FIEMAP_EXTENT_LAST
     377                 :            :                          */
     378 [ #  # ][ #  # ]:          0 :                         if (!past_eof && logical + size >= isize)
     379                 :            :                                 past_eof = true;
     380                 :            :                 }
     381                 :          0 :                 cond_resched();
     382                 :          0 :         } while (1);
     383                 :            : 
     384                 :            :         /* If ret is 1 then we just hit the end of the extent array */
     385         [ #  # ]:          0 :         if (ret == 1)
     386                 :            :                 ret = 0;
     387                 :            : 
     388                 :          0 :         return ret;
     389                 :            : }
     390                 :            : EXPORT_SYMBOL(__generic_block_fiemap);
     391                 :            : 
     392                 :            : /**
     393                 :            :  * generic_block_fiemap - FIEMAP for block based inodes
     394                 :            :  * @inode: The inode to map
     395                 :            :  * @fieinfo: The mapping information
     396                 :            :  * @start: The initial block to map
     397                 :            :  * @len: The length of the extect to attempt to map
     398                 :            :  * @get_block: The block mapping function for the fs
     399                 :            :  *
     400                 :            :  * Calls __generic_block_fiemap to map the inode, after taking
     401                 :            :  * the inode's mutex lock.
     402                 :            :  */
     403                 :            : 
     404                 :          0 : int generic_block_fiemap(struct inode *inode,
     405                 :            :                          struct fiemap_extent_info *fieinfo, u64 start,
     406                 :            :                          u64 len, get_block_t *get_block)
     407                 :            : {
     408                 :            :         int ret;
     409                 :          0 :         mutex_lock(&inode->i_mutex);
     410                 :          0 :         ret = __generic_block_fiemap(inode, fieinfo, start, len, get_block);
     411                 :          0 :         mutex_unlock(&inode->i_mutex);
     412                 :          0 :         return ret;
     413                 :            : }
     414                 :            : EXPORT_SYMBOL(generic_block_fiemap);
     415                 :            : 
     416                 :            : #endif  /*  CONFIG_BLOCK  */
     417                 :            : 
     418                 :            : /*
     419                 :            :  * This provides compatibility with legacy XFS pre-allocation ioctls
     420                 :            :  * which predate the fallocate syscall.
     421                 :            :  *
     422                 :            :  * Only the l_start, l_len and l_whence fields of the 'struct space_resv'
     423                 :            :  * are used here, rest are ignored.
     424                 :            :  */
     425                 :          0 : int ioctl_preallocate(struct file *filp, void __user *argp)
     426                 :            : {
     427                 :            :         struct inode *inode = file_inode(filp);
     428                 :            :         struct space_resv sr;
     429                 :            : 
     430         [ #  # ]:          0 :         if (copy_from_user(&sr, argp, sizeof(sr)))
     431                 :            :                 return -EFAULT;
     432                 :            : 
     433   [ #  #  #  # ]:          0 :         switch (sr.l_whence) {
     434                 :            :         case SEEK_SET:
     435                 :            :                 break;
     436                 :            :         case SEEK_CUR:
     437                 :          0 :                 sr.l_start += filp->f_pos;
     438                 :          0 :                 break;
     439                 :            :         case SEEK_END:
     440                 :          0 :                 sr.l_start += i_size_read(inode);
     441                 :          0 :                 break;
     442                 :            :         default:
     443                 :            :                 return -EINVAL;
     444                 :            :         }
     445                 :            : 
     446                 :          0 :         return do_fallocate(filp, FALLOC_FL_KEEP_SIZE, sr.l_start, sr.l_len);
     447                 :            : }
     448                 :            : 
     449                 :          0 : static int file_ioctl(struct file *filp, unsigned int cmd,
     450                 :            :                 unsigned long arg)
     451                 :            : {
     452                 :            :         struct inode *inode = file_inode(filp);
     453                 :      81832 :         int __user *p = (int __user *)arg;
     454                 :            : 
     455   [ -  -  -  + ]:      81832 :         switch (cmd) {
     456                 :            :         case FIBMAP:
     457                 :          0 :                 return ioctl_fibmap(filp, p);
     458                 :            :         case FIONREAD:
     459                 :          0 :                 return put_user(i_size_read(inode) - filp->f_pos, p);
     460                 :            :         case FS_IOC_RESVSP:
     461                 :            :         case FS_IOC_RESVSP64:
     462                 :          0 :                 return ioctl_preallocate(filp, p);
     463                 :            :         }
     464                 :            : 
     465                 :      81832 :         return vfs_ioctl(filp, cmd, arg);
     466                 :            : }
     467                 :            : 
     468                 :          0 : static int ioctl_fionbio(struct file *filp, int __user *argp)
     469                 :            : {
     470                 :            :         unsigned int flag;
     471                 :            :         int on, error;
     472                 :            : 
     473                 :          1 :         error = get_user(on, argp);
     474         [ +  - ]:          1 :         if (error)
     475                 :            :                 return error;
     476                 :            :         flag = O_NONBLOCK;
     477                 :            : #ifdef __sparc__
     478                 :            :         /* SunOS compatibility item. */
     479                 :            :         if (O_NONBLOCK != O_NDELAY)
     480                 :            :                 flag |= O_NDELAY;
     481                 :            : #endif
     482                 :            :         spin_lock(&filp->f_lock);
     483         [ +  - ]:          2 :         if (on)
     484                 :          1 :                 filp->f_flags |= flag;
     485                 :            :         else
     486                 :          0 :                 filp->f_flags &= ~flag;
     487                 :            :         spin_unlock(&filp->f_lock);
     488                 :          1 :         return error;
     489                 :            : }
     490                 :            : 
     491                 :          0 : static int ioctl_fioasync(unsigned int fd, struct file *filp,
     492                 :            :                           int __user *argp)
     493                 :            : {
     494                 :            :         unsigned int flag;
     495                 :            :         int on, error;
     496                 :            : 
     497                 :          0 :         error = get_user(on, argp);
     498         [ #  # ]:          0 :         if (error)
     499                 :            :                 return error;
     500         [ #  # ]:          0 :         flag = on ? FASYNC : 0;
     501                 :            : 
     502                 :            :         /* Did FASYNC state change ? */
     503         [ #  # ]:          0 :         if ((flag ^ filp->f_flags) & FASYNC) {
     504         [ #  # ]:          0 :                 if (filp->f_op->fasync)
     505                 :            :                         /* fasync() adjusts filp->f_flags */
     506                 :          0 :                         error = filp->f_op->fasync(fd, filp, on);
     507                 :            :                 else
     508                 :            :                         error = -ENOTTY;
     509                 :            :         }
     510                 :          0 :         return error < 0 ? error : 0;
     511                 :            : }
     512                 :            : 
     513                 :          0 : static int ioctl_fsfreeze(struct file *filp)
     514                 :            : {
     515                 :          0 :         struct super_block *sb = file_inode(filp)->i_sb;
     516                 :            : 
     517         [ #  # ]:          0 :         if (!capable(CAP_SYS_ADMIN))
     518                 :            :                 return -EPERM;
     519                 :            : 
     520                 :            :         /* If filesystem doesn't support freeze feature, return. */
     521         [ #  # ]:          0 :         if (sb->s_op->freeze_fs == NULL)
     522                 :            :                 return -EOPNOTSUPP;
     523                 :            : 
     524                 :            :         /* Freeze */
     525                 :          0 :         return freeze_super(sb);
     526                 :            : }
     527                 :            : 
     528                 :          0 : static int ioctl_fsthaw(struct file *filp)
     529                 :            : {
     530                 :          0 :         struct super_block *sb = file_inode(filp)->i_sb;
     531                 :            : 
     532         [ #  # ]:          0 :         if (!capable(CAP_SYS_ADMIN))
     533                 :            :                 return -EPERM;
     534                 :            : 
     535                 :            :         /* Thaw */
     536                 :          0 :         return thaw_super(sb);
     537                 :            : }
     538                 :            : 
     539                 :            : /*
     540                 :            :  * When you add any new common ioctls to the switches above and below
     541                 :            :  * please update compat_sys_ioctl() too.
     542                 :            :  *
     543                 :            :  * do_vfs_ioctl() is not for drivers and not intended to be EXPORT_SYMBOL()'d.
     544                 :            :  * It's just a simple helper for sys_ioctl and compat_sys_ioctl.
     545                 :            :  */
     546                 :          0 : int do_vfs_ioctl(struct file *filp, unsigned int fd, unsigned int cmd,
     547                 :            :              unsigned long arg)
     548                 :            : {
     549                 :            :         int error = 0;
     550                 :     105916 :         int __user *argp = (int __user *)arg;
     551                 :            :         struct inode *inode = file_inode(filp);
     552                 :            : 
     553   [ -  -  +  -  :     105916 :         switch (cmd) {
          -  -  -  +  -  
                      + ]
     554                 :            :         case FIOCLEX:
     555                 :          0 :                 set_close_on_exec(fd, 1);
     556                 :          0 :                 break;
     557                 :            : 
     558                 :            :         case FIONCLEX:
     559                 :          0 :                 set_close_on_exec(fd, 0);
     560                 :          0 :                 break;
     561                 :            : 
     562                 :            :         case FIONBIO:
     563                 :          1 :                 error = ioctl_fionbio(filp, argp);
     564                 :          1 :                 break;
     565                 :            : 
     566                 :            :         case FIOASYNC:
     567                 :          0 :                 error = ioctl_fioasync(fd, filp, argp);
     568                 :          0 :                 break;
     569                 :            : 
     570                 :            :         case FIOQSIZE:
     571 [ #  # ][ #  # ]:          0 :                 if (S_ISDIR(inode->i_mode) || S_ISREG(inode->i_mode) ||
     572                 :          0 :                     S_ISLNK(inode->i_mode)) {
     573                 :          0 :                         loff_t res = inode_get_bytes(inode);
     574                 :            :                         error = copy_to_user(argp, &res, sizeof(res)) ?
     575         [ #  # ]:          0 :                                         -EFAULT : 0;
     576                 :            :                 } else
     577                 :            :                         error = -ENOTTY;
     578                 :            :                 break;
     579                 :            : 
     580                 :            :         case FIFREEZE:
     581                 :          0 :                 error = ioctl_fsfreeze(filp);
     582                 :          0 :                 break;
     583                 :            : 
     584                 :            :         case FITHAW:
     585                 :          0 :                 error = ioctl_fsthaw(filp);
     586                 :          0 :                 break;
     587                 :            : 
     588                 :            :         case FS_IOC_FIEMAP:
     589                 :        413 :                 return ioctl_fiemap(filp, arg);
     590                 :            : 
     591                 :            :         case FIGETBSZ:
     592                 :          0 :                 return put_user(inode->i_sb->s_blocksize, argp);
     593                 :            : 
     594                 :            :         default:
     595         [ +  + ]:     105502 :                 if (S_ISREG(inode->i_mode))
     596                 :      81832 :                         error = file_ioctl(filp, cmd, arg);
     597                 :            :                 else
     598                 :            :                         error = vfs_ioctl(filp, cmd, arg);
     599                 :            :                 break;
     600                 :            :         }
     601                 :     105503 :         return error;
     602                 :            : }
     603                 :            : 
     604                 :          0 : SYSCALL_DEFINE3(ioctl, unsigned int, fd, unsigned int, cmd, unsigned long, arg)
     605                 :            : {
     606                 :            :         int error;
     607                 :            :         struct fd f = fdget(fd);
     608                 :            : 
     609         [ +  + ]:     105982 :         if (!f.file)
     610                 :            :                 return -EBADF;
     611                 :     105916 :         error = security_file_ioctl(f.file, cmd, arg);
     612         [ +  - ]:     105916 :         if (!error)
     613                 :     105916 :                 error = do_vfs_ioctl(f.file, fd, cmd, arg);
     614                 :            :         fdput(f);
     615                 :            :         return error;
     616                 :            : }

Generated by: LCOV version 1.9