cifs: Fix FALLOC_FL_ZERO_RANGE by setting i_size if EOF moved
[platform/kernel/linux-starfive.git] / fs / smb / client / smb2ops.c
index 9aeecee..16512f4 100644 (file)
@@ -756,6 +756,7 @@ SMB3_request_interfaces(const unsigned int xid, struct cifs_tcon *tcon, bool in_
        unsigned int ret_data_len = 0;
        struct network_interface_info_ioctl_rsp *out_buf = NULL;
        struct cifs_ses *ses = tcon->ses;
+       struct TCP_Server_Info *pserver;
 
        /* do not query too frequently */
        if (ses->iface_last_update &&
@@ -780,6 +781,11 @@ SMB3_request_interfaces(const unsigned int xid, struct cifs_tcon *tcon, bool in_
        if (rc)
                goto out;
 
+       /* check if iface is still active */
+       pserver = ses->chans[0].server;
+       if (pserver && !cifs_chan_is_iface_active(ses, pserver))
+               cifs_chan_update_iface(ses, pserver);
+
 out:
        kfree(out_buf);
        return rc;
@@ -3299,6 +3305,7 @@ static long smb3_zero_range(struct file *file, struct cifs_tcon *tcon,
        struct inode *inode = file_inode(file);
        struct cifsInodeInfo *cifsi = CIFS_I(inode);
        struct cifsFileInfo *cfile = file->private_data;
+       unsigned long long new_size;
        long rc;
        unsigned int xid;
        __le64 eof;
@@ -3329,10 +3336,15 @@ static long smb3_zero_range(struct file *file, struct cifs_tcon *tcon,
        /*
         * do we also need to change the size of the file?
         */
-       if (keep_size == false && i_size_read(inode) < offset + len) {
-               eof = cpu_to_le64(offset + len);
+       new_size = offset + len;
+       if (keep_size == false && (unsigned long long)i_size_read(inode) < new_size) {
+               eof = cpu_to_le64(new_size);
                rc = SMB2_set_eof(xid, tcon, cfile->fid.persistent_fid,
                                  cfile->fid.volatile_fid, cfile->pid, &eof);
+               if (rc >= 0) {
+                       truncate_setsize(inode, new_size);
+                       fscache_resize_cookie(cifs_inode_cookie(inode), new_size);
+               }
        }
 
  zero_range_exit:
@@ -5087,7 +5099,7 @@ smb2_make_node(unsigned int xid, struct inode *inode,
         * over SMB2/SMB3 and Samba will do this with SMB3.1.1 POSIX Extensions
         */
 
-       if (!S_ISCHR(mode) && !S_ISBLK(mode))
+       if (!S_ISCHR(mode) && !S_ISBLK(mode) && !S_ISFIFO(mode))
                return rc;
 
        cifs_dbg(FYI, "sfu compat create special file\n");
@@ -5135,6 +5147,12 @@ smb2_make_node(unsigned int xid, struct inode *inode,
                pdev->minor = cpu_to_le64(MINOR(dev));
                rc = tcon->ses->server->ops->sync_write(xid, &fid, &io_parms,
                                                        &bytes_written, iov, 1);
+       } else if (S_ISFIFO(mode)) {
+               memcpy(pdev->type, "LnxFIFO", 8);
+               pdev->major = 0;
+               pdev->minor = 0;
+               rc = tcon->ses->server->ops->sync_write(xid, &fid, &io_parms,
+                                                       &bytes_written, iov, 1);
        }
        tcon->ses->server->ops->close(xid, tcon, &fid);
        d_drop(dentry);