Hi Steve, I think this needs the further changes below, which I will fold in. The issues are: (1) One of the error paths in cifs_atomic_open() uses the cookie when it should jump around that. (2) There's an additional successful return from the middle of cifs_open() that I mistook for an error path, but does need to use the cookie on the way out. David --- diff --git a/fs/cifs/dir.c b/fs/cifs/dir.c index 6186824b366e..bf3b4c9901b9 100644 --- a/fs/cifs/dir.c +++ b/fs/cifs/dir.c @@ -508,6 +508,7 @@ cifs_atomic_open(struct inode *inode, struct dentry *direntry, server->ops->close(xid, tcon, &fid); cifs_del_pending_open(&open); rc = -ENOMEM; + goto out; } fscache_use_cookie(cifs_inode_cookie(file_inode(file)), diff --git a/fs/cifs/file.c b/fs/cifs/file.c index 44da7646f789..47333730c963 100644 --- a/fs/cifs/file.c +++ b/fs/cifs/file.c @@ -568,7 +568,7 @@ int cifs_open(struct inode *inode, struct file *file) spin_lock(&CIFS_I(inode)->deferred_lock); cifs_del_deferred_close(cfile); spin_unlock(&CIFS_I(inode)->deferred_lock); - goto out; + goto use_cache; } else { _cifsFileInfo_put(cfile, true, false); } @@ -630,19 +630,6 @@ int cifs_open(struct inode *inode, struct file *file) goto out; } - - fscache_use_cookie(cifs_inode_cookie(file_inode(file)), - file->f_mode & FMODE_WRITE); - if (file->f_flags & O_DIRECT && - (!((file->f_flags & O_ACCMODE) != O_RDONLY) || - file->f_flags & O_APPEND)) { - struct cifs_fscache_inode_coherency_data cd; - cifs_fscache_fill_coherency(file_inode(file), &cd); - fscache_invalidate(cifs_inode_cookie(file_inode(file)), - &cd, i_size_read(file_inode(file)), - FSCACHE_INVAL_DIO_WRITE); - } - if ((oplock & CIFS_CREATE_ACTION) && !posix_open_ok && tcon->unix_ext) { /* * Time to set mode which we can not set earlier due to @@ -661,6 +648,19 @@ int cifs_open(struct inode *inode, struct file *file) cfile->pid); } +use_cache: + fscache_use_cookie(cifs_inode_cookie(file_inode(file)), + file->f_mode & FMODE_WRITE); + if (file->f_flags & O_DIRECT && + (!((file->f_flags & O_ACCMODE) != O_RDONLY) || + file->f_flags & O_APPEND)) { + struct cifs_fscache_inode_coherency_data cd; + cifs_fscache_fill_coherency(file_inode(file), &cd); + fscache_invalidate(cifs_inode_cookie(file_inode(file)), + &cd, i_size_read(file_inode(file)), + FSCACHE_INVAL_DIO_WRITE); + } + out: free_dentry_path(page); free_xid(xid);