[f2fs] Move fsync handlers to VnodeF2fs
Test: fx sync-tests
Change-Id: I6f8e2f1c26e8486192da7d02185953db9a00bbd7
Reviewed-on: https://fuchsia-review.googlesource.com/c/third_party/f2fs/+/536510
Reviewed-by: Brett Wilson <brettw@google.com>
diff --git a/file.cc b/file.cc
index 1dd7ea9..3b9b8a1 100644
--- a/file.cc
+++ b/file.cc
@@ -89,118 +89,6 @@
// }
#endif
-int File::NeedToSyncDir(SbInfo *sbi, VnodeF2fs *vnode) {
-#if 0 // porting needed
- // dentry *dentry;
-#endif
- nid_t pino = 0;
-
- vnode = static_cast<VnodeF2fs *>(Igrab((void *)vnode));
-#if 0 // porting needed
- // dentry = d_find_any_alias(vnode);
- // if (!dentry) {
- // // Iput(inode);
- // return 0;
- // }
- // pino = dentry->d_parent->d_inode->i_ino;
- // dput(dentry);
-#endif
- Iput(vnode);
- return !Vfs()->Nodemgr().IsCheckpointedNode(pino);
-}
-
-zx_status_t File::SyncFile(loff_t start, loff_t end, int datasync) {
- SbInfo &sbi = Vfs()->GetSbInfo();
- uint64_t cur_version;
- zx_status_t ret = 0;
- bool need_cp = false;
-#if 0 // porting needed
- // WritebackControl wbc;
-
- // wbc.sync_mode = WB_SYNC_ALL;
- // wbc.nr_to_write = LONG_MAX;
- // wbc.for_reclaim = 0;
-
- // ret = filemap_write_and_wait_range(inode->i_mapping, start, end);
- // if (ret)
- // return ret;
-#endif
-
- fbl::AutoLock lock(&i_mutex_);
-
-#if 0 // porting needed
- // if (inode->i_sb->s_flags & MS_RDONLY)
- // goto out;
- // if (datasync && !(i_state & I_DIRTY_DATASYNC)) {
- // goto out;
- //}
-#endif
-
- do {
- fbl::AutoLock cplock(&sbi.cp_mutex);
- cur_version = LeToCpu(GetCheckpoint(&sbi)->checkpoint_ver);
- } while (false);
-
-#if 0 // porting needed
- // if (fi.data_version != cur_version &&
- // !(i_state & I_DIRTY)) {
- // goto out;
- //}
-#endif
- fi_.data_version--;
-
- if (!S_ISREG(i_mode_) || i_nlink_ != 1)
- need_cp = true;
- if (IsInodeFlagSet(&fi_, InodeInfoFlag::kNeedCp))
- need_cp = true;
- if (!Vfs()->SpaceForRollForward())
- need_cp = true;
- if (NeedToSyncDir(&sbi, this))
- need_cp = true;
-
-#if 0 // porting needed
- // WriteInode(nullptr);
-#endif
-
- // clang-format off
- // TODO(unknown): fsync recovery
-#if 0 // porting needed
- // if (need_cp) {
-#else
- if (true) {
-#endif
- WriteInode(nullptr);
- /* all the dirty node pages should be flushed for POR */
- ret = Vfs()->SyncFs(1);
- ClearInodeFlag(&fi_, InodeInfoFlag::kNeedCp);
- }
- else {
- Page *node_page = nullptr;
- int mark = !Vfs()->Nodemgr().IsCheckpointedNode(Ino());
- if (ret = Vfs()->Nodemgr().GetNodePage(Ino(), &node_page); ret != ZX_OK) {
- return ret;
- }
- // clang-format on
-
- Vfs()->Nodemgr().SetFsyncMark(node_page, 1);
- Vfs()->Nodemgr().SetDentryMark(node_page, mark);
-
- UpdateInode(node_page);
- F2fsPutPage(node_page, 1);
-
-#if 0 // porting needed
- // while (Vfs()->Nodemgr().SyncNodePages(Ino(), &wbc) == 0)
- // WriteInode(nullptr);
- // filemap_fdatawait_range(nullptr,//sbi->node_inode->i_mapping,
- // 0, LONG_MAX);
-#endif
-}
-#if 0 // porting needed
- // out:
-#endif
-return ret;
-}
-
#if 0 // porting needed
// int File::F2fsFileMmap(/*file *file,*/ vm_area_struct *vma) {
// // file_accessed(file);
diff --git a/vnode.cc b/vnode.cc
index 88daf93..90ac2ff 100644
--- a/vnode.cc
+++ b/vnode.cc
@@ -531,18 +531,8 @@
void MarkInodeDirty(VnodeF2fs *vnode) { vnode->WriteInode(nullptr); }
void VnodeF2fs::Sync(SyncCallback closure) {
- File *file;
-
- if (closure) {
- if (S_ISDIR(this->i_mode_)) {
- std::cout << "Sync: Invalid args(fsync to directory)" << std::endl;
- closure(ZX_ERR_INVALID_ARGS);
- } else {
- file = static_cast<File *>(this);
- file->SyncFile(0, file->i_size_, 1);
- closure(ZX_OK);
- }
- }
+ SyncFile(0, i_size_, 0);
+ closure(ZX_OK);
}
zx_status_t VnodeF2fs::QueryFilesystem(fuchsia_io::wire::FilesystemInfo *info) {
@@ -567,4 +557,116 @@
return ZX_OK;
}
+zx_status_t VnodeF2fs::SyncFile(loff_t start, loff_t end, int datasync) {
+ SbInfo &sbi = Vfs()->GetSbInfo();
+ uint64_t cur_version;
+ zx_status_t ret = 0;
+ bool need_cp = false;
+#if 0 // porting needed
+ // WritebackControl wbc;
+
+ // wbc.sync_mode = WB_SYNC_ALL;
+ // wbc.nr_to_write = LONG_MAX;
+ // wbc.for_reclaim = 0;
+
+ // ret = filemap_write_and_wait_range(inode->i_mapping, start, end);
+ // if (ret)
+ // return ret;
+#endif
+
+ fbl::AutoLock lock(&i_mutex_);
+
+#if 0 // porting needed
+ // if (inode->i_sb->s_flags & MS_RDONLY)
+ // goto out;
+ // if (datasync && !(i_state & I_DIRTY_DATASYNC)) {
+ // goto out;
+ //}
+#endif
+
+ do {
+ fbl::AutoLock cplock(&sbi.cp_mutex);
+ cur_version = LeToCpu(GetCheckpoint(&sbi)->checkpoint_ver);
+ } while (false);
+
+#if 0 // porting needed
+ // if (fi.data_version != cur_version &&
+ // !(i_state & I_DIRTY)) {
+ // goto out;
+ //}
+#endif
+ fi_.data_version--;
+
+ if (!S_ISREG(i_mode_) || i_nlink_ != 1)
+ need_cp = true;
+ if (IsInodeFlagSet(&fi_, InodeInfoFlag::kNeedCp))
+ need_cp = true;
+ if (!Vfs()->SpaceForRollForward())
+ need_cp = true;
+ if (NeedToSyncDir(&sbi, this))
+ need_cp = true;
+
+#if 0 // porting needed
+ // WriteInode(nullptr);
+#endif
+
+ // clang-format off
+ // TODO(unknown): fsync recovery
+#if 0 // porting needed
+ // if (need_cp) {
+#else
+ if (true) {
+#endif
+ WriteInode(nullptr);
+ /* all the dirty node pages should be flushed for POR */
+ ret = Vfs()->SyncFs(1);
+ ClearInodeFlag(&fi_, InodeInfoFlag::kNeedCp);
+ }
+ else {
+ Page *node_page = nullptr;
+ int mark = !Vfs()->Nodemgr().IsCheckpointedNode(Ino());
+ if (ret = Vfs()->Nodemgr().GetNodePage(Ino(), &node_page); ret != ZX_OK) {
+ return ret;
+ }
+ // clang-format on
+
+ Vfs()->Nodemgr().SetFsyncMark(node_page, 1);
+ Vfs()->Nodemgr().SetDentryMark(node_page, mark);
+
+ UpdateInode(node_page);
+ F2fsPutPage(node_page, 1);
+
+#if 0 // porting needed
+ // while (Vfs()->Nodemgr().SyncNodePages(Ino(), &wbc) == 0)
+ // WriteInode(nullptr);
+ // filemap_fdatawait_range(nullptr,//sbi->node_inode->i_mapping,
+ // 0, LONG_MAX);
+#endif
+}
+#if 0 // porting needed
+ // out:
+#endif
+return ret;
+}
+
+int VnodeF2fs::NeedToSyncDir(SbInfo *sbi, VnodeF2fs *vnode) {
+#if 0 // porting needed
+ // dentry *dentry;
+#endif
+ nid_t pino = 0;
+
+ vnode = static_cast<VnodeF2fs *>(Igrab((void *)vnode));
+#if 0 // porting needed
+ // dentry = d_find_any_alias(vnode);
+ // if (!dentry) {
+ // // Iput(inode);
+ // return 0;
+ // }
+ // pino = dentry->d_parent->d_inode->i_ino;
+ // dput(dentry);
+#endif
+ Iput(vnode);
+ return !Vfs()->Nodemgr().IsCheckpointedNode(pino);
+}
+
} // namespace f2fs
diff --git a/vnode.h b/vnode.h
index 1077770..4b8d8e8 100644
--- a/vnode.h
+++ b/vnode.h
@@ -30,6 +30,8 @@
zx_status_t Close();
void Sync(SyncCallback closure) final;
+ zx_status_t SyncFile(loff_t start, loff_t end, int datasync);
+ int NeedToSyncDir(SbInfo *sbi, VnodeF2fs *vnode);
zx_status_t QueryFilesystem(fuchsia_io::wire::FilesystemInfo *info) final;