aboutsummaryrefslogtreecommitdiff
path: root/fs/minix
diff options
context:
space:
mode:
Diffstat (limited to 'fs/minix')
-rw-r--r--fs/minix/bitmap.c2
-rw-r--r--fs/minix/dir.c2
-rw-r--r--fs/minix/file.c10
-rw-r--r--fs/minix/inode.c68
-rw-r--r--fs/minix/itree_common.c11
-rw-r--r--fs/minix/minix.h5
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 */