LCOV - code coverage report
Current view: top level - fs/ext4 - file.c (source / functions) Hit Total Coverage
Test: coverage.info Lines: 75 205 36.6 %
Date: 2014-02-18 Functions: 7 10 70.0 %
Branches: 39 168 23.2 %

           Branch data     Line data    Source code
       1                 :            : /*
       2                 :            :  *  linux/fs/ext4/file.c
       3                 :            :  *
       4                 :            :  * Copyright (C) 1992, 1993, 1994, 1995
       5                 :            :  * Remy Card (card@masi.ibp.fr)
       6                 :            :  * Laboratoire MASI - Institut Blaise Pascal
       7                 :            :  * Universite Pierre et Marie Curie (Paris VI)
       8                 :            :  *
       9                 :            :  *  from
      10                 :            :  *
      11                 :            :  *  linux/fs/minix/file.c
      12                 :            :  *
      13                 :            :  *  Copyright (C) 1991, 1992  Linus Torvalds
      14                 :            :  *
      15                 :            :  *  ext4 fs regular file handling primitives
      16                 :            :  *
      17                 :            :  *  64-bit file support on 64-bit platforms by Jakub Jelinek
      18                 :            :  *      (jj@sunsite.ms.mff.cuni.cz)
      19                 :            :  */
      20                 :            : 
      21                 :            : #include <linux/time.h>
      22                 :            : #include <linux/fs.h>
      23                 :            : #include <linux/jbd2.h>
      24                 :            : #include <linux/mount.h>
      25                 :            : #include <linux/path.h>
      26                 :            : #include <linux/aio.h>
      27                 :            : #include <linux/quotaops.h>
      28                 :            : #include <linux/pagevec.h>
      29                 :            : #include "ext4.h"
      30                 :            : #include "ext4_jbd2.h"
      31                 :            : #include "xattr.h"
      32                 :            : #include "acl.h"
      33                 :            : 
      34                 :            : /*
      35                 :            :  * Called when an inode is released. Note that this is different
      36                 :            :  * from ext4_file_open: open gets called at every open, but release
      37                 :            :  * gets called only when /all/ the files are closed.
      38                 :            :  */
      39                 :          0 : static int ext4_release_file(struct inode *inode, struct file *filp)
      40                 :            : {
      41         [ +  + ]:    2896819 :         if (ext4_test_inode_state(inode, EXT4_STATE_DA_ALLOC_CLOSE)) {
      42                 :       7217 :                 ext4_alloc_da_blocks(inode);
      43                 :            :                 ext4_clear_inode_state(inode, EXT4_STATE_DA_ALLOC_CLOSE);
      44                 :            :         }
      45                 :            :         /* if we are the last writer on the inode, drop the block reservation */
      46 [ +  + ][ +  + ]:    2896748 :         if ((filp->f_mode & FMODE_WRITE) &&
      47         [ +  + ]:    1534303 :                         (atomic_read(&inode->i_writecount) == 1) &&
      48                 :    1534303 :                         !EXT4_I(inode)->i_reserved_data_blocks)
      49                 :            :         {
      50                 :     331978 :                 down_write(&EXT4_I(inode)->i_data_sem);
      51                 :     331978 :                 ext4_discard_preallocations(inode);
      52                 :     331978 :                 up_write(&EXT4_I(inode)->i_data_sem);
      53                 :            :         }
      54 [ +  - ][ -  + ]:    2896748 :         if (is_dx(inode) && filp->private_data)
                 [ #  # ]
      55                 :          0 :                 ext4_htree_free_dir_info(filp->private_data);
      56                 :            : 
      57                 :    2896748 :         return 0;
      58                 :            : }
      59                 :            : 
      60                 :          0 : void ext4_unwritten_wait(struct inode *inode)
      61                 :            : {
      62                 :          0 :         wait_queue_head_t *wq = ext4_ioend_wq(inode);
      63                 :            : 
      64 [ #  # ][ #  # ]:          0 :         wait_event(*wq, (atomic_read(&EXT4_I(inode)->i_unwritten) == 0));
      65                 :          0 : }
      66                 :            : 
      67                 :            : /*
      68                 :            :  * This tests whether the IO in question is block-aligned or not.
      69                 :            :  * Ext4 utilizes unwritten extents when hole-filling during direct IO, and they
      70                 :            :  * are converted to written only after the IO is complete.  Until they are
      71                 :            :  * mapped, these blocks appear as holes, so dio_zero_block() will assume that
      72                 :            :  * it needs to zero out portions of the start and/or end block.  If 2 AIO
      73                 :            :  * threads are at work on the same unwritten block, they must be synchronized
      74                 :            :  * or one thread will zero the other's data, causing corruption.
      75                 :            :  */
      76                 :            : static int
      77                 :            : ext4_unaligned_aio(struct inode *inode, const struct iovec *iov,
      78                 :            :                    unsigned long nr_segs, loff_t pos)
      79                 :            : {
      80                 :            :         struct super_block *sb = inode->i_sb;
      81                 :          0 :         int blockmask = sb->s_blocksize - 1;
      82                 :            :         size_t count = iov_length(iov, nr_segs);
      83                 :          0 :         loff_t final_size = pos + count;
      84                 :            : 
      85         [ #  # ]:          0 :         if (pos >= inode->i_size)
      86                 :            :                 return 0;
      87                 :            : 
      88 [ #  # ][ #  # ]:          0 :         if ((pos & blockmask) || (final_size & blockmask))
      89                 :            :                 return 1;
      90                 :            : 
      91                 :            :         return 0;
      92                 :            : }
      93                 :            : 
      94                 :            : static ssize_t
      95                 :          0 : ext4_file_dio_write(struct kiocb *iocb, const struct iovec *iov,
      96                 :            :                     unsigned long nr_segs, loff_t pos)
      97                 :            : {
      98                 :      99111 :         struct file *file = iocb->ki_filp;
      99                 :      99111 :         struct inode *inode = file->f_mapping->host;
     100                 :            :         struct blk_plug plug;
     101                 :            :         int unaligned_aio = 0;
     102                 :            :         ssize_t ret;
     103                 :      99111 :         int overwrite = 0;
     104                 :            :         size_t length = iov_length(iov, nr_segs);
     105                 :            : 
     106 [ +  - ][ -  + ]:      99111 :         if (ext4_test_inode_flag(inode, EXT4_INODE_EXTENTS) &&
     107                 :            :             !is_sync_kiocb(iocb))
     108                 :            :                 unaligned_aio = ext4_unaligned_aio(inode, iov, nr_segs, pos);
     109                 :            : 
     110                 :            :         /* Unaligned direct AIO must be serialized; see comment above */
     111         [ #  # ]:      99111 :         if (unaligned_aio) {
     112                 :          0 :                 mutex_lock(ext4_aio_mutex(inode));
     113                 :          0 :                 ext4_unwritten_wait(inode);
     114                 :            :         }
     115                 :            : 
     116         [ -  + ]:      99111 :         BUG_ON(iocb->ki_pos != pos);
     117                 :            : 
     118                 :      99111 :         mutex_lock(&inode->i_mutex);
     119                 :      99111 :         blk_start_plug(&plug);
     120                 :            : 
     121                 :      99111 :         iocb->private = &overwrite;
     122                 :            : 
     123                 :            :         /* check whether we do a DIO overwrite or not */
     124 [ -  + ][ #  # ]:      99111 :         if (ext4_should_dioread_nolock(inode) && !unaligned_aio &&
                 [ #  # ]
     125         [ #  # ]:          0 :             !file->f_mapping->nrpages && pos + length <= i_size_read(inode)) {
     126                 :            :                 struct ext4_map_blocks map;
     127                 :          0 :                 unsigned int blkbits = inode->i_blkbits;
     128                 :            :                 int err, len;
     129                 :            : 
     130                 :          0 :                 map.m_lblk = pos >> blkbits;
     131                 :          0 :                 map.m_len = (EXT4_BLOCK_ALIGN(pos + length, blkbits) >> blkbits)
     132                 :            :                         - map.m_lblk;
     133                 :          0 :                 len = map.m_len;
     134                 :            : 
     135                 :          0 :                 err = ext4_map_blocks(NULL, inode, &map, 0);
     136                 :            :                 /*
     137                 :            :                  * 'err==len' means that all of blocks has been preallocated no
     138                 :            :                  * matter they are initialized or not.  For excluding
     139                 :            :                  * uninitialized extents, we need to check m_flags.  There are
     140                 :            :                  * two conditions that indicate for initialized extents.
     141                 :            :                  * 1) If we hit extent cache, EXT4_MAP_MAPPED flag is returned;
     142                 :            :                  * 2) If we do a real lookup, non-flags are returned.
     143                 :            :                  * So we should check these two conditions.
     144                 :            :                  */
     145 [ #  # ][ #  # ]:          0 :                 if (err == len && (map.m_flags & EXT4_MAP_MAPPED))
     146                 :          0 :                         overwrite = 1;
     147                 :            :         }
     148                 :            : 
     149                 :      99111 :         ret = __generic_file_aio_write(iocb, iov, nr_segs, &iocb->ki_pos);
     150                 :      99111 :         mutex_unlock(&inode->i_mutex);
     151                 :            : 
     152         [ +  + ]:      99111 :         if (ret > 0) {
     153                 :            :                 ssize_t err;
     154                 :            : 
     155                 :      99105 :                 err = generic_write_sync(file, pos, ret);
     156         [ -  + ]:      99105 :                 if (err < 0 && ret > 0)
     157                 :            :                         ret = err;
     158                 :            :         }
     159                 :      99111 :         blk_finish_plug(&plug);
     160                 :            : 
     161         [ -  + ]:      99111 :         if (unaligned_aio)
     162                 :          0 :                 mutex_unlock(ext4_aio_mutex(inode));
     163                 :            : 
     164                 :      99111 :         return ret;
     165                 :            : }
     166                 :            : 
     167                 :            : static ssize_t
     168                 :          0 : ext4_file_write(struct kiocb *iocb, const struct iovec *iov,
     169                 :            :                 unsigned long nr_segs, loff_t pos)
     170                 :            : {
     171                 :    3566385 :         struct inode *inode = file_inode(iocb->ki_filp);
     172                 :            :         ssize_t ret;
     173                 :            : 
     174                 :            :         /*
     175                 :            :          * If we have encountered a bitmap-format file, the size limit
     176                 :            :          * is smaller than s_maxbytes, which is for extent-mapped files.
     177                 :            :          */
     178                 :            : 
     179         [ -  + ]:    3566385 :         if (!(ext4_test_inode_flag(inode, EXT4_INODE_EXTENTS))) {
     180                 :          0 :                 struct ext4_sb_info *sbi = EXT4_SB(inode->i_sb);
     181                 :            :                 size_t length = iov_length(iov, nr_segs);
     182                 :            : 
     183 [ #  # ][ #  # ]:          0 :                 if ((pos > sbi->s_bitmap_maxbytes ||
     184         [ #  # ]:          0 :                     (pos == sbi->s_bitmap_maxbytes && length > 0)))
     185                 :            :                         return -EFBIG;
     186                 :            : 
     187         [ -  + ]:    3566393 :                 if (pos + length > sbi->s_bitmap_maxbytes) {
     188                 :          0 :                         nr_segs = iov_shorten((struct iovec *)iov, nr_segs,
     189                 :            :                                               sbi->s_bitmap_maxbytes - pos);
     190                 :            :                 }
     191                 :            :         }
     192                 :            : 
     193         [ +  + ]:    3566393 :         if (unlikely(iocb->ki_filp->f_flags & O_DIRECT))
     194                 :      99111 :                 ret = ext4_file_dio_write(iocb, iov, nr_segs, pos);
     195                 :            :         else
     196                 :    3467282 :                 ret = generic_file_aio_write(iocb, iov, nr_segs, pos);
     197                 :            : 
     198                 :    3566406 :         return ret;
     199                 :            : }
     200                 :            : 
     201                 :            : static const struct vm_operations_struct ext4_file_vm_ops = {
     202                 :            :         .fault          = filemap_fault,
     203                 :            :         .page_mkwrite   = ext4_page_mkwrite,
     204                 :            :         .remap_pages    = generic_file_remap_pages,
     205                 :            : };
     206                 :            : 
     207                 :          0 : static int ext4_file_mmap(struct file *file, struct vm_area_struct *vma)
     208                 :            : {
     209                 :    1379025 :         struct address_space *mapping = file->f_mapping;
     210                 :            : 
     211         [ +  + ]:    1379025 :         if (!mapping->a_ops->readpage)
     212                 :            :                 return -ENOEXEC;
     213                 :            :         file_accessed(file);
     214                 :    1379012 :         vma->vm_ops = &ext4_file_vm_ops;
     215                 :    1379012 :         return 0;
     216                 :            : }
     217                 :            : 
     218                 :          0 : static int ext4_file_open(struct inode * inode, struct file * filp)
     219                 :            : {
     220                 :    2896795 :         struct super_block *sb = inode->i_sb;
     221                 :    2896795 :         struct ext4_sb_info *sbi = EXT4_SB(inode->i_sb);
     222                 :    2896795 :         struct vfsmount *mnt = filp->f_path.mnt;
     223                 :            :         struct path path;
     224                 :            :         char buf[64], *cp;
     225                 :            : 
     226 [ -  + ][ #  # ]:    2896795 :         if (unlikely(!(sbi->s_mount_flags & EXT4_MF_MNTDIR_SAMPLED) &&
     227                 :            :                      !(sb->s_flags & MS_RDONLY))) {
     228                 :          0 :                 sbi->s_mount_flags |= EXT4_MF_MNTDIR_SAMPLED;
     229                 :            :                 /*
     230                 :            :                  * Sample where the filesystem has been mounted and
     231                 :            :                  * store it in the superblock for sysadmin convenience
     232                 :            :                  * when trying to sort through large numbers of block
     233                 :            :                  * devices or filesystem images.
     234                 :            :                  */
     235                 :          0 :                 memset(buf, 0, sizeof(buf));
     236                 :          0 :                 path.mnt = mnt;
     237                 :          0 :                 path.dentry = mnt->mnt_root;
     238                 :          0 :                 cp = d_path(&path, buf, sizeof(buf));
     239         [ #  # ]:          0 :                 if (!IS_ERR(cp)) {
     240                 :            :                         handle_t *handle;
     241                 :            :                         int err;
     242                 :            : 
     243                 :          0 :                         handle = ext4_journal_start_sb(sb, EXT4_HT_MISC, 1);
     244         [ #  # ]:          0 :                         if (IS_ERR(handle))
     245                 :          0 :                                 return PTR_ERR(handle);
     246                 :          0 :                         err = ext4_journal_get_write_access(handle, sbi->s_sbh);
     247         [ #  # ]:          0 :                         if (err) {
     248                 :          0 :                                 ext4_journal_stop(handle);
     249                 :          0 :                                 return err;
     250                 :            :                         }
     251                 :          0 :                         strlcpy(sbi->s_es->s_last_mounted, cp,
     252                 :            :                                 sizeof(sbi->s_es->s_last_mounted));
     253                 :          0 :                         ext4_handle_dirty_super(handle, sb);
     254                 :          0 :                         ext4_journal_stop(handle);
     255                 :            :                 }
     256                 :            :         }
     257                 :            :         /*
     258                 :            :          * Set up the jbd2_inode if we are opening the inode for
     259                 :            :          * writing and the journal is present
     260                 :            :          */
     261         [ +  + ]:    2896809 :         if (filp->f_mode & FMODE_WRITE) {
     262                 :    1561378 :                 int ret = ext4_inode_attach_jinode(inode);
     263            [ + ]:    1561365 :                 if (ret < 0)
     264                 :            :                         return ret;
     265                 :            :         }
     266                 :    2896808 :         return dquot_file_open(inode, filp);
     267                 :            : }
     268                 :            : 
     269                 :            : /*
     270                 :            :  * Here we use ext4_map_blocks() to get a block mapping for a extent-based
     271                 :            :  * file rather than ext4_ext_walk_space() because we can introduce
     272                 :            :  * SEEK_DATA/SEEK_HOLE for block-mapped and extent-mapped file at the same
     273                 :            :  * function.  When extent status tree has been fully implemented, it will
     274                 :            :  * track all extent status for a file and we can directly use it to
     275                 :            :  * retrieve the offset for SEEK_DATA/SEEK_HOLE.
     276                 :            :  */
     277                 :            : 
     278                 :            : /*
     279                 :            :  * When we retrieve the offset for SEEK_DATA/SEEK_HOLE, we would need to
     280                 :            :  * lookup page cache to check whether or not there has some data between
     281                 :            :  * [startoff, endoff] because, if this range contains an unwritten extent,
     282                 :            :  * we determine this extent as a data or a hole according to whether the
     283                 :            :  * page cache has data or not.
     284                 :            :  */
     285                 :          0 : static int ext4_find_unwritten_pgoff(struct inode *inode,
     286                 :            :                                      int whence,
     287                 :            :                                      struct ext4_map_blocks *map,
     288                 :            :                                      loff_t *offset)
     289                 :            : {
     290                 :            :         struct pagevec pvec;
     291                 :            :         unsigned int blkbits;
     292                 :            :         pgoff_t index;
     293                 :            :         pgoff_t end;
     294                 :            :         loff_t endoff;
     295                 :            :         loff_t startoff;
     296                 :            :         loff_t lastoff;
     297                 :            :         int found = 0;
     298                 :            : 
     299                 :          0 :         blkbits = inode->i_sb->s_blocksize_bits;
     300                 :          0 :         startoff = *offset;
     301                 :            :         lastoff = startoff;
     302                 :          0 :         endoff = (loff_t)(map->m_lblk + map->m_len) << blkbits;
     303                 :            : 
     304                 :          0 :         index = startoff >> PAGE_CACHE_SHIFT;
     305                 :          0 :         end = endoff >> PAGE_CACHE_SHIFT;
     306                 :            : 
     307                 :            :         pagevec_init(&pvec, 0);
     308                 :            :         do {
     309                 :            :                 int i, num;
     310                 :            :                 unsigned long nr_pages;
     311                 :            : 
     312                 :          0 :                 num = min_t(pgoff_t, end - index, PAGEVEC_SIZE);
     313                 :          0 :                 nr_pages = pagevec_lookup(&pvec, inode->i_mapping, index,
     314                 :            :                                           (pgoff_t)num);
     315         [ #  # ]:          0 :                 if (nr_pages == 0) {
     316         [ #  # ]:          0 :                         if (whence == SEEK_DATA)
     317                 :            :                                 break;
     318                 :            : 
     319         [ #  # ]:          0 :                         BUG_ON(whence != SEEK_HOLE);
     320                 :            :                         /*
     321                 :            :                          * If this is the first time to go into the loop and
     322                 :            :                          * offset is not beyond the end offset, it will be a
     323                 :            :                          * hole at this offset
     324                 :            :                          */
     325         [ #  # ]:          0 :                         if (lastoff == startoff || lastoff < endoff)
     326                 :            :                                 found = 1;
     327                 :            :                         break;
     328                 :            :                 }
     329                 :            : 
     330                 :            :                 /*
     331                 :            :                  * If this is the first time to go into the loop and
     332                 :            :                  * offset is smaller than the first page offset, it will be a
     333                 :            :                  * hole at this offset.
     334                 :            :                  */
     335 [ #  # ][ #  # ]:          0 :                 if (lastoff == startoff && whence == SEEK_HOLE &&
     336                 :          0 :                     lastoff < page_offset(pvec.pages[0])) {
     337                 :            :                         found = 1;
     338                 :            :                         break;
     339                 :            :                 }
     340                 :            : 
     341         [ #  # ]:          0 :                 for (i = 0; i < nr_pages; i++) {
     342                 :          0 :                         struct page *page = pvec.pages[i];
     343                 :            :                         struct buffer_head *bh, *head;
     344                 :            : 
     345                 :            :                         /*
     346                 :            :                          * If the current offset is not beyond the end of given
     347                 :            :                          * range, it will be a hole.
     348                 :            :                          */
     349 [ #  # ][ #  # ]:          0 :                         if (lastoff < endoff && whence == SEEK_HOLE &&
     350                 :          0 :                             page->index > end) {
     351                 :            :                                 found = 1;
     352                 :          0 :                                 *offset = lastoff;
     353                 :            :                                 goto out;
     354                 :            :                         }
     355                 :            : 
     356                 :            :                         lock_page(page);
     357                 :            : 
     358         [ #  # ]:          0 :                         if (unlikely(page->mapping != inode->i_mapping)) {
     359                 :          0 :                                 unlock_page(page);
     360                 :          0 :                                 continue;
     361                 :            :                         }
     362                 :            : 
     363         [ #  # ]:          0 :                         if (!page_has_buffers(page)) {
     364                 :          0 :                                 unlock_page(page);
     365                 :          0 :                                 continue;
     366                 :            :                         }
     367                 :            : 
     368         [ #  # ]:          0 :                         if (page_has_buffers(page)) {
     369                 :            :                                 lastoff = page_offset(page);
     370         [ #  # ]:          0 :                                 bh = head = page_buffers(page);
     371                 :            :                                 do {
     372 [ #  # ][ #  # ]:          0 :                                         if (buffer_uptodate(bh) ||
     373                 :            :                                             buffer_unwritten(bh)) {
     374         [ #  # ]:          0 :                                                 if (whence == SEEK_DATA)
     375                 :            :                                                         found = 1;
     376                 :            :                                         } else {
     377         [ #  # ]:          0 :                                                 if (whence == SEEK_HOLE)
     378                 :            :                                                         found = 1;
     379                 :            :                                         }
     380         [ #  # ]:          0 :                                         if (found) {
     381                 :          0 :                                                 *offset = max_t(loff_t,
     382                 :            :                                                         startoff, lastoff);
     383                 :          0 :                                                 unlock_page(page);
     384                 :            :                                                 goto out;
     385                 :            :                                         }
     386                 :          0 :                                         lastoff += bh->b_size;
     387                 :          0 :                                         bh = bh->b_this_page;
     388         [ #  # ]:          0 :                                 } while (bh != head);
     389                 :            :                         }
     390                 :            : 
     391                 :          0 :                         lastoff = page_offset(page) + PAGE_SIZE;
     392                 :          0 :                         unlock_page(page);
     393                 :            :                 }
     394                 :            : 
     395                 :            :                 /*
     396                 :            :                  * The no. of pages is less than our desired, that would be a
     397                 :            :                  * hole in there.
     398                 :            :                  */
     399         [ #  # ]:          0 :                 if (nr_pages < num && whence == SEEK_HOLE) {
     400                 :            :                         found = 1;
     401                 :          0 :                         *offset = lastoff;
     402                 :            :                         break;
     403                 :            :                 }
     404                 :            : 
     405                 :          0 :                 index = pvec.pages[i - 1]->index + 1;
     406                 :            :                 pagevec_release(&pvec);
     407         [ #  # ]:          0 :         } while (index <= end);
     408                 :            : 
     409                 :            : out:
     410                 :            :         pagevec_release(&pvec);
     411                 :          0 :         return found;
     412                 :            : }
     413                 :            : 
     414                 :            : /*
     415                 :            :  * ext4_seek_data() retrieves the offset for SEEK_DATA.
     416                 :            :  */
     417                 :          0 : static loff_t ext4_seek_data(struct file *file, loff_t offset, loff_t maxsize)
     418                 :            : {
     419                 :          0 :         struct inode *inode = file->f_mapping->host;
     420                 :            :         struct ext4_map_blocks map;
     421                 :            :         struct extent_status es;
     422                 :            :         ext4_lblk_t start, last, end;
     423                 :            :         loff_t dataoff, isize;
     424                 :            :         int blkbits;
     425                 :            :         int ret = 0;
     426                 :            : 
     427                 :          0 :         mutex_lock(&inode->i_mutex);
     428                 :            : 
     429                 :            :         isize = i_size_read(inode);
     430         [ #  # ]:          0 :         if (offset >= isize) {
     431                 :          0 :                 mutex_unlock(&inode->i_mutex);
     432                 :          0 :                 return -ENXIO;
     433                 :            :         }
     434                 :            : 
     435                 :          0 :         blkbits = inode->i_sb->s_blocksize_bits;
     436                 :          0 :         start = offset >> blkbits;
     437                 :            :         last = start;
     438                 :          0 :         end = isize >> blkbits;
     439                 :          0 :         dataoff = offset;
     440                 :            : 
     441                 :            :         do {
     442                 :          0 :                 map.m_lblk = last;
     443                 :          0 :                 map.m_len = end - last + 1;
     444                 :          0 :                 ret = ext4_map_blocks(NULL, inode, &map, 0);
     445 [ #  # ][ #  # ]:          0 :                 if (ret > 0 && !(map.m_flags & EXT4_MAP_UNWRITTEN)) {
     446         [ #  # ]:          0 :                         if (last != start)
     447                 :          0 :                                 dataoff = (loff_t)last << blkbits;
     448                 :            :                         break;
     449                 :            :                 }
     450                 :            : 
     451                 :            :                 /*
     452                 :            :                  * If there is a delay extent at this offset,
     453                 :            :                  * it will be as a data.
     454                 :            :                  */
     455                 :          0 :                 ext4_es_find_delayed_extent_range(inode, last, last, &es);
     456 [ #  # ][ #  # ]:          0 :                 if (es.es_len != 0 && in_range(last, es.es_lblk, es.es_len)) {
                 [ #  # ]
     457         [ #  # ]:          0 :                         if (last != start)
     458                 :          0 :                                 dataoff = (loff_t)last << blkbits;
     459                 :            :                         break;
     460                 :            :                 }
     461                 :            : 
     462                 :            :                 /*
     463                 :            :                  * If there is a unwritten extent at this offset,
     464                 :            :                  * it will be as a data or a hole according to page
     465                 :            :                  * cache that has data or not.
     466                 :            :                  */
     467         [ #  # ]:          0 :                 if (map.m_flags & EXT4_MAP_UNWRITTEN) {
     468                 :            :                         int unwritten;
     469                 :          0 :                         unwritten = ext4_find_unwritten_pgoff(inode, SEEK_DATA,
     470                 :            :                                                               &map, &dataoff);
     471         [ #  # ]:          0 :                         if (unwritten)
     472                 :            :                                 break;
     473                 :            :                 }
     474                 :            : 
     475                 :          0 :                 last++;
     476                 :          0 :                 dataoff = (loff_t)last << blkbits;
     477         [ #  # ]:          0 :         } while (last <= end);
     478                 :            : 
     479                 :          0 :         mutex_unlock(&inode->i_mutex);
     480                 :            : 
     481         [ #  # ]:          0 :         if (dataoff > isize)
     482                 :            :                 return -ENXIO;
     483                 :            : 
     484                 :          0 :         return vfs_setpos(file, dataoff, maxsize);
     485                 :            : }
     486                 :            : 
     487                 :            : /*
     488                 :            :  * ext4_seek_hole() retrieves the offset for SEEK_HOLE.
     489                 :            :  */
     490                 :          0 : static loff_t ext4_seek_hole(struct file *file, loff_t offset, loff_t maxsize)
     491                 :            : {
     492                 :        126 :         struct inode *inode = file->f_mapping->host;
     493                 :            :         struct ext4_map_blocks map;
     494                 :            :         struct extent_status es;
     495                 :            :         ext4_lblk_t start, last, end;
     496                 :            :         loff_t holeoff, isize;
     497                 :            :         int blkbits;
     498                 :            :         int ret = 0;
     499                 :            : 
     500                 :        126 :         mutex_lock(&inode->i_mutex);
     501                 :            : 
     502                 :            :         isize = i_size_read(inode);
     503         [ +  + ]:        126 :         if (offset >= isize) {
     504                 :        122 :                 mutex_unlock(&inode->i_mutex);
     505                 :        122 :                 return -ENXIO;
     506                 :            :         }
     507                 :            : 
     508                 :          4 :         blkbits = inode->i_sb->s_blocksize_bits;
     509                 :          4 :         start = offset >> blkbits;
     510                 :            :         last = start;
     511                 :          4 :         end = isize >> blkbits;
     512                 :          4 :         holeoff = offset;
     513                 :            : 
     514                 :            :         do {
     515                 :          4 :                 map.m_lblk = last;
     516                 :          4 :                 map.m_len = end - last + 1;
     517                 :          4 :                 ret = ext4_map_blocks(NULL, inode, &map, 0);
     518 [ -  + ][ #  # ]:          4 :                 if (ret > 0 && !(map.m_flags & EXT4_MAP_UNWRITTEN)) {
     519                 :          0 :                         last += ret;
     520                 :          0 :                         holeoff = (loff_t)last << blkbits;
     521                 :          0 :                         continue;
     522                 :            :                 }
     523                 :            : 
     524                 :            :                 /*
     525                 :            :                  * If there is a delay extent at this offset,
     526                 :            :                  * we will skip this extent.
     527                 :            :                  */
     528                 :          4 :                 ext4_es_find_delayed_extent_range(inode, last, last, &es);
     529 [ +  - ][ +  - ]:          4 :                 if (es.es_len != 0 && in_range(last, es.es_lblk, es.es_len)) {
                 [ +  - ]
     530                 :            :                         last = es.es_lblk + es.es_len;
     531                 :          4 :                         holeoff = (loff_t)last << blkbits;
     532                 :          4 :                         continue;
     533                 :            :                 }
     534                 :            : 
     535                 :            :                 /*
     536                 :            :                  * If there is a unwritten extent at this offset,
     537                 :            :                  * it will be as a data or a hole according to page
     538                 :            :                  * cache that has data or not.
     539                 :            :                  */
     540         [ #  # ]:          0 :                 if (map.m_flags & EXT4_MAP_UNWRITTEN) {
     541                 :            :                         int unwritten;
     542                 :          0 :                         unwritten = ext4_find_unwritten_pgoff(inode, SEEK_HOLE,
     543                 :            :                                                               &map, &holeoff);
     544         [ #  # ]:          0 :                         if (!unwritten) {
     545                 :          0 :                                 last += ret;
     546                 :          0 :                                 holeoff = (loff_t)last << blkbits;
     547                 :          0 :                                 continue;
     548                 :            :                         }
     549                 :            :                 }
     550                 :            : 
     551                 :            :                 /* find a hole */
     552                 :            :                 break;
     553         [ -  + ]:          4 :         } while (last <= end);
     554                 :            : 
     555                 :          4 :         mutex_unlock(&inode->i_mutex);
     556                 :            : 
     557         [ +  - ]:          4 :         if (holeoff > isize)
     558                 :          4 :                 holeoff = isize;
     559                 :            : 
     560                 :          4 :         return vfs_setpos(file, holeoff, maxsize);
     561                 :            : }
     562                 :            : 
     563                 :            : /*
     564                 :            :  * ext4_llseek() handles both block-mapped and extent-mapped maxbytes values
     565                 :            :  * by calling generic_file_llseek_size() with the appropriate maxbytes
     566                 :            :  * value for each.
     567                 :            :  */
     568                 :          0 : loff_t ext4_llseek(struct file *file, loff_t offset, int whence)
     569                 :            : {
     570                 :    8845068 :         struct inode *inode = file->f_mapping->host;
     571                 :            :         loff_t maxbytes;
     572                 :            : 
     573         [ -  + ]:    8845068 :         if (!(ext4_test_inode_flag(inode, EXT4_INODE_EXTENTS)))
     574                 :          0 :                 maxbytes = EXT4_SB(inode->i_sb)->s_bitmap_maxbytes;
     575                 :            :         else
     576                 :    8845068 :                 maxbytes = inode->i_sb->s_maxbytes;
     577                 :            : 
     578      [ +  -  + ]:    8845068 :         switch (whence) {
     579                 :            :         case SEEK_SET:
     580                 :            :         case SEEK_CUR:
     581                 :            :         case SEEK_END:
     582                 :    8845163 :                 return generic_file_llseek_size(file, offset, whence,
     583                 :            :                                                 maxbytes, i_size_read(inode));
     584                 :            :         case SEEK_DATA:
     585                 :          0 :                 return ext4_seek_data(file, offset, maxbytes);
     586                 :            :         case SEEK_HOLE:
     587                 :        126 :                 return ext4_seek_hole(file, offset, maxbytes);
     588                 :            :         }
     589                 :            : 
     590                 :            :         return -EINVAL;
     591                 :            : }
     592                 :            : 
     593                 :            : const struct file_operations ext4_file_operations = {
     594                 :            :         .llseek         = ext4_llseek,
     595                 :            :         .read           = do_sync_read,
     596                 :            :         .write          = do_sync_write,
     597                 :            :         .aio_read       = generic_file_aio_read,
     598                 :            :         .aio_write      = ext4_file_write,
     599                 :            :         .unlocked_ioctl = ext4_ioctl,
     600                 :            : #ifdef CONFIG_COMPAT
     601                 :            :         .compat_ioctl   = ext4_compat_ioctl,
     602                 :            : #endif
     603                 :            :         .mmap           = ext4_file_mmap,
     604                 :            :         .open           = ext4_file_open,
     605                 :            :         .release        = ext4_release_file,
     606                 :            :         .fsync          = ext4_sync_file,
     607                 :            :         .splice_read    = generic_file_splice_read,
     608                 :            :         .splice_write   = generic_file_splice_write,
     609                 :            :         .fallocate      = ext4_fallocate,
     610                 :            : };
     611                 :            : 
     612                 :            : const struct inode_operations ext4_file_inode_operations = {
     613                 :            :         .setattr        = ext4_setattr,
     614                 :            :         .getattr        = ext4_getattr,
     615                 :            :         .setxattr       = generic_setxattr,
     616                 :            :         .getxattr       = generic_getxattr,
     617                 :            :         .listxattr      = ext4_listxattr,
     618                 :            :         .removexattr    = generic_removexattr,
     619                 :            :         .get_acl        = ext4_get_acl,
     620                 :            :         .fiemap         = ext4_fiemap,
     621                 :            : };
     622                 :            : 

Generated by: LCOV version 1.9