diff -u -r --exclude='*.cmd' --exclude='*.o' --exclude='*.orig' --exclude='*.rej' linux-2.6.21-rc4-git7/fs/reiser4/inode.h linux-2.6.20.4/fs/reiser4/inode.h --- linux-2.6.21-rc4-git7/fs/reiser4/inode.h 2007-03-23 14:40:53.445156464 +0300 +++ linux-2.6.20.4/fs/reiser4/inode.h 2007-04-06 04:02:40.000000000 +0400 @@ -136,6 +136,17 @@ cryptcompress_info_t cryptcompress_info; } file_plugin_data; + /* this semaphore is used to serialize writes of any file plugin, + * and should be invariant during file plugin conversion (which + * is going in the context of ->write()). + * inode->i_mutex can not be used for the serialization, because + * write_unix_file uses get_user_pages which is to be used under + * mm->mmap_sem and because it is required to take mm->mmap_sem before + * inode->i_mutex, so inode->i_mutex would have to be up()-ed before + * calling to get_user_pages which is unacceptable. + */ + struct mutex mutex_write; + /* this semaphore is to serialize readers and writers of @pset->file * when file plugin conversion is enabled */ diff -u -r --exclude='*.cmd' --exclude='*.o' --exclude='*.orig' --exclude='*.rej' linux-2.6.21-rc4-git7/fs/reiser4/plugin/file/file.c linux-2.6.20.4/fs/reiser4/plugin/file/file.c --- linux-2.6.21-rc4-git7/fs/reiser4/plugin/file/file.c 2007-03-24 01:14:45.000000000 +0300 +++ linux-2.6.20.4/fs/reiser4/plugin/file/file.c 2007-04-06 04:02:40.000000000 +0400 @@ -1937,6 +1933,7 @@ uf_info = unix_file_inode_data(inode); + mutex_lock(&reiser4_inode_data(inode)->mutex_write); get_exclusive_access(uf_info); if (!IS_RDONLY(inode) && (vma->vm_flags & (VM_MAYWRITE | VM_SHARED))) { @@ -1948,6 +1945,7 @@ result = find_file_state(inode, uf_info); if (result != 0) { drop_exclusive_access(uf_info); + mutex_unlock(&reiser4_inode_data(inode)->mutex_write); reiser4_exit_context(ctx); return result; } @@ -1963,6 +1961,7 @@ result = check_pages_unix_file(file, inode); if (result) { drop_exclusive_access(uf_info); + mutex_unlock(&reiser4_inode_data(inode)->mutex_write); reiser4_exit_context(ctx); return result; } @@ -1977,6 +1976,7 @@ result = reiser4_grab_space_force(needed, BA_CAN_COMMIT); if (result) { drop_exclusive_access(uf_info); + mutex_unlock(&reiser4_inode_data(inode)->mutex_write); reiser4_exit_context(ctx); return result; } @@ -1988,6 +1988,7 @@ } drop_exclusive_access(uf_info); + mutex_unlock(&reiser4_inode_data(inode)->mutex_write); reiser4_exit_context(ctx); return result; } @@ -2369,6 +2370,7 @@ if (in_reiser4 == 0) { uf_info = unix_file_inode_data(inode); + mutex_lock(&reiser4_inode_data(inode)->mutex_write); get_exclusive_access(uf_info); if (atomic_read(&file->f_dentry->d_count) == 1 && uf_info->container == UF_CONTAINER_EXTENTS && @@ -2384,6 +2386,7 @@ } } drop_exclusive_access(uf_info); + mutex_unlock(&reiser4_inode_data(inode)->mutex_write); } else { /* we are within reiser4 context already. How latter is @@ -2678,9 +2681,11 @@ return PTR_ERR(ctx); uf_info = unix_file_inode_data(dentry->d_inode); + mutex_lock(&reiser4_inode_data(dentry->d_inode)->mutex_write); get_exclusive_access(uf_info); result = setattr_truncate(dentry->d_inode, attr); drop_exclusive_access(uf_info); + mutex_unlock(&reiser4_inode_data(dentry->d_inode)->mutex_write); context_set_commit_async(ctx); reiser4_exit_context(ctx); } else diff -u -r --exclude='*.cmd' --exclude='*.o' --exclude='*.orig' --exclude='*.rej' linux-2.6.21-rc4-git7/fs/reiser4/super_ops.c linux-2.6.20.4/fs/reiser4/super_ops.c --- linux-2.6.21-rc4-git7/fs/reiser4/super_ops.c 2007-03-23 14:40:53.818099768 +0300 +++ linux-2.6.20.4/fs/reiser4/super_ops.c 2007-04-06 04:02:40.000000000 +0400 @@ -44,6 +44,7 @@ * etc. that will be added to our private inode part. */ INIT_LIST_HEAD(get_readdir_list(&info->vfs_inode)); + mutex_init(&info->p.mutex_write); init_rwsem(&info->p.conv_sem); /* init semaphore which is used during inode loading */ loading_init_once(&info->p); --- original/fs/reiser4/plugin/file/cryptcompress.c 2007-04-06 08:00:28.000000000 +0400 +++ current/fs/reiser4/plugin/file/cryptcompress.c 2007-04-06 10:20:25.000000000 +0400 @@ -2783,7 +2783,7 @@ if (IS_ERR(ctx)) return PTR_ERR(ctx); - mutex_lock(&inode->i_mutex); + mutex_lock(&reiser4_inode_data(inode)->mutex_write); result = generic_write_checks(file, &pos, &count, 0); if (unlikely(result != 0)) @@ -2803,7 +2803,7 @@ /* update position in a file */ *off = pos + result; out: - mutex_unlock(&inode->i_mutex); + mutex_unlock(&reiser4_inode_data(inode)->mutex_write); context_set_commit_async(ctx); reiser4_exit_context(ctx);