aboutsummaryrefslogtreecommitdiffstats
path: root/fs/nfs/file.c
diff options
context:
space:
mode:
Diffstat (limited to 'fs/nfs/file.c')
-rw-r--r--fs/nfs/file.c90
1 files changed, 63 insertions, 27 deletions
diff --git a/fs/nfs/file.c b/fs/nfs/file.c
index 05bf3c0dc751..2f093ed16980 100644
--- a/fs/nfs/file.c
+++ b/fs/nfs/file.c
@@ -36,6 +36,7 @@
36#include "internal.h" 36#include "internal.h"
37#include "iostat.h" 37#include "iostat.h"
38#include "fscache.h" 38#include "fscache.h"
39#include "pnfs.h"
39 40
40#define NFSDBG_FACILITY NFSDBG_FILE 41#define NFSDBG_FACILITY NFSDBG_FILE
41 42
@@ -300,7 +301,7 @@ nfs_file_mmap(struct file * file, struct vm_area_struct * vma)
300 * disk, but it retrieves and clears ctx->error after synching, despite 301 * disk, but it retrieves and clears ctx->error after synching, despite
301 * the two being set at the same time in nfs_context_set_write_error(). 302 * the two being set at the same time in nfs_context_set_write_error().
302 * This is because the former is used to notify the _next_ call to 303 * This is because the former is used to notify the _next_ call to
303 * nfs_file_write() that a write error occured, and hence cause it to 304 * nfs_file_write() that a write error occurred, and hence cause it to
304 * fall back to doing a synchronous write. 305 * fall back to doing a synchronous write.
305 */ 306 */
306static int 307static int
@@ -325,6 +326,9 @@ nfs_file_fsync(struct file *file, int datasync)
325 ret = xchg(&ctx->error, 0); 326 ret = xchg(&ctx->error, 0);
326 if (!ret && status < 0) 327 if (!ret && status < 0)
327 ret = status; 328 ret = status;
329 if (!ret && !datasync)
330 /* application has asked for meta-data sync */
331 ret = pnfs_layoutcommit_inode(inode, true);
328 return ret; 332 return ret;
329} 333}
330 334
@@ -551,7 +555,7 @@ static int nfs_vm_page_mkwrite(struct vm_area_struct *vma, struct vm_fault *vmf)
551 struct file *filp = vma->vm_file; 555 struct file *filp = vma->vm_file;
552 struct dentry *dentry = filp->f_path.dentry; 556 struct dentry *dentry = filp->f_path.dentry;
553 unsigned pagelen; 557 unsigned pagelen;
554 int ret = -EINVAL; 558 int ret = VM_FAULT_NOPAGE;
555 struct address_space *mapping; 559 struct address_space *mapping;
556 560
557 dfprintk(PAGECACHE, "NFS: vm_page_mkwrite(%s/%s(%ld), offset %lld)\n", 561 dfprintk(PAGECACHE, "NFS: vm_page_mkwrite(%s/%s(%ld), offset %lld)\n",
@@ -567,21 +571,20 @@ static int nfs_vm_page_mkwrite(struct vm_area_struct *vma, struct vm_fault *vmf)
567 if (mapping != dentry->d_inode->i_mapping) 571 if (mapping != dentry->d_inode->i_mapping)
568 goto out_unlock; 572 goto out_unlock;
569 573
570 ret = 0;
571 pagelen = nfs_page_length(page); 574 pagelen = nfs_page_length(page);
572 if (pagelen == 0) 575 if (pagelen == 0)
573 goto out_unlock; 576 goto out_unlock;
574 577
575 ret = nfs_flush_incompatible(filp, page); 578 ret = VM_FAULT_LOCKED;
576 if (ret != 0) 579 if (nfs_flush_incompatible(filp, page) == 0 &&
577 goto out_unlock; 580 nfs_updatepage(filp, page, 0, pagelen) == 0)
581 goto out;
578 582
579 ret = nfs_updatepage(filp, page, 0, pagelen); 583 ret = VM_FAULT_SIGBUS;
580out_unlock: 584out_unlock:
581 if (!ret)
582 return VM_FAULT_LOCKED;
583 unlock_page(page); 585 unlock_page(page);
584 return VM_FAULT_SIGBUS; 586out:
587 return ret;
585} 588}
586 589
587static const struct vm_operations_struct nfs_file_vm_ops = { 590static const struct vm_operations_struct nfs_file_vm_ops = {
@@ -684,10 +687,12 @@ static ssize_t nfs_file_splice_write(struct pipe_inode_info *pipe,
684 return ret; 687 return ret;
685} 688}
686 689
687static int do_getlk(struct file *filp, int cmd, struct file_lock *fl) 690static int
691do_getlk(struct file *filp, int cmd, struct file_lock *fl, int is_local)
688{ 692{
689 struct inode *inode = filp->f_mapping->host; 693 struct inode *inode = filp->f_mapping->host;
690 int status = 0; 694 int status = 0;
695 unsigned int saved_type = fl->fl_type;
691 696
692 /* Try local locking first */ 697 /* Try local locking first */
693 posix_test_lock(filp, fl); 698 posix_test_lock(filp, fl);
@@ -695,11 +700,12 @@ static int do_getlk(struct file *filp, int cmd, struct file_lock *fl)
695 /* found a conflict */ 700 /* found a conflict */
696 goto out; 701 goto out;
697 } 702 }
703 fl->fl_type = saved_type;
698 704
699 if (nfs_have_delegation(inode, FMODE_READ)) 705 if (nfs_have_delegation(inode, FMODE_READ))
700 goto out_noconflict; 706 goto out_noconflict;
701 707
702 if (NFS_SERVER(inode)->flags & NFS_MOUNT_NONLM) 708 if (is_local)
703 goto out_noconflict; 709 goto out_noconflict;
704 710
705 status = NFS_PROTO(inode)->lock(filp, cmd, fl); 711 status = NFS_PROTO(inode)->lock(filp, cmd, fl);
@@ -726,7 +732,8 @@ static int do_vfs_lock(struct file *file, struct file_lock *fl)
726 return res; 732 return res;
727} 733}
728 734
729static int do_unlk(struct file *filp, int cmd, struct file_lock *fl) 735static int
736do_unlk(struct file *filp, int cmd, struct file_lock *fl, int is_local)
730{ 737{
731 struct inode *inode = filp->f_mapping->host; 738 struct inode *inode = filp->f_mapping->host;
732 int status; 739 int status;
@@ -741,15 +748,24 @@ static int do_unlk(struct file *filp, int cmd, struct file_lock *fl)
741 * If we're signalled while cleaning up locks on process exit, we 748 * If we're signalled while cleaning up locks on process exit, we
742 * still need to complete the unlock. 749 * still need to complete the unlock.
743 */ 750 */
744 /* Use local locking if mounted with "-onolock" */ 751 /*
745 if (!(NFS_SERVER(inode)->flags & NFS_MOUNT_NONLM)) 752 * Use local locking if mounted with "-onolock" or with appropriate
753 * "-olocal_lock="
754 */
755 if (!is_local)
746 status = NFS_PROTO(inode)->lock(filp, cmd, fl); 756 status = NFS_PROTO(inode)->lock(filp, cmd, fl);
747 else 757 else
748 status = do_vfs_lock(filp, fl); 758 status = do_vfs_lock(filp, fl);
749 return status; 759 return status;
750} 760}
751 761
752static int do_setlk(struct file *filp, int cmd, struct file_lock *fl) 762static int
763is_time_granular(struct timespec *ts) {
764 return ((ts->tv_sec == 0) && (ts->tv_nsec <= 1000));
765}
766
767static int
768do_setlk(struct file *filp, int cmd, struct file_lock *fl, int is_local)
753{ 769{
754 struct inode *inode = filp->f_mapping->host; 770 struct inode *inode = filp->f_mapping->host;
755 int status; 771 int status;
@@ -762,20 +778,31 @@ static int do_setlk(struct file *filp, int cmd, struct file_lock *fl)
762 if (status != 0) 778 if (status != 0)
763 goto out; 779 goto out;
764 780
765 /* Use local locking if mounted with "-onolock" */ 781 /*
766 if (!(NFS_SERVER(inode)->flags & NFS_MOUNT_NONLM)) 782 * Use local locking if mounted with "-onolock" or with appropriate
783 * "-olocal_lock="
784 */
785 if (!is_local)
767 status = NFS_PROTO(inode)->lock(filp, cmd, fl); 786 status = NFS_PROTO(inode)->lock(filp, cmd, fl);
768 else 787 else
769 status = do_vfs_lock(filp, fl); 788 status = do_vfs_lock(filp, fl);
770 if (status < 0) 789 if (status < 0)
771 goto out; 790 goto out;
791
772 /* 792 /*
773 * Make sure we clear the cache whenever we try to get the lock. 793 * Revalidate the cache if the server has time stamps granular
794 * enough to detect subsecond changes. Otherwise, clear the
795 * cache to prevent missing any changes.
796 *
774 * This makes locking act as a cache coherency point. 797 * This makes locking act as a cache coherency point.
775 */ 798 */
776 nfs_sync_mapping(filp->f_mapping); 799 nfs_sync_mapping(filp->f_mapping);
777 if (!nfs_have_delegation(inode, FMODE_READ)) 800 if (!nfs_have_delegation(inode, FMODE_READ)) {
778 nfs_zap_caches(inode); 801 if (is_time_granular(&NFS_SERVER(inode)->time_delta))
802 __nfs_revalidate_inode(NFS_SERVER(inode), inode);
803 else
804 nfs_zap_caches(inode);
805 }
779out: 806out:
780 return status; 807 return status;
781} 808}
@@ -787,6 +814,7 @@ static int nfs_lock(struct file *filp, int cmd, struct file_lock *fl)
787{ 814{
788 struct inode *inode = filp->f_mapping->host; 815 struct inode *inode = filp->f_mapping->host;
789 int ret = -ENOLCK; 816 int ret = -ENOLCK;
817 int is_local = 0;
790 818
791 dprintk("NFS: lock(%s/%s, t=%x, fl=%x, r=%lld:%lld)\n", 819 dprintk("NFS: lock(%s/%s, t=%x, fl=%x, r=%lld:%lld)\n",
792 filp->f_path.dentry->d_parent->d_name.name, 820 filp->f_path.dentry->d_parent->d_name.name,
@@ -800,6 +828,9 @@ static int nfs_lock(struct file *filp, int cmd, struct file_lock *fl)
800 if (__mandatory_lock(inode) && fl->fl_type != F_UNLCK) 828 if (__mandatory_lock(inode) && fl->fl_type != F_UNLCK)
801 goto out_err; 829 goto out_err;
802 830
831 if (NFS_SERVER(inode)->flags & NFS_MOUNT_LOCAL_FCNTL)
832 is_local = 1;
833
803 if (NFS_PROTO(inode)->lock_check_bounds != NULL) { 834 if (NFS_PROTO(inode)->lock_check_bounds != NULL) {
804 ret = NFS_PROTO(inode)->lock_check_bounds(fl); 835 ret = NFS_PROTO(inode)->lock_check_bounds(fl);
805 if (ret < 0) 836 if (ret < 0)
@@ -807,11 +838,11 @@ static int nfs_lock(struct file *filp, int cmd, struct file_lock *fl)
807 } 838 }
808 839
809 if (IS_GETLK(cmd)) 840 if (IS_GETLK(cmd))
810 ret = do_getlk(filp, cmd, fl); 841 ret = do_getlk(filp, cmd, fl, is_local);
811 else if (fl->fl_type == F_UNLCK) 842 else if (fl->fl_type == F_UNLCK)
812 ret = do_unlk(filp, cmd, fl); 843 ret = do_unlk(filp, cmd, fl, is_local);
813 else 844 else
814 ret = do_setlk(filp, cmd, fl); 845 ret = do_setlk(filp, cmd, fl, is_local);
815out_err: 846out_err:
816 return ret; 847 return ret;
817} 848}
@@ -821,6 +852,9 @@ out_err:
821 */ 852 */
822static int nfs_flock(struct file *filp, int cmd, struct file_lock *fl) 853static int nfs_flock(struct file *filp, int cmd, struct file_lock *fl)
823{ 854{
855 struct inode *inode = filp->f_mapping->host;
856 int is_local = 0;
857
824 dprintk("NFS: flock(%s/%s, t=%x, fl=%x)\n", 858 dprintk("NFS: flock(%s/%s, t=%x, fl=%x)\n",
825 filp->f_path.dentry->d_parent->d_name.name, 859 filp->f_path.dentry->d_parent->d_name.name,
826 filp->f_path.dentry->d_name.name, 860 filp->f_path.dentry->d_name.name,
@@ -829,14 +863,17 @@ static int nfs_flock(struct file *filp, int cmd, struct file_lock *fl)
829 if (!(fl->fl_flags & FL_FLOCK)) 863 if (!(fl->fl_flags & FL_FLOCK))
830 return -ENOLCK; 864 return -ENOLCK;
831 865
866 if (NFS_SERVER(inode)->flags & NFS_MOUNT_LOCAL_FLOCK)
867 is_local = 1;
868
832 /* We're simulating flock() locks using posix locks on the server */ 869 /* We're simulating flock() locks using posix locks on the server */
833 fl->fl_owner = (fl_owner_t)filp; 870 fl->fl_owner = (fl_owner_t)filp;
834 fl->fl_start = 0; 871 fl->fl_start = 0;
835 fl->fl_end = OFFSET_MAX; 872 fl->fl_end = OFFSET_MAX;
836 873
837 if (fl->fl_type == F_UNLCK) 874 if (fl->fl_type == F_UNLCK)
838 return do_unlk(filp, cmd, fl); 875 return do_unlk(filp, cmd, fl, is_local);
839 return do_setlk(filp, cmd, fl); 876 return do_setlk(filp, cmd, fl, is_local);
840} 877}
841 878
842/* 879/*
@@ -848,6 +885,5 @@ static int nfs_setlease(struct file *file, long arg, struct file_lock **fl)
848 dprintk("NFS: setlease(%s/%s, arg=%ld)\n", 885 dprintk("NFS: setlease(%s/%s, arg=%ld)\n",
849 file->f_path.dentry->d_parent->d_name.name, 886 file->f_path.dentry->d_parent->d_name.name,
850 file->f_path.dentry->d_name.name, arg); 887 file->f_path.dentry->d_name.name, arg);
851
852 return -EINVAL; 888 return -EINVAL;
853} 889}