aboutsummaryrefslogtreecommitdiffstats
path: root/fs/cifs/file.c
diff options
context:
space:
mode:
Diffstat (limited to 'fs/cifs/file.c')
-rw-r--r--fs/cifs/file.c67
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)
577int cifs_lock(struct file *file, int cmd, struct file_lock *pfLock) 577int 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);