aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--fs/cifs/cifs_dfs_ref.c14
-rw-r--r--fs/cifs/cifsglob.h41
-rw-r--r--fs/cifs/cifsproto.h4
-rw-r--r--fs/cifs/connect.c12
-rw-r--r--fs/cifs/dns_resolve.c5
-rw-r--r--fs/cifs/link.c16
6 files changed, 61 insertions, 31 deletions
diff --git a/fs/cifs/cifs_dfs_ref.c b/fs/cifs/cifs_dfs_ref.c
index 15e31f8435ba..413ee2349d1a 100644
--- a/fs/cifs/cifs_dfs_ref.c
+++ b/fs/cifs/cifs_dfs_ref.c
@@ -3,8 +3,9 @@
3 * traversal via DFS junction point 3 * traversal via DFS junction point
4 * 4 *
5 * Copyright (c) 2007 Igor Mammedov 5 * Copyright (c) 2007 Igor Mammedov
6 * Copyright (C) International Business Machines Corp., 2008
6 * Author(s): Igor Mammedov (niallain@gmail.com) 7 * Author(s): Igor Mammedov (niallain@gmail.com)
7 * 8 * Steve French (sfrench@us.ibm.com)
8 * This program is free software; you can redistribute it and/or 9 * This program is free software; you can redistribute it and/or
9 * modify it under the terms of the GNU General Public License 10 * modify it under the terms of the GNU General Public License
10 * as published by the Free Software Foundation; either version 11 * as published by the Free Software Foundation; either version
@@ -107,8 +108,9 @@ static char *cifs_get_share_name(const char *node_name)
107 * Returns: pointer to new mount options or ERR_PTR. 108 * Returns: pointer to new mount options or ERR_PTR.
108 * Caller is responcible for freeing retunrned value if it is not error. 109 * Caller is responcible for freeing retunrned value if it is not error.
109 */ 110 */
110char *compose_mount_options(const char *sb_mountdata, const char *ref_unc, 111static char *compose_mount_options(const char *sb_mountdata,
111 char **devname) 112 const char *ref_unc,
113 char **devname)
112{ 114{
113 int rc; 115 int rc;
114 char *mountdata; 116 char *mountdata;
@@ -188,13 +190,13 @@ compose_mount_options_out:
188} 190}
189 191
190 192
191struct vfsmount *cifs_dfs_do_refmount(const struct vfsmount *mnt_parent, 193static struct vfsmount *cifs_dfs_do_refmount(const struct vfsmount *mnt_parent,
192 struct dentry *dentry, char *ref_unc) 194 struct dentry *dentry, char *ref_unc)
193{ 195{
194 struct cifs_sb_info *cifs_sb; 196 struct cifs_sb_info *cifs_sb;
195 struct vfsmount *mnt; 197 struct vfsmount *mnt;
196 char *mountdata; 198 char *mountdata;
197 char *devname; 199 char *devname = NULL;
198 200
199 cifs_sb = CIFS_SB(dentry->d_inode->i_sb); 201 cifs_sb = CIFS_SB(dentry->d_inode->i_sb);
200 mountdata = compose_mount_options(cifs_sb->mountdata, 202 mountdata = compose_mount_options(cifs_sb->mountdata,
@@ -278,7 +280,7 @@ static int add_mount_helper(struct vfsmount *newmnt, struct nameidata *nd,
278 return err; 280 return err;
279} 281}
280 282
281void dump_referral(const struct dfs_info3_param *ref) 283static void dump_referral(const struct dfs_info3_param *ref)
282{ 284{
283 cFYI(1, ("DFS: ref path: %s", ref->path_name)); 285 cFYI(1, ("DFS: ref path: %s", ref->path_name));
284 cFYI(1, ("DFS: node path: %s", ref->node_name)); 286 cFYI(1, ("DFS: node path: %s", ref->node_name));
diff --git a/fs/cifs/cifsglob.h b/fs/cifs/cifsglob.h
index 1fde2197ad76..5d32d8ddc82e 100644
--- a/fs/cifs/cifsglob.h
+++ b/fs/cifs/cifsglob.h
@@ -1,7 +1,7 @@
1/* 1/*
2 * fs/cifs/cifsglob.h 2 * fs/cifs/cifsglob.h
3 * 3 *
4 * Copyright (C) International Business Machines Corp., 2002,2007 4 * Copyright (C) International Business Machines Corp., 2002,2008
5 * Author(s): Steve French (sfrench@us.ibm.com) 5 * Author(s): Steve French (sfrench@us.ibm.com)
6 * Jeremy Allison (jra@samba.org) 6 * Jeremy Allison (jra@samba.org)
7 * 7 *
@@ -70,14 +70,6 @@
70#endif 70#endif
71 71
72/* 72/*
73 * This information is kept on every Server we know about.
74 *
75 * Some things to note:
76 *
77 */
78#define SERVER_NAME_LEN_WITH_NULL (SERVER_NAME_LENGTH + 1)
79
80/*
81 * CIFS vfs client Status information (based on what we know.) 73 * CIFS vfs client Status information (based on what we know.)
82 */ 74 */
83 75
@@ -460,6 +452,37 @@ struct dir_notify_req {
460 struct file *pfile; 452 struct file *pfile;
461}; 453};
462 454
455struct dfs_info3_param {
456 int flags; /* DFSREF_REFERRAL_SERVER, DFSREF_STORAGE_SERVER*/
457 int PathConsumed;
458 int server_type;
459 int ref_flag;
460 char *path_name;
461 char *node_name;
462};
463
464static inline void free_dfs_info_param(struct dfs_info3_param *param)
465{
466 if (param) {
467 kfree(param->path_name);
468 kfree(param->node_name);
469 kfree(param);
470 }
471}
472
473static inline void free_dfs_info_array(struct dfs_info3_param *param,
474 int number_of_items)
475{
476 int i;
477 if ((number_of_items == 0) || (param == NULL))
478 return;
479 for (i = 0; i < number_of_items; i++) {
480 kfree(param[i].path_name);
481 kfree(param[i].node_name);
482 }
483 kfree(param);
484}
485
463#define MID_FREE 0 486#define MID_FREE 0
464#define MID_REQUEST_ALLOCATED 1 487#define MID_REQUEST_ALLOCATED 1
465#define MID_REQUEST_SUBMITTED 2 488#define MID_REQUEST_SUBMITTED 2
diff --git a/fs/cifs/cifsproto.h b/fs/cifs/cifsproto.h
index aaaf748f6a26..2f09f565a3d9 100644
--- a/fs/cifs/cifsproto.h
+++ b/fs/cifs/cifsproto.h
@@ -1,7 +1,7 @@
1/* 1/*
2 * fs/cifs/cifsproto.h 2 * fs/cifs/cifsproto.h
3 * 3 *
4 * Copyright (c) International Business Machines Corp., 2002,2007 4 * Copyright (c) International Business Machines Corp., 2002,2008
5 * Author(s): Steve French (sfrench@us.ibm.com) 5 * Author(s): Steve French (sfrench@us.ibm.com)
6 * 6 *
7 * This library is free software; you can redistribute it and/or modify 7 * This library is free software; you can redistribute it and/or modify
@@ -156,7 +156,7 @@ extern int get_dfs_path(int xid, struct cifsSesInfo *pSesInfo,
156 const char *old_path, 156 const char *old_path,
157 const struct nls_table *nls_codepage, 157 const struct nls_table *nls_codepage,
158 unsigned int *pnum_referrals, 158 unsigned int *pnum_referrals,
159 unsigned char **preferrals, 159 struct dfs_info3_param **preferrals,
160 int remap); 160 int remap);
161extern void reset_cifs_unix_caps(int xid, struct cifsTconInfo *tcon, 161extern void reset_cifs_unix_caps(int xid, struct cifsTconInfo *tcon,
162 struct super_block *sb, struct smb_vol *vol); 162 struct super_block *sb, struct smb_vol *vol);
diff --git a/fs/cifs/connect.c b/fs/cifs/connect.c
index db3746c891b5..65d0ba72e78f 100644
--- a/fs/cifs/connect.c
+++ b/fs/cifs/connect.c
@@ -1,7 +1,7 @@
1/* 1/*
2 * fs/cifs/connect.c 2 * fs/cifs/connect.c
3 * 3 *
4 * Copyright (C) International Business Machines Corp., 2002,2007 4 * Copyright (C) International Business Machines Corp., 2002,2008
5 * Author(s): Steve French (sfrench@us.ibm.com) 5 * Author(s): Steve French (sfrench@us.ibm.com)
6 * 6 *
7 * This library is free software; you can redistribute it and/or modify 7 * This library is free software; you can redistribute it and/or modify
@@ -1410,7 +1410,7 @@ connect_to_dfs_path(int xid, struct cifsSesInfo *pSesInfo,
1410 const char *old_path, const struct nls_table *nls_codepage, 1410 const char *old_path, const struct nls_table *nls_codepage,
1411 int remap) 1411 int remap)
1412{ 1412{
1413 unsigned char *referrals = NULL; 1413 struct dfs_info3_param *referrals = NULL;
1414 unsigned int num_referrals; 1414 unsigned int num_referrals;
1415 int rc = 0; 1415 int rc = 0;
1416 1416
@@ -1429,12 +1429,14 @@ connect_to_dfs_path(int xid, struct cifsSesInfo *pSesInfo,
1429int 1429int
1430get_dfs_path(int xid, struct cifsSesInfo *pSesInfo, const char *old_path, 1430get_dfs_path(int xid, struct cifsSesInfo *pSesInfo, const char *old_path,
1431 const struct nls_table *nls_codepage, unsigned int *pnum_referrals, 1431 const struct nls_table *nls_codepage, unsigned int *pnum_referrals,
1432 unsigned char **preferrals, int remap) 1432 struct dfs_info3_param **preferrals, int remap)
1433{ 1433{
1434 char *temp_unc; 1434 char *temp_unc;
1435 int rc = 0; 1435 int rc = 0;
1436 unsigned char *targetUNCs;
1436 1437
1437 *pnum_referrals = 0; 1438 *pnum_referrals = 0;
1439 *preferrals = NULL;
1438 1440
1439 if (pSesInfo->ipc_tid == 0) { 1441 if (pSesInfo->ipc_tid == 0) {
1440 temp_unc = kmalloc(2 /* for slashes */ + 1442 temp_unc = kmalloc(2 /* for slashes */ +
@@ -1454,8 +1456,10 @@ get_dfs_path(int xid, struct cifsSesInfo *pSesInfo, const char *old_path,
1454 kfree(temp_unc); 1456 kfree(temp_unc);
1455 } 1457 }
1456 if (rc == 0) 1458 if (rc == 0)
1457 rc = CIFSGetDFSRefer(xid, pSesInfo, old_path, preferrals, 1459 rc = CIFSGetDFSRefer(xid, pSesInfo, old_path, &targetUNCs,
1458 pnum_referrals, nls_codepage, remap); 1460 pnum_referrals, nls_codepage, remap);
1461 /* BB map targetUNCs to dfs_info3 structures, here or
1462 in CIFSGetDFSRefer BB */
1459 1463
1460 return rc; 1464 return rc;
1461} 1465}
diff --git a/fs/cifs/dns_resolve.c b/fs/cifs/dns_resolve.c
index 777a086abd6f..ef7f43824347 100644
--- a/fs/cifs/dns_resolve.c
+++ b/fs/cifs/dns_resolve.c
@@ -64,13 +64,14 @@ struct key_type key_type_dns_resolver = {
64 * return 0 on success 64 * return 0 on success
65 */ 65 */
66int 66int
67dns_resolve_server_name_to_ip(const char *unc, char **ip_addr) { 67dns_resolve_server_name_to_ip(const char *unc, char **ip_addr)
68{
68 int rc = -EAGAIN; 69 int rc = -EAGAIN;
69 struct key *rkey; 70 struct key *rkey;
70 char *name; 71 char *name;
71 int len; 72 int len;
72 73
73 if ((!ip_addr) || (!unc)) 74 if (!ip_addr || !unc)
74 return -EINVAL; 75 return -EINVAL;
75 76
76 /* search for server name delimiter */ 77 /* search for server name delimiter */
diff --git a/fs/cifs/link.c b/fs/cifs/link.c
index 11f265726db7..1d6fb01b8e6d 100644
--- a/fs/cifs/link.c
+++ b/fs/cifs/link.c
@@ -1,7 +1,7 @@
1/* 1/*
2 * fs/cifs/link.c 2 * fs/cifs/link.c
3 * 3 *
4 * Copyright (C) International Business Machines Corp., 2002,2003 4 * Copyright (C) International Business Machines Corp., 2002,2008
5 * Author(s): Steve French (sfrench@us.ibm.com) 5 * Author(s): Steve French (sfrench@us.ibm.com)
6 * 6 *
7 * This library is free software; you can redistribute it and/or modify 7 * This library is free software; you can redistribute it and/or modify
@@ -236,8 +236,6 @@ cifs_readlink(struct dentry *direntry, char __user *pBuffer, int buflen)
236 char *full_path = NULL; 236 char *full_path = NULL;
237 char *tmp_path = NULL; 237 char *tmp_path = NULL;
238 char *tmpbuffer; 238 char *tmpbuffer;
239 unsigned char *referrals = NULL;
240 unsigned int num_referrals = 0;
241 int len; 239 int len;
242 __u16 fid; 240 __u16 fid;
243 241
@@ -297,8 +295,11 @@ cifs_readlink(struct dentry *direntry, char __user *pBuffer, int buflen)
297 cFYI(1, ("Error closing junction point " 295 cFYI(1, ("Error closing junction point "
298 "(open for ioctl)")); 296 "(open for ioctl)"));
299 } 297 }
298 /* BB unwind this long, nested function, or remove BB */
300 if (rc == -EIO) { 299 if (rc == -EIO) {
301 /* Query if DFS Junction */ 300 /* Query if DFS Junction */
301 unsigned int num_referrals = 0;
302 struct dfs_info3_param *refs = NULL;
302 tmp_path = 303 tmp_path =
303 kmalloc(MAX_TREE_SIZE + MAX_PATHCONF + 1, 304 kmalloc(MAX_TREE_SIZE + MAX_PATHCONF + 1,
304 GFP_KERNEL); 305 GFP_KERNEL);
@@ -310,7 +311,7 @@ cifs_readlink(struct dentry *direntry, char __user *pBuffer, int buflen)
310 rc = get_dfs_path(xid, pTcon->ses, 311 rc = get_dfs_path(xid, pTcon->ses,
311 tmp_path, 312 tmp_path,
312 cifs_sb->local_nls, 313 cifs_sb->local_nls,
313 &num_referrals, &referrals, 314 &num_referrals, &refs,
314 cifs_sb->mnt_cifs_flags & 315 cifs_sb->mnt_cifs_flags &
315 CIFS_MOUNT_MAP_SPECIAL_CHR); 316 CIFS_MOUNT_MAP_SPECIAL_CHR);
316 cFYI(1, ("Get DFS for %s rc = %d ", 317 cFYI(1, ("Get DFS for %s rc = %d ",
@@ -320,14 +321,13 @@ cifs_readlink(struct dentry *direntry, char __user *pBuffer, int buflen)
320 else { 321 else {
321 cFYI(1, ("num referral: %d", 322 cFYI(1, ("num referral: %d",
322 num_referrals)); 323 num_referrals));
323 if (referrals) { 324 if (refs && refs->path_name) {
324 cFYI(1,("referral string: %s", referrals));
325 strncpy(tmpbuffer, 325 strncpy(tmpbuffer,
326 referrals, 326 refs->path_name,
327 len-1); 327 len-1);
328 } 328 }
329 } 329 }
330 kfree(referrals); 330 kfree(refs);
331 kfree(tmp_path); 331 kfree(tmp_path);
332} 332}
333 /* BB add code like else decode referrals 333 /* BB add code like else decode referrals