diff options
Diffstat (limited to 'fs/minix')
| -rw-r--r-- | fs/minix/bitmap.c | 6 | ||||
| -rw-r--r-- | fs/minix/dir.c | 21 | ||||
| -rw-r--r-- | fs/minix/file.c | 22 | ||||
| -rw-r--r-- | fs/minix/inode.c | 35 | ||||
| -rw-r--r-- | fs/minix/minix.h | 4 |
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) | |||
| 200 | ino = inode->i_ino; | 200 | ino = inode->i_ino; |
| 201 | if (ino < 1 || ino > sbi->s_ninodes) { | 201 | if (ino < 1 || ino > sbi->s_ninodes) { |
| 202 | printk("minix_free_inode: inode 0 or nonexistent inode\n"); | 202 | printk("minix_free_inode: inode 0 or nonexistent inode\n"); |
| 203 | goto out; | 203 | return; |
| 204 | } | 204 | } |
| 205 | bit = ino & ((1<<k) - 1); | 205 | bit = ino & ((1<<k) - 1); |
| 206 | ino >>= k; | 206 | ino >>= k; |
| 207 | if (ino >= sbi->s_imap_blocks) { | 207 | if (ino >= sbi->s_imap_blocks) { |
| 208 | printk("minix_free_inode: nonexistent imap in superblock\n"); | 208 | printk("minix_free_inode: nonexistent imap in superblock\n"); |
| 209 | goto out; | 209 | return; |
| 210 | } | 210 | } |
| 211 | 211 | ||
| 212 | minix_clear_inode(inode); /* clear on-disk copy */ | 212 | minix_clear_inode(inode); /* clear on-disk copy */ |
| @@ -217,8 +217,6 @@ void minix_free_inode(struct inode * inode) | |||
| 217 | printk("minix_free_inode: bit %lu already cleared\n", bit); | 217 | printk("minix_free_inode: bit %lu already cleared\n", bit); |
| 218 | spin_unlock(&bitmap_lock); | 218 | spin_unlock(&bitmap_lock); |
| 219 | mark_buffer_dirty(bh); | 219 | mark_buffer_dirty(bh); |
| 220 | out: | ||
| 221 | clear_inode(inode); /* clear in-memory copy */ | ||
| 222 | } | 220 | } |
| 223 | 221 | ||
| 224 | struct inode *minix_new_inode(const struct inode *dir, int mode, int *error) | 222 | 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) | |||
| 271 | 271 | ||
| 272 | got_it: | 272 | got_it: |
| 273 | pos = page_offset(page) + p - (char *)page_address(page); | 273 | pos = page_offset(page) + p - (char *)page_address(page); |
| 274 | err = __minix_write_begin(NULL, page->mapping, pos, sbi->s_dirsize, | 274 | err = minix_prepare_chunk(page, pos, sbi->s_dirsize); |
| 275 | AOP_FLAG_UNINTERRUPTIBLE, &page, NULL); | ||
| 276 | if (err) | 275 | if (err) |
| 277 | goto out_unlock; | 276 | goto out_unlock; |
| 278 | memcpy (namx, name, namelen); | 277 | memcpy (namx, name, namelen); |
| @@ -297,8 +296,7 @@ out_unlock: | |||
| 297 | 296 | ||
| 298 | int minix_delete_entry(struct minix_dir_entry *de, struct page *page) | 297 | int minix_delete_entry(struct minix_dir_entry *de, struct page *page) |
| 299 | { | 298 | { |
| 300 | struct address_space *mapping = page->mapping; | 299 | struct inode *inode = page->mapping->host; |
| 301 | struct inode *inode = (struct inode*)mapping->host; | ||
| 302 | char *kaddr = page_address(page); | 300 | char *kaddr = page_address(page); |
| 303 | loff_t pos = page_offset(page) + (char*)de - kaddr; | 301 | loff_t pos = page_offset(page) + (char*)de - kaddr; |
| 304 | struct minix_sb_info *sbi = minix_sb(inode->i_sb); | 302 | 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) | |||
| 306 | int err; | 304 | int err; |
| 307 | 305 | ||
| 308 | lock_page(page); | 306 | lock_page(page); |
| 309 | err = __minix_write_begin(NULL, mapping, pos, len, | 307 | err = minix_prepare_chunk(page, pos, len); |
| 310 | AOP_FLAG_UNINTERRUPTIBLE, &page, NULL); | ||
| 311 | if (err == 0) { | 308 | if (err == 0) { |
| 312 | if (sbi->s_version == MINIX_V3) | 309 | if (sbi->s_version == MINIX_V3) |
| 313 | ((minix3_dirent *) de)->inode = 0; | 310 | ((minix3_dirent *) de)->inode = 0; |
| @@ -325,16 +322,14 @@ int minix_delete_entry(struct minix_dir_entry *de, struct page *page) | |||
| 325 | 322 | ||
| 326 | int minix_make_empty(struct inode *inode, struct inode *dir) | 323 | int minix_make_empty(struct inode *inode, struct inode *dir) |
| 327 | { | 324 | { |
| 328 | struct address_space *mapping = inode->i_mapping; | 325 | struct page *page = grab_cache_page(inode->i_mapping, 0); |
| 329 | struct page *page = grab_cache_page(mapping, 0); | ||
| 330 | struct minix_sb_info *sbi = minix_sb(inode->i_sb); | 326 | struct minix_sb_info *sbi = minix_sb(inode->i_sb); |
| 331 | char *kaddr; | 327 | char *kaddr; |
| 332 | int err; | 328 | int err; |
| 333 | 329 | ||
| 334 | if (!page) | 330 | if (!page) |
| 335 | return -ENOMEM; | 331 | return -ENOMEM; |
| 336 | err = __minix_write_begin(NULL, mapping, 0, 2 * sbi->s_dirsize, | 332 | err = minix_prepare_chunk(page, 0, 2 * sbi->s_dirsize); |
| 337 | AOP_FLAG_UNINTERRUPTIBLE, &page, NULL); | ||
| 338 | if (err) { | 333 | if (err) { |
| 339 | unlock_page(page); | 334 | unlock_page(page); |
| 340 | goto fail; | 335 | goto fail; |
| @@ -425,8 +420,7 @@ not_empty: | |||
| 425 | void minix_set_link(struct minix_dir_entry *de, struct page *page, | 420 | void minix_set_link(struct minix_dir_entry *de, struct page *page, |
| 426 | struct inode *inode) | 421 | struct inode *inode) |
| 427 | { | 422 | { |
| 428 | struct address_space *mapping = page->mapping; | 423 | struct inode *dir = page->mapping->host; |
| 429 | struct inode *dir = mapping->host; | ||
| 430 | struct minix_sb_info *sbi = minix_sb(dir->i_sb); | 424 | struct minix_sb_info *sbi = minix_sb(dir->i_sb); |
| 431 | loff_t pos = page_offset(page) + | 425 | loff_t pos = page_offset(page) + |
| 432 | (char *)de-(char*)page_address(page); | 426 | (char *)de-(char*)page_address(page); |
| @@ -434,8 +428,7 @@ void minix_set_link(struct minix_dir_entry *de, struct page *page, | |||
| 434 | 428 | ||
| 435 | lock_page(page); | 429 | lock_page(page); |
| 436 | 430 | ||
| 437 | err = __minix_write_begin(NULL, mapping, pos, sbi->s_dirsize, | 431 | err = minix_prepare_chunk(page, pos, sbi->s_dirsize); |
| 438 | AOP_FLAG_UNINTERRUPTIBLE, &page, NULL); | ||
| 439 | if (err == 0) { | 432 | if (err == 0) { |
| 440 | if (sbi->s_version == MINIX_V3) | 433 | if (sbi->s_version == MINIX_V3) |
| 441 | ((minix3_dirent *) de)->inode = inode->i_ino; | 434 | ((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 = { | |||
| 23 | .splice_read = generic_file_splice_read, | 23 | .splice_read = generic_file_splice_read, |
| 24 | }; | 24 | }; |
| 25 | 25 | ||
| 26 | static int minix_setattr(struct dentry *dentry, struct iattr *attr) | ||
| 27 | { | ||
| 28 | struct inode *inode = dentry->d_inode; | ||
| 29 | int error; | ||
| 30 | |||
| 31 | error = inode_change_ok(inode, attr); | ||
| 32 | if (error) | ||
| 33 | return error; | ||
| 34 | |||
| 35 | if ((attr->ia_valid & ATTR_SIZE) && | ||
| 36 | attr->ia_size != i_size_read(inode)) { | ||
| 37 | error = vmtruncate(inode, attr->ia_size); | ||
| 38 | if (error) | ||
| 39 | return error; | ||
| 40 | } | ||
| 41 | |||
| 42 | setattr_copy(inode, attr); | ||
| 43 | mark_inode_dirty(inode); | ||
| 44 | return 0; | ||
| 45 | } | ||
| 46 | |||
| 26 | const struct inode_operations minix_file_inode_operations = { | 47 | const struct inode_operations minix_file_inode_operations = { |
| 27 | .truncate = minix_truncate, | 48 | .truncate = minix_truncate, |
| 49 | .setattr = minix_setattr, | ||
| 28 | .getattr = minix_getattr, | 50 | .getattr = minix_getattr, |
| 29 | }; | 51 | }; |
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, | |||
| 24 | static int minix_statfs(struct dentry *dentry, struct kstatfs *buf); | 24 | static int minix_statfs(struct dentry *dentry, struct kstatfs *buf); |
| 25 | static int minix_remount (struct super_block * sb, int * flags, char * data); | 25 | static int minix_remount (struct super_block * sb, int * flags, char * data); |
| 26 | 26 | ||
| 27 | static void minix_delete_inode(struct inode *inode) | 27 | static void minix_evict_inode(struct inode *inode) |
| 28 | { | 28 | { |
| 29 | truncate_inode_pages(&inode->i_data, 0); | 29 | truncate_inode_pages(&inode->i_data, 0); |
| 30 | inode->i_size = 0; | 30 | if (!inode->i_nlink) { |
| 31 | minix_truncate(inode); | 31 | inode->i_size = 0; |
| 32 | minix_free_inode(inode); | 32 | minix_truncate(inode); |
| 33 | } | ||
| 34 | invalidate_inode_buffers(inode); | ||
| 35 | end_writeback(inode); | ||
| 36 | if (!inode->i_nlink) | ||
| 37 | minix_free_inode(inode); | ||
| 33 | } | 38 | } |
| 34 | 39 | ||
| 35 | static void minix_put_super(struct super_block *sb) | 40 | static void minix_put_super(struct super_block *sb) |
| @@ -96,7 +101,7 @@ static const struct super_operations minix_sops = { | |||
| 96 | .alloc_inode = minix_alloc_inode, | 101 | .alloc_inode = minix_alloc_inode, |
| 97 | .destroy_inode = minix_destroy_inode, | 102 | .destroy_inode = minix_destroy_inode, |
| 98 | .write_inode = minix_write_inode, | 103 | .write_inode = minix_write_inode, |
| 99 | .delete_inode = minix_delete_inode, | 104 | .evict_inode = minix_evict_inode, |
| 100 | .put_super = minix_put_super, | 105 | .put_super = minix_put_super, |
| 101 | .statfs = minix_statfs, | 106 | .statfs = minix_statfs, |
| 102 | .remount_fs = minix_remount, | 107 | .remount_fs = minix_remount, |
| @@ -357,20 +362,26 @@ static int minix_readpage(struct file *file, struct page *page) | |||
| 357 | return block_read_full_page(page,minix_get_block); | 362 | return block_read_full_page(page,minix_get_block); |
| 358 | } | 363 | } |
| 359 | 364 | ||
| 360 | int __minix_write_begin(struct file *file, struct address_space *mapping, | 365 | int minix_prepare_chunk(struct page *page, loff_t pos, unsigned len) |
| 361 | loff_t pos, unsigned len, unsigned flags, | ||
| 362 | struct page **pagep, void **fsdata) | ||
| 363 | { | 366 | { |
| 364 | return block_write_begin(file, mapping, pos, len, flags, pagep, fsdata, | 367 | return __block_write_begin(page, pos, len, minix_get_block); |
| 365 | minix_get_block); | ||
| 366 | } | 368 | } |
| 367 | 369 | ||
| 368 | static int minix_write_begin(struct file *file, struct address_space *mapping, | 370 | static int minix_write_begin(struct file *file, struct address_space *mapping, |
| 369 | loff_t pos, unsigned len, unsigned flags, | 371 | loff_t pos, unsigned len, unsigned flags, |
| 370 | struct page **pagep, void **fsdata) | 372 | struct page **pagep, void **fsdata) |
| 371 | { | 373 | { |
| 372 | *pagep = NULL; | 374 | int ret; |
| 373 | return __minix_write_begin(file, mapping, pos, len, flags, pagep, fsdata); | 375 | |
| 376 | ret = block_write_begin(mapping, pos, len, flags, pagep, | ||
| 377 | minix_get_block); | ||
| 378 | if (unlikely(ret)) { | ||
| 379 | loff_t isize = mapping->host->i_size; | ||
| 380 | if (pos + len > isize) | ||
| 381 | vmtruncate(mapping->host, isize); | ||
| 382 | } | ||
| 383 | |||
| 384 | return ret; | ||
| 374 | } | 385 | } |
| 375 | 386 | ||
| 376 | static sector_t minix_bmap(struct address_space *mapping, sector_t block) | 387 | 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); | |||
| 53 | extern void minix_free_block(struct inode *inode, unsigned long block); | 53 | extern void minix_free_block(struct inode *inode, unsigned long block); |
| 54 | extern unsigned long minix_count_free_blocks(struct minix_sb_info *sbi); | 54 | extern unsigned long minix_count_free_blocks(struct minix_sb_info *sbi); |
| 55 | extern int minix_getattr(struct vfsmount *, struct dentry *, struct kstat *); | 55 | extern int minix_getattr(struct vfsmount *, struct dentry *, struct kstat *); |
| 56 | extern int __minix_write_begin(struct file *file, struct address_space *mapping, | 56 | extern int minix_prepare_chunk(struct page *page, loff_t pos, unsigned len); |
| 57 | loff_t pos, unsigned len, unsigned flags, | ||
| 58 | struct page **pagep, void **fsdata); | ||
| 59 | 57 | ||
| 60 | extern void V1_minix_truncate(struct inode *); | 58 | extern void V1_minix_truncate(struct inode *); |
| 61 | extern void V2_minix_truncate(struct inode *); | 59 | extern void V2_minix_truncate(struct inode *); |
