int ext3_sync_file(struct file *file, loff_t start, loff_t end, int datasync) { struct inode *inode = file->f_mapping->host; struct ext3_inode_info *ei = EXT3_I(inode); journal_t *journal = EXT3_SB(inode->i_sb)->s_journal; int ret, needs_barrier = 0; tid_t commit_tid; trace_ext3_sync_file_enter(file, datasync); if (inode->i_sb->s_flags & MS_RDONLY) return 0; ret = filemap_write_and_wait_range(inode->i_mapping, start, end); if (ret) goto out; J_ASSERT(ext3_journal_current_handle() == NULL); /* * data=writeback,ordered: * The caller's filemap_fdatawrite()/wait will sync the data. * Metadata is in the journal, we wait for a proper transaction * to commit here. * * data=journal: * filemap_fdatawrite won't do anything (the buffers are clean). * ext3_force_commit will write the file data into the journal and * will wait on that. * filemap_fdatawait() will encounter a ton of newly-dirtied pages * (they were dirtied by commit). But that's OK - the blocks are * safe in-journal, which is all fsync() needs to ensure. */ if (ext3_should_journal_data(inode)) { ret = ext3_force_commit(inode->i_sb); goto out; } if (datasync) commit_tid = atomic_read(&ei->i_datasync_tid); else commit_tid = atomic_read(&ei->i_sync_tid); if (test_opt(inode->i_sb, BARRIER) && !journal_trans_will_send_data_barrier(journal, commit_tid)) needs_barrier = 1; log_start_commit(journal, commit_tid); ret = log_wait_commit(journal, commit_tid); /* * In case we didn't commit a transaction, we have to flush * disk caches manually so that data really is on persistent * storage */ if (needs_barrier) blkdev_issue_flush(inode->i_sb->s_bdev, GFP_KERNEL, NULL); out: trace_ext3_sync_file_exit(inode, ret); return ret; }
static ssize_t ext3_file_write(struct kiocb *iocb, const struct iovec *iov, unsigned long nr_segs, loff_t pos) { struct file *file = iocb->ki_filp; struct inode *inode = file->f_dentry->d_inode; ssize_t ret; int err; ret = generic_file_aio_write(iocb, iov, nr_segs, pos); /* * Skip flushing if there was an error, or if nothing was written. */ if (ret <= 0) return ret; /* * If the inode is IS_SYNC, or is O_SYNC and we are doing data * journalling then we need to make sure that we force the transaction * to disk to keep all metadata uptodate synchronously. */ if (file->f_flags & O_SYNC) { /* * If we are non-data-journaled, then the dirty data has * already been flushed to backing store by generic_osync_inode, * and the inode has been flushed too if there have been any * modifications other than mere timestamp updates. * * Open question --- do we care about flushing timestamps too * if the inode is IS_SYNC? */ if (!ext3_should_journal_data(inode)) return ret; goto force_commit; } /* * So we know that there has been no forced data flush. If the inode * is marked IS_SYNC, we need to force one ourselves. */ if (!IS_SYNC(inode)) return ret; /* * Open question #2 --- should we force data to disk here too? If we * don't, the only impact is that data=writeback filesystems won't * flush data to disk automatically on IS_SYNC, only metadata (but * historically, that is what ext2 has done.) */ force_commit: err = ext3_force_commit(inode->i_sb); if (err) return err; return ret; }
int ext3_sync_file(struct file * file, struct dentry *dentry, int datasync) { struct inode *inode = dentry->d_inode; int ret = 0; J_ASSERT(ext3_journal_current_handle() == 0); /* * data=writeback: * The caller's filemap_fdatawrite()/wait will sync the data. * sync_inode() will sync the metadata * * data=ordered: * The caller's filemap_fdatawrite() will write the data and * sync_inode() will write the inode if it is dirty. Then the caller's * filemap_fdatawait() will wait on the pages. * * data=journal: * filemap_fdatawrite won't do anything (the buffers are clean). * ext3_force_commit will write the file data into the journal and * will wait on that. * filemap_fdatawait() will encounter a ton of newly-dirtied pages * (they were dirtied by commit). But that's OK - the blocks are * safe in-journal, which is all fsync() needs to ensure. */ if (ext3_should_journal_data(inode)) { ret = ext3_force_commit(inode->i_sb); goto out; } if (datasync && !(inode->i_state & I_DIRTY_DATASYNC)) goto flush; /* * The VFS has written the file data. If the inode is unaltered * then we need not start a commit. */ if (inode->i_state & (I_DIRTY_SYNC|I_DIRTY_DATASYNC)) { struct writeback_control wbc = { .sync_mode = WB_SYNC_ALL, .nr_to_write = 0, /* sys_fsync did this */ }; ret = sync_inode(inode, &wbc); goto out; } flush: /* * In case we didn't commit a transaction, we have to flush * disk caches manually so that data really is on persistent * storage */ if (test_opt(inode->i_sb, BARRIER)) blkdev_issue_flush(inode->i_sb->s_bdev, NULL); out: return ret; }
int ext3_sync_file(struct file * file, struct dentry *dentry, int datasync) { struct inode *inode = dentry->d_inode; struct ext3_inode_info *ei = EXT3_I(inode); journal_t *journal = EXT3_SB(inode->i_sb)->s_journal; int ret = 0; tid_t commit_tid; if (inode->i_sb->s_flags & MS_RDONLY) return 0; J_ASSERT(ext3_journal_current_handle() == NULL); /* * data=writeback,ordered: * The caller's filemap_fdatawrite()/wait will sync the data. * Metadata is in the journal, we wait for a proper transaction * to commit here. * * data=journal: * filemap_fdatawrite won't do anything (the buffers are clean). * ext3_force_commit will write the file data into the journal and * will wait on that. * filemap_fdatawait() will encounter a ton of newly-dirtied pages * (they were dirtied by commit). But that's OK - the blocks are * safe in-journal, which is all fsync() needs to ensure. */ if (ext3_should_journal_data(inode)) { ret = ext3_force_commit(inode->i_sb); goto out; } if (datasync) commit_tid = atomic_read(&ei->i_datasync_tid); else commit_tid = atomic_read(&ei->i_sync_tid); if (log_start_commit(journal, commit_tid)) { log_wait_commit(journal, commit_tid); goto out; } /* * In case we didn't commit a transaction, we have to flush * disk caches manually so that data really is on persistent * storage */ if (test_opt(inode->i_sb, BARRIER)) blkdev_issue_flush(inode->i_sb->s_bdev, GFP_KERNEL, NULL, BLKDEV_IFL_WAIT); out: return ret; }
int ext3_sync_file(struct file * file, struct dentry *dentry, int datasync) { struct inode *inode = dentry->d_inode; int ret = 0; J_ASSERT(ext3_journal_current_handle() == NULL); /* * data=writeback: * The caller's filemap_fdatawrite()/wait will sync the data. * sync_inode() will sync the metadata * * data=ordered: * The caller's filemap_fdatawrite() will write the data and * sync_inode() will write the inode if it is dirty. Then the caller's * filemap_fdatawait() will wait on the pages. * * data=journal: * filemap_fdatawrite won't do anything (the buffers are clean). * ext3_force_commit will write the file data into the journal and * will wait on that. * filemap_fdatawait() will encounter a ton of newly-dirtied pages * (they were dirtied by commit). But that's OK - the blocks are * safe in-journal, which is all fsync() needs to ensure. */ if (ext3_should_journal_data(inode)) { ret = ext3_force_commit(inode->i_sb); goto out; } /* * The VFS has written the file data. If the inode is unaltered * then we need not start a commit. */ if (inode->i_state & (I_DIRTY_SYNC|I_DIRTY_DATASYNC)) { struct writeback_control wbc = { .sync_mode = WB_SYNC_ALL, .nr_to_write = 0, /* sys_fsync did this */ }; ret = sync_inode(inode, &wbc); } out: return ret; }
/* * The ext3 forget function must perform a revoke if we are freeing data * which has been journaled. Metadata (eg. indirect blocks) must be * revoked in all cases. * * "bh" may be NULL: a metadata block may have been freed from memory * but there may still be a record of it in the journal, and that record * still needs to be revoked. */ int ext3_forget(handle_t *handle, int is_metadata, struct inode *inode, struct buffer_head *bh, ext3_fsblk_t blocknr) { int err; might_sleep(); trace_ext3_forget(inode, is_metadata, blocknr); BUFFER_TRACE(bh, "enter"); jbd_debug(4, "forgetting bh %p: is_metadata = %d, mode %o, " "data mode %lx\n", bh, is_metadata, inode->i_mode, test_opt(inode->i_sb, DATA_FLAGS)); /* Never use the revoke function if we are doing full data * journaling: there is no need to, and a V1 superblock won't * support it. Otherwise, only skip the revoke on un-journaled * data blocks. */ if (test_opt(inode->i_sb, DATA_FLAGS) == EXT3_MOUNT_JOURNAL_DATA || (!is_metadata && !ext3_should_journal_data(inode))) { if (bh) { BUFFER_TRACE(bh, "call journal_forget"); return ext3_journal_forget(handle, bh); } return 0; } /* * data!=journal && (is_metadata || should_journal_data(inode)) */ BUFFER_TRACE(bh, "call ext3_journal_revoke"); err = ext3_journal_revoke(handle, blocknr, bh); if (err) ext3_abort(inode->i_sb, __func__, "error %d when attempting revoke", err); BUFFER_TRACE(bh, "exit"); return err; }
/* * Called at inode eviction from icache */ void ext3_evict_inode (struct inode *inode) { struct ext3_inode_info *ei = EXT3_I(inode); struct ext3_block_alloc_info *rsv; handle_t *handle; int want_delete = 0; trace_ext3_evict_inode(inode); if (!inode->i_nlink && !is_bad_inode(inode)) { dquot_initialize(inode); want_delete = 1; } /* * When journalling data dirty buffers are tracked only in the journal. * So although mm thinks everything is clean and ready for reaping the * inode might still have some pages to write in the running * transaction or waiting to be checkpointed. Thus calling * journal_invalidatepage() (via truncate_inode_pages()) to discard * these buffers can cause data loss. Also even if we did not discard * these buffers, we would have no way to find them after the inode * is reaped and thus user could see stale data if he tries to read * them before the transaction is checkpointed. So be careful and * force everything to disk here... We use ei->i_datasync_tid to * store the newest transaction containing inode's data. * * Note that directories do not have this problem because they don't * use page cache. * * The s_journal check handles the case when ext3_get_journal() fails * and puts the journal inode. */ if (inode->i_nlink && ext3_should_journal_data(inode) && EXT3_SB(inode->i_sb)->s_journal && (S_ISLNK(inode->i_mode) || S_ISREG(inode->i_mode)) && inode->i_ino != EXT3_JOURNAL_INO) { tid_t commit_tid = atomic_read(&ei->i_datasync_tid); journal_t *journal = EXT3_SB(inode->i_sb)->s_journal; log_start_commit(journal, commit_tid); log_wait_commit(journal, commit_tid); filemap_write_and_wait(&inode->i_data); } truncate_inode_pages(&inode->i_data, 0); ext3_discard_reservation(inode); rsv = ei->i_block_alloc_info; ei->i_block_alloc_info = NULL; if (unlikely(rsv)) kfree(rsv); if (!want_delete) goto no_delete; handle = start_transaction(inode); if (IS_ERR(handle)) { /* * If we're going to skip the normal cleanup, we still need to * make sure that the in-core orphan linked list is properly * cleaned up. */ ext3_orphan_del(NULL, inode); goto no_delete; } if (IS_SYNC(inode)) handle->h_sync = 1; inode->i_size = 0; if (inode->i_blocks) ext3_truncate(inode); /* * Kill off the orphan record created when the inode lost the last * link. Note that ext3_orphan_del() has to be able to cope with the * deletion of a non-existent orphan - ext3_truncate() could * have removed the record. */ ext3_orphan_del(handle, inode); ei->i_dtime = get_seconds(); /* * One subtle ordering requirement: if anything has gone wrong * (transaction abort, IO errors, whatever), then we can still * do these next steps (the fs will already have been marked as * having errors), but we can't free the inode if the mark_dirty * fails. */ if (ext3_mark_inode_dirty(handle, inode)) { /* If that failed, just dquot_drop() and be done with that */ dquot_drop(inode); clear_inode(inode); } else { ext3_xattr_delete_inode(handle, inode); dquot_free_inode(inode); dquot_drop(inode); clear_inode(inode); ext3_free_inode(handle, inode); } ext3_journal_stop(handle); return; no_delete: clear_inode(inode); dquot_drop(inode); }