aboutsummaryrefslogtreecommitdiffstats
path: root/fs/cifs/file.c
diff options
context:
space:
mode:
authorSteve French <sfrench@us.ibm.com>2008-12-02 12:24:33 -0500
committerSteve French <sfrench@us.ibm.com>2008-12-25 21:29:10 -0500
commit13a6e42af8d90e2e8eb7fa50adf862a525b70518 (patch)
tree5d6021da7bc49b75cca5a0947f89bde7233ebce4 /fs/cifs/file.c
parentd5c5605c27c92dac6de1a7a658af5b030847f949 (diff)
[CIFS] add mount option to send mandatory rather than advisory locks
Some applications/subsystems require mandatory byte range locks (as is used for Windows/DOS/OS2 etc). Sending advisory (posix style) byte range lock requests (instead of mandatory byte range locks) can lead to problems for these applications (which expect that other clients be prevented from writing to portions of the file which they have locked and are updating). This mount option allows mounting cifs with the new mount option "forcemand" (or "forcemandatorylock") in order to have the cifs client use mandatory byte range locks (ie SMB/CIFS/Windows/NTFS style locks) rather than posix byte range lock requests, even if the server would support posix byte range lock requests. This has no effect if the server does not support the CIFS Unix Extensions (since posix style locks require support for the CIFS Unix Extensions), but for mounts to Samba servers this can be helpful for Wine and applications that require mandatory byte range locks. Acked-by: Jeff Layton <jlayton@redhat.com> CC: Alexander Bokovoy <ab@samba.org> Signed-off-by: Steve French <sfrench@us.ibm.com>
Diffstat (limited to 'fs/cifs/file.c')
-rw-r--r--fs/cifs/file.c25
1 files changed, 13 insertions, 12 deletions
diff --git a/fs/cifs/file.c b/fs/cifs/file.c
index f0a81e631ae6..babd27a4699a 100644
--- a/fs/cifs/file.c
+++ b/fs/cifs/file.c
@@ -644,10 +644,10 @@ int cifs_lock(struct file *file, int cmd, struct file_lock *pfLock)
644 __u64 length; 644 __u64 length;
645 bool wait_flag = false; 645 bool wait_flag = false;
646 struct cifs_sb_info *cifs_sb; 646 struct cifs_sb_info *cifs_sb;
647 struct cifsTconInfo *pTcon; 647 struct cifsTconInfo *tcon;
648 __u16 netfid; 648 __u16 netfid;
649 __u8 lockType = LOCKING_ANDX_LARGE_FILES; 649 __u8 lockType = LOCKING_ANDX_LARGE_FILES;
650 bool posix_locking; 650 bool posix_locking = 0;
651 651
652 length = 1 + pfLock->fl_end - pfLock->fl_start; 652 length = 1 + pfLock->fl_end - pfLock->fl_start;
653 rc = -EACCES; 653 rc = -EACCES;
@@ -698,7 +698,7 @@ int cifs_lock(struct file *file, int cmd, struct file_lock *pfLock)
698 cFYI(1, ("Unknown type of lock")); 698 cFYI(1, ("Unknown type of lock"));
699 699
700 cifs_sb = CIFS_SB(file->f_path.dentry->d_sb); 700 cifs_sb = CIFS_SB(file->f_path.dentry->d_sb);
701 pTcon = cifs_sb->tcon; 701 tcon = cifs_sb->tcon;
702 702
703 if (file->private_data == NULL) { 703 if (file->private_data == NULL) {
704 FreeXid(xid); 704 FreeXid(xid);
@@ -706,9 +706,10 @@ int cifs_lock(struct file *file, int cmd, struct file_lock *pfLock)
706 } 706 }
707 netfid = ((struct cifsFileInfo *)file->private_data)->netfid; 707 netfid = ((struct cifsFileInfo *)file->private_data)->netfid;
708 708
709 posix_locking = (cifs_sb->tcon->ses->capabilities & CAP_UNIX) && 709 if ((tcon->ses->capabilities & CAP_UNIX) &&
710 (CIFS_UNIX_FCNTL_CAP & le64_to_cpu(cifs_sb->tcon->fsUnixInfo.Capability)); 710 (CIFS_UNIX_FCNTL_CAP & le64_to_cpu(tcon->fsUnixInfo.Capability)) &&
711 711 (cifs_sb->mnt_cifs_flags & CIFS_MOUNT_NOPOSIXBRL == 0))
712 posix_locking = 1;
712 /* BB add code here to normalize offset and length to 713 /* BB add code here to normalize offset and length to
713 account for negative length which we can not accept over the 714 account for negative length which we can not accept over the
714 wire */ 715 wire */
@@ -719,7 +720,7 @@ int cifs_lock(struct file *file, int cmd, struct file_lock *pfLock)
719 posix_lock_type = CIFS_RDLCK; 720 posix_lock_type = CIFS_RDLCK;
720 else 721 else
721 posix_lock_type = CIFS_WRLCK; 722 posix_lock_type = CIFS_WRLCK;
722 rc = CIFSSMBPosixLock(xid, pTcon, netfid, 1 /* get */, 723 rc = CIFSSMBPosixLock(xid, tcon, netfid, 1 /* get */,
723 length, pfLock, 724 length, pfLock,
724 posix_lock_type, wait_flag); 725 posix_lock_type, wait_flag);
725 FreeXid(xid); 726 FreeXid(xid);
@@ -727,10 +728,10 @@ int cifs_lock(struct file *file, int cmd, struct file_lock *pfLock)
727 } 728 }
728 729
729 /* BB we could chain these into one lock request BB */ 730 /* BB we could chain these into one lock request BB */
730 rc = CIFSSMBLock(xid, pTcon, netfid, length, pfLock->fl_start, 731 rc = CIFSSMBLock(xid, tcon, netfid, length, pfLock->fl_start,
731 0, 1, lockType, 0 /* wait flag */ ); 732 0, 1, lockType, 0 /* wait flag */ );
732 if (rc == 0) { 733 if (rc == 0) {
733 rc = CIFSSMBLock(xid, pTcon, netfid, length, 734 rc = CIFSSMBLock(xid, tcon, netfid, length,
734 pfLock->fl_start, 1 /* numUnlock */ , 735 pfLock->fl_start, 1 /* numUnlock */ ,
735 0 /* numLock */ , lockType, 736 0 /* numLock */ , lockType,
736 0 /* wait flag */ ); 737 0 /* wait flag */ );
@@ -767,7 +768,7 @@ int cifs_lock(struct file *file, int cmd, struct file_lock *pfLock)
767 if (numUnlock == 1) 768 if (numUnlock == 1)
768 posix_lock_type = CIFS_UNLCK; 769 posix_lock_type = CIFS_UNLCK;
769 770
770 rc = CIFSSMBPosixLock(xid, pTcon, netfid, 0 /* set */, 771 rc = CIFSSMBPosixLock(xid, tcon, netfid, 0 /* set */,
771 length, pfLock, 772 length, pfLock,
772 posix_lock_type, wait_flag); 773 posix_lock_type, wait_flag);
773 } else { 774 } else {
@@ -775,7 +776,7 @@ int cifs_lock(struct file *file, int cmd, struct file_lock *pfLock)
775 (struct cifsFileInfo *)file->private_data; 776 (struct cifsFileInfo *)file->private_data;
776 777
777 if (numLock) { 778 if (numLock) {
778 rc = CIFSSMBLock(xid, pTcon, netfid, length, 779 rc = CIFSSMBLock(xid, tcon, netfid, length,
779 pfLock->fl_start, 780 pfLock->fl_start,
780 0, numLock, lockType, wait_flag); 781 0, numLock, lockType, wait_flag);
781 782
@@ -796,7 +797,7 @@ int cifs_lock(struct file *file, int cmd, struct file_lock *pfLock)
796 if (pfLock->fl_start <= li->offset && 797 if (pfLock->fl_start <= li->offset &&
797 (pfLock->fl_start + length) >= 798 (pfLock->fl_start + length) >=
798 (li->offset + li->length)) { 799 (li->offset + li->length)) {
799 stored_rc = CIFSSMBLock(xid, pTcon, 800 stored_rc = CIFSSMBLock(xid, tcon,
800 netfid, 801 netfid,
801 li->length, li->offset, 802 li->length, li->offset,
802 1, 0, li->type, false); 803 1, 0, li->type, false);