diff options
Diffstat (limited to 'fs')
-rw-r--r-- | fs/cifs/cifsglob.h | 1 | ||||
-rw-r--r-- | fs/cifs/cifsproto.h | 2 | ||||
-rw-r--r-- | fs/cifs/cifssmb.c | 4 | ||||
-rw-r--r-- | fs/cifs/file.c | 370 |
4 files changed, 205 insertions, 172 deletions
diff --git a/fs/cifs/cifsglob.h b/fs/cifs/cifsglob.h index 3b83fe7bfe60..1f265ffe7e63 100644 --- a/fs/cifs/cifsglob.h +++ b/fs/cifs/cifsglob.h | |||
@@ -492,6 +492,7 @@ struct cifsLockInfo { | |||
492 | struct list_head llist; /* pointer to next cifsLockInfo */ | 492 | struct list_head llist; /* pointer to next cifsLockInfo */ |
493 | __u64 offset; | 493 | __u64 offset; |
494 | __u64 length; | 494 | __u64 length; |
495 | __u32 pid; | ||
495 | __u8 type; | 496 | __u8 type; |
496 | }; | 497 | }; |
497 | 498 | ||
diff --git a/fs/cifs/cifsproto.h b/fs/cifs/cifsproto.h index 9ddb1eccde69..94834dbb46da 100644 --- a/fs/cifs/cifsproto.h +++ b/fs/cifs/cifsproto.h | |||
@@ -361,7 +361,7 @@ extern int CIFSGetSrvInodeNumber(const int xid, struct cifs_tcon *tcon, | |||
361 | int remap_special_chars); | 361 | int remap_special_chars); |
362 | 362 | ||
363 | extern int CIFSSMBLock(const int xid, struct cifs_tcon *tcon, | 363 | extern int CIFSSMBLock(const int xid, struct cifs_tcon *tcon, |
364 | const __u16 netfid, const __u64 len, | 364 | const __u16 netfid, const __u32 netpid, const __u64 len, |
365 | const __u64 offset, const __u32 numUnlock, | 365 | const __u64 offset, const __u32 numUnlock, |
366 | const __u32 numLock, const __u8 lockType, | 366 | const __u32 numLock, const __u8 lockType, |
367 | const bool waitFlag, const __u8 oplock_level); | 367 | const bool waitFlag, const __u8 oplock_level); |
diff --git a/fs/cifs/cifssmb.c b/fs/cifs/cifssmb.c index 602326fa4a4f..e33093f7ef0d 100644 --- a/fs/cifs/cifssmb.c +++ b/fs/cifs/cifssmb.c | |||
@@ -1963,7 +1963,7 @@ CIFSSMBWrite2(const int xid, struct cifs_io_parms *io_parms, | |||
1963 | 1963 | ||
1964 | int | 1964 | int |
1965 | CIFSSMBLock(const int xid, struct cifs_tcon *tcon, | 1965 | CIFSSMBLock(const int xid, struct cifs_tcon *tcon, |
1966 | const __u16 smb_file_id, const __u64 len, | 1966 | const __u16 smb_file_id, const __u32 netpid, const __u64 len, |
1967 | const __u64 offset, const __u32 numUnlock, | 1967 | const __u64 offset, const __u32 numUnlock, |
1968 | const __u32 numLock, const __u8 lockType, | 1968 | const __u32 numLock, const __u8 lockType, |
1969 | const bool waitFlag, const __u8 oplock_level) | 1969 | const bool waitFlag, const __u8 oplock_level) |
@@ -1999,7 +1999,7 @@ CIFSSMBLock(const int xid, struct cifs_tcon *tcon, | |||
1999 | pSMB->Fid = smb_file_id; /* netfid stays le */ | 1999 | pSMB->Fid = smb_file_id; /* netfid stays le */ |
2000 | 2000 | ||
2001 | if ((numLock != 0) || (numUnlock != 0)) { | 2001 | if ((numLock != 0) || (numUnlock != 0)) { |
2002 | pSMB->Locks[0].Pid = cpu_to_le16(current->tgid); | 2002 | pSMB->Locks[0].Pid = cpu_to_le16(netpid); |
2003 | /* BB where to store pid high? */ | 2003 | /* BB where to store pid high? */ |
2004 | pSMB->Locks[0].LengthLow = cpu_to_le32((u32)len); | 2004 | pSMB->Locks[0].LengthLow = cpu_to_le32((u32)len); |
2005 | pSMB->Locks[0].LengthHigh = cpu_to_le32((u32)(len>>32)); | 2005 | pSMB->Locks[0].LengthHigh = cpu_to_le32((u32)(len>>32)); |
diff --git a/fs/cifs/file.c b/fs/cifs/file.c index 237192ae7587..ab85699c5653 100644 --- a/fs/cifs/file.c +++ b/fs/cifs/file.c | |||
@@ -639,8 +639,8 @@ int cifs_closedir(struct inode *inode, struct file *file) | |||
639 | return rc; | 639 | return rc; |
640 | } | 640 | } |
641 | 641 | ||
642 | static int store_file_lock(struct cifsFileInfo *fid, __u64 len, | 642 | static int store_file_lock(struct cifsFileInfo *cfile, __u64 len, |
643 | __u64 offset, __u8 lockType) | 643 | __u64 offset, __u8 type, __u16 netfid) |
644 | { | 644 | { |
645 | struct cifsLockInfo *li = | 645 | struct cifsLockInfo *li = |
646 | kmalloc(sizeof(struct cifsLockInfo), GFP_KERNEL); | 646 | kmalloc(sizeof(struct cifsLockInfo), GFP_KERNEL); |
@@ -648,210 +648,241 @@ static int store_file_lock(struct cifsFileInfo *fid, __u64 len, | |||
648 | return -ENOMEM; | 648 | return -ENOMEM; |
649 | li->offset = offset; | 649 | li->offset = offset; |
650 | li->length = len; | 650 | li->length = len; |
651 | li->type = lockType; | 651 | li->type = type; |
652 | mutex_lock(&fid->lock_mutex); | 652 | li->pid = current->tgid; |
653 | list_add(&li->llist, &fid->llist); | 653 | mutex_lock(&cfile->lock_mutex); |
654 | mutex_unlock(&fid->lock_mutex); | 654 | list_add_tail(&li->llist, &cfile->llist); |
655 | mutex_unlock(&cfile->lock_mutex); | ||
655 | return 0; | 656 | return 0; |
656 | } | 657 | } |
657 | 658 | ||
658 | int cifs_lock(struct file *file, int cmd, struct file_lock *pfLock) | 659 | static void |
660 | cifs_read_flock(struct file_lock *flock, __u8 *type, int *lock, int *unlock, | ||
661 | bool *wait_flag) | ||
659 | { | 662 | { |
660 | int rc, xid; | 663 | if (flock->fl_flags & FL_POSIX) |
661 | __u32 numLock = 0; | ||
662 | __u32 numUnlock = 0; | ||
663 | __u64 length; | ||
664 | bool wait_flag = false; | ||
665 | struct cifs_sb_info *cifs_sb; | ||
666 | struct cifs_tcon *tcon; | ||
667 | __u16 netfid; | ||
668 | __u8 lockType = LOCKING_ANDX_LARGE_FILES; | ||
669 | bool posix_locking = 0; | ||
670 | |||
671 | length = 1 + pfLock->fl_end - pfLock->fl_start; | ||
672 | rc = -EACCES; | ||
673 | xid = GetXid(); | ||
674 | |||
675 | cFYI(1, "Lock parm: 0x%x flockflags: " | ||
676 | "0x%x flocktype: 0x%x start: %lld end: %lld", | ||
677 | cmd, pfLock->fl_flags, pfLock->fl_type, pfLock->fl_start, | ||
678 | pfLock->fl_end); | ||
679 | |||
680 | if (pfLock->fl_flags & FL_POSIX) | ||
681 | cFYI(1, "Posix"); | 664 | cFYI(1, "Posix"); |
682 | if (pfLock->fl_flags & FL_FLOCK) | 665 | if (flock->fl_flags & FL_FLOCK) |
683 | cFYI(1, "Flock"); | 666 | cFYI(1, "Flock"); |
684 | if (pfLock->fl_flags & FL_SLEEP) { | 667 | if (flock->fl_flags & FL_SLEEP) { |
685 | cFYI(1, "Blocking lock"); | 668 | cFYI(1, "Blocking lock"); |
686 | wait_flag = true; | 669 | *wait_flag = true; |
687 | } | 670 | } |
688 | if (pfLock->fl_flags & FL_ACCESS) | 671 | if (flock->fl_flags & FL_ACCESS) |
689 | cFYI(1, "Process suspended by mandatory locking - " | 672 | cFYI(1, "Process suspended by mandatory locking - " |
690 | "not implemented yet"); | 673 | "not implemented yet"); |
691 | if (pfLock->fl_flags & FL_LEASE) | 674 | if (flock->fl_flags & FL_LEASE) |
692 | cFYI(1, "Lease on file - not implemented yet"); | 675 | cFYI(1, "Lease on file - not implemented yet"); |
693 | if (pfLock->fl_flags & | 676 | if (flock->fl_flags & |
694 | (~(FL_POSIX | FL_FLOCK | FL_SLEEP | FL_ACCESS | FL_LEASE))) | 677 | (~(FL_POSIX | FL_FLOCK | FL_SLEEP | FL_ACCESS | FL_LEASE))) |
695 | cFYI(1, "Unknown lock flags 0x%x", pfLock->fl_flags); | 678 | cFYI(1, "Unknown lock flags 0x%x", flock->fl_flags); |
696 | 679 | ||
697 | if (pfLock->fl_type == F_WRLCK) { | 680 | *type = LOCKING_ANDX_LARGE_FILES; |
681 | if (flock->fl_type == F_WRLCK) { | ||
698 | cFYI(1, "F_WRLCK "); | 682 | cFYI(1, "F_WRLCK "); |
699 | numLock = 1; | 683 | *lock = 1; |
700 | } else if (pfLock->fl_type == F_UNLCK) { | 684 | } else if (flock->fl_type == F_UNLCK) { |
701 | cFYI(1, "F_UNLCK"); | 685 | cFYI(1, "F_UNLCK"); |
702 | numUnlock = 1; | 686 | *unlock = 1; |
703 | /* Check if unlock includes more than | 687 | /* Check if unlock includes more than one lock range */ |
704 | one lock range */ | 688 | } else if (flock->fl_type == F_RDLCK) { |
705 | } else if (pfLock->fl_type == F_RDLCK) { | ||
706 | cFYI(1, "F_RDLCK"); | 689 | cFYI(1, "F_RDLCK"); |
707 | lockType |= LOCKING_ANDX_SHARED_LOCK; | 690 | *type |= LOCKING_ANDX_SHARED_LOCK; |
708 | numLock = 1; | 691 | *lock = 1; |
709 | } else if (pfLock->fl_type == F_EXLCK) { | 692 | } else if (flock->fl_type == F_EXLCK) { |
710 | cFYI(1, "F_EXLCK"); | 693 | cFYI(1, "F_EXLCK"); |
711 | numLock = 1; | 694 | *lock = 1; |
712 | } else if (pfLock->fl_type == F_SHLCK) { | 695 | } else if (flock->fl_type == F_SHLCK) { |
713 | cFYI(1, "F_SHLCK"); | 696 | cFYI(1, "F_SHLCK"); |
714 | lockType |= LOCKING_ANDX_SHARED_LOCK; | 697 | *type |= LOCKING_ANDX_SHARED_LOCK; |
715 | numLock = 1; | 698 | *lock = 1; |
716 | } else | 699 | } else |
717 | cFYI(1, "Unknown type of lock"); | 700 | cFYI(1, "Unknown type of lock"); |
701 | } | ||
718 | 702 | ||
719 | cifs_sb = CIFS_SB(file->f_path.dentry->d_sb); | 703 | static int |
720 | tcon = tlink_tcon(((struct cifsFileInfo *)file->private_data)->tlink); | 704 | cifs_getlk(struct cifsFileInfo *cfile, struct file_lock *flock, __u8 type, |
721 | netfid = ((struct cifsFileInfo *)file->private_data)->netfid; | 705 | bool wait_flag, bool posix_lck, int xid) |
722 | 706 | { | |
723 | if ((tcon->ses->capabilities & CAP_UNIX) && | 707 | int rc = 0; |
724 | (CIFS_UNIX_FCNTL_CAP & le64_to_cpu(tcon->fsUnixInfo.Capability)) && | 708 | __u64 length = 1 + flock->fl_end - flock->fl_start; |
725 | ((cifs_sb->mnt_cifs_flags & CIFS_MOUNT_NOPOSIXBRL) == 0)) | 709 | __u16 netfid = cfile->netfid; |
726 | posix_locking = 1; | 710 | struct cifs_tcon *tcon = tlink_tcon(cfile->tlink); |
727 | /* BB add code here to normalize offset and length to | ||
728 | account for negative length which we can not accept over the | ||
729 | wire */ | ||
730 | if (IS_GETLK(cmd)) { | ||
731 | if (posix_locking) { | ||
732 | int posix_lock_type; | ||
733 | if (lockType & LOCKING_ANDX_SHARED_LOCK) | ||
734 | posix_lock_type = CIFS_RDLCK; | ||
735 | else | ||
736 | posix_lock_type = CIFS_WRLCK; | ||
737 | rc = CIFSSMBPosixLock(xid, tcon, netfid, 1 /* get */, | ||
738 | length, pfLock, posix_lock_type, | ||
739 | wait_flag); | ||
740 | FreeXid(xid); | ||
741 | return rc; | ||
742 | } | ||
743 | |||
744 | /* BB we could chain these into one lock request BB */ | ||
745 | rc = CIFSSMBLock(xid, tcon, netfid, length, pfLock->fl_start, | ||
746 | 0, 1, lockType, 0 /* wait flag */, 0); | ||
747 | if (rc == 0) { | ||
748 | rc = CIFSSMBLock(xid, tcon, netfid, length, | ||
749 | pfLock->fl_start, 1 /* numUnlock */ , | ||
750 | 0 /* numLock */ , lockType, | ||
751 | 0 /* wait flag */, 0); | ||
752 | pfLock->fl_type = F_UNLCK; | ||
753 | if (rc != 0) | ||
754 | cERROR(1, "Error unlocking previously locked " | ||
755 | "range %d during test of lock", rc); | ||
756 | rc = 0; | ||
757 | |||
758 | } else { | ||
759 | /* if rc == ERR_SHARING_VIOLATION ? */ | ||
760 | rc = 0; | ||
761 | 711 | ||
762 | if (lockType & LOCKING_ANDX_SHARED_LOCK) { | 712 | if (posix_lck) { |
763 | pfLock->fl_type = F_WRLCK; | 713 | int posix_lock_type; |
764 | } else { | 714 | if (type & LOCKING_ANDX_SHARED_LOCK) |
765 | rc = CIFSSMBLock(xid, tcon, netfid, length, | 715 | posix_lock_type = CIFS_RDLCK; |
766 | pfLock->fl_start, 0, 1, | 716 | else |
767 | lockType | LOCKING_ANDX_SHARED_LOCK, | 717 | posix_lock_type = CIFS_WRLCK; |
768 | 0 /* wait flag */, 0); | 718 | rc = CIFSSMBPosixLock(xid, tcon, netfid, 1 /* get */, |
769 | if (rc == 0) { | 719 | length, flock, posix_lock_type, |
770 | rc = CIFSSMBLock(xid, tcon, netfid, | 720 | wait_flag); |
771 | length, pfLock->fl_start, 1, 0, | 721 | return rc; |
772 | lockType | | 722 | } |
773 | LOCKING_ANDX_SHARED_LOCK, | ||
774 | 0 /* wait flag */, 0); | ||
775 | pfLock->fl_type = F_RDLCK; | ||
776 | if (rc != 0) | ||
777 | cERROR(1, "Error unlocking " | ||
778 | "previously locked range %d " | ||
779 | "during test of lock", rc); | ||
780 | rc = 0; | ||
781 | } else { | ||
782 | pfLock->fl_type = F_WRLCK; | ||
783 | rc = 0; | ||
784 | } | ||
785 | } | ||
786 | } | ||
787 | 723 | ||
788 | FreeXid(xid); | 724 | /* BB we could chain these into one lock request BB */ |
725 | rc = CIFSSMBLock(xid, tcon, netfid, current->tgid, length, | ||
726 | flock->fl_start, 0, 1, type, 0, 0); | ||
727 | if (rc == 0) { | ||
728 | rc = CIFSSMBLock(xid, tcon, netfid, current->tgid, | ||
729 | length, flock->fl_start, 1, 0, | ||
730 | type, 0, 0); | ||
731 | flock->fl_type = F_UNLCK; | ||
732 | if (rc != 0) | ||
733 | cERROR(1, "Error unlocking previously locked " | ||
734 | "range %d during test of lock", rc); | ||
735 | rc = 0; | ||
789 | return rc; | 736 | return rc; |
790 | } | 737 | } |
791 | 738 | ||
792 | if (!numLock && !numUnlock) { | 739 | if (type & LOCKING_ANDX_SHARED_LOCK) { |
793 | /* if no lock or unlock then nothing | 740 | flock->fl_type = F_WRLCK; |
794 | to do since we do not know what it is */ | 741 | rc = 0; |
795 | FreeXid(xid); | 742 | return rc; |
796 | return -EOPNOTSUPP; | ||
797 | } | 743 | } |
798 | 744 | ||
799 | if (posix_locking) { | 745 | rc = CIFSSMBLock(xid, tcon, netfid, current->tgid, length, |
746 | flock->fl_start, 0, 1, | ||
747 | type | LOCKING_ANDX_SHARED_LOCK, 0, 0); | ||
748 | if (rc == 0) { | ||
749 | rc = CIFSSMBLock(xid, tcon, netfid, current->tgid, | ||
750 | length, flock->fl_start, 1, 0, | ||
751 | type | LOCKING_ANDX_SHARED_LOCK, | ||
752 | 0, 0); | ||
753 | flock->fl_type = F_RDLCK; | ||
754 | if (rc != 0) | ||
755 | cERROR(1, "Error unlocking previously locked " | ||
756 | "range %d during test of lock", rc); | ||
757 | } else | ||
758 | flock->fl_type = F_WRLCK; | ||
759 | |||
760 | rc = 0; | ||
761 | return rc; | ||
762 | } | ||
763 | |||
764 | static int | ||
765 | cifs_setlk(struct file *file, struct file_lock *flock, __u8 type, | ||
766 | bool wait_flag, bool posix_lck, int lock, int unlock, int xid) | ||
767 | { | ||
768 | int rc = 0; | ||
769 | __u64 length = 1 + flock->fl_end - flock->fl_start; | ||
770 | struct cifsFileInfo *cfile = (struct cifsFileInfo *)file->private_data; | ||
771 | struct cifs_tcon *tcon = tlink_tcon(cfile->tlink); | ||
772 | __u16 netfid = cfile->netfid; | ||
773 | |||
774 | if (posix_lck) { | ||
800 | int posix_lock_type; | 775 | int posix_lock_type; |
801 | if (lockType & LOCKING_ANDX_SHARED_LOCK) | 776 | if (type & LOCKING_ANDX_SHARED_LOCK) |
802 | posix_lock_type = CIFS_RDLCK; | 777 | posix_lock_type = CIFS_RDLCK; |
803 | else | 778 | else |
804 | posix_lock_type = CIFS_WRLCK; | 779 | posix_lock_type = CIFS_WRLCK; |
805 | 780 | ||
806 | if (numUnlock == 1) | 781 | if (unlock == 1) |
807 | posix_lock_type = CIFS_UNLCK; | 782 | posix_lock_type = CIFS_UNLCK; |
808 | 783 | ||
809 | rc = CIFSSMBPosixLock(xid, tcon, netfid, 0 /* set */, | 784 | rc = CIFSSMBPosixLock(xid, tcon, netfid, 0 /* set */, length, |
810 | length, pfLock, posix_lock_type, | 785 | flock, posix_lock_type, wait_flag); |
811 | wait_flag); | 786 | goto out; |
812 | } else { | 787 | } |
813 | struct cifsFileInfo *fid = file->private_data; | ||
814 | |||
815 | if (numLock) { | ||
816 | rc = CIFSSMBLock(xid, tcon, netfid, length, | ||
817 | pfLock->fl_start, 0, numLock, lockType, | ||
818 | wait_flag, 0); | ||
819 | |||
820 | if (rc == 0) { | ||
821 | /* For Windows locks we must store them. */ | ||
822 | rc = store_file_lock(fid, length, | ||
823 | pfLock->fl_start, lockType); | ||
824 | } | ||
825 | } else if (numUnlock) { | ||
826 | /* For each stored lock that this unlock overlaps | ||
827 | completely, unlock it. */ | ||
828 | int stored_rc = 0; | ||
829 | struct cifsLockInfo *li, *tmp; | ||
830 | 788 | ||
831 | rc = 0; | 789 | if (lock) { |
832 | mutex_lock(&fid->lock_mutex); | 790 | rc = CIFSSMBLock(xid, tcon, netfid, current->tgid, length, |
833 | list_for_each_entry_safe(li, tmp, &fid->llist, llist) { | 791 | flock->fl_start, 0, lock, type, wait_flag, 0); |
834 | if (pfLock->fl_start <= li->offset && | 792 | if (rc == 0) { |
835 | (pfLock->fl_start + length) >= | 793 | /* For Windows locks we must store them. */ |
836 | (li->offset + li->length)) { | 794 | rc = store_file_lock(cfile, length, flock->fl_start, |
837 | stored_rc = CIFSSMBLock(xid, tcon, | 795 | type, netfid); |
838 | netfid, li->length, | 796 | } |
839 | li->offset, 1, 0, | 797 | } else if (unlock) { |
840 | li->type, false, 0); | 798 | /* |
841 | if (stored_rc) | 799 | * For each stored lock that this unlock overlaps completely, |
842 | rc = stored_rc; | 800 | * unlock it. |
843 | else { | 801 | */ |
844 | list_del(&li->llist); | 802 | int stored_rc = 0; |
845 | kfree(li); | 803 | struct cifsLockInfo *li, *tmp; |
846 | } | 804 | |
847 | } | 805 | mutex_lock(&cfile->lock_mutex); |
806 | list_for_each_entry_safe(li, tmp, &cfile->llist, llist) { | ||
807 | if (flock->fl_start > li->offset || | ||
808 | (flock->fl_start + length) < | ||
809 | (li->offset + li->length)) | ||
810 | continue; | ||
811 | if (current->tgid != li->pid) | ||
812 | continue; | ||
813 | |||
814 | stored_rc = CIFSSMBLock(xid, tcon, netfid, | ||
815 | current->tgid, li->length, | ||
816 | li->offset, 1, 0, li->type, | ||
817 | 0, 0); | ||
818 | if (stored_rc) | ||
819 | rc = stored_rc; | ||
820 | else { | ||
821 | list_del(&li->llist); | ||
822 | kfree(li); | ||
848 | } | 823 | } |
849 | mutex_unlock(&fid->lock_mutex); | ||
850 | } | 824 | } |
825 | mutex_unlock(&cfile->lock_mutex); | ||
826 | } | ||
827 | out: | ||
828 | if (flock->fl_flags & FL_POSIX) | ||
829 | posix_lock_file_wait(file, flock); | ||
830 | return rc; | ||
831 | } | ||
832 | |||
833 | int cifs_lock(struct file *file, int cmd, struct file_lock *flock) | ||
834 | { | ||
835 | int rc, xid; | ||
836 | int lock = 0, unlock = 0; | ||
837 | bool wait_flag = false; | ||
838 | bool posix_lck = false; | ||
839 | struct cifs_sb_info *cifs_sb; | ||
840 | struct cifs_tcon *tcon; | ||
841 | struct cifsInodeInfo *cinode; | ||
842 | struct cifsFileInfo *cfile; | ||
843 | __u16 netfid; | ||
844 | __u8 type; | ||
845 | |||
846 | rc = -EACCES; | ||
847 | xid = GetXid(); | ||
848 | |||
849 | cFYI(1, "Lock parm: 0x%x flockflags: 0x%x flocktype: 0x%x start: %lld " | ||
850 | "end: %lld", cmd, flock->fl_flags, flock->fl_type, | ||
851 | flock->fl_start, flock->fl_end); | ||
852 | |||
853 | cifs_read_flock(flock, &type, &lock, &unlock, &wait_flag); | ||
854 | |||
855 | cifs_sb = CIFS_SB(file->f_path.dentry->d_sb); | ||
856 | cfile = (struct cifsFileInfo *)file->private_data; | ||
857 | tcon = tlink_tcon(cfile->tlink); | ||
858 | netfid = cfile->netfid; | ||
859 | cinode = CIFS_I(file->f_path.dentry->d_inode); | ||
860 | |||
861 | if ((tcon->ses->capabilities & CAP_UNIX) && | ||
862 | (CIFS_UNIX_FCNTL_CAP & le64_to_cpu(tcon->fsUnixInfo.Capability)) && | ||
863 | ((cifs_sb->mnt_cifs_flags & CIFS_MOUNT_NOPOSIXBRL) == 0)) | ||
864 | posix_lck = true; | ||
865 | /* | ||
866 | * BB add code here to normalize offset and length to account for | ||
867 | * negative length which we can not accept over the wire. | ||
868 | */ | ||
869 | if (IS_GETLK(cmd)) { | ||
870 | rc = cifs_getlk(cfile, flock, type, wait_flag, posix_lck, xid); | ||
871 | FreeXid(xid); | ||
872 | return rc; | ||
873 | } | ||
874 | |||
875 | if (!lock && !unlock) { | ||
876 | /* | ||
877 | * if no lock or unlock then nothing to do since we do not | ||
878 | * know what it is | ||
879 | */ | ||
880 | FreeXid(xid); | ||
881 | return -EOPNOTSUPP; | ||
851 | } | 882 | } |
852 | 883 | ||
853 | if (pfLock->fl_flags & FL_POSIX) | 884 | rc = cifs_setlk(file, flock, type, wait_flag, posix_lck, lock, unlock, |
854 | posix_lock_file_wait(file, pfLock); | 885 | xid); |
855 | FreeXid(xid); | 886 | FreeXid(xid); |
856 | return rc; | 887 | return rc; |
857 | } | 888 | } |
@@ -2423,8 +2454,9 @@ void cifs_oplock_break(struct work_struct *work) | |||
2423 | * disconnected since oplock already released by the server | 2454 | * disconnected since oplock already released by the server |
2424 | */ | 2455 | */ |
2425 | if (!cfile->oplock_break_cancelled) { | 2456 | if (!cfile->oplock_break_cancelled) { |
2426 | rc = CIFSSMBLock(0, tlink_tcon(cfile->tlink), cfile->netfid, 0, | 2457 | rc = CIFSSMBLock(0, tlink_tcon(cfile->tlink), cfile->netfid, |
2427 | 0, 0, 0, LOCKING_ANDX_OPLOCK_RELEASE, false, | 2458 | current->tgid, 0, 0, 0, 0, |
2459 | LOCKING_ANDX_OPLOCK_RELEASE, false, | ||
2428 | cinode->clientCanCacheRead ? 1 : 0); | 2460 | cinode->clientCanCacheRead ? 1 : 0); |
2429 | cFYI(1, "Oplock release rc = %d", rc); | 2461 | cFYI(1, "Oplock release rc = %d", rc); |
2430 | } | 2462 | } |