aboutsummaryrefslogtreecommitdiff
path: root/fs/minix
diff options
context:
space:
mode:
Diffstat (limited to 'fs/minix')
-rw-r--r--fs/minix/Kconfig2
-rw-r--r--fs/minix/dir.c42
-rw-r--r--fs/minix/file.c14
-rw-r--r--fs/minix/inode.c44
-rw-r--r--fs/minix/itree_v2.c3
-rw-r--r--fs/minix/namei.c13
6 files changed, 72 insertions, 46 deletions
diff --git a/fs/minix/Kconfig b/fs/minix/Kconfig
index 6624684dd5d..f2a0cfcef11 100644
--- a/fs/minix/Kconfig
+++ b/fs/minix/Kconfig
@@ -18,7 +18,7 @@ config MINIX_FS
config MINIX_FS_NATIVE_ENDIAN
def_bool MINIX_FS
- depends on H8300 || M32R || MICROBLAZE || MIPS || S390 || SUPERH || SPARC || XTENSA || (M68K && !MMU)
+ depends on M32R || MICROBLAZE || MIPS || S390 || SUPERH || SPARC || XTENSA || (M68K && !MMU)
config MINIX_FS_BIG_ENDIAN_16BIT_INDEXED
def_bool MINIX_FS
diff --git a/fs/minix/dir.c b/fs/minix/dir.c
index 685b2d981b8..dfaf6fa9b7b 100644
--- a/fs/minix/dir.c
+++ b/fs/minix/dir.c
@@ -16,12 +16,12 @@
typedef struct minix_dir_entry minix_dirent;
typedef struct minix3_dir_entry minix3_dirent;
-static int minix_readdir(struct file *, void *, filldir_t);
+static int minix_readdir(struct file *, struct dir_context *);
const struct file_operations minix_dir_operations = {
.llseek = generic_file_llseek,
.read = generic_read_dir,
- .readdir = minix_readdir,
+ .iterate = minix_readdir,
.fsync = generic_file_fsync,
};
@@ -82,22 +82,23 @@ static inline void *minix_next_entry(void *de, struct minix_sb_info *sbi)
return (void*)((char*)de + sbi->s_dirsize);
}
-static int minix_readdir(struct file * filp, void * dirent, filldir_t filldir)
+static int minix_readdir(struct file *file, struct dir_context *ctx)
{
- unsigned long pos = filp->f_pos;
- struct inode *inode = filp->f_path.dentry->d_inode;
+ struct inode *inode = file_inode(file);
struct super_block *sb = inode->i_sb;
- unsigned offset = pos & ~PAGE_CACHE_MASK;
- unsigned long n = pos >> PAGE_CACHE_SHIFT;
- unsigned long npages = dir_pages(inode);
struct minix_sb_info *sbi = minix_sb(sb);
unsigned chunk_size = sbi->s_dirsize;
- char *name;
- __u32 inumber;
+ unsigned long npages = dir_pages(inode);
+ unsigned long pos = ctx->pos;
+ unsigned offset;
+ unsigned long n;
- pos = (pos + chunk_size-1) & ~(chunk_size-1);
+ ctx->pos = pos = ALIGN(pos, chunk_size);
if (pos >= inode->i_size)
- goto done;
+ return 0;
+
+ offset = pos & ~PAGE_CACHE_MASK;
+ n = pos >> PAGE_CACHE_SHIFT;
for ( ; n < npages; n++, offset = 0) {
char *p, *kaddr, *limit;
@@ -109,6 +110,8 @@ static int minix_readdir(struct file * filp, void * dirent, filldir_t filldir)
p = kaddr+offset;
limit = kaddr + minix_last_byte(inode, n) - chunk_size;
for ( ; p <= limit; p = minix_next_entry(p, sbi)) {
+ const char *name;
+ __u32 inumber;
if (sbi->s_version == MINIX_V3) {
minix3_dirent *de3 = (minix3_dirent *)p;
name = de3->name;
@@ -119,24 +122,17 @@ static int minix_readdir(struct file * filp, void * dirent, filldir_t filldir)
inumber = de->inode;
}
if (inumber) {
- int over;
-
unsigned l = strnlen(name, sbi->s_namelen);
- offset = p - kaddr;
- over = filldir(dirent, name, l,
- (n << PAGE_CACHE_SHIFT) | offset,
- inumber, DT_UNKNOWN);
- if (over) {
+ if (!dir_emit(ctx, name, l,
+ inumber, DT_UNKNOWN)) {
dir_put_page(page);
- goto done;
+ return 0;
}
}
+ ctx->pos += chunk_size;
}
dir_put_page(page);
}
-
-done:
- filp->f_pos = (n << PAGE_CACHE_SHIFT) | offset;
return 0;
}
diff --git a/fs/minix/file.c b/fs/minix/file.c
index 4493ce695ab..a967de085ac 100644
--- a/fs/minix/file.c
+++ b/fs/minix/file.c
@@ -14,10 +14,10 @@
*/
const struct file_operations minix_file_operations = {
.llseek = generic_file_llseek,
- .read = do_sync_read,
- .aio_read = generic_file_aio_read,
- .write = do_sync_write,
- .aio_write = generic_file_aio_write,
+ .read = new_sync_read,
+ .read_iter = generic_file_read_iter,
+ .write = new_sync_write,
+ .write_iter = generic_file_write_iter,
.mmap = generic_file_mmap,
.fsync = generic_file_fsync,
.splice_read = generic_file_splice_read,
@@ -34,9 +34,12 @@ static int minix_setattr(struct dentry *dentry, struct iattr *attr)
if ((attr->ia_valid & ATTR_SIZE) &&
attr->ia_size != i_size_read(inode)) {
- error = vmtruncate(inode, attr->ia_size);
+ error = inode_newsize_ok(inode, attr->ia_size);
if (error)
return error;
+
+ truncate_setsize(inode, attr->ia_size);
+ minix_truncate(inode);
}
setattr_copy(inode, attr);
@@ -45,7 +48,6 @@ static int minix_setattr(struct dentry *dentry, struct iattr *attr)
}
const struct inode_operations minix_file_inode_operations = {
- .truncate = minix_truncate,
.setattr = minix_setattr,
.getattr = minix_getattr,
};
diff --git a/fs/minix/inode.c b/fs/minix/inode.c
index 2a503ad020d..f007a335557 100644
--- a/fs/minix/inode.c
+++ b/fs/minix/inode.c
@@ -26,7 +26,7 @@ static int minix_remount (struct super_block * sb, int * flags, char * data);
static void minix_evict_inode(struct inode *inode)
{
- truncate_inode_pages(&inode->i_data, 0);
+ truncate_inode_pages_final(&inode->i_data);
if (!inode->i_nlink) {
inode->i_size = 0;
minix_truncate(inode);
@@ -86,7 +86,7 @@ static void init_once(void *foo)
inode_init_once(&ei->vfs_inode);
}
-static int init_inodecache(void)
+static int __init init_inodecache(void)
{
minix_inode_cachep = kmem_cache_create("minix_inode_cache",
sizeof(struct minix_inode_info),
@@ -100,6 +100,11 @@ static int init_inodecache(void)
static void destroy_inodecache(void)
{
+ /*
+ * Make sure all delayed rcu free inodes are flushed before we
+ * destroy cache.
+ */
+ rcu_barrier();
kmem_cache_destroy(minix_inode_cachep);
}
@@ -118,6 +123,7 @@ static int minix_remount (struct super_block * sb, int * flags, char * data)
struct minix_sb_info * sbi = minix_sb(sb);
struct minix_super_block * ms;
+ sync_filesystem(sb);
ms = sbi->s_ms;
if ((*flags & MS_RDONLY) == (sb->s_flags & MS_RDONLY))
return 0;
@@ -390,6 +396,16 @@ int minix_prepare_chunk(struct page *page, loff_t pos, unsigned len)
return __block_write_begin(page, pos, len, minix_get_block);
}
+static void minix_write_failed(struct address_space *mapping, loff_t to)
+{
+ struct inode *inode = mapping->host;
+
+ if (to > inode->i_size) {
+ truncate_pagecache(inode, inode->i_size);
+ minix_truncate(inode);
+ }
+}
+
static int minix_write_begin(struct file *file, struct address_space *mapping,
loff_t pos, unsigned len, unsigned flags,
struct page **pagep, void **fsdata)
@@ -398,11 +414,8 @@ static int minix_write_begin(struct file *file, struct address_space *mapping,
ret = block_write_begin(mapping, pos, len, flags, pagep,
minix_get_block);
- if (unlikely(ret)) {
- loff_t isize = mapping->host->i_size;
- if (pos + len > isize)
- vmtruncate(mapping->host, isize);
- }
+ if (unlikely(ret))
+ minix_write_failed(mapping, pos + len);
return ret;
}
@@ -460,8 +473,8 @@ static struct inode *V1_minix_iget(struct inode *inode)
return ERR_PTR(-EIO);
}
inode->i_mode = raw_inode->i_mode;
- inode->i_uid = (uid_t)raw_inode->i_uid;
- inode->i_gid = (gid_t)raw_inode->i_gid;
+ i_uid_write(inode, raw_inode->i_uid);
+ i_gid_write(inode, raw_inode->i_gid);
set_nlink(inode, raw_inode->i_nlinks);
inode->i_size = raw_inode->i_size;
inode->i_mtime.tv_sec = inode->i_atime.tv_sec = inode->i_ctime.tv_sec = raw_inode->i_time;
@@ -493,8 +506,8 @@ static struct inode *V2_minix_iget(struct inode *inode)
return ERR_PTR(-EIO);
}
inode->i_mode = raw_inode->i_mode;
- inode->i_uid = (uid_t)raw_inode->i_uid;
- inode->i_gid = (gid_t)raw_inode->i_gid;
+ i_uid_write(inode, raw_inode->i_uid);
+ i_gid_write(inode, raw_inode->i_gid);
set_nlink(inode, raw_inode->i_nlinks);
inode->i_size = raw_inode->i_size;
inode->i_mtime.tv_sec = raw_inode->i_mtime;
@@ -545,8 +558,8 @@ static struct buffer_head * V1_minix_update_inode(struct inode * inode)
if (!raw_inode)
return NULL;
raw_inode->i_mode = inode->i_mode;
- raw_inode->i_uid = fs_high2lowuid(inode->i_uid);
- raw_inode->i_gid = fs_high2lowgid(inode->i_gid);
+ raw_inode->i_uid = fs_high2lowuid(i_uid_read(inode));
+ raw_inode->i_gid = fs_high2lowgid(i_gid_read(inode));
raw_inode->i_nlinks = inode->i_nlink;
raw_inode->i_size = inode->i_size;
raw_inode->i_time = inode->i_mtime.tv_sec;
@@ -572,8 +585,8 @@ static struct buffer_head * V2_minix_update_inode(struct inode * inode)
if (!raw_inode)
return NULL;
raw_inode->i_mode = inode->i_mode;
- raw_inode->i_uid = fs_high2lowuid(inode->i_uid);
- raw_inode->i_gid = fs_high2lowgid(inode->i_gid);
+ raw_inode->i_uid = fs_high2lowuid(i_uid_read(inode));
+ raw_inode->i_gid = fs_high2lowgid(i_gid_read(inode));
raw_inode->i_nlinks = inode->i_nlink;
raw_inode->i_size = inode->i_size;
raw_inode->i_mtime = inode->i_mtime.tv_sec;
@@ -648,6 +661,7 @@ static struct file_system_type minix_fs_type = {
.kill_sb = kill_block_super,
.fs_flags = FS_REQUIRES_DEV,
};
+MODULE_ALIAS_FS("minix");
static int __init init_minix_fs(void)
{
diff --git a/fs/minix/itree_v2.c b/fs/minix/itree_v2.c
index 13487ad1689..78e2d93e5c8 100644
--- a/fs/minix/itree_v2.c
+++ b/fs/minix/itree_v2.c
@@ -32,7 +32,8 @@ static int block_to_path(struct inode * inode, long block, int offsets[DEPTH])
if (block < 0) {
printk("MINIX-fs: block_to_path: block %ld < 0 on dev %s\n",
block, bdevname(sb->s_bdev, b));
- } else if (block >= (minix_sb(inode->i_sb)->s_max_size/sb->s_blocksize)) {
+ } else if ((u64)block * (u64)sb->s_blocksize >=
+ minix_sb(sb)->s_max_size) {
if (printk_ratelimit())
printk("MINIX-fs: block_to_path: "
"block %ld too big on dev %s\n",
diff --git a/fs/minix/namei.c b/fs/minix/namei.c
index 0db73d9dd66..cd950e2331b 100644
--- a/fs/minix/namei.c
+++ b/fs/minix/namei.c
@@ -54,6 +54,18 @@ static int minix_mknod(struct inode * dir, struct dentry *dentry, umode_t mode,
return error;
}
+static int minix_tmpfile(struct inode *dir, struct dentry *dentry, umode_t mode)
+{
+ int error;
+ struct inode *inode = minix_new_inode(dir, mode, &error);
+ if (inode) {
+ minix_set_inode(inode, 0);
+ mark_inode_dirty(inode);
+ d_tmpfile(dentry, inode);
+ }
+ return error;
+}
+
static int minix_create(struct inode *dir, struct dentry *dentry, umode_t mode,
bool excl)
{
@@ -254,4 +266,5 @@ const struct inode_operations minix_dir_inode_operations = {
.mknod = minix_mknod,
.rename = minix_rename,
.getattr = minix_getattr,
+ .tmpfile = minix_tmpfile,
};