| .. | .. |
|---|
| 1 | +// SPDX-License-Identifier: GPL-2.0-only |
|---|
| 1 | 2 | /* |
|---|
| 2 | 3 | * Copyright (C) Sistina Software, Inc. 1997-2003 All rights reserved. |
|---|
| 3 | 4 | * Copyright (C) 2004-2006 Red Hat, Inc. All rights reserved. |
|---|
| 4 | | - * |
|---|
| 5 | | - * This copyrighted material is made available to anyone wishing to use, |
|---|
| 6 | | - * modify, copy, or redistribute it subject to the terms and conditions |
|---|
| 7 | | - * of the GNU General Public License version 2. |
|---|
| 8 | 5 | */ |
|---|
| 9 | 6 | |
|---|
| 10 | 7 | #include <linux/slab.h> |
|---|
| 11 | 8 | #include <linux/spinlock.h> |
|---|
| 9 | +#include <linux/compat.h> |
|---|
| 12 | 10 | #include <linux/completion.h> |
|---|
| 13 | 11 | #include <linux/buffer_head.h> |
|---|
| 14 | 12 | #include <linux/pagemap.h> |
|---|
| .. | .. |
|---|
| 139 | 137 | {FS_JOURNAL_DATA_FL, GFS2_DIF_JDATA | GFS2_DIF_INHERIT_JDATA}, |
|---|
| 140 | 138 | }; |
|---|
| 141 | 139 | |
|---|
| 140 | +static inline u32 gfs2_gfsflags_to_fsflags(struct inode *inode, u32 gfsflags) |
|---|
| 141 | +{ |
|---|
| 142 | + int i; |
|---|
| 143 | + u32 fsflags = 0; |
|---|
| 144 | + |
|---|
| 145 | + if (S_ISDIR(inode->i_mode)) |
|---|
| 146 | + gfsflags &= ~GFS2_DIF_JDATA; |
|---|
| 147 | + else |
|---|
| 148 | + gfsflags &= ~GFS2_DIF_INHERIT_JDATA; |
|---|
| 149 | + |
|---|
| 150 | + for (i = 0; i < ARRAY_SIZE(fsflag_gfs2flag); i++) |
|---|
| 151 | + if (gfsflags & fsflag_gfs2flag[i].gfsflag) |
|---|
| 152 | + fsflags |= fsflag_gfs2flag[i].fsflag; |
|---|
| 153 | + return fsflags; |
|---|
| 154 | +} |
|---|
| 155 | + |
|---|
| 142 | 156 | static int gfs2_get_flags(struct file *filp, u32 __user *ptr) |
|---|
| 143 | 157 | { |
|---|
| 144 | 158 | struct inode *inode = file_inode(filp); |
|---|
| 145 | 159 | struct gfs2_inode *ip = GFS2_I(inode); |
|---|
| 146 | 160 | struct gfs2_holder gh; |
|---|
| 147 | | - int i, error; |
|---|
| 148 | | - u32 gfsflags, fsflags = 0; |
|---|
| 161 | + int error; |
|---|
| 162 | + u32 fsflags; |
|---|
| 149 | 163 | |
|---|
| 150 | 164 | gfs2_holder_init(ip->i_gl, LM_ST_SHARED, 0, &gh); |
|---|
| 151 | 165 | error = gfs2_glock_nq(&gh); |
|---|
| 152 | 166 | if (error) |
|---|
| 153 | 167 | goto out_uninit; |
|---|
| 154 | 168 | |
|---|
| 155 | | - gfsflags = ip->i_diskflags; |
|---|
| 156 | | - if (S_ISDIR(inode->i_mode)) |
|---|
| 157 | | - gfsflags &= ~GFS2_DIF_JDATA; |
|---|
| 158 | | - else |
|---|
| 159 | | - gfsflags &= ~GFS2_DIF_INHERIT_JDATA; |
|---|
| 160 | | - for (i = 0; i < ARRAY_SIZE(fsflag_gfs2flag); i++) |
|---|
| 161 | | - if (gfsflags & fsflag_gfs2flag[i].gfsflag) |
|---|
| 162 | | - fsflags |= fsflag_gfs2flag[i].fsflag; |
|---|
| 169 | + fsflags = gfs2_gfsflags_to_fsflags(inode, ip->i_diskflags); |
|---|
| 163 | 170 | |
|---|
| 164 | 171 | if (put_user(fsflags, ptr)) |
|---|
| 165 | 172 | error = -EFAULT; |
|---|
| .. | .. |
|---|
| 203 | 210 | * @filp: file pointer |
|---|
| 204 | 211 | * @reqflags: The flags to set |
|---|
| 205 | 212 | * @mask: Indicates which flags are valid |
|---|
| 213 | + * @fsflags: The FS_* inode flags passed in |
|---|
| 206 | 214 | * |
|---|
| 207 | 215 | */ |
|---|
| 208 | | -static int do_gfs2_set_flags(struct file *filp, u32 reqflags, u32 mask) |
|---|
| 216 | +static int do_gfs2_set_flags(struct file *filp, u32 reqflags, u32 mask, |
|---|
| 217 | + const u32 fsflags) |
|---|
| 209 | 218 | { |
|---|
| 210 | 219 | struct inode *inode = file_inode(filp); |
|---|
| 211 | 220 | struct gfs2_inode *ip = GFS2_I(inode); |
|---|
| .. | .. |
|---|
| 213 | 222 | struct buffer_head *bh; |
|---|
| 214 | 223 | struct gfs2_holder gh; |
|---|
| 215 | 224 | int error; |
|---|
| 216 | | - u32 new_flags, flags; |
|---|
| 225 | + u32 new_flags, flags, oldflags; |
|---|
| 217 | 226 | |
|---|
| 218 | 227 | error = mnt_want_write_file(filp); |
|---|
| 219 | 228 | if (error) |
|---|
| .. | .. |
|---|
| 222 | 231 | error = gfs2_glock_nq_init(ip->i_gl, LM_ST_EXCLUSIVE, 0, &gh); |
|---|
| 223 | 232 | if (error) |
|---|
| 224 | 233 | goto out_drop_write; |
|---|
| 234 | + |
|---|
| 235 | + oldflags = gfs2_gfsflags_to_fsflags(inode, ip->i_diskflags); |
|---|
| 236 | + error = vfs_ioc_setflags_prepare(inode, oldflags, fsflags); |
|---|
| 237 | + if (error) |
|---|
| 238 | + goto out; |
|---|
| 225 | 239 | |
|---|
| 226 | 240 | error = -EACCES; |
|---|
| 227 | 241 | if (!inode_owner_or_capable(inode)) |
|---|
| .. | .. |
|---|
| 311 | 325 | mask &= ~(GFS2_DIF_TOPDIR | GFS2_DIF_INHERIT_JDATA); |
|---|
| 312 | 326 | } |
|---|
| 313 | 327 | |
|---|
| 314 | | - return do_gfs2_set_flags(filp, gfsflags, mask); |
|---|
| 328 | + return do_gfs2_set_flags(filp, gfsflags, mask, fsflags); |
|---|
| 329 | +} |
|---|
| 330 | + |
|---|
| 331 | +static int gfs2_getlabel(struct file *filp, char __user *label) |
|---|
| 332 | +{ |
|---|
| 333 | + struct inode *inode = file_inode(filp); |
|---|
| 334 | + struct gfs2_sbd *sdp = GFS2_SB(inode); |
|---|
| 335 | + |
|---|
| 336 | + if (copy_to_user(label, sdp->sd_sb.sb_locktable, GFS2_LOCKNAME_LEN)) |
|---|
| 337 | + return -EFAULT; |
|---|
| 338 | + |
|---|
| 339 | + return 0; |
|---|
| 315 | 340 | } |
|---|
| 316 | 341 | |
|---|
| 317 | 342 | static long gfs2_ioctl(struct file *filp, unsigned int cmd, unsigned long arg) |
|---|
| .. | .. |
|---|
| 323 | 348 | return gfs2_set_flags(filp, (u32 __user *)arg); |
|---|
| 324 | 349 | case FITRIM: |
|---|
| 325 | 350 | return gfs2_fitrim(filp, (void __user *)arg); |
|---|
| 351 | + case FS_IOC_GETFSLABEL: |
|---|
| 352 | + return gfs2_getlabel(filp, (char __user *)arg); |
|---|
| 326 | 353 | } |
|---|
| 354 | + |
|---|
| 327 | 355 | return -ENOTTY; |
|---|
| 328 | 356 | } |
|---|
| 357 | + |
|---|
| 358 | +#ifdef CONFIG_COMPAT |
|---|
| 359 | +static long gfs2_compat_ioctl(struct file *filp, unsigned int cmd, unsigned long arg) |
|---|
| 360 | +{ |
|---|
| 361 | + switch(cmd) { |
|---|
| 362 | + /* These are just misnamed, they actually get/put from/to user an int */ |
|---|
| 363 | + case FS_IOC32_GETFLAGS: |
|---|
| 364 | + cmd = FS_IOC_GETFLAGS; |
|---|
| 365 | + break; |
|---|
| 366 | + case FS_IOC32_SETFLAGS: |
|---|
| 367 | + cmd = FS_IOC_SETFLAGS; |
|---|
| 368 | + break; |
|---|
| 369 | + /* Keep this list in sync with gfs2_ioctl */ |
|---|
| 370 | + case FITRIM: |
|---|
| 371 | + case FS_IOC_GETFSLABEL: |
|---|
| 372 | + break; |
|---|
| 373 | + default: |
|---|
| 374 | + return -ENOIOCTLCMD; |
|---|
| 375 | + } |
|---|
| 376 | + |
|---|
| 377 | + return gfs2_ioctl(filp, cmd, (unsigned long)compat_ptr(arg)); |
|---|
| 378 | +} |
|---|
| 379 | +#else |
|---|
| 380 | +#define gfs2_compat_ioctl NULL |
|---|
| 381 | +#endif |
|---|
| 329 | 382 | |
|---|
| 330 | 383 | /** |
|---|
| 331 | 384 | * gfs2_size_hint - Give a hint to the size of a write request |
|---|
| .. | .. |
|---|
| 347 | 400 | size_t blks = (size + sdp->sd_sb.sb_bsize - 1) >> sdp->sd_sb.sb_bsize_shift; |
|---|
| 348 | 401 | int hint = min_t(size_t, INT_MAX, blks); |
|---|
| 349 | 402 | |
|---|
| 350 | | - if (hint > atomic_read(&ip->i_res.rs_sizehint)) |
|---|
| 351 | | - atomic_set(&ip->i_res.rs_sizehint, hint); |
|---|
| 403 | + if (hint > atomic_read(&ip->i_sizehint)) |
|---|
| 404 | + atomic_set(&ip->i_sizehint, hint); |
|---|
| 352 | 405 | } |
|---|
| 353 | 406 | |
|---|
| 354 | 407 | /** |
|---|
| 355 | | - * gfs2_allocate_page_backing - Use bmap to allocate blocks |
|---|
| 408 | + * gfs2_allocate_page_backing - Allocate blocks for a write fault |
|---|
| 356 | 409 | * @page: The (locked) page to allocate backing for |
|---|
| 410 | + * @length: Size of the allocation |
|---|
| 357 | 411 | * |
|---|
| 358 | | - * We try to allocate all the blocks required for the page in |
|---|
| 359 | | - * one go. This might fail for various reasons, so we keep |
|---|
| 360 | | - * trying until all the blocks to back this page are allocated. |
|---|
| 361 | | - * If some of the blocks are already allocated, thats ok too. |
|---|
| 412 | + * We try to allocate all the blocks required for the page in one go. This |
|---|
| 413 | + * might fail for various reasons, so we keep trying until all the blocks to |
|---|
| 414 | + * back this page are allocated. If some of the blocks are already allocated, |
|---|
| 415 | + * that is ok too. |
|---|
| 362 | 416 | */ |
|---|
| 363 | | - |
|---|
| 364 | | -static int gfs2_allocate_page_backing(struct page *page) |
|---|
| 417 | +static int gfs2_allocate_page_backing(struct page *page, unsigned int length) |
|---|
| 365 | 418 | { |
|---|
| 366 | | - struct inode *inode = page->mapping->host; |
|---|
| 367 | | - struct buffer_head bh; |
|---|
| 368 | | - unsigned long size = PAGE_SIZE; |
|---|
| 369 | | - u64 lblock = page->index << (PAGE_SHIFT - inode->i_blkbits); |
|---|
| 419 | + u64 pos = page_offset(page); |
|---|
| 370 | 420 | |
|---|
| 371 | 421 | do { |
|---|
| 372 | | - bh.b_state = 0; |
|---|
| 373 | | - bh.b_size = size; |
|---|
| 374 | | - gfs2_block_map(inode, lblock, &bh, 1); |
|---|
| 375 | | - if (!buffer_mapped(&bh)) |
|---|
| 422 | + struct iomap iomap = { }; |
|---|
| 423 | + |
|---|
| 424 | + if (gfs2_iomap_get_alloc(page->mapping->host, pos, length, &iomap)) |
|---|
| 376 | 425 | return -EIO; |
|---|
| 377 | | - size -= bh.b_size; |
|---|
| 378 | | - lblock += (bh.b_size >> inode->i_blkbits); |
|---|
| 379 | | - } while(size > 0); |
|---|
| 426 | + |
|---|
| 427 | + if (length < iomap.length) |
|---|
| 428 | + iomap.length = length; |
|---|
| 429 | + length -= iomap.length; |
|---|
| 430 | + pos += iomap.length; |
|---|
| 431 | + } while (length > 0); |
|---|
| 432 | + |
|---|
| 380 | 433 | return 0; |
|---|
| 381 | 434 | } |
|---|
| 382 | 435 | |
|---|
| .. | .. |
|---|
| 396 | 449 | struct gfs2_inode *ip = GFS2_I(inode); |
|---|
| 397 | 450 | struct gfs2_sbd *sdp = GFS2_SB(inode); |
|---|
| 398 | 451 | struct gfs2_alloc_parms ap = { .aflags = 0, }; |
|---|
| 399 | | - unsigned long last_index; |
|---|
| 400 | | - u64 pos = page->index << PAGE_SHIFT; |
|---|
| 452 | + u64 offset = page_offset(page); |
|---|
| 401 | 453 | unsigned int data_blocks, ind_blocks, rblocks; |
|---|
| 402 | 454 | struct gfs2_holder gh; |
|---|
| 455 | + unsigned int length; |
|---|
| 403 | 456 | loff_t size; |
|---|
| 404 | 457 | int ret; |
|---|
| 405 | 458 | |
|---|
| 406 | 459 | sb_start_pagefault(inode->i_sb); |
|---|
| 407 | | - |
|---|
| 408 | | - ret = gfs2_rsqa_alloc(ip); |
|---|
| 409 | | - if (ret) |
|---|
| 410 | | - goto out; |
|---|
| 411 | | - |
|---|
| 412 | | - gfs2_size_hint(vmf->vma->vm_file, pos, PAGE_SIZE); |
|---|
| 413 | 460 | |
|---|
| 414 | 461 | gfs2_holder_init(ip->i_gl, LM_ST_EXCLUSIVE, 0, &gh); |
|---|
| 415 | 462 | ret = gfs2_glock_nq(&gh); |
|---|
| 416 | 463 | if (ret) |
|---|
| 417 | 464 | goto out_uninit; |
|---|
| 418 | 465 | |
|---|
| 466 | + /* Check page index against inode size */ |
|---|
| 467 | + size = i_size_read(inode); |
|---|
| 468 | + if (offset >= size) { |
|---|
| 469 | + ret = -EINVAL; |
|---|
| 470 | + goto out_unlock; |
|---|
| 471 | + } |
|---|
| 472 | + |
|---|
| 419 | 473 | /* Update file times before taking page lock */ |
|---|
| 420 | 474 | file_update_time(vmf->vma->vm_file); |
|---|
| 475 | + |
|---|
| 476 | + /* page is wholly or partially inside EOF */ |
|---|
| 477 | + if (size - offset < PAGE_SIZE) |
|---|
| 478 | + length = size - offset; |
|---|
| 479 | + else |
|---|
| 480 | + length = PAGE_SIZE; |
|---|
| 481 | + |
|---|
| 482 | + gfs2_size_hint(vmf->vma->vm_file, offset, length); |
|---|
| 421 | 483 | |
|---|
| 422 | 484 | set_bit(GLF_DIRTY, &ip->i_gl->gl_flags); |
|---|
| 423 | 485 | set_bit(GIF_SW_PAGED, &ip->i_flags); |
|---|
| 424 | 486 | |
|---|
| 425 | | - if (!gfs2_write_alloc_required(ip, pos, PAGE_SIZE)) { |
|---|
| 487 | + /* |
|---|
| 488 | + * iomap_writepage / iomap_writepages currently don't support inline |
|---|
| 489 | + * files, so always unstuff here. |
|---|
| 490 | + */ |
|---|
| 491 | + |
|---|
| 492 | + if (!gfs2_is_stuffed(ip) && |
|---|
| 493 | + !gfs2_write_alloc_required(ip, offset, length)) { |
|---|
| 426 | 494 | lock_page(page); |
|---|
| 427 | 495 | if (!PageUptodate(page) || page->mapping != inode->i_mapping) { |
|---|
| 428 | 496 | ret = -EAGAIN; |
|---|
| .. | .. |
|---|
| 435 | 503 | if (ret) |
|---|
| 436 | 504 | goto out_unlock; |
|---|
| 437 | 505 | |
|---|
| 438 | | - gfs2_write_calc_reserv(ip, PAGE_SIZE, &data_blocks, &ind_blocks); |
|---|
| 506 | + gfs2_write_calc_reserv(ip, length, &data_blocks, &ind_blocks); |
|---|
| 439 | 507 | ap.target = data_blocks + ind_blocks; |
|---|
| 440 | 508 | ret = gfs2_quota_lock_check(ip, &ap); |
|---|
| 441 | 509 | if (ret) |
|---|
| .. | .. |
|---|
| 456 | 524 | goto out_trans_fail; |
|---|
| 457 | 525 | |
|---|
| 458 | 526 | lock_page(page); |
|---|
| 459 | | - ret = -EINVAL; |
|---|
| 460 | | - size = i_size_read(inode); |
|---|
| 461 | | - last_index = (size - 1) >> PAGE_SHIFT; |
|---|
| 462 | | - /* Check page index against inode size */ |
|---|
| 463 | | - if (size == 0 || (page->index > last_index)) |
|---|
| 464 | | - goto out_trans_end; |
|---|
| 465 | | - |
|---|
| 466 | 527 | ret = -EAGAIN; |
|---|
| 467 | 528 | /* If truncated, we must retry the operation, we may have raced |
|---|
| 468 | 529 | * with the glock demotion code. |
|---|
| .. | .. |
|---|
| 475 | 536 | if (gfs2_is_stuffed(ip)) |
|---|
| 476 | 537 | ret = gfs2_unstuff_dinode(ip, page); |
|---|
| 477 | 538 | if (ret == 0) |
|---|
| 478 | | - ret = gfs2_allocate_page_backing(page); |
|---|
| 539 | + ret = gfs2_allocate_page_backing(page, length); |
|---|
| 479 | 540 | |
|---|
| 480 | 541 | out_trans_end: |
|---|
| 481 | 542 | if (ret) |
|---|
| .. | .. |
|---|
| 493 | 554 | set_page_dirty(page); |
|---|
| 494 | 555 | wait_for_stable_page(page); |
|---|
| 495 | 556 | } |
|---|
| 496 | | -out: |
|---|
| 497 | 557 | sb_end_pagefault(inode->i_sb); |
|---|
| 498 | 558 | return block_page_mkwrite_return(ret); |
|---|
| 499 | 559 | } |
|---|
| 500 | 560 | |
|---|
| 561 | +static vm_fault_t gfs2_fault(struct vm_fault *vmf) |
|---|
| 562 | +{ |
|---|
| 563 | + struct inode *inode = file_inode(vmf->vma->vm_file); |
|---|
| 564 | + struct gfs2_inode *ip = GFS2_I(inode); |
|---|
| 565 | + struct gfs2_holder gh; |
|---|
| 566 | + vm_fault_t ret; |
|---|
| 567 | + int err; |
|---|
| 568 | + |
|---|
| 569 | + gfs2_holder_init(ip->i_gl, LM_ST_SHARED, 0, &gh); |
|---|
| 570 | + err = gfs2_glock_nq(&gh); |
|---|
| 571 | + if (err) { |
|---|
| 572 | + ret = block_page_mkwrite_return(err); |
|---|
| 573 | + goto out_uninit; |
|---|
| 574 | + } |
|---|
| 575 | + ret = filemap_fault(vmf); |
|---|
| 576 | + gfs2_glock_dq(&gh); |
|---|
| 577 | +out_uninit: |
|---|
| 578 | + gfs2_holder_uninit(&gh); |
|---|
| 579 | + return ret; |
|---|
| 580 | +} |
|---|
| 581 | + |
|---|
| 501 | 582 | static const struct vm_operations_struct gfs2_vm_ops = { |
|---|
| 502 | | - .fault = filemap_fault, |
|---|
| 583 | + .fault = gfs2_fault, |
|---|
| 503 | 584 | .map_pages = filemap_map_pages, |
|---|
| 504 | 585 | .page_mkwrite = gfs2_page_mkwrite, |
|---|
| 505 | 586 | }; |
|---|
| .. | .. |
|---|
| 570 | 651 | |
|---|
| 571 | 652 | gfs2_assert_warn(GFS2_SB(inode), !file->private_data); |
|---|
| 572 | 653 | file->private_data = fp; |
|---|
| 654 | + if (file->f_mode & FMODE_WRITE) { |
|---|
| 655 | + ret = gfs2_qa_get(GFS2_I(inode)); |
|---|
| 656 | + if (ret) |
|---|
| 657 | + goto fail; |
|---|
| 658 | + } |
|---|
| 573 | 659 | return 0; |
|---|
| 660 | + |
|---|
| 661 | +fail: |
|---|
| 662 | + kfree(file->private_data); |
|---|
| 663 | + file->private_data = NULL; |
|---|
| 664 | + return ret; |
|---|
| 574 | 665 | } |
|---|
| 575 | 666 | |
|---|
| 576 | 667 | /** |
|---|
| .. | .. |
|---|
| 625 | 716 | kfree(file->private_data); |
|---|
| 626 | 717 | file->private_data = NULL; |
|---|
| 627 | 718 | |
|---|
| 628 | | - if (!(file->f_mode & FMODE_WRITE)) |
|---|
| 629 | | - return 0; |
|---|
| 630 | | - |
|---|
| 631 | | - gfs2_rsqa_delete(ip, &inode->i_writecount); |
|---|
| 719 | + if (file->f_mode & FMODE_WRITE) { |
|---|
| 720 | + if (gfs2_rs_active(&ip->i_res)) |
|---|
| 721 | + gfs2_rs_delete(ip); |
|---|
| 722 | + gfs2_qa_put(ip); |
|---|
| 723 | + } |
|---|
| 632 | 724 | return 0; |
|---|
| 633 | 725 | } |
|---|
| 634 | 726 | |
|---|
| .. | .. |
|---|
| 690 | 782 | return ret ? ret : ret1; |
|---|
| 691 | 783 | } |
|---|
| 692 | 784 | |
|---|
| 693 | | -static ssize_t gfs2_file_direct_read(struct kiocb *iocb, struct iov_iter *to) |
|---|
| 785 | +static ssize_t gfs2_file_direct_read(struct kiocb *iocb, struct iov_iter *to, |
|---|
| 786 | + struct gfs2_holder *gh) |
|---|
| 694 | 787 | { |
|---|
| 695 | 788 | struct file *file = iocb->ki_filp; |
|---|
| 696 | 789 | struct gfs2_inode *ip = GFS2_I(file->f_mapping->host); |
|---|
| 697 | 790 | size_t count = iov_iter_count(to); |
|---|
| 698 | | - struct gfs2_holder gh; |
|---|
| 699 | 791 | ssize_t ret; |
|---|
| 700 | 792 | |
|---|
| 701 | 793 | if (!count) |
|---|
| 702 | 794 | return 0; /* skip atime */ |
|---|
| 703 | 795 | |
|---|
| 704 | | - gfs2_holder_init(ip->i_gl, LM_ST_DEFERRED, 0, &gh); |
|---|
| 705 | | - ret = gfs2_glock_nq(&gh); |
|---|
| 796 | + gfs2_holder_init(ip->i_gl, LM_ST_DEFERRED, 0, gh); |
|---|
| 797 | + ret = gfs2_glock_nq(gh); |
|---|
| 706 | 798 | if (ret) |
|---|
| 707 | 799 | goto out_uninit; |
|---|
| 708 | 800 | |
|---|
| 709 | | - ret = iomap_dio_rw(iocb, to, &gfs2_iomap_ops, NULL); |
|---|
| 801 | + ret = iomap_dio_rw(iocb, to, &gfs2_iomap_ops, NULL, |
|---|
| 802 | + is_sync_kiocb(iocb)); |
|---|
| 710 | 803 | |
|---|
| 711 | | - gfs2_glock_dq(&gh); |
|---|
| 804 | + gfs2_glock_dq(gh); |
|---|
| 712 | 805 | out_uninit: |
|---|
| 713 | | - gfs2_holder_uninit(&gh); |
|---|
| 806 | + gfs2_holder_uninit(gh); |
|---|
| 714 | 807 | return ret; |
|---|
| 715 | 808 | } |
|---|
| 716 | 809 | |
|---|
| 717 | | -static ssize_t gfs2_file_direct_write(struct kiocb *iocb, struct iov_iter *from) |
|---|
| 810 | +static ssize_t gfs2_file_direct_write(struct kiocb *iocb, struct iov_iter *from, |
|---|
| 811 | + struct gfs2_holder *gh) |
|---|
| 718 | 812 | { |
|---|
| 719 | 813 | struct file *file = iocb->ki_filp; |
|---|
| 720 | 814 | struct inode *inode = file->f_mapping->host; |
|---|
| 721 | 815 | struct gfs2_inode *ip = GFS2_I(inode); |
|---|
| 722 | 816 | size_t len = iov_iter_count(from); |
|---|
| 723 | 817 | loff_t offset = iocb->ki_pos; |
|---|
| 724 | | - struct gfs2_holder gh; |
|---|
| 725 | 818 | ssize_t ret; |
|---|
| 726 | 819 | |
|---|
| 727 | 820 | /* |
|---|
| .. | .. |
|---|
| 732 | 825 | * unfortunately, have the option of only flushing a range like the |
|---|
| 733 | 826 | * VFS does. |
|---|
| 734 | 827 | */ |
|---|
| 735 | | - gfs2_holder_init(ip->i_gl, LM_ST_DEFERRED, 0, &gh); |
|---|
| 736 | | - ret = gfs2_glock_nq(&gh); |
|---|
| 828 | + gfs2_holder_init(ip->i_gl, LM_ST_DEFERRED, 0, gh); |
|---|
| 829 | + ret = gfs2_glock_nq(gh); |
|---|
| 737 | 830 | if (ret) |
|---|
| 738 | 831 | goto out_uninit; |
|---|
| 739 | 832 | |
|---|
| .. | .. |
|---|
| 741 | 834 | if (offset + len > i_size_read(&ip->i_inode)) |
|---|
| 742 | 835 | goto out; |
|---|
| 743 | 836 | |
|---|
| 744 | | - ret = iomap_dio_rw(iocb, from, &gfs2_iomap_ops, NULL); |
|---|
| 745 | | - |
|---|
| 837 | + ret = iomap_dio_rw(iocb, from, &gfs2_iomap_ops, NULL, |
|---|
| 838 | + is_sync_kiocb(iocb)); |
|---|
| 839 | + if (ret == -ENOTBLK) |
|---|
| 840 | + ret = 0; |
|---|
| 746 | 841 | out: |
|---|
| 747 | | - gfs2_glock_dq(&gh); |
|---|
| 842 | + gfs2_glock_dq(gh); |
|---|
| 748 | 843 | out_uninit: |
|---|
| 749 | | - gfs2_holder_uninit(&gh); |
|---|
| 844 | + gfs2_holder_uninit(gh); |
|---|
| 750 | 845 | return ret; |
|---|
| 751 | 846 | } |
|---|
| 752 | 847 | |
|---|
| 753 | 848 | static ssize_t gfs2_file_read_iter(struct kiocb *iocb, struct iov_iter *to) |
|---|
| 754 | 849 | { |
|---|
| 850 | + struct gfs2_inode *ip; |
|---|
| 851 | + struct gfs2_holder gh; |
|---|
| 852 | + size_t written = 0; |
|---|
| 755 | 853 | ssize_t ret; |
|---|
| 756 | 854 | |
|---|
| 757 | 855 | if (iocb->ki_flags & IOCB_DIRECT) { |
|---|
| 758 | | - ret = gfs2_file_direct_read(iocb, to); |
|---|
| 856 | + ret = gfs2_file_direct_read(iocb, to, &gh); |
|---|
| 759 | 857 | if (likely(ret != -ENOTBLK)) |
|---|
| 760 | 858 | return ret; |
|---|
| 761 | 859 | iocb->ki_flags &= ~IOCB_DIRECT; |
|---|
| 762 | 860 | } |
|---|
| 763 | | - return generic_file_read_iter(iocb, to); |
|---|
| 861 | + pagefault_disable(); |
|---|
| 862 | + iocb->ki_flags |= IOCB_NOIO; |
|---|
| 863 | + ret = generic_file_read_iter(iocb, to); |
|---|
| 864 | + iocb->ki_flags &= ~IOCB_NOIO; |
|---|
| 865 | + pagefault_enable(); |
|---|
| 866 | + if (ret >= 0) { |
|---|
| 867 | + if (!iov_iter_count(to)) |
|---|
| 868 | + return ret; |
|---|
| 869 | + written = ret; |
|---|
| 870 | + } else if (ret != -EFAULT) { |
|---|
| 871 | + if (ret != -EAGAIN) |
|---|
| 872 | + return ret; |
|---|
| 873 | + if (iocb->ki_flags & IOCB_NOWAIT) |
|---|
| 874 | + return ret; |
|---|
| 875 | + } |
|---|
| 876 | + ip = GFS2_I(iocb->ki_filp->f_mapping->host); |
|---|
| 877 | + gfs2_holder_init(ip->i_gl, LM_ST_SHARED, 0, &gh); |
|---|
| 878 | + ret = gfs2_glock_nq(&gh); |
|---|
| 879 | + if (ret) |
|---|
| 880 | + goto out_uninit; |
|---|
| 881 | + ret = generic_file_read_iter(iocb, to); |
|---|
| 882 | + if (ret > 0) |
|---|
| 883 | + written += ret; |
|---|
| 884 | + gfs2_glock_dq(&gh); |
|---|
| 885 | +out_uninit: |
|---|
| 886 | + gfs2_holder_uninit(&gh); |
|---|
| 887 | + return written ? written : ret; |
|---|
| 764 | 888 | } |
|---|
| 765 | 889 | |
|---|
| 766 | 890 | /** |
|---|
| .. | .. |
|---|
| 780 | 904 | struct file *file = iocb->ki_filp; |
|---|
| 781 | 905 | struct inode *inode = file_inode(file); |
|---|
| 782 | 906 | struct gfs2_inode *ip = GFS2_I(inode); |
|---|
| 907 | + struct gfs2_holder gh; |
|---|
| 783 | 908 | ssize_t ret; |
|---|
| 784 | | - |
|---|
| 785 | | - ret = gfs2_rsqa_alloc(ip); |
|---|
| 786 | | - if (ret) |
|---|
| 787 | | - return ret; |
|---|
| 788 | 909 | |
|---|
| 789 | 910 | gfs2_size_hint(file, iocb->ki_pos, iov_iter_count(from)); |
|---|
| 790 | 911 | |
|---|
| 791 | 912 | if (iocb->ki_flags & IOCB_APPEND) { |
|---|
| 792 | | - struct gfs2_holder gh; |
|---|
| 793 | | - |
|---|
| 794 | 913 | ret = gfs2_glock_nq_init(ip->i_gl, LM_ST_SHARED, 0, &gh); |
|---|
| 795 | 914 | if (ret) |
|---|
| 796 | 915 | return ret; |
|---|
| .. | .. |
|---|
| 814 | 933 | struct address_space *mapping = file->f_mapping; |
|---|
| 815 | 934 | ssize_t buffered, ret2; |
|---|
| 816 | 935 | |
|---|
| 817 | | - ret = gfs2_file_direct_write(iocb, from); |
|---|
| 936 | + ret = gfs2_file_direct_write(iocb, from, &gh); |
|---|
| 818 | 937 | if (ret < 0 || !iov_iter_count(from)) |
|---|
| 819 | 938 | goto out_unlock; |
|---|
| 820 | 939 | |
|---|
| .. | .. |
|---|
| 900 | 1019 | brelse(dibh); |
|---|
| 901 | 1020 | return error; |
|---|
| 902 | 1021 | } |
|---|
| 1022 | + |
|---|
| 903 | 1023 | /** |
|---|
| 904 | 1024 | * calc_max_reserv() - Reverse of write_calc_reserv. Given a number of |
|---|
| 905 | 1025 | * blocks, determine how many bytes can be written. |
|---|
| .. | .. |
|---|
| 1016 | 1136 | rblocks += data_blocks ? data_blocks : 1; |
|---|
| 1017 | 1137 | |
|---|
| 1018 | 1138 | error = gfs2_trans_begin(sdp, rblocks, |
|---|
| 1019 | | - PAGE_SIZE/sdp->sd_sb.sb_bsize); |
|---|
| 1139 | + PAGE_SIZE >> inode->i_blkbits); |
|---|
| 1020 | 1140 | if (error) |
|---|
| 1021 | 1141 | goto out_trans_fail; |
|---|
| 1022 | 1142 | |
|---|
| .. | .. |
|---|
| 1032 | 1152 | gfs2_quota_unlock(ip); |
|---|
| 1033 | 1153 | } |
|---|
| 1034 | 1154 | |
|---|
| 1035 | | - if (!(mode & FALLOC_FL_KEEP_SIZE) && (pos + count) > inode->i_size) { |
|---|
| 1155 | + if (!(mode & FALLOC_FL_KEEP_SIZE) && (pos + count) > inode->i_size) |
|---|
| 1036 | 1156 | i_size_write(inode, pos + count); |
|---|
| 1037 | | - file_update_time(file); |
|---|
| 1038 | | - mark_inode_dirty(inode); |
|---|
| 1039 | | - } |
|---|
| 1157 | + file_update_time(file); |
|---|
| 1158 | + mark_inode_dirty(inode); |
|---|
| 1040 | 1159 | |
|---|
| 1041 | 1160 | if ((file->f_flags & O_DSYNC) || IS_SYNC(file->f_mapping->host)) |
|---|
| 1042 | 1161 | return vfs_fsync_range(file, pos, pos + count - 1, |
|---|
| .. | .. |
|---|
| 1085 | 1204 | if (mode & FALLOC_FL_PUNCH_HOLE) { |
|---|
| 1086 | 1205 | ret = __gfs2_punch_hole(file, offset, len); |
|---|
| 1087 | 1206 | } else { |
|---|
| 1088 | | - ret = gfs2_rsqa_alloc(ip); |
|---|
| 1089 | | - if (ret) |
|---|
| 1090 | | - goto out_putw; |
|---|
| 1091 | | - |
|---|
| 1092 | 1207 | ret = __gfs2_fallocate(file, mode, offset, len); |
|---|
| 1093 | | - |
|---|
| 1094 | 1208 | if (ret) |
|---|
| 1095 | 1209 | gfs2_rs_deltree(&ip->i_res); |
|---|
| 1096 | 1210 | } |
|---|
| 1097 | 1211 | |
|---|
| 1098 | | -out_putw: |
|---|
| 1099 | 1212 | put_write_access(inode); |
|---|
| 1100 | 1213 | out_unlock: |
|---|
| 1101 | 1214 | gfs2_glock_dq(&gh); |
|---|
| .. | .. |
|---|
| 1109 | 1222 | struct file *out, loff_t *ppos, |
|---|
| 1110 | 1223 | size_t len, unsigned int flags) |
|---|
| 1111 | 1224 | { |
|---|
| 1112 | | - int error; |
|---|
| 1113 | | - struct gfs2_inode *ip = GFS2_I(out->f_mapping->host); |
|---|
| 1114 | | - |
|---|
| 1115 | | - error = gfs2_rsqa_alloc(ip); |
|---|
| 1116 | | - if (error) |
|---|
| 1117 | | - return (ssize_t)error; |
|---|
| 1225 | + ssize_t ret; |
|---|
| 1118 | 1226 | |
|---|
| 1119 | 1227 | gfs2_size_hint(out, *ppos, len); |
|---|
| 1120 | 1228 | |
|---|
| 1121 | | - return iter_file_splice_write(pipe, out, ppos, len, flags); |
|---|
| 1229 | + ret = iter_file_splice_write(pipe, out, ppos, len, flags); |
|---|
| 1230 | + return ret; |
|---|
| 1122 | 1231 | } |
|---|
| 1123 | 1232 | |
|---|
| 1124 | 1233 | #ifdef CONFIG_GFS2_FS_LOCKING_DLM |
|---|
| .. | .. |
|---|
| 1148 | 1257 | cmd = F_SETLK; |
|---|
| 1149 | 1258 | fl->fl_type = F_UNLCK; |
|---|
| 1150 | 1259 | } |
|---|
| 1151 | | - if (unlikely(test_bit(SDF_SHUTDOWN, &sdp->sd_flags))) { |
|---|
| 1260 | + if (unlikely(gfs2_withdrawn(sdp))) { |
|---|
| 1152 | 1261 | if (fl->fl_type == F_UNLCK) |
|---|
| 1153 | 1262 | locks_lock_file_wait(file, fl); |
|---|
| 1154 | 1263 | return -EIO; |
|---|
| .. | .. |
|---|
| 1178 | 1287 | mutex_lock(&fp->f_fl_mutex); |
|---|
| 1179 | 1288 | |
|---|
| 1180 | 1289 | if (gfs2_holder_initialized(fl_gh)) { |
|---|
| 1290 | + struct file_lock request; |
|---|
| 1181 | 1291 | if (fl_gh->gh_state == state) |
|---|
| 1182 | 1292 | goto out; |
|---|
| 1183 | | - locks_lock_file_wait(file, |
|---|
| 1184 | | - &(struct file_lock) { |
|---|
| 1185 | | - .fl_type = F_UNLCK, |
|---|
| 1186 | | - .fl_flags = FL_FLOCK |
|---|
| 1187 | | - }); |
|---|
| 1293 | + locks_init_lock(&request); |
|---|
| 1294 | + request.fl_type = F_UNLCK; |
|---|
| 1295 | + request.fl_flags = FL_FLOCK; |
|---|
| 1296 | + locks_lock_file_wait(file, &request); |
|---|
| 1188 | 1297 | gfs2_glock_dq(fl_gh); |
|---|
| 1189 | 1298 | gfs2_holder_reinit(state, flags, fl_gh); |
|---|
| 1190 | 1299 | } else { |
|---|
| .. | .. |
|---|
| 1259 | 1368 | .llseek = gfs2_llseek, |
|---|
| 1260 | 1369 | .read_iter = gfs2_file_read_iter, |
|---|
| 1261 | 1370 | .write_iter = gfs2_file_write_iter, |
|---|
| 1371 | + .iopoll = iomap_dio_iopoll, |
|---|
| 1262 | 1372 | .unlocked_ioctl = gfs2_ioctl, |
|---|
| 1373 | + .compat_ioctl = gfs2_compat_ioctl, |
|---|
| 1263 | 1374 | .mmap = gfs2_mmap, |
|---|
| 1264 | 1375 | .open = gfs2_open, |
|---|
| 1265 | 1376 | .release = gfs2_release, |
|---|
| .. | .. |
|---|
| 1275 | 1386 | const struct file_operations gfs2_dir_fops = { |
|---|
| 1276 | 1387 | .iterate_shared = gfs2_readdir, |
|---|
| 1277 | 1388 | .unlocked_ioctl = gfs2_ioctl, |
|---|
| 1389 | + .compat_ioctl = gfs2_compat_ioctl, |
|---|
| 1278 | 1390 | .open = gfs2_open, |
|---|
| 1279 | 1391 | .release = gfs2_release, |
|---|
| 1280 | 1392 | .fsync = gfs2_fsync, |
|---|
| .. | .. |
|---|
| 1289 | 1401 | .llseek = gfs2_llseek, |
|---|
| 1290 | 1402 | .read_iter = gfs2_file_read_iter, |
|---|
| 1291 | 1403 | .write_iter = gfs2_file_write_iter, |
|---|
| 1404 | + .iopoll = iomap_dio_iopoll, |
|---|
| 1292 | 1405 | .unlocked_ioctl = gfs2_ioctl, |
|---|
| 1406 | + .compat_ioctl = gfs2_compat_ioctl, |
|---|
| 1293 | 1407 | .mmap = gfs2_mmap, |
|---|
| 1294 | 1408 | .open = gfs2_open, |
|---|
| 1295 | 1409 | .release = gfs2_release, |
|---|
| .. | .. |
|---|
| 1303 | 1417 | const struct file_operations gfs2_dir_fops_nolock = { |
|---|
| 1304 | 1418 | .iterate_shared = gfs2_readdir, |
|---|
| 1305 | 1419 | .unlocked_ioctl = gfs2_ioctl, |
|---|
| 1420 | + .compat_ioctl = gfs2_compat_ioctl, |
|---|
| 1306 | 1421 | .open = gfs2_open, |
|---|
| 1307 | 1422 | .release = gfs2_release, |
|---|
| 1308 | 1423 | .fsync = gfs2_fsync, |
|---|