[PATCH 07/11] cifs: allow for cifs_sb_tcon() to return an error

Jeff Layton <[email protected]>
Newsgroups gmane.linux.file-systems.cifs,gmane.linux.file-systems
Message-ID <[email protected]>
Fix the callers to expect and handle it properly.

Signed-off-by: Jeff Layton <[email protected]>
---
 fs/cifs/cifs_dfs_ref.c |   10 ++--
 fs/cifs/cifsacl.c      |   32 ++++++++++---
 fs/cifs/cifsfs.c       |   69 ++++++++++------------------
 fs/cifs/cifsglob.h     |    6 --
 fs/cifs/cifsproto.h    |    5 ++-
 fs/cifs/dir.c          |   47 +++++++++++--------
 fs/cifs/file.c         |   12 +++--
 fs/cifs/inode.c        |  120 +++++++++++++++++++++++++++++++++++++----------
 fs/cifs/link.c         |   13 +++++-
 fs/cifs/misc.c         |    2 +-
 fs/cifs/readdir.c      |   12 +++--
 fs/cifs/xattr.c        |   23 +++++++++-
 12 files changed, 229 insertions(+), 122 deletions(-)

diff --git a/fs/cifs/cifs_dfs_ref.c b/fs/cifs/cifs_dfs_ref.c
index fc7035a..f3edaf3 100644
--- a/fs/cifs/cifs_dfs_ref.c
+++ b/fs/cifs/cifs_dfs_ref.c
@@ -308,6 +308,7 @@ cifs_dfs_follow_mountpoint(struct dentry *dentry, struct nameidata *nd)
 	struct dfs_info3_param *referrals = NULL;
 	unsigned int num_referrals = 0;
 	struct cifs_sb_info *cifs_sb;
+	struct cifsTconInfo *tcon;
 	struct cifsSesInfo *ses;
 	char *full_path = NULL;
 	int xid, i;
@@ -323,13 +324,14 @@ cifs_dfs_follow_mountpoint(struct dentry *dentry, struct nameidata *nd)
 	nd->path.dentry = dget(dentry);
 
 	cifs_sb = CIFS_SB(dentry->d_inode->i_sb);
-	ses = cifs_sb_tcon(cifs_sb)->ses;
-
-	if (!ses) {
-		rc = -EINVAL;
+	tcon = cifs_sb_tcon(cifs_sb);
+	if (IS_ERR(tcon)) {
+		rc = PTR_ERR(tcon);
 		goto out_err;
 	}
 
+	ses = tcon->ses;
+
 	/*
 	 * The MSDFS spec states that paths in DFS referral requests and
 	 * responses must be prefixed by a single '\' character instead of
diff --git a/fs/cifs/cifsacl.c b/fs/cifs/cifsacl.c
index c2fb35c..673a0dc 100644
--- a/fs/cifs/cifsacl.c
+++ b/fs/cifs/cifsacl.c
@@ -556,10 +556,14 @@ static struct cifs_ntsd *get_cifs_acl_by_fid(struct cifs_sb_info *cifs_sb,
 		__u16 fid, u32 *pacllen)
 {
 	struct cifs_ntsd *pntsd = NULL;
+	struct cifsTconInfo *tcon = cifs_sb_tcon(cifs_sb);
 	int xid, rc;
 
+	if (IS_ERR(tcon))
+		return (struct cifs_ntsd *) tcon;
+
 	xid = GetXid();
-	rc = CIFSSMBGetCIFSACL(xid, cifs_sb_tcon(cifs_sb), fid, &pntsd, pacllen);
+	rc = CIFSSMBGetCIFSACL(xid, tcon, fid, &pntsd, pacllen);
 	FreeXid(xid);
 
 
@@ -571,13 +575,17 @@ static struct cifs_ntsd *get_cifs_acl_by_path(struct cifs_sb_info *cifs_sb,
 		const char *path, u32 *pacllen)
 {
 	struct cifs_ntsd *pntsd = NULL;
+	struct cifsTconInfo *tcon = cifs_sb_tcon(cifs_sb);
 	int oplock = 0;
 	int xid, rc;
 	__u16 fid;
 
+	if (IS_ERR(tcon))
+		return (struct cifs_ntsd *) tcon;
+
 	xid = GetXid();
 
-	rc = CIFSSMBOpen(xid, cifs_sb_tcon(cifs_sb), path, FILE_OPEN, READ_CONTROL, 0,
+	rc = CIFSSMBOpen(xid, tcon, path, FILE_OPEN, READ_CONTROL, 0,
 			 &fid, &oplock, NULL, cifs_sb->local_nls,
 			 cifs_sb->mnt_cifs_flags & CIFS_MOUNT_MAP_SPECIAL_CHR);
 	if (rc) {
@@ -585,10 +593,10 @@ static struct cifs_ntsd *get_cifs_acl_by_path(struct cifs_sb_info *cifs_sb,
 		goto out;
 	}
 
-	rc = CIFSSMBGetCIFSACL(xid, cifs_sb_tcon(cifs_sb), fid, &pntsd, pacllen);
+	rc = CIFSSMBGetCIFSACL(xid, tcon, fid, &pntsd, pacllen);
 	cFYI(1, ("GetCIFSACL rc = %d ACL len %d", rc, *pacllen));
 
-	CIFSSMBClose(xid, cifs_sb_tcon(cifs_sb), fid);
+	CIFSSMBClose(xid, tcon, fid);
  out:
 	FreeXid(xid);
 	return pntsd;
@@ -616,9 +624,13 @@ static int set_cifs_acl_by_fid(struct cifs_sb_info *cifs_sb, __u16 fid,
 		struct cifs_ntsd *pnntsd, u32 acllen)
 {
 	int xid, rc;
+	struct cifsTconInfo *tcon = cifs_sb_tcon(cifs_sb);
+
+	if (IS_ERR(tcon))
+		return PTR_ERR(tcon);
 
 	xid = GetXid();
-	rc = CIFSSMBSetCIFSACL(xid, cifs_sb_tcon(cifs_sb), fid, pnntsd, acllen);
+	rc = CIFSSMBSetCIFSACL(xid, tcon, fid, pnntsd, acllen);
 	FreeXid(xid);
 
 	cFYI(DBG2, ("SetCIFSACL rc = %d", rc));
@@ -631,10 +643,14 @@ static int set_cifs_acl_by_path(struct cifs_sb_info *cifs_sb, const char *path,
 	int oplock = 0;
 	int xid, rc;
 	__u16 fid;
+	struct cifsTconInfo *tcon = cifs_sb_tcon(cifs_sb);
+
+	if (IS_ERR(tcon))
+		return PTR_ERR(tcon);
 
 	xid = GetXid();
 
-	rc = CIFSSMBOpen(xid, cifs_sb_tcon(cifs_sb), path, FILE_OPEN, WRITE_DAC, 0,
+	rc = CIFSSMBOpen(xid, tcon, path, FILE_OPEN, WRITE_DAC, 0,
 			 &fid, &oplock, NULL, cifs_sb->local_nls,
 			 cifs_sb->mnt_cifs_flags & CIFS_MOUNT_MAP_SPECIAL_CHR);
 	if (rc) {
@@ -642,10 +658,10 @@ static int set_cifs_acl_by_path(struct cifs_sb_info *cifs_sb, const char *path,
 		goto out;
 	}
 
-	rc = CIFSSMBSetCIFSACL(xid, cifs_sb_tcon(cifs_sb), fid, pnntsd, acllen);
+	rc = CIFSSMBSetCIFSACL(xid, tcon, fid, pnntsd, acllen);
 	cFYI(DBG2, ("SetCIFSACL rc = %d", rc));
 
-	CIFSSMBClose(xid, cifs_sb_tcon(cifs_sb), fid);
+	CIFSSMBClose(xid, tcon, fid);
  out:
 	FreeXid(xid);
 	return rc;
diff --git a/fs/cifs/cifsfs.c b/fs/cifs/cifsfs.c
index b9ceec0..10137f4 100644
--- a/fs/cifs/cifsfs.c
+++ b/fs/cifs/cifsfs.c
@@ -102,6 +102,8 @@ cifs_read_super(struct super_block *sb, void *data,
 	cifs_sb = CIFS_SB(sb);
 	if (cifs_sb == NULL)
 		return -ENOMEM;
+	INIT_RADIX_TREE(&cifs_sb->tcon_tree, GFP_KERNEL);
+	spin_lock_init(&cifs_sb->tcon_tree_lock);
 
 #ifdef CONFIG_CIFS_DFS_UPCALL
 	/* copy mount params to sb for use in submounts */
@@ -228,6 +230,9 @@ cifs_statfs(struct dentry *dentry, struct kstatfs *buf)
 	int rc = -EOPNOTSUPP;
 	int xid;
 
+	if (IS_ERR(tcon))
+		return PTR_ERR(tcon);
+
 	xid = GetXid();
 
 	buf->f_type = CIFS_MAGIC_NUMBER;
@@ -359,7 +364,7 @@ static int
 cifs_show_options(struct seq_file *s, struct vfsmount *m)
 {
 	struct cifs_sb_info *cifs_sb = CIFS_SB(m->mnt_sb);
-	struct cifsTconInfo *tcon = cifs_sb_tcon(cifs_sb);
+	struct cifsTconInfo *tcon = cifs_sb_master_tcon(cifs_sb);
 
 	seq_printf(s, ",unc=%s", tcon->treeName);
 
@@ -433,20 +438,13 @@ int cifs_xquota_set(struct super_block *sb, int quota_type, qid_t qid,
 	int xid;
 	int rc = 0;
 	struct cifs_sb_info *cifs_sb = CIFS_SB(sb);
-	struct cifsTconInfo *pTcon;
-
-	if (cifs_sb)
-		pTcon = cifs_sb_tcon(cifs_sb);
-	else
-		return -EIO;
+	struct cifsTconInfo *tcon = cifs_sb_tcon(cifs_sb);
 
+	if (IS_ERR(tcon))
+		return PTR_ERR(tcon);
 
 	xid = GetXid();
-	if (pTcon) {
-		cFYI(1, ("set type: 0x%x id: %d", quota_type, qid));
-	} else
-		rc = -EIO;
-
+	cFYI(1, ("set type: 0x%x id: %d", quota_type, qid));
 	FreeXid(xid);
 	return rc;
 }
@@ -457,19 +455,13 @@ int cifs_xquota_get(struct super_block *sb, int quota_type, qid_t qid,
 	int xid;
 	int rc = 0;
 	struct cifs_sb_info *cifs_sb = CIFS_SB(sb);
-	struct cifsTconInfo *pTcon;
+	struct cifsTconInfo *tcon = cifs_sb_tcon(cifs_sb);
 
-	if (cifs_sb)
-		pTcon = cifs_sb_tcon(cifs_sb);
-	else
-		return -EIO;
+	if (IS_ERR(tcon))
+		return PTR_ERR(tcon);
 
 	xid = GetXid();
-	if (pTcon) {
-		cFYI(1, ("set type: 0x%x id: %d", quota_type, qid));
-	} else
-		rc = -EIO;
-
+	cFYI(1, ("set type: 0x%x id: %d", quota_type, qid));
 	FreeXid(xid);
 	return rc;
 }
@@ -479,19 +471,13 @@ int cifs_xstate_set(struct super_block *sb, unsigned int flags, int operation)
 	int xid;
 	int rc = 0;
 	struct cifs_sb_info *cifs_sb = CIFS_SB(sb);
-	struct cifsTconInfo *pTcon;
+	struct cifsTconInfo *tcon = cifs_sb_tcon(cifs_sb);
 
-	if (cifs_sb)
-		pTcon = cifs_sb_tcon(cifs_sb);
-	else
-		return -EIO;
+	if (IS_ERR(tcon))
+		return PTR_ERR(tcon);
 
 	xid = GetXid();
-	if (pTcon) {
-		cFYI(1, ("flags: 0x%x operation: 0x%x", flags, operation));
-	} else
-		rc = -EIO;
-
+	cFYI(1, ("flags: 0x%x operation: 0x%x", flags, operation));
 	FreeXid(xid);
 	return rc;
 }
@@ -501,19 +487,13 @@ int cifs_xstate_get(struct super_block *sb, struct fs_quota_stat *qstats)
 	int xid;
 	int rc = 0;
 	struct cifs_sb_info *cifs_sb = CIFS_SB(sb);
-	struct cifsTconInfo *pTcon;
+	struct cifsTconInfo *tcon = cifs_sb_tcon(cifs_sb);
 
-	if (cifs_sb)
-		pTcon = cifs_sb_tcon(cifs_sb);
-	else
-		return -EIO;
+	if (IS_ERR(tcon))
+		return PTR_ERR(tcon);
 
 	xid = GetXid();
-	if (pTcon) {
-		cFYI(1, ("pqstats %p", qstats));
-	} else
-		rc = -EIO;
-
+	cFYI(1, ("pqstats %p", qstats));
 	FreeXid(xid);
 	return rc;
 }
@@ -534,9 +514,8 @@ static void cifs_umount_begin(struct super_block *sb)
 	if (cifs_sb == NULL)
 		return;
 
-	tcon = cifs_sb_tcon(cifs_sb);
-	if (tcon == NULL)
-		return;
+	/* FIXME: handle multisession case properly */
+	tcon = cifs_sb_master_tcon(cifs_sb);
 
 	read_lock(&cifs_tcp_ses_lock);
 	if ((tcon->tc_count > 1) || (tcon->tidStatus == CifsExiting)) {
diff --git a/fs/cifs/cifsglob.h b/fs/cifs/cifsglob.h
index ca9dd9d..2e3c489 100644
--- a/fs/cifs/cifsglob.h
+++ b/fs/cifs/cifsglob.h
@@ -401,12 +401,6 @@ CIFS_SB(struct super_block *sb)
 	return sb->s_fs_info;
 }
 
-static inline struct cifsTconInfo *
-cifs_sb_tcon(struct cifs_sb_info *cifs_sb)
-{
-	return cifs_sb->tcon;
-}
-
 static inline char CIFS_DIR_SEP(const struct cifs_sb_info *cifs_sb)
 {
 	if (cifs_sb->mnt_cifs_flags & CIFS_MOUNT_POSIX_PATHS)
diff --git a/fs/cifs/cifsproto.h b/fs/cifs/cifsproto.h
index ca341fc..301566e 100644
--- a/fs/cifs/cifsproto.h
+++ b/fs/cifs/cifsproto.h
@@ -92,7 +92,8 @@ extern struct timespec cnvrtDosUnixTm(__le16 le_date, __le16 le_time,
 
 extern struct cifsFileInfo *cifs_new_fileinfo(struct inode *newinode,
 				__u16 fileHandle, struct file *file,
-				struct vfsmount *mnt, unsigned int oflags);
+				struct vfsmount *mnt, struct cifsTconInfo *tcon,
+				unsigned int oflags);
 extern int cifs_posix_open(char *full_path, struct inode **pinode,
 			   struct vfsmount *mnt, int mode, int oflags,
 			   __u32 *poplock, __u16 *pnetfid, int xid);
@@ -117,6 +118,8 @@ extern void cifs_acl_to_fattr(struct cifs_sb_info *cifs_sb,
 			      const char *path, const __u16 *pfid);
 extern int mode_to_acl(struct inode *inode, const char *path, __u64);
 
+extern struct cifsTconInfo *cifs_sb_master_tcon(struct cifs_sb_info *cifs_sb);
+extern struct cifsTconInfo *cifs_sb_tcon(struct cifs_sb_info *cifs_sb);
 extern int cifs_mount(struct super_block *, struct cifs_sb_info *, char *,
 			const char *);
 extern int cifs_umount(struct super_block *, struct cifs_sb_info *);
diff --git a/fs/cifs/dir.c b/fs/cifs/dir.c
index 05ee024..90184cd 100644
--- a/fs/cifs/dir.c
+++ b/fs/cifs/dir.c
@@ -53,18 +53,19 @@ build_path_from_dentry(struct dentry *direntry)
 	int dfsplen;
 	char *full_path;
 	char dirsep;
-	struct cifs_sb_info *cifs_sb;
+	struct cifs_sb_info *cifs_sb = CIFS_SB(direntry->d_sb);
+	struct cifsTconInfo *tcon = cifs_sb_master_tcon(cifs_sb);
 
+	/* FIXME: this is racy -- need to take proper references */
 	if (direntry == NULL)
 		return NULL;  /* not much we can do if dentry is freed and
 		we need to reopen the file after it was closed implicitly
 		when the server crashed */
 
-	cifs_sb = CIFS_SB(direntry->d_sb);
 	dirsep = CIFS_DIR_SEP(cifs_sb);
 	pplen = cifs_sb->prepathlen;
-	if (cifs_sb_tcon(cifs_sb) && (cifs_sb_tcon(cifs_sb)->Flags & SMB_SHARE_IS_IN_DFS))
-		dfsplen = strnlen(cifs_sb_tcon(cifs_sb)->treeName, MAX_TREE_SIZE + 1);
+	if (tcon && (tcon->Flags & SMB_SHARE_IS_IN_DFS))
+		dfsplen = strnlen(tcon->treeName, MAX_TREE_SIZE + 1);
 	else
 		dfsplen = 0;
 cifs_bp_rename_retry:
@@ -117,7 +118,7 @@ cifs_bp_rename_retry:
 	/* BB test paths to Windows with '/' in the midst of prepath */
 
 	if (dfsplen) {
-		strncpy(full_path, cifs_sb_tcon(cifs_sb)->treeName, dfsplen);
+		strncpy(full_path, tcon->treeName, dfsplen);
 		if (cifs_sb->mnt_cifs_flags & CIFS_MOUNT_POSIX_PATHS) {
 			int i;
 			for (i = 0; i < dfsplen; i++) {
@@ -126,7 +127,7 @@ cifs_bp_rename_retry:
 			}
 		}
 	}
-	strncpy(full_path + dfsplen, CIFS_SB(direntry->d_sb)->prepath, pplen);
+	strncpy(full_path + dfsplen, cifs_sb->prepath, pplen);
 	return full_path;
 }
 
@@ -138,7 +139,6 @@ cifs_new_fileinfo(struct inode *newinode, __u16 fileHandle, struct file *file,
 	int oplock = 0;
 	struct cifsFileInfo *pCifsFile;
 	struct cifsInodeInfo *pCifsInode;
-	struct cifs_sb_info *cifs_sb = CIFS_SB(mnt->mnt_sb);
 
 	pCifsFile = kzalloc(sizeof(struct cifsFileInfo), GFP_KERNEL);
 	if (pCifsFile == NULL)
@@ -163,7 +163,7 @@ cifs_new_fileinfo(struct inode *newinode, __u16 fileHandle, struct file *file,
 	slow_work_init(&pCifsFile->oplock_break, &cifs_oplock_break_ops);
 
 	write_lock(&GlobalSMBSeslock);
-	list_add(&pCifsFile->tlist, &cifs_sb_tcon(cifs_sb)->openFileList);
+	list_add(&pCifsFile->tlist, &tcon->openFileList);
 	pCifsInode = CIFS_I(newinode);
 	if (pCifsInode) {
 		/* if readable file instance put first in list*/
@@ -193,14 +193,17 @@ int cifs_posix_open(char *full_path, struct inode **pinode,
 	FILE_UNIX_BASIC_INFO *presp_data;
 	__u32 posix_flags = 0;
 	struct cifs_sb_info *cifs_sb = CIFS_SB(mnt->mnt_sb);
-	struct cifs_fattr fattr;
 	struct cifsTconInfo *tcon = cifs_sb_tcon(cifs_sb);
+	struct cifs_fattr fattr;
 
 	if (IS_ERR(tcon))
 		return PTR_ERR(tcon);
 
 	cFYI(1, ("posix open %s", full_path));
 
+	if (IS_ERR(tcon))
+		return PTR_ERR(tcon);
+
 	presp_data = kzalloc(sizeof(FILE_UNIX_BASIC_INFO), GFP_KERNEL);
 	if (presp_data == NULL)
 		return -ENOMEM;
@@ -297,17 +300,17 @@ cifs_create(struct inode *inode, struct dentry *direntry, int mode,
 	 */
 	int desiredAccess = GENERIC_READ | GENERIC_WRITE;
 	__u16 fileHandle;
-	struct cifs_sb_info *cifs_sb;
-	struct cifsTconInfo *tcon;
+	struct cifs_sb_info *cifs_sb = CIFS_SB(inode->i_sb);
+	struct cifsTconInfo *tcon = cifs_sb_tcon(cifs_sb);
 	char *full_path = NULL;
 	FILE_ALL_INFO *buf = NULL;
 	struct inode *newinode = NULL;
 	int disposition = FILE_OVERWRITE_IF;
 
-	xid = GetXid();
+	if (IS_ERR(tcon))
+		return PTR_ERR(tcon);
 
-	cifs_sb = CIFS_SB(inode->i_sb);
-	tcon = cifs_sb_tcon(cifs_sb);
+	xid = GetXid();
 
 	if (IS_ERR(tcon)) {
 		FreeXid(xid);
@@ -390,7 +393,7 @@ cifs_create(struct inode *inode, struct dentry *direntry, int mode,
 	if (!tcon->unix_ext && (mode & S_IWUGO) == 0)
 		create_options |= CREATE_OPTION_READONLY;
 
-	if (cifs_sb_tcon(cifs_sb)->ses->capabilities & CAP_NT_SMBS)
+	if (tcon->ses->capabilities & CAP_NT_SMBS)
 		rc = CIFSSMBOpen(xid, tcon, full_path, disposition,
 			 desiredAccess, create_options,
 			 &fileHandle, &oplock, buf, cifs_sb->local_nls,
@@ -491,18 +494,18 @@ int cifs_mknod(struct inode *inode, struct dentry *direntry, int mode,
 {
 	int rc = -EPERM;
 	int xid;
-	struct cifs_sb_info *cifs_sb;
-	struct cifsTconInfo *pTcon;
+	struct cifs_sb_info *cifs_sb = CIFS_SB(inode->i_sb);
+	struct cifsTconInfo *pTcon = cifs_sb_tcon(cifs_sb);
 	char *full_path = NULL;
 	struct inode *newinode = NULL;
 
 	if (!old_valid_dev(device_number))
 		return -EINVAL;
 
-	xid = GetXid();
+	if (IS_ERR(pTcon))
+		return PTR_ERR(pTcon);
 
-	cifs_sb = CIFS_SB(inode->i_sb);
-	pTcon = cifs_sb_tcon(cifs_sb);
+	xid = GetXid();
 
 	full_path = build_path_from_dentry(direntry);
 	if (full_path == NULL)
@@ -635,6 +638,10 @@ cifs_lookup(struct inode *parent_dir_inode, struct dentry *direntry,
 
 	cifs_sb = CIFS_SB(parent_dir_inode->i_sb);
 	pTcon = cifs_sb_tcon(cifs_sb);
+	if (IS_ERR(pTcon)) {
+		FreeXid(xid);
+		return (struct dentry *) pTcon;
+	}
 
 	/*
 	 * Don't allow the separator character in a path component.
diff --git a/fs/cifs/file.c b/fs/cifs/file.c
index 26665b8..b56913a 100644
--- a/fs/cifs/file.c
+++ b/fs/cifs/file.c
@@ -265,9 +265,9 @@ int cifs_open(struct inode *inode, struct file *file)
 	__u16 netfid;
 	FILE_ALL_INFO *buf = NULL;
 
-	xid = GetXid();
-
 	cifs_sb = CIFS_SB(inode->i_sb);
+
+	xid = GetXid();
 	tcon = cifs_sb_tcon(cifs_sb);
 	if (IS_ERR(tcon)) {
 		FreeXid(xid);
@@ -374,7 +374,7 @@ int cifs_open(struct inode *inode, struct file *file)
 		goto out;
 	}
 
-	if (cifs_sb_tcon(cifs_sb)->ses->capabilities & CAP_NT_SMBS)
+	if (tcon->ses->capabilities & CAP_NT_SMBS)
 		rc = CIFSSMBOpen(xid, tcon, full_path, disposition,
 			 desiredAccess, CREATE_NOT_DIR, &netfid, &oplock, buf,
 			 cifs_sb->local_nls, cifs_sb->mnt_cifs_flags
@@ -1399,6 +1399,7 @@ static int cifs_writepages(struct address_space *mapping,
 	int xid, long_op;
 
 	cifs_sb = CIFS_SB(mapping->host->i_sb);
+	tcon = cifs_sb_master_tcon(cifs_sb);
 
 	/*
 	 * If wsize is smaller that the page cache size, default to writing
@@ -1407,7 +1408,10 @@ static int cifs_writepages(struct address_space *mapping,
 	if (cifs_sb->wsize < PAGE_CACHE_SIZE)
 		return generic_writepages(mapping, wbc);
 
-	if (cifs_sb_tcon(cifs_sb)->ses->sign && !experimEnabled)
+	/* FIXME: not quite right -- we need to determine this once we know
+	 * what tcon we're going to use.
+	 */
+	if (tcon->ses->sign && !experimEnabled)
 		return generic_writepages(mapping, wbc);
 
 	iov = kmalloc(32 * sizeof(struct kvec), GFP_KERNEL);
diff --git a/fs/cifs/inode.c b/fs/cifs/inode.c
index e21feaa..100ad85 100644
--- a/fs/cifs/inode.c
+++ b/fs/cifs/inode.c
@@ -51,7 +51,7 @@ static void cifs_set_ops(struct inode *inode, const bool is_dfs_referral)
 
 
 		/* check if server can support readpages */
-		if (cifs_sb_tcon(cifs_sb)->ses->server->maxBuf <
+		if (cifs_sb_master_tcon(cifs_sb)->ses->server->maxBuf <
 				PAGE_CACHE_SIZE + MAX_CIFS_HDR_SIZE)
 			inode->i_data.a_ops = &cifs_addr_ops_smallbuf;
 		else
@@ -301,12 +301,14 @@ 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_sb_info *cifs_sb = CIFS_SB(sb);
+	struct cifsTconInfo *tcon = cifs_sb_tcon(cifs_sb);
 
-	tcon = cifs_sb_tcon(cifs_sb);
 	cFYI(1, ("Getting info on %s", full_path));
 
+	if (IS_ERR(tcon))
+		return PTR_ERR(tcon);
+
 	/* could have done a find first instead but this returns more info */
 	rc = CIFSSMBUnixQPathInfo(xid, tcon, full_path, &find_data,
 				  cifs_sb->local_nls, cifs_sb->mnt_cifs_flags &
@@ -341,11 +343,14 @@ cifs_sfu_type(struct cifs_fattr *fattr, const unsigned char *path,
 	int rc;
 	int oplock = 0;
 	__u16 netfid;
-	struct cifsTconInfo *pTcon = cifs_sb_tcon(cifs_sb);
+	struct cifsTconInfo *tcon = cifs_sb_tcon(cifs_sb);
 	char buf[24];
 	unsigned int bytes_read;
 	char *pbuf;
 
+	if (IS_ERR(tcon))
+		return PTR_ERR(tcon);
+
 	pbuf = buf;
 
 	fattr->cf_mode &= ~S_IFMT;
@@ -360,7 +365,7 @@ cifs_sfu_type(struct cifs_fattr *fattr, const unsigned char *path,
 		return -EINVAL;	 /* EOPNOTSUPP? */
 	}
 
-	rc = CIFSSMBOpen(xid, pTcon, path, FILE_OPEN, GENERIC_READ,
+	rc = CIFSSMBOpen(xid, tcon, path, FILE_OPEN, GENERIC_READ,
 			 CREATE_NOT_DIR, &netfid, &oplock, NULL,
 			 cifs_sb->local_nls,
 			 cifs_sb->mnt_cifs_flags &
@@ -368,7 +373,7 @@ 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, pTcon, netfid,
+		rc = CIFSSMBRead(xid, tcon, netfid,
 				 24 /* length */, 0 /* offset */,
 				 &bytes_read, &pbuf, &buf_type);
 		if ((rc == 0) && (bytes_read >= 8)) {
@@ -410,7 +415,7 @@ cifs_sfu_type(struct cifs_fattr *fattr, const unsigned char *path,
 			fattr->cf_dtype = DT_REG;
 			rc = -EOPNOTSUPP; /* or some unknown SFU type */
 		}
-		CIFSSMBClose(xid, pTcon, netfid);
+		CIFSSMBClose(xid, tcon, netfid);
 	}
 	return rc;
 }
@@ -429,8 +434,12 @@ static int cifs_sfu_mode(struct cifs_fattr *fattr, const unsigned char *path,
 	ssize_t rc;
 	char ea_value[4];
 	__u32 mode;
+	struct cifsTconInfo *tcon = cifs_sb_tcon(cifs_sb);
+
+	if (IS_ERR(tcon))
+		return PTR_ERR(tcon);
 
-	rc = CIFSSMBQAllEAs(xid, cifs_sb_tcon(cifs_sb), path, "SETFILEBITS",
+	rc = CIFSSMBQAllEAs(xid, tcon, path, "SETFILEBITS",
 			    ea_value, 4 /* size of buf */, cifs_sb->local_nls,
 			    cifs_sb->mnt_cifs_flags &
 				CIFS_MOUNT_MAP_SPECIAL_CHR);
@@ -456,6 +465,8 @@ 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);
+
 	memset(fattr, 0, sizeof(*fattr));
 	fattr->cf_cifsattrs = le32_to_cpu(info->Attributes);
 	if (info->DeletePending)
@@ -470,8 +481,8 @@ cifs_all_info_to_fattr(struct cifs_fattr *fattr, FILE_ALL_INFO *info,
 	fattr->cf_mtime = cifs_NTtimeToUnix(info->LastWriteTime);
 
 	if (adjust_tz) {
-		fattr->cf_ctime.tv_sec += cifs_sb_tcon(cifs_sb)->ses->server->timeAdj;
-		fattr->cf_mtime.tv_sec += cifs_sb_tcon(cifs_sb)->ses->server->timeAdj;
+		fattr->cf_ctime.tv_sec += tcon->ses->server->timeAdj;
+		fattr->cf_mtime.tv_sec += tcon->ses->server->timeAdj;
 	}
 
 	fattr->cf_eof = le64_to_cpu(info->EndOfFile);
@@ -541,15 +552,17 @@ 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_sb_info *cifs_sb = CIFS_SB(sb);
+	struct cifsTconInfo *pTcon = cifs_sb_tcon(cifs_sb);
 	char *buf = NULL;
 	bool adjustTZ = false;
 	struct cifs_fattr fattr;
 
-	pTcon = cifs_sb_tcon(cifs_sb);
 	cFYI(1, ("Getting info on %s", full_path));
 
+	if (IS_ERR(pTcon))
+		return PTR_ERR(pTcon);
+
 	if ((pfindData == NULL) && (*pinode != NULL)) {
 		if (CIFS_I(*pinode)->clientCanCacheRead) {
 			cFYI(1, ("No need to revalidate cached inode sizes"));
@@ -671,6 +684,7 @@ char *cifs_build_path_to_root(struct cifs_sb_info *cifs_sb)
 	int pplen = cifs_sb->prepathlen;
 	int dfsplen;
 	char *full_path = NULL;
+	struct cifsTconInfo *tcon = cifs_sb_master_tcon(cifs_sb);
 
 	/* if no prefix path, simply set path to the root of share to "" */
 	if (pplen == 0) {
@@ -680,8 +694,8 @@ char *cifs_build_path_to_root(struct cifs_sb_info *cifs_sb)
 		return full_path;
 	}
 
-	if (cifs_sb_tcon(cifs_sb) && (cifs_sb_tcon(cifs_sb)->Flags & SMB_SHARE_IS_IN_DFS))
-		dfsplen = strnlen(cifs_sb_tcon(cifs_sb)->treeName, MAX_TREE_SIZE + 1);
+	if (tcon->Flags & SMB_SHARE_IS_IN_DFS)
+		dfsplen = strnlen(tcon->treeName, MAX_TREE_SIZE + 1);
 	else
 		dfsplen = 0;
 
@@ -690,7 +704,7 @@ char *cifs_build_path_to_root(struct cifs_sb_info *cifs_sb)
 		return full_path;
 
 	if (dfsplen) {
-		strncpy(full_path, cifs_sb_tcon(cifs_sb)->treeName, dfsplen);
+		strncpy(full_path, tcon->treeName, dfsplen);
 		/* switch slash direction in prepath depending on whether
 		 * windows or posix style path names
 		 */
@@ -759,18 +773,21 @@ cifs_iget(struct super_block *sb, struct cifs_fattr *fattr)
 struct inode *cifs_root_iget(struct super_block *sb, unsigned long ino)
 {
 	int xid;
-	struct cifs_sb_info *cifs_sb;
+	struct cifs_sb_info *cifs_sb = CIFS_SB(sb);
+	struct cifsTconInfo *tcon = cifs_sb_tcon(cifs_sb);
 	struct inode *inode = NULL;
 	long rc;
 	char *full_path;
 
-	cifs_sb = CIFS_SB(sb);
+	if (IS_ERR(tcon))
+		return (struct inode *) tcon;
+
 	full_path = cifs_build_path_to_root(cifs_sb);
 	if (full_path == NULL)
 		return ERR_PTR(-ENOMEM);
 
 	xid = GetXid();
-	if (cifs_sb_tcon(cifs_sb)->unix_ext)
+	if (tcon->unix_ext)
 		rc = cifs_get_inode_info_unix(&inode, full_path, sb, xid);
 	else
 		rc = cifs_get_inode_info(&inode, full_path, NULL, sb,
@@ -779,7 +796,7 @@ struct inode *cifs_root_iget(struct super_block *sb, unsigned long ino)
 	if (!inode)
 		return ERR_PTR(-ENOMEM);
 
-	if (rc && cifs_sb_tcon(cifs_sb)->ipc) {
+	if (rc && tcon->ipc) {
 		cFYI(1, ("ipc connection - fake read inode"));
 		inode->i_mode |= S_IFDIR;
 		inode->i_nlink = 2;
@@ -862,7 +879,11 @@ cifs_set_file_info(struct inode *inode, struct iattr *attrs, int xid,
 		goto set_via_filehandle;
 	}
 
-	pTcon = open_file->tcon;
+	pTcon = cifs_sb_tcon(cifs_sb);
+	if (IS_ERR(pTcon)) {
+		rc = PTR_ERR(pTcon);
+		goto out;
+	}
 
 	/*
 	 * NT4 apparently returns success on this call, but it doesn't
@@ -928,6 +949,11 @@ cifs_rename_pending_delete(char *full_path, struct dentry *dentry, int xid)
 	__u32 dosattr, origattr;
 	FILE_BASIC_INFO *info_buf = NULL;
 
+	if (IS_ERR(tcon)) {
+		rc = PTR_ERR(tcon);
+		goto out;
+	}
+
 	rc = CIFSSMBOpen(xid, tcon, full_path, FILE_OPEN,
 			 DELETE|FILE_WRITE_ATTRIBUTES, CREATE_NOT_DIR,
 			 &netfid, &oplock, NULL, cifs_sb->local_nls,
@@ -1042,6 +1068,11 @@ int cifs_unlink(struct inode *dir, struct dentry *dentry)
 	cFYI(1, ("cifs_unlink, dir=0x%p, dentry=0x%p", dir, dentry));
 
 	xid = GetXid();
+	if (IS_ERR(tcon)) {
+		rc = PTR_ERR(tcon);
+		FreeXid(xid);
+		return rc;
+	}
 
 	/* Unlink can be called from rename so we can not take the
 	 * sb->s_vfs_rename_mutex here */
@@ -1138,6 +1169,11 @@ int cifs_mkdir(struct inode *inode, struct dentry *direntry, int mode)
 
 	cifs_sb = CIFS_SB(inode->i_sb);
 	pTcon = cifs_sb_tcon(cifs_sb);
+	if (IS_ERR(pTcon)) {
+		rc = PTR_ERR(pTcon);
+		FreeXid(xid);
+		return rc;
+	}
 
 	full_path = build_path_from_dentry(direntry);
 	if (full_path == NULL) {
@@ -1318,6 +1354,11 @@ int cifs_rmdir(struct inode *inode, struct dentry *direntry)
 
 	cifs_sb = CIFS_SB(inode->i_sb);
 	pTcon = cifs_sb_tcon(cifs_sb);
+	if (IS_ERR(pTcon)) {
+		rc = PTR_ERR(pTcon);
+		FreeXid(xid);
+		return rc;
+	}
 
 	full_path = build_path_from_dentry(direntry);
 	if (full_path == NULL) {
@@ -1362,6 +1403,9 @@ cifs_do_rename(int xid, struct dentry *from_dentry, const char *fromPath,
 	__u16 srcfid;
 	int oplock, rc;
 
+	if (IS_ERR(pTcon))
+		return PTR_ERR(pTcon);
+
 	/* try path-based rename first */
 	rc = CIFSSMBRename(xid, pTcon, fromPath, toPath, cifs_sb->local_nls,
 			   cifs_sb->mnt_cifs_flags &
@@ -1400,14 +1444,21 @@ int cifs_rename(struct inode *source_dir, struct dentry *source_dentry,
 	char *toName = NULL;
 	struct cifs_sb_info *cifs_sb_source;
 	struct cifs_sb_info *cifs_sb_target;
-	struct cifsTconInfo *tcon;
+	struct cifsTconInfo *source_tcon, *target_tcon;
 	FILE_UNIX_BASIC_INFO *info_buf_source = NULL;
 	FILE_UNIX_BASIC_INFO *info_buf_target;
 	int xid, rc, tmprc;
 
 	cifs_sb_target = CIFS_SB(target_dir->i_sb);
 	cifs_sb_source = CIFS_SB(source_dir->i_sb);
-	tcon = cifs_sb_tcon(cifs_sb_source);
+	source_tcon = cifs_sb_tcon(cifs_sb_source);
+	target_tcon = cifs_sb_tcon(cifs_sb_target);
+
+	if (IS_ERR(source_tcon))
+		return PTR_ERR(source_tcon);
+
+	if (IS_ERR(target_tcon))
+		return PTR_ERR(target_tcon);
 
 	xid = GetXid();
 
@@ -1415,7 +1466,7 @@ int cifs_rename(struct inode *source_dir, struct dentry *source_dentry,
 	 * BB: this might be allowed if same server, but different share.
 	 * Consider adding support for this
 	 */
-	if (tcon != cifs_sb_tcon(cifs_sb_target)) {
+	if (source_tcon != target_tcon) {
 		rc = -EXDEV;
 		goto cifs_rename_exit;
 	}
@@ -1439,7 +1490,7 @@ int cifs_rename(struct inode *source_dir, struct dentry *source_dentry,
 	rc = cifs_do_rename(xid, source_dentry, fromName,
 			    target_dentry, toName);
 
-	if (rc == -EEXIST && tcon->unix_ext) {
+	if (rc == -EEXIST && source_tcon->unix_ext) {
 		/*
 		 * Are src and dst hardlinks of same inode? We can
 		 * only tell with unix extensions enabled
@@ -1453,7 +1504,7 @@ int cifs_rename(struct inode *source_dir, struct dentry *source_dentry,
 		}
 
 		info_buf_target = info_buf_source + 1;
-		tmprc = CIFSSMBUnixQPathInfo(xid, tcon, fromName,
+		tmprc = CIFSSMBUnixQPathInfo(xid, source_tcon, fromName,
 					info_buf_source,
 					cifs_sb_source->local_nls,
 					cifs_sb_source->mnt_cifs_flags &
@@ -1461,7 +1512,7 @@ int cifs_rename(struct inode *source_dir, struct dentry *source_dentry,
 		if (tmprc != 0)
 			goto unlink_target;
 
-		tmprc = CIFSSMBUnixQPathInfo(xid, tcon,
+		tmprc = CIFSSMBUnixQPathInfo(xid, source_tcon,
 					toName, info_buf_target,
 					cifs_sb_target->local_nls,
 					/* remap based on source sb */
@@ -1564,12 +1615,19 @@ int cifs_revalidate_dentry(struct dentry *dentry)
 	char *full_path = NULL;
 	struct inode *inode = dentry->d_inode;
 	struct super_block *sb = dentry->d_sb;
+	struct cifsTconInfo *tcon;
 
 	if (inode == NULL)
 		return -ENOENT;
 
 	xid = GetXid();
 
+	tcon = cifs_sb_tcon(CIFS_SB(sb));
+	if (IS_ERR(tcon)) {
+		rc = PTR_ERR(tcon);
+		goto check_inval;
+	}
+
 	if (!cifs_inode_needs_reval(inode))
 		goto check_inval;
 
@@ -1692,6 +1750,9 @@ cifs_set_file_size(struct inode *inode, struct iattr *attrs,
 		if (pTcon == NULL)
 			pTcon = cifs_sb_tcon(cifs_sb);
 
+		if (IS_ERR(pTcon))
+			return PTR_ERR(pTcon);
+
 		/* Set file size by pathname rather than by handle
 		   either because no valid, writeable file handle for
 		   it was found or because there was an error setting
@@ -1839,6 +1900,10 @@ cifs_setattr_unix(struct dentry *direntry, struct iattr *attrs)
 		cifsFileInfo_put(open_file);
 	} else {
 		pTcon = cifs_sb_tcon(cifs_sb);
+		if (IS_ERR(pTcon)) {
+			rc = PTR_ERR(pTcon);
+			goto out;
+		}
 		rc = CIFSSMBUnixSetPathInfo(xid, pTcon, full_path, args,
 				    cifs_sb->local_nls,
 				    cifs_sb->mnt_cifs_flags &
@@ -2011,6 +2076,9 @@ cifs_setattr(struct dentry *direntry, struct iattr *attrs)
 	struct cifs_sb_info *cifs_sb = CIFS_SB(inode->i_sb);
 	struct cifsTconInfo *pTcon = cifs_sb_tcon(cifs_sb);
 
+	if (IS_ERR(pTcon))
+		return PTR_ERR(pTcon);
+
 	if (pTcon->unix_ext)
 		return cifs_setattr_unix(direntry, attrs);
 
diff --git a/fs/cifs/link.c b/fs/cifs/link.c
index deff001..72be30c 100644
--- a/fs/cifs/link.c
+++ b/fs/cifs/link.c
@@ -45,6 +45,8 @@ cifs_hardlink(struct dentry *old_file, struct inode *inode,
 
 	cifs_sb_target = CIFS_SB(inode->i_sb);
 	pTcon = cifs_sb_tcon(cifs_sb_target);
+	if (IS_ERR(pTcon))
+		return PTR_ERR(pTcon);
 
 /* No need to check for cross device links since server will do that
    BB note DFS case in future though (when we may have to check) */
@@ -117,6 +119,11 @@ cifs_follow_link(struct dentry *direntry, struct nameidata *nd)
 
 	xid = GetXid();
 
+	if (IS_ERR(tcon)) {
+		rc = PTR_ERR(tcon);
+		goto out;
+	}
+
 	/*
 	 * For now, we just handle symlinks with unix extensions enabled.
 	 * Eventually we should handle NTFS reparse points, and MacOS
@@ -169,9 +176,13 @@ cifs_symlink(struct inode *inode, struct dentry *direntry, const char *symname)
 
 	cifs_sb = CIFS_SB(inode->i_sb);
 	pTcon = cifs_sb_tcon(cifs_sb);
+	if (IS_ERR(pTcon)) {
+		rc = PTR_ERR(pTcon);
+		FreeXid(xid);
+		return rc;
+	}
 
 	full_path = build_path_from_dentry(direntry);
-
 	if (full_path == NULL) {
 		rc = -ENOMEM;
 		FreeXid(xid);
diff --git a/fs/cifs/misc.c b/fs/cifs/misc.c
index 789cf12..28cfccd 100644
--- a/fs/cifs/misc.c
+++ b/fs/cifs/misc.c
@@ -724,6 +724,6 @@ cifs_autodisable_serverino(struct cifs_sb_info *cifs_sb)
 			   "properly. Hardlinks will not be recognized on this "
 			   "mount. Consider mounting with the \"noserverino\" "
 			   "option to silence this message.",
-			   cifs_sb_tcon(cifs_sb)->treeName));
+			   cifs_sb_master_tcon(cifs_sb)->treeName));
 	}
 }
diff --git a/fs/cifs/readdir.c b/fs/cifs/readdir.c
index 17effab..10b987b 100644
--- a/fs/cifs/readdir.c
+++ b/fs/cifs/readdir.c
@@ -102,7 +102,7 @@ cifs_readdir_lookup(struct dentry *parent, struct qstr *name,
 		return NULL;
 	}
 
-	if (cifs_sb_tcon(CIFS_SB(sb))->nocase)
+	if (cifs_sb_master_tcon(CIFS_SB(sb))->nocase)
 		dentry->d_op = &cifs_ci_dentry_ops;
 	else
 		dentry->d_op = &cifs_dentry_ops;
@@ -171,7 +171,7 @@ static void
 cifs_std_info_to_fattr(struct cifs_fattr *fattr, FIND_FILE_STANDARD_INFO *info,
 		       struct cifs_sb_info *cifs_sb)
 {
-	int offset = cifs_sb_tcon(cifs_sb)->ses->server->timeAdj;
+	int offset = cifs_sb_master_tcon(cifs_sb)->ses->server->timeAdj;
 
 	memset(fattr, 0, sizeof(*fattr));
 	fattr->cf_atime = cnvrtDosUnixTm(info->LastAccessDate,
@@ -232,6 +232,10 @@ static int initiate_cifs_search(const int xid, struct file *file)
 	if (cifs_sb == NULL)
 		return -EINVAL;
 
+	pTcon = cifs_sb_tcon(cifs_sb);
+	if (IS_ERR(pTcon))
+		return PTR_ERR(pTcon);
+
 	if (file->private_data == NULL)
 		file->private_data =
 			kzalloc(sizeof(struct cifsFileInfo), GFP_KERNEL);
@@ -241,11 +245,9 @@ static int initiate_cifs_search(const int xid, struct file *file)
 	cifsFile = file->private_data;
 	cifsFile->invalidHandle = true;
 	cifsFile->srch_inf.endOfSearch = false;
-	cifsFile->tcon = cifs_sb_tcon(cifs_sb);
+	cifsFile->tcon = pTcon;
 
 	pTcon = cifsFile->tcon;
-	if (pTcon == NULL)
-		return -EINVAL;
 
 	full_path = build_path_from_dentry(file->f_path.dentry);
 
diff --git a/fs/cifs/xattr.c b/fs/cifs/xattr.c
index 2161019..77ee3b6 100644
--- a/fs/cifs/xattr.c
+++ b/fs/cifs/xattr.c
@@ -62,6 +62,11 @@ int cifs_removexattr(struct dentry *direntry, const char *ea_name)
 
 	cifs_sb = CIFS_SB(sb);
 	pTcon = cifs_sb_tcon(cifs_sb);
+	if (IS_ERR(pTcon)) {
+		rc = PTR_ERR(pTcon);
+		FreeXid(xid);
+		return rc;
+	}
 
 	full_path = build_path_from_dentry(direntry);
 	if (full_path == NULL) {
@@ -117,6 +122,11 @@ int cifs_setxattr(struct dentry *direntry, const char *ea_name,
 
 	cifs_sb = CIFS_SB(sb);
 	pTcon = cifs_sb_tcon(cifs_sb);
+	if (IS_ERR(pTcon)) {
+		rc = PTR_ERR(pTcon);
+		FreeXid(xid);
+		return rc;
+	}
 
 	full_path = build_path_from_dentry(direntry);
 	if (full_path == NULL) {
@@ -225,6 +235,11 @@ ssize_t cifs_getxattr(struct dentry *direntry, const char *ea_name,
 
 	cifs_sb = CIFS_SB(sb);
 	pTcon = cifs_sb_tcon(cifs_sb);
+	if (IS_ERR(pTcon)) {
+		rc = PTR_ERR(pTcon);
+		FreeXid(xid);
+		return rc;
+	}
 
 	full_path = build_path_from_dentry(direntry);
 	if (full_path == NULL) {
@@ -346,13 +361,19 @@ ssize_t cifs_listxattr(struct dentry *direntry, char *data, size_t buf_size)
 		return -EIO;
 
 	cifs_sb = CIFS_SB(sb);
-	pTcon = cifs_sb_tcon(cifs_sb);
 
 	if (cifs_sb->mnt_cifs_flags & CIFS_MOUNT_NO_XATTR)
 		return -EOPNOTSUPP;
 
 	xid = GetXid();
 
+	pTcon = cifs_sb_tcon(cifs_sb);
+	if (IS_ERR(pTcon)) {
+		rc = PTR_ERR(pTcon);
+		FreeXid(xid);
+		return rc;
+	}
+
 	full_path = build_path_from_dentry(direntry);
 	if (full_path == NULL) {
 		rc = -ENOMEM;
-- 
1.6.6.1
lmpx.com only provides a reader for public news (NNTP) servers. It is not affiliated with the servers or forums shown here and is not responsible for the content of articles, which is written by their respective authors.