diff options
author | Pavel Shilovsky <piastry@etersoft.ru> | 2012-11-22 08:07:16 -0500 |
---|---|---|
committer | Steve French <smfrench@gmail.com> | 2012-12-05 14:27:29 -0500 |
commit | b8db928b765b4b0fe1aec3eb7f1741fedbed9a33 (patch) | |
tree | d2a9a40b73af32f7d5be942eea8f716b904c5eae /fs/cifs | |
parent | 9ec3c882879d3777914d34c0143c7d5b87dbb5ea (diff) |
CIFS: Separate pushing mandatory locks and lock_sem handling
Reviewed-by: Jeff Layton <jlayton@redhat.com>
Signed-off-by: Pavel Shilovsky <piastry@etersoft.ru>
Signed-off-by: Steve French <smfrench@gmail.com>
Diffstat (limited to 'fs/cifs')
-rw-r--r-- | fs/cifs/file.c | 39 | ||||
-rw-r--r-- | fs/cifs/smb2file.c | 12 |
2 files changed, 10 insertions, 41 deletions
diff --git a/fs/cifs/file.c b/fs/cifs/file.c index 5fbbf99e61f9..1747cbff7ddf 100644 --- a/fs/cifs/file.c +++ b/fs/cifs/file.c | |||
@@ -948,7 +948,6 @@ cifs_push_mandatory_locks(struct cifsFileInfo *cfile) | |||
948 | int rc = 0, stored_rc; | 948 | int rc = 0, stored_rc; |
949 | struct cifsLockInfo *li, *tmp; | 949 | struct cifsLockInfo *li, *tmp; |
950 | struct cifs_tcon *tcon; | 950 | struct cifs_tcon *tcon; |
951 | struct cifsInodeInfo *cinode = CIFS_I(cfile->dentry->d_inode); | ||
952 | unsigned int num, max_num, max_buf; | 951 | unsigned int num, max_num, max_buf; |
953 | LOCKING_ANDX_RANGE *buf, *cur; | 952 | LOCKING_ANDX_RANGE *buf, *cur; |
954 | int types[] = {LOCKING_ANDX_LARGE_FILES, | 953 | int types[] = {LOCKING_ANDX_LARGE_FILES, |
@@ -958,21 +957,12 @@ cifs_push_mandatory_locks(struct cifsFileInfo *cfile) | |||
958 | xid = get_xid(); | 957 | xid = get_xid(); |
959 | tcon = tlink_tcon(cfile->tlink); | 958 | tcon = tlink_tcon(cfile->tlink); |
960 | 959 | ||
961 | /* we are going to update can_cache_brlcks here - need a write access */ | ||
962 | down_write(&cinode->lock_sem); | ||
963 | if (!cinode->can_cache_brlcks) { | ||
964 | up_write(&cinode->lock_sem); | ||
965 | free_xid(xid); | ||
966 | return rc; | ||
967 | } | ||
968 | |||
969 | /* | 960 | /* |
970 | * Accessing maxBuf is racy with cifs_reconnect - need to store value | 961 | * Accessing maxBuf is racy with cifs_reconnect - need to store value |
971 | * and check it for zero before using. | 962 | * and check it for zero before using. |
972 | */ | 963 | */ |
973 | max_buf = tcon->ses->server->maxBuf; | 964 | max_buf = tcon->ses->server->maxBuf; |
974 | if (!max_buf) { | 965 | if (!max_buf) { |
975 | up_write(&cinode->lock_sem); | ||
976 | free_xid(xid); | 966 | free_xid(xid); |
977 | return -EINVAL; | 967 | return -EINVAL; |
978 | } | 968 | } |
@@ -981,7 +971,6 @@ cifs_push_mandatory_locks(struct cifsFileInfo *cfile) | |||
981 | sizeof(LOCKING_ANDX_RANGE); | 971 | sizeof(LOCKING_ANDX_RANGE); |
982 | buf = kzalloc(max_num * sizeof(LOCKING_ANDX_RANGE), GFP_KERNEL); | 972 | buf = kzalloc(max_num * sizeof(LOCKING_ANDX_RANGE), GFP_KERNEL); |
983 | if (!buf) { | 973 | if (!buf) { |
984 | up_write(&cinode->lock_sem); | ||
985 | free_xid(xid); | 974 | free_xid(xid); |
986 | return -ENOMEM; | 975 | return -ENOMEM; |
987 | } | 976 | } |
@@ -1018,9 +1007,6 @@ cifs_push_mandatory_locks(struct cifsFileInfo *cfile) | |||
1018 | } | 1007 | } |
1019 | } | 1008 | } |
1020 | 1009 | ||
1021 | cinode->can_cache_brlcks = false; | ||
1022 | up_write(&cinode->lock_sem); | ||
1023 | |||
1024 | kfree(buf); | 1010 | kfree(buf); |
1025 | free_xid(xid); | 1011 | free_xid(xid); |
1026 | return rc; | 1012 | return rc; |
@@ -1041,7 +1027,7 @@ struct lock_to_push { | |||
1041 | }; | 1027 | }; |
1042 | 1028 | ||
1043 | static int | 1029 | static int |
1044 | cifs_push_posix_locks_locked(struct cifsFileInfo *cfile) | 1030 | cifs_push_posix_locks(struct cifsFileInfo *cfile) |
1045 | { | 1031 | { |
1046 | struct cifs_tcon *tcon = tlink_tcon(cfile->tlink); | 1032 | struct cifs_tcon *tcon = tlink_tcon(cfile->tlink); |
1047 | struct file_lock *flock, **before; | 1033 | struct file_lock *flock, **before; |
@@ -1129,9 +1115,11 @@ err_out: | |||
1129 | } | 1115 | } |
1130 | 1116 | ||
1131 | static int | 1117 | static int |
1132 | cifs_push_posix_locks(struct cifsFileInfo *cfile) | 1118 | cifs_push_locks(struct cifsFileInfo *cfile) |
1133 | { | 1119 | { |
1120 | struct cifs_sb_info *cifs_sb = CIFS_SB(cfile->dentry->d_sb); | ||
1134 | struct cifsInodeInfo *cinode = CIFS_I(cfile->dentry->d_inode); | 1121 | struct cifsInodeInfo *cinode = CIFS_I(cfile->dentry->d_inode); |
1122 | struct cifs_tcon *tcon = tlink_tcon(cfile->tlink); | ||
1135 | int rc = 0; | 1123 | int rc = 0; |
1136 | 1124 | ||
1137 | /* we are going to update can_cache_brlcks here - need a write access */ | 1125 | /* we are going to update can_cache_brlcks here - need a write access */ |
@@ -1140,24 +1128,17 @@ cifs_push_posix_locks(struct cifsFileInfo *cfile) | |||
1140 | up_write(&cinode->lock_sem); | 1128 | up_write(&cinode->lock_sem); |
1141 | return rc; | 1129 | return rc; |
1142 | } | 1130 | } |
1143 | rc = cifs_push_posix_locks_locked(cfile); | ||
1144 | cinode->can_cache_brlcks = false; | ||
1145 | up_write(&cinode->lock_sem); | ||
1146 | return rc; | ||
1147 | } | ||
1148 | |||
1149 | static int | ||
1150 | cifs_push_locks(struct cifsFileInfo *cfile) | ||
1151 | { | ||
1152 | struct cifs_sb_info *cifs_sb = CIFS_SB(cfile->dentry->d_sb); | ||
1153 | struct cifs_tcon *tcon = tlink_tcon(cfile->tlink); | ||
1154 | 1131 | ||
1155 | if (cap_unix(tcon->ses) && | 1132 | if (cap_unix(tcon->ses) && |
1156 | (CIFS_UNIX_FCNTL_CAP & le64_to_cpu(tcon->fsUnixInfo.Capability)) && | 1133 | (CIFS_UNIX_FCNTL_CAP & le64_to_cpu(tcon->fsUnixInfo.Capability)) && |
1157 | ((cifs_sb->mnt_cifs_flags & CIFS_MOUNT_NOPOSIXBRL) == 0)) | 1134 | ((cifs_sb->mnt_cifs_flags & CIFS_MOUNT_NOPOSIXBRL) == 0)) |
1158 | return cifs_push_posix_locks(cfile); | 1135 | rc = cifs_push_posix_locks(cfile); |
1136 | else | ||
1137 | rc = tcon->ses->server->ops->push_mand_locks(cfile); | ||
1159 | 1138 | ||
1160 | return tcon->ses->server->ops->push_mand_locks(cfile); | 1139 | cinode->can_cache_brlcks = false; |
1140 | up_write(&cinode->lock_sem); | ||
1141 | return rc; | ||
1161 | } | 1142 | } |
1162 | 1143 | ||
1163 | static void | 1144 | static void |
diff --git a/fs/cifs/smb2file.c b/fs/cifs/smb2file.c index a93eec30a50d..71e6aed4b382 100644 --- a/fs/cifs/smb2file.c +++ b/fs/cifs/smb2file.c | |||
@@ -260,13 +260,6 @@ smb2_push_mandatory_locks(struct cifsFileInfo *cfile) | |||
260 | struct cifs_fid_locks *fdlocks; | 260 | struct cifs_fid_locks *fdlocks; |
261 | 261 | ||
262 | xid = get_xid(); | 262 | xid = get_xid(); |
263 | /* we are going to update can_cache_brlcks here - need a write access */ | ||
264 | down_write(&cinode->lock_sem); | ||
265 | if (!cinode->can_cache_brlcks) { | ||
266 | up_write(&cinode->lock_sem); | ||
267 | free_xid(xid); | ||
268 | return rc; | ||
269 | } | ||
270 | 263 | ||
271 | /* | 264 | /* |
272 | * Accessing maxBuf is racy with cifs_reconnect - need to store value | 265 | * Accessing maxBuf is racy with cifs_reconnect - need to store value |
@@ -274,7 +267,6 @@ smb2_push_mandatory_locks(struct cifsFileInfo *cfile) | |||
274 | */ | 267 | */ |
275 | max_buf = tlink_tcon(cfile->tlink)->ses->server->maxBuf; | 268 | max_buf = tlink_tcon(cfile->tlink)->ses->server->maxBuf; |
276 | if (!max_buf) { | 269 | if (!max_buf) { |
277 | up_write(&cinode->lock_sem); | ||
278 | free_xid(xid); | 270 | free_xid(xid); |
279 | return -EINVAL; | 271 | return -EINVAL; |
280 | } | 272 | } |
@@ -282,7 +274,6 @@ smb2_push_mandatory_locks(struct cifsFileInfo *cfile) | |||
282 | max_num = max_buf / sizeof(struct smb2_lock_element); | 274 | max_num = max_buf / sizeof(struct smb2_lock_element); |
283 | buf = kzalloc(max_num * sizeof(struct smb2_lock_element), GFP_KERNEL); | 275 | buf = kzalloc(max_num * sizeof(struct smb2_lock_element), GFP_KERNEL); |
284 | if (!buf) { | 276 | if (!buf) { |
285 | up_write(&cinode->lock_sem); | ||
286 | free_xid(xid); | 277 | free_xid(xid); |
287 | return -ENOMEM; | 278 | return -ENOMEM; |
288 | } | 279 | } |
@@ -293,10 +284,7 @@ smb2_push_mandatory_locks(struct cifsFileInfo *cfile) | |||
293 | rc = stored_rc; | 284 | rc = stored_rc; |
294 | } | 285 | } |
295 | 286 | ||
296 | cinode->can_cache_brlcks = false; | ||
297 | kfree(buf); | 287 | kfree(buf); |
298 | |||
299 | up_write(&cinode->lock_sem); | ||
300 | free_xid(xid); | 288 | free_xid(xid); |
301 | return rc; | 289 | return rc; |
302 | } | 290 | } |