diff options
Diffstat (limited to 'fs/minix')
| -rw-r--r-- | fs/minix/bitmap.c | 2 | ||||
| -rw-r--r-- | fs/minix/dir.c | 2 | ||||
| -rw-r--r-- | fs/minix/file.c | 10 | ||||
| -rw-r--r-- | fs/minix/inode.c | 68 | ||||
| -rw-r--r-- | fs/minix/itree_common.c | 11 | ||||
| -rw-r--r-- | fs/minix/minix.h | 5 |
6 files changed, 61 insertions, 37 deletions
diff --git a/fs/minix/bitmap.c b/fs/minix/bitmap.c index 7da66ca184f4..abec438330a7 100644 --- a/fs/minix/bitmap.c +++ b/fs/minix/bitmap.c @@ -247,7 +247,7 @@ struct inode *minix_new_inode(const struct inode *dir, umode_t mode) j += i * bits_per_zone; if (!j || j > sbi->s_ninodes) { iput(inode); - return ERR_PTR(-ENOSPC); + return ERR_PTR(-EFSCORRUPTED); } inode_init_owner(&nop_mnt_idmap, inode, dir, mode); inode->i_ino = j; diff --git a/fs/minix/dir.c b/fs/minix/dir.c index 19052fc47e9e..361d26d87d2e 100644 --- a/fs/minix/dir.c +++ b/fs/minix/dir.c @@ -23,7 +23,7 @@ const struct file_operations minix_dir_operations = { .llseek = generic_file_llseek, .read = generic_read_dir, .iterate_shared = minix_readdir, - .fsync = generic_file_fsync, + .fsync = minix_fsync, }; /* diff --git a/fs/minix/file.c b/fs/minix/file.c index dca7ac71f049..86e5943cd2ff 100644 --- a/fs/minix/file.c +++ b/fs/minix/file.c @@ -7,8 +7,16 @@ * minix regular file handling primitives */ +#include <linux/buffer_head.h> #include "minix.h" +int minix_fsync(struct file *file, loff_t start, loff_t end, int datasync) +{ + return mmb_fsync(file, + &minix_i(file->f_mapping->host)->i_metadata_bhs, + start, end, datasync); +} + /* * We have mostly NULLs here: the current defaults are OK for * the minix filesystem. @@ -18,7 +26,7 @@ const struct file_operations minix_file_operations = { .read_iter = generic_file_read_iter, .write_iter = generic_file_write_iter, .mmap_prepare = generic_file_mmap_prepare, - .fsync = generic_file_fsync, + .fsync = minix_fsync, .splice_read = filemap_splice_read, }; diff --git a/fs/minix/inode.c b/fs/minix/inode.c index 51ea9bdc813f..9c6bac248907 100644 --- a/fs/minix/inode.c +++ b/fs/minix/inode.c @@ -36,7 +36,7 @@ void __minix_error_inode(struct inode *inode, const char *function, vaf.fmt = fmt; vaf.va = &args; printk(KERN_CRIT "minix-fs error (device %s): %s:%d: " - "inode #%lu: comm %s: %pV\n", + "inode #%llu: comm %s: %pV\n", inode->i_sb->s_id, function, line, inode->i_ino, current->comm, &vaf); va_end(args); @@ -48,8 +48,10 @@ static void minix_evict_inode(struct inode *inode) if (!inode->i_nlink) { inode->i_size = 0; minix_truncate(inode); + } else { + mmb_sync(&minix_i(inode)->i_metadata_bhs); } - invalidate_inode_buffers(inode); + mmb_invalidate(&minix_i(inode)->i_metadata_bhs); clear_inode(inode); if (!inode->i_nlink) minix_free_inode(inode); @@ -83,6 +85,8 @@ static struct inode *minix_alloc_inode(struct super_block *sb) ei = alloc_inode_sb(sb, minix_inode_cachep, GFP_KERNEL); if (!ei) return NULL; + mmb_init(&ei->i_metadata_bhs, &ei->vfs_inode.i_data); + return &ei->vfs_inode; } @@ -170,9 +174,37 @@ static int minix_reconfigure(struct fs_context *fc) static bool minix_check_superblock(struct super_block *sb) { struct minix_sb_info *sbi = minix_sb(sb); + unsigned long block; + + if (sbi->s_log_zone_size != 0) { + printk("minix-fs error: zone size must equal block size. " + "s_log_zone_size > 0 is not supported.\n"); + return false; + } - if (sbi->s_imap_blocks == 0 || sbi->s_zmap_blocks == 0) + if (sbi->s_ninodes < 1 || sbi->s_firstdatazone <= 4 || + sbi->s_firstdatazone >= sbi->s_nzones) + return false; + + /* Apparently minix can create filesystems that allocate more blocks for + * the bitmaps than needed. We simply ignore that, but verify it didn't + * create one with not enough blocks and bail out if so. + */ + block = minix_blocks_needed(sbi->s_ninodes, sb->s_blocksize); + if (sbi->s_imap_blocks < block) { + printk("MINIX-fs: file system does not have enough " + "imap blocks allocated. Refusing to mount.\n"); return false; + } + + block = minix_blocks_needed( + (sbi->s_nzones - sbi->s_firstdatazone + 1), + sb->s_blocksize); + if (sbi->s_zmap_blocks < block) { + printk("MINIX-fs: file system does not have enough " + "zmap blocks allocated. Refusing to mount.\n"); + return false; + } /* * s_max_size must not exceed the block mapping limitation. This check @@ -198,7 +230,7 @@ static int minix_fill_super(struct super_block *s, struct fs_context *fc) int ret = -EINVAL; int silent = fc->sb_flags & SB_SILENT; - sbi = kzalloc(sizeof(struct minix_sb_info), GFP_KERNEL); + sbi = kzalloc_obj(struct minix_sb_info); if (!sbi) return -ENOMEM; s->s_fs_info = sbi; @@ -293,26 +325,6 @@ static int minix_fill_super(struct super_block *s, struct fs_context *fc) minix_set_bit(0,sbi->s_imap[0]->b_data); minix_set_bit(0,sbi->s_zmap[0]->b_data); - /* Apparently minix can create filesystems that allocate more blocks for - * the bitmaps than needed. We simply ignore that, but verify it didn't - * create one with not enough blocks and bail out if so. - */ - block = minix_blocks_needed(sbi->s_ninodes, s->s_blocksize); - if (sbi->s_imap_blocks < block) { - printk("MINIX-fs: file system does not have enough " - "imap blocks allocated. Refusing to mount.\n"); - goto out_no_bitmap; - } - - block = minix_blocks_needed( - (sbi->s_nzones - sbi->s_firstdatazone + 1), - s->s_blocksize); - if (sbi->s_zmap_blocks < block) { - printk("MINIX-fs: file system does not have enough " - "zmap blocks allocated. Refusing to mount.\n"); - goto out_no_bitmap; - } - /* set up enough so that it can read an inode */ s->s_op = &minix_sops; s->s_time_min = 0; @@ -512,7 +524,7 @@ void minix_set_inode(struct inode *inode, dev_t rdev) S_ISFIFO(inode->i_mode) || S_ISSOCK(inode->i_mode)) { init_special_inode(inode, inode->i_mode, rdev); } else { - printk(KERN_DEBUG "MINIX-fs: Invalid file type 0%04o for inode %lu.\n", + printk(KERN_DEBUG "MINIX-fs: Invalid file type 0%04o for inode %llu.\n", inode->i_mode, inode->i_ino); make_bad_inode(inode); } @@ -534,7 +546,7 @@ static struct inode *V1_minix_iget(struct inode *inode) return ERR_PTR(-EIO); } if (raw_inode->i_nlinks == 0) { - printk("MINIX-fs: deleted inode referenced: %lu\n", + printk("MINIX-fs: deleted inode referenced: %llu\n", inode->i_ino); brelse(bh); iget_failed(inode); @@ -572,7 +584,7 @@ static struct inode *V2_minix_iget(struct inode *inode) return ERR_PTR(-EIO); } if (raw_inode->i_nlinks == 0) { - printk("MINIX-fs: deleted inode referenced: %lu\n", + printk("MINIX-fs: deleted inode referenced: %llu\n", inode->i_ino); brelse(bh); iget_failed(inode); @@ -684,7 +696,7 @@ static int minix_write_inode(struct inode *inode, struct writeback_control *wbc) if (wbc->sync_mode == WB_SYNC_ALL && buffer_dirty(bh)) { sync_dirty_buffer(bh); if (buffer_req(bh) && !buffer_uptodate(bh)) { - printk("IO error syncing minix inode [%s:%08lx]\n", + printk("IO error syncing minix inode [%s:%08llx]\n", inode->i_sb->s_id, inode->i_ino); err = -EIO; } diff --git a/fs/minix/itree_common.c b/fs/minix/itree_common.c index dad131e30c05..c3cd2c75af9c 100644 --- a/fs/minix/itree_common.c +++ b/fs/minix/itree_common.c @@ -98,7 +98,7 @@ static int alloc_branch(struct inode *inode, *branch[n].p = branch[n].key; set_buffer_uptodate(bh); unlock_buffer(bh); - mark_buffer_dirty_inode(bh, inode); + mmb_mark_buffer_dirty(bh, &minix_i(inode)->i_metadata_bhs); parent = nr; } if (n == num) @@ -135,7 +135,8 @@ static inline int splice_branch(struct inode *inode, /* had we spliced it onto indirect block? */ if (where->bh) - mark_buffer_dirty_inode(where->bh, inode); + mmb_mark_buffer_dirty(where->bh, + &minix_i(inode)->i_metadata_bhs); mark_inode_dirty(inode); return 0; @@ -328,14 +329,16 @@ static inline void truncate (struct inode * inode) if (partial == chain) mark_inode_dirty(inode); else - mark_buffer_dirty_inode(partial->bh, inode); + mmb_mark_buffer_dirty(partial->bh, + &minix_i(inode)->i_metadata_bhs); free_branches(inode, &nr, &nr+1, (chain+n-1) - partial); } /* Clear the ends of indirect blocks on the shared branch */ while (partial > chain) { free_branches(inode, partial->p + 1, block_end(partial->bh), (chain+n-1) - partial); - mark_buffer_dirty_inode(partial->bh, inode); + mmb_mark_buffer_dirty(partial->bh, + &minix_i(inode)->i_metadata_bhs); brelse (partial->bh); partial--; } diff --git a/fs/minix/minix.h b/fs/minix/minix.h index 2bfaf377f208..f2025c9b5825 100644 --- a/fs/minix/minix.h +++ b/fs/minix/minix.h @@ -19,6 +19,7 @@ struct minix_inode_info { __u16 i1_data[16]; __u32 i2_data[16]; } u; + struct mapping_metadata_bhs i_metadata_bhs; struct inode vfs_inode; }; @@ -57,6 +58,8 @@ unsigned long minix_count_free_blocks(struct super_block *sb); int minix_getattr(struct mnt_idmap *, const struct path *, struct kstat *, u32, unsigned int); int minix_prepare_chunk(struct folio *folio, loff_t pos, unsigned len); +struct mapping_metadata_bhs *minix_get_metadata_bhs(struct inode *inode); +int minix_fsync(struct file *file, loff_t start, loff_t end, int datasync); extern void V1_minix_truncate(struct inode *); extern void V2_minix_truncate(struct inode *); @@ -175,6 +178,4 @@ static inline int minix_test_bit(int nr, const void *vaddr) __minix_error_inode((inode), __func__, __LINE__, \ (fmt), ##__VA_ARGS__) -#define EFSCORRUPTED EUCLEAN /* Filesystem is corrupted */ - #endif /* FS_MINIX_H */ |
