Merge tag 'dma-rename-4.18' of git://git.infradead.org/users/hch/dma-mapping
[sfrench/cifs-2.6.git] / fs / cifs / inode.c
index 6be9a7cfaf0e23bf90ad680efecf471c5fd6d64e..a2cfb33e85c1f8cb25a2d32a52bb5d60c93b79f1 100644 (file)
@@ -748,7 +748,8 @@ cifs_get_inode_info(struct inode **inode, const char *full_path,
        cifs_dbg(FYI, "Getting info on %s\n", full_path);
 
        if ((data == NULL) && (*inode != NULL)) {
-               if (CIFS_CACHE_READ(CIFS_I(*inode))) {
+               if (CIFS_CACHE_READ(CIFS_I(*inode)) &&
+                   CIFS_I(*inode)->time != 0) {
                        cifs_dbg(FYI, "No need to revalidate cached inode sizes\n");
                        goto cgii_exit;
                }
@@ -1574,6 +1575,17 @@ int cifs_mkdir(struct inode *inode, struct dentry *direntry, umode_t mode)
                goto mkdir_out;
        }
 
+       server = tcon->ses->server;
+
+#ifdef CONFIG_CIFS_SMB311
+       if ((server->ops->posix_mkdir) && (tcon->posix_extensions)) {
+               rc = server->ops->posix_mkdir(xid, inode, mode, tcon, full_path,
+                                             cifs_sb);
+               d_drop(direntry); /* for time being always refresh inode info */
+               goto mkdir_out;
+       }
+#endif /* SMB311 */
+
        if (cap_unix(tcon->ses) && (CIFS_UNIX_POSIX_PATH_OPS_CAP &
                                le64_to_cpu(tcon->fsUnixInfo.Capability))) {
                rc = cifs_posix_mkdir(inode, direntry, mode, full_path, cifs_sb,
@@ -1582,8 +1594,6 @@ int cifs_mkdir(struct inode *inode, struct dentry *direntry, umode_t mode)
                        goto mkdir_out;
        }
 
-       server = tcon->ses->server;
-
        if (!server->ops->mkdir) {
                rc = -ENOSYS;
                goto mkdir_out;
@@ -1793,7 +1803,7 @@ cifs_rename2(struct inode *source_dir, struct dentry *source_dentry,
                 * with unix extensions enabled.
                 */
                info_buf_source =
-                       kmalloc(2 * sizeof(FILE_UNIX_BASIC_INFO),
+                       kmalloc_array(2, sizeof(FILE_UNIX_BASIC_INFO),
                                        GFP_KERNEL);
                if (info_buf_source == NULL) {
                        rc = -ENOMEM;
@@ -1859,15 +1869,15 @@ cifs_inode_needs_reval(struct inode *inode)
        struct cifsInodeInfo *cifs_i = CIFS_I(inode);
        struct cifs_sb_info *cifs_sb = CIFS_SB(inode->i_sb);
 
+       if (cifs_i->time == 0)
+               return true;
+
        if (CIFS_CACHE_READ(cifs_i))
                return false;
 
        if (!lookupCacheEnabled)
                return true;
 
-       if (cifs_i->time == 0)
-               return true;
-
        if (!cifs_sb->actimeo)
                return true;
 
@@ -2106,10 +2116,14 @@ static int cifs_truncate_page(struct address_space *mapping, loff_t from)
 
 static void cifs_setsize(struct inode *inode, loff_t offset)
 {
+       struct cifsInodeInfo *cifs_i = CIFS_I(inode);
+
        spin_lock(&inode->i_lock);
        i_size_write(inode, offset);
        spin_unlock(&inode->i_lock);
 
+       /* Cached inode must be refreshed on truncate */
+       cifs_i->time = 0;
        truncate_pagecache(inode, offset);
 }