loop.c (ebf8889bd1fe3615991ff4494635d237280652a2) | loop.c (afddba49d18f346e5cc2938b6ed7c512db18ca68) |
---|---|
1/* 2 * linux/drivers/block/loop.c 3 * 4 * Written by Theodore Ts'o, 3/29/93 5 * 6 * Copyright 1993 by Theodore Ts'o. Redistribution of this file is 7 * permitted under the GNU General Public License. 8 * --- 190 unchanged lines hidden (view full) --- 199 200 return lo->transfer(lo, cmd, rpage, roffs, lpage, loffs, size, rblock); 201} 202 203/** 204 * do_lo_send_aops - helper for writing data to a loop device 205 * 206 * This is the fast version for backing filesystems which implement the address | 1/* 2 * linux/drivers/block/loop.c 3 * 4 * Written by Theodore Ts'o, 3/29/93 5 * 6 * Copyright 1993 by Theodore Ts'o. Redistribution of this file is 7 * permitted under the GNU General Public License. 8 * --- 190 unchanged lines hidden (view full) --- 199 200 return lo->transfer(lo, cmd, rpage, roffs, lpage, loffs, size, rblock); 201} 202 203/** 204 * do_lo_send_aops - helper for writing data to a loop device 205 * 206 * This is the fast version for backing filesystems which implement the address |
207 * space operations prepare_write and commit_write. | 207 * space operations write_begin and write_end. |
208 */ 209static int do_lo_send_aops(struct loop_device *lo, struct bio_vec *bvec, | 208 */ 209static int do_lo_send_aops(struct loop_device *lo, struct bio_vec *bvec, |
210 int bsize, loff_t pos, struct page *page) | 210 int bsize, loff_t pos, struct page *unused) |
211{ 212 struct file *file = lo->lo_backing_file; /* kudos to NFsckingS */ 213 struct address_space *mapping = file->f_mapping; | 211{ 212 struct file *file = lo->lo_backing_file; /* kudos to NFsckingS */ 213 struct address_space *mapping = file->f_mapping; |
214 const struct address_space_operations *aops = mapping->a_ops; | |
215 pgoff_t index; 216 unsigned offset, bv_offs; 217 int len, ret; 218 219 mutex_lock(&mapping->host->i_mutex); 220 index = pos >> PAGE_CACHE_SHIFT; 221 offset = pos & ((pgoff_t)PAGE_CACHE_SIZE - 1); 222 bv_offs = bvec->bv_offset; 223 len = bvec->bv_len; 224 while (len > 0) { 225 sector_t IV; | 214 pgoff_t index; 215 unsigned offset, bv_offs; 216 int len, ret; 217 218 mutex_lock(&mapping->host->i_mutex); 219 index = pos >> PAGE_CACHE_SHIFT; 220 offset = pos & ((pgoff_t)PAGE_CACHE_SIZE - 1); 221 bv_offs = bvec->bv_offset; 222 len = bvec->bv_len; 223 while (len > 0) { 224 sector_t IV; |
226 unsigned size; | 225 unsigned size, copied; |
227 int transfer_result; | 226 int transfer_result; |
227 struct page *page; 228 void *fsdata; |
|
228 229 IV = ((sector_t)index << (PAGE_CACHE_SHIFT - 9))+(offset >> 9); 230 size = PAGE_CACHE_SIZE - offset; 231 if (size > len) 232 size = len; | 229 230 IV = ((sector_t)index << (PAGE_CACHE_SHIFT - 9))+(offset >> 9); 231 size = PAGE_CACHE_SIZE - offset; 232 if (size > len) 233 size = len; |
233 page = grab_cache_page(mapping, index); 234 if (unlikely(!page)) | 234 235 ret = pagecache_write_begin(file, mapping, pos, size, 0, 236 &page, &fsdata); 237 if (ret) |
235 goto fail; | 238 goto fail; |
236 ret = aops->prepare_write(file, page, offset, 237 offset + size); 238 if (unlikely(ret)) { 239 if (ret == AOP_TRUNCATED_PAGE) { 240 page_cache_release(page); 241 continue; 242 } 243 goto unlock; 244 } | 239 |
245 transfer_result = lo_do_transfer(lo, WRITE, page, offset, 246 bvec->bv_page, bv_offs, size, IV); | 240 transfer_result = lo_do_transfer(lo, WRITE, page, offset, 241 bvec->bv_page, bv_offs, size, IV); |
247 if (unlikely(transfer_result)) { 248 /* 249 * The transfer failed, but we still write the data to 250 * keep prepare/commit calls balanced. 251 */ 252 printk(KERN_ERR "loop: transfer error block %llu\n", 253 (unsigned long long)index); 254 zero_user_page(page, offset, size, KM_USER0); 255 } 256 flush_dcache_page(page); 257 ret = aops->commit_write(file, page, offset, 258 offset + size); 259 if (unlikely(ret)) { 260 if (ret == AOP_TRUNCATED_PAGE) { 261 page_cache_release(page); 262 continue; 263 } 264 goto unlock; 265 } | 242 copied = size; |
266 if (unlikely(transfer_result)) | 243 if (unlikely(transfer_result)) |
267 goto unlock; 268 bv_offs += size; 269 len -= size; | 244 copied = 0; 245 246 ret = pagecache_write_end(file, mapping, pos, size, copied, 247 page, fsdata); 248 if (ret < 0) 249 goto fail; 250 if (ret < copied) 251 copied = ret; 252 253 if (unlikely(transfer_result)) 254 goto fail; 255 256 bv_offs += copied; 257 len -= copied; |
270 offset = 0; 271 index++; | 258 offset = 0; 259 index++; |
272 pos += size; 273 unlock_page(page); 274 page_cache_release(page); | 260 pos += copied; |
275 } 276 ret = 0; 277out: 278 mutex_unlock(&mapping->host->i_mutex); 279 return ret; | 261 } 262 ret = 0; 263out: 264 mutex_unlock(&mapping->host->i_mutex); 265 return ret; |
280unlock: 281 unlock_page(page); 282 page_cache_release(page); | |
283fail: 284 ret = -1; 285 goto out; 286} 287 288/** 289 * __do_lo_send_write - helper for writing data to a loop device 290 * --- 17 unchanged lines hidden (view full) --- 308 bw = -EIO; 309 return bw; 310} 311 312/** 313 * do_lo_send_direct_write - helper for writing data to a loop device 314 * 315 * This is the fast, non-transforming version for backing filesystems which do | 266fail: 267 ret = -1; 268 goto out; 269} 270 271/** 272 * __do_lo_send_write - helper for writing data to a loop device 273 * --- 17 unchanged lines hidden (view full) --- 291 bw = -EIO; 292 return bw; 293} 294 295/** 296 * do_lo_send_direct_write - helper for writing data to a loop device 297 * 298 * This is the fast, non-transforming version for backing filesystems which do |
316 * not implement the address space operations prepare_write and commit_write. | 299 * not implement the address space operations write_begin and write_end. |
317 * It uses the write file operation which should be present on all writeable 318 * filesystems. 319 */ 320static int do_lo_send_direct_write(struct loop_device *lo, 321 struct bio_vec *bvec, int bsize, loff_t pos, struct page *page) 322{ 323 ssize_t bw = __do_lo_send_write(lo->lo_backing_file, 324 kmap(bvec->bv_page) + bvec->bv_offset, 325 bvec->bv_len, pos); 326 kunmap(bvec->bv_page); 327 cond_resched(); 328 return bw; 329} 330 331/** 332 * do_lo_send_write - helper for writing data to a loop device 333 * 334 * This is the slow, transforming version for filesystems which do not | 300 * It uses the write file operation which should be present on all writeable 301 * filesystems. 302 */ 303static int do_lo_send_direct_write(struct loop_device *lo, 304 struct bio_vec *bvec, int bsize, loff_t pos, struct page *page) 305{ 306 ssize_t bw = __do_lo_send_write(lo->lo_backing_file, 307 kmap(bvec->bv_page) + bvec->bv_offset, 308 bvec->bv_len, pos); 309 kunmap(bvec->bv_page); 310 cond_resched(); 311 return bw; 312} 313 314/** 315 * do_lo_send_write - helper for writing data to a loop device 316 * 317 * This is the slow, transforming version for filesystems which do not |
335 * implement the address space operations prepare_write and commit_write. It | 318 * implement the address space operations write_begin and write_end. It |
336 * uses the write file operation which should be present on all writeable 337 * filesystems. 338 * 339 * Using fops->write is slower than using aops->{prepare,commit}_write in the 340 * transforming case because we need to double buffer the data as we cannot do 341 * the transformations in place as we do not have direct access to the 342 * destination pages of the backing file. 343 */ --- 431 unchanged lines hidden (view full) --- 775 if (S_ISREG(inode->i_mode) || S_ISBLK(inode->i_mode)) { 776 const struct address_space_operations *aops = mapping->a_ops; 777 /* 778 * If we can't read - sorry. If we only can't write - well, 779 * it's going to be read-only. 780 */ 781 if (!file->f_op->splice_read) 782 goto out_putf; | 319 * uses the write file operation which should be present on all writeable 320 * filesystems. 321 * 322 * Using fops->write is slower than using aops->{prepare,commit}_write in the 323 * transforming case because we need to double buffer the data as we cannot do 324 * the transformations in place as we do not have direct access to the 325 * destination pages of the backing file. 326 */ --- 431 unchanged lines hidden (view full) --- 758 if (S_ISREG(inode->i_mode) || S_ISBLK(inode->i_mode)) { 759 const struct address_space_operations *aops = mapping->a_ops; 760 /* 761 * If we can't read - sorry. If we only can't write - well, 762 * it's going to be read-only. 763 */ 764 if (!file->f_op->splice_read) 765 goto out_putf; |
783 if (aops->prepare_write && aops->commit_write) | 766 if (aops->prepare_write || aops->write_begin) |
784 lo_flags |= LO_FLAGS_USE_AOPS; 785 if (!(lo_flags & LO_FLAGS_USE_AOPS) && !file->f_op->write) 786 lo_flags |= LO_FLAGS_READ_ONLY; 787 788 lo_blocksize = S_ISBLK(inode->i_mode) ? 789 inode->i_bdev->bd_block_size : PAGE_SIZE; 790 791 error = 0; --- 794 unchanged lines hidden --- | 767 lo_flags |= LO_FLAGS_USE_AOPS; 768 if (!(lo_flags & LO_FLAGS_USE_AOPS) && !file->f_op->write) 769 lo_flags |= LO_FLAGS_READ_ONLY; 770 771 lo_blocksize = S_ISBLK(inode->i_mode) ? 772 inode->i_bdev->bd_block_size : PAGE_SIZE; 773 774 error = 0; --- 794 unchanged lines hidden --- |