diff options
author | Pavel Shilovsky <pshilovsky@etersoft.ru> | 2012-09-19 09:22:44 -0400 |
---|---|---|
committer | Steve French <smfrench@gmail.com> | 2012-09-24 22:46:33 -0400 |
commit | b140799a11adb6023d5f96712874c37b71dab290 (patch) | |
tree | 7b2dc7493db1b65b0d8c03901b86fb9e967c76c5 /fs/cifs | |
parent | f7ba7fe685bc3ed8fd0687870e68b2567d17357f (diff) |
CIFS: Use brlock cache for SMB2
Signed-off-by: Pavel Shilovsky <pshilovsky@etersoft.ru>
Signed-off-by: Steve French <sfrench@us.ibm.com>
Diffstat (limited to 'fs/cifs')
-rw-r--r-- | fs/cifs/smb2file.c | 91 | ||||
-rw-r--r-- | fs/cifs/smb2ops.c | 3 | ||||
-rw-r--r-- | fs/cifs/smb2proto.h | 1 |
3 files changed, 94 insertions, 1 deletions
diff --git a/fs/cifs/smb2file.c b/fs/cifs/smb2file.c index a25ea02149e7..181e13d9f9db 100644 --- a/fs/cifs/smb2file.c +++ b/fs/cifs/smb2file.c | |||
@@ -201,3 +201,94 @@ smb2_unlock_range(struct cifsFileInfo *cfile, struct file_lock *flock, | |||
201 | kfree(buf); | 201 | kfree(buf); |
202 | return rc; | 202 | return rc; |
203 | } | 203 | } |
204 | |||
205 | static int | ||
206 | smb2_push_mand_fdlocks(struct cifs_fid_locks *fdlocks, const unsigned int xid, | ||
207 | struct smb2_lock_element *buf, unsigned int max_num) | ||
208 | { | ||
209 | int rc = 0, stored_rc; | ||
210 | struct cifsFileInfo *cfile = fdlocks->cfile; | ||
211 | struct cifsLockInfo *li; | ||
212 | unsigned int num = 0; | ||
213 | struct smb2_lock_element *cur = buf; | ||
214 | struct cifs_tcon *tcon = tlink_tcon(cfile->tlink); | ||
215 | |||
216 | list_for_each_entry(li, &fdlocks->locks, llist) { | ||
217 | cur->Length = cpu_to_le64(li->length); | ||
218 | cur->Offset = cpu_to_le64(li->offset); | ||
219 | cur->Flags = cpu_to_le32(li->type | | ||
220 | SMB2_LOCKFLAG_FAIL_IMMEDIATELY); | ||
221 | if (++num == max_num) { | ||
222 | stored_rc = smb2_lockv(xid, tcon, | ||
223 | cfile->fid.persistent_fid, | ||
224 | cfile->fid.volatile_fid, | ||
225 | current->tgid, num, buf); | ||
226 | if (stored_rc) | ||
227 | rc = stored_rc; | ||
228 | cur = buf; | ||
229 | num = 0; | ||
230 | } else | ||
231 | cur++; | ||
232 | } | ||
233 | if (num) { | ||
234 | stored_rc = smb2_lockv(xid, tcon, | ||
235 | cfile->fid.persistent_fid, | ||
236 | cfile->fid.volatile_fid, | ||
237 | current->tgid, num, buf); | ||
238 | if (stored_rc) | ||
239 | rc = stored_rc; | ||
240 | } | ||
241 | |||
242 | return rc; | ||
243 | } | ||
244 | |||
245 | int | ||
246 | smb2_push_mandatory_locks(struct cifsFileInfo *cfile) | ||
247 | { | ||
248 | int rc = 0, stored_rc; | ||
249 | unsigned int xid; | ||
250 | unsigned int max_num, max_buf; | ||
251 | struct smb2_lock_element *buf; | ||
252 | struct cifsInodeInfo *cinode = CIFS_I(cfile->dentry->d_inode); | ||
253 | struct cifs_fid_locks *fdlocks; | ||
254 | |||
255 | xid = get_xid(); | ||
256 | mutex_lock(&cinode->lock_mutex); | ||
257 | if (!cinode->can_cache_brlcks) { | ||
258 | mutex_unlock(&cinode->lock_mutex); | ||
259 | free_xid(xid); | ||
260 | return rc; | ||
261 | } | ||
262 | |||
263 | /* | ||
264 | * Accessing maxBuf is racy with cifs_reconnect - need to store value | ||
265 | * and check it for zero before using. | ||
266 | */ | ||
267 | max_buf = tlink_tcon(cfile->tlink)->ses->server->maxBuf; | ||
268 | if (!max_buf) { | ||
269 | mutex_unlock(&cinode->lock_mutex); | ||
270 | free_xid(xid); | ||
271 | return -EINVAL; | ||
272 | } | ||
273 | |||
274 | max_num = max_buf / sizeof(struct smb2_lock_element); | ||
275 | buf = kzalloc(max_num * sizeof(struct smb2_lock_element), GFP_KERNEL); | ||
276 | if (!buf) { | ||
277 | mutex_unlock(&cinode->lock_mutex); | ||
278 | free_xid(xid); | ||
279 | return -ENOMEM; | ||
280 | } | ||
281 | |||
282 | list_for_each_entry(fdlocks, &cinode->llist, llist) { | ||
283 | stored_rc = smb2_push_mand_fdlocks(fdlocks, xid, buf, max_num); | ||
284 | if (stored_rc) | ||
285 | rc = stored_rc; | ||
286 | } | ||
287 | |||
288 | cinode->can_cache_brlcks = false; | ||
289 | kfree(buf); | ||
290 | |||
291 | mutex_unlock(&cinode->lock_mutex); | ||
292 | free_xid(xid); | ||
293 | return rc; | ||
294 | } | ||
diff --git a/fs/cifs/smb2ops.c b/fs/cifs/smb2ops.c index caed2c57896d..0808b238219b 100644 --- a/fs/cifs/smb2ops.c +++ b/fs/cifs/smb2ops.c | |||
@@ -371,7 +371,7 @@ smb2_set_fid(struct cifsFileInfo *cfile, struct cifs_fid *fid, __u32 oplock) | |||
371 | cfile->fid.persistent_fid = fid->persistent_fid; | 371 | cfile->fid.persistent_fid = fid->persistent_fid; |
372 | cfile->fid.volatile_fid = fid->volatile_fid; | 372 | cfile->fid.volatile_fid = fid->volatile_fid; |
373 | smb2_set_oplock_level(cinode, oplock); | 373 | smb2_set_oplock_level(cinode, oplock); |
374 | /* cinode->can_cache_brlcks = cinode->clientCanCacheAll; */ | 374 | cinode->can_cache_brlcks = cinode->clientCanCacheAll; |
375 | } | 375 | } |
376 | 376 | ||
377 | static int | 377 | static int |
@@ -615,6 +615,7 @@ struct smb_version_operations smb21_operations = { | |||
615 | .queryfs = smb2_queryfs, | 615 | .queryfs = smb2_queryfs, |
616 | .mand_lock = smb2_mand_lock, | 616 | .mand_lock = smb2_mand_lock, |
617 | .mand_unlock_range = smb2_unlock_range, | 617 | .mand_unlock_range = smb2_unlock_range, |
618 | .push_mand_locks = smb2_push_mandatory_locks, | ||
618 | }; | 619 | }; |
619 | 620 | ||
620 | struct smb_version_values smb21_values = { | 621 | struct smb_version_values smb21_values = { |
diff --git a/fs/cifs/smb2proto.h b/fs/cifs/smb2proto.h index ab19152b092b..8b4d3712255b 100644 --- a/fs/cifs/smb2proto.h +++ b/fs/cifs/smb2proto.h | |||
@@ -86,6 +86,7 @@ extern int smb2_open_file(const unsigned int xid, struct cifs_tcon *tcon, | |||
86 | extern void smb2_set_oplock_level(struct cifsInodeInfo *cinode, __u32 oplock); | 86 | extern void smb2_set_oplock_level(struct cifsInodeInfo *cinode, __u32 oplock); |
87 | extern int smb2_unlock_range(struct cifsFileInfo *cfile, | 87 | extern int smb2_unlock_range(struct cifsFileInfo *cfile, |
88 | struct file_lock *flock, const unsigned int xid); | 88 | struct file_lock *flock, const unsigned int xid); |
89 | extern int smb2_push_mandatory_locks(struct cifsFileInfo *cfile); | ||
89 | 90 | ||
90 | /* | 91 | /* |
91 | * SMB2 Worker functions - most of protocol specific implementation details | 92 | * SMB2 Worker functions - most of protocol specific implementation details |