[v2,13/15] CIFS: Add support for direct I/O read

Message ID 20180530194807.31657-14-longli@linuxonhyperv.com
State New
Headers show
Series
  • CIFS: Add direct I/O support
Related show

Commit Message

Long Li May 30, 2018, 7:48 p.m.
From: Long Li <longli@microsoft.com>

Implement the function for direct I/O read. It doesn't support AIO, which
will be implemented in a follow up patch.

Signed-off-by: Long Li <longli@microsoft.com>
---
 fs/cifs/cifsfs.h |   1 +
 fs/cifs/file.c   | 149 +++++++++++++++++++++++++++++++++++++++++++++++++++++++
 2 files changed, 150 insertions(+)

Comments

kbuild test robot June 2, 2018, 5:51 a.m. | #1
Hi Long,

Thank you for the patch! Perhaps something to improve:

[auto build test WARNING on v4.17-rc6]
[cannot apply to cifs/for-next next-20180601]
[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/Long-Li/CIFS-Add-direct-I-O-support/20180602-130240
config: i386-randconfig-x000-201821 (attached as .config)
compiler: gcc-7 (Debian 7.3.0-16) 7.3.0
reproduce:
        # save the attached .config to linux build tree
        make ARCH=i386 

All warnings (new ones prefixed by >>):

   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/cifs/file.c:24:
   fs/cifs/file.c: In function 'cifs_direct_readv':
   include/linux/kern_levels.h:5:18: warning: format '%lu' expects argument of type 'long unsigned int', but argument 4 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:342:12: note: in expansion of macro 'KERN_DEBUG'
     no_printk(KERN_DEBUG pr_fmt(fmt), ##__VA_ARGS__)
               ^~~~~~~~~~
>> fs/cifs/cifs_debug.h:82:3: note: in expansion of macro 'pr_debug'
      pr_debug(fmt, ##__VA_ARGS__);    \
      ^~~~~~~~
   fs/cifs/file.c:3346:4: note: in expansion of macro 'cifs_dbg'
       cifs_dbg(VFS,
       ^~~~~~~~
   fs/cifs/file.c:3348:20: note: format string is defined here
        " iov_offset %lu count %lu\n",
                     ~~^
                     %u
   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/cifs/file.c:24:
   include/linux/kern_levels.h:5:18: warning: format '%lu' expects argument of type 'long unsigned int', but argument 5 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:342:12: note: in expansion of macro 'KERN_DEBUG'
     no_printk(KERN_DEBUG pr_fmt(fmt), ##__VA_ARGS__)
               ^~~~~~~~~~
>> fs/cifs/cifs_debug.h:82:3: note: in expansion of macro 'pr_debug'
      pr_debug(fmt, ##__VA_ARGS__);    \
      ^~~~~~~~
   fs/cifs/file.c:3346:4: note: in expansion of macro 'cifs_dbg'
       cifs_dbg(VFS,
       ^~~~~~~~
   fs/cifs/file.c:3348:30: note: format string is defined here
        " iov_offset %lu count %lu\n",
                               ~~^
                               %u

vim +/pr_debug +82 fs/cifs/cifs_debug.h

f2f176b4 Aurelien Aptel  2018-04-10  73  
^1da177e Linus Torvalds  2005-04-16  74  /*
^1da177e Linus Torvalds  2005-04-16  75   *	debug OFF
^1da177e Linus Torvalds  2005-04-16  76   *	---------
^1da177e Linus Torvalds  2005-04-16  77   */
^1da177e Linus Torvalds  2005-04-16  78  #else		/* _CIFS_DEBUG */
f96637be Joe Perches     2013-05-04  79  #define cifs_dbg(type, fmt, ...)					\
bde98197 Joe Perches     2012-12-05  80  do {									\
bde98197 Joe Perches     2012-12-05  81  	if (0)								\
0b456f04 Andy Shevchenko 2014-08-27 @82  		pr_debug(fmt, ##__VA_ARGS__);				\
bde98197 Joe Perches     2012-12-05  83  } while (0)
f96637be Joe Perches     2013-05-04  84  #endif
^1da177e Linus Torvalds  2005-04-16  85  

:::::: The code at line 82 was first introduced by commit
:::::: 0b456f04bcdf5b1151136adaada158bfc26f1be7 cifs: convert printk(LEVEL...) to pr_<level>

:::::: TO: Andy Shevchenko <andriy.shevchenko@linux.intel.com>
:::::: CC: Steve French <steve.french@primarydata.com>

---
0-DAY kernel test infrastructure                Open Source Technology Center
https://lists.01.org/pipermail/kbuild-all                   Intel Corporation
kbuild test robot June 2, 2018, 7:15 a.m. | #2
Hi Long,

Thank you for the patch! Perhaps something to improve:

[auto build test WARNING on v4.17-rc6]
[cannot apply to cifs/for-next next-20180601]
[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/Long-Li/CIFS-Add-direct-I-O-support/20180602-130240
config: i386-randconfig-x008-201821 (attached as .config)
compiler: gcc-7 (Debian 7.3.0-16) 7.3.0
reproduce:
        # save the attached .config to linux build tree
        make ARCH=i386 

All warnings (new ones prefixed by >>):

   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//cifs/file.c:24:
   fs//cifs/file.c: In function 'cifs_direct_readv':
   include/linux/kern_levels.h:5:18: warning: format '%lu' expects argument of type 'long unsigned int', but argument 5 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:410:12: note: in expansion of macro 'KERN_DEBUG'
     no_printk(KERN_DEBUG pr_fmt(fmt), ##__VA_ARGS__)
               ^~~~~~~~~~
   fs//cifs/cifs_debug.h:54:3: note: in expansion of macro 'pr_debug_once'
      pr_debug_ ## ratefunc("%s: "   \
      ^~~~~~~~~
   fs//cifs/cifs_debug.h:67:3: note: in expansion of macro 'cifs_dbg_func'
      cifs_dbg_func(once,   \
      ^~~~~~~~~~~~~
>> fs//cifs/file.c:3346:4: note: in expansion of macro 'cifs_dbg'
       cifs_dbg(VFS,
       ^~~~~~~~
   fs//cifs/file.c:3348:20: note: format string is defined here
        " iov_offset %lu count %lu\n",
                     ~~^
                     %u
   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//cifs/file.c:24:
   include/linux/kern_levels.h:5:18: warning: format '%lu' expects argument of type 'long unsigned int', but argument 6 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:410:12: note: in expansion of macro 'KERN_DEBUG'
     no_printk(KERN_DEBUG pr_fmt(fmt), ##__VA_ARGS__)
               ^~~~~~~~~~
   fs//cifs/cifs_debug.h:54:3: note: in expansion of macro 'pr_debug_once'
      pr_debug_ ## ratefunc("%s: "   \
      ^~~~~~~~~
   fs//cifs/cifs_debug.h:67:3: note: in expansion of macro 'cifs_dbg_func'
      cifs_dbg_func(once,   \
      ^~~~~~~~~~~~~
>> fs//cifs/file.c:3346:4: note: in expansion of macro 'cifs_dbg'
       cifs_dbg(VFS,
       ^~~~~~~~
   fs//cifs/file.c:3348:30: note: format string is defined here
        " iov_offset %lu count %lu\n",
                               ~~^
                               %u
   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//cifs/file.c:24:
   include/linux/kern_levels.h:5:18: warning: format '%lu' expects argument of type 'long unsigned int', but argument 4 has type 'size_t {aka unsigned int}' [-Wformat=]
    #define KERN_SOH "\001"  /* ASCII Start Of Header */
                     ^
   include/linux/printk.h:357:10: note: in definition of macro 'printk_once'
      printk(fmt, ##__VA_ARGS__);   \
             ^~~
   include/linux/kern_levels.h:11:18: note: in expansion of macro 'KERN_SOH'
    #define KERN_ERR KERN_SOH "3" /* error conditions */
                     ^~~~~~~~
   include/linux/printk.h:386:14: note: in expansion of macro 'KERN_ERR'
     printk_once(KERN_ERR pr_fmt(fmt), ##__VA_ARGS__)
                 ^~~~~~~~
   fs//cifs/cifs_debug.h:57:3: note: in expansion of macro 'pr_err_once'
      pr_err_ ## ratefunc("CIFS VFS: "  \
      ^~~~~~~
   fs//cifs/cifs_debug.h:67:3: note: in expansion of macro 'cifs_dbg_func'
      cifs_dbg_func(once,   \
      ^~~~~~~~~~~~~
>> fs//cifs/file.c:3346:4: note: in expansion of macro 'cifs_dbg'
       cifs_dbg(VFS,
       ^~~~~~~~
   fs//cifs/file.c:3348:20: note: format string is defined here
        " iov_offset %lu count %lu\n",
                     ~~^
                     %u
   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//cifs/file.c:24:
   include/linux/kern_levels.h:5:18: warning: format '%lu' expects argument of type 'long unsigned int', but argument 5 has type 'size_t {aka unsigned int}' [-Wformat=]
    #define KERN_SOH "\001"  /* ASCII Start Of Header */
                     ^
   include/linux/printk.h:357:10: note: in definition of macro 'printk_once'
      printk(fmt, ##__VA_ARGS__);   \
             ^~~
   include/linux/kern_levels.h:11:18: note: in expansion of macro 'KERN_SOH'
    #define KERN_ERR KERN_SOH "3" /* error conditions */
                     ^~~~~~~~
   include/linux/printk.h:386:14: note: in expansion of macro 'KERN_ERR'
     printk_once(KERN_ERR pr_fmt(fmt), ##__VA_ARGS__)
                 ^~~~~~~~
   fs//cifs/cifs_debug.h:57:3: note: in expansion of macro 'pr_err_once'
      pr_err_ ## ratefunc("CIFS VFS: "  \
      ^~~~~~~
   fs//cifs/cifs_debug.h:67:3: note: in expansion of macro 'cifs_dbg_func'
      cifs_dbg_func(once,   \
      ^~~~~~~~~~~~~
>> fs//cifs/file.c:3346:4: note: in expansion of macro 'cifs_dbg'
       cifs_dbg(VFS,
       ^~~~~~~~
   fs//cifs/file.c:3348:30: note: format string is defined here
        " iov_offset %lu count %lu\n",
                               ~~^
                               %u
   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//cifs/file.c:24:
   include/linux/kern_levels.h:5:18: warning: format '%lu' expects argument of type 'long unsigned int', but argument 4 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:410:12: note: in expansion of macro 'KERN_DEBUG'
     no_printk(KERN_DEBUG pr_fmt(fmt), ##__VA_ARGS__)
               ^~~~~~~~~~
   fs//cifs/cifs_debug.h:60:3: note: in expansion of macro 'pr_debug_once'
      pr_debug_ ## ratefunc(fmt, ##__VA_ARGS__); \
      ^~~~~~~~~
   fs//cifs/cifs_debug.h:67:3: note: in expansion of macro 'cifs_dbg_func'
      cifs_dbg_func(once,   \
      ^~~~~~~~~~~~~
>> fs//cifs/file.c:3346:4: note: in expansion of macro 'cifs_dbg'
       cifs_dbg(VFS,
       ^~~~~~~~
   fs//cifs/file.c:3348:20: note: format string is defined here
        " iov_offset %lu count %lu\n",
                     ~~^
                     %u
   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//cifs/file.c:24:
   include/linux/kern_levels.h:5:18: warning: format '%lu' expects argument of type 'long unsigned int', but argument 5 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:410:12: note: in expansion of macro 'KERN_DEBUG'
     no_printk(KERN_DEBUG pr_fmt(fmt), ##__VA_ARGS__)
               ^~~~~~~~~~
   fs//cifs/cifs_debug.h:60:3: note: in expansion of macro 'pr_debug_once'
      pr_debug_ ## ratefunc(fmt, ##__VA_ARGS__); \
      ^~~~~~~~~
   fs//cifs/cifs_debug.h:67:3: note: in expansion of macro 'cifs_dbg_func'
      cifs_dbg_func(once,   \
      ^~~~~~~~~~~~~
>> fs//cifs/file.c:3346:4: note: in expansion of macro 'cifs_dbg'
       cifs_dbg(VFS,
       ^~~~~~~~
   fs//cifs/file.c:3348:30: note: format string is defined here
        " iov_offset %lu count %lu\n",
                               ~~^
                               %u
   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//cifs/file.c:24:
   include/linux/kern_levels.h:5:18: warning: format '%lu' expects argument of type 'long unsigned int', but argument 5 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:474:12: note: in expansion of macro 'KERN_DEBUG'
     no_printk(KERN_DEBUG pr_fmt(fmt), ##__VA_ARGS__)
               ^~~~~~~~~~
   fs//cifs/cifs_debug.h:54:3: note: in expansion of macro 'pr_debug_ratelimited'
      pr_debug_ ## ratefunc("%s: "   \
      ^~~~~~~~~
   fs//cifs/cifs_debug.h:70:3: note: in expansion of macro 'cifs_dbg_func'
      cifs_dbg_func(ratelimited,  \
      ^~~~~~~~~~~~~
>> fs//cifs/file.c:3346:4: note: in expansion of macro 'cifs_dbg'
       cifs_dbg(VFS,
       ^~~~~~~~
   fs//cifs/file.c:3348:20: note: format string is defined here
        " iov_offset %lu count %lu\n",
                     ~~^
                     %u
   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//cifs/file.c:24:
   include/linux/kern_levels.h:5:18: warning: format '%lu' expects argument of type 'long unsigned int', but argument 6 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:474:12: note: in expansion of macro 'KERN_DEBUG'
     no_printk(KERN_DEBUG pr_fmt(fmt), ##__VA_ARGS__)
               ^~~~~~~~~~
   fs//cifs/cifs_debug.h:54:3: note: in expansion of macro 'pr_debug_ratelimited'
      pr_debug_ ## ratefunc("%s: "   \
      ^~~~~~~~~
   fs//cifs/cifs_debug.h:70:3: note: in expansion of macro 'cifs_dbg_func'
      cifs_dbg_func(ratelimited,  \
      ^~~~~~~~~~~~~
>> fs//cifs/file.c:3346:4: note: in expansion of macro 'cifs_dbg'
       cifs_dbg(VFS,
       ^~~~~~~~
   fs//cifs/file.c:3348:30: note: format string is defined here
        " iov_offset %lu count %lu\n",
                               ~~^
                               %u
   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//cifs/file.c:24:
   include/linux/kern_levels.h:5:18: warning: format '%lu' expects argument of type 'long unsigned int', but argument 4 has type 'size_t {aka unsigned int}' [-Wformat=]
    #define KERN_SOH "\001"  /* ASCII Start Of Header */
                     ^
   include/linux/printk.h:425:10: note: in definition of macro 'printk_ratelimited'
      printk(fmt, ##__VA_ARGS__);    \
             ^~~
   include/linux/kern_levels.h:11:18: note: in expansion of macro 'KERN_SOH'
    #define KERN_ERR KERN_SOH "3" /* error conditions */
                     ^~~~~~~~
   include/linux/printk.h:439:21: note: in expansion of macro 'KERN_ERR'
     printk_ratelimited(KERN_ERR pr_fmt(fmt), ##__VA_ARGS__)
                        ^~~~~~~~
   fs//cifs/cifs_debug.h:57:3: note: in expansion of macro 'pr_err_ratelimited'
      pr_err_ ## ratefunc("CIFS VFS: "  \
      ^~~~~~~
   fs//cifs/cifs_debug.h:70:3: note: in expansion of macro 'cifs_dbg_func'
      cifs_dbg_func(ratelimited,  \
      ^~~~~~~~~~~~~
>> fs//cifs/file.c:3346:4: note: in expansion of macro 'cifs_dbg'
       cifs_dbg(VFS,
       ^~~~~~~~
   fs//cifs/file.c:3348:20: note: format string is defined here
        " iov_offset %lu count %lu\n",
                     ~~^
                     %u
   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//cifs/file.c:24:
   include/linux/kern_levels.h:5:18: warning: format '%lu' expects argument of type 'long unsigned int', but argument 5 has type 'size_t {aka unsigned int}' [-Wformat=]
    #define KERN_SOH "\001"  /* ASCII Start Of Header */
                     ^
   include/linux/printk.h:425:10: note: in definition of macro 'printk_ratelimited'
      printk(fmt, ##__VA_ARGS__);    \
             ^~~
   include/linux/kern_levels.h:11:18: note: in expansion of macro 'KERN_SOH'
    #define KERN_ERR KERN_SOH "3" /* error conditions */
                     ^~~~~~~~
   include/linux/printk.h:439:21: note: in expansion of macro 'KERN_ERR'
     printk_ratelimited(KERN_ERR pr_fmt(fmt), ##__VA_ARGS__)
                        ^~~~~~~~
   fs//cifs/cifs_debug.h:57:3: note: in expansion of macro 'pr_err_ratelimited'
      pr_err_ ## ratefunc("CIFS VFS: "  \
      ^~~~~~~
   fs//cifs/cifs_debug.h:70:3: note: in expansion of macro 'cifs_dbg_func'
      cifs_dbg_func(ratelimited,  \
      ^~~~~~~~~~~~~
>> fs//cifs/file.c:3346:4: note: in expansion of macro 'cifs_dbg'
       cifs_dbg(VFS,
       ^~~~~~~~
   fs//cifs/file.c:3348:30: note: format string is defined here
        " iov_offset %lu count %lu\n",
                               ~~^
                               %u
   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//cifs/file.c:24:
   include/linux/kern_levels.h:5:18: warning: format '%lu' expects argument of type 'long unsigned int', but argument 4 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:474:12: note: in expansion of macro 'KERN_DEBUG'
     no_printk(KERN_DEBUG pr_fmt(fmt), ##__VA_ARGS__)
               ^~~~~~~~~~
   fs//cifs/cifs_debug.h:60:3: note: in expansion of macro 'pr_debug_ratelimited'
      pr_debug_ ## ratefunc(fmt, ##__VA_ARGS__); \
      ^~~~~~~~~
   fs//cifs/cifs_debug.h:70:3: note: in expansion of macro 'cifs_dbg_func'
      cifs_dbg_func(ratelimited,  \
      ^~~~~~~~~~~~~
>> fs//cifs/file.c:3346:4: note: in expansion of macro 'cifs_dbg'
       cifs_dbg(VFS,
       ^~~~~~~~
   fs//cifs/file.c:3348:20: note: format string is defined here
        " iov_offset %lu count %lu\n",
                     ~~^
                     %u
   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//cifs/file.c:24:
   include/linux/kern_levels.h:5:18: warning: format '%lu' expects argument of type 'long unsigned int', but argument 5 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:474:12: note: in expansion of macro 'KERN_DEBUG'
     no_printk(KERN_DEBUG pr_fmt(fmt), ##__VA_ARGS__)
               ^~~~~~~~~~
   fs//cifs/cifs_debug.h:60:3: note: in expansion of macro 'pr_debug_ratelimited'
      pr_debug_ ## ratefunc(fmt, ##__VA_ARGS__); \
      ^~~~~~~~~
   fs//cifs/cifs_debug.h:70:3: note: in expansion of macro 'cifs_dbg_func'
      cifs_dbg_func(ratelimited,  \
      ^~~~~~~~~~~~~
>> fs//cifs/file.c:3346:4: note: in expansion of macro 'cifs_dbg'
       cifs_dbg(VFS,
       ^~~~~~~~
   fs//cifs/file.c:3348:30: note: format string is defined here
        " iov_offset %lu count %lu\n",
                               ~~^
                               %u

vim +/cifs_dbg +3346 fs//cifs/file.c

  3290	
  3291	ssize_t cifs_direct_readv(struct kiocb *iocb, struct iov_iter *to)
  3292	{
  3293		size_t len, cur_len, start;
  3294		unsigned int npages, rsize, credits;
  3295		struct file *file;
  3296		struct cifs_sb_info *cifs_sb;
  3297		struct cifsFileInfo *cfile;
  3298		struct cifs_tcon *tcon;
  3299		struct page **pagevec;
  3300		ssize_t rc, total_read = 0;
  3301		struct TCP_Server_Info *server;
  3302		loff_t offset = iocb->ki_pos;
  3303		pid_t pid;
  3304		struct cifs_readdata *rdata;
  3305	
  3306		/*
  3307		 * iov_iter_get_pages_alloc() doesn't work with ITER_KVEC,
  3308		 * fall back to data copy read path
  3309		 */
  3310		if (to->type & ITER_KVEC) {
  3311			cifs_dbg(FYI, "use non-direct cifs_user_readv for kvec I/O\n");
  3312			return cifs_user_readv(iocb, to);
  3313		}
  3314	
  3315		len = iov_iter_count(to);
  3316		if (!len)
  3317			return 0;
  3318	
  3319		file = iocb->ki_filp;
  3320		cifs_sb = CIFS_FILE_SB(file);
  3321		cfile = file->private_data;
  3322		tcon = tlink_tcon(cfile->tlink);
  3323		server = tcon->ses->server;
  3324	
  3325		if (!server->ops->async_readv)
  3326			return -ENOSYS;
  3327	
  3328		if (cifs_sb->mnt_cifs_flags & CIFS_MOUNT_RWPIDFORWARD)
  3329			pid = cfile->pid;
  3330		else
  3331			pid = current->tgid;
  3332	
  3333		if ((file->f_flags & O_ACCMODE) == O_WRONLY)
  3334			cifs_dbg(FYI, "attempting read on write only file instance\n");
  3335	
  3336		do {
  3337			rc = server->ops->wait_mtu_credits(server, cifs_sb->rsize,
  3338						&rsize, &credits);
  3339			if (rc)
  3340				break;
  3341	
  3342			cur_len = min_t(const size_t, len, rsize);
  3343	
  3344			rc = iov_iter_get_pages_alloc(to, &pagevec, cur_len, &start);
  3345			if (rc < 0) {
> 3346				cifs_dbg(VFS,
  3347					"couldn't get user pages (rc=%zd) iter type %d"
  3348					" iov_offset %lu count %lu\n",
  3349					rc, to->type, to->iov_offset, to->count);
  3350				dump_stack();
  3351				break;
  3352			}
  3353	
  3354			rdata = cifs_readdata_direct_alloc(
  3355					pagevec, cifs_direct_readv_complete);
  3356			if (!rdata) {
  3357				add_credits_and_wake_if(server, credits, 0);
  3358				rc = -ENOMEM;
  3359				break;
  3360			}
  3361	
  3362			npages = (rc + start + PAGE_SIZE-1) / PAGE_SIZE;
  3363			rdata->nr_pages = npages;
  3364			rdata->page_offset = start;
  3365			rdata->pagesz = PAGE_SIZE;
  3366			rdata->tailsz = npages > 1 ?
  3367					rc-(PAGE_SIZE-start)-(npages-2)*PAGE_SIZE :
  3368					rc;
  3369			cur_len = rc;
  3370	
  3371			rdata->cfile = cifsFileInfo_get(cfile);
  3372			rdata->offset = offset;
  3373			rdata->bytes = rc;
  3374			rdata->pid = pid;
  3375			rdata->read_into_pages = cifs_uncached_read_into_pages;
  3376			rdata->copy_into_pages = cifs_uncached_copy_into_pages;
  3377			rdata->credits = credits;
  3378	
  3379			rc = 0;
  3380			if (rdata->cfile->invalidHandle)
  3381				rc = cifs_reopen_file(rdata->cfile, true);
  3382	
  3383			if (!rc)
  3384				rc = server->ops->async_readv(rdata);
  3385	
  3386			if (rc) {
  3387				add_credits_and_wake_if(server, rdata->credits, 0);
  3388				kref_put(&rdata->refcount,
  3389					 cifs_direct_readdata_release);
  3390				if (rc == -EAGAIN)
  3391					continue;
  3392				break;
  3393			}
  3394	
  3395			wait_for_completion(&rdata->done);
  3396			rc = rdata->result;
  3397			if (rc) {
  3398				kref_put(
  3399					&rdata->refcount,
  3400					cifs_direct_readdata_release);
  3401				if (rc == -EAGAIN)
  3402					continue;
  3403				break;
  3404			}
  3405	
  3406			total_read += rdata->got_bytes;
  3407			kref_put(&rdata->refcount, cifs_direct_readdata_release);
  3408	
  3409			iov_iter_advance(to, cur_len);
  3410			len -= cur_len;
  3411			offset += cur_len;
  3412		} while (len);
  3413	
  3414		iocb->ki_pos += total_read;
  3415	
  3416		return total_read;
  3417	}
  3418	

---
0-DAY kernel test infrastructure                Open Source Technology Center
https://lists.01.org/pipermail/kbuild-all                   Intel Corporation
Tom Talpey June 24, 2018, 2:39 a.m. | #3
On 5/30/2018 3:48 PM, Long Li wrote:
> From: Long Li <longli@microsoft.com>
> 
> Implement the function for direct I/O read. It doesn't support AIO, which
> will be implemented in a follow up patch.
> 
> Signed-off-by: Long Li <longli@microsoft.com>
> ---
>   fs/cifs/cifsfs.h |   1 +
>   fs/cifs/file.c   | 149 +++++++++++++++++++++++++++++++++++++++++++++++++++++++
>   2 files changed, 150 insertions(+)
> 
> diff --git a/fs/cifs/cifsfs.h b/fs/cifs/cifsfs.h
> index 5f02318..7fba9aa 100644
> --- a/fs/cifs/cifsfs.h
> +++ b/fs/cifs/cifsfs.h
> @@ -102,6 +102,7 @@ extern int cifs_open(struct inode *inode, struct file *file);
>   extern int cifs_close(struct inode *inode, struct file *file);
>   extern int cifs_closedir(struct inode *inode, struct file *file);
>   extern ssize_t cifs_user_readv(struct kiocb *iocb, struct iov_iter *to);
> +extern ssize_t cifs_direct_readv(struct kiocb *iocb, struct iov_iter *to);
>   extern ssize_t cifs_strict_readv(struct kiocb *iocb, struct iov_iter *to);
>   extern ssize_t cifs_user_writev(struct kiocb *iocb, struct iov_iter *from);
>   extern ssize_t cifs_strict_writev(struct kiocb *iocb, struct iov_iter *from);
> diff --git a/fs/cifs/file.c b/fs/cifs/file.c
> index 87eece6..e6e6f24 100644
> --- a/fs/cifs/file.c
> +++ b/fs/cifs/file.c
> @@ -2955,6 +2955,18 @@ cifs_read_allocate_pages(struct cifs_readdata *rdata, unsigned int nr_pages)
>   	return rc;
>   }
>   
> +static void cifs_direct_readdata_release(struct kref *refcount)
> +{
> +	struct cifs_readdata *rdata = container_of(refcount,
> +					struct cifs_readdata, refcount);
> +	unsigned int i;
> +
> +	for (i = 0; i < rdata->nr_pages; i++)
> +		put_page(rdata->pages[i]);
> +
> +	cifs_readdata_release(refcount);
> +}
> +
>   static void
>   cifs_uncached_readdata_release(struct kref *refcount)
>   {
> @@ -3267,6 +3279,143 @@ collect_uncached_read_data(struct cifs_aio_ctx *ctx)
>   		complete(&ctx->done);
>   }
>   
> +static void cifs_direct_readv_complete(struct work_struct *work)
> +{
> +	struct cifs_readdata *rdata =
> +		container_of(work, struct cifs_readdata, work);
> +
> +	complete(&rdata->done);
> +	kref_put(&rdata->refcount, cifs_direct_readdata_release);
> +}
> +
> +ssize_t cifs_direct_readv(struct kiocb *iocb, struct iov_iter *to)
> +{
> +	size_t len, cur_len, start;
> +	unsigned int npages, rsize, credits;
> +	struct file *file;
> +	struct cifs_sb_info *cifs_sb;
> +	struct cifsFileInfo *cfile;
> +	struct cifs_tcon *tcon;
> +	struct page **pagevec;
> +	ssize_t rc, total_read = 0;
> +	struct TCP_Server_Info *server;
> +	loff_t offset = iocb->ki_pos;
> +	pid_t pid;
> +	struct cifs_readdata *rdata;
> +
> +	/*
> +	 * iov_iter_get_pages_alloc() doesn't work with ITER_KVEC,
> +	 * fall back to data copy read path
> +	 */
> +	if (to->type & ITER_KVEC) {
> +		cifs_dbg(FYI, "use non-direct cifs_user_readv for kvec I/O\n");
> +		return cifs_user_readv(iocb, to);
> +	}
> +
> +	len = iov_iter_count(to);
> +	if (!len)
> +		return 0;
> +
> +	file = iocb->ki_filp;
> +	cifs_sb = CIFS_FILE_SB(file);
> +	cfile = file->private_data;
> +	tcon = tlink_tcon(cfile->tlink);
> +	server = tcon->ses->server;
> +
> +	if (!server->ops->async_readv)
> +		return -ENOSYS;
> +
> +	if (cifs_sb->mnt_cifs_flags & CIFS_MOUNT_RWPIDFORWARD)
> +		pid = cfile->pid;
> +	else
> +		pid = current->tgid;
> +
> +	if ((file->f_flags & O_ACCMODE) == O_WRONLY)
> +		cifs_dbg(FYI, "attempting read on write only file instance\n");

Confusing. Maybe "attempting read on write-only filehandle"?

> +
> +	do {
> +		rc = server->ops->wait_mtu_credits(server, cifs_sb->rsize,
> +					&rsize, &credits);
> +		if (rc)
> +			break;
> +
> +		cur_len = min_t(const size_t, len, rsize);
> +
> +		rc = iov_iter_get_pages_alloc(to, &pagevec, cur_len, &start);
> +		if (rc < 0) {
> +			cifs_dbg(VFS,
> +				"couldn't get user pages (rc=%zd) iter type %d"
> +				" iov_offset %lu count %lu\n",
> +				rc, to->type, to->iov_offset, to->count);
> +			dump_stack();
> +			break;
> +		}
> +
> +		rdata = cifs_readdata_direct_alloc(
> +				pagevec, cifs_direct_readv_complete);
> +		if (!rdata) {
> +			add_credits_and_wake_if(server, credits, 0);
> +			rc = -ENOMEM;
> +			break;
> +		}
> +
> +		npages = (rc + start + PAGE_SIZE-1) / PAGE_SIZE;
> +		rdata->nr_pages = npages;
> +		rdata->page_offset = start;
> +		rdata->pagesz = PAGE_SIZE;
> +		rdata->tailsz = npages > 1 ?
> +				rc-(PAGE_SIZE-start)-(npages-2)*PAGE_SIZE :
> +				rc;

This expression makes my head hurt. Surely it can be simplified, or
expressed in a clearer way.

> +		cur_len = rc;
> +
> +		rdata->cfile = cifsFileInfo_get(cfile);
> +		rdata->offset = offset;
> +		rdata->bytes = rc;
> +		rdata->pid = pid;
> +		rdata->read_into_pages = cifs_uncached_read_into_pages;
> +		rdata->copy_into_pages = cifs_uncached_copy_into_pages;
> +		rdata->credits = credits;
> +
> +		rc = 0;
> +		if (rdata->cfile->invalidHandle)
> +			rc = cifs_reopen_file(rdata->cfile, true);
> +
> +		if (!rc)
> +			rc = server->ops->async_readv(rdata);
> +
> +		if (rc) {

This whole rc thing is messy. Initializing to zero, setting only in
one case, then testing the result, then setting it again, is twisted.
I actually think a goto or two would read much more clearly.

> +			add_credits_and_wake_if(server, rdata->credits, 0);
> +			kref_put(&rdata->refcount,
> +				 cifs_direct_readdata_release);
> +			if (rc == -EAGAIN)
> +				continue;
> +			break;

It's worth a comment here that this either breaks or continues the
entire do {} while (); and btw when it breaks it does *not* return "rc".
Again, maybe a goto instead of a break?

> +		}
> +
> +		wait_for_completion(&rdata->done);
> +		rc = rdata->result;
> +		if (rc) {
> +			kref_put(
> +				&rdata->refcount,
> +				cifs_direct_readdata_release);
> +			if (rc == -EAGAIN)
> +				continue;
> +			break;

Ditto.

> +		}
> +
> +		total_read += rdata->got_bytes;
> +		kref_put(&rdata->refcount, cifs_direct_readdata_release);
> +
> +		iov_iter_advance(to, cur_len);
> +		len -= cur_len;
> +		offset += cur_len;
> +	} while (len);
> +
> +	iocb->ki_pos += total_read;
> +
> +	return total_read;
> +}
> +
>   ssize_t cifs_user_readv(struct kiocb *iocb, struct iov_iter *to)
>   {
>   	struct file *file = iocb->ki_filp;
> 
--
To unsubscribe from this list: send the line "unsubscribe linux-cifs" in
the body of a message to majordomo@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Long Li June 26, 2018, 4:34 a.m. | #4
PiBTdWJqZWN0OiBSZTogW1BhdGNoIHYyIDEzLzE1XSBDSUZTOiBBZGQgc3VwcG9ydCBmb3IgZGly
ZWN0IEkvTyByZWFkDQo+IA0KPiANCj4gDQo+IE9uIDUvMzAvMjAxOCAzOjQ4IFBNLCBMb25nIExp
IHdyb3RlOg0KPiA+IEZyb206IExvbmcgTGkgPGxvbmdsaUBtaWNyb3NvZnQuY29tPg0KPiA+DQo+
ID4gSW1wbGVtZW50IHRoZSBmdW5jdGlvbiBmb3IgZGlyZWN0IEkvTyByZWFkLiBJdCBkb2Vzbid0
IHN1cHBvcnQgQUlPLA0KPiA+IHdoaWNoIHdpbGwgYmUgaW1wbGVtZW50ZWQgaW4gYSBmb2xsb3cg
dXAgcGF0Y2guDQo+ID4NCj4gPiBTaWduZWQtb2ZmLWJ5OiBMb25nIExpIDxsb25nbGlAbWljcm9z
b2Z0LmNvbT4NCj4gPiAtLS0NCj4gPiAgIGZzL2NpZnMvY2lmc2ZzLmggfCAgIDEgKw0KPiA+ICAg
ZnMvY2lmcy9maWxlLmMgICB8IDE0OQ0KPiArKysrKysrKysrKysrKysrKysrKysrKysrKysrKysr
KysrKysrKysrKysrKysrKysrKysrKysrDQo+ID4gICAyIGZpbGVzIGNoYW5nZWQsIDE1MCBpbnNl
cnRpb25zKCspDQo+ID4NCj4gPiBkaWZmIC0tZ2l0IGEvZnMvY2lmcy9jaWZzZnMuaCBiL2ZzL2Np
ZnMvY2lmc2ZzLmggaW5kZXgNCj4gPiA1ZjAyMzE4Li43ZmJhOWFhIDEwMDY0NA0KPiA+IC0tLSBh
L2ZzL2NpZnMvY2lmc2ZzLmgNCj4gPiArKysgYi9mcy9jaWZzL2NpZnNmcy5oDQo+ID4gQEAgLTEw
Miw2ICsxMDIsNyBAQCBleHRlcm4gaW50IGNpZnNfb3BlbihzdHJ1Y3QgaW5vZGUgKmlub2RlLCBz
dHJ1Y3QgZmlsZQ0KPiAqZmlsZSk7DQo+ID4gICBleHRlcm4gaW50IGNpZnNfY2xvc2Uoc3RydWN0
IGlub2RlICppbm9kZSwgc3RydWN0IGZpbGUgKmZpbGUpOw0KPiA+ICAgZXh0ZXJuIGludCBjaWZz
X2Nsb3NlZGlyKHN0cnVjdCBpbm9kZSAqaW5vZGUsIHN0cnVjdCBmaWxlICpmaWxlKTsNCj4gPiAg
IGV4dGVybiBzc2l6ZV90IGNpZnNfdXNlcl9yZWFkdihzdHJ1Y3Qga2lvY2IgKmlvY2IsIHN0cnVj
dCBpb3ZfaXRlcg0KPiA+ICp0byk7DQo+ID4gK2V4dGVybiBzc2l6ZV90IGNpZnNfZGlyZWN0X3Jl
YWR2KHN0cnVjdCBraW9jYiAqaW9jYiwgc3RydWN0IGlvdl9pdGVyDQo+ID4gKyp0byk7DQo+ID4g
ICBleHRlcm4gc3NpemVfdCBjaWZzX3N0cmljdF9yZWFkdihzdHJ1Y3Qga2lvY2IgKmlvY2IsIHN0
cnVjdCBpb3ZfaXRlciAqdG8pOw0KPiA+ICAgZXh0ZXJuIHNzaXplX3QgY2lmc191c2VyX3dyaXRl
dihzdHJ1Y3Qga2lvY2IgKmlvY2IsIHN0cnVjdCBpb3ZfaXRlciAqZnJvbSk7DQo+ID4gICBleHRl
cm4gc3NpemVfdCBjaWZzX3N0cmljdF93cml0ZXYoc3RydWN0IGtpb2NiICppb2NiLCBzdHJ1Y3QN
Cj4gPiBpb3ZfaXRlciAqZnJvbSk7IGRpZmYgLS1naXQgYS9mcy9jaWZzL2ZpbGUuYyBiL2ZzL2Np
ZnMvZmlsZS5jIGluZGV4DQo+ID4gODdlZWNlNi4uZTZlNmYyNCAxMDA2NDQNCj4gPiAtLS0gYS9m
cy9jaWZzL2ZpbGUuYw0KPiA+ICsrKyBiL2ZzL2NpZnMvZmlsZS5jDQo+ID4gQEAgLTI5NTUsNiAr
Mjk1NSwxOCBAQCBjaWZzX3JlYWRfYWxsb2NhdGVfcGFnZXMoc3RydWN0IGNpZnNfcmVhZGRhdGEN
Cj4gKnJkYXRhLCB1bnNpZ25lZCBpbnQgbnJfcGFnZXMpDQo+ID4gICAJcmV0dXJuIHJjOw0KPiA+
ICAgfQ0KPiA+DQo+ID4gK3N0YXRpYyB2b2lkIGNpZnNfZGlyZWN0X3JlYWRkYXRhX3JlbGVhc2Uo
c3RydWN0IGtyZWYgKnJlZmNvdW50KSB7DQo+ID4gKwlzdHJ1Y3QgY2lmc19yZWFkZGF0YSAqcmRh
dGEgPSBjb250YWluZXJfb2YocmVmY291bnQsDQo+ID4gKwkJCQkJc3RydWN0IGNpZnNfcmVhZGRh
dGEsIHJlZmNvdW50KTsNCj4gPiArCXVuc2lnbmVkIGludCBpOw0KPiA+ICsNCj4gPiArCWZvciAo
aSA9IDA7IGkgPCByZGF0YS0+bnJfcGFnZXM7IGkrKykNCj4gPiArCQlwdXRfcGFnZShyZGF0YS0+
cGFnZXNbaV0pOw0KPiA+ICsNCj4gPiArCWNpZnNfcmVhZGRhdGFfcmVsZWFzZShyZWZjb3VudCk7
DQo+ID4gK30NCj4gPiArDQo+ID4gICBzdGF0aWMgdm9pZA0KPiA+ICAgY2lmc191bmNhY2hlZF9y
ZWFkZGF0YV9yZWxlYXNlKHN0cnVjdCBrcmVmICpyZWZjb3VudCkNCj4gPiAgIHsNCj4gPiBAQCAt
MzI2Nyw2ICszMjc5LDE0MyBAQCBjb2xsZWN0X3VuY2FjaGVkX3JlYWRfZGF0YShzdHJ1Y3QNCj4g
Y2lmc19haW9fY3R4ICpjdHgpDQo+ID4gICAJCWNvbXBsZXRlKCZjdHgtPmRvbmUpOw0KPiA+ICAg
fQ0KPiA+DQo+ID4gK3N0YXRpYyB2b2lkIGNpZnNfZGlyZWN0X3JlYWR2X2NvbXBsZXRlKHN0cnVj
dCB3b3JrX3N0cnVjdCAqd29yaykgew0KPiA+ICsJc3RydWN0IGNpZnNfcmVhZGRhdGEgKnJkYXRh
ID0NCj4gPiArCQljb250YWluZXJfb2Yod29yaywgc3RydWN0IGNpZnNfcmVhZGRhdGEsIHdvcmsp
Ow0KPiA+ICsNCj4gPiArCWNvbXBsZXRlKCZyZGF0YS0+ZG9uZSk7DQo+ID4gKwlrcmVmX3B1dCgm
cmRhdGEtPnJlZmNvdW50LCBjaWZzX2RpcmVjdF9yZWFkZGF0YV9yZWxlYXNlKTsgfQ0KPiA+ICsN
Cj4gPiArc3NpemVfdCBjaWZzX2RpcmVjdF9yZWFkdihzdHJ1Y3Qga2lvY2IgKmlvY2IsIHN0cnVj
dCBpb3ZfaXRlciAqdG8pIHsNCj4gPiArCXNpemVfdCBsZW4sIGN1cl9sZW4sIHN0YXJ0Ow0KPiA+
ICsJdW5zaWduZWQgaW50IG5wYWdlcywgcnNpemUsIGNyZWRpdHM7DQo+ID4gKwlzdHJ1Y3QgZmls
ZSAqZmlsZTsNCj4gPiArCXN0cnVjdCBjaWZzX3NiX2luZm8gKmNpZnNfc2I7DQo+ID4gKwlzdHJ1
Y3QgY2lmc0ZpbGVJbmZvICpjZmlsZTsNCj4gPiArCXN0cnVjdCBjaWZzX3Rjb24gKnRjb247DQo+
ID4gKwlzdHJ1Y3QgcGFnZSAqKnBhZ2V2ZWM7DQo+ID4gKwlzc2l6ZV90IHJjLCB0b3RhbF9yZWFk
ID0gMDsNCj4gPiArCXN0cnVjdCBUQ1BfU2VydmVyX0luZm8gKnNlcnZlcjsNCj4gPiArCWxvZmZf
dCBvZmZzZXQgPSBpb2NiLT5raV9wb3M7DQo+ID4gKwlwaWRfdCBwaWQ7DQo+ID4gKwlzdHJ1Y3Qg
Y2lmc19yZWFkZGF0YSAqcmRhdGE7DQo+ID4gKw0KPiA+ICsJLyoNCj4gPiArCSAqIGlvdl9pdGVy
X2dldF9wYWdlc19hbGxvYygpIGRvZXNuJ3Qgd29yayB3aXRoIElURVJfS1ZFQywNCj4gPiArCSAq
IGZhbGwgYmFjayB0byBkYXRhIGNvcHkgcmVhZCBwYXRoDQo+ID4gKwkgKi8NCj4gPiArCWlmICh0
by0+dHlwZSAmIElURVJfS1ZFQykgew0KPiA+ICsJCWNpZnNfZGJnKEZZSSwgInVzZSBub24tZGly
ZWN0IGNpZnNfdXNlcl9yZWFkdiBmb3Iga3ZlYw0KPiBJL09cbiIpOw0KPiA+ICsJCXJldHVybiBj
aWZzX3VzZXJfcmVhZHYoaW9jYiwgdG8pOw0KPiA+ICsJfQ0KPiA+ICsNCj4gPiArCWxlbiA9IGlv
dl9pdGVyX2NvdW50KHRvKTsNCj4gPiArCWlmICghbGVuKQ0KPiA+ICsJCXJldHVybiAwOw0KPiA+
ICsNCj4gPiArCWZpbGUgPSBpb2NiLT5raV9maWxwOw0KPiA+ICsJY2lmc19zYiA9IENJRlNfRklM
RV9TQihmaWxlKTsNCj4gPiArCWNmaWxlID0gZmlsZS0+cHJpdmF0ZV9kYXRhOw0KPiA+ICsJdGNv
biA9IHRsaW5rX3Rjb24oY2ZpbGUtPnRsaW5rKTsNCj4gPiArCXNlcnZlciA9IHRjb24tPnNlcy0+
c2VydmVyOw0KPiA+ICsNCj4gPiArCWlmICghc2VydmVyLT5vcHMtPmFzeW5jX3JlYWR2KQ0KPiA+
ICsJCXJldHVybiAtRU5PU1lTOw0KPiA+ICsNCj4gPiArCWlmIChjaWZzX3NiLT5tbnRfY2lmc19m
bGFncyAmIENJRlNfTU9VTlRfUldQSURGT1JXQVJEKQ0KPiA+ICsJCXBpZCA9IGNmaWxlLT5waWQ7
DQo+ID4gKwllbHNlDQo+ID4gKwkJcGlkID0gY3VycmVudC0+dGdpZDsNCj4gPiArDQo+ID4gKwlp
ZiAoKGZpbGUtPmZfZmxhZ3MgJiBPX0FDQ01PREUpID09IE9fV1JPTkxZKQ0KPiA+ICsJCWNpZnNf
ZGJnKEZZSSwgImF0dGVtcHRpbmcgcmVhZCBvbiB3cml0ZSBvbmx5IGZpbGUgaW5zdGFuY2VcbiIp
Ow0KPiANCj4gQ29uZnVzaW5nLiBNYXliZSAiYXR0ZW1wdGluZyByZWFkIG9uIHdyaXRlLW9ubHkg
ZmlsZWhhbmRsZSI/DQo+IA0KPiA+ICsNCj4gPiArCWRvIHsNCj4gPiArCQlyYyA9IHNlcnZlci0+
b3BzLT53YWl0X210dV9jcmVkaXRzKHNlcnZlciwgY2lmc19zYi0+cnNpemUsDQo+ID4gKwkJCQkJ
JnJzaXplLCAmY3JlZGl0cyk7DQo+ID4gKwkJaWYgKHJjKQ0KPiA+ICsJCQlicmVhazsNCj4gPiAr
DQo+ID4gKwkJY3VyX2xlbiA9IG1pbl90KGNvbnN0IHNpemVfdCwgbGVuLCByc2l6ZSk7DQo+ID4g
Kw0KPiA+ICsJCXJjID0gaW92X2l0ZXJfZ2V0X3BhZ2VzX2FsbG9jKHRvLCAmcGFnZXZlYywgY3Vy
X2xlbiwgJnN0YXJ0KTsNCj4gPiArCQlpZiAocmMgPCAwKSB7DQo+ID4gKwkJCWNpZnNfZGJnKFZG
UywNCj4gPiArCQkJCSJjb3VsZG4ndCBnZXQgdXNlciBwYWdlcyAocmM9JXpkKSBpdGVyDQo+IHR5
cGUgJWQiDQo+ID4gKwkJCQkiIGlvdl9vZmZzZXQgJWx1IGNvdW50ICVsdVxuIiwNCj4gPiArCQkJ
CXJjLCB0by0+dHlwZSwgdG8tPmlvdl9vZmZzZXQsIHRvLT5jb3VudCk7DQo+ID4gKwkJCWR1bXBf
c3RhY2soKTsNCj4gPiArCQkJYnJlYWs7DQo+ID4gKwkJfQ0KPiA+ICsNCj4gPiArCQlyZGF0YSA9
IGNpZnNfcmVhZGRhdGFfZGlyZWN0X2FsbG9jKA0KPiA+ICsJCQkJcGFnZXZlYywgY2lmc19kaXJl
Y3RfcmVhZHZfY29tcGxldGUpOw0KPiA+ICsJCWlmICghcmRhdGEpIHsNCj4gPiArCQkJYWRkX2Ny
ZWRpdHNfYW5kX3dha2VfaWYoc2VydmVyLCBjcmVkaXRzLCAwKTsNCj4gPiArCQkJcmMgPSAtRU5P
TUVNOw0KPiA+ICsJCQlicmVhazsNCj4gPiArCQl9DQo+ID4gKw0KPiA+ICsJCW5wYWdlcyA9IChy
YyArIHN0YXJ0ICsgUEFHRV9TSVpFLTEpIC8gUEFHRV9TSVpFOw0KPiA+ICsJCXJkYXRhLT5ucl9w
YWdlcyA9IG5wYWdlczsNCj4gPiArCQlyZGF0YS0+cGFnZV9vZmZzZXQgPSBzdGFydDsNCj4gPiAr
CQlyZGF0YS0+cGFnZXN6ID0gUEFHRV9TSVpFOw0KPiA+ICsJCXJkYXRhLT50YWlsc3ogPSBucGFn
ZXMgPiAxID8NCj4gPiArCQkJCXJjLShQQUdFX1NJWkUtc3RhcnQpLShucGFnZXMtMikqUEFHRV9T
SVpFIDoNCj4gPiArCQkJCXJjOw0KPiANCj4gVGhpcyBleHByZXNzaW9uIG1ha2VzIG15IGhlYWQg
aHVydC4gU3VyZWx5IGl0IGNhbiBiZSBzaW1wbGlmaWVkLCBvciBleHByZXNzZWQNCj4gaW4gYSBj
bGVhcmVyIHdheS4NCj4gDQo+ID4gKwkJY3VyX2xlbiA9IHJjOw0KPiA+ICsNCj4gPiArCQlyZGF0
YS0+Y2ZpbGUgPSBjaWZzRmlsZUluZm9fZ2V0KGNmaWxlKTsNCj4gPiArCQlyZGF0YS0+b2Zmc2V0
ID0gb2Zmc2V0Ow0KPiA+ICsJCXJkYXRhLT5ieXRlcyA9IHJjOw0KPiA+ICsJCXJkYXRhLT5waWQg
PSBwaWQ7DQo+ID4gKwkJcmRhdGEtPnJlYWRfaW50b19wYWdlcyA9IGNpZnNfdW5jYWNoZWRfcmVh
ZF9pbnRvX3BhZ2VzOw0KPiA+ICsJCXJkYXRhLT5jb3B5X2ludG9fcGFnZXMgPSBjaWZzX3VuY2Fj
aGVkX2NvcHlfaW50b19wYWdlczsNCj4gPiArCQlyZGF0YS0+Y3JlZGl0cyA9IGNyZWRpdHM7DQo+
ID4gKw0KPiA+ICsJCXJjID0gMDsNCj4gPiArCQlpZiAocmRhdGEtPmNmaWxlLT5pbnZhbGlkSGFu
ZGxlKQ0KPiA+ICsJCQlyYyA9IGNpZnNfcmVvcGVuX2ZpbGUocmRhdGEtPmNmaWxlLCB0cnVlKTsN
Cj4gPiArDQo+ID4gKwkJaWYgKCFyYykNCj4gPiArCQkJcmMgPSBzZXJ2ZXItPm9wcy0+YXN5bmNf
cmVhZHYocmRhdGEpOw0KPiA+ICsNCj4gPiArCQlpZiAocmMpIHsNCj4gDQo+IFRoaXMgd2hvbGUg
cmMgdGhpbmcgaXMgbWVzc3kuIEluaXRpYWxpemluZyB0byB6ZXJvLCBzZXR0aW5nIG9ubHkgaW4g
b25lIGNhc2UsIHRoZW4NCj4gdGVzdGluZyB0aGUgcmVzdWx0LCB0aGVuIHNldHRpbmcgaXQgYWdh
aW4sIGlzIHR3aXN0ZWQuDQo+IEkgYWN0dWFsbHkgdGhpbmsgYSBnb3RvIG9yIHR3byB3b3VsZCBy
ZWFkIG11Y2ggbW9yZSBjbGVhcmx5Lg0KPiANCj4gPiArCQkJYWRkX2NyZWRpdHNfYW5kX3dha2Vf
aWYoc2VydmVyLCByZGF0YS0+Y3JlZGl0cywgMCk7DQo+ID4gKwkJCWtyZWZfcHV0KCZyZGF0YS0+
cmVmY291bnQsDQo+ID4gKwkJCQkgY2lmc19kaXJlY3RfcmVhZGRhdGFfcmVsZWFzZSk7DQo+ID4g
KwkJCWlmIChyYyA9PSAtRUFHQUlOKQ0KPiA+ICsJCQkJY29udGludWU7DQo+ID4gKwkJCWJyZWFr
Ow0KPiANCj4gSXQncyB3b3J0aCBhIGNvbW1lbnQgaGVyZSB0aGF0IHRoaXMgZWl0aGVyIGJyZWFr
cyBvciBjb250aW51ZXMgdGhlIGVudGlyZSBkbyB7fQ0KPiB3aGlsZSAoKTsgYW5kIGJ0dyB3aGVu
IGl0IGJyZWFrcyBpdCBkb2VzICpub3QqIHJldHVybiAicmMiLg0KPiBBZ2FpbiwgbWF5YmUgYSBn
b3RvIGluc3RlYWQgb2YgYSBicmVhaz8NCj4gDQo+ID4gKwkJfQ0KPiA+ICsNCj4gPiArCQl3YWl0
X2Zvcl9jb21wbGV0aW9uKCZyZGF0YS0+ZG9uZSk7DQo+ID4gKwkJcmMgPSByZGF0YS0+cmVzdWx0
Ow0KPiA+ICsJCWlmIChyYykgew0KPiA+ICsJCQlrcmVmX3B1dCgNCj4gPiArCQkJCSZyZGF0YS0+
cmVmY291bnQsDQo+ID4gKwkJCQljaWZzX2RpcmVjdF9yZWFkZGF0YV9yZWxlYXNlKTsNCj4gPiAr
CQkJaWYgKHJjID09IC1FQUdBSU4pDQo+ID4gKwkJCQljb250aW51ZTsNCj4gPiArCQkJYnJlYWs7
DQo+IA0KPiBEaXR0by4NCg0KSSB3aWxsIHJlLXdvcmsgdGhpcyBwYXRjaC4NCg0KPiANCj4gPiAr
CQl9DQo+ID4gKw0KPiA+ICsJCXRvdGFsX3JlYWQgKz0gcmRhdGEtPmdvdF9ieXRlczsNCj4gPiAr
CQlrcmVmX3B1dCgmcmRhdGEtPnJlZmNvdW50LCBjaWZzX2RpcmVjdF9yZWFkZGF0YV9yZWxlYXNl
KTsNCj4gPiArDQo+ID4gKwkJaW92X2l0ZXJfYWR2YW5jZSh0bywgY3VyX2xlbik7DQo+ID4gKwkJ
bGVuIC09IGN1cl9sZW47DQo+ID4gKwkJb2Zmc2V0ICs9IGN1cl9sZW47DQo+ID4gKwl9IHdoaWxl
IChsZW4pOw0KPiA+ICsNCj4gPiArCWlvY2ItPmtpX3BvcyArPSB0b3RhbF9yZWFkOw0KPiA+ICsN
Cj4gPiArCXJldHVybiB0b3RhbF9yZWFkOw0KPiA+ICt9DQo+ID4gKw0KPiA+ICAgc3NpemVfdCBj
aWZzX3VzZXJfcmVhZHYoc3RydWN0IGtpb2NiICppb2NiLCBzdHJ1Y3QgaW92X2l0ZXIgKnRvKQ0K
PiA+ICAgew0KPiA+ICAgCXN0cnVjdCBmaWxlICpmaWxlID0gaW9jYi0+a2lfZmlscDsNCj4gPg0K
--
To unsubscribe from this list: send the line "unsubscribe linux-cifs" in
the body of a message to majordomo@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html

Patch

diff --git a/fs/cifs/cifsfs.h b/fs/cifs/cifsfs.h
index 5f02318..7fba9aa 100644
--- a/fs/cifs/cifsfs.h
+++ b/fs/cifs/cifsfs.h
@@ -102,6 +102,7 @@  extern int cifs_open(struct inode *inode, struct file *file);
 extern int cifs_close(struct inode *inode, struct file *file);
 extern int cifs_closedir(struct inode *inode, struct file *file);
 extern ssize_t cifs_user_readv(struct kiocb *iocb, struct iov_iter *to);
+extern ssize_t cifs_direct_readv(struct kiocb *iocb, struct iov_iter *to);
 extern ssize_t cifs_strict_readv(struct kiocb *iocb, struct iov_iter *to);
 extern ssize_t cifs_user_writev(struct kiocb *iocb, struct iov_iter *from);
 extern ssize_t cifs_strict_writev(struct kiocb *iocb, struct iov_iter *from);
diff --git a/fs/cifs/file.c b/fs/cifs/file.c
index 87eece6..e6e6f24 100644
--- a/fs/cifs/file.c
+++ b/fs/cifs/file.c
@@ -2955,6 +2955,18 @@  cifs_read_allocate_pages(struct cifs_readdata *rdata, unsigned int nr_pages)
 	return rc;
 }
 
+static void cifs_direct_readdata_release(struct kref *refcount)
+{
+	struct cifs_readdata *rdata = container_of(refcount,
+					struct cifs_readdata, refcount);
+	unsigned int i;
+
+	for (i = 0; i < rdata->nr_pages; i++)
+		put_page(rdata->pages[i]);
+
+	cifs_readdata_release(refcount);
+}
+
 static void
 cifs_uncached_readdata_release(struct kref *refcount)
 {
@@ -3267,6 +3279,143 @@  collect_uncached_read_data(struct cifs_aio_ctx *ctx)
 		complete(&ctx->done);
 }
 
+static void cifs_direct_readv_complete(struct work_struct *work)
+{
+	struct cifs_readdata *rdata =
+		container_of(work, struct cifs_readdata, work);
+
+	complete(&rdata->done);
+	kref_put(&rdata->refcount, cifs_direct_readdata_release);
+}
+
+ssize_t cifs_direct_readv(struct kiocb *iocb, struct iov_iter *to)
+{
+	size_t len, cur_len, start;
+	unsigned int npages, rsize, credits;
+	struct file *file;
+	struct cifs_sb_info *cifs_sb;
+	struct cifsFileInfo *cfile;
+	struct cifs_tcon *tcon;
+	struct page **pagevec;
+	ssize_t rc, total_read = 0;
+	struct TCP_Server_Info *server;
+	loff_t offset = iocb->ki_pos;
+	pid_t pid;
+	struct cifs_readdata *rdata;
+
+	/*
+	 * iov_iter_get_pages_alloc() doesn't work with ITER_KVEC,
+	 * fall back to data copy read path
+	 */
+	if (to->type & ITER_KVEC) {
+		cifs_dbg(FYI, "use non-direct cifs_user_readv for kvec I/O\n");
+		return cifs_user_readv(iocb, to);
+	}
+
+	len = iov_iter_count(to);
+	if (!len)
+		return 0;
+
+	file = iocb->ki_filp;
+	cifs_sb = CIFS_FILE_SB(file);
+	cfile = file->private_data;
+	tcon = tlink_tcon(cfile->tlink);
+	server = tcon->ses->server;
+
+	if (!server->ops->async_readv)
+		return -ENOSYS;
+
+	if (cifs_sb->mnt_cifs_flags & CIFS_MOUNT_RWPIDFORWARD)
+		pid = cfile->pid;
+	else
+		pid = current->tgid;
+
+	if ((file->f_flags & O_ACCMODE) == O_WRONLY)
+		cifs_dbg(FYI, "attempting read on write only file instance\n");
+
+	do {
+		rc = server->ops->wait_mtu_credits(server, cifs_sb->rsize,
+					&rsize, &credits);
+		if (rc)
+			break;
+
+		cur_len = min_t(const size_t, len, rsize);
+
+		rc = iov_iter_get_pages_alloc(to, &pagevec, cur_len, &start);
+		if (rc < 0) {
+			cifs_dbg(VFS,
+				"couldn't get user pages (rc=%zd) iter type %d"
+				" iov_offset %lu count %lu\n",
+				rc, to->type, to->iov_offset, to->count);
+			dump_stack();
+			break;
+		}
+
+		rdata = cifs_readdata_direct_alloc(
+				pagevec, cifs_direct_readv_complete);
+		if (!rdata) {
+			add_credits_and_wake_if(server, credits, 0);
+			rc = -ENOMEM;
+			break;
+		}
+
+		npages = (rc + start + PAGE_SIZE-1) / PAGE_SIZE;
+		rdata->nr_pages = npages;
+		rdata->page_offset = start;
+		rdata->pagesz = PAGE_SIZE;
+		rdata->tailsz = npages > 1 ?
+				rc-(PAGE_SIZE-start)-(npages-2)*PAGE_SIZE :
+				rc;
+		cur_len = rc;
+
+		rdata->cfile = cifsFileInfo_get(cfile);
+		rdata->offset = offset;
+		rdata->bytes = rc;
+		rdata->pid = pid;
+		rdata->read_into_pages = cifs_uncached_read_into_pages;
+		rdata->copy_into_pages = cifs_uncached_copy_into_pages;
+		rdata->credits = credits;
+
+		rc = 0;
+		if (rdata->cfile->invalidHandle)
+			rc = cifs_reopen_file(rdata->cfile, true);
+
+		if (!rc)
+			rc = server->ops->async_readv(rdata);
+
+		if (rc) {
+			add_credits_and_wake_if(server, rdata->credits, 0);
+			kref_put(&rdata->refcount,
+				 cifs_direct_readdata_release);
+			if (rc == -EAGAIN)
+				continue;
+			break;
+		}
+
+		wait_for_completion(&rdata->done);
+		rc = rdata->result;
+		if (rc) {
+			kref_put(
+				&rdata->refcount,
+				cifs_direct_readdata_release);
+			if (rc == -EAGAIN)
+				continue;
+			break;
+		}
+
+		total_read += rdata->got_bytes;
+		kref_put(&rdata->refcount, cifs_direct_readdata_release);
+
+		iov_iter_advance(to, cur_len);
+		len -= cur_len;
+		offset += cur_len;
+	} while (len);
+
+	iocb->ki_pos += total_read;
+
+	return total_read;
+}
+
 ssize_t cifs_user_readv(struct kiocb *iocb, struct iov_iter *to)
 {
 	struct file *file = iocb->ki_filp;