diff options
| -rw-r--r-- | arch/um/os-Linux/time.c | 2 | ||||
| -rw-r--r-- | fs/udf/file.c | 9 | ||||
| -rw-r--r-- | fs/udf/inode.c | 52 |
3 files changed, 46 insertions, 17 deletions
diff --git a/arch/um/os-Linux/time.c b/arch/um/os-Linux/time.c index f60238559af3..0748fe0c8a73 100644 --- a/arch/um/os-Linux/time.c +++ b/arch/um/os-Linux/time.c | |||
| @@ -114,7 +114,7 @@ static void deliver_alarm(void) | |||
| 114 | skew += this_tick - last_tick; | 114 | skew += this_tick - last_tick; |
| 115 | 115 | ||
| 116 | while (skew >= one_tick) { | 116 | while (skew >= one_tick) { |
| 117 | alarm_handler(SIGVTALRM, NULL); | 117 | alarm_handler(SIGVTALRM, NULL, NULL); |
| 118 | skew -= one_tick; | 118 | skew -= one_tick; |
| 119 | } | 119 | } |
| 120 | 120 | ||
diff --git a/fs/udf/file.c b/fs/udf/file.c index d1c6093fd3d3..77b5953eaac8 100644 --- a/fs/udf/file.c +++ b/fs/udf/file.c | |||
| @@ -118,11 +118,20 @@ static int udf_adinicb_write_end(struct file *file, | |||
| 118 | return simple_write_end(file, mapping, pos, len, copied, page, fsdata); | 118 | return simple_write_end(file, mapping, pos, len, copied, page, fsdata); |
| 119 | } | 119 | } |
| 120 | 120 | ||
| 121 | static ssize_t udf_adinicb_direct_IO(int rw, struct kiocb *iocb, | ||
| 122 | const struct iovec *iov, | ||
| 123 | loff_t offset, unsigned long nr_segs) | ||
| 124 | { | ||
| 125 | /* Fallback to buffered I/O. */ | ||
| 126 | return 0; | ||
| 127 | } | ||
| 128 | |||
| 121 | const struct address_space_operations udf_adinicb_aops = { | 129 | const struct address_space_operations udf_adinicb_aops = { |
| 122 | .readpage = udf_adinicb_readpage, | 130 | .readpage = udf_adinicb_readpage, |
| 123 | .writepage = udf_adinicb_writepage, | 131 | .writepage = udf_adinicb_writepage, |
| 124 | .write_begin = udf_adinicb_write_begin, | 132 | .write_begin = udf_adinicb_write_begin, |
| 125 | .write_end = udf_adinicb_write_end, | 133 | .write_end = udf_adinicb_write_end, |
| 134 | .direct_IO = udf_adinicb_direct_IO, | ||
| 126 | }; | 135 | }; |
| 127 | 136 | ||
| 128 | static ssize_t udf_file_aio_write(struct kiocb *iocb, const struct iovec *iov, | 137 | static ssize_t udf_file_aio_write(struct kiocb *iocb, const struct iovec *iov, |
diff --git a/fs/udf/inode.c b/fs/udf/inode.c index 1a0588e77a2f..41d58309d6a8 100644 --- a/fs/udf/inode.c +++ b/fs/udf/inode.c | |||
| @@ -95,6 +95,22 @@ void udf_evict_inode(struct inode *inode) | |||
| 95 | } | 95 | } |
| 96 | } | 96 | } |
| 97 | 97 | ||
| 98 | static void udf_write_failed(struct address_space *mapping, loff_t to) | ||
| 99 | { | ||
| 100 | struct inode *inode = mapping->host; | ||
| 101 | struct udf_inode_info *iinfo = UDF_I(inode); | ||
| 102 | loff_t isize = inode->i_size; | ||
| 103 | |||
| 104 | if (to > isize) { | ||
| 105 | truncate_pagecache(inode, to, isize); | ||
| 106 | if (iinfo->i_alloc_type != ICBTAG_FLAG_AD_IN_ICB) { | ||
| 107 | down_write(&iinfo->i_data_sem); | ||
| 108 | udf_truncate_extents(inode); | ||
| 109 | up_write(&iinfo->i_data_sem); | ||
| 110 | } | ||
| 111 | } | ||
| 112 | } | ||
| 113 | |||
| 98 | static int udf_writepage(struct page *page, struct writeback_control *wbc) | 114 | static int udf_writepage(struct page *page, struct writeback_control *wbc) |
| 99 | { | 115 | { |
| 100 | return block_write_full_page(page, udf_get_block, wbc); | 116 | return block_write_full_page(page, udf_get_block, wbc); |
| @@ -124,21 +140,24 @@ static int udf_write_begin(struct file *file, struct address_space *mapping, | |||
| 124 | int ret; | 140 | int ret; |
| 125 | 141 | ||
| 126 | ret = block_write_begin(mapping, pos, len, flags, pagep, udf_get_block); | 142 | ret = block_write_begin(mapping, pos, len, flags, pagep, udf_get_block); |
| 127 | if (unlikely(ret)) { | 143 | if (unlikely(ret)) |
| 128 | struct inode *inode = mapping->host; | 144 | udf_write_failed(mapping, pos + len); |
| 129 | struct udf_inode_info *iinfo = UDF_I(inode); | 145 | return ret; |
| 130 | loff_t isize = inode->i_size; | 146 | } |
| 131 | |||
| 132 | if (pos + len > isize) { | ||
| 133 | truncate_pagecache(inode, pos + len, isize); | ||
| 134 | if (iinfo->i_alloc_type != ICBTAG_FLAG_AD_IN_ICB) { | ||
| 135 | down_write(&iinfo->i_data_sem); | ||
| 136 | udf_truncate_extents(inode); | ||
| 137 | up_write(&iinfo->i_data_sem); | ||
| 138 | } | ||
| 139 | } | ||
| 140 | } | ||
| 141 | 147 | ||
| 148 | static ssize_t udf_direct_IO(int rw, struct kiocb *iocb, | ||
| 149 | const struct iovec *iov, | ||
| 150 | loff_t offset, unsigned long nr_segs) | ||
| 151 | { | ||
| 152 | struct file *file = iocb->ki_filp; | ||
| 153 | struct address_space *mapping = file->f_mapping; | ||
| 154 | struct inode *inode = mapping->host; | ||
| 155 | ssize_t ret; | ||
| 156 | |||
| 157 | ret = blockdev_direct_IO(rw, iocb, inode, iov, offset, nr_segs, | ||
| 158 | udf_get_block); | ||
| 159 | if (unlikely(ret < 0 && (rw & WRITE))) | ||
| 160 | udf_write_failed(mapping, offset + iov_length(iov, nr_segs)); | ||
| 142 | return ret; | 161 | return ret; |
| 143 | } | 162 | } |
| 144 | 163 | ||
| @@ -152,8 +171,9 @@ const struct address_space_operations udf_aops = { | |||
| 152 | .readpages = udf_readpages, | 171 | .readpages = udf_readpages, |
| 153 | .writepage = udf_writepage, | 172 | .writepage = udf_writepage, |
| 154 | .writepages = udf_writepages, | 173 | .writepages = udf_writepages, |
| 155 | .write_begin = udf_write_begin, | 174 | .write_begin = udf_write_begin, |
| 156 | .write_end = generic_write_end, | 175 | .write_end = generic_write_end, |
| 176 | .direct_IO = udf_direct_IO, | ||
| 157 | .bmap = udf_bmap, | 177 | .bmap = udf_bmap, |
| 158 | }; | 178 | }; |
| 159 | 179 | ||
