extern int checkSMB(char *buf, unsigned int len, struct TCP_Server_Info *srvr);
 extern bool is_valid_oplock_break(char *, struct TCP_Server_Info *);
 extern bool backup_cred(struct cifs_sb_info *);
-extern bool is_size_safe_to_change(struct cifsInodeInfo *, __u64 eof);
+extern bool is_size_safe_to_change(struct cifsInodeInfo *cifsInode, __u64 eof,
+                                  bool from_readdir);
 extern void cifs_update_eof(struct cifsInodeInfo *cifsi, loff_t offset,
                            unsigned int bytes_written);
 extern struct cifsFileInfo *find_writable_file(struct cifsInodeInfo *, int);
                                     struct cifs_sb_info *cifs_sb);
 extern void cifs_dir_info_to_fattr(struct cifs_fattr *, FILE_DIRECTORY_INFO *,
                                        struct cifs_sb_info *);
-extern int cifs_fattr_to_inode(struct inode *inode, struct cifs_fattr *fattr);
+extern int cifs_fattr_to_inode(struct inode *inode, struct cifs_fattr *fattr,
+                              bool from_readdir);
 extern struct inode *cifs_iget(struct super_block *sb,
                               struct cifs_fattr *fattr);
 
 
                }
        } else {
                cifs_revalidate_mapping(*pinode);
-               rc = cifs_fattr_to_inode(*pinode, &fattr);
+               rc = cifs_fattr_to_inode(*pinode, &fattr, false);
        }
 
 posix_open_ret:
    refreshing the inode only on increases in the file size
    but this is tricky to do without racing with writebehind
    page caching in the current Linux kernel design */
-bool is_size_safe_to_change(struct cifsInodeInfo *cifsInode, __u64 end_of_file)
+bool is_size_safe_to_change(struct cifsInodeInfo *cifsInode, __u64 end_of_file,
+                           bool from_readdir)
 {
        if (!cifsInode)
                return true;
 
-       if (is_inode_writable(cifsInode)) {
+       if (is_inode_writable(cifsInode) ||
+               ((cifsInode->oplock & CIFS_CACHE_RW_FLG) != 0 && from_readdir)) {
                /* This inode is open for write at least once */
                struct cifs_sb_info *cifs_sb;
 
 
 
 /* populate an inode with info from a cifs_fattr struct */
 int
-cifs_fattr_to_inode(struct inode *inode, struct cifs_fattr *fattr)
+cifs_fattr_to_inode(struct inode *inode, struct cifs_fattr *fattr,
+                   bool from_readdir)
 {
        struct cifsInodeInfo *cifs_i = CIFS_I(inode);
        struct cifs_sb_info *cifs_sb = CIFS_SB(inode->i_sb);
         * Can't safely change the file size here if the client is writing to
         * it due to potential races.
         */
-       if (is_size_safe_to_change(cifs_i, fattr->cf_eof)) {
+       if (is_size_safe_to_change(cifs_i, fattr->cf_eof, from_readdir)) {
                i_size_write(inode, fattr->cf_eof);
 
                /*
                CIFS_I(*inode)->time = 0; /* force reval */
                return -ESTALE;
        }
-       return cifs_fattr_to_inode(*inode, fattr);
+       return cifs_fattr_to_inode(*inode, fattr, false);
 }
 
 #ifdef CONFIG_CIFS_ALLOW_INSECURE_LEGACY
        } else
                goto cifs_gfiunix_out;
 
-       rc = cifs_fattr_to_inode(inode, &fattr);
+       rc = cifs_fattr_to_inode(inode, &fattr, false);
 
 cifs_gfiunix_out:
        free_xid(xid);
        fattr.cf_uniqueid = CIFS_I(inode)->uniqueid;
        fattr.cf_flags |= CIFS_FATTR_NEED_REVAL;
        /* if filetype is different, return error */
-       rc = cifs_fattr_to_inode(inode, &fattr);
+       rc = cifs_fattr_to_inode(inode, &fattr, false);
 cgfi_exit:
        cifs_free_open_info(&data);
        free_xid(xid);
                }
 
                /* can't fail - see cifs_find_inode() */
-               cifs_fattr_to_inode(inode, fattr);
+               cifs_fattr_to_inode(inode, fattr, false);
                if (sb->s_flags & SB_NOATIME)
                        inode->i_flags |= S_NOATIME | S_NOCMTIME;
                if (inode->i_state & I_NEW) {
 
                                                rc = -ESTALE;
                                        }
                                }
-                               if (!rc && !cifs_fattr_to_inode(inode, fattr)) {
+                               if (!rc && !cifs_fattr_to_inode(inode, fattr, true)) {
                                        dput(dentry);
                                        return;
                                }