diff options
Diffstat (limited to 'fs/cifs/file.c')
-rw-r--r-- | fs/cifs/file.c | 67 |
1 files changed, 48 insertions, 19 deletions
diff --git a/fs/cifs/file.c b/fs/cifs/file.c index e5bf1ad540d9..bd135c4e4958 100644 --- a/fs/cifs/file.c +++ b/fs/cifs/file.c | |||
@@ -577,13 +577,14 @@ int cifs_closedir(struct inode *inode, struct file *file) | |||
577 | int cifs_lock(struct file *file, int cmd, struct file_lock *pfLock) | 577 | int cifs_lock(struct file *file, int cmd, struct file_lock *pfLock) |
578 | { | 578 | { |
579 | int rc, xid; | 579 | int rc, xid; |
580 | __u32 lockType = LOCKING_ANDX_LARGE_FILES; | ||
581 | __u32 numLock = 0; | 580 | __u32 numLock = 0; |
582 | __u32 numUnlock = 0; | 581 | __u32 numUnlock = 0; |
583 | __u64 length; | 582 | __u64 length; |
584 | int wait_flag = FALSE; | 583 | int wait_flag = FALSE; |
585 | struct cifs_sb_info *cifs_sb; | 584 | struct cifs_sb_info *cifs_sb; |
586 | struct cifsTconInfo *pTcon; | 585 | struct cifsTconInfo *pTcon; |
586 | __u16 netfid; | ||
587 | __u8 lockType = LOCKING_ANDX_LARGE_FILES; | ||
587 | 588 | ||
588 | length = 1 + pfLock->fl_end - pfLock->fl_start; | 589 | length = 1 + pfLock->fl_end - pfLock->fl_start; |
589 | rc = -EACCES; | 590 | rc = -EACCES; |
@@ -640,27 +641,39 @@ int cifs_lock(struct file *file, int cmd, struct file_lock *pfLock) | |||
640 | FreeXid(xid); | 641 | FreeXid(xid); |
641 | return -EBADF; | 642 | return -EBADF; |
642 | } | 643 | } |
644 | netfid = ((struct cifsFileInfo *)file->private_data)->netfid; | ||
645 | |||
643 | 646 | ||
647 | /* BB add code here to normalize offset and length to | ||
648 | account for negative length which we can not accept over the | ||
649 | wire */ | ||
644 | if (IS_GETLK(cmd)) { | 650 | if (IS_GETLK(cmd)) { |
645 | rc = CIFSSMBLock(xid, pTcon, | 651 | if(experimEnabled && |
646 | ((struct cifsFileInfo *)file-> | 652 | (cifs_sb->tcon->ses->capabilities & CAP_UNIX)) { |
647 | private_data)->netfid, | 653 | int posix_lock_type; |
648 | length, | 654 | if(lockType & LOCKING_ANDX_SHARED_LOCK) |
649 | pfLock->fl_start, 0, 1, lockType, | 655 | posix_lock_type = CIFS_RDLCK; |
650 | 0 /* wait flag */ ); | 656 | else |
657 | posix_lock_type = CIFS_WRLCK; | ||
658 | rc = CIFSSMBPosixLock(xid, pTcon, netfid, 1 /* get */, | ||
659 | length, pfLock->fl_start, | ||
660 | posix_lock_type, wait_flag); | ||
661 | FreeXid(xid); | ||
662 | return rc; | ||
663 | } | ||
664 | |||
665 | /* BB we could chain these into one lock request BB */ | ||
666 | rc = CIFSSMBLock(xid, pTcon, netfid, length, pfLock->fl_start, | ||
667 | 0, 1, lockType, 0 /* wait flag */ ); | ||
651 | if (rc == 0) { | 668 | if (rc == 0) { |
652 | rc = CIFSSMBLock(xid, pTcon, | 669 | rc = CIFSSMBLock(xid, pTcon, netfid, length, |
653 | ((struct cifsFileInfo *) file-> | ||
654 | private_data)->netfid, | ||
655 | length, | ||
656 | pfLock->fl_start, 1 /* numUnlock */ , | 670 | pfLock->fl_start, 1 /* numUnlock */ , |
657 | 0 /* numLock */ , lockType, | 671 | 0 /* numLock */ , lockType, |
658 | 0 /* wait flag */ ); | 672 | 0 /* wait flag */ ); |
659 | pfLock->fl_type = F_UNLCK; | 673 | pfLock->fl_type = F_UNLCK; |
660 | if (rc != 0) | 674 | if (rc != 0) |
661 | cERROR(1, ("Error unlocking previously locked " | 675 | cERROR(1, ("Error unlocking previously locked " |
662 | "range %d during test of lock ", | 676 | "range %d during test of lock", rc)); |
663 | rc)); | ||
664 | rc = 0; | 677 | rc = 0; |
665 | 678 | ||
666 | } else { | 679 | } else { |
@@ -672,12 +685,28 @@ int cifs_lock(struct file *file, int cmd, struct file_lock *pfLock) | |||
672 | FreeXid(xid); | 685 | FreeXid(xid); |
673 | return rc; | 686 | return rc; |
674 | } | 687 | } |
675 | 688 | if (experimEnabled && | |
676 | rc = CIFSSMBLock(xid, pTcon, | 689 | (cifs_sb->tcon->ses->capabilities & CAP_UNIX)) { |
677 | ((struct cifsFileInfo *) file->private_data)-> | 690 | int posix_lock_type; |
678 | netfid, length, | 691 | if(lockType & LOCKING_ANDX_SHARED_LOCK) |
679 | pfLock->fl_start, numUnlock, numLock, lockType, | 692 | posix_lock_type = CIFS_RDLCK; |
680 | wait_flag); | 693 | else |
694 | posix_lock_type = CIFS_WRLCK; | ||
695 | |||
696 | if(numUnlock == 1) | ||
697 | posix_lock_type |= CIFS_UNLCK; | ||
698 | else if(numLock == 0) { | ||
699 | /* if no lock or unlock then nothing | ||
700 | to do since we do not know what it is */ | ||
701 | FreeXid(xid); | ||
702 | return -EOPNOTSUPP; | ||
703 | } | ||
704 | rc = CIFSSMBPosixLock(xid, pTcon, netfid, 0 /* set */, | ||
705 | length, pfLock->fl_start, | ||
706 | posix_lock_type, wait_flag); | ||
707 | } else | ||
708 | rc = CIFSSMBLock(xid, pTcon, netfid, length, pfLock->fl_start, | ||
709 | numUnlock, numLock, lockType, wait_flag); | ||
681 | if (pfLock->fl_flags & FL_POSIX) | 710 | if (pfLock->fl_flags & FL_POSIX) |
682 | posix_lock_file_wait(file, pfLock); | 711 | posix_lock_file_wait(file, pfLock); |
683 | FreeXid(xid); | 712 | FreeXid(xid); |