diff options
author | Stefan Metzmacher <metze@samba.org> | 2010-08-05 15:19:56 -0400 |
---|---|---|
committer | Steve French <sfrench@us.ibm.com> | 2010-09-29 15:04:31 -0400 |
commit | 1b12b9c15b4371d83b729b8fc18c670e78a1479b (patch) | |
tree | f82c9b0d01cdc5e64765780403f460e9e0d8496b /fs/cifs/link.c | |
parent | 8713d01db8bf948eb9632726f529ec4f821bb025 (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.c | 27 |
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); |
424 | out: | 438 | out: |
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 |