diff options
-rw-r--r-- | fs/reiserfs/file.c | 20 | ||||
-rw-r--r-- | fs/reiserfs/inode.c | 2 | ||||
-rw-r--r-- | include/linux/reiserfs_fs_i.h | 2 |
3 files changed, 23 insertions, 1 deletions
diff --git a/fs/reiserfs/file.c b/fs/reiserfs/file.c index be12879bb17..fdd96365218 100644 --- a/fs/reiserfs/file.c +++ b/fs/reiserfs/file.c @@ -50,6 +50,11 @@ static int reiserfs_file_release(struct inode *inode, struct file *filp) reiserfs_write_lock(inode->i_sb); mutex_lock(&inode->i_mutex); + + mutex_lock(&(REISERFS_I(inode)->i_mmap)); + if (REISERFS_I(inode)->i_flags & i_ever_mapped) + REISERFS_I(inode)->i_flags &= ~i_pack_on_close_mask; + /* freeing preallocation only involves relogging blocks that * are already in the current transaction. preallocation gets * freed at the end of each transaction, so it is impossible for @@ -100,11 +105,24 @@ static int reiserfs_file_release(struct inode *inode, struct file *filp) err = reiserfs_truncate_file(inode, 0); } out: + mutex_unlock(&(REISERFS_I(inode)->i_mmap)); mutex_unlock(&inode->i_mutex); reiserfs_write_unlock(inode->i_sb); return err; } +static int reiserfs_file_mmap(struct file *file, struct vm_area_struct *vma) +{ + struct inode *inode; + + inode = file->f_dentry->d_inode; + mutex_lock(&(REISERFS_I(inode)->i_mmap)); + REISERFS_I(inode)->i_flags |= i_ever_mapped; + mutex_unlock(&(REISERFS_I(inode)->i_mmap)); + + return generic_file_mmap(file, vma); +} + static void reiserfs_vfs_truncate_file(struct inode *inode) { reiserfs_truncate_file(inode, 1); @@ -1570,7 +1588,7 @@ struct file_operations reiserfs_file_operations = { .read = generic_file_read, .write = reiserfs_file_write, .ioctl = reiserfs_ioctl, - .mmap = generic_file_mmap, + .mmap = reiserfs_file_mmap, .release = reiserfs_file_release, .fsync = reiserfs_sync_file, .sendfile = generic_file_sendfile, diff --git a/fs/reiserfs/inode.c b/fs/reiserfs/inode.c index d60f6238c66..4cb01689aec 100644 --- a/fs/reiserfs/inode.c +++ b/fs/reiserfs/inode.c @@ -1140,6 +1140,7 @@ static void init_inode(struct inode *inode, struct path *path) REISERFS_I(inode)->i_prealloc_count = 0; REISERFS_I(inode)->i_trans_id = 0; REISERFS_I(inode)->i_jl = NULL; + mutex_init(&(REISERFS_I(inode)->i_mmap)); REISERFS_I(inode)->i_acl_access = NULL; REISERFS_I(inode)->i_acl_default = NULL; init_rwsem(&REISERFS_I(inode)->xattr_sem); @@ -1847,6 +1848,7 @@ int reiserfs_new_inode(struct reiserfs_transaction_handle *th, REISERFS_I(inode)->i_attrs = REISERFS_I(dir)->i_attrs & REISERFS_INHERIT_MASK; sd_attrs_to_i_attrs(REISERFS_I(inode)->i_attrs, inode); + mutex_init(&(REISERFS_I(inode)->i_mmap)); REISERFS_I(inode)->i_acl_access = NULL; REISERFS_I(inode)->i_acl_default = NULL; init_rwsem(&REISERFS_I(inode)->xattr_sem); diff --git a/include/linux/reiserfs_fs_i.h b/include/linux/reiserfs_fs_i.h index 149be8d9a0c..547bbf3a119 100644 --- a/include/linux/reiserfs_fs_i.h +++ b/include/linux/reiserfs_fs_i.h @@ -25,6 +25,7 @@ typedef enum { i_link_saved_truncate_mask = 0x0020, i_has_xattr_dir = 0x0040, i_data_log = 0x0080, + i_ever_mapped = 0x0100 } reiserfs_inode_flags; struct reiserfs_inode_info { @@ -52,6 +53,7 @@ struct reiserfs_inode_info { ** flushed */ unsigned long i_trans_id; struct reiserfs_journal_list *i_jl; + struct mutex i_mmap; struct posix_acl *i_acl_access; struct posix_acl *i_acl_default; |