ext4: return non-zero st_blocks for inline data
[cascardo/linux.git] / fs / ext4 / inode.c
index 4cf2619..0757634 100644 (file)
@@ -727,8 +727,12 @@ static int _ext4_get_block(struct inode *inode, sector_t iblock,
 
        ret = ext4_map_blocks(handle, inode, &map, flags);
        if (ret > 0) {
+               ext4_io_end_t *io_end = ext4_inode_aio(inode);
+
                map_bh(bh, inode->i_sb, map.m_pblk);
                bh->b_state = (bh->b_state & ~EXT4_MAP_FLAGS) | map.m_flags;
+               if (io_end && io_end->flag & EXT4_IO_END_UNWRITTEN)
+                       set_buffer_defer_completion(bh);
                bh->b_size = inode->i_sb->s_blocksize * map.m_len;
                ret = 0;
        }
@@ -2174,6 +2178,9 @@ static int mpage_map_one_extent(handle_t *handle, struct mpage_da_data *mpd)
  *
  * @handle - handle for journal operations
  * @mpd - extent to map
+ * @give_up_on_write - we set this to true iff there is a fatal error and there
+ *                     is no hope of writing the data. The caller should discard
+ *                     dirty pages to avoid infinite loops.
  *
  * The function maps extent starting at mpd->lblk of length mpd->len. If it is
  * delayed, blocks are allocated, if it is unwritten, we may need to convert
@@ -2291,6 +2298,7 @@ static int mpage_prepare_extent_to_map(struct mpage_da_data *mpd)
        struct address_space *mapping = mpd->inode->i_mapping;
        struct pagevec pvec;
        unsigned int nr_pages;
+       long left = mpd->wbc->nr_to_write;
        pgoff_t index = mpd->first_page;
        pgoff_t end = mpd->last_page;
        int tag;
@@ -2326,6 +2334,17 @@ static int mpage_prepare_extent_to_map(struct mpage_da_data *mpd)
                        if (page->index > end)
                                goto out;
 
+                       /*
+                        * Accumulated enough dirty pages? This doesn't apply
+                        * to WB_SYNC_ALL mode. For integrity sync we have to
+                        * keep going because someone may be concurrently
+                        * dirtying pages, and we might have synced a lot of
+                        * newly appeared dirty pages, but have not synced all
+                        * of the old dirty pages.
+                        */
+                       if (mpd->wbc->sync_mode == WB_SYNC_NONE && left <= 0)
+                               goto out;
+
                        /* If we can't merge this page, we are done. */
                        if (mpd->map.m_len > 0 && mpd->next_page != page->index)
                                goto out;
@@ -2360,19 +2379,7 @@ static int mpage_prepare_extent_to_map(struct mpage_da_data *mpd)
                        if (err <= 0)
                                goto out;
                        err = 0;
-
-                       /*
-                        * Accumulated enough dirty pages? This doesn't apply
-                        * to WB_SYNC_ALL mode. For integrity sync we have to
-                        * keep going because someone may be concurrently
-                        * dirtying pages, and we might have synced a lot of
-                        * newly appeared dirty pages, but have not synced all
-                        * of the old dirty pages.
-                        */
-                       if (mpd->wbc->sync_mode == WB_SYNC_NONE &&
-                           mpd->next_page - mpd->first_page >=
-                                                       mpd->wbc->nr_to_write)
-                               goto out;
+                       left--;
                }
                pagevec_release(&pvec);
                cond_resched();
@@ -2416,16 +2423,15 @@ static int ext4_writepages(struct address_space *mapping,
         * because that could violate lock ordering on umount
         */
        if (!mapping->nrpages || !mapping_tagged(mapping, PAGECACHE_TAG_DIRTY))
-               return 0;
+               goto out_writepages;
 
        if (ext4_should_journal_data(inode)) {
                struct blk_plug plug;
-               int ret;
 
                blk_start_plug(&plug);
                ret = write_cache_pages(mapping, wbc, __writepage, mapping);
                blk_finish_plug(&plug);
-               return ret;
+               goto out_writepages;
        }
 
        /*
@@ -2438,8 +2444,10 @@ static int ext4_writepages(struct address_space *mapping,
         * *never* be called, so if that ever happens, we would want
         * the stack trace.
         */
-       if (unlikely(sbi->s_mount_flags & EXT4_MF_FS_ABORTED))
-               return -EROFS;
+       if (unlikely(sbi->s_mount_flags & EXT4_MF_FS_ABORTED)) {
+               ret = -EROFS;
+               goto out_writepages;
+       }
 
        if (ext4_should_dioread_nolock(inode)) {
                /*
@@ -3024,19 +3032,13 @@ static int ext4_get_block_write_nolock(struct inode *inode, sector_t iblock,
 }
 
 static void ext4_end_io_dio(struct kiocb *iocb, loff_t offset,
-                           ssize_t size, void *private, int ret,
-                           bool is_async)
+                           ssize_t size, void *private)
 {
-       struct inode *inode = file_inode(iocb->ki_filp);
         ext4_io_end_t *io_end = iocb->private;
 
        /* if not async direct IO just return */
-       if (!io_end) {
-               inode_dio_done(inode);
-               if (is_async)
-                       aio_complete(iocb, ret, 0);
+       if (!io_end)
                return;
-       }
 
        ext_debug("ext4_end_io_dio(): io_end 0x%p "
                  "for inode %lu, iocb 0x%p, offset %llu, size %zd\n",
@@ -3046,11 +3048,7 @@ static void ext4_end_io_dio(struct kiocb *iocb, loff_t offset,
        iocb->private = NULL;
        io_end->offset = offset;
        io_end->size = size;
-       if (is_async) {
-               io_end->iocb = iocb;
-               io_end->result = ret;
-       }
-       ext4_put_io_end_defer(io_end);
+       ext4_put_io_end(io_end);
 }
 
 /*
@@ -3135,7 +3133,6 @@ static ssize_t ext4_ext_direct_IO(int rw, struct kiocb *iocb,
                        ret = -ENOMEM;
                        goto retake_lock;
                }
-               io_end->flag |= EXT4_IO_END_DIRECT;
                /*
                 * Grab reference for DIO. Will be dropped in ext4_end_io_dio()
                 */
@@ -3180,13 +3177,6 @@ static ssize_t ext4_ext_direct_IO(int rw, struct kiocb *iocb,
                if (ret <= 0 && ret != -EIOCBQUEUED && iocb->private) {
                        WARN_ON(iocb->private != io_end);
                        WARN_ON(io_end->flag & EXT4_IO_END_UNWRITTEN);
-                       WARN_ON(io_end->iocb);
-                       /*
-                        * Generic code already did inode_dio_done() so we
-                        * have to clear EXT4_IO_END_DIRECT to not do it for
-                        * the second time.
-                        */
-                       io_end->flag = 0;
                        ext4_put_io_end(io_end);
                        iocb->private = NULL;
                }
@@ -4601,7 +4591,6 @@ int ext4_setattr(struct dentry *dentry, struct iattr *attr)
 
        if (attr->ia_valid & ATTR_SIZE && attr->ia_size != inode->i_size) {
                handle_t *handle;
-               loff_t oldsize = inode->i_size;
 
                if (!(ext4_test_inode_flag(inode, EXT4_INODE_EXTENTS))) {
                        struct ext4_sb_info *sbi = EXT4_SB(inode->i_sb);
@@ -4664,7 +4653,7 @@ int ext4_setattr(struct dentry *dentry, struct iattr *attr)
                 * Truncate pagecache after we've waited for commit
                 * in data=journal mode to make pages freeable.
                 */
-               truncate_pagecache(inode, oldsize, inode->i_size);
+                       truncate_pagecache(inode, inode->i_size);
        }
        /*
         * We want to call ext4_truncate() even if attr->ia_size ==
@@ -4704,6 +4693,15 @@ int ext4_getattr(struct vfsmount *mnt, struct dentry *dentry,
        inode = dentry->d_inode;
        generic_fillattr(inode, stat);
 
+       /*
+        * If there is inline data in the inode, the inode will normally not
+        * have data blocks allocated (it may have an external xattr block).
+        * Report at least one sector for such files, so tools like tar, rsync,
+        * others doen't incorrectly think the file is completely sparse.
+        */
+       if (unlikely(ext4_has_inline_data(inode)))
+               stat->blocks += (stat->size + 511) >> 9;
+
        /*
         * We can't update i_blocks if the block allocation is delayed
         * otherwise in the case of system crash before the real block
@@ -4715,9 +4713,8 @@ int ext4_getattr(struct vfsmount *mnt, struct dentry *dentry,
         * blocks for this file.
         */
        delalloc_blocks = EXT4_C2B(EXT4_SB(inode->i_sb),
-                               EXT4_I(inode)->i_reserved_data_blocks);
-
-       stat->blocks += delalloc_blocks << (inode->i_sb->s_blocksize_bits-9);
+                                  EXT4_I(inode)->i_reserved_data_blocks);
+       stat->blocks += delalloc_blocks << (inode->i_sb->s_blocksize_bits - 9);
        return 0;
 }