diff options
Diffstat (limited to 'fs/affs/file.c')
-rw-r--r-- | fs/affs/file.c | 29 |
1 files changed, 17 insertions, 12 deletions
diff --git a/fs/affs/file.c b/fs/affs/file.c index 1a4f092f24ef..1377b1240b6e 100644 --- a/fs/affs/file.c +++ b/fs/affs/file.c | |||
@@ -46,22 +46,25 @@ const struct inode_operations affs_file_inode_operations = { | |||
46 | static int | 46 | static int |
47 | affs_file_open(struct inode *inode, struct file *filp) | 47 | affs_file_open(struct inode *inode, struct file *filp) |
48 | { | 48 | { |
49 | if (atomic_read(&filp->f_count) != 1) | 49 | pr_debug("AFFS: open(%lu,%d)\n", |
50 | return 0; | 50 | inode->i_ino, atomic_read(&AFFS_I(inode)->i_opencnt)); |
51 | pr_debug("AFFS: open(%d)\n", AFFS_I(inode)->i_opencnt); | 51 | atomic_inc(&AFFS_I(inode)->i_opencnt); |
52 | AFFS_I(inode)->i_opencnt++; | ||
53 | return 0; | 52 | return 0; |
54 | } | 53 | } |
55 | 54 | ||
56 | static int | 55 | static int |
57 | affs_file_release(struct inode *inode, struct file *filp) | 56 | affs_file_release(struct inode *inode, struct file *filp) |
58 | { | 57 | { |
59 | if (atomic_read(&filp->f_count) != 0) | 58 | pr_debug("AFFS: release(%lu, %d)\n", |
60 | return 0; | 59 | inode->i_ino, atomic_read(&AFFS_I(inode)->i_opencnt)); |
61 | pr_debug("AFFS: release(%d)\n", AFFS_I(inode)->i_opencnt); | 60 | |
62 | AFFS_I(inode)->i_opencnt--; | 61 | if (atomic_dec_and_test(&AFFS_I(inode)->i_opencnt)) { |
63 | if (!AFFS_I(inode)->i_opencnt) | 62 | mutex_lock(&inode->i_mutex); |
63 | if (inode->i_size != AFFS_I(inode)->mmu_private) | ||
64 | affs_truncate(inode); | ||
64 | affs_free_prealloc(inode); | 65 | affs_free_prealloc(inode); |
66 | mutex_unlock(&inode->i_mutex); | ||
67 | } | ||
65 | 68 | ||
66 | return 0; | 69 | return 0; |
67 | } | 70 | } |
@@ -180,7 +183,7 @@ affs_get_extblock(struct inode *inode, u32 ext) | |||
180 | /* inline the simplest case: same extended block as last time */ | 183 | /* inline the simplest case: same extended block as last time */ |
181 | struct buffer_head *bh = AFFS_I(inode)->i_ext_bh; | 184 | struct buffer_head *bh = AFFS_I(inode)->i_ext_bh; |
182 | if (ext == AFFS_I(inode)->i_ext_last) | 185 | if (ext == AFFS_I(inode)->i_ext_last) |
183 | atomic_inc(&bh->b_count); | 186 | get_bh(bh); |
184 | else | 187 | else |
185 | /* we have to do more (not inlined) */ | 188 | /* we have to do more (not inlined) */ |
186 | bh = affs_get_extblock_slow(inode, ext); | 189 | bh = affs_get_extblock_slow(inode, ext); |
@@ -306,7 +309,7 @@ store_ext: | |||
306 | affs_brelse(AFFS_I(inode)->i_ext_bh); | 309 | affs_brelse(AFFS_I(inode)->i_ext_bh); |
307 | AFFS_I(inode)->i_ext_last = ext; | 310 | AFFS_I(inode)->i_ext_last = ext; |
308 | AFFS_I(inode)->i_ext_bh = bh; | 311 | AFFS_I(inode)->i_ext_bh = bh; |
309 | atomic_inc(&bh->b_count); | 312 | get_bh(bh); |
310 | 313 | ||
311 | return bh; | 314 | return bh; |
312 | 315 | ||
@@ -324,7 +327,6 @@ affs_get_block(struct inode *inode, sector_t block, struct buffer_head *bh_resul | |||
324 | 327 | ||
325 | pr_debug("AFFS: get_block(%u, %lu)\n", (u32)inode->i_ino, (unsigned long)block); | 328 | pr_debug("AFFS: get_block(%u, %lu)\n", (u32)inode->i_ino, (unsigned long)block); |
326 | 329 | ||
327 | |||
328 | BUG_ON(block > (sector_t)0x7fffffffUL); | 330 | BUG_ON(block > (sector_t)0x7fffffffUL); |
329 | 331 | ||
330 | if (block >= AFFS_I(inode)->i_blkcnt) { | 332 | if (block >= AFFS_I(inode)->i_blkcnt) { |
@@ -827,6 +829,8 @@ affs_truncate(struct inode *inode) | |||
827 | res = mapping->a_ops->write_begin(NULL, mapping, size, 0, 0, &page, &fsdata); | 829 | res = mapping->a_ops->write_begin(NULL, mapping, size, 0, 0, &page, &fsdata); |
828 | if (!res) | 830 | if (!res) |
829 | res = mapping->a_ops->write_end(NULL, mapping, size, 0, 0, page, fsdata); | 831 | res = mapping->a_ops->write_end(NULL, mapping, size, 0, 0, page, fsdata); |
832 | else | ||
833 | inode->i_size = AFFS_I(inode)->mmu_private; | ||
830 | mark_inode_dirty(inode); | 834 | mark_inode_dirty(inode); |
831 | return; | 835 | return; |
832 | } else if (inode->i_size == AFFS_I(inode)->mmu_private) | 836 | } else if (inode->i_size == AFFS_I(inode)->mmu_private) |
@@ -862,6 +866,7 @@ affs_truncate(struct inode *inode) | |||
862 | blk++; | 866 | blk++; |
863 | } else | 867 | } else |
864 | AFFS_HEAD(ext_bh)->first_data = 0; | 868 | AFFS_HEAD(ext_bh)->first_data = 0; |
869 | AFFS_HEAD(ext_bh)->block_count = cpu_to_be32(i); | ||
865 | size = AFFS_SB(sb)->s_hashsize; | 870 | size = AFFS_SB(sb)->s_hashsize; |
866 | if (size > blkcnt - blk + i) | 871 | if (size > blkcnt - blk + i) |
867 | size = blkcnt - blk + i; | 872 | size = blkcnt - blk + i; |