aboutsummaryrefslogtreecommitdiffstats
path: root/fs/cifs/file.c
diff options
context:
space:
mode:
authorSteve French <sfrench@us.ibm.com>2006-02-28 17:39:25 -0500
committerSteve French <sfrench@us.ibm.com>2006-02-28 17:39:25 -0500
commit08547b036b8445e2318e14f1f03308105b01fc5b (patch)
tree1e153a255d1485aba7de50f862d23c674d3c9e97 /fs/cifs/file.c
parentd47d7c1a850b867047fe17140fabd0376894e849 (diff)
[CIFS] Add posix (advisory) byte range locking support to cifs client
Samba (version 3) server support for this is also currently being done. This client code is in an experimental path (requires enabling /proc/fs/cifs/Experimental) while it is being tested. Signed-off-by: Steve French <sfrench@us.ibm.com>
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);