diff options
| author | Jan Kara <jack@suse.cz> | 2010-11-16 08:33:48 -0500 |
|---|---|---|
| committer | Jan Kara <jack@suse.cz> | 2011-01-06 11:03:57 -0500 |
| commit | 8754a3f718f08dc21b3c5eccd044f612d4bc1ab1 (patch) | |
| tree | 40d2b8af8e64f9041f19e8d93df0ab81e6b8054e | |
| parent | 9db9f9e31d7661dff35a75ed01ff9fc0d6acdaf8 (diff) | |
udf: Protect udf_file_aio_write from possible races
Code doing conversion from INICB file to a normal file in udf_file_aio_write()
is not protected by any lock from other code modifying the inode. Use
i_alloc_sem for that.
Reported-by: Alessio Igor Bogani <abogani@texware.it>
Signed-off-by: Jan Kara <jack@suse.cz>
| -rw-r--r-- | fs/udf/file.c | 3 |
1 files changed, 3 insertions, 0 deletions
diff --git a/fs/udf/file.c b/fs/udf/file.c index 4e3bbd81b57b..89c78486cbbe 100644 --- a/fs/udf/file.c +++ b/fs/udf/file.c | |||
| @@ -113,6 +113,7 @@ static ssize_t udf_file_aio_write(struct kiocb *iocb, const struct iovec *iov, | |||
| 113 | size_t count = iocb->ki_left; | 113 | size_t count = iocb->ki_left; |
| 114 | struct udf_inode_info *iinfo = UDF_I(inode); | 114 | struct udf_inode_info *iinfo = UDF_I(inode); |
| 115 | 115 | ||
| 116 | down_write(&iinfo->i_data_sem); | ||
| 116 | if (iinfo->i_alloc_type == ICBTAG_FLAG_AD_IN_ICB) { | 117 | if (iinfo->i_alloc_type == ICBTAG_FLAG_AD_IN_ICB) { |
| 117 | if (file->f_flags & O_APPEND) | 118 | if (file->f_flags & O_APPEND) |
| 118 | pos = inode->i_size; | 119 | pos = inode->i_size; |
| @@ -125,6 +126,7 @@ static ssize_t udf_file_aio_write(struct kiocb *iocb, const struct iovec *iov, | |||
| 125 | udf_expand_file_adinicb(inode, pos + count, &err); | 126 | udf_expand_file_adinicb(inode, pos + count, &err); |
| 126 | if (iinfo->i_alloc_type == ICBTAG_FLAG_AD_IN_ICB) { | 127 | if (iinfo->i_alloc_type == ICBTAG_FLAG_AD_IN_ICB) { |
| 127 | udf_debug("udf_expand_adinicb: err=%d\n", err); | 128 | udf_debug("udf_expand_adinicb: err=%d\n", err); |
| 129 | up_write(&iinfo->i_data_sem); | ||
| 128 | return err; | 130 | return err; |
| 129 | } | 131 | } |
| 130 | } else { | 132 | } else { |
| @@ -134,6 +136,7 @@ static ssize_t udf_file_aio_write(struct kiocb *iocb, const struct iovec *iov, | |||
| 134 | iinfo->i_lenAlloc = inode->i_size; | 136 | iinfo->i_lenAlloc = inode->i_size; |
| 135 | } | 137 | } |
| 136 | } | 138 | } |
| 139 | up_write(&iinfo->i_data_sem); | ||
| 137 | 140 | ||
| 138 | retval = generic_file_aio_write(iocb, iov, nr_segs, ppos); | 141 | retval = generic_file_aio_write(iocb, iov, nr_segs, ppos); |
| 139 | if (retval > 0) | 142 | if (retval > 0) |
