Merge branch 'for-linus-4.4' of git://git.kernel.org/pub/scm/linux/kernel/git/mason...
[firefly-linux-kernel-4.4.55.git] / fs / f2fs / inline.c
index 3d143be428959153872146e4c4bba4278fec2da5..bda7126466c09f9b16f4d275cac5b287a06c9142 100644 (file)
@@ -12,6 +12,7 @@
 #include <linux/f2fs_fs.h>
 
 #include "f2fs.h"
+#include "node.h"
 
 bool f2fs_may_inline_data(struct inode *inode)
 {
@@ -274,12 +275,14 @@ process_inline:
        if (f2fs_has_inline_data(inode)) {
                ipage = get_node_page(sbi, inode->i_ino);
                f2fs_bug_on(sbi, IS_ERR(ipage));
-               truncate_inline_inode(ipage, 0);
+               if (!truncate_inline_inode(ipage, 0))
+                       return false;
                f2fs_clear_inline_inode(inode);
                update_inode(inode, ipage);
                f2fs_put_page(ipage, 1);
        } else if (ri && (ri->i_inline & F2FS_INLINE_DATA)) {
-               truncate_blocks(inode, 0, false);
+               if (truncate_blocks(inode, 0, false))
+                       return false;
                goto process_inline;
        }
        return false;
@@ -568,3 +571,38 @@ int f2fs_read_inline_dir(struct file *file, struct dir_context *ctx,
        f2fs_put_page(ipage, 1);
        return 0;
 }
+
+int f2fs_inline_data_fiemap(struct inode *inode,
+               struct fiemap_extent_info *fieinfo, __u64 start, __u64 len)
+{
+       __u64 byteaddr, ilen;
+       __u32 flags = FIEMAP_EXTENT_DATA_INLINE | FIEMAP_EXTENT_NOT_ALIGNED |
+               FIEMAP_EXTENT_LAST;
+       struct node_info ni;
+       struct page *ipage;
+       int err = 0;
+
+       ipage = get_node_page(F2FS_I_SB(inode), inode->i_ino);
+       if (IS_ERR(ipage))
+               return PTR_ERR(ipage);
+
+       if (!f2fs_has_inline_data(inode)) {
+               err = -EAGAIN;
+               goto out;
+       }
+
+       ilen = min_t(size_t, MAX_INLINE_DATA, i_size_read(inode));
+       if (start >= ilen)
+               goto out;
+       if (start + len < ilen)
+               ilen = start + len;
+       ilen -= start;
+
+       get_node_info(F2FS_I_SB(inode), inode->i_ino, &ni);
+       byteaddr = (__u64)ni.blk_addr << inode->i_sb->s_blocksize_bits;
+       byteaddr += (char *)inline_data_addr(ipage) - (char *)F2FS_INODE(ipage);
+       err = fiemap_fill_next_extent(fieinfo, start, byteaddr, ilen, flags);
+out:
+       f2fs_put_page(ipage, 1);
+       return err;
+}