diff mbox series

[28/52] Do fallocate() to grow file before mapping for file growing writes

Message ID 20181210171318.16998-29-vgoyal@redhat.com (mailing list archive)
State New, archived
Headers show
Series virtio-fs: shared file system for virtual machines | expand

Commit Message

Vivek Goyal Dec. 10, 2018, 5:12 p.m. UTC
How to handle file growing writes. For now, this patch does fallocate() to
grow file and then map it using dax. We need to figure out what's the best
way to handle it.

This patch does fallocate() and setup mapping operations in
fuse_dax_write_iter(), instead of iomap_begin(). I don't have access to file
pointer needed to send a message to fuse daemon in iomap_begin().

Dave Chinner has expressed concers with this approach as this is not
atomic. If guest crashes after falloc() but before data was written,
user will think that filesystem lost its data. So this is still an
outstanding issue.

Signed-off-by: Vivek Goyal <vgoyal@redhat.com>
---
 fs/fuse/file.c | 71 +++++++++++++++++++++++++++++++++++++++++++++-------------
 1 file changed, 55 insertions(+), 16 deletions(-)

Comments

kernel test robot Dec. 11, 2018, 6:13 a.m. UTC | #1
Hi Vivek,

I love your patch! Perhaps something to improve:

[auto build test WARNING on fuse/for-next]
[also build test WARNING on v4.20-rc6]
[cannot apply to next-20181210]
[if your patch is applied to the wrong git tree, please drop us a note to help improve the system]

url:    https://github.com/0day-ci/linux/commits/Vivek-Goyal/virtio-fs-shared-file-system-for-virtual-machines/20181211-103034
base:   https://git.kernel.org/pub/scm/linux/kernel/git/mszeredi/fuse.git for-next
config: i386-randconfig-x005-201849 (attached as .config)
compiler: gcc-7 (Debian 7.3.0-1) 7.3.0
reproduce:
        # save the attached .config to linux build tree
        make ARCH=i386 

All warnings (new ones prefixed by >>):

   fs/fuse/file.c: In function 'fuse_dax_write_iter':
>> fs/fuse/file.c:1834:47: warning: format '%lx' expects argument of type 'long unsigned int', but argument 3 has type 'size_t {aka unsigned int}' [-Wformat=]
       printk("fallocate(offset=0x%llx length=0x%lx)"
                                                ~~^
                                                %x
   fs/fuse/file.c:1836:4:
       iov_iter_count(from), ret);
       ~~~~~~~~~~~~~~~~~~~~                        
>> fs/fuse/file.c:1834:11: warning: format '%ld' expects argument of type 'long int', but argument 4 has type 'ssize_t {aka int}' [-Wformat=]
       printk("fallocate(offset=0x%llx length=0x%lx)"
              ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
   fs/fuse/file.c:1835:20: note: format string is defined here
       " failed. err=%ld\n", iocb->ki_pos,
                     ~~^
                     %d
   In file included from include/linux/kernel.h:14:0,
                    from include/linux/list.h:9,
                    from include/linux/wait.h:7,
                    from include/linux/wait_bit.h:8,
                    from include/linux/fs.h:6,
                    from fs/fuse/fuse_i.h:13,
                    from fs/fuse/file.c:9:
   fs/fuse/file.c:1839:12: warning: format '%lx' expects argument of type 'long unsigned int', but argument 4 has type 'size_t {aka unsigned int}' [-Wformat=]
      pr_debug("fallocate(offset=0x%llx length=0x%lx)"
               ^
   include/linux/printk.h:292:21: note: in definition of macro 'pr_fmt'
    #define pr_fmt(fmt) fmt
                        ^~~
   include/linux/printk.h:340:2: note: in expansion of macro 'dynamic_pr_debug'
     dynamic_pr_debug(fmt, ##__VA_ARGS__)
     ^~~~~~~~~~~~~~~~
>> fs/fuse/file.c:1839:3: note: in expansion of macro 'pr_debug'
      pr_debug("fallocate(offset=0x%llx length=0x%lx)"
      ^~~~~~~~
   fs/fuse/file.c:1839:48: note: format string is defined here
      pr_debug("fallocate(offset=0x%llx length=0x%lx)"
                                                 ~~^
                                                 %x
   In file included from include/linux/kernel.h:14:0,
                    from include/linux/list.h:9,
                    from include/linux/wait.h:7,
                    from include/linux/wait_bit.h:8,
                    from include/linux/fs.h:6,
                    from fs/fuse/fuse_i.h:13,
                    from fs/fuse/file.c:9:
   fs/fuse/file.c:1839:12: warning: format '%ld' expects argument of type 'long int', but argument 5 has type 'ssize_t {aka int}' [-Wformat=]
      pr_debug("fallocate(offset=0x%llx length=0x%lx)"
               ^
   include/linux/printk.h:292:21: note: in definition of macro 'pr_fmt'
    #define pr_fmt(fmt) fmt
                        ^~~
   include/linux/printk.h:340:2: note: in expansion of macro 'dynamic_pr_debug'
     dynamic_pr_debug(fmt, ##__VA_ARGS__)
     ^~~~~~~~~~~~~~~~
>> fs/fuse/file.c:1839:3: note: in expansion of macro 'pr_debug'
      pr_debug("fallocate(offset=0x%llx length=0x%lx)"
      ^~~~~~~~
   fs/fuse/file.c:1840:20: note: format string is defined here
      " succeed. ret=%ld\n", iocb->ki_pos, iov_iter_count(from), ret);
                     ~~^
                     %d
   Cyclomatic Complexity 5 include/linux/compiler.h:__read_once_size
   Cyclomatic Complexity 5 include/linux/compiler.h:__write_once_size
   Cyclomatic Complexity 1 include/linux/kasan-checks.h:kasan_check_read
   Cyclomatic Complexity 1 include/linux/kasan-checks.h:kasan_check_write
   Cyclomatic Complexity 2 arch/x86/include/asm/bitops.h:set_bit
   Cyclomatic Complexity 1 arch/x86/include/asm/bitops.h:__set_bit
   Cyclomatic Complexity 2 arch/x86/include/asm/bitops.h:clear_bit
   Cyclomatic Complexity 1 arch/x86/include/asm/bitops.h:__clear_bit
   Cyclomatic Complexity 1 arch/x86/include/asm/bitops.h:test_and_set_bit
   Cyclomatic Complexity 1 arch/x86/include/asm/bitops.h:test_and_set_bit_lock
   Cyclomatic Complexity 1 arch/x86/include/asm/bitops.h:constant_test_bit
   Cyclomatic Complexity 1 arch/x86/include/asm/bitops.h:fls
   Cyclomatic Complexity 1 include/linux/log2.h:__ilog2_u32
   Cyclomatic Complexity 2 arch/x86/include/asm/jump_label.h:arch_static_branch
   Cyclomatic Complexity 1 include/linux/list.h:INIT_LIST_HEAD
   Cyclomatic Complexity 1 include/linux/list.h:__list_add_valid
   Cyclomatic Complexity 1 include/linux/list.h:__list_del_entry_valid
   Cyclomatic Complexity 2 include/linux/list.h:__list_add
   Cyclomatic Complexity 1 include/linux/list.h:list_add
   Cyclomatic Complexity 1 include/linux/list.h:list_add_tail
   Cyclomatic Complexity 1 include/linux/list.h:__list_del
   Cyclomatic Complexity 2 include/linux/list.h:__list_del_entry
   Cyclomatic Complexity 1 include/linux/list.h:list_del
   Cyclomatic Complexity 1 include/linux/list.h:list_del_init
   Cyclomatic Complexity 1 include/linux/list.h:list_empty
   Cyclomatic Complexity 1 arch/x86/include/asm/current.h:get_current
   Cyclomatic Complexity 1 arch/x86/include/asm/page_32.h:copy_page
   Cyclomatic Complexity 1 include/asm-generic/getorder.h:__get_order
   Cyclomatic Complexity 1 include/linux/err.h:PTR_ERR
   Cyclomatic Complexity 1 include/linux/err.h:IS_ERR
   Cyclomatic Complexity 1 arch/x86/include/asm/irqflags.h:native_save_fl
   Cyclomatic Complexity 1 arch/x86/include/asm/irqflags.h:native_restore_fl
   Cyclomatic Complexity 1 arch/x86/include/asm/irqflags.h:native_irq_disable
   Cyclomatic Complexity 1 arch/x86/include/asm/irqflags.h:arch_local_save_flags
   Cyclomatic Complexity 1 arch/x86/include/asm/irqflags.h:arch_local_irq_restore
   Cyclomatic Complexity 1 arch/x86/include/asm/irqflags.h:arch_local_irq_disable
   Cyclomatic Complexity 1 arch/x86/include/asm/irqflags.h:arch_local_irq_save
   Cyclomatic Complexity 1 arch/x86/include/asm/processor.h:rep_nop
   Cyclomatic Complexity 1 arch/x86/include/asm/processor.h:cpu_relax
   Cyclomatic Complexity 1 arch/x86/include/asm/atomic.h:arch_atomic_read
   Cyclomatic Complexity 1 arch/x86/include/asm/atomic.h:arch_atomic_set
   Cyclomatic Complexity 1 arch/x86/include/asm/atomic.h:arch_atomic_inc
   Cyclomatic Complexity 1 arch/x86/include/asm/atomic.h:arch_atomic_dec_and_test
   Cyclomatic Complexity 1 include/asm-generic/atomic-instrumented.h:atomic_read
   Cyclomatic Complexity 1 include/asm-generic/atomic-instrumented.h:atomic_set
   Cyclomatic Complexity 1 include/asm-generic/atomic-instrumented.h:atomic_inc
   Cyclomatic Complexity 1 include/asm-generic/atomic-instrumented.h:atomic_dec_and_test
   Cyclomatic Complexity 5 arch/x86/include/asm/preempt.h:__preempt_count_add
   Cyclomatic Complexity 5 arch/x86/include/asm/preempt.h:__preempt_count_sub
   Cyclomatic Complexity 1 include/linux/spinlock.h:spinlock_check
   Cyclomatic Complexity 1 include/linux/spinlock.h:spin_lock
   Cyclomatic Complexity 1 include/linux/spinlock.h:spin_unlock
   Cyclomatic Complexity 1 include/linux/wait.h:waitqueue_active
   Cyclomatic Complexity 1 include/linux/rcupdate.h:__rcu_read_lock
   Cyclomatic Complexity 1 include/linux/rcupdate.h:__rcu_read_unlock
   Cyclomatic Complexity 1 include/linux/rcupdate.h:rcu_lock_acquire
   Cyclomatic Complexity 1 include/linux/rcupdate.h:rcu_lock_release
   Cyclomatic Complexity 1 include/linux/rcupdate.h:rcu_read_lock
   Cyclomatic Complexity 1 include/linux/rcupdate.h:rcu_read_unlock
   Cyclomatic Complexity 1 include/linux/seqlock.h:seqcount_lockdep_reader_access
   Cyclomatic Complexity 2 include/linux/seqlock.h:__read_seqcount_begin
   Cyclomatic Complexity 1 include/linux/seqlock.h:raw_read_seqcount_begin
   Cyclomatic Complexity 1 include/linux/seqlock.h:read_seqcount_begin
   Cyclomatic Complexity 1 include/linux/seqlock.h:__read_seqcount_retry
   Cyclomatic Complexity 1 include/linux/seqlock.h:read_seqcount_retry
   Cyclomatic Complexity 1 include/linux/seqlock.h:raw_write_seqcount_begin
   Cyclomatic Complexity 1 include/linux/seqlock.h:raw_write_seqcount_end
   Cyclomatic Complexity 1 include/linux/seqlock.h:write_seqcount_begin_nested
   Cyclomatic Complexity 1 include/linux/seqlock.h:write_seqcount_begin
   Cyclomatic Complexity 1 include/linux/seqlock.h:write_seqcount_end
   Cyclomatic Complexity 2 include/linux/dcache.h:d_real
   Cyclomatic Complexity 1 include/linux/completion.h:__init_completion
   Cyclomatic Complexity 1 arch/x86/include/asm/topology.h:numa_node_id
   Cyclomatic Complexity 1 include/linux/rbtree.h:rb_link_node
   Cyclomatic Complexity 1 include/linux/topology.h:numa_mem_id
   Cyclomatic Complexity 1 include/linux/gfp.h:__alloc_pages
   Cyclomatic Complexity 1 include/linux/gfp.h:__alloc_pages_node
   Cyclomatic Complexity 2 include/linux/gfp.h:alloc_pages_node
   Cyclomatic Complexity 1 include/linux/refcount.h:refcount_set
   Cyclomatic Complexity 1 include/linux/refcount.h:refcount_read
   Cyclomatic Complexity 1 arch/x86/include/asm/refcount.h:refcount_inc
   Cyclomatic Complexity 1 arch/x86/include/asm/refcount.h:refcount_dec_and_test
   Cyclomatic Complexity 1 include/linux/fs.h:is_sync_kiocb
   Cyclomatic Complexity 1 include/linux/fs.h:mapping_writably_mapped
   Cyclomatic Complexity 1 include/linux/fs.h:inode_lock
   Cyclomatic Complexity 1 include/linux/fs.h:inode_unlock
   Cyclomatic Complexity 1 include/linux/fs.h:inode_lock_shared
   Cyclomatic Complexity 1 include/linux/fs.h:inode_unlock_shared
   Cyclomatic Complexity 1 include/linux/fs.h:inode_trylock
   Cyclomatic Complexity 1 include/linux/fs.h:inode_trylock_shared
   Cyclomatic Complexity 2 include/linux/fs.h:i_size_read
   Cyclomatic Complexity 1 include/linux/fs.h:i_size_write
   Cyclomatic Complexity 1 include/linux/fs.h:file_inode
   Cyclomatic Complexity 1 include/linux/fs.h:file_dentry

vim +1834 fs/fuse/file.c

  1803	
  1804	static ssize_t fuse_dax_write_iter(struct kiocb *iocb, struct iov_iter *from)
  1805	{
  1806		struct inode *inode = file_inode(iocb->ki_filp);
  1807		ssize_t ret;
  1808	
  1809		if (iocb->ki_flags & IOCB_NOWAIT) {
  1810			if (!inode_trylock(inode))
  1811				return -EAGAIN;
  1812		} else {
  1813			inode_lock(inode);
  1814		}
  1815	
  1816		ret = generic_write_checks(iocb, from);
  1817		if (ret <= 0)
  1818			goto out;
  1819	
  1820		ret = file_remove_privs(iocb->ki_filp);
  1821		if (ret)
  1822			goto out;
  1823		/* TODO file_update_time() but we don't want metadata I/O */
  1824	
  1825		/* TODO handle growing the file */
  1826		/* Grow file here if need be. iomap_begin() does not have access
  1827		 * to file pointer
  1828		 */
  1829		if (iov_iter_rw(from) == WRITE &&
  1830		    ((iocb->ki_pos + iov_iter_count(from)) > i_size_read(inode))) {
  1831			ret = __fuse_file_fallocate(iocb->ki_filp, 0, iocb->ki_pos,
  1832							iov_iter_count(from));
  1833			if (ret < 0) {
> 1834				printk("fallocate(offset=0x%llx length=0x%lx)"
  1835				" failed. err=%ld\n", iocb->ki_pos,
  1836				iov_iter_count(from), ret);
  1837				goto out;
  1838			}
> 1839			pr_debug("fallocate(offset=0x%llx length=0x%lx)"
  1840			" succeed. ret=%ld\n", iocb->ki_pos, iov_iter_count(from), ret);
  1841		}
  1842	
  1843		ret = dax_iomap_rw(iocb, from, &fuse_iomap_ops);
  1844	
  1845	out:
  1846		inode_unlock(inode);
  1847	
  1848		if (ret > 0)
  1849			ret = generic_write_sync(iocb, ret);
  1850		return ret;
  1851	}
  1852	

---
0-DAY kernel test infrastructure                Open Source Technology Center
https://lists.01.org/pipermail/kbuild-all                   Intel Corporation
kernel test robot Dec. 11, 2018, 6:20 a.m. UTC | #2
Hi Vivek,

I love your patch! Perhaps something to improve:

[auto build test WARNING on fuse/for-next]
[also build test WARNING on v4.20-rc6]
[cannot apply to next-20181210]
[if your patch is applied to the wrong git tree, please drop us a note to help improve the system]

url:    https://github.com/0day-ci/linux/commits/Vivek-Goyal/virtio-fs-shared-file-system-for-virtual-machines/20181211-103034
base:   https://git.kernel.org/pub/scm/linux/kernel/git/mszeredi/fuse.git for-next
config: i386-randconfig-x000-201849 (attached as .config)
compiler: gcc-7 (Debian 7.3.0-1) 7.3.0
reproduce:
        # save the attached .config to linux build tree
        make ARCH=i386 

All warnings (new ones prefixed by >>):

   fs/fuse/file.c: In function 'fuse_dax_write_iter':
   fs/fuse/file.c:1834:47: warning: format '%lx' expects argument of type 'long unsigned int', but argument 3 has type 'size_t {aka unsigned int}' [-Wformat=]
       printk("fallocate(offset=0x%llx length=0x%lx)"
                                                ~~^
                                                %x
   fs/fuse/file.c:1836:4:
       iov_iter_count(from), ret);
       ~~~~~~~~~~~~~~~~~~~~                        
   fs/fuse/file.c:1834:11: warning: format '%ld' expects argument of type 'long int', but argument 4 has type 'ssize_t {aka int}' [-Wformat=]
       printk("fallocate(offset=0x%llx length=0x%lx)"
              ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
   fs/fuse/file.c:1835:20: note: format string is defined here
       " failed. err=%ld\n", iocb->ki_pos,
                     ~~^
                     %d
   In file included from include/linux/kernel.h:14:0,
                    from include/linux/list.h:9,
                    from include/linux/wait.h:7,
                    from include/linux/wait_bit.h:8,
                    from include/linux/fs.h:6,
                    from fs/fuse/fuse_i.h:13,
                    from fs/fuse/file.c:9:
   include/linux/kern_levels.h:5:18: warning: format '%lx' expects argument of type 'long unsigned int', but argument 3 has type 'size_t {aka unsigned int}' [-Wformat=]
    #define KERN_SOH "\001"  /* ASCII Start Of Header */
                     ^
   include/linux/printk.h:136:10: note: in definition of macro 'no_printk'
      printk(fmt, ##__VA_ARGS__);  \
             ^~~
   include/linux/kern_levels.h:15:20: note: in expansion of macro 'KERN_SOH'
    #define KERN_DEBUG KERN_SOH "7" /* debug-level messages */
                       ^~~~~~~~
   include/linux/printk.h:346:12: note: in expansion of macro 'KERN_DEBUG'
     no_printk(KERN_DEBUG pr_fmt(fmt), ##__VA_ARGS__)
               ^~~~~~~~~~
   fs/fuse/file.c:1839:3: note: in expansion of macro 'pr_debug'
      pr_debug("fallocate(offset=0x%llx length=0x%lx)"
      ^~~~~~~~
   fs/fuse/file.c:1839:48: note: format string is defined here
      pr_debug("fallocate(offset=0x%llx length=0x%lx)"
                                                 ~~^
                                                 %x
   In file included from include/linux/kernel.h:14:0,
                    from include/linux/list.h:9,
                    from include/linux/wait.h:7,
                    from include/linux/wait_bit.h:8,
                    from include/linux/fs.h:6,
                    from fs/fuse/fuse_i.h:13,
                    from fs/fuse/file.c:9:
>> include/linux/kern_levels.h:5:18: warning: format '%ld' expects argument of type 'long int', but argument 4 has type 'ssize_t {aka int}' [-Wformat=]
    #define KERN_SOH "\001"  /* ASCII Start Of Header */
                     ^
   include/linux/printk.h:136:10: note: in definition of macro 'no_printk'
      printk(fmt, ##__VA_ARGS__);  \
             ^~~
   include/linux/kern_levels.h:15:20: note: in expansion of macro 'KERN_SOH'
    #define KERN_DEBUG KERN_SOH "7" /* debug-level messages */
                       ^~~~~~~~
   include/linux/printk.h:346:12: note: in expansion of macro 'KERN_DEBUG'
     no_printk(KERN_DEBUG pr_fmt(fmt), ##__VA_ARGS__)
               ^~~~~~~~~~
   fs/fuse/file.c:1839:3: note: in expansion of macro 'pr_debug'
      pr_debug("fallocate(offset=0x%llx length=0x%lx)"
      ^~~~~~~~
   fs/fuse/file.c:1840:20: note: format string is defined here
      " succeed. ret=%ld\n", iocb->ki_pos, iov_iter_count(from), ret);
                     ~~^
                     %d
--
   fs//fuse/file.c: In function 'fuse_dax_write_iter':
   fs//fuse/file.c:1834:47: warning: format '%lx' expects argument of type 'long unsigned int', but argument 3 has type 'size_t {aka unsigned int}' [-Wformat=]
       printk("fallocate(offset=0x%llx length=0x%lx)"
                                                ~~^
                                                %x
   fs//fuse/file.c:1836:4:
       iov_iter_count(from), ret);
       ~~~~~~~~~~~~~~~~~~~~                        
   fs//fuse/file.c:1834:11: warning: format '%ld' expects argument of type 'long int', but argument 4 has type 'ssize_t {aka int}' [-Wformat=]
       printk("fallocate(offset=0x%llx length=0x%lx)"
              ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
   fs//fuse/file.c:1835:20: note: format string is defined here
       " failed. err=%ld\n", iocb->ki_pos,
                     ~~^
                     %d
   In file included from include/linux/kernel.h:14:0,
                    from include/linux/list.h:9,
                    from include/linux/wait.h:7,
                    from include/linux/wait_bit.h:8,
                    from include/linux/fs.h:6,
                    from fs//fuse/fuse_i.h:13,
                    from fs//fuse/file.c:9:
   include/linux/kern_levels.h:5:18: warning: format '%lx' expects argument of type 'long unsigned int', but argument 3 has type 'size_t {aka unsigned int}' [-Wformat=]
    #define KERN_SOH "\001"  /* ASCII Start Of Header */
                     ^
   include/linux/printk.h:136:10: note: in definition of macro 'no_printk'
      printk(fmt, ##__VA_ARGS__);  \
             ^~~
   include/linux/kern_levels.h:15:20: note: in expansion of macro 'KERN_SOH'
    #define KERN_DEBUG KERN_SOH "7" /* debug-level messages */
                       ^~~~~~~~
   include/linux/printk.h:346:12: note: in expansion of macro 'KERN_DEBUG'
     no_printk(KERN_DEBUG pr_fmt(fmt), ##__VA_ARGS__)
               ^~~~~~~~~~
   fs//fuse/file.c:1839:3: note: in expansion of macro 'pr_debug'
      pr_debug("fallocate(offset=0x%llx length=0x%lx)"
      ^~~~~~~~
   fs//fuse/file.c:1839:48: note: format string is defined here
      pr_debug("fallocate(offset=0x%llx length=0x%lx)"
                                                 ~~^
                                                 %x
   In file included from include/linux/kernel.h:14:0,
                    from include/linux/list.h:9,
                    from include/linux/wait.h:7,
                    from include/linux/wait_bit.h:8,
                    from include/linux/fs.h:6,
                    from fs//fuse/fuse_i.h:13,
                    from fs//fuse/file.c:9:
>> include/linux/kern_levels.h:5:18: warning: format '%ld' expects argument of type 'long int', but argument 4 has type 'ssize_t {aka int}' [-Wformat=]
    #define KERN_SOH "\001"  /* ASCII Start Of Header */
                     ^
   include/linux/printk.h:136:10: note: in definition of macro 'no_printk'
      printk(fmt, ##__VA_ARGS__);  \
             ^~~
   include/linux/kern_levels.h:15:20: note: in expansion of macro 'KERN_SOH'
    #define KERN_DEBUG KERN_SOH "7" /* debug-level messages */
                       ^~~~~~~~
   include/linux/printk.h:346:12: note: in expansion of macro 'KERN_DEBUG'
     no_printk(KERN_DEBUG pr_fmt(fmt), ##__VA_ARGS__)
               ^~~~~~~~~~
   fs//fuse/file.c:1839:3: note: in expansion of macro 'pr_debug'
      pr_debug("fallocate(offset=0x%llx length=0x%lx)"
      ^~~~~~~~
   fs//fuse/file.c:1840:20: note: format string is defined here
      " succeed. ret=%ld\n", iocb->ki_pos, iov_iter_count(from), ret);
                     ~~^
                     %d

vim +5 include/linux/kern_levels.h

314ba352 Joe Perches 2012-07-30  4  
04d2c8c8 Joe Perches 2012-07-30 @5  #define KERN_SOH	"\001"		/* ASCII Start Of Header */
04d2c8c8 Joe Perches 2012-07-30  6  #define KERN_SOH_ASCII	'\001'
04d2c8c8 Joe Perches 2012-07-30  7  

:::::: The code at line 5 was first introduced by commit
:::::: 04d2c8c83d0e3ac5f78aeede51babb3236200112 printk: convert the format for KERN_<LEVEL> to a 2 byte pattern

:::::: TO: Joe Perches <joe@perches.com>
:::::: CC: Linus Torvalds <torvalds@linux-foundation.org>

---
0-DAY kernel test infrastructure                Open Source Technology Center
https://lists.01.org/pipermail/kbuild-all                   Intel Corporation
diff mbox series

Patch

diff --git a/fs/fuse/file.c b/fs/fuse/file.c
index 94ad76382a6f..41d773ba2c72 100644
--- a/fs/fuse/file.c
+++ b/fs/fuse/file.c
@@ -28,6 +28,9 @@  INTERVAL_TREE_DEFINE(struct fuse_dax_mapping,
                      rb, __u64, __subtree_last,
                      START, LAST, static inline, fuse_dax_interval_tree);
 
+static long __fuse_file_fallocate(struct file *file, int mode,
+					loff_t offset, loff_t length);
+
 static int fuse_send_open(struct fuse_conn *fc, u64 nodeid, struct file *file,
 			  int opcode, struct fuse_open_out *outargp)
 {
@@ -1819,6 +1822,22 @@  static ssize_t fuse_dax_write_iter(struct kiocb *iocb, struct iov_iter *from)
 	/* TODO file_update_time() but we don't want metadata I/O */
 
 	/* TODO handle growing the file */
+	/* Grow file here if need be. iomap_begin() does not have access
+	 * to file pointer
+	 */
+	if (iov_iter_rw(from) == WRITE &&
+	    ((iocb->ki_pos + iov_iter_count(from)) > i_size_read(inode))) {
+		ret = __fuse_file_fallocate(iocb->ki_filp, 0, iocb->ki_pos,
+						iov_iter_count(from));
+		if (ret < 0) {
+			printk("fallocate(offset=0x%llx length=0x%lx)"
+			" failed. err=%ld\n", iocb->ki_pos,
+			iov_iter_count(from), ret);
+			goto out;
+		}
+		pr_debug("fallocate(offset=0x%llx length=0x%lx)"
+		" succeed. ret=%ld\n", iocb->ki_pos, iov_iter_count(from), ret);
+	}
 
 	ret = dax_iomap_rw(iocb, from, &fuse_iomap_ops);
 
@@ -3331,8 +3350,12 @@  fuse_direct_IO(struct kiocb *iocb, struct iov_iter *iter)
 	return ret;
 }
 
-static long fuse_file_fallocate(struct file *file, int mode, loff_t offset,
-				loff_t length)
+/*
+ * This variant does not take any inode lock and if locking is required,
+ * caller is supposed to hold lock
+ */
+static long __fuse_file_fallocate(struct file *file, int mode,
+					loff_t offset, loff_t length)
 {
 	struct fuse_file *ff = file->private_data;
 	struct inode *inode = file_inode(file);
@@ -3346,8 +3369,6 @@  static long fuse_file_fallocate(struct file *file, int mode, loff_t offset,
 		.mode = mode
 	};
 	int err;
-	bool lock_inode = !(mode & FALLOC_FL_KEEP_SIZE) ||
-			   (mode & FALLOC_FL_PUNCH_HOLE);
 
 	if (mode & ~(FALLOC_FL_KEEP_SIZE | FALLOC_FL_PUNCH_HOLE))
 		return -EOPNOTSUPP;
@@ -3355,17 +3376,13 @@  static long fuse_file_fallocate(struct file *file, int mode, loff_t offset,
 	if (fc->no_fallocate)
 		return -EOPNOTSUPP;
 
-	if (lock_inode) {
-		inode_lock(inode);
-		if (mode & FALLOC_FL_PUNCH_HOLE) {
-			loff_t endbyte = offset + length - 1;
-			err = filemap_write_and_wait_range(inode->i_mapping,
-							   offset, endbyte);
-			if (err)
-				goto out;
-
-			fuse_sync_writes(inode);
-		}
+	if (mode & FALLOC_FL_PUNCH_HOLE) {
+		loff_t endbyte = offset + length - 1;
+		err = filemap_write_and_wait_range(inode->i_mapping, offset,
+							endbyte);
+		if (err)
+			goto out;
+		fuse_sync_writes(inode);
 	}
 
 	if (!(mode & FALLOC_FL_KEEP_SIZE))
@@ -3401,9 +3418,31 @@  static long fuse_file_fallocate(struct file *file, int mode, loff_t offset,
 	if (!(mode & FALLOC_FL_KEEP_SIZE))
 		clear_bit(FUSE_I_SIZE_UNSTABLE, &fi->state);
 
+	return err;
+}
+
+static long fuse_file_fallocate(struct file *file, int mode, loff_t offset,
+				loff_t length)
+{
+	struct fuse_file *ff = file->private_data;
+	struct inode *inode = file_inode(file);
+	struct fuse_conn *fc = ff->fc;
+	int err;
+	bool lock_inode = !(mode & FALLOC_FL_KEEP_SIZE) ||
+			   (mode & FALLOC_FL_PUNCH_HOLE);
+
+	if (mode & ~(FALLOC_FL_KEEP_SIZE | FALLOC_FL_PUNCH_HOLE))
+		return -EOPNOTSUPP;
+
+	if (fc->no_fallocate)
+		return -EOPNOTSUPP;
+
 	if (lock_inode)
-		inode_unlock(inode);
+		inode_lock(inode);
 
+	err = __fuse_file_fallocate(file, mode, offset, length);
+	if (lock_inode)
+		inode_unlock(inode);
 	return err;
 }