diff options
author | Pavel Shilovsky <piastry@etersoft.ru> | 2012-02-28 06:23:34 -0500 |
---|---|---|
committer | Steve French <sfrench@us.ibm.com> | 2012-05-16 21:13:36 -0400 |
commit | 106dc538abac88e804c63b7fe21ffb09cffaefc7 (patch) | |
tree | f3c4a0075e09c852b42a6f265a4dea42761352ed | |
parent | 04a6aa8acfac51385ec3e72fac1227e15db78ed9 (diff) |
CIFS: Separate protocol specific lock type handling
Signed-off-by: Pavel Shilovsky <piastry@etersoft.ru>
-rw-r--r-- | fs/cifs/cifsglob.h | 4 | ||||
-rw-r--r-- | fs/cifs/file.c | 40 | ||||
-rw-r--r-- | fs/cifs/smb1ops.c | 5 |
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 | ||
165 | struct smb_version_values { | 165 | struct 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 | ||
169 | struct smb_vol { | 173 | struct 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 | ||
1070 | static void | 1072 | static void |
1071 | cifs_read_flock(struct file_lock *flock, __u32 *type, int *lock, int *unlock, | 1073 | cifs_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 | ||
66 | struct smb_version_values smb1_values = { | 67 | struct 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 | }; |