diff options
Diffstat (limited to 'fs/udf/file.c')
-rw-r--r-- | fs/udf/file.c | 19 |
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, | |||
99 | const struct address_space_operations udf_adinicb_aops = { | 98 | const 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 | ||
198 | out: | 197 | out: |
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 | ||
251 | const struct inode_operations udf_file_inode_operations = { | 249 | const struct inode_operations udf_file_inode_operations = { |
252 | .setattr = udf_setattr, | 250 | .setattr = udf_setattr, |
253 | .truncate = udf_truncate, | ||
254 | }; | 251 | }; |