Skip to content

Commit

Permalink
Merge tag 'fs_for_v6.9-rc1' of git://git.kernel.org/pub/scm/linux/ker…
Browse files Browse the repository at this point in the history
…nel/git/jack/linux-fs

Pull ext2, isofs, udf, and quota updates from Jan Kara:
 "A lot of material this time:

   - removal of a lot of GFP_NOFS usage from ext2, udf, quota (either it
     was legacy or replaced with scoped memalloc_nofs_*() API)

   - removal of BUG_ONs in quota code

   - conversion of UDF to the new mount API

   - tightening quota on disk format verification

   - fix some potentially unsafe use of RCU pointers in quota code and
     annotate everything properly to make sparse happy

   - a few other small quota, ext2, udf, and isofs fixes"

* tag 'fs_for_v6.9-rc1' of git://git.kernel.org/pub/scm/linux/kernel/git/jack/linux-fs: (26 commits)
  udf: remove SLAB_MEM_SPREAD flag usage
  quota: remove SLAB_MEM_SPREAD flag usage
  isofs: remove SLAB_MEM_SPREAD flag usage
  ext2: remove SLAB_MEM_SPREAD flag usage
  ext2: mark as deprecated
  udf: convert to new mount API
  udf: convert novrs to an option flag
  MAINTAINERS: add missing git address for ext2 entry
  quota: Detect loops in quota tree
  quota: Properly annotate i_dquot arrays with __rcu
  quota: Fix rcu annotations of inode dquot pointers
  isofs: handle CDs with bad root inode but good Joliet root directory
  udf: Avoid invalid LVID used on mount
  quota: Fix potential NULL pointer dereference
  quota: Drop GFP_NOFS instances under dquot->dq_lock and dqio_sem
  quota: Set nofs allocation context when acquiring dqio_sem
  ext2: Remove GFP_NOFS use in ext2_xattr_cache_insert()
  ext2: Drop GFP_NOFS use in ext2_get_blocks()
  ext2: Drop GFP_NOFS allocation from ext2_init_block_alloc_info()
  udf: Remove GFP_NOFS allocation in udf_expand_file_adinicb()
  ...
  • Loading branch information
torvalds committed Mar 13, 2024
2 parents 1715f71 + a78e41a commit e5e038b
Show file tree
Hide file tree
Showing 32 changed files with 608 additions and 423 deletions.
1 change: 1 addition & 0 deletions MAINTAINERS
Original file line number Diff line number Diff line change
Expand Up @@ -8021,6 +8021,7 @@ M: Jan Kara <jack@suse.com>
L: linux-ext4@vger.kernel.org
S: Maintained
F: Documentation/filesystems/ext2.rst
T: git git://git.kernel.org/pub/scm/linux/kernel/git/jack/linux-fs.git
F: fs/ext2/
F: include/linux/ext2*

Expand Down
15 changes: 11 additions & 4 deletions fs/ext2/Kconfig
Original file line number Diff line number Diff line change
@@ -1,16 +1,23 @@
# SPDX-License-Identifier: GPL-2.0-only
config EXT2_FS
tristate "Second extended fs support"
tristate "Second extended fs support (DEPRECATED)"
select BUFFER_HEAD
select FS_IOMAP
select LEGACY_DIRECT_IO
help
Ext2 is a standard Linux file system for hard disks.

To compile this file system support as a module, choose M here: the
module will be called ext2.
This filesystem driver is deprecated because it does not properly
support inode time stamps beyond 03:14:07 UTC on 19 January 2038.

If unsure, say Y.
Ext2 users are advised to use ext4 driver to access their filesystem.
The driver is fully compatible, supports filesystems without journal
or extents, and also supports larger time stamps if the filesystem
is created with at least 256 byte inodes.

This code is kept as a simple reference for filesystem developers.

If unsure, say N.

config EXT2_FS_XATTR
bool "Ext2 extended attributes"
Expand Down
2 changes: 1 addition & 1 deletion fs/ext2/balloc.c
Original file line number Diff line number Diff line change
Expand Up @@ -412,7 +412,7 @@ void ext2_init_block_alloc_info(struct inode *inode)
struct ext2_block_alloc_info *block_i;
struct super_block *sb = inode->i_sb;

block_i = kmalloc(sizeof(*block_i), GFP_NOFS);
block_i = kmalloc(sizeof(*block_i), GFP_KERNEL);
if (block_i) {
struct ext2_reserve_window_node *rsv = &block_i->rsv_window_node;

Expand Down
2 changes: 1 addition & 1 deletion fs/ext2/ext2.h
Original file line number Diff line number Diff line change
Expand Up @@ -674,7 +674,7 @@ struct ext2_inode_info {
struct inode vfs_inode;
struct list_head i_orphan; /* unlinked but open inodes */
#ifdef CONFIG_QUOTA
struct dquot *i_dquot[MAXQUOTAS];
struct dquot __rcu *i_dquot[MAXQUOTAS];
#endif
};

Expand Down
2 changes: 1 addition & 1 deletion fs/ext2/inode.c
Original file line number Diff line number Diff line change
Expand Up @@ -754,7 +754,7 @@ static int ext2_get_blocks(struct inode *inode,
*/
err = sb_issue_zeroout(inode->i_sb,
le32_to_cpu(chain[depth-1].key), count,
GFP_NOFS);
GFP_KERNEL);
if (err) {
mutex_unlock(&ei->truncate_mutex);
goto cleanup;
Expand Down
2 changes: 1 addition & 1 deletion fs/ext2/super.c
Original file line number Diff line number Diff line change
Expand Up @@ -319,7 +319,7 @@ static ssize_t ext2_quota_read(struct super_block *sb, int type, char *data, siz
static ssize_t ext2_quota_write(struct super_block *sb, int type, const char *data, size_t len, loff_t off);
static int ext2_quota_on(struct super_block *sb, int type, int format_id,
const struct path *path);
static struct dquot **ext2_get_dquots(struct inode *inode)
static struct dquot __rcu **ext2_get_dquots(struct inode *inode)
{
return EXT2_I(inode)->i_dquot;
}
Expand Down
2 changes: 1 addition & 1 deletion fs/ext2/xattr.c
Original file line number Diff line number Diff line change
Expand Up @@ -874,7 +874,7 @@ ext2_xattr_cache_insert(struct mb_cache *cache, struct buffer_head *bh)
__u32 hash = le32_to_cpu(HDR(bh)->h_hash);
int error;

error = mb_cache_entry_create(cache, GFP_NOFS, hash, bh->b_blocknr,
error = mb_cache_entry_create(cache, GFP_KERNEL, hash, bh->b_blocknr,
true);
if (error) {
if (error == -EBUSY) {
Expand Down
2 changes: 1 addition & 1 deletion fs/ext4/ext4.h
Original file line number Diff line number Diff line change
Expand Up @@ -1158,7 +1158,7 @@ struct ext4_inode_info {
tid_t i_datasync_tid;

#ifdef CONFIG_QUOTA
struct dquot *i_dquot[MAXQUOTAS];
struct dquot __rcu *i_dquot[MAXQUOTAS];
#endif

/* Precomputed uuid+inum+igen checksum for seeding inode checksums */
Expand Down
2 changes: 1 addition & 1 deletion fs/ext4/super.c
Original file line number Diff line number Diff line change
Expand Up @@ -1599,7 +1599,7 @@ static ssize_t ext4_quota_write(struct super_block *sb, int type,
static int ext4_quota_enable(struct super_block *sb, int type, int format_id,
unsigned int flags);

static struct dquot **ext4_get_dquots(struct inode *inode)
static struct dquot __rcu **ext4_get_dquots(struct inode *inode)
{
return EXT4_I(inode)->i_dquot;
}
Expand Down
2 changes: 1 addition & 1 deletion fs/f2fs/f2fs.h
Original file line number Diff line number Diff line change
Expand Up @@ -830,7 +830,7 @@ struct f2fs_inode_info {
spinlock_t i_size_lock; /* protect last_disk_size */

#ifdef CONFIG_QUOTA
struct dquot *i_dquot[MAXQUOTAS];
struct dquot __rcu *i_dquot[MAXQUOTAS];

/* quota space reservation, managed internally by quota code */
qsize_t i_reserved_quota;
Expand Down
2 changes: 1 addition & 1 deletion fs/f2fs/super.c
Original file line number Diff line number Diff line change
Expand Up @@ -2768,7 +2768,7 @@ int f2fs_dquot_initialize(struct inode *inode)
return dquot_initialize(inode);
}

static struct dquot **f2fs_get_dquots(struct inode *inode)
static struct dquot __rcu **f2fs_get_dquots(struct inode *inode)
{
return F2FS_I(inode)->i_dquot;
}
Expand Down
18 changes: 16 additions & 2 deletions fs/isofs/inode.c
Original file line number Diff line number Diff line change
Expand Up @@ -908,8 +908,22 @@ static int isofs_fill_super(struct super_block *s, void *data, int silent)
* we then decide whether to use the Joliet descriptor.
*/
inode = isofs_iget(s, sbi->s_firstdatazone, 0);
if (IS_ERR(inode))
goto out_no_root;

/*
* Fix for broken CDs with a corrupt root inode but a correct Joliet
* root directory.
*/
if (IS_ERR(inode)) {
if (joliet_level && sbi->s_firstdatazone != first_data_zone) {
printk(KERN_NOTICE
"ISOFS: root inode is unusable. "
"Disabling Rock Ridge and switching to Joliet.");
sbi->s_rock = 0;
inode = NULL;
} else {
goto out_no_root;
}
}

/*
* Fix for broken CDs with Rock Ridge and empty ISO root directory but
Expand Down
2 changes: 1 addition & 1 deletion fs/jfs/jfs_incore.h
Original file line number Diff line number Diff line change
Expand Up @@ -92,7 +92,7 @@ struct jfs_inode_info {
} link;
} u;
#ifdef CONFIG_QUOTA
struct dquot *i_dquot[MAXQUOTAS];
struct dquot __rcu *i_dquot[MAXQUOTAS];
#endif
u32 dev; /* will die when we get wide dev_t */
struct inode vfs_inode;
Expand Down
2 changes: 1 addition & 1 deletion fs/jfs/super.c
Original file line number Diff line number Diff line change
Expand Up @@ -824,7 +824,7 @@ static ssize_t jfs_quota_write(struct super_block *sb, int type,
return len - towrite;
}

static struct dquot **jfs_get_dquots(struct inode *inode)
static struct dquot __rcu **jfs_get_dquots(struct inode *inode)
{
return JFS_IP(inode)->i_dquot;
}
Expand Down
2 changes: 1 addition & 1 deletion fs/ocfs2/inode.h
Original file line number Diff line number Diff line change
Expand Up @@ -65,7 +65,7 @@ struct ocfs2_inode_info
tid_t i_sync_tid;
tid_t i_datasync_tid;

struct dquot *i_dquot[MAXQUOTAS];
struct dquot __rcu *i_dquot[MAXQUOTAS];
};

/*
Expand Down
12 changes: 12 additions & 0 deletions fs/ocfs2/quota_global.c
Original file line number Diff line number Diff line change
Expand Up @@ -447,14 +447,17 @@ int ocfs2_global_write_info(struct super_block *sb, int type)
int err;
struct quota_info *dqopt = sb_dqopt(sb);
struct ocfs2_mem_dqinfo *info = dqopt->info[type].dqi_priv;
unsigned int memalloc;

down_write(&dqopt->dqio_sem);
memalloc = memalloc_nofs_save();
err = ocfs2_qinfo_lock(info, 1);
if (err < 0)
goto out_sem;
err = __ocfs2_global_write_info(sb, type);
ocfs2_qinfo_unlock(info, 1);
out_sem:
memalloc_nofs_restore(memalloc);
up_write(&dqopt->dqio_sem);
return err;
}
Expand Down Expand Up @@ -601,6 +604,7 @@ static int ocfs2_sync_dquot_helper(struct dquot *dquot, unsigned long type)
struct ocfs2_mem_dqinfo *oinfo = sb_dqinfo(sb, type)->dqi_priv;
struct ocfs2_super *osb = OCFS2_SB(sb);
int status = 0;
unsigned int memalloc;

trace_ocfs2_sync_dquot_helper(from_kqid(&init_user_ns, dquot->dq_id),
dquot->dq_id.type,
Expand All @@ -618,13 +622,15 @@ static int ocfs2_sync_dquot_helper(struct dquot *dquot, unsigned long type)
goto out_ilock;
}
down_write(&sb_dqopt(sb)->dqio_sem);
memalloc = memalloc_nofs_save();
status = ocfs2_sync_dquot(dquot);
if (status < 0)
mlog_errno(status);
/* We have to write local structure as well... */
status = ocfs2_local_write_dquot(dquot);
if (status < 0)
mlog_errno(status);
memalloc_nofs_restore(memalloc);
up_write(&sb_dqopt(sb)->dqio_sem);
ocfs2_commit_trans(osb, handle);
out_ilock:
Expand Down Expand Up @@ -662,6 +668,7 @@ static int ocfs2_write_dquot(struct dquot *dquot)
handle_t *handle;
struct ocfs2_super *osb = OCFS2_SB(dquot->dq_sb);
int status = 0;
unsigned int memalloc;

trace_ocfs2_write_dquot(from_kqid(&init_user_ns, dquot->dq_id),
dquot->dq_id.type);
Expand All @@ -673,7 +680,9 @@ static int ocfs2_write_dquot(struct dquot *dquot)
goto out;
}
down_write(&sb_dqopt(dquot->dq_sb)->dqio_sem);
memalloc = memalloc_nofs_save();
status = ocfs2_local_write_dquot(dquot);
memalloc_nofs_restore(memalloc);
up_write(&sb_dqopt(dquot->dq_sb)->dqio_sem);
ocfs2_commit_trans(osb, handle);
out:
Expand Down Expand Up @@ -920,6 +929,7 @@ static int ocfs2_mark_dquot_dirty(struct dquot *dquot)
struct ocfs2_mem_dqinfo *oinfo = sb_dqinfo(sb, type)->dqi_priv;
handle_t *handle;
struct ocfs2_super *osb = OCFS2_SB(sb);
unsigned int memalloc;

trace_ocfs2_mark_dquot_dirty(from_kqid(&init_user_ns, dquot->dq_id),
type);
Expand All @@ -946,6 +956,7 @@ static int ocfs2_mark_dquot_dirty(struct dquot *dquot)
goto out_ilock;
}
down_write(&sb_dqopt(sb)->dqio_sem);
memalloc = memalloc_nofs_save();
status = ocfs2_sync_dquot(dquot);
if (status < 0) {
mlog_errno(status);
Expand All @@ -954,6 +965,7 @@ static int ocfs2_mark_dquot_dirty(struct dquot *dquot)
/* Now write updated local dquot structure */
status = ocfs2_local_write_dquot(dquot);
out_dlock:
memalloc_nofs_restore(memalloc);
up_write(&sb_dqopt(sb)->dqio_sem);
ocfs2_commit_trans(osb, handle);
out_ilock:
Expand Down
3 changes: 3 additions & 0 deletions fs/ocfs2/quota_local.c
Original file line number Diff line number Diff line change
Expand Up @@ -470,6 +470,7 @@ static int ocfs2_recover_local_quota_file(struct inode *lqinode,
int bit, chunk;
struct ocfs2_recovery_chunk *rchunk, *next;
qsize_t spacechange, inodechange;
unsigned int memalloc;

trace_ocfs2_recover_local_quota_file((unsigned long)lqinode->i_ino, type);

Expand Down Expand Up @@ -521,6 +522,7 @@ static int ocfs2_recover_local_quota_file(struct inode *lqinode,
goto out_drop_lock;
}
down_write(&sb_dqopt(sb)->dqio_sem);
memalloc = memalloc_nofs_save();
spin_lock(&dquot->dq_dqb_lock);
/* Add usage from quota entry into quota changes
* of our node. Auxiliary variables are important
Expand Down Expand Up @@ -553,6 +555,7 @@ static int ocfs2_recover_local_quota_file(struct inode *lqinode,
unlock_buffer(qbh);
ocfs2_journal_dirty(handle, qbh);
out_commit:
memalloc_nofs_restore(memalloc);
up_write(&sb_dqopt(sb)->dqio_sem);
ocfs2_commit_trans(OCFS2_SB(sb), handle);
out_drop_lock:
Expand Down
2 changes: 1 addition & 1 deletion fs/ocfs2/super.c
Original file line number Diff line number Diff line change
Expand Up @@ -122,7 +122,7 @@ static int ocfs2_susp_quotas(struct ocfs2_super *osb, int unsuspend);
static int ocfs2_enable_quotas(struct ocfs2_super *osb);
static void ocfs2_disable_quotas(struct ocfs2_super *osb);

static struct dquot **ocfs2_get_dquots(struct inode *inode)
static struct dquot __rcu **ocfs2_get_dquots(struct inode *inode)
{
return OCFS2_I(inode)->i_dquot;
}
Expand Down
Loading

0 comments on commit e5e038b

Please sign in to comment.