Skip to content

Commit

Permalink
cifs: Add support for follow_link on dfs shares under posix extensions
Browse files Browse the repository at this point in the history
When using posix extensions, dfs shares in the dfs root show up as
symlinks resulting in userland tools such as 'ls' calling readlink() on
these shares. Since these are dfs shares, we end up returning -EREMOTE.

$ ls -l /mnt
ls: cannot read symbolic link /mnt/test: Object is remote
total 0
lrwxrwxrwx. 1 root root 19 Nov  6 09:47 test

With added follow_link() support for dfs shares, when using unix
extensions, we call GET_DFS_REFERRAL to obtain the DFS referral and
return the first node returned.

The dfs share in the dfs root is now displayed in the following manner.
$ ls -l /mnt
total 0
lrwxrwxrwx. 1 root root 19 Nov  6 09:47 test -> \vm140-31\test

Signed-off-by: Sachin Prabhu <sprabhu@redhat.com>
Reviewed-by: Jeff Layton <jlayton@redhat.com>
Signed-off-by: Steve French <smfrench@gmail.com>
  • Loading branch information
Sachin Prabhu authored and Steve French committed Jan 20, 2014
1 parent 0ecdb4f commit 924e3fa
Showing 1 changed file with 32 additions and 0 deletions.
32 changes: 32 additions & 0 deletions fs/cifs/smb1ops.c
Original file line number Diff line number Diff line change
Expand Up @@ -907,6 +907,33 @@ cifs_mand_lock(const unsigned int xid, struct cifsFileInfo *cfile, __u64 offset,
(__u8)type, wait, 0);
}

static int
cifs_unix_dfs_readlink(const unsigned int xid, struct cifs_tcon *tcon,
const unsigned char *searchName, char **symlinkinfo,
const struct nls_table *nls_codepage)
{
#ifdef CONFIG_CIFS_DFS_UPCALL
int rc;
unsigned int num_referrals = 0;
struct dfs_info3_param *referrals = NULL;

rc = get_dfs_path(xid, tcon->ses, searchName, nls_codepage,
&num_referrals, &referrals, 0);

if (!rc && num_referrals > 0) {
*symlinkinfo = kstrndup(referrals->node_name,
strlen(referrals->node_name),
GFP_KERNEL);
if (!*symlinkinfo)
rc = -ENOMEM;
free_dfs_info_array(referrals, num_referrals);
}
return rc;
#else /* No DFS support */
return -EREMOTE;
#endif
}

static int
cifs_query_symlink(const unsigned int xid, struct cifs_tcon *tcon,
const char *full_path, char **target_path,
Expand All @@ -922,6 +949,11 @@ cifs_query_symlink(const unsigned int xid, struct cifs_tcon *tcon,
if (cap_unix(tcon->ses)) {
rc = CIFSSMBUnixQuerySymLink(xid, tcon, full_path, target_path,
cifs_sb->local_nls);
if (rc == -EREMOTE)
rc = cifs_unix_dfs_readlink(xid, tcon, full_path,
target_path,
cifs_sb->local_nls);

goto out;
}

Expand Down

0 comments on commit 924e3fa

Please sign in to comment.