ext4: move dcache manipulation out of __ext4_link()

__ext4_link() has two callers.

- ext4_link() calls it during normal handling of the link() system
  call or similar
- ext4_fc_replay_link_internal() calls it when replaying the journal
  at mount time.

The former needs changes to dcache - instantiating the dentry to the
inode on success.  The latter doesn't need or want any dcache
manipulation.

So move the manipulation out of __ext4_link() and do it in ext4_link()
only.

This requires:
 - passing the qname from the dentry explicitly to __ext4_link.
   The parent dir is already passed.  The dentry is still passed
   in the ext4_link() case purely for use by ext4_fc_track_link().
 - passing the inode separately to ext4_fc_track_link() as the
   dentry will not be instantiated yet.
 - using __ext4_add_entry() in ext4_link, which doesn't need a dentry.
 - moving ihold(), d_instantiate(), drop_nlink() and iput() calls out
   of __ext4_link() into ext4_link().

Note that ext4_inc_count() and drop_nlink() remain in __ext4_link()
as both callers need them and they are not related to the dentry.

This substantially simplifies ext4_fc_replay_link_internal(), and
removes a use of d_alloc() which, it is planned, will be removed.

Reviewed-by: Jan Kara <jack@suse.cz>
Signed-off-by: NeilBrown <neil@brown.name>
Link: https://patch.msgid.link/20260320000838.3797494-4-neilb@ownmail.net
Signed-off-by: Theodore Ts'o <tytso@mit.edu>
This commit is contained in:
NeilBrown
2026-03-20 11:03:18 +11:00
committed by Theodore Ts'o
parent 0f5f14f334
commit 52b4fea162
3 changed files with 18 additions and 38 deletions

View File

@@ -3452,7 +3452,8 @@ out_retry:
return err;
}
int __ext4_link(struct inode *dir, struct inode *inode, struct dentry *dentry)
int __ext4_link(struct inode *dir, struct inode *inode,
const struct qstr *d_name, struct dentry *dentry)
{
handle_t *handle;
int err, retries = 0;
@@ -3468,9 +3469,8 @@ retry:
inode_set_ctime_current(inode);
ext4_inc_count(inode);
ihold(inode);
err = ext4_add_entry(handle, dentry, inode);
err = __ext4_add_entry(handle, dir, d_name, inode);
if (!err) {
err = ext4_mark_inode_dirty(handle, inode);
/* this can happen only for tmpfile being
@@ -3478,11 +3478,10 @@ retry:
*/
if (inode->i_nlink == 1)
ext4_orphan_del(handle, inode);
d_instantiate(dentry, inode);
ext4_fc_track_link(handle, dentry);
if (dentry)
ext4_fc_track_link(handle, inode, dentry);
} else {
drop_nlink(inode);
iput(inode);
}
ext4_journal_stop(handle);
if (err == -ENOSPC && ext4_should_retry_alloc(dir->i_sb, &retries))
@@ -3511,9 +3510,13 @@ static int ext4_link(struct dentry *old_dentry,
err = dquot_initialize(dir);
if (err)
return err;
return __ext4_link(dir, inode, dentry);
err = __ext4_link(dir, inode, &dentry->d_name, dentry);
if (!err) {
ihold(inode);
d_instantiate(dentry, inode);
}
return err;
}
/*
* Try to find buffer head where contains the parent block.
* It should be the inode block if it is inlined or the 1st block