aboutsummaryrefslogtreecommitdiffstats
path: root/fs/cifs/link.c
diff options
context:
space:
mode:
authorStefan Metzmacher <metze@samba.org>2010-08-05 15:19:56 -0400
committerSteve French <sfrench@us.ibm.com>2010-09-29 15:04:31 -0400
commit1b12b9c15b4371d83b729b8fc18c670e78a1479b (patch)
treef82c9b0d01cdc5e64765780403f460e9e0d8496b /fs/cifs/link.c
parent8713d01db8bf948eb9632726f529ec4f821bb025 (diff)
cifs: use Minshall+French symlink functions
If configured, Minshall+French Symlinks are used against all servers. If the server supports UNIX Extensions, we still create Minshall+French Symlinks on write, but on read we fallback to UNIX Extension symlinks. Signed-off-by: Stefan Metzmacher <metze@samba.org> Signed-off-by: Steve French <sfrench@us.ibm.com>
Diffstat (limited to 'fs/cifs/link.c')
-rw-r--r--fs/cifs/link.c27
1 files changed, 23 insertions, 4 deletions
diff --git a/fs/cifs/link.c b/fs/cifs/link.c
index 1b2a8c971995..cbf7b112287b 100644
--- a/fs/cifs/link.c
+++ b/fs/cifs/link.c
@@ -407,7 +407,8 @@ cifs_follow_link(struct dentry *direntry, struct nameidata *nd)
407 * but there doesn't seem to be any harm in allowing the client to 407 * but there doesn't seem to be any harm in allowing the client to
408 * read them. 408 * read them.
409 */ 409 */
410 if (!(tcon->ses->capabilities & CAP_UNIX)) { 410 if (!(cifs_sb->mnt_cifs_flags & CIFS_MOUNT_MF_SYMLINKS)
411 && !(tcon->ses->capabilities & CAP_UNIX)) {
411 rc = -EACCES; 412 rc = -EACCES;
412 goto out; 413 goto out;
413 } 414 }
@@ -418,8 +419,21 @@ cifs_follow_link(struct dentry *direntry, struct nameidata *nd)
418 419
419 cFYI(1, "Full path: %s inode = 0x%p", full_path, inode); 420 cFYI(1, "Full path: %s inode = 0x%p", full_path, inode);
420 421
421 rc = CIFSSMBUnixQuerySymLink(xid, tcon, full_path, &target_path, 422 rc = -EACCES;
422 cifs_sb->local_nls); 423 /*
424 * First try Minshall+French Symlinks, if configured
425 * and fallback to UNIX Extensions Symlinks.
426 */
427 if (cifs_sb->mnt_cifs_flags & CIFS_MOUNT_MF_SYMLINKS)
428 rc = CIFSQueryMFSymLink(xid, tcon, full_path, &target_path,
429 cifs_sb->local_nls,
430 cifs_sb->mnt_cifs_flags &
431 CIFS_MOUNT_MAP_SPECIAL_CHR);
432
433 if ((rc != 0) && (tcon->ses->capabilities & CAP_UNIX))
434 rc = CIFSSMBUnixQuerySymLink(xid, tcon, full_path, &target_path,
435 cifs_sb->local_nls);
436
423 kfree(full_path); 437 kfree(full_path);
424out: 438out:
425 if (rc != 0) { 439 if (rc != 0) {
@@ -459,7 +473,12 @@ cifs_symlink(struct inode *inode, struct dentry *direntry, const char *symname)
459 cFYI(1, "symname is %s", symname); 473 cFYI(1, "symname is %s", symname);
460 474
461 /* BB what if DFS and this volume is on different share? BB */ 475 /* BB what if DFS and this volume is on different share? BB */
462 if (pTcon->unix_ext) 476 if (cifs_sb->mnt_cifs_flags & CIFS_MOUNT_MF_SYMLINKS)
477 rc = CIFSCreateMFSymLink(xid, pTcon, full_path, symname,
478 cifs_sb->local_nls,
479 cifs_sb->mnt_cifs_flags &
480 CIFS_MOUNT_MAP_SPECIAL_CHR);
481 else if (pTcon->unix_ext)
463 rc = CIFSUnixCreateSymLink(xid, pTcon, full_path, symname, 482 rc = CIFSUnixCreateSymLink(xid, pTcon, full_path, symname,
464 cifs_sb->local_nls); 483 cifs_sb->local_nls);
465 /* else 484 /* else