Loading fs/cifs/connect.c +93 −65 Original line number Diff line number Diff line Loading @@ -1616,6 +1616,7 @@ cifs_put_smb_ses(struct cifsSesInfo *ses) int xid; struct TCP_Server_Info *server = ses->server; cFYI(1, "%s: ses_count=%d\n", __func__, ses->ses_count); write_lock(&cifs_tcp_ses_lock); if (--ses->ses_count > 0) { write_unlock(&cifs_tcp_ses_lock); Loading @@ -1634,6 +1635,92 @@ cifs_put_smb_ses(struct cifsSesInfo *ses) cifs_put_tcp_session(server); } static struct cifsSesInfo * cifs_get_smb_ses(struct TCP_Server_Info *server, struct smb_vol *volume_info) { int rc = -ENOMEM, xid; struct cifsSesInfo *ses; xid = GetXid(); ses = cifs_find_smb_ses(server, volume_info->username); if (ses) { cFYI(1, "Existing smb sess found (status=%d)", ses->status); /* existing SMB ses has a server reference already */ cifs_put_tcp_session(server); mutex_lock(&ses->session_mutex); if (ses->need_reconnect) { cFYI(1, "Session needs reconnect"); rc = cifs_setup_session(xid, ses, volume_info->local_nls); if (rc) { mutex_unlock(&ses->session_mutex); /* problem -- put our reference */ cifs_put_smb_ses(ses); FreeXid(xid); return ERR_PTR(rc); } } mutex_unlock(&ses->session_mutex); FreeXid(xid); return ses; } cFYI(1, "Existing smb sess not found"); ses = sesInfoAlloc(); if (ses == NULL) goto get_ses_fail; /* new SMB session uses our server ref */ ses->server = server; if (server->addr.sockAddr6.sin6_family == AF_INET6) sprintf(ses->serverName, "%pI6", &server->addr.sockAddr6.sin6_addr); else sprintf(ses->serverName, "%pI4", &server->addr.sockAddr.sin_addr.s_addr); if (volume_info->username) strncpy(ses->userName, volume_info->username, MAX_USERNAME_SIZE); /* volume_info->password freed at unmount */ if (volume_info->password) { ses->password = kstrdup(volume_info->password, GFP_KERNEL); if (!ses->password) goto get_ses_fail; } if (volume_info->domainname) { int len = strlen(volume_info->domainname); ses->domainName = kmalloc(len + 1, GFP_KERNEL); if (ses->domainName) strcpy(ses->domainName, volume_info->domainname); } ses->linux_uid = volume_info->linux_uid; ses->overrideSecFlg = volume_info->secFlg; mutex_lock(&ses->session_mutex); rc = cifs_setup_session(xid, ses, volume_info->local_nls); mutex_unlock(&ses->session_mutex); if (rc) goto get_ses_fail; /* success, put it on the list */ write_lock(&cifs_tcp_ses_lock); list_add(&ses->smb_ses_list, &server->smb_ses_list); write_unlock(&cifs_tcp_ses_lock); FreeXid(xid); return ses; get_ses_fail: sesInfoFree(ses); FreeXid(xid); return ERR_PTR(rc); } static struct cifsTconInfo * cifs_find_tcon(struct cifsSesInfo *ses, const char *unc) { Loading Loading @@ -2376,72 +2463,13 @@ cifs_mount(struct super_block *sb, struct cifs_sb_info *cifs_sb, goto out; } pSesInfo = cifs_find_smb_ses(srvTcp, volume_info->username); if (pSesInfo) { cFYI(1, "Existing smb sess found (status=%d)", pSesInfo->status); /* * The existing SMB session already has a reference to srvTcp, * so we can put back the extra one we got before */ cifs_put_tcp_session(srvTcp); mutex_lock(&pSesInfo->session_mutex); if (pSesInfo->need_reconnect) { cFYI(1, "Session needs reconnect"); rc = cifs_setup_session(xid, pSesInfo, cifs_sb->local_nls); } mutex_unlock(&pSesInfo->session_mutex); } else if (!rc) { cFYI(1, "Existing smb sess not found"); pSesInfo = sesInfoAlloc(); if (pSesInfo == NULL) { rc = -ENOMEM; goto mount_fail_check; } /* new SMB session uses our srvTcp ref */ pSesInfo->server = srvTcp; if (srvTcp->addr.sockAddr6.sin6_family == AF_INET6) sprintf(pSesInfo->serverName, "%pI6", &srvTcp->addr.sockAddr6.sin6_addr); else sprintf(pSesInfo->serverName, "%pI4", &srvTcp->addr.sockAddr.sin_addr.s_addr); write_lock(&cifs_tcp_ses_lock); list_add(&pSesInfo->smb_ses_list, &srvTcp->smb_ses_list); write_unlock(&cifs_tcp_ses_lock); /* volume_info->password freed at unmount */ if (volume_info->password) { pSesInfo->password = kstrdup(volume_info->password, GFP_KERNEL); if (!pSesInfo->password) { rc = -ENOMEM; /* get a reference to a SMB session */ pSesInfo = cifs_get_smb_ses(srvTcp, volume_info); if (IS_ERR(pSesInfo)) { rc = PTR_ERR(pSesInfo); pSesInfo = NULL; goto mount_fail_check; } } if (volume_info->username) strncpy(pSesInfo->userName, volume_info->username, MAX_USERNAME_SIZE); if (volume_info->domainname) { int len = strlen(volume_info->domainname); pSesInfo->domainName = kmalloc(len + 1, GFP_KERNEL); if (pSesInfo->domainName) strcpy(pSesInfo->domainName, volume_info->domainname); } pSesInfo->linux_uid = volume_info->linux_uid; pSesInfo->overrideSecFlg = volume_info->secFlg; mutex_lock(&pSesInfo->session_mutex); /* BB FIXME need to pass vol->secFlgs BB */ rc = cifs_setup_session(xid, pSesInfo, cifs_sb->local_nls); mutex_unlock(&pSesInfo->session_mutex); } /* search for existing tcon to this server share */ if (!rc) { Loading Loading
fs/cifs/connect.c +93 −65 Original line number Diff line number Diff line Loading @@ -1616,6 +1616,7 @@ cifs_put_smb_ses(struct cifsSesInfo *ses) int xid; struct TCP_Server_Info *server = ses->server; cFYI(1, "%s: ses_count=%d\n", __func__, ses->ses_count); write_lock(&cifs_tcp_ses_lock); if (--ses->ses_count > 0) { write_unlock(&cifs_tcp_ses_lock); Loading @@ -1634,6 +1635,92 @@ cifs_put_smb_ses(struct cifsSesInfo *ses) cifs_put_tcp_session(server); } static struct cifsSesInfo * cifs_get_smb_ses(struct TCP_Server_Info *server, struct smb_vol *volume_info) { int rc = -ENOMEM, xid; struct cifsSesInfo *ses; xid = GetXid(); ses = cifs_find_smb_ses(server, volume_info->username); if (ses) { cFYI(1, "Existing smb sess found (status=%d)", ses->status); /* existing SMB ses has a server reference already */ cifs_put_tcp_session(server); mutex_lock(&ses->session_mutex); if (ses->need_reconnect) { cFYI(1, "Session needs reconnect"); rc = cifs_setup_session(xid, ses, volume_info->local_nls); if (rc) { mutex_unlock(&ses->session_mutex); /* problem -- put our reference */ cifs_put_smb_ses(ses); FreeXid(xid); return ERR_PTR(rc); } } mutex_unlock(&ses->session_mutex); FreeXid(xid); return ses; } cFYI(1, "Existing smb sess not found"); ses = sesInfoAlloc(); if (ses == NULL) goto get_ses_fail; /* new SMB session uses our server ref */ ses->server = server; if (server->addr.sockAddr6.sin6_family == AF_INET6) sprintf(ses->serverName, "%pI6", &server->addr.sockAddr6.sin6_addr); else sprintf(ses->serverName, "%pI4", &server->addr.sockAddr.sin_addr.s_addr); if (volume_info->username) strncpy(ses->userName, volume_info->username, MAX_USERNAME_SIZE); /* volume_info->password freed at unmount */ if (volume_info->password) { ses->password = kstrdup(volume_info->password, GFP_KERNEL); if (!ses->password) goto get_ses_fail; } if (volume_info->domainname) { int len = strlen(volume_info->domainname); ses->domainName = kmalloc(len + 1, GFP_KERNEL); if (ses->domainName) strcpy(ses->domainName, volume_info->domainname); } ses->linux_uid = volume_info->linux_uid; ses->overrideSecFlg = volume_info->secFlg; mutex_lock(&ses->session_mutex); rc = cifs_setup_session(xid, ses, volume_info->local_nls); mutex_unlock(&ses->session_mutex); if (rc) goto get_ses_fail; /* success, put it on the list */ write_lock(&cifs_tcp_ses_lock); list_add(&ses->smb_ses_list, &server->smb_ses_list); write_unlock(&cifs_tcp_ses_lock); FreeXid(xid); return ses; get_ses_fail: sesInfoFree(ses); FreeXid(xid); return ERR_PTR(rc); } static struct cifsTconInfo * cifs_find_tcon(struct cifsSesInfo *ses, const char *unc) { Loading Loading @@ -2376,72 +2463,13 @@ cifs_mount(struct super_block *sb, struct cifs_sb_info *cifs_sb, goto out; } pSesInfo = cifs_find_smb_ses(srvTcp, volume_info->username); if (pSesInfo) { cFYI(1, "Existing smb sess found (status=%d)", pSesInfo->status); /* * The existing SMB session already has a reference to srvTcp, * so we can put back the extra one we got before */ cifs_put_tcp_session(srvTcp); mutex_lock(&pSesInfo->session_mutex); if (pSesInfo->need_reconnect) { cFYI(1, "Session needs reconnect"); rc = cifs_setup_session(xid, pSesInfo, cifs_sb->local_nls); } mutex_unlock(&pSesInfo->session_mutex); } else if (!rc) { cFYI(1, "Existing smb sess not found"); pSesInfo = sesInfoAlloc(); if (pSesInfo == NULL) { rc = -ENOMEM; goto mount_fail_check; } /* new SMB session uses our srvTcp ref */ pSesInfo->server = srvTcp; if (srvTcp->addr.sockAddr6.sin6_family == AF_INET6) sprintf(pSesInfo->serverName, "%pI6", &srvTcp->addr.sockAddr6.sin6_addr); else sprintf(pSesInfo->serverName, "%pI4", &srvTcp->addr.sockAddr.sin_addr.s_addr); write_lock(&cifs_tcp_ses_lock); list_add(&pSesInfo->smb_ses_list, &srvTcp->smb_ses_list); write_unlock(&cifs_tcp_ses_lock); /* volume_info->password freed at unmount */ if (volume_info->password) { pSesInfo->password = kstrdup(volume_info->password, GFP_KERNEL); if (!pSesInfo->password) { rc = -ENOMEM; /* get a reference to a SMB session */ pSesInfo = cifs_get_smb_ses(srvTcp, volume_info); if (IS_ERR(pSesInfo)) { rc = PTR_ERR(pSesInfo); pSesInfo = NULL; goto mount_fail_check; } } if (volume_info->username) strncpy(pSesInfo->userName, volume_info->username, MAX_USERNAME_SIZE); if (volume_info->domainname) { int len = strlen(volume_info->domainname); pSesInfo->domainName = kmalloc(len + 1, GFP_KERNEL); if (pSesInfo->domainName) strcpy(pSesInfo->domainName, volume_info->domainname); } pSesInfo->linux_uid = volume_info->linux_uid; pSesInfo->overrideSecFlg = volume_info->secFlg; mutex_lock(&pSesInfo->session_mutex); /* BB FIXME need to pass vol->secFlgs BB */ rc = cifs_setup_session(xid, pSesInfo, cifs_sb->local_nls); mutex_unlock(&pSesInfo->session_mutex); } /* search for existing tcon to this server share */ if (!rc) { Loading