aboutsummaryrefslogtreecommitdiffstatshomepage
path: root/fs/minix
diff options
context:
space:
mode:
Diffstat (limited to '')
-rw-r--r--fs/minix/bitmap.c18
-rw-r--r--fs/minix/dir.c62
-rw-r--r--fs/minix/file.c6
-rw-r--r--fs/minix/inode.c4
-rw-r--r--fs/minix/minix.h7
-rw-r--r--fs/minix/namei.c114
6 files changed, 105 insertions, 106 deletions
diff --git a/fs/minix/bitmap.c b/fs/minix/bitmap.c
index 9115948c624e..870207ba23f1 100644
--- a/fs/minix/bitmap.c
+++ b/fs/minix/bitmap.c
@@ -210,7 +210,7 @@ void minix_free_inode(struct inode * inode)
mark_buffer_dirty(bh);
}
-struct inode *minix_new_inode(const struct inode *dir, umode_t mode, int *error)
+struct inode *minix_new_inode(const struct inode *dir, umode_t mode)
{
struct super_block *sb = dir->i_sb;
struct minix_sb_info *sbi = minix_sb(sb);
@@ -220,13 +220,10 @@ struct inode *minix_new_inode(const struct inode *dir, umode_t mode, int *error)
unsigned long j;
int i;
- if (!inode) {
- *error = -ENOMEM;
- return NULL;
- }
+ if (!inode)
+ return ERR_PTR(-ENOMEM);
j = bits_per_zone;
bh = NULL;
- *error = -ENOSPC;
spin_lock(&bitmap_lock);
for (i = 0; i < sbi->s_imap_blocks; i++) {
bh = sbi->s_imap[i];
@@ -237,22 +234,22 @@ struct inode *minix_new_inode(const struct inode *dir, umode_t mode, int *error)
if (!bh || j >= bits_per_zone) {
spin_unlock(&bitmap_lock);
iput(inode);
- return NULL;
+ return ERR_PTR(-ENOSPC);
}
if (minix_test_and_set_bit(j, bh->b_data)) { /* shouldn't happen */
spin_unlock(&bitmap_lock);
printk("minix_new_inode: bit already set\n");
iput(inode);
- return NULL;
+ return ERR_PTR(-ENOSPC);
}
spin_unlock(&bitmap_lock);
mark_buffer_dirty(bh);
j += i * bits_per_zone;
if (!j || j > sbi->s_ninodes) {
iput(inode);
- return NULL;
+ return ERR_PTR(-ENOSPC);
}
- inode_init_owner(&init_user_ns, inode, dir, mode);
+ inode_init_owner(&nop_mnt_idmap, inode, dir, mode);
inode->i_ino = j;
inode->i_mtime = inode->i_atime = inode->i_ctime = current_time(inode);
inode->i_blocks = 0;
@@ -260,7 +257,6 @@ struct inode *minix_new_inode(const struct inode *dir, umode_t mode, int *error)
insert_inode_hash(inode);
mark_inode_dirty(inode);
- *error = 0;
return inode;
}
diff --git a/fs/minix/dir.c b/fs/minix/dir.c
index dcfe5b25378b..bf9858f76b6a 100644
--- a/fs/minix/dir.c
+++ b/fs/minix/dir.c
@@ -46,21 +46,27 @@ minix_last_byte(struct inode *inode, unsigned long page_nr)
return last_byte;
}
-static int dir_commit_chunk(struct page *page, loff_t pos, unsigned len)
+static void dir_commit_chunk(struct page *page, loff_t pos, unsigned len)
{
struct address_space *mapping = page->mapping;
struct inode *dir = mapping->host;
- int err = 0;
+
block_write_end(NULL, mapping, pos, len, len, page, NULL);
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);
+ unlock_page(page);
+}
+
+static int minix_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;
}
@@ -274,9 +280,10 @@ got_it:
memset (namx + namelen, 0, sbi->s_dirsize - namelen - 2);
de->inode = inode->i_ino;
}
- err = dir_commit_chunk(page, pos, sbi->s_dirsize);
+ dir_commit_chunk(page, pos, sbi->s_dirsize);
dir->i_mtime = dir->i_ctime = current_time(dir);
mark_inode_dirty(dir);
+ err = minix_handle_dirsync(dir);
out_put:
dir_put_page(page);
out:
@@ -297,19 +304,18 @@ int minix_delete_entry(struct minix_dir_entry *de, struct page *page)
lock_page(page);
err = minix_prepare_chunk(page, pos, len);
- if (err == 0) {
- if (sbi->s_version == MINIX_V3)
- ((minix3_dirent *) de)->inode = 0;
- else
- de->inode = 0;
- err = dir_commit_chunk(page, pos, len);
- } else {
+ if (err) {
unlock_page(page);
+ return err;
}
- dir_put_page(page);
+ if (sbi->s_version == MINIX_V3)
+ ((minix3_dirent *)de)->inode = 0;
+ else
+ de->inode = 0;
+ dir_commit_chunk(page, pos, len);
inode->i_ctime = inode->i_mtime = current_time(inode);
mark_inode_dirty(inode);
- return err;
+ return minix_handle_dirsync(inode);
}
int minix_make_empty(struct inode *inode, struct inode *dir)
@@ -349,7 +355,8 @@ int minix_make_empty(struct inode *inode, struct inode *dir)
}
kunmap_atomic(kaddr);
- err = dir_commit_chunk(page, 0, 2 * sbi->s_dirsize);
+ dir_commit_chunk(page, 0, 2 * sbi->s_dirsize);
+ err = minix_handle_dirsync(inode);
fail:
put_page(page);
return err;
@@ -409,8 +416,8 @@ not_empty:
}
/* Releases the page */
-void minix_set_link(struct minix_dir_entry *de, struct page *page,
- struct inode *inode)
+int minix_set_link(struct minix_dir_entry *de, struct page *page,
+ struct inode *inode)
{
struct inode *dir = page->mapping->host;
struct minix_sb_info *sbi = minix_sb(dir->i_sb);
@@ -419,20 +426,19 @@ void minix_set_link(struct minix_dir_entry *de, struct page *page,
int err;
lock_page(page);
-
err = minix_prepare_chunk(page, pos, sbi->s_dirsize);
- if (err == 0) {
- if (sbi->s_version == MINIX_V3)
- ((minix3_dirent *) de)->inode = inode->i_ino;
- else
- de->inode = inode->i_ino;
- err = dir_commit_chunk(page, pos, sbi->s_dirsize);
- } else {
+ if (err) {
unlock_page(page);
+ return err;
}
- dir_put_page(page);
+ if (sbi->s_version == MINIX_V3)
+ ((minix3_dirent *)de)->inode = inode->i_ino;
+ else
+ de->inode = inode->i_ino;
+ dir_commit_chunk(page, pos, sbi->s_dirsize);
dir->i_mtime = dir->i_ctime = current_time(dir);
mark_inode_dirty(dir);
+ return minix_handle_dirsync(dir);
}
struct minix_dir_entry * minix_dotdot (struct inode *dir, struct page **p)
diff --git a/fs/minix/file.c b/fs/minix/file.c
index 6a7bd2d9eec0..0dd05d47724a 100644
--- a/fs/minix/file.c
+++ b/fs/minix/file.c
@@ -22,13 +22,13 @@ const struct file_operations minix_file_operations = {
.splice_read = generic_file_splice_read,
};
-static int minix_setattr(struct user_namespace *mnt_userns,
+static int minix_setattr(struct mnt_idmap *idmap,
struct dentry *dentry, struct iattr *attr)
{
struct inode *inode = d_inode(dentry);
int error;
- error = setattr_prepare(&init_user_ns, dentry, attr);
+ error = setattr_prepare(&nop_mnt_idmap, dentry, attr);
if (error)
return error;
@@ -42,7 +42,7 @@ static int minix_setattr(struct user_namespace *mnt_userns,
minix_truncate(inode);
}
- setattr_copy(&init_user_ns, inode, attr);
+ setattr_copy(&nop_mnt_idmap, inode, attr);
mark_inode_dirty(inode);
return 0;
}
diff --git a/fs/minix/inode.c b/fs/minix/inode.c
index da8bdd1712a7..e9fbb5303a22 100644
--- a/fs/minix/inode.c
+++ b/fs/minix/inode.c
@@ -654,13 +654,13 @@ static int minix_write_inode(struct inode *inode, struct writeback_control *wbc)
return err;
}
-int minix_getattr(struct user_namespace *mnt_userns, const struct path *path,
+int minix_getattr(struct mnt_idmap *idmap, const struct path *path,
struct kstat *stat, u32 request_mask, unsigned int flags)
{
struct super_block *sb = path->dentry->d_sb;
struct inode *inode = d_inode(path->dentry);
- generic_fillattr(&init_user_ns, inode, stat);
+ generic_fillattr(&nop_mnt_idmap, inode, stat);
if (INODE_VERSION(inode) == MINIX_V1)
stat->blocks = (BLOCK_SIZE / 512) * V1_minix_blocks(stat->size, sb);
else
diff --git a/fs/minix/minix.h b/fs/minix/minix.h
index 202173368025..d493507c064f 100644
--- a/fs/minix/minix.h
+++ b/fs/minix/minix.h
@@ -45,13 +45,13 @@ struct minix_sb_info {
extern struct inode *minix_iget(struct super_block *, unsigned long);
extern struct minix_inode * minix_V1_raw_inode(struct super_block *, ino_t, struct buffer_head **);
extern struct minix2_inode * minix_V2_raw_inode(struct super_block *, ino_t, struct buffer_head **);
-extern struct inode * minix_new_inode(const struct inode *, umode_t, int *);
+extern struct inode * minix_new_inode(const struct inode *, umode_t);
extern void minix_free_inode(struct inode * inode);
extern unsigned long minix_count_free_inodes(struct super_block *sb);
extern int minix_new_block(struct inode * inode);
extern void minix_free_block(struct inode *inode, unsigned long block);
extern unsigned long minix_count_free_blocks(struct super_block *sb);
-extern int minix_getattr(struct user_namespace *, const struct path *,
+extern int minix_getattr(struct mnt_idmap *, const struct path *,
struct kstat *, u32, unsigned int);
extern int minix_prepare_chunk(struct page *page, loff_t pos, unsigned len);
@@ -69,7 +69,8 @@ extern int minix_add_link(struct dentry*, struct inode*);
extern int minix_delete_entry(struct minix_dir_entry*, struct page*);
extern int minix_make_empty(struct inode*, struct inode*);
extern int minix_empty_dir(struct inode*);
-extern void minix_set_link(struct minix_dir_entry*, struct page*, struct inode*);
+int minix_set_link(struct minix_dir_entry *de, struct page *page,
+ struct inode *inode);
extern struct minix_dir_entry *minix_dotdot(struct inode*, struct page**);
extern ino_t minix_inode_by_name(struct dentry*);
diff --git a/fs/minix/namei.c b/fs/minix/namei.c
index 8afdc408ca4f..956d5183828d 100644
--- a/fs/minix/namei.c
+++ b/fs/minix/namei.c
@@ -33,71 +33,64 @@ static struct dentry *minix_lookup(struct inode * dir, struct dentry *dentry, un
return d_splice_alias(inode, dentry);
}
-static int minix_mknod(struct user_namespace *mnt_userns, struct inode *dir,
+static int minix_mknod(struct mnt_idmap *idmap, struct inode *dir,
struct dentry *dentry, umode_t mode, dev_t rdev)
{
- int error;
struct inode *inode;
if (!old_valid_dev(rdev))
return -EINVAL;
- inode = minix_new_inode(dir, mode, &error);
+ inode = minix_new_inode(dir, mode);
+ if (IS_ERR(inode))
+ return PTR_ERR(inode);
- if (inode) {
- minix_set_inode(inode, rdev);
- mark_inode_dirty(inode);
- error = add_nondir(dentry, inode);
- }
- return error;
+ minix_set_inode(inode, rdev);
+ mark_inode_dirty(inode);
+ return add_nondir(dentry, inode);
}
-static int minix_tmpfile(struct user_namespace *mnt_userns, struct inode *dir,
+static int minix_tmpfile(struct mnt_idmap *idmap, struct inode *dir,
struct file *file, 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(file, inode);
- }
- return finish_open_simple(file, error);
+ struct inode *inode = minix_new_inode(dir, mode);
+
+ if (IS_ERR(inode))
+ return finish_open_simple(file, PTR_ERR(inode));
+ minix_set_inode(inode, 0);
+ mark_inode_dirty(inode);
+ d_tmpfile(file, inode);
+ return finish_open_simple(file, 0);
}
-static int minix_create(struct user_namespace *mnt_userns, struct inode *dir,
+static int minix_create(struct mnt_idmap *idmap, struct inode *dir,
struct dentry *dentry, umode_t mode, bool excl)
{
- return minix_mknod(mnt_userns, dir, dentry, mode, 0);
+ return minix_mknod(&nop_mnt_idmap, dir, dentry, mode, 0);
}
-static int minix_symlink(struct user_namespace *mnt_userns, struct inode *dir,
+static int minix_symlink(struct mnt_idmap *idmap, struct inode *dir,
struct dentry *dentry, const char *symname)
{
- int err = -ENAMETOOLONG;
int i = strlen(symname)+1;
struct inode * inode;
+ int err;
if (i > dir->i_sb->s_blocksize)
- goto out;
+ return -ENAMETOOLONG;
- inode = minix_new_inode(dir, S_IFLNK | 0777, &err);
- if (!inode)
- goto out;
+ inode = minix_new_inode(dir, S_IFLNK | 0777);
+ if (IS_ERR(inode))
+ return PTR_ERR(inode);
minix_set_inode(inode, 0);
err = page_symlink(inode, symname, i);
- if (err)
- goto out_fail;
-
- err = add_nondir(dentry, inode);
-out:
- return err;
-
-out_fail:
- inode_dec_link_count(inode);
- iput(inode);
- goto out;
+ if (unlikely(err)) {
+ inode_dec_link_count(inode);
+ iput(inode);
+ return err;
+ }
+ return add_nondir(dentry, inode);
}
static int minix_link(struct dentry * old_dentry, struct inode * dir,
@@ -111,20 +104,18 @@ static int minix_link(struct dentry * old_dentry, struct inode * dir,
return add_nondir(dentry, inode);
}
-static int minix_mkdir(struct user_namespace *mnt_userns, struct inode *dir,
+static int minix_mkdir(struct mnt_idmap *idmap, struct inode *dir,
struct dentry *dentry, umode_t mode)
{
struct inode * inode;
int err;
- inode_inc_link_count(dir);
-
- inode = minix_new_inode(dir, S_IFDIR | mode, &err);
- if (!inode)
- goto out_dir;
+ inode = minix_new_inode(dir, S_IFDIR | mode);
+ if (IS_ERR(inode))
+ return PTR_ERR(inode);
+ inode_inc_link_count(dir);
minix_set_inode(inode, 0);
-
inode_inc_link_count(inode);
err = minix_make_empty(inode, dir);
@@ -143,30 +134,29 @@ out_fail:
inode_dec_link_count(inode);
inode_dec_link_count(inode);
iput(inode);
-out_dir:
inode_dec_link_count(dir);
goto out;
}
static int minix_unlink(struct inode * dir, struct dentry *dentry)
{
- int err = -ENOENT;
struct inode * inode = d_inode(dentry);
struct page * page;
struct minix_dir_entry * de;
+ int err;
de = minix_find_entry(dentry, &page);
if (!de)
- goto end_unlink;
-
+ return -ENOENT;
err = minix_delete_entry(de, page);
- if (err)
- goto end_unlink;
+ kunmap(page);
+ put_page(page);
+ if (err)
+ return err;
inode->i_ctime = dir->i_ctime;
inode_dec_link_count(inode);
-end_unlink:
- return err;
+ return 0;
}
static int minix_rmdir(struct inode * dir, struct dentry *dentry)
@@ -184,7 +174,7 @@ static int minix_rmdir(struct inode * dir, struct dentry *dentry)
return err;
}
-static int minix_rename(struct user_namespace *mnt_userns,
+static int minix_rename(struct mnt_idmap *idmap,
struct inode *old_dir, struct dentry *old_dentry,
struct inode *new_dir, struct dentry *new_dentry,
unsigned int flags)
@@ -223,7 +213,11 @@ static int minix_rename(struct user_namespace *mnt_userns,
new_de = minix_find_entry(new_dentry, &new_page);
if (!new_de)
goto out_dir;
- minix_set_link(new_de, new_page, old_inode);
+ err = minix_set_link(new_de, new_page, old_inode);
+ kunmap(new_page);
+ put_page(new_page);
+ if (err)
+ goto out_dir;
new_inode->i_ctime = current_time(new_inode);
if (dir_de)
drop_nlink(new_inode);
@@ -236,15 +230,17 @@ static int minix_rename(struct user_namespace *mnt_userns,
inode_inc_link_count(new_dir);
}
- minix_delete_entry(old_de, old_page);
+ err = minix_delete_entry(old_de, old_page);
+ if (err)
+ goto out_dir;
+
mark_inode_dirty(old_inode);
if (dir_de) {
- minix_set_link(dir_de, dir_page, new_dir);
- inode_dec_link_count(old_dir);
+ err = minix_set_link(dir_de, dir_page, new_dir);
+ if (!err)
+ inode_dec_link_count(old_dir);
}
- return 0;
-
out_dir:
if (dir_de) {
kunmap(dir_page);