aboutsummaryrefslogtreecommitdiffstats
path: root/fs/cifs/dir.c
diff options
context:
space:
mode:
authorPavel Shilovsky <pshilovsky@etersoft.ru>2012-09-19 09:22:45 -0400
committerSteve French <smfrench@gmail.com>2012-09-24 22:46:33 -0400
commit233839b1df65a24c8b67b748fe7b18d86d0ad6d7 (patch)
treeba9af2849063c2213fc0fbecb494967f1e662806 /fs/cifs/dir.c
parent0822f51426b51bd599b3a7e972b14aacaa045a92 (diff)
CIFS: Fix fast lease break after open problem
Now we walk though cifsFileInfo's list for every incoming lease break and look for an equivalent there. That approach misses lease breaks that come just after an open response - we don't have time to populate new cifsFileInfo structure to the list. Fix this by adding new list of pending opens and look for a lease there if we didn't find it in the list of cifsFileInfo structures. Signed-off-by: Pavel Shilovsky <pshilovsky@etersoft.ru> Signed-off-by: Steve French <sfrench@us.ibm.com>
Diffstat (limited to 'fs/cifs/dir.c')
-rw-r--r--fs/cifs/dir.c9
1 files changed, 8 insertions, 1 deletions
diff --git a/fs/cifs/dir.c b/fs/cifs/dir.c
index 4f2147c5adb6..7c0a81283645 100644
--- a/fs/cifs/dir.c
+++ b/fs/cifs/dir.c
@@ -382,6 +382,7 @@ cifs_atomic_open(struct inode *inode, struct dentry *direntry,
382 struct cifs_tcon *tcon; 382 struct cifs_tcon *tcon;
383 struct TCP_Server_Info *server; 383 struct TCP_Server_Info *server;
384 struct cifs_fid fid; 384 struct cifs_fid fid;
385 struct cifs_pending_open open;
385 __u32 oplock; 386 __u32 oplock;
386 struct cifsFileInfo *file_info; 387 struct cifsFileInfo *file_info;
387 388
@@ -423,16 +424,21 @@ cifs_atomic_open(struct inode *inode, struct dentry *direntry,
423 if (server->ops->new_lease_key) 424 if (server->ops->new_lease_key)
424 server->ops->new_lease_key(&fid); 425 server->ops->new_lease_key(&fid);
425 426
427 cifs_add_pending_open(&fid, tlink, &open);
428
426 rc = cifs_do_create(inode, direntry, xid, tlink, oflags, mode, 429 rc = cifs_do_create(inode, direntry, xid, tlink, oflags, mode,
427 &oplock, &fid, opened); 430 &oplock, &fid, opened);
428 431
429 if (rc) 432 if (rc) {
433 cifs_del_pending_open(&open);
430 goto out; 434 goto out;
435 }
431 436
432 rc = finish_open(file, direntry, generic_file_open, opened); 437 rc = finish_open(file, direntry, generic_file_open, opened);
433 if (rc) { 438 if (rc) {
434 if (server->ops->close) 439 if (server->ops->close)
435 server->ops->close(xid, tcon, &fid); 440 server->ops->close(xid, tcon, &fid);
441 cifs_del_pending_open(&open);
436 goto out; 442 goto out;
437 } 443 }
438 444
@@ -440,6 +446,7 @@ cifs_atomic_open(struct inode *inode, struct dentry *direntry,
440 if (file_info == NULL) { 446 if (file_info == NULL) {
441 if (server->ops->close) 447 if (server->ops->close)
442 server->ops->close(xid, tcon, &fid); 448 server->ops->close(xid, tcon, &fid);
449 cifs_del_pending_open(&open);
443 rc = -ENOMEM; 450 rc = -ENOMEM;
444 } 451 }
445 452