Submitted by: Zeckma Date: 2026-05-09 Initial Package Version: efe55b Upstream Status: Upstream is basically defunct, not applied Origin: Self Description: Builds the kernel module unconditionally, the library as shared instead of static, and fixes the kernel module to prevent build failures and make sure it uses up to date versions of interfaces for the kernel, glibc, and GCC. diff '--color=auto' -Naurp s4-3b1-pc7300-efe55b8cc917e3e27bcae9786c5b5dec0469be45.orig/Makefile s4-3b1-pc7300-efe55b8cc917e3e27bcae9786c5b5dec0469be45/Makefile --- s4-3b1-pc7300-efe55b8cc917e3e27bcae9786c5b5dec0469be45.orig/Makefile 2022-10-23 19:25:15.000000000 -0600 +++ s4-3b1-pc7300-efe55b8cc917e3e27bcae9786c5b5dec0469be45/Makefile 2026-05-09 21:04:51.100647377 -0600 @@ -14,12 +14,12 @@ INSTALLDIR = ~/bin INC = -I. -DEBUG = -g -Wall +DEBUG = -g -Wall -fPIC OPTIM = -O CFLAGS = $(OPTIM) $(DEBUG) $(INC) CC = gcc -S4LIB = libs4.a +S4LIB = libs4.so S4DATE = s4date S4DISK = s4disk @@ -52,7 +52,7 @@ s4fsck.o : s4fsck.c $(CC) $(CFLAGS) -c -DFsTYPE=2 $< $(S4LIB): $(LIBOBJ) - $(AR) rvu $(S4LIB) $(LIBOBJ) + $(CC) -shared -o $(S4LIB) $(LIBOBJ) $(S4DATE): s4date.o $(LIB) $(CC) s4date.o $(LIBOPTS) -o $@ diff '--color=auto' -Naurp s4-3b1-pc7300-efe55b8cc917e3e27bcae9786c5b5dec0469be45.orig/sysv/dir.c s4-3b1-pc7300-efe55b8cc917e3e27bcae9786c5b5dec0469be45/sysv/dir.c --- s4-3b1-pc7300-efe55b8cc917e3e27bcae9786c5b5dec0469be45.orig/sysv/dir.c 2022-10-23 19:25:15.000000000 -0600 +++ s4-3b1-pc7300-efe55b8cc917e3e27bcae9786c5b5dec0469be45/sysv/dir.c 2026-05-09 21:04:51.100905902 -0600 @@ -28,37 +28,45 @@ const struct file_operations sysv_dir_op .fsync = generic_file_fsync, }; -static inline void dir_put_page(struct page *page) +static void dir_commit_chunk(struct folio *folio, loff_t pos, unsigned len) { - kunmap(page); - put_page(page); -} - -static int dir_commit_chunk(struct page *page, loff_t pos, unsigned len) -{ - struct address_space *mapping = page->mapping; + struct address_space *mapping = folio->mapping; struct inode *dir = mapping->host; - int err = 0; - block_write_end(NULL, mapping, pos, len, len, page, NULL); + block_write_end(pos, len, len, folio); if (pos+len > dir->i_size) { i_size_write(dir, pos+len); mark_inode_dirty(dir); } - if (IS_DIRSYNC(dir)) - err = write_one_page(page); - else - unlock_page(page); + folio_unlock(folio); +} + +static int sysv_handle_dirsync(struct inode *dir) +{ + int err; + + err = filemap_write_and_wait(dir->i_mapping); + if (!err) + err = sync_inode_metadata(dir, 1); return err; } -static struct page * dir_get_page(struct inode *dir, unsigned long n) +/* + * Calls to dir_get_folio()/folio_release_kmap() must be nested according to the + * rules documented in mm/highmem.rst. + * + * NOTE: sysv_find_entry() and sysv_dotdot() act as calls to dir_get_folio() + * and must be treated accordingly for nesting purposes. + */ +static void *dir_get_folio(struct inode *dir, unsigned long n, + struct folio **foliop) { - struct address_space *mapping = dir->i_mapping; - struct page *page = read_mapping_page(mapping, n, NULL); - if (!IS_ERR(page)) - kmap(page); - return page; + struct folio *folio = read_mapping_folio(dir->i_mapping, n, NULL); + + if (IS_ERR(folio)) + return ERR_CAST(folio); + *foliop = folio; + return kmap_local_folio(folio, 0); } static int sysv_readdir(struct file *file, struct dir_context *ctx) @@ -80,11 +88,11 @@ static int sysv_readdir(struct file *fil for ( ; n < npages; n++, offset = 0) { char *kaddr, *limit; struct sysv_dir_entry *de; - struct page *page = dir_get_page(inode, n); + struct folio *folio; - if (IS_ERR(page)) + kaddr = dir_get_folio(inode, n, &folio); + if (IS_ERR(kaddr)) continue; - kaddr = (char *)page_address(page); de = (struct sysv_dir_entry *)(kaddr+offset); limit = kaddr + PAGE_SIZE - SYSV_DIRSIZE; for ( ;(char*)de <= limit; de++, ctx->pos += sizeof(*de)) { @@ -96,11 +104,11 @@ static int sysv_readdir(struct file *fil if (!dir_emit(ctx, name, strnlen(name,SYSV_NAMELEN), fs16_to_cpu(SYSV_SB(sb), de->inode), DT_UNKNOWN)) { - dir_put_page(page); + folio_release_kmap(folio, kaddr); return 0; } } - dir_put_page(page); + folio_release_kmap(folio, kaddr); } return 0; } @@ -124,30 +132,26 @@ static inline int namecompare(int len, i * itself (as a parameter - res_dir). It does NOT read the inode of the * entry - you'll have to do that yourself if you want to. */ -struct sysv_dir_entry *sysv_find_entry(struct dentry *dentry, struct page **res_page) +struct sysv_dir_entry *sysv_find_entry(struct dentry *dentry, struct folio **foliop) { const char * name = dentry->d_name.name; int namelen = dentry->d_name.len; struct inode * dir = d_inode(dentry->d_parent); unsigned long start, n; unsigned long npages = dir_pages(dir); - struct page *page = NULL; struct sysv_dir_entry *de; - *res_page = NULL; - start = SYSV_I(dir)->i_dir_start_lookup; if (start >= npages) start = 0; n = start; do { - char *kaddr; - page = dir_get_page(dir, n); - if (!IS_ERR(page)) { - kaddr = (char*)page_address(page); - de = (struct sysv_dir_entry *) kaddr; - kaddr += PAGE_SIZE - SYSV_DIRSIZE; + char *kaddr = dir_get_folio(dir, n, foliop); + + if (!IS_ERR(kaddr)) { + de = (struct sysv_dir_entry *)kaddr; + kaddr += folio_size(*foliop) - SYSV_DIRSIZE; for ( ; (char *) de <= kaddr ; de++) { if (!de->inode) continue; @@ -155,7 +159,7 @@ struct sysv_dir_entry *sysv_find_entry(s name, de->name)) goto found; } - dir_put_page(page); + folio_release_kmap(*foliop, kaddr); } if (++n >= npages) @@ -166,7 +170,6 @@ struct sysv_dir_entry *sysv_find_entry(s found: SYSV_I(dir)->i_dir_start_lookup = n; - *res_page = page; return de; } @@ -175,7 +178,7 @@ int sysv_add_link(struct dentry *dentry, struct inode *dir = d_inode(dentry->d_parent); const char * name = dentry->d_name.name; int namelen = dentry->d_name.len; - struct page *page = NULL; + struct folio *folio = NULL; struct sysv_dir_entry * de; unsigned long npages = dir_pages(dir); unsigned long n; @@ -185,96 +188,94 @@ int sysv_add_link(struct dentry *dentry, /* We take care of directory expansion in the same loop */ for (n = 0; n <= npages; n++) { - page = dir_get_page(dir, n); - err = PTR_ERR(page); - if (IS_ERR(page)) - goto out; - kaddr = (char*)page_address(page); + kaddr = dir_get_folio(dir, n, &folio); + if (IS_ERR(kaddr)) + return PTR_ERR(kaddr); de = (struct sysv_dir_entry *)kaddr; kaddr += PAGE_SIZE - SYSV_DIRSIZE; + while ((char *)de <= kaddr) { if (!de->inode) goto got_it; err = -EEXIST; if (namecompare(namelen, SYSV_NAMELEN, name, de->name)) - goto out_page; + goto out_folio; de++; } - dir_put_page(page); + folio_release_kmap(folio, kaddr); } BUG(); return -EINVAL; got_it: - pos = page_offset(page) + - (char*)de - (char*)page_address(page); - lock_page(page); - err = sysv_prepare_chunk(page, pos, SYSV_DIRSIZE); + pos = folio_pos(folio) + offset_in_folio(folio, de); + folio_lock(folio); + err = sysv_prepare_chunk(folio, pos, SYSV_DIRSIZE); if (err) goto out_unlock; memcpy (de->name, name, namelen); memset (de->name + namelen, 0, SYSV_DIRSIZE - namelen - 2); de->inode = cpu_to_fs16(SYSV_SB(inode->i_sb), inode->i_ino); - err = dir_commit_chunk(page, pos, SYSV_DIRSIZE); - dir->i_mtime = dir->i_ctime = current_time(dir); + dir_commit_chunk(folio, pos, SYSV_DIRSIZE); + inode_set_mtime_to_ts(dir, inode_set_ctime_current(dir)); mark_inode_dirty(dir); -out_page: - dir_put_page(page); -out: + err = sysv_handle_dirsync(dir); +out_folio: + folio_release_kmap(folio, kaddr); return err; out_unlock: - unlock_page(page); - goto out_page; + folio_unlock(folio); + goto out_folio; } -int sysv_delete_entry(struct sysv_dir_entry *de, struct page *page) +int sysv_delete_entry(struct sysv_dir_entry *de, struct folio *folio) { - struct inode *inode = page->mapping->host; - char *kaddr = (char*)page_address(page); - loff_t pos = page_offset(page) + (char *)de - kaddr; + struct inode *inode = folio->mapping->host; + loff_t pos = folio_pos(folio) + offset_in_folio(folio, de); int err; - lock_page(page); - err = sysv_prepare_chunk(page, pos, SYSV_DIRSIZE); - BUG_ON(err); + folio_lock(folio); + err = sysv_prepare_chunk(folio, pos, SYSV_DIRSIZE); + if (err) { + folio_unlock(folio); + return err; + } de->inode = 0; - err = dir_commit_chunk(page, pos, SYSV_DIRSIZE); - dir_put_page(page); - inode->i_ctime = inode->i_mtime = current_time(inode); + dir_commit_chunk(folio, pos, SYSV_DIRSIZE); + inode_set_mtime_to_ts(inode, inode_set_ctime_current(inode)); mark_inode_dirty(inode); - return err; + return sysv_handle_dirsync(inode);; } int sysv_make_empty(struct inode *inode, struct inode *dir) { - struct page *page = grab_cache_page(inode->i_mapping, 0); + struct folio *folio = filemap_grab_folio(inode->i_mapping, 0); struct sysv_dir_entry * de; - char *base; + char *kaddr; int err; - if (!page) - return -ENOMEM; - err = sysv_prepare_chunk(page, 0, 2 * SYSV_DIRSIZE); + if (IS_ERR(folio)) + return PTR_ERR(folio); + err = sysv_prepare_chunk(folio, 0, 2 * SYSV_DIRSIZE); if (err) { - unlock_page(page); + folio_unlock(folio); goto fail; } - kmap(page); - - base = (char*)page_address(page); - memset(base, 0, PAGE_SIZE); + kaddr = kmap_local_folio(folio, 0); + memset(kaddr, 0, folio_size(folio)); - de = (struct sysv_dir_entry *) base; + de = (struct sysv_dir_entry *)kaddr; de->inode = cpu_to_fs16(SYSV_SB(inode->i_sb), inode->i_ino); strcpy(de->name,"."); de++; de->inode = cpu_to_fs16(SYSV_SB(inode->i_sb), dir->i_ino); strcpy(de->name,".."); - kunmap(page); - err = dir_commit_chunk(page, 0, 2 * SYSV_DIRSIZE); + kunmap_local(kaddr); + dir_commit_chunk(folio, 0, 2 * SYSV_DIRSIZE); + err = sysv_handle_dirsync(inode); fail: - put_page(page); + folio_put(folio); return err; } @@ -284,21 +285,17 @@ fail: int sysv_empty_dir(struct inode * inode) { struct super_block *sb = inode->i_sb; - struct page *page = NULL; + struct folio *folio = NULL; unsigned long i, npages = dir_pages(inode); + char *kaddr; for (i = 0; i < npages; i++) { - char *kaddr; struct sysv_dir_entry * de; - page = dir_get_page(inode, i); - if (IS_ERR(page)) + kaddr = dir_get_folio(inode, i, &folio); + if (IS_ERR(kaddr)) continue; - kaddr = (char *)page_address(page); - de = (struct sysv_dir_entry *)kaddr; - kaddr += PAGE_SIZE-SYSV_DIRSIZE; - for ( ;(char *)de <= kaddr; de++) { if (!de->inode) continue; @@ -314,55 +311,55 @@ int sysv_empty_dir(struct inode * inode) if (de->name[1] != '.' || de->name[2]) goto not_empty; } - dir_put_page(page); + folio_release_kmap(folio, kaddr); } return 1; not_empty: - dir_put_page(page); + folio_release_kmap(folio, kaddr); return 0; } /* Releases the page */ -void sysv_set_link(struct sysv_dir_entry *de, struct page *page, +int sysv_set_link(struct sysv_dir_entry *de, struct folio *folio, struct inode *inode) { - struct inode *dir = page->mapping->host; - loff_t pos = page_offset(page) + - (char *)de-(char*)page_address(page); + struct inode *dir = folio->mapping->host; + loff_t pos = folio_pos(folio) + offset_in_folio(folio, de); int err; - lock_page(page); - err = sysv_prepare_chunk(page, pos, SYSV_DIRSIZE); - BUG_ON(err); + folio_lock(folio); + err = sysv_prepare_chunk(folio, pos, SYSV_DIRSIZE); + if (err) { + folio_unlock(folio); + return err; + } de->inode = cpu_to_fs16(SYSV_SB(inode->i_sb), inode->i_ino); - err = dir_commit_chunk(page, pos, SYSV_DIRSIZE); - dir_put_page(page); - dir->i_mtime = dir->i_ctime = current_time(dir); + dir_commit_chunk(folio, pos, SYSV_DIRSIZE); + inode_set_mtime_to_ts(dir, inode_set_ctime_current(dir)); mark_inode_dirty(dir); + return sysv_handle_dirsync(inode); } -struct sysv_dir_entry * sysv_dotdot (struct inode *dir, struct page **p) +struct sysv_dir_entry * sysv_dotdot (struct inode *dir, struct folio **foliop) { - struct page *page = dir_get_page(dir, 0); - struct sysv_dir_entry *de = NULL; + struct sysv_dir_entry *de = dir_get_folio(dir, 0, foliop);; - if (!IS_ERR(page)) { - de = (struct sysv_dir_entry*) page_address(page) + 1; - *p = page; + if (IS_ERR(de)) { + return NULL; } - return de; + return de + 1; } ino_t sysv_inode_by_name(struct dentry *dentry) { - struct page *page; - struct sysv_dir_entry *de = sysv_find_entry (dentry, &page); + struct folio *folio; + struct sysv_dir_entry *de = sysv_find_entry (dentry, &folio); ino_t res = 0; if (de) { res = fs16_to_cpu(SYSV_SB(dentry->d_sb), de->inode); - dir_put_page(page); + folio_release_kmap(folio, de); } return res; } diff '--color=auto' -Naurp s4-3b1-pc7300-efe55b8cc917e3e27bcae9786c5b5dec0469be45.orig/sysv/file.c s4-3b1-pc7300-efe55b8cc917e3e27bcae9786c5b5dec0469be45/sysv/file.c --- s4-3b1-pc7300-efe55b8cc917e3e27bcae9786c5b5dec0469be45.orig/sysv/file.c 2022-10-23 19:25:15.000000000 -0600 +++ s4-3b1-pc7300-efe55b8cc917e3e27bcae9786c5b5dec0469be45/sysv/file.c 2026-05-09 21:04:51.101156913 -0600 @@ -26,15 +26,16 @@ const struct file_operations sysv_file_o .write_iter = generic_file_write_iter, .mmap = generic_file_mmap, .fsync = generic_file_fsync, - .splice_read = generic_file_splice_read, + .splice_read = filemap_splice_read, }; -static int sysv_setattr(struct dentry *dentry, struct iattr *attr) +static int sysv_setattr(struct mnt_idmap *idmap, +struct dentry *dentry, struct iattr *attr) { struct inode *inode = d_inode(dentry); int error; - error = setattr_prepare(dentry, attr); + error = setattr_prepare(&nop_mnt_idmap, dentry, attr); if (error) return error; @@ -47,7 +48,7 @@ static int sysv_setattr(struct dentry *d sysv_truncate(inode); } - setattr_copy(inode, attr); + setattr_copy(&nop_mnt_idmap, inode, attr); mark_inode_dirty(inode); return 0; } diff '--color=auto' -Naurp s4-3b1-pc7300-efe55b8cc917e3e27bcae9786c5b5dec0469be45.orig/sysv/ialloc.c s4-3b1-pc7300-efe55b8cc917e3e27bcae9786c5b5dec0469be45/sysv/ialloc.c --- s4-3b1-pc7300-efe55b8cc917e3e27bcae9786c5b5dec0469be45.orig/sysv/ialloc.c 2022-10-23 19:25:15.000000000 -0600 +++ s4-3b1-pc7300-efe55b8cc917e3e27bcae9786c5b5dec0469be45/sysv/ialloc.c 2026-05-09 21:04:51.101307365 -0600 @@ -163,9 +163,9 @@ struct inode * sysv_new_inode(const stru *sbi->s_sb_fic_count = cpu_to_fs16(sbi, count); fs16_add(sbi, sbi->s_sb_total_free_inodes, -1); dirty_sb(sb); - inode_init_owner(inode, dir, mode); + inode_init_owner(&nop_mnt_idmap, inode, dir, mode); inode->i_ino = fs16_to_cpu(sbi, ino); - inode->i_mtime = inode->i_atime = inode->i_ctime = current_time(inode); + simple_inode_init_ts(inode); inode->i_blocks = 0; memset(SYSV_I(inode)->i_data, 0, sizeof(SYSV_I(inode)->i_data)); SYSV_I(inode)->i_dir_start_lookup = 0; diff '--color=auto' -Naurp s4-3b1-pc7300-efe55b8cc917e3e27bcae9786c5b5dec0469be45.orig/sysv/inode.c s4-3b1-pc7300-efe55b8cc917e3e27bcae9786c5b5dec0469be45/sysv/inode.c --- s4-3b1-pc7300-efe55b8cc917e3e27bcae9786c5b5dec0469be45.orig/sysv/inode.c 2022-10-23 19:25:15.000000000 -0600 +++ s4-3b1-pc7300-efe55b8cc917e3e27bcae9786c5b5dec0469be45/sysv/inode.c 2026-05-09 21:05:21.428053963 -0600 @@ -194,7 +194,7 @@ struct inode *sysv_iget(struct super_blo inode = iget_locked(sb, ino); if (!inode) return ERR_PTR(-ENOMEM); - if (!(inode->i_state & I_NEW)) + if (!(inode_state_read(inode) & I_NEW)) return inode; raw_inode = sysv_raw_inode(sb, ino, &bh); @@ -209,12 +209,9 @@ struct inode *sysv_iget(struct super_blo i_gid_write(inode, (gid_t)fs16_to_cpu(sbi, raw_inode->i_gid)); set_nlink(inode, fs16_to_cpu(sbi, raw_inode->i_nlink)); inode->i_size = fs32_to_cpu(sbi, raw_inode->i_size); - inode->i_atime.tv_sec = fs32_to_cpu(sbi, raw_inode->i_atime); - inode->i_mtime.tv_sec = fs32_to_cpu(sbi, raw_inode->i_mtime); - inode->i_ctime.tv_sec = fs32_to_cpu(sbi, raw_inode->i_ctime); - inode->i_ctime.tv_nsec = 0; - inode->i_atime.tv_nsec = 0; - inode->i_mtime.tv_nsec = 0; + inode_set_atime(inode, fs32_to_cpu(sbi, raw_inode->i_atime), 0); + inode_set_mtime(inode, fs32_to_cpu(sbi, raw_inode->i_mtime), 0); + inode_set_ctime(inode, fs32_to_cpu(sbi, raw_inode->i_ctime), 0); inode->i_blocks = 0; #ifdef dbrower_ @@ -268,9 +265,9 @@ static int __sysv_write_inode(struct ino raw_inode->i_gid = cpu_to_fs16(sbi, fs_high2lowgid(i_gid_read(inode))); raw_inode->i_nlink = cpu_to_fs16(sbi, inode->i_nlink); raw_inode->i_size = cpu_to_fs32(sbi, inode->i_size); - raw_inode->i_atime = cpu_to_fs32(sbi, inode->i_atime.tv_sec); - raw_inode->i_mtime = cpu_to_fs32(sbi, inode->i_mtime.tv_sec); - raw_inode->i_ctime = cpu_to_fs32(sbi, inode->i_ctime.tv_sec); + raw_inode->i_atime = cpu_to_fs32(sbi, inode_get_atime_sec(inode)); + raw_inode->i_mtime = cpu_to_fs32(sbi, inode_get_mtime_sec(inode)); + raw_inode->i_ctime = cpu_to_fs32(sbi, inode_get_ctime_sec(inode)); si = SYSV_I(inode); if (S_ISCHR(inode->i_mode) || S_ISBLK(inode->i_mode)) @@ -360,7 +357,7 @@ int __init sysv_init_icache(void) { sysv_inode_cachep = kmem_cache_create("sysv_inode_cache", sizeof(struct sysv_inode_info), 0, - SLAB_RECLAIM_ACCOUNT|SLAB_MEM_SPREAD|SLAB_ACCOUNT, + SLAB_RECLAIM_ACCOUNT|SLAB_ACCOUNT, init_once); if (!sysv_inode_cachep) return -ENOMEM; diff '--color=auto' -Naurp s4-3b1-pc7300-efe55b8cc917e3e27bcae9786c5b5dec0469be45.orig/sysv/itree.c s4-3b1-pc7300-efe55b8cc917e3e27bcae9786c5b5dec0469be45/sysv/itree.c --- s4-3b1-pc7300-efe55b8cc917e3e27bcae9786c5b5dec0469be45.orig/sysv/itree.c 2022-10-23 19:25:15.000000000 -0600 +++ s4-3b1-pc7300-efe55b8cc917e3e27bcae9786c5b5dec0469be45/sysv/itree.c 2026-05-09 21:04:51.101672019 -0600 @@ -8,6 +8,7 @@ #include #include +#include #include #include "sysv.h" @@ -179,7 +180,7 @@ static inline int splice_branch(struct i *where->p = where->key; write_unlock(&pointers_lock); - inode->i_ctime = current_time(inode); + inode_set_ctime_current(inode); /* had we spliced it onto indirect block? */ if (where->bh) @@ -419,7 +420,7 @@ do_indirects: } n++; } - inode->i_mtime = inode->i_ctime = current_time(inode); + inode_set_mtime_to_ts(inode, inode_set_ctime_current(inode)); if (IS_SYNC(inode)) sysv_sync_inode (inode); else @@ -441,29 +442,29 @@ static unsigned sysv_nblocks(struct supe return blocks; } -int sysv_getattr(const struct path *path, struct kstat *stat, +int sysv_getattr(struct mnt_idmap *idmap, const struct path *path, struct kstat *stat, u32 request_mask, unsigned int flags) { struct super_block *s = path->dentry->d_sb; - generic_fillattr(d_inode(path->dentry), stat); + generic_fillattr(&nop_mnt_idmap, request_mask, d_inode(path->dentry), stat); stat->blocks = (s->s_blocksize / 512) * sysv_nblocks(s, stat->size); stat->blksize = s->s_blocksize; return 0; } -static int sysv_writepage(struct page *page, struct writeback_control *wbc) +static int sysv_writepages(struct address_space *mapping, struct writeback_control *wbc) { - return block_write_full_page(page,get_block,wbc); + return mpage_writepages(mapping, wbc, get_block); } -static int sysv_readpage(struct file *file, struct page *page) +static int sysv_read_folio(struct file *file, struct folio *folio) { - return block_read_full_page(page,get_block); + return block_read_full_folio(folio, get_block); } -int sysv_prepare_chunk(struct page *page, loff_t pos, unsigned len) +int sysv_prepare_chunk(struct folio *folio, loff_t pos, unsigned len) { - return __block_write_begin(page, pos, len, get_block); + return __block_write_begin(folio, pos, len, get_block); } static void sysv_write_failed(struct address_space *mapping, loff_t to) @@ -476,13 +477,13 @@ static void sysv_write_failed(struct add } } -static int sysv_write_begin(struct file *file, struct address_space *mapping, - loff_t pos, unsigned len, unsigned flags, - struct page **pagep, void **fsdata) +static int sysv_write_begin(const struct kiocb *file, struct address_space *mapping, + loff_t pos, unsigned len, + struct folio **foliop, void **fsdata) { int ret; - ret = block_write_begin(mapping, pos, len, flags, pagep, get_block); + ret = block_write_begin(mapping, pos, len, foliop, get_block); if (unlikely(ret)) sysv_write_failed(mapping, pos + len); @@ -495,9 +496,12 @@ static sector_t sysv_bmap(struct address } const struct address_space_operations sysv_aops = { - .readpage = sysv_readpage, - .writepage = sysv_writepage, + .dirty_folio = block_dirty_folio, + .invalidate_folio = block_invalidate_folio, + .read_folio = sysv_read_folio, + .writepages = sysv_writepages, .write_begin = sysv_write_begin, .write_end = generic_write_end, + .migrate_folio = buffer_migrate_folio, .bmap = sysv_bmap }; diff '--color=auto' -Naurp s4-3b1-pc7300-efe55b8cc917e3e27bcae9786c5b5dec0469be45.orig/sysv/Makefile s4-3b1-pc7300-efe55b8cc917e3e27bcae9786c5b5dec0469be45/sysv/Makefile --- s4-3b1-pc7300-efe55b8cc917e3e27bcae9786c5b5dec0469be45.orig/sysv/Makefile 2022-10-23 19:25:15.000000000 -0600 +++ s4-3b1-pc7300-efe55b8cc917e3e27bcae9786c5b5dec0469be45/sysv/Makefile 2026-05-09 21:04:51.101859691 -0600 @@ -2,7 +2,7 @@ # Makefile for the Linux SystemV/Coherent filesystem routines. # -obj-$(CONFIG_SYSV_FS) += sysv.o +obj-m += sysv.o sysv-objs := ialloc.o balloc.o inode.o itree.o file.o dir.o \ namei.o super.o # symlink.o diff '--color=auto' -Naurp s4-3b1-pc7300-efe55b8cc917e3e27bcae9786c5b5dec0469be45.orig/sysv/namei.c s4-3b1-pc7300-efe55b8cc917e3e27bcae9786c5b5dec0469be45/sysv/namei.c --- s4-3b1-pc7300-efe55b8cc917e3e27bcae9786c5b5dec0469be45.orig/sysv/namei.c 2022-10-23 19:25:15.000000000 -0600 +++ s4-3b1-pc7300-efe55b8cc917e3e27bcae9786c5b5dec0469be45/sysv/namei.c 2026-05-09 21:04:51.102045970 -0600 @@ -50,6 +50,10 @@ static struct dentry *sysv_lookup(struct if (dentry->d_name.len > SYSV_NAMELEN) return ERR_PTR(-ENAMETOOLONG); + + if (SYSV_SB(dir->i_sb)->s_truncate) + dentry->d_op = &sysv_dentry_operations; + ino = sysv_inode_by_name(dentry); if (ino) { @@ -61,7 +65,8 @@ static struct dentry *sysv_lookup(struct return NULL; } -static int sysv_mknod(struct inode * dir, struct dentry * dentry, umode_t mode, dev_t rdev) +static int sysv_mknod(struct mnt_idmap *idmap, struct inode * dir, + struct dentry * dentry, umode_t mode, dev_t rdev) { struct inode * inode; int err; @@ -80,13 +85,14 @@ static int sysv_mknod(struct inode * dir return err; } -static int sysv_create(struct inode * dir, struct dentry * dentry, umode_t mode, bool excl) +static int sysv_create(struct mnt_idmap *idmap, struct inode * dir, + struct dentry * dentry, umode_t mode, bool excl) { - return sysv_mknod(dir, dentry, mode, 0); + return sysv_mknod(&nop_mnt_idmap, dir, dentry, mode, 0); } -static int sysv_symlink(struct inode * dir, struct dentry * dentry, - const char * symname) +static int sysv_symlink(struct mnt_idmap *idmap, struct inode * dir, + struct dentry * dentry, const char * symname) { int err = -ENAMETOOLONG; int l = strlen(symname)+1; @@ -121,14 +127,15 @@ static int sysv_link(struct dentry * old { struct inode *inode = d_inode(old_dentry); - inode->i_ctime = current_time(inode); + inode_set_ctime_current(inode); inode_inc_link_count(inode); ihold(inode); return add_nondir(dentry, inode); } -static int sysv_mkdir(struct inode * dir, struct dentry *dentry, umode_t mode) +static struct dentry *sysv_mkdir(struct mnt_idmap *idmap, struct inode * dir, + struct dentry *dentry, umode_t mode) { struct inode * inode; int err; @@ -154,7 +161,7 @@ static int sysv_mkdir(struct inode * dir d_instantiate(dentry, inode); out: - return err; + return ERR_PTR(err); out_fail: inode_dec_link_count(inode); @@ -168,21 +175,20 @@ out_dir: static int sysv_unlink(struct inode * dir, struct dentry * dentry) { struct inode * inode = d_inode(dentry); - struct page * page; + struct folio *folio; struct sysv_dir_entry * de; int err = -ENOENT; - de = sysv_find_entry(dentry, &page); + de = sysv_find_entry(dentry, &folio); if (!de) - goto out; + return -ENOENT; - err = sysv_delete_entry (de, page); - if (err) - goto out; - - inode->i_ctime = dir->i_ctime; - inode_dec_link_count(inode); -out: + err = sysv_delete_entry (de, folio); + if (!err) { + inode_set_ctime_to_ts(inode, inode_get_ctime(dir)); + inode_dec_link_count(inode); + } + folio_release_kmap(folio, de); return err; } @@ -206,34 +212,34 @@ static int sysv_rmdir(struct inode * dir * Anybody can rename anything with this: the permission checks are left to the * higher-level routines. */ -static int sysv_rename(struct inode * old_dir, struct dentry * old_dentry, - struct inode * new_dir, struct dentry * new_dentry, - unsigned int flags) +static int sysv_rename(struct mnt_idmap *idmap, struct inode * old_dir, + struct dentry * old_dentry, struct inode * new_dir, + struct dentry * new_dentry, unsigned int flags) { struct inode * old_inode = d_inode(old_dentry); struct inode * new_inode = d_inode(new_dentry); - struct page * dir_page = NULL; + struct folio *dir_folio; struct sysv_dir_entry * dir_de = NULL; - struct page * old_page; + struct folio *old_folio; struct sysv_dir_entry * old_de; int err = -ENOENT; if (flags & ~RENAME_NOREPLACE) return -EINVAL; - old_de = sysv_find_entry(old_dentry, &old_page); + old_de = sysv_find_entry(old_dentry, &old_folio); if (!old_de) goto out; if (S_ISDIR(old_inode->i_mode)) { err = -EIO; - dir_de = sysv_dotdot(old_inode, &dir_page); + dir_de = sysv_dotdot(old_inode, &dir_folio); if (!dir_de) goto out_old; } if (new_inode) { - struct page * new_page; + struct folio *new_folio; struct sysv_dir_entry * new_de; err = -ENOTEMPTY; @@ -241,11 +247,14 @@ static int sysv_rename(struct inode * ol goto out_dir; err = -ENOENT; - new_de = sysv_find_entry(new_dentry, &new_page); + new_de = sysv_find_entry(new_dentry, &new_folio); if (!new_de) goto out_dir; - sysv_set_link(new_de, new_page, old_inode); - new_inode->i_ctime = current_time(new_inode); + err = sysv_set_link(new_de, new_folio, old_inode); + folio_release_kmap(new_folio, new_de); + if (err) + goto out_dir; + inode_set_ctime_current(new_inode); if (dir_de) drop_nlink(new_inode); inode_dec_link_count(new_inode); @@ -257,23 +266,25 @@ static int sysv_rename(struct inode * ol inode_inc_link_count(new_dir); } - sysv_delete_entry(old_de, old_page); + err = sysv_delete_entry(old_de, old_folio); + if (err) + goto out_dir; + mark_inode_dirty(old_inode); if (dir_de) { - sysv_set_link(dir_de, dir_page, new_dir); - inode_dec_link_count(old_dir); + err = sysv_set_link(dir_de, dir_folio, new_dir); + if (!err) + inode_dec_link_count(old_dir); } return 0; out_dir: if (dir_de) { - kunmap(dir_page); - put_page(dir_page); + folio_release_kmap(dir_folio, dir_de); } out_old: - kunmap(old_page); - put_page(old_page); + folio_release_kmap(old_folio, old_de); out: return err; } diff '--color=auto' -Naurp s4-3b1-pc7300-efe55b8cc917e3e27bcae9786c5b5dec0469be45.orig/sysv/super.c s4-3b1-pc7300-efe55b8cc917e3e27bcae9786c5b5dec0469be45/sysv/super.c --- s4-3b1-pc7300-efe55b8cc917e3e27bcae9786c5b5dec0469be45.orig/sysv/super.c 2022-10-23 19:25:15.000000000 -0600 +++ s4-3b1-pc7300-efe55b8cc917e3e27bcae9786c5b5dec0469be45/sysv/super.c 2026-05-09 21:04:51.102238060 -0600 @@ -24,6 +24,7 @@ #include #include #include +#include #include "sysv.h" /* @@ -395,8 +396,6 @@ static int complete_read_super(struct su sb->s_op = &sysv_sops; if (sbi->s_forced_ro) sb->s_flags |= SB_RDONLY; - if (sbi->s_truncate) - sb->s_d_op = &sysv_dentry_operations; root_inode = sysv_iget(sb, SYSV_ROOT_INO); if (IS_ERR(root_inode)) { printk("SysV FS: get root inode failed\n"); @@ -410,12 +409,13 @@ static int complete_read_super(struct su return 1; } -static int sysv_fill_super(struct super_block *sb, void *data, int silent) +static int sysv_fill_super(struct super_block *sb, struct fs_context *fc) { struct buffer_head *bh1, *bh = NULL; struct sysv_sb_info *sbi; unsigned long blocknr; int size = 0, i; + int silent = fc->sb_flags & SB_SILENT; BUILD_BUG_ON(1024 != sizeof (struct xenix_super_block)); BUILD_BUG_ON(512 != sizeof (struct sysv4_super_block)); @@ -532,10 +532,11 @@ static int v7_sanity_check(struct super_ return 1; } -static int v7_fill_super(struct super_block *sb, void *data, int silent) +static int v7_fill_super(struct super_block *sb, struct fs_context *fc) { struct sysv_sb_info *sbi; struct buffer_head *bh; + int silent = fc->sb_flags & SB_SILENT; if (440 != sizeof (struct v7_super_block)) panic("V7 FS: bad super-block size"); @@ -589,33 +590,51 @@ failed: /* Every kernel module contains stuff like this. */ -static struct dentry *sysv_mount(struct file_system_type *fs_type, - int flags, const char *dev_name, void *data) +static int sysv_get_tree(struct fs_context *fc) { - return mount_bdev(fs_type, flags, dev_name, data, sysv_fill_super); + return get_tree_bdev(fc, sysv_fill_super); } -static struct dentry *v7_mount(struct file_system_type *fs_type, - int flags, const char *dev_name, void *data) +static int v7_get_tree(struct fs_context *fc) { - return mount_bdev(fs_type, flags, dev_name, data, v7_fill_super); + return get_tree_bdev(fc, v7_fill_super); +} + +static const struct fs_context_operations sysv_context_ops = { + .get_tree = sysv_get_tree, +}; + +static const struct fs_context_operations v7_context_ops = { + .get_tree = v7_get_tree, +}; + +static int sysv_init_fs_context(struct fs_context *fc) +{ + fc->ops = &sysv_context_ops; + return 0; +} + +static int v7_init_fs_context(struct fs_context *fc) +{ + fc->ops = &v7_context_ops; + return 0; } static struct file_system_type sysv_fs_type = { - .owner = THIS_MODULE, - .name = "sysv", - .mount = sysv_mount, - .kill_sb = kill_block_super, - .fs_flags = FS_REQUIRES_DEV, + .owner = THIS_MODULE, + .name = "sysv", + .kill_sb = kill_block_super, + .fs_flags = FS_REQUIRES_DEV, + .init_fs_context = sysv_init_fs_context, }; MODULE_ALIAS_FS("sysv"); static struct file_system_type v7_fs_type = { - .owner = THIS_MODULE, - .name = "v7", - .mount = v7_mount, - .kill_sb = kill_block_super, - .fs_flags = FS_REQUIRES_DEV, + .owner = THIS_MODULE, + .name = "v7", + .kill_sb = kill_block_super, + .fs_flags = FS_REQUIRES_DEV, + .init_fs_context = v7_init_fs_context, }; MODULE_ALIAS_FS("v7"); MODULE_ALIAS("v7"); diff '--color=auto' -Naurp s4-3b1-pc7300-efe55b8cc917e3e27bcae9786c5b5dec0469be45.orig/sysv/sysv.h s4-3b1-pc7300-efe55b8cc917e3e27bcae9786c5b5dec0469be45/sysv/sysv.h --- s4-3b1-pc7300-efe55b8cc917e3e27bcae9786c5b5dec0469be45.orig/sysv/sysv.h 2022-10-23 19:25:15.000000000 -0600 +++ s4-3b1-pc7300-efe55b8cc917e3e27bcae9786c5b5dec0469be45/sysv/sysv.h 2026-05-09 21:04:51.102462922 -0600 @@ -139,27 +139,27 @@ extern unsigned long sysv_count_free_blo /* itree.c */ extern void sysv_truncate(struct inode *); -extern int sysv_prepare_chunk(struct page *page, loff_t pos, unsigned len); +extern int sysv_prepare_chunk(struct folio *folio, loff_t pos, unsigned len); /* inode.c */ extern struct inode *sysv_iget(struct super_block *, unsigned int); extern int sysv_write_inode(struct inode *, struct writeback_control *wbc); extern int sysv_sync_inode(struct inode *); extern void sysv_set_inode(struct inode *, dev_t); -extern int sysv_getattr(const struct path *, struct kstat *, u32, unsigned int); +extern int sysv_getattr(struct mnt_idmap *, const struct path *, struct kstat *, u32, unsigned int); extern int sysv_init_icache(void); extern void sysv_destroy_icache(void); /* dir.c */ -extern struct sysv_dir_entry *sysv_find_entry(struct dentry *, struct page **); +extern struct sysv_dir_entry *sysv_find_entry(struct dentry *, struct folio **); extern int sysv_add_link(struct dentry *, struct inode *); -extern int sysv_delete_entry(struct sysv_dir_entry *, struct page *); +extern int sysv_delete_entry(struct sysv_dir_entry *, struct folio *); extern int sysv_make_empty(struct inode *, struct inode *); extern int sysv_empty_dir(struct inode *); -extern void sysv_set_link(struct sysv_dir_entry *, struct page *, +extern int sysv_set_link(struct sysv_dir_entry *, struct folio *, struct inode *); -extern struct sysv_dir_entry *sysv_dotdot(struct inode *, struct page **); +extern struct sysv_dir_entry *sysv_dotdot(struct inode *, struct folio **); extern ino_t sysv_inode_by_name(struct dentry *);