summaryrefslogtreecommitdiff
path: root/fs/minix
diff options
context:
space:
mode:
Diffstat (limited to 'fs/minix')
-rw-r--r--fs/minix/bitmap.c6
-rw-r--r--fs/minix/dir.c21
-rw-r--r--fs/minix/file.c22
-rw-r--r--fs/minix/inode.c35
-rw-r--r--fs/minix/minix.h4
5 files changed, 55 insertions, 33 deletions
diff --git a/fs/minix/bitmap.c b/fs/minix/bitmap.c
index 482779fe4e7c..3f32bcb0d9bd 100644
--- a/fs/minix/bitmap.c
+++ b/fs/minix/bitmap.c
@@ -200,13 +200,13 @@ void minix_free_inode(struct inode * inode)
ino = inode->i_ino;
if (ino < 1 || ino > sbi->s_ninodes) {
printk("minix_free_inode: inode 0 or nonexistent inode\n");
- goto out;
+ return;
}
bit = ino & ((1<<k) - 1);
ino >>= k;
if (ino >= sbi->s_imap_blocks) {
printk("minix_free_inode: nonexistent imap in superblock\n");
- goto out;
+ return;
}
minix_clear_inode(inode); /* clear on-disk copy */
@@ -217,8 +217,6 @@ void minix_free_inode(struct inode * inode)
printk("minix_free_inode: bit %lu already cleared\n", bit);
spin_unlock(&bitmap_lock);
mark_buffer_dirty(bh);
- out:
- clear_inode(inode); /* clear in-memory copy */
}
struct inode *minix_new_inode(const struct inode *dir, int mode, int *error)
diff --git a/fs/minix/dir.c b/fs/minix/dir.c
index 1dbf921ca44b..085a9262c692 100644
--- a/fs/minix/dir.c
+++ b/fs/minix/dir.c
@@ -271,8 +271,7 @@ int minix_add_link(struct dentry *dentry, struct inode *inode)
got_it:
pos = page_offset(page) + p - (char *)page_address(page);
- err = __minix_write_begin(NULL, page->mapping, pos, sbi->s_dirsize,
- AOP_FLAG_UNINTERRUPTIBLE, &page, NULL);
+ err = minix_prepare_chunk(page, pos, sbi->s_dirsize);
if (err)
goto out_unlock;
memcpy (namx, name, namelen);
@@ -297,8 +296,7 @@ out_unlock:
int minix_delete_entry(struct minix_dir_entry *de, struct page *page)
{
- struct address_space *mapping = page->mapping;
- struct inode *inode = (struct inode*)mapping->host;
+ struct inode *inode = page->mapping->host;
char *kaddr = page_address(page);
loff_t pos = page_offset(page) + (char*)de - kaddr;
struct minix_sb_info *sbi = minix_sb(inode->i_sb);
@@ -306,8 +304,7 @@ int minix_delete_entry(struct minix_dir_entry *de, struct page *page)
int err;
lock_page(page);
- err = __minix_write_begin(NULL, mapping, pos, len,
- AOP_FLAG_UNINTERRUPTIBLE, &page, NULL);
+ err = minix_prepare_chunk(page, pos, len);
if (err == 0) {
if (sbi->s_version == MINIX_V3)
((minix3_dirent *) de)->inode = 0;
@@ -325,16 +322,14 @@ int minix_delete_entry(struct minix_dir_entry *de, struct page *page)
int minix_make_empty(struct inode *inode, struct inode *dir)
{
- struct address_space *mapping = inode->i_mapping;
- struct page *page = grab_cache_page(mapping, 0);
+ struct page *page = grab_cache_page(inode->i_mapping, 0);
struct minix_sb_info *sbi = minix_sb(inode->i_sb);
char *kaddr;
int err;
if (!page)
return -ENOMEM;
- err = __minix_write_begin(NULL, mapping, 0, 2 * sbi->s_dirsize,
- AOP_FLAG_UNINTERRUPTIBLE, &page, NULL);
+ err = minix_prepare_chunk(page, 0, 2 * sbi->s_dirsize);
if (err) {
unlock_page(page);
goto fail;
@@ -425,8 +420,7 @@ not_empty:
void minix_set_link(struct minix_dir_entry *de, struct page *page,
struct inode *inode)
{
- struct address_space *mapping = page->mapping;
- struct inode *dir = mapping->host;
+ struct inode *dir = page->mapping->host;
struct minix_sb_info *sbi = minix_sb(dir->i_sb);
loff_t pos = page_offset(page) +
(char *)de-(char*)page_address(page);
@@ -434,8 +428,7 @@ void minix_set_link(struct minix_dir_entry *de, struct page *page,
lock_page(page);
- err = __minix_write_begin(NULL, mapping, pos, sbi->s_dirsize,
- AOP_FLAG_UNINTERRUPTIBLE, &page, NULL);
+ 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;
diff --git a/fs/minix/file.c b/fs/minix/file.c
index d5320ff23faf..4493ce695ab8 100644
--- a/fs/minix/file.c
+++ b/fs/minix/file.c
@@ -23,7 +23,29 @@ const struct file_operations minix_file_operations = {
.splice_read = generic_file_splice_read,
};
+static int minix_setattr(struct dentry *dentry, struct iattr *attr)
+{
+ struct inode *inode = dentry->d_inode;
+ int error;
+
+ error = inode_change_ok(inode, attr);
+ if (error)
+ return error;
+
+ if ((attr->ia_valid & ATTR_SIZE) &&
+ attr->ia_size != i_size_read(inode)) {
+ error = vmtruncate(inode, attr->ia_size);
+ if (error)
+ return error;
+ }
+
+ setattr_copy(inode, attr);
+ mark_inode_dirty(inode);
+ return 0;
+}
+
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 756f8c93780c..e39d6bf2e8fb 100644
--- a/fs/minix/inode.c
+++ b/fs/minix/inode.c
@@ -24,12 +24,17 @@ static int minix_write_inode(struct inode *inode,
static int minix_statfs(struct dentry *dentry, struct kstatfs *buf);
static int minix_remount (struct super_block * sb, int * flags, char * data);
-static void minix_delete_inode(struct inode *inode)
+static void minix_evict_inode(struct inode *inode)
{
truncate_inode_pages(&inode->i_data, 0);
- inode->i_size = 0;
- minix_truncate(inode);
- minix_free_inode(inode);
+ if (!inode->i_nlink) {
+ inode->i_size = 0;
+ minix_truncate(inode);
+ }
+ invalidate_inode_buffers(inode);
+ end_writeback(inode);
+ if (!inode->i_nlink)
+ minix_free_inode(inode);
}
static void minix_put_super(struct super_block *sb)
@@ -96,7 +101,7 @@ static const struct super_operations minix_sops = {
.alloc_inode = minix_alloc_inode,
.destroy_inode = minix_destroy_inode,
.write_inode = minix_write_inode,
- .delete_inode = minix_delete_inode,
+ .evict_inode = minix_evict_inode,
.put_super = minix_put_super,
.statfs = minix_statfs,
.remount_fs = minix_remount,
@@ -357,20 +362,26 @@ static int minix_readpage(struct file *file, struct page *page)
return block_read_full_page(page,minix_get_block);
}
-int __minix_write_begin(struct file *file, struct address_space *mapping,
- loff_t pos, unsigned len, unsigned flags,
- struct page **pagep, void **fsdata)
+int minix_prepare_chunk(struct page *page, loff_t pos, unsigned len)
{
- return block_write_begin(file, mapping, pos, len, flags, pagep, fsdata,
- minix_get_block);
+ return __block_write_begin(page, pos, len, minix_get_block);
}
static int minix_write_begin(struct file *file, struct address_space *mapping,
loff_t pos, unsigned len, unsigned flags,
struct page **pagep, void **fsdata)
{
- *pagep = NULL;
- return __minix_write_begin(file, mapping, pos, len, flags, pagep, fsdata);
+ int ret;
+
+ 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);
+ }
+
+ return ret;
}
static sector_t minix_bmap(struct address_space *mapping, sector_t block)
diff --git a/fs/minix/minix.h b/fs/minix/minix.h
index 111f34ee9e3b..407b1c84911e 100644
--- a/fs/minix/minix.h
+++ b/fs/minix/minix.h
@@ -53,9 +53,7 @@ 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 minix_sb_info *sbi);
extern int minix_getattr(struct vfsmount *, struct dentry *, struct kstat *);
-extern int __minix_write_begin(struct file *file, struct address_space *mapping,
- loff_t pos, unsigned len, unsigned flags,
- struct page **pagep, void **fsdata);
+extern int minix_prepare_chunk(struct page *page, loff_t pos, unsigned len);
extern void V1_minix_truncate(struct inode *);
extern void V2_minix_truncate(struct inode *);