0001
0002
0003
0004
0005
0006
0007
0008
0009
0010
0011
0012
0013
0014
0015
0016
0017
0018
0019
0020
0021
0022
0023
0024
0025
0026 #include <linux/time.h>
0027 #include <linux/fs.h>
0028 #include <linux/sched.h>
0029 #include <linux/writeback.h>
0030 #include <linux/blkdev.h>
0031
0032 #include "ext4.h"
0033 #include "ext4_jbd2.h"
0034
0035 #include <trace/events/ext4.h>
0036
0037
0038
0039
0040
0041
0042
0043
0044
0045 static int ext4_sync_parent(struct inode *inode)
0046 {
0047 struct dentry *dentry, *next;
0048 int ret = 0;
0049
0050 if (!ext4_test_inode_state(inode, EXT4_STATE_NEWENTRY))
0051 return 0;
0052 dentry = d_find_any_alias(inode);
0053 if (!dentry)
0054 return 0;
0055 while (ext4_test_inode_state(inode, EXT4_STATE_NEWENTRY)) {
0056 ext4_clear_inode_state(inode, EXT4_STATE_NEWENTRY);
0057
0058 next = dget_parent(dentry);
0059 dput(dentry);
0060 dentry = next;
0061 inode = dentry->d_inode;
0062
0063
0064
0065
0066
0067
0068
0069
0070 ret = sync_mapping_buffers(inode->i_mapping);
0071 if (ret)
0072 break;
0073 ret = sync_inode_metadata(inode, 1);
0074 if (ret)
0075 break;
0076 }
0077 dput(dentry);
0078 return ret;
0079 }
0080
0081 static int ext4_fsync_nojournal(struct inode *inode, bool datasync,
0082 bool *needs_barrier)
0083 {
0084 int ret, err;
0085
0086 ret = sync_mapping_buffers(inode->i_mapping);
0087 if (!(inode->i_state & I_DIRTY_ALL))
0088 return ret;
0089 if (datasync && !(inode->i_state & I_DIRTY_DATASYNC))
0090 return ret;
0091
0092 err = sync_inode_metadata(inode, 1);
0093 if (!ret)
0094 ret = err;
0095
0096 if (!ret)
0097 ret = ext4_sync_parent(inode);
0098 if (test_opt(inode->i_sb, BARRIER))
0099 *needs_barrier = true;
0100
0101 return ret;
0102 }
0103
0104 static int ext4_fsync_journal(struct inode *inode, bool datasync,
0105 bool *needs_barrier)
0106 {
0107 struct ext4_inode_info *ei = EXT4_I(inode);
0108 journal_t *journal = EXT4_SB(inode->i_sb)->s_journal;
0109 tid_t commit_tid = datasync ? ei->i_datasync_tid : ei->i_sync_tid;
0110
0111 if (journal->j_flags & JBD2_BARRIER &&
0112 !jbd2_trans_will_send_data_barrier(journal, commit_tid))
0113 *needs_barrier = true;
0114
0115 return ext4_fc_commit(journal, commit_tid);
0116 }
0117
0118
0119
0120
0121
0122
0123
0124
0125
0126
0127
0128
0129 int ext4_sync_file(struct file *file, loff_t start, loff_t end, int datasync)
0130 {
0131 int ret = 0, err;
0132 bool needs_barrier = false;
0133 struct inode *inode = file->f_mapping->host;
0134 struct ext4_sb_info *sbi = EXT4_SB(inode->i_sb);
0135
0136 if (unlikely(ext4_forced_shutdown(sbi)))
0137 return -EIO;
0138
0139 ASSERT(ext4_journal_current_handle() == NULL);
0140
0141 trace_ext4_sync_file_enter(file, datasync);
0142
0143 if (sb_rdonly(inode->i_sb)) {
0144
0145 smp_rmb();
0146 if (ext4_test_mount_flag(inode->i_sb, EXT4_MF_FS_ABORTED))
0147 ret = -EROFS;
0148 goto out;
0149 }
0150
0151 ret = file_write_and_wait_range(file, start, end);
0152 if (ret)
0153 goto out;
0154
0155
0156
0157
0158
0159
0160
0161
0162
0163
0164
0165
0166
0167
0168
0169 if (!sbi->s_journal)
0170 ret = ext4_fsync_nojournal(inode, datasync, &needs_barrier);
0171 else if (ext4_should_journal_data(inode))
0172 ret = ext4_force_commit(inode->i_sb);
0173 else
0174 ret = ext4_fsync_journal(inode, datasync, &needs_barrier);
0175
0176 if (needs_barrier) {
0177 err = blkdev_issue_flush(inode->i_sb->s_bdev);
0178 if (!ret)
0179 ret = err;
0180 }
0181 out:
0182 err = file_check_and_advance_wb_err(file);
0183 if (ret == 0)
0184 ret = err;
0185 trace_ext4_sync_file_exit(inode, ret);
0186 return ret;
0187 }