x86: Fix boot on Twinhead H12Y
[firefly-linux-kernel-4.4.55.git] / fs / cifs / inode.c
index de02ed5e25c2ad09919cf84c23c69b2383e55360..745e5cdca8f7f75b27b2d56d631051c11733f9e4 100644 (file)
@@ -295,7 +295,7 @@ int cifs_get_file_info_unix(struct file *filp)
        struct inode *inode = filp->f_path.dentry->d_inode;
        struct cifs_sb_info *cifs_sb = CIFS_SB(inode->i_sb);
        struct cifsFileInfo *cfile = filp->private_data;
-       struct cifsTconInfo *tcon = tlink_tcon(cfile->tlink);
+       struct cifs_tcon *tcon = tlink_tcon(cfile->tlink);
 
        xid = GetXid();
        rc = CIFSSMBUnixQFileInfo(xid, tcon, cfile->netfid, &find_data);
@@ -318,7 +318,7 @@ int cifs_get_inode_info_unix(struct inode **pinode,
        int rc;
        FILE_UNIX_BASIC_INFO find_data;
        struct cifs_fattr fattr;
-       struct cifsTconInfo *tcon;
+       struct cifs_tcon *tcon;
        struct tcon_link *tlink;
        struct cifs_sb_info *cifs_sb = CIFS_SB(sb);
 
@@ -373,7 +373,8 @@ cifs_sfu_type(struct cifs_fattr *fattr, const unsigned char *path,
        int oplock = 0;
        __u16 netfid;
        struct tcon_link *tlink;
-       struct cifsTconInfo *tcon;
+       struct cifs_tcon *tcon;
+       struct cifs_io_parms io_parms;
        char buf[24];
        unsigned int bytes_read;
        char *pbuf;
@@ -405,9 +406,13 @@ cifs_sfu_type(struct cifs_fattr *fattr, const unsigned char *path,
        if (rc == 0) {
                int buf_type = CIFS_NO_BUFFER;
                        /* Read header */
-               rc = CIFSSMBRead(xid, tcon, netfid,
-                                24 /* length */, 0 /* offset */,
-                                &bytes_read, &pbuf, &buf_type);
+               io_parms.netfid = netfid;
+               io_parms.pid = current->tgid;
+               io_parms.tcon = tcon;
+               io_parms.offset = 0;
+               io_parms.length = 24;
+               rc = CIFSSMBRead(xid, &io_parms, &bytes_read, &pbuf,
+                                &buf_type);
                if ((rc == 0) && (bytes_read >= 8)) {
                        if (memcmp("IntxBLK", pbuf, 8) == 0) {
                                cFYI(1, "Block device");
@@ -468,7 +473,7 @@ static int cifs_sfu_mode(struct cifs_fattr *fattr, const unsigned char *path,
        char ea_value[4];
        __u32 mode;
        struct tcon_link *tlink;
-       struct cifsTconInfo *tcon;
+       struct cifs_tcon *tcon;
 
        tlink = cifs_sb_tlink(cifs_sb);
        if (IS_ERR(tlink))
@@ -502,7 +507,7 @@ static void
 cifs_all_info_to_fattr(struct cifs_fattr *fattr, FILE_ALL_INFO *info,
                       struct cifs_sb_info *cifs_sb, bool adjust_tz)
 {
-       struct cifsTconInfo *tcon = cifs_sb_master_tcon(cifs_sb);
+       struct cifs_tcon *tcon = cifs_sb_master_tcon(cifs_sb);
 
        memset(fattr, 0, sizeof(*fattr));
        fattr->cf_cifsattrs = le32_to_cpu(info->Attributes);
@@ -553,11 +558,20 @@ int cifs_get_file_info(struct file *filp)
        struct inode *inode = filp->f_path.dentry->d_inode;
        struct cifs_sb_info *cifs_sb = CIFS_SB(inode->i_sb);
        struct cifsFileInfo *cfile = filp->private_data;
-       struct cifsTconInfo *tcon = tlink_tcon(cfile->tlink);
+       struct cifs_tcon *tcon = tlink_tcon(cfile->tlink);
 
        xid = GetXid();
        rc = CIFSSMBQFileInfo(xid, tcon, cfile->netfid, &find_data);
-       if (rc == -EOPNOTSUPP || rc == -EINVAL) {
+       switch (rc) {
+       case 0:
+               cifs_all_info_to_fattr(&fattr, &find_data, cifs_sb, false);
+               break;
+       case -EREMOTE:
+               cifs_create_dfs_fattr(&fattr, inode->i_sb);
+               rc = 0;
+               break;
+       case -EOPNOTSUPP:
+       case -EINVAL:
                /*
                 * FIXME: legacy server -- fall back to path-based call?
                 * for now, just skip revalidating and mark inode for
@@ -565,18 +579,14 @@ int cifs_get_file_info(struct file *filp)
                 */
                rc = 0;
                CIFS_I(inode)->time = 0;
+       default:
                goto cgfi_exit;
-       } else if (rc == -EREMOTE) {
-               cifs_create_dfs_fattr(&fattr, inode->i_sb);
-               rc = 0;
-       } else if (rc)
-               goto cgfi_exit;
+       }
 
        /*
         * don't bother with SFU junk here -- just mark inode as needing
         * revalidation.
         */
-       cifs_all_info_to_fattr(&fattr, &find_data, cifs_sb, false);
        fattr.cf_uniqueid = CIFS_I(inode)->uniqueid;
        fattr.cf_flags |= CIFS_FATTR_NEED_REVAL;
        cifs_fattr_to_inode(inode, &fattr);
@@ -590,7 +600,7 @@ int cifs_get_inode_info(struct inode **pinode,
        struct super_block *sb, int xid, const __u16 *pfid)
 {
        int rc = 0, tmprc;
-       struct cifsTconInfo *pTcon;
+       struct cifs_tcon *pTcon;
        struct tcon_link *tlink;
        struct cifs_sb_info *cifs_sb = CIFS_SB(sb);
        char *buf = NULL;
@@ -735,10 +745,10 @@ static const struct inode_operations cifs_ipc_inode_ops = {
        .lookup = cifs_lookup,
 };
 
-char *cifs_build_path_to_root(struct cifs_sb_info *cifs_sb,
-                               struct cifsTconInfo *tcon)
+char *cifs_build_path_to_root(struct smb_vol *vol, struct cifs_sb_info *cifs_sb,
+                             struct cifs_tcon *tcon)
 {
-       int pplen = cifs_sb->prepathlen;
+       int pplen = vol->prepath ? strlen(vol->prepath) : 0;
        int dfsplen;
        char *full_path = NULL;
 
@@ -759,20 +769,10 @@ char *cifs_build_path_to_root(struct cifs_sb_info *cifs_sb,
        if (full_path == NULL)
                return full_path;
 
-       if (dfsplen) {
+       if (dfsplen)
                strncpy(full_path, tcon->treeName, dfsplen);
-               /* switch slash direction in prepath depending on whether
-                * windows or posix style path names
-                */
-               if (cifs_sb->mnt_cifs_flags & CIFS_MOUNT_POSIX_PATHS) {
-                       int i;
-                       for (i = 0; i < dfsplen; i++) {
-                               if (full_path[i] == '\\')
-                                       full_path[i] = '/';
-                       }
-               }
-       }
-       strncpy(full_path + dfsplen, cifs_sb->prepath, pplen);
+       strncpy(full_path + dfsplen, vol->prepath, pplen);
+       convert_delimiter(full_path, CIFS_DIR_SEP(cifs_sb));
        full_path[dfsplen + pplen] = 0; /* add trailing null */
        return full_path;
 }
@@ -884,19 +884,13 @@ struct inode *cifs_root_iget(struct super_block *sb)
        struct cifs_sb_info *cifs_sb = CIFS_SB(sb);
        struct inode *inode = NULL;
        long rc;
-       char *full_path;
-       struct cifsTconInfo *tcon = cifs_sb_master_tcon(cifs_sb);
-
-       full_path = cifs_build_path_to_root(cifs_sb, tcon);
-       if (full_path == NULL)
-               return ERR_PTR(-ENOMEM);
+       struct cifs_tcon *tcon = cifs_sb_master_tcon(cifs_sb);
 
        xid = GetXid();
        if (tcon->unix_ext)
-               rc = cifs_get_inode_info_unix(&inode, full_path, sb, xid);
+               rc = cifs_get_inode_info_unix(&inode, "", sb, xid);
        else
-               rc = cifs_get_inode_info(&inode, full_path, NULL, sb,
-                                               xid, NULL);
+               rc = cifs_get_inode_info(&inode, "", NULL, sb, xid, NULL);
 
        if (!inode) {
                inode = ERR_PTR(rc);
@@ -922,7 +916,6 @@ struct inode *cifs_root_iget(struct super_block *sb)
        }
 
 out:
-       kfree(full_path);
        /* can not call macro FreeXid here since in a void func
         * TODO: This is no longer true
         */
@@ -943,7 +936,7 @@ cifs_set_file_info(struct inode *inode, struct iattr *attrs, int xid,
        struct cifsInodeInfo *cifsInode = CIFS_I(inode);
        struct cifs_sb_info *cifs_sb = CIFS_SB(inode->i_sb);
        struct tcon_link *tlink = NULL;
-       struct cifsTconInfo *pTcon;
+       struct cifs_tcon *pTcon;
        FILE_BASIC_INFO info_buf;
 
        if (attrs == NULL)
@@ -1061,7 +1054,7 @@ cifs_rename_pending_delete(char *full_path, struct dentry *dentry, int xid)
        struct cifsInodeInfo *cifsInode = CIFS_I(inode);
        struct cifs_sb_info *cifs_sb = CIFS_SB(inode->i_sb);
        struct tcon_link *tlink;
-       struct cifsTconInfo *tcon;
+       struct cifs_tcon *tcon;
        __u32 dosattr, origattr;
        FILE_BASIC_INFO *info_buf = NULL;
 
@@ -1179,7 +1172,7 @@ int cifs_unlink(struct inode *dir, struct dentry *dentry)
        struct super_block *sb = dir->i_sb;
        struct cifs_sb_info *cifs_sb = CIFS_SB(sb);
        struct tcon_link *tlink;
-       struct cifsTconInfo *tcon;
+       struct cifs_tcon *tcon;
        struct iattr *attrs = NULL;
        __u32 dosattr = 0, origattr = 0;
 
@@ -1277,7 +1270,7 @@ int cifs_mkdir(struct inode *inode, struct dentry *direntry, int mode)
        int xid;
        struct cifs_sb_info *cifs_sb;
        struct tcon_link *tlink;
-       struct cifsTconInfo *pTcon;
+       struct cifs_tcon *pTcon;
        char *full_path = NULL;
        struct inode *newinode = NULL;
        struct cifs_fattr fattr;
@@ -1455,7 +1448,7 @@ int cifs_rmdir(struct inode *inode, struct dentry *direntry)
        int xid;
        struct cifs_sb_info *cifs_sb;
        struct tcon_link *tlink;
-       struct cifsTconInfo *pTcon;
+       struct cifs_tcon *pTcon;
        char *full_path = NULL;
        struct cifsInodeInfo *cifsInode;
 
@@ -1512,7 +1505,7 @@ cifs_do_rename(int xid, struct dentry *from_dentry, const char *fromPath,
 {
        struct cifs_sb_info *cifs_sb = CIFS_SB(from_dentry->d_sb);
        struct tcon_link *tlink;
-       struct cifsTconInfo *pTcon;
+       struct cifs_tcon *pTcon;
        __u16 srcfid;
        int oplock, rc;
 
@@ -1564,7 +1557,7 @@ int cifs_rename(struct inode *source_dir, struct dentry *source_dentry,
        char *toName = NULL;
        struct cifs_sb_info *cifs_sb;
        struct tcon_link *tlink;
-       struct cifsTconInfo *tcon;
+       struct cifs_tcon *tcon;
        FILE_UNIX_BASIC_INFO *info_buf_source = NULL;
        FILE_UNIX_BASIC_INFO *info_buf_target;
        int xid, rc, tmprc;
@@ -1794,7 +1787,7 @@ int cifs_getattr(struct vfsmount *mnt, struct dentry *dentry,
                 struct kstat *stat)
 {
        struct cifs_sb_info *cifs_sb = CIFS_SB(dentry->d_sb);
-       struct cifsTconInfo *tcon = cifs_sb_master_tcon(cifs_sb);
+       struct cifs_tcon *tcon = cifs_sb_master_tcon(cifs_sb);
        struct inode *inode = dentry->d_inode;
        int rc;
 
@@ -1872,7 +1865,8 @@ cifs_set_file_size(struct inode *inode, struct iattr *attrs,
        struct cifsInodeInfo *cifsInode = CIFS_I(inode);
        struct cifs_sb_info *cifs_sb = CIFS_SB(inode->i_sb);
        struct tcon_link *tlink = NULL;
-       struct cifsTconInfo *pTcon = NULL;
+       struct cifs_tcon *pTcon = NULL;
+       struct cifs_io_parms io_parms;
 
        /*
         * To avoid spurious oplock breaks from server, in the case of
@@ -1894,8 +1888,14 @@ cifs_set_file_size(struct inode *inode, struct iattr *attrs,
                cFYI(1, "SetFSize for attrs rc = %d", rc);
                if ((rc == -EINVAL) || (rc == -EOPNOTSUPP)) {
                        unsigned int bytes_written;
-                       rc = CIFSSMBWrite(xid, pTcon, nfid, 0, attrs->ia_size,
-                                         &bytes_written, NULL, NULL, 1);
+
+                       io_parms.netfid = nfid;
+                       io_parms.pid = npid;
+                       io_parms.tcon = pTcon;
+                       io_parms.offset = 0;
+                       io_parms.length = attrs->ia_size;
+                       rc = CIFSSMBWrite(xid, &io_parms, &bytes_written,
+                                         NULL, NULL, 1);
                        cFYI(1, "Wrt seteof rc %d", rc);
                }
        } else
@@ -1930,10 +1930,15 @@ cifs_set_file_size(struct inode *inode, struct iattr *attrs,
                                        CIFS_MOUNT_MAP_SPECIAL_CHR);
                        if (rc == 0) {
                                unsigned int bytes_written;
-                               rc = CIFSSMBWrite(xid, pTcon, netfid, 0,
-                                                 attrs->ia_size,
-                                                 &bytes_written, NULL,
-                                                 NULL, 1);
+
+                               io_parms.netfid = netfid;
+                               io_parms.pid = current->tgid;
+                               io_parms.tcon = pTcon;
+                               io_parms.offset = 0;
+                               io_parms.length = attrs->ia_size;
+                               rc = CIFSSMBWrite(xid, &io_parms,
+                                                 &bytes_written,
+                                                 NULL, NULL,  1);
                                cFYI(1, "wrt seteof rc %d", rc);
                                CIFSSMBClose(xid, pTcon, netfid);
                        }
@@ -1961,7 +1966,7 @@ cifs_setattr_unix(struct dentry *direntry, struct iattr *attrs)
        struct cifsInodeInfo *cifsInode = CIFS_I(inode);
        struct cifs_sb_info *cifs_sb = CIFS_SB(inode->i_sb);
        struct tcon_link *tlink;
-       struct cifsTconInfo *pTcon;
+       struct cifs_tcon *pTcon;
        struct cifs_unix_set_info_args *args = NULL;
        struct cifsFileInfo *open_file;
 
@@ -2247,7 +2252,7 @@ cifs_setattr(struct dentry *direntry, struct iattr *attrs)
 {
        struct inode *inode = direntry->d_inode;
        struct cifs_sb_info *cifs_sb = CIFS_SB(inode->i_sb);
-       struct cifsTconInfo *pTcon = cifs_sb_master_tcon(cifs_sb);
+       struct cifs_tcon *pTcon = cifs_sb_master_tcon(cifs_sb);
 
        if (pTcon->unix_ext)
                return cifs_setattr_unix(direntry, attrs);