From aedf8a783ee67ab18528c853803747d14a5d8f7f Mon Sep 17 00:00:00 2001 From: jason50123 Date: Fri, 3 May 2024 20:07:21 +0800 Subject: [PATCH] Support Linux 6.8 To align with best practices recommended by Linux kernel v6.8, this commit replaces direct accesses to the __i_atime and __i_mtime fields with the newly introduced accessor functions. The functions used, such as inode_get_atime_sec and simple_inode_init_ts, encapsulate direct interactions with these inode fields. This change not only enhances code readability and maintainability but also ensures that the codebase adheres to the evolving kernel API standards. This approach minimizes direct manipulations of internal structures, thereby reducing potential for bugs and improving future compatibility with kernel updates. --- file.c | 15 ++++++++++++++- inode.c | 41 ++++++++++++++++++++++++++++++++++------- super.c | 11 ++++++++++- 3 files changed, 58 insertions(+), 9 deletions(-) diff --git a/file.c b/file.c index 4320c72..408e56b 100644 --- a/file.c +++ b/file.c @@ -96,10 +96,19 @@ static int simplefs_readpage(struct file *file, struct page *page) /* Called by the page cache to write a dirty page to the physical disk (when * sync is called or when memory is needed). */ +#if LINUX_VERSION_CODE >= KERNEL_VERSION(6, 8, 0) +static int simplefs_writepage(struct page *page, struct writeback_control *wbc) +{ + struct folio *folio = page_folio(page); + return __block_write_full_folio(page->mapping->host, folio, + simplefs_file_get_block, wbc); +} +#else static int simplefs_writepage(struct page *page, struct writeback_control *wbc) { return block_write_full_page(page, simplefs_file_get_block, wbc); } +#endif /* Called by the VFS when a write() syscall is made on a file, before writing * the data into the page cache. This function checks if the write operation @@ -183,7 +192,11 @@ static int simplefs_write_end(struct file *file, /* Update inode metadata */ inode->i_blocks = inode->i_size / SIMPLEFS_BLOCK_SIZE + 2; -#if LINUX_VERSION_CODE >= KERNEL_VERSION(6, 6, 0) +#if LINUX_VERSION_CODE >= KERNEL_VERSION(6, 7, 0) + cur_time = current_time(inode); + inode_set_mtime_to_ts(inode, cur_time); + inode_set_ctime_to_ts(inode, cur_time); +#elif LINUX_VERSION_CODE >= KERNEL_VERSION(6, 6, 0) cur_time = current_time(inode); inode->i_mtime = cur_time; inode_set_ctime_to_ts(inode, cur_time); diff --git a/inode.c b/inode.c index 504fbd2..cb6f3ff 100644 --- a/inode.c +++ b/inode.c @@ -63,10 +63,16 @@ struct inode *simplefs_iget(struct super_block *sb, unsigned long ino) inode->i_ctime.tv_nsec = 0; #endif +#if LINUX_VERSION_CODE >= KERNEL_VERSION(6, 7, 0) + inode_set_atime(inode, (time64_t) le32_to_cpu(cinode->i_atime), 0); + inode_set_mtime(inode, (time64_t) le32_to_cpu(cinode->i_mtime), 0); +#else inode->i_atime.tv_sec = (time64_t) le32_to_cpu(cinode->i_atime); inode->i_atime.tv_nsec = 0; inode->i_mtime.tv_sec = (time64_t) le32_to_cpu(cinode->i_mtime); inode->i_mtime.tv_nsec = 0; +#endif + inode->i_blocks = le32_to_cpu(cinode->i_blocks); set_nlink(inode, le32_to_cpu(cinode->i_nlink)); @@ -161,7 +167,12 @@ static struct dentry *simplefs_lookup(struct inode *dir, brelse(bh); /* Update directory access time */ +#if LINUX_VERSION_CODE >= KERNEL_VERSION(6, 7, 0) + inode_set_atime_to_ts(dir, current_time(dir)); +#else dir->i_atime = current_time(dir); +#endif + mark_inode_dirty(dir); /* Fill the dentry with the inode */ @@ -219,7 +230,9 @@ static struct inode *simplefs_new_inode(struct inode *dir, mode_t mode) #endif set_nlink(inode, 1); -#if LINUX_VERSION_CODE >= KERNEL_VERSION(6, 6, 0) +#if LINUX_VERSION_CODE >= KERNEL_VERSION(6, 7, 0) + simple_inode_init_ts(inode); +#elif LINUX_VERSION_CODE >= KERNEL_VERSION(6, 6, 0) cur_time = current_time(inode); inode->i_atime = inode->i_mtime = cur_time; inode_set_ctime_to_ts(inode, cur_time); @@ -261,7 +274,9 @@ static struct inode *simplefs_new_inode(struct inode *dir, mode_t mode) set_nlink(inode, 1); } -#if LINUX_VERSION_CODE >= KERNEL_VERSION(6, 6, 0) +#if LINUX_VERSION_CODE >= KERNEL_VERSION(6, 7, 0) + simple_inode_init_ts(inode); +#elif LINUX_VERSION_CODE >= KERNEL_VERSION(6, 6, 0) cur_time = current_time(inode); inode->i_atime = inode->i_mtime = cur_time; inode_set_ctime_to_ts(inode, cur_time); @@ -395,7 +410,9 @@ static int simplefs_create(struct inode *dir, /* Update stats and mark dir and new inode dirty */ mark_inode_dirty(inode); -#if LINUX_VERSION_CODE >= KERNEL_VERSION(6, 6, 0) +#if LINUX_VERSION_CODE >= KERNEL_VERSION(6, 7, 0) + simple_inode_init_ts(dir); +#elif LINUX_VERSION_CODE >= KERNEL_VERSION(6, 6, 0) cur_time = current_time(dir); dir->i_mtime = dir->i_atime = cur_time; inode_set_ctime_to_ts(dir, cur_time); @@ -537,7 +554,9 @@ static int simplefs_unlink(struct inode *dir, struct dentry *dentry) goto clean_inode; /* Update inode stats */ -#if LINUX_VERSION_CODE >= KERNEL_VERSION(6, 6, 0) +#if LINUX_VERSION_CODE >= KERNEL_VERSION(6, 7, 0) + simple_inode_init_ts(dir); +#elif LINUX_VERSION_CODE >= KERNEL_VERSION(6, 6, 0) cur_time = current_time(dir); dir->i_mtime = dir->i_atime = cur_time; inode_set_ctime_to_ts(dir, cur_time); @@ -606,7 +625,11 @@ static int simplefs_unlink(struct inode *dir, struct dentry *dentry) i_gid_write(inode, 0); inode->i_mode = 0; -#if LINUX_VERSION_CODE >= KERNEL_VERSION(6, 6, 0) +#if LINUX_VERSION_CODE >= KERNEL_VERSION(6, 7, 0) + inode_set_mtime(inode, 0, 0); + inode_set_atime(inode, 0, 0); + inode_set_ctime(inode, 0, 0); +#elif LINUX_VERSION_CODE >= KERNEL_VERSION(6, 6, 0) inode->i_mtime.tv_sec = inode->i_atime.tv_sec = 0; inode_set_ctime(inode, 0, 0); #else @@ -749,7 +772,9 @@ static int simplefs_rename(struct inode *old_dir, brelse(bh2); /* Update new parent inode metadata */ -#if LINUX_VERSION_CODE >= KERNEL_VERSION(6, 6, 0) +#if LINUX_VERSION_CODE >= KERNEL_VERSION(6, 7, 0) + simple_inode_init_ts(new_dir); +#elif LINUX_VERSION_CODE >= KERNEL_VERSION(6, 6, 0) cur_time = current_time(new_dir); new_dir->i_atime = new_dir->i_mtime = cur_time; inode_set_ctime_to_ts(new_dir, cur_time); @@ -768,7 +793,9 @@ static int simplefs_rename(struct inode *old_dir, goto release_new; /* Update old parent inode metadata */ -#if LINUX_VERSION_CODE >= KERNEL_VERSION(6, 6, 0) +#if LINUX_VERSION_CODE >= KERNEL_VERSION(6, 7, 0) + simple_inode_init_ts(old_dir); +#elif LINUX_VERSION_CODE >= KERNEL_VERSION(6, 6, 0) cur_time = current_time(old_dir); old_dir->i_atime = old_dir->i_mtime = cur_time; inode_set_ctime_to_ts(old_dir, cur_time); diff --git a/super.c b/super.c index 0126603..e803392 100644 --- a/super.c +++ b/super.c @@ -8,7 +8,11 @@ #include #include "simplefs.h" - +struct dentry *simplefs_mount(struct file_system_type *fs_type, + int flags, + const char *dev_name, + void *data); +void simplefs_kill_sb(struct super_block *sb); static struct kmem_cache *simplefs_inode_cache; int simplefs_init_inode_cache(void) @@ -78,8 +82,13 @@ static int simplefs_write_inode(struct inode *inode, disk_inode->i_ctime = inode->i_ctime.tv_sec; #endif +#if LINUX_VERSION_CODE >= KERNEL_VERSION(6, 7, 0) + disk_inode->i_atime = inode_get_atime_sec(inode); + disk_inode->i_atime = inode_get_mtime_sec(inode); +#else disk_inode->i_atime = inode->i_atime.tv_sec; disk_inode->i_mtime = inode->i_mtime.tv_sec; +#endif disk_inode->i_blocks = inode->i_blocks; disk_inode->i_nlink = inode->i_nlink; disk_inode->ei_block = ci->ei_block;