|
@@ -247,6 +247,7 @@ cifs_new_fileinfo(struct cifs_fid *fid, struct file *file,
|
|
|
struct cifsInodeInfo *cinode = CIFS_I(inode);
|
|
|
struct cifsFileInfo *cfile;
|
|
|
struct cifs_fid_locks *fdlocks;
|
|
|
+ struct cifs_tcon *tcon = tlink_tcon(tlink);
|
|
|
|
|
|
cfile = kzalloc(sizeof(struct cifsFileInfo), GFP_KERNEL);
|
|
|
if (cfile == NULL)
|
|
@@ -274,10 +275,15 @@ cifs_new_fileinfo(struct cifs_fid *fid, struct file *file,
|
|
|
cfile->tlink = cifs_get_tlink(tlink);
|
|
|
INIT_WORK(&cfile->oplock_break, cifs_oplock_break);
|
|
|
mutex_init(&cfile->fh_mutex);
|
|
|
- tlink_tcon(tlink)->ses->server->ops->set_fid(cfile, fid, oplock);
|
|
|
|
|
|
spin_lock(&cifs_file_list_lock);
|
|
|
- list_add(&cfile->tlist, &(tlink_tcon(tlink)->openFileList));
|
|
|
+ if (fid->pending_open->oplock != CIFS_OPLOCK_NO_CHANGE)
|
|
|
+ oplock = fid->pending_open->oplock;
|
|
|
+ list_del(&fid->pending_open->olist);
|
|
|
+
|
|
|
+ tlink_tcon(tlink)->ses->server->ops->set_fid(cfile, fid, oplock);
|
|
|
+
|
|
|
+ list_add(&cfile->tlist, &tcon->openFileList);
|
|
|
/* if readable file instance put first in list*/
|
|
|
if (file->f_mode & FMODE_READ)
|
|
|
list_add(&cfile->flist, &cinode->openFileList);
|
|
@@ -307,9 +313,12 @@ void cifsFileInfo_put(struct cifsFileInfo *cifs_file)
|
|
|
{
|
|
|
struct inode *inode = cifs_file->dentry->d_inode;
|
|
|
struct cifs_tcon *tcon = tlink_tcon(cifs_file->tlink);
|
|
|
+ struct TCP_Server_Info *server = tcon->ses->server;
|
|
|
struct cifsInodeInfo *cifsi = CIFS_I(inode);
|
|
|
struct cifs_sb_info *cifs_sb = CIFS_SB(inode->i_sb);
|
|
|
struct cifsLockInfo *li, *tmp;
|
|
|
+ struct cifs_fid fid;
|
|
|
+ struct cifs_pending_open open;
|
|
|
|
|
|
spin_lock(&cifs_file_list_lock);
|
|
|
if (--cifs_file->count > 0) {
|
|
@@ -317,6 +326,12 @@ void cifsFileInfo_put(struct cifsFileInfo *cifs_file)
|
|
|
return;
|
|
|
}
|
|
|
|
|
|
+ if (server->ops->get_lease_key)
|
|
|
+ server->ops->get_lease_key(inode, &fid);
|
|
|
+
|
|
|
+ /* store open in pending opens to make sure we don't miss lease break */
|
|
|
+ cifs_add_pending_open_locked(&fid, cifs_file->tlink, &open);
|
|
|
+
|
|
|
/* remove it from the lists */
|
|
|
list_del(&cifs_file->flist);
|
|
|
list_del(&cifs_file->tlist);
|
|
@@ -348,6 +363,8 @@ void cifsFileInfo_put(struct cifsFileInfo *cifs_file)
|
|
|
free_xid(xid);
|
|
|
}
|
|
|
|
|
|
+ cifs_del_pending_open(&open);
|
|
|
+
|
|
|
/*
|
|
|
* Delete any outstanding lock records. We'll lose them when the file
|
|
|
* is closed anyway.
|
|
@@ -368,6 +385,7 @@ void cifsFileInfo_put(struct cifsFileInfo *cifs_file)
|
|
|
}
|
|
|
|
|
|
int cifs_open(struct inode *inode, struct file *file)
|
|
|
+
|
|
|
{
|
|
|
int rc = -EACCES;
|
|
|
unsigned int xid;
|
|
@@ -380,6 +398,7 @@ int cifs_open(struct inode *inode, struct file *file)
|
|
|
char *full_path = NULL;
|
|
|
bool posix_open_ok = false;
|
|
|
struct cifs_fid fid;
|
|
|
+ struct cifs_pending_open open;
|
|
|
|
|
|
xid = get_xid();
|
|
|
|
|
@@ -401,7 +420,7 @@ int cifs_open(struct inode *inode, struct file *file)
|
|
|
cFYI(1, "inode = 0x%p file flags are 0x%x for %s",
|
|
|
inode, file->f_flags, full_path);
|
|
|
|
|
|
- if (tcon->ses->server->oplocks)
|
|
|
+ if (server->oplocks)
|
|
|
oplock = REQ_OPLOCK;
|
|
|
else
|
|
|
oplock = 0;
|
|
@@ -434,20 +453,28 @@ int cifs_open(struct inode *inode, struct file *file)
|
|
|
*/
|
|
|
}
|
|
|
|
|
|
+ if (server->ops->get_lease_key)
|
|
|
+ server->ops->get_lease_key(inode, &fid);
|
|
|
+
|
|
|
+ cifs_add_pending_open(&fid, tlink, &open);
|
|
|
+
|
|
|
if (!posix_open_ok) {
|
|
|
if (server->ops->get_lease_key)
|
|
|
server->ops->get_lease_key(inode, &fid);
|
|
|
|
|
|
rc = cifs_nt_open(full_path, inode, cifs_sb, tcon,
|
|
|
file->f_flags, &oplock, &fid, xid);
|
|
|
- if (rc)
|
|
|
+ if (rc) {
|
|
|
+ cifs_del_pending_open(&open);
|
|
|
goto out;
|
|
|
+ }
|
|
|
}
|
|
|
|
|
|
cfile = cifs_new_fileinfo(&fid, file, tlink, oplock);
|
|
|
if (cfile == NULL) {
|
|
|
if (server->ops->close)
|
|
|
server->ops->close(xid, tcon, &fid);
|
|
|
+ cifs_del_pending_open(&open);
|
|
|
rc = -ENOMEM;
|
|
|
goto out;
|
|
|
}
|