aboutsummaryrefslogtreecommitdiffstats
path: root/fs/udf/file.c
diff options
context:
space:
mode:
Diffstat (limited to 'fs/udf/file.c')
-rw-r--r--fs/udf/file.c19
1 files changed, 8 insertions, 11 deletions
diff --git a/fs/udf/file.c b/fs/udf/file.c
index 66b9e7e7e4c5..2a346bb1d9f5 100644
--- a/fs/udf/file.c
+++ b/fs/udf/file.c
@@ -32,7 +32,6 @@
32#include <linux/string.h> /* memset */ 32#include <linux/string.h> /* memset */
33#include <linux/capability.h> 33#include <linux/capability.h>
34#include <linux/errno.h> 34#include <linux/errno.h>
35#include <linux/smp_lock.h>
36#include <linux/pagemap.h> 35#include <linux/pagemap.h>
37#include <linux/buffer_head.h> 36#include <linux/buffer_head.h>
38#include <linux/aio.h> 37#include <linux/aio.h>
@@ -99,7 +98,6 @@ static int udf_adinicb_write_end(struct file *file,
99const struct address_space_operations udf_adinicb_aops = { 98const struct address_space_operations udf_adinicb_aops = {
100 .readpage = udf_adinicb_readpage, 99 .readpage = udf_adinicb_readpage,
101 .writepage = udf_adinicb_writepage, 100 .writepage = udf_adinicb_writepage,
102 .sync_page = block_sync_page,
103 .write_begin = simple_write_begin, 101 .write_begin = simple_write_begin,
104 .write_end = udf_adinicb_write_end, 102 .write_end = udf_adinicb_write_end,
105}; 103};
@@ -114,6 +112,7 @@ static ssize_t udf_file_aio_write(struct kiocb *iocb, const struct iovec *iov,
114 size_t count = iocb->ki_left; 112 size_t count = iocb->ki_left;
115 struct udf_inode_info *iinfo = UDF_I(inode); 113 struct udf_inode_info *iinfo = UDF_I(inode);
116 114
115 down_write(&iinfo->i_data_sem);
117 if (iinfo->i_alloc_type == ICBTAG_FLAG_AD_IN_ICB) { 116 if (iinfo->i_alloc_type == ICBTAG_FLAG_AD_IN_ICB) {
118 if (file->f_flags & O_APPEND) 117 if (file->f_flags & O_APPEND)
119 pos = inode->i_size; 118 pos = inode->i_size;
@@ -123,9 +122,10 @@ static ssize_t udf_file_aio_write(struct kiocb *iocb, const struct iovec *iov,
123 if (inode->i_sb->s_blocksize < 122 if (inode->i_sb->s_blocksize <
124 (udf_file_entry_alloc_offset(inode) + 123 (udf_file_entry_alloc_offset(inode) +
125 pos + count)) { 124 pos + count)) {
126 udf_expand_file_adinicb(inode, pos + count, &err); 125 err = udf_expand_file_adinicb(inode);
127 if (iinfo->i_alloc_type == ICBTAG_FLAG_AD_IN_ICB) { 126 if (err) {
128 udf_debug("udf_expand_adinicb: err=%d\n", err); 127 udf_debug("udf_expand_adinicb: err=%d\n", err);
128 up_write(&iinfo->i_data_sem);
129 return err; 129 return err;
130 } 130 }
131 } else { 131 } else {
@@ -135,6 +135,7 @@ static ssize_t udf_file_aio_write(struct kiocb *iocb, const struct iovec *iov,
135 iinfo->i_lenAlloc = inode->i_size; 135 iinfo->i_lenAlloc = inode->i_size;
136 } 136 }
137 } 137 }
138 up_write(&iinfo->i_data_sem);
138 139
139 retval = generic_file_aio_write(iocb, iov, nr_segs, ppos); 140 retval = generic_file_aio_write(iocb, iov, nr_segs, ppos);
140 if (retval > 0) 141 if (retval > 0)
@@ -149,8 +150,6 @@ long udf_ioctl(struct file *filp, unsigned int cmd, unsigned long arg)
149 long old_block, new_block; 150 long old_block, new_block;
150 int result = -EINVAL; 151 int result = -EINVAL;
151 152
152 lock_kernel();
153
154 if (file_permission(filp, MAY_READ) != 0) { 153 if (file_permission(filp, MAY_READ) != 0) {
155 udf_debug("no permission to access inode %lu\n", inode->i_ino); 154 udf_debug("no permission to access inode %lu\n", inode->i_ino);
156 result = -EPERM; 155 result = -EPERM;
@@ -196,7 +195,6 @@ long udf_ioctl(struct file *filp, unsigned int cmd, unsigned long arg)
196 } 195 }
197 196
198out: 197out:
199 unlock_kernel();
200 return result; 198 return result;
201} 199}
202 200
@@ -204,10 +202,10 @@ static int udf_release_file(struct inode *inode, struct file *filp)
204{ 202{
205 if (filp->f_mode & FMODE_WRITE) { 203 if (filp->f_mode & FMODE_WRITE) {
206 mutex_lock(&inode->i_mutex); 204 mutex_lock(&inode->i_mutex);
207 lock_kernel(); 205 down_write(&UDF_I(inode)->i_data_sem);
208 udf_discard_prealloc(inode); 206 udf_discard_prealloc(inode);
209 udf_truncate_tail_extent(inode); 207 udf_truncate_tail_extent(inode);
210 unlock_kernel(); 208 up_write(&UDF_I(inode)->i_data_sem);
211 mutex_unlock(&inode->i_mutex); 209 mutex_unlock(&inode->i_mutex);
212 } 210 }
213 return 0; 211 return 0;
@@ -238,7 +236,7 @@ static int udf_setattr(struct dentry *dentry, struct iattr *attr)
238 236
239 if ((attr->ia_valid & ATTR_SIZE) && 237 if ((attr->ia_valid & ATTR_SIZE) &&
240 attr->ia_size != i_size_read(inode)) { 238 attr->ia_size != i_size_read(inode)) {
241 error = vmtruncate(inode, attr->ia_size); 239 error = udf_setsize(inode, attr->ia_size);
242 if (error) 240 if (error)
243 return error; 241 return error;
244 } 242 }
@@ -250,5 +248,4 @@ static int udf_setattr(struct dentry *dentry, struct iattr *attr)
250 248
251const struct inode_operations udf_file_inode_operations = { 249const struct inode_operations udf_file_inode_operations = {
252 .setattr = udf_setattr, 250 .setattr = udf_setattr,
253 .truncate = udf_truncate,
254}; 251};