Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 1b12b9c1 authored by Stefan Metzmacher's avatar Stefan Metzmacher Committed by Steve French
Browse files

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: default avatarStefan Metzmacher <metze@samba.org>
Signed-off-by: default avatarSteve French <sfrench@us.ibm.com>
parent 8713d01d
Loading
Loading
Loading
Loading
+1 −0
Original line number Diff line number Diff line
@@ -36,6 +36,7 @@
#define CIFS_MOUNT_NOPOSIXBRL   0x2000 /* mandatory not posix byte range lock */
#define CIFS_MOUNT_NOSSYNC      0x4000 /* don't do slow SMBflush on every sync*/
#define CIFS_MOUNT_FSCACHE	0x8000 /* local caching enabled */
#define CIFS_MOUNT_MF_SYMLINKS	0x10000 /* Minshall+French Symlinks enabled */

struct cifs_sb_info {
	struct cifsTconInfo *tcon;	/* primary mount */
+14 −0
Original line number Diff line number Diff line
@@ -332,6 +332,13 @@ int cifs_get_inode_info_unix(struct inode **pinode,
		return rc;
	}

	/* check for Minshall+French symlinks */
	if (cifs_sb->mnt_cifs_flags & CIFS_MOUNT_MF_SYMLINKS) {
		int tmprc = CIFSCheckMFSymlink(&fattr, full_path, cifs_sb, xid);
		if (tmprc)
			cFYI(1, "CIFSCheckMFSymlink: %d", tmprc);
	}

	if (*pinode == NULL) {
		/* get new inode */
		cifs_fill_uniqueid(sb, &fattr);
@@ -661,6 +668,13 @@ int cifs_get_inode_info(struct inode **pinode,
	if (cifs_sb->mnt_cifs_flags & CIFS_MOUNT_UNX_EMUL)
		cifs_sfu_mode(&fattr, full_path, cifs_sb, xid);

	/* check for Minshall+French symlinks */
	if (cifs_sb->mnt_cifs_flags & CIFS_MOUNT_MF_SYMLINKS) {
		tmprc = CIFSCheckMFSymlink(&fattr, full_path, cifs_sb, xid);
		if (tmprc)
			cFYI(1, "CIFSCheckMFSymlink: %d", tmprc);
	}

	if (!*pinode) {
		*pinode = cifs_iget(sb, &fattr);
		if (!*pinode)
+23 −4
Original line number Diff line number Diff line
@@ -407,7 +407,8 @@ cifs_follow_link(struct dentry *direntry, struct nameidata *nd)
	 * but there doesn't seem to be any harm in allowing the client to
	 * read them.
	 */
	if (!(tcon->ses->capabilities & CAP_UNIX)) {
	if (!(cifs_sb->mnt_cifs_flags & CIFS_MOUNT_MF_SYMLINKS)
	    && !(tcon->ses->capabilities & CAP_UNIX)) {
		rc = -EACCES;
		goto out;
	}
@@ -418,8 +419,21 @@ cifs_follow_link(struct dentry *direntry, struct nameidata *nd)

	cFYI(1, "Full path: %s inode = 0x%p", full_path, inode);

	rc = -EACCES;
	/*
	 * First try Minshall+French Symlinks, if configured
	 * and fallback to UNIX Extensions Symlinks.
	 */
	if (cifs_sb->mnt_cifs_flags & CIFS_MOUNT_MF_SYMLINKS)
		rc = CIFSQueryMFSymLink(xid, tcon, full_path, &target_path,
					cifs_sb->local_nls,
					cifs_sb->mnt_cifs_flags &
						CIFS_MOUNT_MAP_SPECIAL_CHR);

	if ((rc != 0) && (tcon->ses->capabilities & CAP_UNIX))
		rc = CIFSSMBUnixQuerySymLink(xid, tcon, full_path, &target_path,
					     cifs_sb->local_nls);

	kfree(full_path);
out:
	if (rc != 0) {
@@ -459,7 +473,12 @@ cifs_symlink(struct inode *inode, struct dentry *direntry, const char *symname)
	cFYI(1, "symname is %s", symname);

	/* BB what if DFS and this volume is on different share? BB */
	if (pTcon->unix_ext)
	if (cifs_sb->mnt_cifs_flags & CIFS_MOUNT_MF_SYMLINKS)
		rc = CIFSCreateMFSymLink(xid, pTcon, full_path, symname,
					 cifs_sb->local_nls,
					 cifs_sb->mnt_cifs_flags &
						CIFS_MOUNT_MAP_SPECIAL_CHR);
	else if (pTcon->unix_ext)
		rc = CIFSUnixCreateSymLink(xid, pTcon, full_path, symname,
					   cifs_sb->local_nls);
	/* else
+9 −0
Original line number Diff line number Diff line
@@ -738,6 +738,15 @@ static int cifs_filldir(char *pfindEntry, struct file *file, filldir_t filldir,
		cifs_autodisable_serverino(cifs_sb);
	}

	if ((cifs_sb->mnt_cifs_flags & CIFS_MOUNT_MF_SYMLINKS) &&
	    CIFSCouldBeMFSymlink(&fattr))
		/*
		 * trying to get the type and mode can be slow,
		 * so just call those regular files for now, and mark
		 * for reval
		 */
		fattr.cf_flags |= CIFS_FATTR_NEED_REVAL;

	ino = cifs_uniqueid_to_ino_t(fattr.cf_uniqueid);
	tmp_dentry = cifs_readdir_lookup(file->f_dentry, &qstring, &fattr);