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>
diff --git a/fs/cifs/dir.c b/fs/cifs/dir.c
index 4f2147c..7c0a812 100644
--- a/fs/cifs/dir.c
+++ b/fs/cifs/dir.c
@@ -382,6 +382,7 @@
struct cifs_tcon *tcon;
struct TCP_Server_Info *server;
struct cifs_fid fid;
+ struct cifs_pending_open open;
__u32 oplock;
struct cifsFileInfo *file_info;
@@ -423,16 +424,21 @@
if (server->ops->new_lease_key)
server->ops->new_lease_key(&fid);
+ cifs_add_pending_open(&fid, tlink, &open);
+
rc = cifs_do_create(inode, direntry, xid, tlink, oflags, mode,
&oplock, &fid, opened);
- if (rc)
+ if (rc) {
+ cifs_del_pending_open(&open);
goto out;
+ }
rc = finish_open(file, direntry, generic_file_open, opened);
if (rc) {
if (server->ops->close)
server->ops->close(xid, tcon, &fid);
+ cifs_del_pending_open(&open);
goto out;
}
@@ -440,6 +446,7 @@
if (file_info == NULL) {
if (server->ops->close)
server->ops->close(xid, tcon, &fid);
+ cifs_del_pending_open(&open);
rc = -ENOMEM;
}