diff options
-rw-r--r-- | fs/cifs/CHANGES | 6 | ||||
-rw-r--r-- | fs/cifs/README | 12 | ||||
-rw-r--r-- | fs/cifs/cifs_fs_sb.h | 5 | ||||
-rw-r--r-- | fs/cifs/cifsfs.h | 2 | ||||
-rw-r--r-- | fs/cifs/connect.c | 14 | ||||
-rw-r--r-- | fs/cifs/file.c | 25 |
6 files changed, 48 insertions, 16 deletions
diff --git a/fs/cifs/CHANGES b/fs/cifs/CHANGES index e078b7aea143..3d848f463c44 100644 --- a/fs/cifs/CHANGES +++ b/fs/cifs/CHANGES | |||
@@ -1,3 +1,9 @@ | |||
1 | Version 1.56 | ||
2 | ------------ | ||
3 | Add "forcemandatorylock" mount option to allow user to use mandatory | ||
4 | rather than posix (advisory) byte range locks, even though server would | ||
5 | support posix byte range locks. | ||
6 | |||
1 | Version 1.55 | 7 | Version 1.55 |
2 | ------------ | 8 | ------------ |
3 | Various fixes to make delete of open files behavior more predictable | 9 | Various fixes to make delete of open files behavior more predictable |
diff --git a/fs/cifs/README b/fs/cifs/README index a439dc1739b3..da4515e3be20 100644 --- a/fs/cifs/README +++ b/fs/cifs/README | |||
@@ -463,9 +463,19 @@ A partial list of the supported mount options follows: | |||
463 | with cifs style mandatory byte range locks (and most | 463 | with cifs style mandatory byte range locks (and most |
464 | cifs servers do not yet support requesting advisory | 464 | cifs servers do not yet support requesting advisory |
465 | byte range locks). | 465 | byte range locks). |
466 | forcemandatorylock Even if the server supports posix (advisory) byte range | ||
467 | locking, send only mandatory lock requests. For some | ||
468 | (presumably rare) applications, originally coded for | ||
469 | DOS/Windows, which require Windows style mandatory byte range | ||
470 | locking, they may be able to take advantage of this option, | ||
471 | forcing the cifs client to only send mandatory locks | ||
472 | even if the cifs server would support posix advisory locks. | ||
473 | "forcemand" is accepted as a shorter form of this mount | ||
474 | option. | ||
466 | nodfs Disable DFS (global name space support) even if the | 475 | nodfs Disable DFS (global name space support) even if the |
467 | server claims to support it. This can help work around | 476 | server claims to support it. This can help work around |
468 | a problem with parsing of DFS paths with Samba 3.0.24 server. | 477 | a problem with parsing of DFS paths with Samba server |
478 | versions 3.0.24 and 3.0.25. | ||
469 | remount remount the share (often used to change from ro to rw mounts | 479 | remount remount the share (often used to change from ro to rw mounts |
470 | or vice versa) | 480 | or vice versa) |
471 | cifsacl Report mode bits (e.g. on stat) based on the Windows ACL for | 481 | cifsacl Report mode bits (e.g. on stat) based on the Windows ACL for |
diff --git a/fs/cifs/cifs_fs_sb.h b/fs/cifs/cifs_fs_sb.h index 877c85409f1f..5edd5cc415aa 100644 --- a/fs/cifs/cifs_fs_sb.h +++ b/fs/cifs/cifs_fs_sb.h | |||
@@ -20,7 +20,7 @@ | |||
20 | 20 | ||
21 | #define CIFS_MOUNT_NO_PERM 1 /* do not do client vfs_perm check */ | 21 | #define CIFS_MOUNT_NO_PERM 1 /* do not do client vfs_perm check */ |
22 | #define CIFS_MOUNT_SET_UID 2 /* set current->euid in create etc. */ | 22 | #define CIFS_MOUNT_SET_UID 2 /* set current->euid in create etc. */ |
23 | #define CIFS_MOUNT_SERVER_INUM 4 /* inode numbers from uniqueid from server */ | 23 | #define CIFS_MOUNT_SERVER_INUM 4 /* inode numbers from uniqueid from server */ |
24 | #define CIFS_MOUNT_DIRECT_IO 8 /* do not write nor read through page cache */ | 24 | #define CIFS_MOUNT_DIRECT_IO 8 /* do not write nor read through page cache */ |
25 | #define CIFS_MOUNT_NO_XATTR 0x10 /* if set - disable xattr support */ | 25 | #define CIFS_MOUNT_NO_XATTR 0x10 /* if set - disable xattr support */ |
26 | #define CIFS_MOUNT_MAP_SPECIAL_CHR 0x20 /* remap illegal chars in filenames */ | 26 | #define CIFS_MOUNT_MAP_SPECIAL_CHR 0x20 /* remap illegal chars in filenames */ |
@@ -30,7 +30,8 @@ | |||
30 | #define CIFS_MOUNT_CIFS_ACL 0x200 /* send ACL requests to non-POSIX srv */ | 30 | #define CIFS_MOUNT_CIFS_ACL 0x200 /* send ACL requests to non-POSIX srv */ |
31 | #define CIFS_MOUNT_OVERR_UID 0x400 /* override uid returned from server */ | 31 | #define CIFS_MOUNT_OVERR_UID 0x400 /* override uid returned from server */ |
32 | #define CIFS_MOUNT_OVERR_GID 0x800 /* override gid returned from server */ | 32 | #define CIFS_MOUNT_OVERR_GID 0x800 /* override gid returned from server */ |
33 | #define CIFS_MOUNT_DYNPERM 0x1000 /* allow in-memory only mode setting */ | 33 | #define CIFS_MOUNT_DYNPERM 0x1000 /* allow in-memory only mode setting */ |
34 | #define CIFS_MOUNT_NOPOSIXBRL 0x2000 /* mandatory not posix byte range lock */ | ||
34 | 35 | ||
35 | struct cifs_sb_info { | 36 | struct cifs_sb_info { |
36 | struct cifsTconInfo *tcon; /* primary mount */ | 37 | struct cifsTconInfo *tcon; /* primary mount */ |
diff --git a/fs/cifs/cifsfs.h b/fs/cifs/cifsfs.h index 074de0b5064d..fb676076946b 100644 --- a/fs/cifs/cifsfs.h +++ b/fs/cifs/cifsfs.h | |||
@@ -101,5 +101,5 @@ extern long cifs_ioctl(struct file *filep, unsigned int cmd, unsigned long arg); | |||
101 | extern const struct export_operations cifs_export_ops; | 101 | extern const struct export_operations cifs_export_ops; |
102 | #endif /* EXPERIMENTAL */ | 102 | #endif /* EXPERIMENTAL */ |
103 | 103 | ||
104 | #define CIFS_VERSION "1.55" | 104 | #define CIFS_VERSION "1.5666666" |
105 | #endif /* _CIFSFS_H */ | 105 | #endif /* _CIFSFS_H */ |
diff --git a/fs/cifs/connect.c b/fs/cifs/connect.c index d6a3c1c8a6f8..351942042833 100644 --- a/fs/cifs/connect.c +++ b/fs/cifs/connect.c | |||
@@ -89,6 +89,7 @@ struct smb_vol { | |||
89 | bool nullauth:1; /* attempt to authenticate with null user */ | 89 | bool nullauth:1; /* attempt to authenticate with null user */ |
90 | bool nocase:1; /* request case insensitive filenames */ | 90 | bool nocase:1; /* request case insensitive filenames */ |
91 | bool nobrl:1; /* disable sending byte range locks to srv */ | 91 | bool nobrl:1; /* disable sending byte range locks to srv */ |
92 | bool mand_lock:1; /* send mandatory not posix byte range lock reqs */ | ||
92 | bool seal:1; /* request transport encryption on share */ | 93 | bool seal:1; /* request transport encryption on share */ |
93 | bool nodfs:1; /* Do not request DFS, even if available */ | 94 | bool nodfs:1; /* Do not request DFS, even if available */ |
94 | bool local_lease:1; /* check leases only on local system, not remote */ | 95 | bool local_lease:1; /* check leases only on local system, not remote */ |
@@ -1246,6 +1247,17 @@ cifs_parse_mount_options(char *options, const char *devname, | |||
1246 | if (vol->file_mode == | 1247 | if (vol->file_mode == |
1247 | (S_IALLUGO & ~(S_ISUID | S_IXGRP))) | 1248 | (S_IALLUGO & ~(S_ISUID | S_IXGRP))) |
1248 | vol->file_mode = S_IALLUGO; | 1249 | vol->file_mode = S_IALLUGO; |
1250 | } else if (strnicmp(data, "forcemandatorylock", 9) == 0) { | ||
1251 | /* will take the shorter form "forcemand" as well */ | ||
1252 | /* This mount option will force use of mandatory | ||
1253 | (DOS/Windows style) byte range locks, instead of | ||
1254 | using posix advisory byte range locks, even if the | ||
1255 | Unix extensions are available and posix locks would | ||
1256 | be supported otherwise. If Unix extensions are not | ||
1257 | negotiated this has no effect since mandatory locks | ||
1258 | would be used (mandatory locks is all that those | ||
1259 | those servers support) */ | ||
1260 | vol->mand_lock = 1; | ||
1249 | } else if (strnicmp(data, "setuids", 7) == 0) { | 1261 | } else if (strnicmp(data, "setuids", 7) == 0) { |
1250 | vol->setuids = 1; | 1262 | vol->setuids = 1; |
1251 | } else if (strnicmp(data, "nosetuids", 9) == 0) { | 1263 | } else if (strnicmp(data, "nosetuids", 9) == 0) { |
@@ -2150,6 +2162,8 @@ static void setup_cifs_sb(struct smb_vol *pvolume_info, | |||
2150 | cifs_sb->mnt_cifs_flags |= CIFS_MOUNT_UNX_EMUL; | 2162 | cifs_sb->mnt_cifs_flags |= CIFS_MOUNT_UNX_EMUL; |
2151 | if (pvolume_info->nobrl) | 2163 | if (pvolume_info->nobrl) |
2152 | cifs_sb->mnt_cifs_flags |= CIFS_MOUNT_NO_BRL; | 2164 | cifs_sb->mnt_cifs_flags |= CIFS_MOUNT_NO_BRL; |
2165 | if (pvolume_info->mand_lock) | ||
2166 | cifs_sb->mnt_cifs_flags |= CIFS_MOUNT_NOPOSIXBRL; | ||
2153 | if (pvolume_info->cifs_acl) | 2167 | if (pvolume_info->cifs_acl) |
2154 | cifs_sb->mnt_cifs_flags |= CIFS_MOUNT_CIFS_ACL; | 2168 | cifs_sb->mnt_cifs_flags |= CIFS_MOUNT_CIFS_ACL; |
2155 | if (pvolume_info->override_uid) | 2169 | if (pvolume_info->override_uid) |
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); |