]> git.ipfire.org Git - thirdparty/kernel/stable.git/commitdiff
fs/hpfs: Fix error code for new_inode() failure in mkdir/create/mknod/symlink
authorYikang Yue <yikangy2@illinois.edu>
Sun, 4 May 2025 01:44:34 +0000 (20:44 -0500)
committerGreg Kroah-Hartman <gregkh@linuxfoundation.org>
Wed, 3 Dec 2025 11:45:14 +0000 (12:45 +0100)
[ Upstream commit 32058c38d3b79a28963a59ac0353644dc24775cd ]

The function call new_inode() is a primitive for allocating an inode in memory,
rather than planning disk space for it. Therefore, -ENOMEM should be returned
as the error code rather than -ENOSPC.

To be specific, new_inode()'s call path looks like this:
new_inode
  new_inode_pseudo
    alloc_inode
      ops->alloc_inode (hpfs_alloc_inode)
        alloc_inode_sb
          kmem_cache_alloc_lru

Therefore, the failure of new_inode() indicates a memory presure issue (-ENOMEM),
not a lack of disk space. However, the current implementation of
hpfs_mkdir/create/mknod/symlink incorrectly returns -ENOSPC when new_inode() fails.
This patch fix this by set err to -ENOMEM before the goto statement.

BTW, we also noticed that other nested calls within these four functions,
like hpfs_alloc_f/dnode and hpfs_add_dirent, might also fail due to memory presure.
But similarly, only -ENOSPC is returned. Addressing these will involve code
modifications in other functions, and we plan to submit dedicated patches for these
issues in the future. For this patch, we focus on new_inode().

Signed-off-by: Yikang Yue <yikangy2@illinois.edu>
Signed-off-by: Mikulas Patocka <mpatocka@redhat.com>
Signed-off-by: Sasha Levin <sashal@kernel.org>
fs/hpfs/namei.c

index 1aee39160ac5b14d49c3cb604aafede94aa4e1ae..bc1309ef4cfa5347ecef222f4744917ab5ee9862 100644 (file)
@@ -52,8 +52,10 @@ static int hpfs_mkdir(struct inode *dir, struct dentry *dentry, umode_t mode)
        dee.fnode = cpu_to_le32(fno);
        dee.creation_date = dee.write_date = dee.read_date = cpu_to_le32(local_get_seconds(dir->i_sb));
        result = new_inode(dir->i_sb);
-       if (!result)
+       if (!result) {
+               err = -ENOMEM;
                goto bail2;
+       }
        hpfs_init_inode(result);
        result->i_ino = fno;
        hpfs_i(result)->i_parent_dir = dir->i_ino;
@@ -154,9 +156,10 @@ static int hpfs_create(struct inode *dir, struct dentry *dentry, umode_t mode, b
        dee.creation_date = dee.write_date = dee.read_date = cpu_to_le32(local_get_seconds(dir->i_sb));
 
        result = new_inode(dir->i_sb);
-       if (!result)
+       if (!result) {
+               err = -ENOMEM;
                goto bail1;
-       
+       }
        hpfs_init_inode(result);
        result->i_ino = fno;
        result->i_mode |= S_IFREG;
@@ -241,9 +244,10 @@ static int hpfs_mknod(struct inode *dir, struct dentry *dentry, umode_t mode, de
        dee.creation_date = dee.write_date = dee.read_date = cpu_to_le32(local_get_seconds(dir->i_sb));
 
        result = new_inode(dir->i_sb);
-       if (!result)
+       if (!result) {
+               err = -ENOMEM;
                goto bail1;
-
+       }
        hpfs_init_inode(result);
        result->i_ino = fno;
        hpfs_i(result)->i_parent_dir = dir->i_ino;
@@ -317,8 +321,10 @@ static int hpfs_symlink(struct inode *dir, struct dentry *dentry, const char *sy
        dee.creation_date = dee.write_date = dee.read_date = cpu_to_le32(local_get_seconds(dir->i_sb));
 
        result = new_inode(dir->i_sb);
-       if (!result)
+       if (!result) {
+               err = -ENOMEM;
                goto bail1;
+       }
        result->i_ino = fno;
        hpfs_init_inode(result);
        hpfs_i(result)->i_parent_dir = dir->i_ino;