aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorPavel Shilovsky <piastry@etersoft.ru>2012-02-28 06:23:34 -0500
committerSteve French <sfrench@us.ibm.com>2012-05-16 21:13:36 -0400
commit106dc538abac88e804c63b7fe21ffb09cffaefc7 (patch)
treef3c4a0075e09c852b42a6f265a4dea42761352ed
parent04a6aa8acfac51385ec3e72fac1227e15db78ed9 (diff)
CIFS: Separate protocol specific lock type handling
Signed-off-by: Pavel Shilovsky <piastry@etersoft.ru>
-rw-r--r--fs/cifs/cifsglob.h4
-rw-r--r--fs/cifs/file.c40
-rw-r--r--fs/cifs/smb1ops.c5
3 files changed, 33 insertions, 16 deletions
diff --git a/fs/cifs/cifsglob.h b/fs/cifs/cifsglob.h
index 0e06de16f34e..6943448c57e2 100644
--- a/fs/cifs/cifsglob.h
+++ b/fs/cifs/cifsglob.h
@@ -164,6 +164,10 @@ struct smb_version_operations {
164 164
165struct smb_version_values { 165struct smb_version_values {
166 char *version_string; 166 char *version_string;
167 __u32 large_lock_type;
168 __u32 exclusive_lock_type;
169 __u32 shared_lock_type;
170 __u32 unlock_lock_type;
167}; 171};
168 172
169struct smb_vol { 173struct smb_vol {
diff --git a/fs/cifs/file.c b/fs/cifs/file.c
index 8d5d9c04cd78..ac71f85cff72 100644
--- a/fs/cifs/file.c
+++ b/fs/cifs/file.c
@@ -675,12 +675,13 @@ cifs_find_fid_lock_conflict(struct cifsFileInfo *cfile, __u64 offset,
675 struct cifsLockInfo **conf_lock) 675 struct cifsLockInfo **conf_lock)
676{ 676{
677 struct cifsLockInfo *li; 677 struct cifsLockInfo *li;
678 struct TCP_Server_Info *server = tlink_tcon(cfile->tlink)->ses->server;
678 679
679 list_for_each_entry(li, &cfile->llist, llist) { 680 list_for_each_entry(li, &cfile->llist, llist) {
680 if (offset + length <= li->offset || 681 if (offset + length <= li->offset ||
681 offset >= li->offset + li->length) 682 offset >= li->offset + li->length)
682 continue; 683 continue;
683 else if ((type & LOCKING_ANDX_SHARED_LOCK) && 684 else if ((type & server->vals->shared_lock_type) &&
684 ((netfid == cfile->netfid && current->tgid == li->pid) 685 ((netfid == cfile->netfid && current->tgid == li->pid)
685 || type == li->type)) 686 || type == li->type))
686 continue; 687 continue;
@@ -726,6 +727,7 @@ cifs_lock_test(struct cifsFileInfo *cfile, __u64 offset, __u64 length,
726 int rc = 0; 727 int rc = 0;
727 struct cifsLockInfo *conf_lock; 728 struct cifsLockInfo *conf_lock;
728 struct cifsInodeInfo *cinode = CIFS_I(cfile->dentry->d_inode); 729 struct cifsInodeInfo *cinode = CIFS_I(cfile->dentry->d_inode);
730 struct TCP_Server_Info *server = tlink_tcon(cfile->tlink)->ses->server;
729 bool exist; 731 bool exist;
730 732
731 mutex_lock(&cinode->lock_mutex); 733 mutex_lock(&cinode->lock_mutex);
@@ -736,7 +738,7 @@ cifs_lock_test(struct cifsFileInfo *cfile, __u64 offset, __u64 length,
736 flock->fl_start = conf_lock->offset; 738 flock->fl_start = conf_lock->offset;
737 flock->fl_end = conf_lock->offset + conf_lock->length - 1; 739 flock->fl_end = conf_lock->offset + conf_lock->length - 1;
738 flock->fl_pid = conf_lock->pid; 740 flock->fl_pid = conf_lock->pid;
739 if (conf_lock->type & LOCKING_ANDX_SHARED_LOCK) 741 if (conf_lock->type & server->vals->shared_lock_type)
740 flock->fl_type = F_RDLCK; 742 flock->fl_type = F_RDLCK;
741 else 743 else
742 flock->fl_type = F_WRLCK; 744 flock->fl_type = F_WRLCK;
@@ -1069,7 +1071,7 @@ cifs_push_locks(struct cifsFileInfo *cfile)
1069 1071
1070static void 1072static void
1071cifs_read_flock(struct file_lock *flock, __u32 *type, int *lock, int *unlock, 1073cifs_read_flock(struct file_lock *flock, __u32 *type, int *lock, int *unlock,
1072 bool *wait_flag) 1074 bool *wait_flag, struct TCP_Server_Info *server)
1073{ 1075{
1074 if (flock->fl_flags & FL_POSIX) 1076 if (flock->fl_flags & FL_POSIX)
1075 cFYI(1, "Posix"); 1077 cFYI(1, "Posix");
@@ -1088,24 +1090,27 @@ cifs_read_flock(struct file_lock *flock, __u32 *type, int *lock, int *unlock,
1088 (~(FL_POSIX | FL_FLOCK | FL_SLEEP | FL_ACCESS | FL_LEASE))) 1090 (~(FL_POSIX | FL_FLOCK | FL_SLEEP | FL_ACCESS | FL_LEASE)))
1089 cFYI(1, "Unknown lock flags 0x%x", flock->fl_flags); 1091 cFYI(1, "Unknown lock flags 0x%x", flock->fl_flags);
1090 1092
1091 *type = LOCKING_ANDX_LARGE_FILES; 1093 *type = server->vals->large_lock_type;
1092 if (flock->fl_type == F_WRLCK) { 1094 if (flock->fl_type == F_WRLCK) {
1093 cFYI(1, "F_WRLCK "); 1095 cFYI(1, "F_WRLCK ");
1096 *type |= server->vals->exclusive_lock_type;
1094 *lock = 1; 1097 *lock = 1;
1095 } else if (flock->fl_type == F_UNLCK) { 1098 } else if (flock->fl_type == F_UNLCK) {
1096 cFYI(1, "F_UNLCK"); 1099 cFYI(1, "F_UNLCK");
1100 *type |= server->vals->unlock_lock_type;
1097 *unlock = 1; 1101 *unlock = 1;
1098 /* Check if unlock includes more than one lock range */ 1102 /* Check if unlock includes more than one lock range */
1099 } else if (flock->fl_type == F_RDLCK) { 1103 } else if (flock->fl_type == F_RDLCK) {
1100 cFYI(1, "F_RDLCK"); 1104 cFYI(1, "F_RDLCK");
1101 *type |= LOCKING_ANDX_SHARED_LOCK; 1105 *type |= server->vals->shared_lock_type;
1102 *lock = 1; 1106 *lock = 1;
1103 } else if (flock->fl_type == F_EXLCK) { 1107 } else if (flock->fl_type == F_EXLCK) {
1104 cFYI(1, "F_EXLCK"); 1108 cFYI(1, "F_EXLCK");
1109 *type |= server->vals->exclusive_lock_type;
1105 *lock = 1; 1110 *lock = 1;
1106 } else if (flock->fl_type == F_SHLCK) { 1111 } else if (flock->fl_type == F_SHLCK) {
1107 cFYI(1, "F_SHLCK"); 1112 cFYI(1, "F_SHLCK");
1108 *type |= LOCKING_ANDX_SHARED_LOCK; 1113 *type |= server->vals->shared_lock_type;
1109 *lock = 1; 1114 *lock = 1;
1110 } else 1115 } else
1111 cFYI(1, "Unknown type of lock"); 1116 cFYI(1, "Unknown type of lock");
@@ -1119,6 +1124,7 @@ cifs_getlk(struct file *file, struct file_lock *flock, __u32 type,
1119 __u64 length = 1 + flock->fl_end - flock->fl_start; 1124 __u64 length = 1 + flock->fl_end - flock->fl_start;
1120 struct cifsFileInfo *cfile = (struct cifsFileInfo *)file->private_data; 1125 struct cifsFileInfo *cfile = (struct cifsFileInfo *)file->private_data;
1121 struct cifs_tcon *tcon = tlink_tcon(cfile->tlink); 1126 struct cifs_tcon *tcon = tlink_tcon(cfile->tlink);
1127 struct TCP_Server_Info *server = tcon->ses->server;
1122 __u16 netfid = cfile->netfid; 1128 __u16 netfid = cfile->netfid;
1123 1129
1124 if (posix_lck) { 1130 if (posix_lck) {
@@ -1128,7 +1134,7 @@ cifs_getlk(struct file *file, struct file_lock *flock, __u32 type,
1128 if (!rc) 1134 if (!rc)
1129 return rc; 1135 return rc;
1130 1136
1131 if (type & LOCKING_ANDX_SHARED_LOCK) 1137 if (type & server->vals->shared_lock_type)
1132 posix_lock_type = CIFS_RDLCK; 1138 posix_lock_type = CIFS_RDLCK;
1133 else 1139 else
1134 posix_lock_type = CIFS_WRLCK; 1140 posix_lock_type = CIFS_WRLCK;
@@ -1152,23 +1158,22 @@ cifs_getlk(struct file *file, struct file_lock *flock, __u32 type,
1152 flock->fl_type = F_UNLCK; 1158 flock->fl_type = F_UNLCK;
1153 if (rc != 0) 1159 if (rc != 0)
1154 cERROR(1, "Error unlocking previously locked " 1160 cERROR(1, "Error unlocking previously locked "
1155 "range %d during test of lock", rc); 1161 "range %d during test of lock", rc);
1156 return 0; 1162 return 0;
1157 } 1163 }
1158 1164
1159 if (type & LOCKING_ANDX_SHARED_LOCK) { 1165 if (type & server->vals->shared_lock_type) {
1160 flock->fl_type = F_WRLCK; 1166 flock->fl_type = F_WRLCK;
1161 return 0; 1167 return 0;
1162 } 1168 }
1163 1169
1164 rc = CIFSSMBLock(xid, tcon, netfid, current->tgid, length, 1170 rc = CIFSSMBLock(xid, tcon, netfid, current->tgid, length,
1165 flock->fl_start, 0, 1, 1171 flock->fl_start, 0, 1,
1166 type | LOCKING_ANDX_SHARED_LOCK, 0, 0); 1172 type | server->vals->shared_lock_type, 0, 0);
1167 if (rc == 0) { 1173 if (rc == 0) {
1168 rc = CIFSSMBLock(xid, tcon, netfid, current->tgid, 1174 rc = CIFSSMBLock(xid, tcon, netfid, current->tgid,
1169 length, flock->fl_start, 1, 0, 1175 length, flock->fl_start, 1, 0,
1170 type | LOCKING_ANDX_SHARED_LOCK, 1176 type | server->vals->shared_lock_type, 0, 0);
1171 0, 0);
1172 flock->fl_type = F_RDLCK; 1177 flock->fl_type = F_RDLCK;
1173 if (rc != 0) 1178 if (rc != 0)
1174 cERROR(1, "Error unlocking previously locked " 1179 cERROR(1, "Error unlocking previously locked "
@@ -1307,6 +1312,7 @@ cifs_setlk(struct file *file, struct file_lock *flock, __u32 type,
1307 __u64 length = 1 + flock->fl_end - flock->fl_start; 1312 __u64 length = 1 + flock->fl_end - flock->fl_start;
1308 struct cifsFileInfo *cfile = (struct cifsFileInfo *)file->private_data; 1313 struct cifsFileInfo *cfile = (struct cifsFileInfo *)file->private_data;
1309 struct cifs_tcon *tcon = tlink_tcon(cfile->tlink); 1314 struct cifs_tcon *tcon = tlink_tcon(cfile->tlink);
1315 struct TCP_Server_Info *server = tcon->ses->server;
1310 __u16 netfid = cfile->netfid; 1316 __u16 netfid = cfile->netfid;
1311 1317
1312 if (posix_lck) { 1318 if (posix_lck) {
@@ -1316,7 +1322,7 @@ cifs_setlk(struct file *file, struct file_lock *flock, __u32 type,
1316 if (!rc || rc < 0) 1322 if (!rc || rc < 0)
1317 return rc; 1323 return rc;
1318 1324
1319 if (type & LOCKING_ANDX_SHARED_LOCK) 1325 if (type & server->vals->shared_lock_type)
1320 posix_lock_type = CIFS_RDLCK; 1326 posix_lock_type = CIFS_RDLCK;
1321 else 1327 else
1322 posix_lock_type = CIFS_WRLCK; 1328 posix_lock_type = CIFS_WRLCK;
@@ -1380,11 +1386,13 @@ int cifs_lock(struct file *file, int cmd, struct file_lock *flock)
1380 "end: %lld", cmd, flock->fl_flags, flock->fl_type, 1386 "end: %lld", cmd, flock->fl_flags, flock->fl_type,
1381 flock->fl_start, flock->fl_end); 1387 flock->fl_start, flock->fl_end);
1382 1388
1383 cifs_read_flock(flock, &type, &lock, &unlock, &wait_flag);
1384
1385 cifs_sb = CIFS_SB(file->f_path.dentry->d_sb);
1386 cfile = (struct cifsFileInfo *)file->private_data; 1389 cfile = (struct cifsFileInfo *)file->private_data;
1387 tcon = tlink_tcon(cfile->tlink); 1390 tcon = tlink_tcon(cfile->tlink);
1391
1392 cifs_read_flock(flock, &type, &lock, &unlock, &wait_flag,
1393 tcon->ses->server);
1394
1395 cifs_sb = CIFS_SB(file->f_path.dentry->d_sb);
1388 netfid = cfile->netfid; 1396 netfid = cfile->netfid;
1389 cinode = CIFS_I(file->f_path.dentry->d_inode); 1397 cinode = CIFS_I(file->f_path.dentry->d_inode);
1390 1398
diff --git a/fs/cifs/smb1ops.c b/fs/cifs/smb1ops.c
index fa486f0ca8b2..af48a8b8b75d 100644
--- a/fs/cifs/smb1ops.c
+++ b/fs/cifs/smb1ops.c
@@ -20,6 +20,7 @@
20#include "cifsglob.h" 20#include "cifsglob.h"
21#include "cifsproto.h" 21#include "cifsproto.h"
22#include "cifs_debug.h" 22#include "cifs_debug.h"
23#include "cifspdu.h"
23 24
24/* 25/*
25 * An NT cancel request header looks just like the original request except: 26 * An NT cancel request header looks just like the original request except:
@@ -65,4 +66,8 @@ struct smb_version_operations smb1_operations = {
65 66
66struct smb_version_values smb1_values = { 67struct smb_version_values smb1_values = {
67 .version_string = SMB1_VERSION_STRING, 68 .version_string = SMB1_VERSION_STRING,
69 .large_lock_type = LOCKING_ANDX_LARGE_FILES,
70 .exclusive_lock_type = 0,
71 .shared_lock_type = LOCKING_ANDX_SHARED_LOCK,
72 .unlock_lock_type = 0,
68}; 73};