ext4: Log inode exhaustion to dmesg

Message ID 20171023120247.lsupeazdwwpaisek@gaztest-VM
State New
Headers show
Series
  • ext4: Log inode exhaustion to dmesg
Related show

Commit Message

Gazala Muhamed Oct. 23, 2017, 12:02 p.m.
Make a log in dmesg when file creation fails due to no free inodes.
The error code for both "out of disk space" and "out of inode" is the same.
This is misleading to the user. Logging the exact reason helps to find and
correct the issue from the users' side.

Fix bug 197335 - https://bugzilla.kernel.org/show_bug.cgi?id=197335

Signed-off-by: Team Athena <teamathena.nitc@gmail.com>
---
 fs/ext4/namei.c | 2 ++
 1 file changed, 2 insertions(+)

Comments

Theodore Ts'o Oct. 23, 2017, 12:04 p.m. | #1
Hi,

The Signed-off-by needs to contain your real name (sorry, no
pseudonyms or anonymous contributions.)  That's because it has a
formal legal meaning.  See Section 11: "Sign your work - the
Developer’s Certificate of Origin" of the Submitting Patches
docuementation:

https://www.kernel.org/doc/html/latest/process/submitting-patches.html

(Also, you should use ext4_warning() and not a bare printk).

						- Ted

On Mon, Oct 23, 2017 at 05:32:47PM +0530, Team Athena wrote:
> Make a log in dmesg when file creation fails due to no free inodes.
> The error code for both "out of disk space" and "out of inode" is the same.
> This is misleading to the user. Logging the exact reason helps to find and
> correct the issue from the users' side.
> 
> Fix bug 197335 - https://bugzilla.kernel.org/show_bug.cgi?id=197335
> 
> Signed-off-by: Team Athena <teamathena.nitc@gmail.com>
> ---
>  fs/ext4/namei.c | 2 ++
>  1 file changed, 2 insertions(+)
> 
> diff --git a/fs/ext4/namei.c b/fs/ext4/namei.c
> index c1cf020d..c3990d2d 100644
> --- a/fs/ext4/namei.c
> +++ b/fs/ext4/namei.c
> @@ -2463,6 +2463,8 @@ static int ext4_create(struct inode *dir, struct dentry *dentry, umode_t mode,
>  		ext4_journal_stop(handle);
>  	if (err == -ENOSPC && ext4_should_retry_alloc(dir->i_sb, &retries))
>  		goto retry;
> +	else if (err == -ENOSPC && printk_ratelimited())
> +		printk(pr_warning "ext4: No space on disk, inode usage full");
>  	return err;
>  }
>  
> -- 
> 2.11.0
>
kbuild test robot Oct. 23, 2017, 2:54 p.m. | #2
Hi Team,

[auto build test WARNING on ext4/dev]
[also build test WARNING on v4.14-rc6 next-20171018]
[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/Team-Athena/ext4-Log-inode-exhaustion-to-dmesg/20171023-222824
base:   https://git.kernel.org/pub/scm/linux/kernel/git/tytso/ext4.git dev
config: i386-randconfig-x009-201743 (attached as .config)
compiler: gcc-6 (Debian 6.2.0-3) 6.2.0 20160901
reproduce:
        # save the attached .config to linux build tree
        make ARCH=i386 

All warnings (new ones prefixed by >>):

   In file included from include/linux/linkage.h:4:0,
                    from include/linux/fs.h:4,
                    from fs/ext4/namei.c:27:
   fs/ext4/namei.c: In function 'ext4_create':
   include/linux/printk.h:422:3: error: too few arguments to function 'printk'
      printk(fmt, ##__VA_ARGS__);    \
      ^
   include/linux/compiler.h:156:30: note: in definition of macro '__trace_if'
     if (__builtin_constant_p(!!(cond)) ? !!(cond) :   \
                                 ^~~~
>> fs/ext4/namei.c:2466:7: note: in expansion of macro 'if'
     else if (err == -ENOSPC && printk_ratelimited())
          ^~
   fs/ext4/namei.c:2466:29: note: in expansion of macro 'printk_ratelimited'
     else if (err == -ENOSPC && printk_ratelimited())
                                ^~~~~~~~~~~~~~~~~~
   In file included from include/linux/kernel.h:13:0,
                    from include/linux/list.h:8,
                    from include/linux/wait.h:6,
                    from include/linux/wait_bit.h:7,
                    from include/linux/fs.h:5,
                    from fs/ext4/namei.c:27:
   include/linux/printk.h:172:5: note: declared here
    int printk(const char *fmt, ...);
        ^~~~~~
   In file included from include/linux/linkage.h:4:0,
                    from include/linux/fs.h:4,
                    from fs/ext4/namei.c:27:
   include/linux/printk.h:416:2: error: void value not ignored as it ought to be
    ({         \
    ~^~~~~~~~~~~
     static DEFINE_RATELIMIT_STATE(_rs,    \
     ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
              DEFAULT_RATELIMIT_INTERVAL, \
              ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
              DEFAULT_RATELIMIT_BURST);  \
              ~~~~~~~~~~~~~~~~~~~~~~~~~~~~
             \
             ~
     if (__ratelimit(&_rs))      \
     ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
      printk(fmt, ##__VA_ARGS__);    \
      ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
    })
    ~~
   include/linux/compiler.h:156:30: note: in definition of macro '__trace_if'
     if (__builtin_constant_p(!!(cond)) ? !!(cond) :   \
                                 ^~~~
>> fs/ext4/namei.c:2466:7: note: in expansion of macro 'if'
     else if (err == -ENOSPC && printk_ratelimited())
          ^~
   fs/ext4/namei.c:2466:29: note: in expansion of macro 'printk_ratelimited'
     else if (err == -ENOSPC && printk_ratelimited())
                                ^~~~~~~~~~~~~~~~~~
   include/linux/printk.h:422:3: error: too few arguments to function 'printk'
      printk(fmt, ##__VA_ARGS__);    \
      ^
   include/linux/compiler.h:156:42: note: in definition of macro '__trace_if'
     if (__builtin_constant_p(!!(cond)) ? !!(cond) :   \
                                             ^~~~
>> fs/ext4/namei.c:2466:7: note: in expansion of macro 'if'
     else if (err == -ENOSPC && printk_ratelimited())
          ^~
   fs/ext4/namei.c:2466:29: note: in expansion of macro 'printk_ratelimited'
     else if (err == -ENOSPC && printk_ratelimited())
                                ^~~~~~~~~~~~~~~~~~
   In file included from include/linux/kernel.h:13:0,
                    from include/linux/list.h:8,
                    from include/linux/wait.h:6,
                    from include/linux/wait_bit.h:7,
                    from include/linux/fs.h:5,
                    from fs/ext4/namei.c:27:
   include/linux/printk.h:172:5: note: declared here
    int printk(const char *fmt, ...);
        ^~~~~~
   In file included from include/linux/linkage.h:4:0,
                    from include/linux/fs.h:4,
                    from fs/ext4/namei.c:27:
   include/linux/printk.h:416:2: error: void value not ignored as it ought to be
    ({         \
    ~^~~~~~~~~~~
     static DEFINE_RATELIMIT_STATE(_rs,    \
     ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
              DEFAULT_RATELIMIT_INTERVAL, \
              ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
              DEFAULT_RATELIMIT_BURST);  \
              ~~~~~~~~~~~~~~~~~~~~~~~~~~~~
             \
             ~
     if (__ratelimit(&_rs))      \
     ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
      printk(fmt, ##__VA_ARGS__);    \
      ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
    })
    ~~
   include/linux/compiler.h:156:42: note: in definition of macro '__trace_if'
     if (__builtin_constant_p(!!(cond)) ? !!(cond) :   \
                                             ^~~~
>> fs/ext4/namei.c:2466:7: note: in expansion of macro 'if'
     else if (err == -ENOSPC && printk_ratelimited())
          ^~
   fs/ext4/namei.c:2466:29: note: in expansion of macro 'printk_ratelimited'
     else if (err == -ENOSPC && printk_ratelimited())
                                ^~~~~~~~~~~~~~~~~~
   include/linux/printk.h:422:3: error: too few arguments to function 'printk'
      printk(fmt, ##__VA_ARGS__);    \
      ^
   include/linux/compiler.h:167:16: note: in definition of macro '__trace_if'
      ______r = !!(cond);     \
                   ^~~~
>> fs/ext4/namei.c:2466:7: note: in expansion of macro 'if'
     else if (err == -ENOSPC && printk_ratelimited())
          ^~
   fs/ext4/namei.c:2466:29: note: in expansion of macro 'printk_ratelimited'
     else if (err == -ENOSPC && printk_ratelimited())
                                ^~~~~~~~~~~~~~~~~~
   In file included from include/linux/kernel.h:13:0,
                    from include/linux/list.h:8,
                    from include/linux/wait.h:6,
                    from include/linux/wait_bit.h:7,
                    from include/linux/fs.h:5,
                    from fs/ext4/namei.c:27:
   include/linux/printk.h:172:5: note: declared here
    int printk(const char *fmt, ...);
        ^~~~~~
   In file included from include/linux/linkage.h:4:0,
                    from include/linux/fs.h:4,
                    from fs/ext4/namei.c:27:
   include/linux/printk.h:416:2: error: void value not ignored as it ought to be
    ({         \
    ~^~~~~~~~~~~
     static DEFINE_RATELIMIT_STATE(_rs,    \
     ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
              DEFAULT_RATELIMIT_INTERVAL, \
              ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
              DEFAULT_RATELIMIT_BURST);  \
              ~~~~~~~~~~~~~~~~~~~~~~~~~~~~
             \
             ~
     if (__ratelimit(&_rs))      \
     ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
      printk(fmt, ##__VA_ARGS__);    \
      ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
    })
    ~~
   include/linux/compiler.h:167:16: note: in definition of macro '__trace_if'
      ______r = !!(cond);     \
                   ^~~~
>> fs/ext4/namei.c:2466:7: note: in expansion of macro 'if'
     else if (err == -ENOSPC && printk_ratelimited())
          ^~
   fs/ext4/namei.c:2466:29: note: in expansion of macro 'printk_ratelimited'
     else if (err == -ENOSPC && printk_ratelimited())
                                ^~~~~~~~~~~~~~~~~~
   fs/ext4/namei.c:2467:10: error: 'pr_warning' undeclared (first use in this function)
      printk(pr_warning "ext4: No space on disk, inode usage full");
             ^~~~~~~~~~
   fs/ext4/namei.c:2467:10: note: each undeclared identifier is reported only once for each function it appears in
   fs/ext4/namei.c:2467:21: error: expected ')' before string constant
      printk(pr_warning "ext4: No space on disk, inode usage full");
                        ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

vim +/if +2466 fs/ext4/namei.c

  2427	
  2428	/*
  2429	 * By the time this is called, we already have created
  2430	 * the directory cache entry for the new file, but it
  2431	 * is so far negative - it has no inode.
  2432	 *
  2433	 * If the create succeeds, we fill in the inode information
  2434	 * with d_instantiate().
  2435	 */
  2436	static int ext4_create(struct inode *dir, struct dentry *dentry, umode_t mode,
  2437			       bool excl)
  2438	{
  2439		handle_t *handle;
  2440		struct inode *inode;
  2441		int err, credits, retries = 0;
  2442	
  2443		err = dquot_initialize(dir);
  2444		if (err)
  2445			return err;
  2446	
  2447		credits = (EXT4_DATA_TRANS_BLOCKS(dir->i_sb) +
  2448			   EXT4_INDEX_EXTRA_TRANS_BLOCKS + 3);
  2449	retry:
  2450		inode = ext4_new_inode_start_handle(dir, mode, &dentry->d_name, 0,
  2451						    NULL, EXT4_HT_DIR, credits);
  2452		handle = ext4_journal_current_handle();
  2453		err = PTR_ERR(inode);
  2454		if (!IS_ERR(inode)) {
  2455			inode->i_op = &ext4_file_inode_operations;
  2456			inode->i_fop = &ext4_file_operations;
  2457			ext4_set_aops(inode);
  2458			err = ext4_add_nondir(handle, dentry, inode);
  2459			if (!err && IS_DIRSYNC(dir))
  2460				ext4_handle_sync(handle);
  2461		}
  2462		if (handle)
  2463			ext4_journal_stop(handle);
  2464		if (err == -ENOSPC && ext4_should_retry_alloc(dir->i_sb, &retries))
  2465			goto retry;
> 2466		else if (err == -ENOSPC && printk_ratelimited())
  2467			printk(pr_warning "ext4: No space on disk, inode usage full");
  2468		return err;
  2469	}
  2470	

---
0-DAY kernel test infrastructure                Open Source Technology Center
https://lists.01.org/pipermail/kbuild-all                   Intel Corporation
kbuild test robot Oct. 23, 2017, 3:21 p.m. | #3
Hi Team,

[auto build test ERROR on ext4/dev]
[also build test ERROR on v4.14-rc6 next-20171018]
[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/Team-Athena/ext4-Log-inode-exhaustion-to-dmesg/20171023-222824
base:   https://git.kernel.org/pub/scm/linux/kernel/git/tytso/ext4.git dev
config: i386-randconfig-x001-201743 (attached as .config)
compiler: gcc-6 (Debian 6.2.0-3) 6.2.0 20160901
reproduce:
        # save the attached .config to linux build tree
        make ARCH=i386 

All error/warnings (new ones prefixed by >>):

   In file included from include/linux/kernel.h:13:0,
                    from include/linux/list.h:8,
                    from include/linux/wait.h:6,
                    from include/linux/wait_bit.h:7,
                    from include/linux/fs.h:5,
                    from fs/ext4/namei.c:27:
   fs/ext4/namei.c: In function 'ext4_create':
>> include/linux/printk.h:422:3: error: too few arguments to function 'printk'
      printk(fmt, ##__VA_ARGS__);    \
      ^
>> fs/ext4/namei.c:2466:29: note: in expansion of macro 'printk_ratelimited'
     else if (err == -ENOSPC && printk_ratelimited())
                                ^~~~~~~~~~~~~~~~~~
   In file included from include/linux/kernel.h:13:0,
                    from include/linux/list.h:8,
                    from include/linux/wait.h:6,
                    from include/linux/wait_bit.h:7,
                    from include/linux/fs.h:5,
                    from fs/ext4/namei.c:27:
   include/linux/printk.h:172:5: note: declared here
    int printk(const char *fmt, ...);
        ^~~~~~
   In file included from include/linux/kernel.h:13:0,
                    from include/linux/list.h:8,
                    from include/linux/wait.h:6,
                    from include/linux/wait_bit.h:7,
                    from include/linux/fs.h:5,
                    from fs/ext4/namei.c:27:
>> include/linux/printk.h:416:2: error: void value not ignored as it ought to be
    ({         \
    ~^~~~~~~~~~~
     static DEFINE_RATELIMIT_STATE(_rs,    \
     ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
              DEFAULT_RATELIMIT_INTERVAL, \
              ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
              DEFAULT_RATELIMIT_BURST);  \
              ~~~~~~~~~~~~~~~~~~~~~~~~~~~~
             \
             ~
     if (__ratelimit(&_rs))      \
     ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
      printk(fmt, ##__VA_ARGS__);    \
      ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
    })
    ~~
>> fs/ext4/namei.c:2466:29: note: in expansion of macro 'printk_ratelimited'
     else if (err == -ENOSPC && printk_ratelimited())
                                ^~~~~~~~~~~~~~~~~~
>> fs/ext4/namei.c:2467:10: error: 'pr_warning' undeclared (first use in this function)
      printk(pr_warning "ext4: No space on disk, inode usage full");
             ^~~~~~~~~~
   fs/ext4/namei.c:2467:10: note: each undeclared identifier is reported only once for each function it appears in
>> fs/ext4/namei.c:2467:21: error: expected ')' before string constant
      printk(pr_warning "ext4: No space on disk, inode usage full");
                        ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
--
   In file included from include/linux/kernel.h:13:0,
                    from include/linux/list.h:8,
                    from include/linux/wait.h:6,
                    from include/linux/wait_bit.h:7,
                    from include/linux/fs.h:5,
                    from fs//ext4/namei.c:27:
   fs//ext4/namei.c: In function 'ext4_create':
>> include/linux/printk.h:422:3: error: too few arguments to function 'printk'
      printk(fmt, ##__VA_ARGS__);    \
      ^
   fs//ext4/namei.c:2466:29: note: in expansion of macro 'printk_ratelimited'
     else if (err == -ENOSPC && printk_ratelimited())
                                ^~~~~~~~~~~~~~~~~~
   In file included from include/linux/kernel.h:13:0,
                    from include/linux/list.h:8,
                    from include/linux/wait.h:6,
                    from include/linux/wait_bit.h:7,
                    from include/linux/fs.h:5,
                    from fs//ext4/namei.c:27:
   include/linux/printk.h:172:5: note: declared here
    int printk(const char *fmt, ...);
        ^~~~~~
   In file included from include/linux/kernel.h:13:0,
                    from include/linux/list.h:8,
                    from include/linux/wait.h:6,
                    from include/linux/wait_bit.h:7,
                    from include/linux/fs.h:5,
                    from fs//ext4/namei.c:27:
>> include/linux/printk.h:416:2: error: void value not ignored as it ought to be
    ({         \
    ~^~~~~~~~~~~
     static DEFINE_RATELIMIT_STATE(_rs,    \
     ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
              DEFAULT_RATELIMIT_INTERVAL, \
              ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
              DEFAULT_RATELIMIT_BURST);  \
              ~~~~~~~~~~~~~~~~~~~~~~~~~~~~
             \
             ~
     if (__ratelimit(&_rs))      \
     ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
      printk(fmt, ##__VA_ARGS__);    \
      ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
    })
    ~~
   fs//ext4/namei.c:2466:29: note: in expansion of macro 'printk_ratelimited'
     else if (err == -ENOSPC && printk_ratelimited())
                                ^~~~~~~~~~~~~~~~~~
   fs//ext4/namei.c:2467:10: error: 'pr_warning' undeclared (first use in this function)
      printk(pr_warning "ext4: No space on disk, inode usage full");
             ^~~~~~~~~~
   fs//ext4/namei.c:2467:10: note: each undeclared identifier is reported only once for each function it appears in
   fs//ext4/namei.c:2467:21: error: expected ')' before string constant
      printk(pr_warning "ext4: No space on disk, inode usage full");
                        ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

vim +/pr_warning +2467 fs/ext4/namei.c

  2427	
  2428	/*
  2429	 * By the time this is called, we already have created
  2430	 * the directory cache entry for the new file, but it
  2431	 * is so far negative - it has no inode.
  2432	 *
  2433	 * If the create succeeds, we fill in the inode information
  2434	 * with d_instantiate().
  2435	 */
  2436	static int ext4_create(struct inode *dir, struct dentry *dentry, umode_t mode,
  2437			       bool excl)
  2438	{
  2439		handle_t *handle;
  2440		struct inode *inode;
  2441		int err, credits, retries = 0;
  2442	
  2443		err = dquot_initialize(dir);
  2444		if (err)
  2445			return err;
  2446	
  2447		credits = (EXT4_DATA_TRANS_BLOCKS(dir->i_sb) +
  2448			   EXT4_INDEX_EXTRA_TRANS_BLOCKS + 3);
  2449	retry:
  2450		inode = ext4_new_inode_start_handle(dir, mode, &dentry->d_name, 0,
  2451						    NULL, EXT4_HT_DIR, credits);
  2452		handle = ext4_journal_current_handle();
  2453		err = PTR_ERR(inode);
  2454		if (!IS_ERR(inode)) {
  2455			inode->i_op = &ext4_file_inode_operations;
  2456			inode->i_fop = &ext4_file_operations;
  2457			ext4_set_aops(inode);
  2458			err = ext4_add_nondir(handle, dentry, inode);
  2459			if (!err && IS_DIRSYNC(dir))
  2460				ext4_handle_sync(handle);
  2461		}
  2462		if (handle)
  2463			ext4_journal_stop(handle);
  2464		if (err == -ENOSPC && ext4_should_retry_alloc(dir->i_sb, &retries))
  2465			goto retry;
> 2466		else if (err == -ENOSPC && printk_ratelimited())
> 2467			printk(pr_warning "ext4: No space on disk, inode usage full");
  2468		return err;
  2469	}
  2470	

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

Patch

diff --git a/fs/ext4/namei.c b/fs/ext4/namei.c
index c1cf020d..c3990d2d 100644
--- a/fs/ext4/namei.c
+++ b/fs/ext4/namei.c
@@ -2463,6 +2463,8 @@  static int ext4_create(struct inode *dir, struct dentry *dentry, umode_t mode,
 		ext4_journal_stop(handle);
 	if (err == -ENOSPC && ext4_should_retry_alloc(dir->i_sb, &retries))
 		goto retry;
+	else if (err == -ENOSPC && printk_ratelimited())
+		printk(pr_warning "ext4: No space on disk, inode usage full");
 	return err;
 }