aboutsummaryrefslogtreecommitdiffstats
path: root/fs/cifs/inode.c
diff options
context:
space:
mode:
authorSteve French <sfrench@us.ibm.com>2008-05-14 21:50:56 -0400
committerSteve French <sfrench@us.ibm.com>2008-05-14 21:50:56 -0400
commit646dd539878a194bc14b104621c0b2b33587e40f (patch)
treeba3e9a8a9565e66ea53905b209438fae6d413853 /fs/cifs/inode.c
parent35fc37d5175091c36d034a28c057da0f9594ee7e (diff)
[CIFS] Fix paths when share is in DFS to include proper prefix
Some versions of Samba (3.2-pre e.g.) are stricter about checking to make sure that paths in DFS name spaces are sent in the form \\server\share\dir\subdir ... instead of \dir\subdir Acked-by: Jeff Layton <jlayton@redhat.com> Signed-off-by: Steve French <sfrench@us.ibm.com>
Diffstat (limited to 'fs/cifs/inode.c')
-rw-r--r--fs/cifs/inode.c65
1 files changed, 8 insertions, 57 deletions
diff --git a/fs/cifs/inode.c b/fs/cifs/inode.c
index 2d53b436d511..9d9b56a9c08e 100644
--- a/fs/cifs/inode.c
+++ b/fs/cifs/inode.c
@@ -161,52 +161,18 @@ static void cifs_unix_info_to_inode(struct inode *inode,
161 spin_unlock(&inode->i_lock); 161 spin_unlock(&inode->i_lock);
162} 162}
163 163
164static const unsigned char *cifs_get_search_path(struct cifs_sb_info *cifs_sb,
165 const char *search_path)
166{
167 int tree_len;
168 int path_len;
169 int i;
170 char *tmp_path;
171 struct cifsTconInfo *pTcon = cifs_sb->tcon;
172
173 if (!(pTcon->Flags & SMB_SHARE_IS_IN_DFS))
174 return search_path;
175
176 /* use full path name for working with DFS */
177 tree_len = strnlen(pTcon->treeName, MAX_TREE_SIZE + 1);
178 path_len = strnlen(search_path, MAX_PATHCONF);
179
180 tmp_path = kmalloc(tree_len+path_len+1, GFP_KERNEL);
181 if (tmp_path == NULL)
182 return search_path;
183
184 strncpy(tmp_path, pTcon->treeName, tree_len);
185 if (cifs_sb->mnt_cifs_flags & CIFS_MOUNT_POSIX_PATHS)
186 for (i = 0; i < tree_len; i++) {
187 if (tmp_path[i] == '\\')
188 tmp_path[i] = '/';
189 }
190 strncpy(tmp_path+tree_len, search_path, path_len);
191 tmp_path[tree_len+path_len] = 0;
192 return tmp_path;
193}
194
195int cifs_get_inode_info_unix(struct inode **pinode, 164int cifs_get_inode_info_unix(struct inode **pinode,
196 const unsigned char *search_path, struct super_block *sb, int xid) 165 const unsigned char *full_path, struct super_block *sb, int xid)
197{ 166{
198 int rc = 0; 167 int rc = 0;
199 FILE_UNIX_BASIC_INFO findData; 168 FILE_UNIX_BASIC_INFO findData;
200 struct cifsTconInfo *pTcon; 169 struct cifsTconInfo *pTcon;
201 struct inode *inode; 170 struct inode *inode;
202 struct cifs_sb_info *cifs_sb = CIFS_SB(sb); 171 struct cifs_sb_info *cifs_sb = CIFS_SB(sb);
203 const unsigned char *full_path;
204 bool is_dfs_referral = false; 172 bool is_dfs_referral = false;
205 173
206 pTcon = cifs_sb->tcon; 174 pTcon = cifs_sb->tcon;
207 cFYI(1, ("Getting info on %s", search_path)); 175 cFYI(1, ("Getting info on %s", full_path));
208
209 full_path = cifs_get_search_path(cifs_sb, search_path);
210 176
211try_again_CIFSSMBUnixQPathInfo: 177try_again_CIFSSMBUnixQPathInfo:
212 /* could have done a find first instead but this returns more info */ 178 /* could have done a find first instead but this returns more info */
@@ -218,10 +184,6 @@ try_again_CIFSSMBUnixQPathInfo:
218 if (rc) { 184 if (rc) {
219 if (rc == -EREMOTE && !is_dfs_referral) { 185 if (rc == -EREMOTE && !is_dfs_referral) {
220 is_dfs_referral = true; 186 is_dfs_referral = true;
221 if (full_path != search_path) {
222 kfree(full_path);
223 full_path = search_path;
224 }
225 goto try_again_CIFSSMBUnixQPathInfo; 187 goto try_again_CIFSSMBUnixQPathInfo;
226 } 188 }
227 goto cgiiu_exit; 189 goto cgiiu_exit;
@@ -271,8 +233,6 @@ try_again_CIFSSMBUnixQPathInfo:
271 cifs_set_ops(inode, is_dfs_referral); 233 cifs_set_ops(inode, is_dfs_referral);
272 } 234 }
273cgiiu_exit: 235cgiiu_exit:
274 if (full_path != search_path)
275 kfree(full_path);
276 return rc; 236 return rc;
277} 237}
278 238
@@ -380,20 +340,19 @@ static int get_sfu_mode(struct inode *inode,
380} 340}
381 341
382int cifs_get_inode_info(struct inode **pinode, 342int cifs_get_inode_info(struct inode **pinode,
383 const unsigned char *search_path, FILE_ALL_INFO *pfindData, 343 const unsigned char *full_path, FILE_ALL_INFO *pfindData,
384 struct super_block *sb, int xid, const __u16 *pfid) 344 struct super_block *sb, int xid, const __u16 *pfid)
385{ 345{
386 int rc = 0; 346 int rc = 0;
387 struct cifsTconInfo *pTcon; 347 struct cifsTconInfo *pTcon;
388 struct inode *inode; 348 struct inode *inode;
389 struct cifs_sb_info *cifs_sb = CIFS_SB(sb); 349 struct cifs_sb_info *cifs_sb = CIFS_SB(sb);
390 const unsigned char *full_path = NULL;
391 char *buf = NULL; 350 char *buf = NULL;
392 bool adjustTZ = false; 351 bool adjustTZ = false;
393 bool is_dfs_referral = false; 352 bool is_dfs_referral = false;
394 353
395 pTcon = cifs_sb->tcon; 354 pTcon = cifs_sb->tcon;
396 cFYI(1, ("Getting info on %s", search_path)); 355 cFYI(1, ("Getting info on %s", full_path));
397 356
398 if ((pfindData == NULL) && (*pinode != NULL)) { 357 if ((pfindData == NULL) && (*pinode != NULL)) {
399 if (CIFS_I(*pinode)->clientCanCacheRead) { 358 if (CIFS_I(*pinode)->clientCanCacheRead) {
@@ -409,8 +368,6 @@ int cifs_get_inode_info(struct inode **pinode,
409 return -ENOMEM; 368 return -ENOMEM;
410 pfindData = (FILE_ALL_INFO *)buf; 369 pfindData = (FILE_ALL_INFO *)buf;
411 370
412 full_path = cifs_get_search_path(cifs_sb, search_path);
413
414try_again_CIFSSMBQPathInfo: 371try_again_CIFSSMBQPathInfo:
415 /* could do find first instead but this returns more info */ 372 /* could do find first instead but this returns more info */
416 rc = CIFSSMBQPathInfo(xid, pTcon, full_path, pfindData, 373 rc = CIFSSMBQPathInfo(xid, pTcon, full_path, pfindData,
@@ -432,10 +389,6 @@ try_again_CIFSSMBQPathInfo:
432 if (rc) { 389 if (rc) {
433 if (rc == -EREMOTE && !is_dfs_referral) { 390 if (rc == -EREMOTE && !is_dfs_referral) {
434 is_dfs_referral = true; 391 is_dfs_referral = true;
435 if (full_path != search_path) {
436 kfree(full_path);
437 full_path = search_path;
438 }
439 goto try_again_CIFSSMBQPathInfo; 392 goto try_again_CIFSSMBQPathInfo;
440 } 393 }
441 goto cgii_exit; 394 goto cgii_exit;
@@ -470,7 +423,7 @@ try_again_CIFSSMBQPathInfo:
470 __u64 inode_num; 423 __u64 inode_num;
471 424
472 rc1 = CIFSGetSrvInodeNumber(xid, pTcon, 425 rc1 = CIFSGetSrvInodeNumber(xid, pTcon,
473 search_path, &inode_num, 426 full_path, &inode_num,
474 cifs_sb->local_nls, 427 cifs_sb->local_nls,
475 cifs_sb->mnt_cifs_flags & 428 cifs_sb->mnt_cifs_flags &
476 CIFS_MOUNT_MAP_SPECIAL_CHR); 429 CIFS_MOUNT_MAP_SPECIAL_CHR);
@@ -539,7 +492,7 @@ try_again_CIFSSMBQPathInfo:
539 (cifsInfo->cifsAttrs & ATTR_SYSTEM)) { 492 (cifsInfo->cifsAttrs & ATTR_SYSTEM)) {
540 if (decode_sfu_inode(inode, 493 if (decode_sfu_inode(inode,
541 le64_to_cpu(pfindData->EndOfFile), 494 le64_to_cpu(pfindData->EndOfFile),
542 search_path, 495 full_path,
543 cifs_sb, xid)) 496 cifs_sb, xid))
544 cFYI(1, ("Unrecognized sfu inode type")); 497 cFYI(1, ("Unrecognized sfu inode type"));
545 498
@@ -582,12 +535,12 @@ try_again_CIFSSMBQPathInfo:
582 /* fill in 0777 bits from ACL */ 535 /* fill in 0777 bits from ACL */
583 if (cifs_sb->mnt_cifs_flags & CIFS_MOUNT_CIFS_ACL) { 536 if (cifs_sb->mnt_cifs_flags & CIFS_MOUNT_CIFS_ACL) {
584 cFYI(1, ("Getting mode bits from ACL")); 537 cFYI(1, ("Getting mode bits from ACL"));
585 acl_to_uid_mode(inode, search_path, pfid); 538 acl_to_uid_mode(inode, full_path, pfid);
586 } 539 }
587#endif 540#endif
588 if (cifs_sb->mnt_cifs_flags & CIFS_MOUNT_UNX_EMUL) { 541 if (cifs_sb->mnt_cifs_flags & CIFS_MOUNT_UNX_EMUL) {
589 /* fill in remaining high mode bits e.g. SUID, VTX */ 542 /* fill in remaining high mode bits e.g. SUID, VTX */
590 get_sfu_mode(inode, search_path, cifs_sb, xid); 543 get_sfu_mode(inode, full_path, cifs_sb, xid);
591 } else if (atomic_read(&cifsInfo->inUse) == 0) { 544 } else if (atomic_read(&cifsInfo->inUse) == 0) {
592 inode->i_uid = cifs_sb->mnt_uid; 545 inode->i_uid = cifs_sb->mnt_uid;
593 inode->i_gid = cifs_sb->mnt_gid; 546 inode->i_gid = cifs_sb->mnt_gid;
@@ -599,8 +552,6 @@ try_again_CIFSSMBQPathInfo:
599 cifs_set_ops(inode, is_dfs_referral); 552 cifs_set_ops(inode, is_dfs_referral);
600 } 553 }
601cgii_exit: 554cgii_exit:
602 if (full_path != search_path)
603 kfree(full_path);
604 kfree(buf); 555 kfree(buf);
605 return rc; 556 return rc;
606} 557}