1
0
Fork 0
mirror of synced 2025-03-06 20:59:54 +01:00

ext4: fixup ext4_fc_track_* functions' signature

Firstly, pass handle to all ext4_fc_track_* functions and use
transaction id found in handle->h_transaction->h_tid for tracking fast
commit updates. Secondly, don't pass inode to
ext4_fc_track_link/create/unlink functions. inode can be found inside
these functions as d_inode(dentry). However, rename path is an
exeception. That's because in that case, we need inode that's not same
as d_inode(dentry). To handle that, add a couple of low-level wrapper
functions that take inode and dentry as arguments.

Suggested-by: Jan Kara <jack@suse.cz>
Signed-off-by: Harshad Shirwadkar <harshadshirwadkar@gmail.com>
Link: https://lore.kernel.org/r/20201106035911.1942128-5-harshadshirwadkar@gmail.com
Signed-off-by: Theodore Ts'o <tytso@mit.edu>
This commit is contained in:
Harshad Shirwadkar 2020-11-05 19:58:53 -08:00 committed by Theodore Ts'o
parent 5b552ad70c
commit a80f7fcf18
5 changed files with 74 additions and 63 deletions

View file

@ -2738,12 +2738,16 @@ extern void ext4_end_bitmap_read(struct buffer_head *bh, int uptodate);
int ext4_fc_info_show(struct seq_file *seq, void *v); int ext4_fc_info_show(struct seq_file *seq, void *v);
void ext4_fc_init(struct super_block *sb, journal_t *journal); void ext4_fc_init(struct super_block *sb, journal_t *journal);
void ext4_fc_init_inode(struct inode *inode); void ext4_fc_init_inode(struct inode *inode);
void ext4_fc_track_range(struct inode *inode, ext4_lblk_t start, void ext4_fc_track_range(handle_t *handle, struct inode *inode, ext4_lblk_t start,
ext4_lblk_t end); ext4_lblk_t end);
void ext4_fc_track_unlink(struct inode *inode, struct dentry *dentry); void __ext4_fc_track_unlink(handle_t *handle, struct inode *inode,
void ext4_fc_track_link(struct inode *inode, struct dentry *dentry); struct dentry *dentry);
void ext4_fc_track_create(struct inode *inode, struct dentry *dentry); void __ext4_fc_track_link(handle_t *handle, struct inode *inode,
void ext4_fc_track_inode(struct inode *inode); struct dentry *dentry);
void ext4_fc_track_unlink(handle_t *handle, struct dentry *dentry);
void ext4_fc_track_link(handle_t *handle, struct dentry *dentry);
void ext4_fc_track_create(handle_t *handle, struct dentry *dentry);
void ext4_fc_track_inode(handle_t *handle, struct inode *inode);
void ext4_fc_mark_ineligible(struct super_block *sb, int reason); void ext4_fc_mark_ineligible(struct super_block *sb, int reason);
void ext4_fc_start_ineligible(struct super_block *sb, int reason); void ext4_fc_start_ineligible(struct super_block *sb, int reason);
void ext4_fc_stop_ineligible(struct super_block *sb); void ext4_fc_stop_ineligible(struct super_block *sb);
@ -3459,7 +3463,7 @@ extern int ext4_handle_dirty_dirblock(handle_t *handle, struct inode *inode,
extern int ext4_ci_compare(const struct inode *parent, extern int ext4_ci_compare(const struct inode *parent,
const struct qstr *fname, const struct qstr *fname,
const struct qstr *entry, bool quick); const struct qstr *entry, bool quick);
extern int __ext4_unlink(struct inode *dir, const struct qstr *d_name, extern int __ext4_unlink(handle_t *handle, struct inode *dir, const struct qstr *d_name,
struct inode *inode); struct inode *inode);
extern int __ext4_link(struct inode *dir, struct inode *inode, extern int __ext4_link(struct inode *dir, struct inode *inode,
struct dentry *dentry); struct dentry *dentry);

View file

@ -4599,7 +4599,7 @@ static long ext4_zero_range(struct file *file, loff_t offset,
ret = ext4_mark_inode_dirty(handle, inode); ret = ext4_mark_inode_dirty(handle, inode);
if (unlikely(ret)) if (unlikely(ret))
goto out_handle; goto out_handle;
ext4_fc_track_range(inode, offset >> inode->i_sb->s_blocksize_bits, ext4_fc_track_range(handle, inode, offset >> inode->i_sb->s_blocksize_bits,
(offset + len - 1) >> inode->i_sb->s_blocksize_bits); (offset + len - 1) >> inode->i_sb->s_blocksize_bits);
/* Zero out partial block at the edges of the range */ /* Zero out partial block at the edges of the range */
ret = ext4_zero_partial_blocks(handle, inode, offset, len); ret = ext4_zero_partial_blocks(handle, inode, offset, len);

View file

@ -323,13 +323,14 @@ static inline int ext4_fc_is_ineligible(struct super_block *sb)
* If enqueue is set, this function enqueues the inode in fast commit list. * If enqueue is set, this function enqueues the inode in fast commit list.
*/ */
static int ext4_fc_track_template( static int ext4_fc_track_template(
struct inode *inode, int (*__fc_track_fn)(struct inode *, void *, bool), handle_t *handle, struct inode *inode,
int (*__fc_track_fn)(struct inode *, void *, bool),
void *args, int enqueue) void *args, int enqueue)
{ {
tid_t running_txn_tid;
bool update = false; bool update = false;
struct ext4_inode_info *ei = EXT4_I(inode); struct ext4_inode_info *ei = EXT4_I(inode);
struct ext4_sb_info *sbi = EXT4_SB(inode->i_sb); struct ext4_sb_info *sbi = EXT4_SB(inode->i_sb);
tid_t tid = 0;
int ret; int ret;
if (!test_opt2(inode->i_sb, JOURNAL_FAST_COMMIT) || if (!test_opt2(inode->i_sb, JOURNAL_FAST_COMMIT) ||
@ -339,15 +340,13 @@ static int ext4_fc_track_template(
if (ext4_fc_is_ineligible(inode->i_sb)) if (ext4_fc_is_ineligible(inode->i_sb))
return -EINVAL; return -EINVAL;
running_txn_tid = sbi->s_journal ? tid = handle->h_transaction->t_tid;
sbi->s_journal->j_commit_sequence + 1 : 0;
mutex_lock(&ei->i_fc_lock); mutex_lock(&ei->i_fc_lock);
if (running_txn_tid == ei->i_sync_tid) { if (tid == ei->i_sync_tid) {
update = true; update = true;
} else { } else {
ext4_fc_reset_inode(inode); ext4_fc_reset_inode(inode);
ei->i_sync_tid = running_txn_tid; ei->i_sync_tid = tid;
} }
ret = __fc_track_fn(inode, args, update); ret = __fc_track_fn(inode, args, update);
mutex_unlock(&ei->i_fc_lock); mutex_unlock(&ei->i_fc_lock);
@ -422,7 +421,8 @@ static int __track_dentry_update(struct inode *inode, void *arg, bool update)
return 0; return 0;
} }
void ext4_fc_track_unlink(struct inode *inode, struct dentry *dentry) void __ext4_fc_track_unlink(handle_t *handle,
struct inode *inode, struct dentry *dentry)
{ {
struct __track_dentry_update_args args; struct __track_dentry_update_args args;
int ret; int ret;
@ -430,12 +430,18 @@ void ext4_fc_track_unlink(struct inode *inode, struct dentry *dentry)
args.dentry = dentry; args.dentry = dentry;
args.op = EXT4_FC_TAG_UNLINK; args.op = EXT4_FC_TAG_UNLINK;
ret = ext4_fc_track_template(inode, __track_dentry_update, ret = ext4_fc_track_template(handle, inode, __track_dentry_update,
(void *)&args, 0); (void *)&args, 0);
trace_ext4_fc_track_unlink(inode, dentry, ret); trace_ext4_fc_track_unlink(inode, dentry, ret);
} }
void ext4_fc_track_link(struct inode *inode, struct dentry *dentry) void ext4_fc_track_unlink(handle_t *handle, struct dentry *dentry)
{
__ext4_fc_track_unlink(handle, d_inode(dentry), dentry);
}
void __ext4_fc_track_link(handle_t *handle,
struct inode *inode, struct dentry *dentry)
{ {
struct __track_dentry_update_args args; struct __track_dentry_update_args args;
int ret; int ret;
@ -443,20 +449,26 @@ void ext4_fc_track_link(struct inode *inode, struct dentry *dentry)
args.dentry = dentry; args.dentry = dentry;
args.op = EXT4_FC_TAG_LINK; args.op = EXT4_FC_TAG_LINK;
ret = ext4_fc_track_template(inode, __track_dentry_update, ret = ext4_fc_track_template(handle, inode, __track_dentry_update,
(void *)&args, 0); (void *)&args, 0);
trace_ext4_fc_track_link(inode, dentry, ret); trace_ext4_fc_track_link(inode, dentry, ret);
} }
void ext4_fc_track_create(struct inode *inode, struct dentry *dentry) void ext4_fc_track_link(handle_t *handle, struct dentry *dentry)
{
__ext4_fc_track_link(handle, d_inode(dentry), dentry);
}
void ext4_fc_track_create(handle_t *handle, struct dentry *dentry)
{ {
struct __track_dentry_update_args args; struct __track_dentry_update_args args;
struct inode *inode = d_inode(dentry);
int ret; int ret;
args.dentry = dentry; args.dentry = dentry;
args.op = EXT4_FC_TAG_CREAT; args.op = EXT4_FC_TAG_CREAT;
ret = ext4_fc_track_template(inode, __track_dentry_update, ret = ext4_fc_track_template(handle, inode, __track_dentry_update,
(void *)&args, 0); (void *)&args, 0);
trace_ext4_fc_track_create(inode, dentry, ret); trace_ext4_fc_track_create(inode, dentry, ret);
} }
@ -472,14 +484,14 @@ static int __track_inode(struct inode *inode, void *arg, bool update)
return 0; return 0;
} }
void ext4_fc_track_inode(struct inode *inode) void ext4_fc_track_inode(handle_t *handle, struct inode *inode)
{ {
int ret; int ret;
if (S_ISDIR(inode->i_mode)) if (S_ISDIR(inode->i_mode))
return; return;
ret = ext4_fc_track_template(inode, __track_inode, NULL, 1); ret = ext4_fc_track_template(handle, inode, __track_inode, NULL, 1);
trace_ext4_fc_track_inode(inode, ret); trace_ext4_fc_track_inode(inode, ret);
} }
@ -515,7 +527,7 @@ static int __track_range(struct inode *inode, void *arg, bool update)
return 0; return 0;
} }
void ext4_fc_track_range(struct inode *inode, ext4_lblk_t start, void ext4_fc_track_range(handle_t *handle, struct inode *inode, ext4_lblk_t start,
ext4_lblk_t end) ext4_lblk_t end)
{ {
struct __track_range_args args; struct __track_range_args args;
@ -527,7 +539,7 @@ void ext4_fc_track_range(struct inode *inode, ext4_lblk_t start,
args.start = start; args.start = start;
args.end = end; args.end = end;
ret = ext4_fc_track_template(inode, __track_range, &args, 1); ret = ext4_fc_track_template(handle, inode, __track_range, &args, 1);
trace_ext4_fc_track_range(inode, start, end, ret); trace_ext4_fc_track_range(inode, start, end, ret);
} }
@ -1263,7 +1275,7 @@ static int ext4_fc_replay_unlink(struct super_block *sb, struct ext4_fc_tl *tl)
return 0; return 0;
} }
ret = __ext4_unlink(old_parent, &entry, inode); ret = __ext4_unlink(NULL, old_parent, &entry, inode);
/* -ENOENT ok coz it might not exist anymore. */ /* -ENOENT ok coz it might not exist anymore. */
if (ret == -ENOENT) if (ret == -ENOENT)
ret = 0; ret = 0;

View file

@ -732,7 +732,7 @@ out_sem:
if (ret) if (ret)
return ret; return ret;
} }
ext4_fc_track_range(inode, map->m_lblk, ext4_fc_track_range(handle, inode, map->m_lblk,
map->m_lblk + map->m_len - 1); map->m_lblk + map->m_len - 1);
} }
@ -4111,7 +4111,7 @@ int ext4_punch_hole(struct inode *inode, loff_t offset, loff_t length)
up_write(&EXT4_I(inode)->i_data_sem); up_write(&EXT4_I(inode)->i_data_sem);
} }
ext4_fc_track_range(inode, first_block, stop_block); ext4_fc_track_range(handle, inode, first_block, stop_block);
if (IS_SYNC(inode)) if (IS_SYNC(inode))
ext4_handle_sync(handle); ext4_handle_sync(handle);
@ -5444,14 +5444,14 @@ int ext4_setattr(struct dentry *dentry, struct iattr *attr)
} }
if (shrink) if (shrink)
ext4_fc_track_range(inode, ext4_fc_track_range(handle, inode,
(attr->ia_size > 0 ? attr->ia_size - 1 : 0) >> (attr->ia_size > 0 ? attr->ia_size - 1 : 0) >>
inode->i_sb->s_blocksize_bits, inode->i_sb->s_blocksize_bits,
(oldsize > 0 ? oldsize - 1 : 0) >> (oldsize > 0 ? oldsize - 1 : 0) >>
inode->i_sb->s_blocksize_bits); inode->i_sb->s_blocksize_bits);
else else
ext4_fc_track_range( ext4_fc_track_range(
inode, handle, inode,
(oldsize > 0 ? oldsize - 1 : oldsize) >> (oldsize > 0 ? oldsize - 1 : oldsize) >>
inode->i_sb->s_blocksize_bits, inode->i_sb->s_blocksize_bits,
(attr->ia_size > 0 ? attr->ia_size - 1 : 0) >> (attr->ia_size > 0 ? attr->ia_size - 1 : 0) >>
@ -5701,7 +5701,7 @@ int ext4_mark_iloc_dirty(handle_t *handle,
put_bh(iloc->bh); put_bh(iloc->bh);
return -EIO; return -EIO;
} }
ext4_fc_track_inode(inode); ext4_fc_track_inode(handle, inode);
if (IS_I_VERSION(inode)) if (IS_I_VERSION(inode))
inode_inc_iversion(inode); inode_inc_iversion(inode);

View file

@ -2606,7 +2606,7 @@ static int ext4_create(struct inode *dir, struct dentry *dentry, umode_t mode,
bool excl) bool excl)
{ {
handle_t *handle; handle_t *handle;
struct inode *inode, *inode_save; struct inode *inode;
int err, credits, retries = 0; int err, credits, retries = 0;
err = dquot_initialize(dir); err = dquot_initialize(dir);
@ -2624,11 +2624,9 @@ retry:
inode->i_op = &ext4_file_inode_operations; inode->i_op = &ext4_file_inode_operations;
inode->i_fop = &ext4_file_operations; inode->i_fop = &ext4_file_operations;
ext4_set_aops(inode); ext4_set_aops(inode);
inode_save = inode;
ihold(inode_save);
err = ext4_add_nondir(handle, dentry, &inode); err = ext4_add_nondir(handle, dentry, &inode);
ext4_fc_track_create(inode_save, dentry); if (!err)
iput(inode_save); ext4_fc_track_create(handle, dentry);
} }
if (handle) if (handle)
ext4_journal_stop(handle); ext4_journal_stop(handle);
@ -2643,7 +2641,7 @@ static int ext4_mknod(struct inode *dir, struct dentry *dentry,
umode_t mode, dev_t rdev) umode_t mode, dev_t rdev)
{ {
handle_t *handle; handle_t *handle;
struct inode *inode, *inode_save; struct inode *inode;
int err, credits, retries = 0; int err, credits, retries = 0;
err = dquot_initialize(dir); err = dquot_initialize(dir);
@ -2660,12 +2658,9 @@ retry:
if (!IS_ERR(inode)) { if (!IS_ERR(inode)) {
init_special_inode(inode, inode->i_mode, rdev); init_special_inode(inode, inode->i_mode, rdev);
inode->i_op = &ext4_special_inode_operations; inode->i_op = &ext4_special_inode_operations;
inode_save = inode;
ihold(inode_save);
err = ext4_add_nondir(handle, dentry, &inode); err = ext4_add_nondir(handle, dentry, &inode);
if (!err) if (!err)
ext4_fc_track_create(inode_save, dentry); ext4_fc_track_create(handle, dentry);
iput(inode_save);
} }
if (handle) if (handle)
ext4_journal_stop(handle); ext4_journal_stop(handle);
@ -2829,7 +2824,6 @@ out_clear_inode:
iput(inode); iput(inode);
goto out_retry; goto out_retry;
} }
ext4_fc_track_create(inode, dentry);
ext4_inc_count(dir); ext4_inc_count(dir);
ext4_update_dx_flag(dir); ext4_update_dx_flag(dir);
@ -2837,6 +2831,7 @@ out_clear_inode:
if (err) if (err)
goto out_clear_inode; goto out_clear_inode;
d_instantiate_new(dentry, inode); d_instantiate_new(dentry, inode);
ext4_fc_track_create(handle, dentry);
if (IS_DIRSYNC(dir)) if (IS_DIRSYNC(dir))
ext4_handle_sync(handle); ext4_handle_sync(handle);
@ -3171,7 +3166,7 @@ static int ext4_rmdir(struct inode *dir, struct dentry *dentry)
goto end_rmdir; goto end_rmdir;
ext4_dec_count(dir); ext4_dec_count(dir);
ext4_update_dx_flag(dir); ext4_update_dx_flag(dir);
ext4_fc_track_unlink(inode, dentry); ext4_fc_track_unlink(handle, dentry);
retval = ext4_mark_inode_dirty(handle, dir); retval = ext4_mark_inode_dirty(handle, dir);
#ifdef CONFIG_UNICODE #ifdef CONFIG_UNICODE
@ -3192,13 +3187,12 @@ end_rmdir:
return retval; return retval;
} }
int __ext4_unlink(struct inode *dir, const struct qstr *d_name, int __ext4_unlink(handle_t *handle, struct inode *dir, const struct qstr *d_name,
struct inode *inode) struct inode *inode)
{ {
int retval = -ENOENT; int retval = -ENOENT;
struct buffer_head *bh; struct buffer_head *bh;
struct ext4_dir_entry_2 *de; struct ext4_dir_entry_2 *de;
handle_t *handle = NULL;
int skip_remove_dentry = 0; int skip_remove_dentry = 0;
bh = ext4_find_entry(dir, d_name, &de, NULL); bh = ext4_find_entry(dir, d_name, &de, NULL);
@ -3217,14 +3211,7 @@ int __ext4_unlink(struct inode *dir, const struct qstr *d_name,
if (EXT4_SB(inode->i_sb)->s_mount_state & EXT4_FC_REPLAY) if (EXT4_SB(inode->i_sb)->s_mount_state & EXT4_FC_REPLAY)
skip_remove_dentry = 1; skip_remove_dentry = 1;
else else
goto out_bh; goto out;
}
handle = ext4_journal_start(dir, EXT4_HT_DIR,
EXT4_DATA_TRANS_BLOCKS(dir->i_sb));
if (IS_ERR(handle)) {
retval = PTR_ERR(handle);
goto out_bh;
} }
if (IS_DIRSYNC(dir)) if (IS_DIRSYNC(dir))
@ -3233,12 +3220,12 @@ int __ext4_unlink(struct inode *dir, const struct qstr *d_name,
if (!skip_remove_dentry) { if (!skip_remove_dentry) {
retval = ext4_delete_entry(handle, dir, de, bh); retval = ext4_delete_entry(handle, dir, de, bh);
if (retval) if (retval)
goto out_handle; goto out;
dir->i_ctime = dir->i_mtime = current_time(dir); dir->i_ctime = dir->i_mtime = current_time(dir);
ext4_update_dx_flag(dir); ext4_update_dx_flag(dir);
retval = ext4_mark_inode_dirty(handle, dir); retval = ext4_mark_inode_dirty(handle, dir);
if (retval) if (retval)
goto out_handle; goto out;
} else { } else {
retval = 0; retval = 0;
} }
@ -3252,15 +3239,14 @@ int __ext4_unlink(struct inode *dir, const struct qstr *d_name,
inode->i_ctime = current_time(inode); inode->i_ctime = current_time(inode);
retval = ext4_mark_inode_dirty(handle, inode); retval = ext4_mark_inode_dirty(handle, inode);
out_handle: out:
ext4_journal_stop(handle);
out_bh:
brelse(bh); brelse(bh);
return retval; return retval;
} }
static int ext4_unlink(struct inode *dir, struct dentry *dentry) static int ext4_unlink(struct inode *dir, struct dentry *dentry)
{ {
handle_t *handle;
int retval; int retval;
if (unlikely(ext4_forced_shutdown(EXT4_SB(dir->i_sb)))) if (unlikely(ext4_forced_shutdown(EXT4_SB(dir->i_sb))))
@ -3278,9 +3264,16 @@ static int ext4_unlink(struct inode *dir, struct dentry *dentry)
if (retval) if (retval)
goto out_trace; goto out_trace;
retval = __ext4_unlink(dir, &dentry->d_name, d_inode(dentry)); handle = ext4_journal_start(dir, EXT4_HT_DIR,
EXT4_DATA_TRANS_BLOCKS(dir->i_sb));
if (IS_ERR(handle)) {
retval = PTR_ERR(handle);
goto out_trace;
}
retval = __ext4_unlink(handle, dir, &dentry->d_name, d_inode(dentry));
if (!retval) if (!retval)
ext4_fc_track_unlink(d_inode(dentry), dentry); ext4_fc_track_unlink(handle, dentry);
#ifdef CONFIG_UNICODE #ifdef CONFIG_UNICODE
/* VFS negative dentries are incompatible with Encoding and /* VFS negative dentries are incompatible with Encoding and
* Case-insensitiveness. Eventually we'll want avoid * Case-insensitiveness. Eventually we'll want avoid
@ -3291,6 +3284,8 @@ static int ext4_unlink(struct inode *dir, struct dentry *dentry)
if (IS_CASEFOLDED(dir)) if (IS_CASEFOLDED(dir))
d_invalidate(dentry); d_invalidate(dentry);
#endif #endif
if (handle)
ext4_journal_stop(handle);
out_trace: out_trace:
trace_ext4_unlink_exit(dentry, retval); trace_ext4_unlink_exit(dentry, retval);
@ -3447,7 +3442,6 @@ retry:
err = ext4_add_entry(handle, dentry, inode); err = ext4_add_entry(handle, dentry, inode);
if (!err) { if (!err) {
ext4_fc_track_link(inode, dentry);
err = ext4_mark_inode_dirty(handle, inode); err = ext4_mark_inode_dirty(handle, inode);
/* this can happen only for tmpfile being /* this can happen only for tmpfile being
* linked the first time * linked the first time
@ -3455,6 +3449,7 @@ retry:
if (inode->i_nlink == 1) if (inode->i_nlink == 1)
ext4_orphan_del(handle, inode); ext4_orphan_del(handle, inode);
d_instantiate(dentry, inode); d_instantiate(dentry, inode);
ext4_fc_track_link(handle, dentry);
} else { } else {
drop_nlink(inode); drop_nlink(inode);
iput(inode); iput(inode);
@ -3915,9 +3910,9 @@ static int ext4_rename(struct inode *old_dir, struct dentry *old_dentry,
EXT4_FC_REASON_RENAME_DIR); EXT4_FC_REASON_RENAME_DIR);
} else { } else {
if (new.inode) if (new.inode)
ext4_fc_track_unlink(new.inode, new.dentry); ext4_fc_track_unlink(handle, new.dentry);
ext4_fc_track_link(old.inode, new.dentry); __ext4_fc_track_link(handle, old.inode, new.dentry);
ext4_fc_track_unlink(old.inode, old.dentry); __ext4_fc_track_unlink(handle, old.inode, old.dentry);
} }
if (new.inode) { if (new.inode) {