Re: [PATCH 3/3] cifs: Add support for creating reparse points over SMB1

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



On Friday 27 December 2024 18:40:47 Pali Rohár wrote:
> SMB1 already supports querying reparse points and detecting types of
> symlink, fifo, socket, block and char.
> 
> This change implements the missing part - ability to create a new reparse
> points over SMB1. This includes everything which SMB2+ already supports:
> - native SMB symlinks and sockets
> - NFS style of special files (symlinks, fifos, sockets, char/block devs)
> - WSL style of special files (symlinks, fifos, sockets, char/block devs)
> 
> Attaching a reparse point to an existing file or directory is done via
> SMB1 SMB_COM_NT_TRANSACT/NT_TRANSACT_IOCTL/FSCTL_SET_REPARSE_POINT command
> and implemented in a new cifs_create_reparse_inode() function.
> 
> This change introduce a new callback ->create_reparse_inode() which creates
> a new reperse point file or directory and returns inode. For SMB1 it is
> provided via that new cifs_create_reparse_inode() function.
> 
> Existing reparse.c code was only slightly updated to call new protocol
> callback ->create_reparse_inode() instead of hardcoded SMB2+ function.
> This make the whole reparse.c code to work with every SMB dialect.
> 
> The original callback ->create_reparse_symlink() is not needed anymore as
> the implementation of new create_reparse_symlink() function is dialect
> agnostic too. So the link.c code was updated to call that function directly
> (and not via callback).
> 
> Signed-off-by: Pali Rohár <pali@xxxxxxxxxx>
> ---
>  fs/smb/client/cifsglob.h  |  14 +++--
>  fs/smb/client/cifsproto.h |   8 +++
>  fs/smb/client/cifssmb.c   | 128 ++++++++++++++++++++++++++++++++++++++
>  fs/smb/client/link.c      |  13 ++--
>  fs/smb/client/reparse.c   |  16 +++--
>  fs/smb/client/reparse.h   |   4 +-
>  fs/smb/client/smb1ops.c   |  31 ++++++---
>  fs/smb/client/smb2inode.c |   2 +-
>  fs/smb/client/smb2ops.c   |  10 +--
>  fs/smb/client/smb2proto.h |   5 +-
>  10 files changed, 188 insertions(+), 43 deletions(-)
> 
> diff --git a/fs/smb/client/cifsglob.h b/fs/smb/client/cifsglob.h
> index e1deb5f6209d..06ad727e824b 100644
> --- a/fs/smb/client/cifsglob.h
> +++ b/fs/smb/client/cifsglob.h
> @@ -625,12 +625,14 @@ struct smb_version_operations {
>  	bool (*is_network_name_deleted)(char *buf, struct TCP_Server_Info *srv);
>  	struct reparse_data_buffer * (*get_reparse_point_buffer)(const struct kvec *rsp_iov,
>  								 u32 *plen);
> -	int (*create_reparse_symlink)(const unsigned int xid,
> -				      struct inode *inode,
> -				      struct dentry *dentry,
> -				      struct cifs_tcon *tcon,
> -				      const char *full_path,
> -				      const char *symname);
> +	struct inode * (*create_reparse_inode)(struct cifs_open_info_data *data,
> +					       struct super_block *sb,
> +					       const unsigned int xid,
> +					       struct cifs_tcon *tcon,
> +					       const char *full_path,
> +					       bool directory,
> +					       struct kvec *reparse_iov,
> +					       struct kvec *xattr_iov);
>  };
>  
>  struct smb_version_values {
> diff --git a/fs/smb/client/cifsproto.h b/fs/smb/client/cifsproto.h
> index 9833837c6299..ea8a0ecce9dc 100644
> --- a/fs/smb/client/cifsproto.h
> +++ b/fs/smb/client/cifsproto.h
> @@ -477,6 +477,14 @@ extern int cifs_query_reparse_point(const unsigned int xid,
>  				    const char *full_path,
>  				    u32 *tag, struct kvec *rsp,
>  				    int *rsp_buftype);
> +extern struct inode *cifs_create_reparse_inode(struct cifs_open_info_data *data,
> +					       struct super_block *sb,
> +					       const unsigned int xid,
> +					       struct cifs_tcon *tcon,
> +					       const char *full_path,
> +					       bool directory,
> +					       struct kvec *reparse_iov,
> +					       struct kvec *xattr_iov);
>  extern int CIFSSMB_set_compression(const unsigned int xid,
>  				   struct cifs_tcon *tcon, __u16 fid);
>  extern int CIFS_open(const unsigned int xid, struct cifs_open_parms *oparms,
> diff --git a/fs/smb/client/cifssmb.c b/fs/smb/client/cifssmb.c
> index ff8633fde85c..dd71c4c8f776 100644
> --- a/fs/smb/client/cifssmb.c
> +++ b/fs/smb/client/cifssmb.c
> @@ -2795,6 +2795,134 @@ int cifs_query_reparse_point(const unsigned int xid,
>  	return rc;
>  }
>  
> +struct inode *cifs_create_reparse_inode(struct cifs_open_info_data *data,
> +					struct super_block *sb,
> +					const unsigned int xid,
> +					struct cifs_tcon *tcon,
> +					const char *full_path,
> +					bool directory,
> +					struct kvec *reparse_iov,
> +					struct kvec *xattr_iov)
> +{
> +	struct cifs_sb_info *cifs_sb = CIFS_SB(sb);
> +	struct cifs_open_parms oparms;
> +	TRANSACT_IOCTL_REQ *io_req;
> +	struct inode *new = NULL;
> +	struct kvec in_iov[2];
> +	struct kvec out_iov;
> +	struct cifs_fid fid;
> +	int io_req_len;
> +	int oplock = 0;
> +	int buf_type = 0;
> +	int rc;
> +
> +	cifs_tcon_dbg(FYI, "%s: path=%s\n", __func__, full_path);
> +
> +	/*
> +	 * If server filesystem does not support reparse points then do not
> +	 * attempt to create reparse point. This will prevent creating unusable
> +	 * empty object on the server.
> +	 */
> +	if (!(le32_to_cpu(tcon->fsAttrInfo.Attributes) & FILE_SUPPORTS_REPARSE_POINTS))
> +		return ERR_PTR(-EOPNOTSUPP);
> +
> +#ifndef CONFIG_CIFS_XATTR
> +	if (xattr_iov)
> +		return ERR_PTR(-EOPNOTSUPP);
> +#endif
> +
> +	oparms = CIFS_OPARMS(cifs_sb, tcon, full_path,
> +			     FILE_READ_ATTRIBUTES | FILE_WRITE_DATA | FILE_WRITE_EA,
> +			     FILE_CREATE,
> +			     (directory ? CREATE_NOT_FILE : CREATE_NOT_DIR) | OPEN_REPARSE_POINT,
> +			     ACL_NO_MODE);
> +	oparms.fid = &fid;
> +
> +	rc = CIFS_open(xid, &oparms, &oplock, NULL);
> +	if (rc)
> +		return ERR_PTR(rc);
> +
> +#ifdef CONFIG_CIFS_XATTR
> +	if (xattr_iov) {
> +		struct smb2_file_full_ea_info *ea;
> +
> +		ea = &((struct smb2_create_ea_ctx *)xattr_iov->iov_base)->ea;
> +		while (1) {
> +			rc = CIFSSMBSetEA(xid,
> +					  tcon,
> +					  full_path,
> +					  &ea->ea_data[0],
> +					  &ea->ea_data[ea->ea_name_length+1],
> +					  le16_to_cpu(ea->ea_value_length),
> +					  cifs_sb->local_nls,
> +					  cifs_sb);
> +			if (rc)
> +				goto out_close;
> +			if (le32_to_cpu(ea->next_entry_offset) == 0)
> +				break;
> +			ea = (struct smb2_file_full_ea_info *)((u8 *)ea +
> +				le32_to_cpu(ea->next_entry_offset));
> +		}
> +	}
> +#endif
> +
> +	rc = smb_init(SMB_COM_NT_TRANSACT, 23, tcon, (void **)&io_req, NULL);
> +	if (rc)
> +		goto out_close;
> +
> +	inc_rfc1001_len(io_req, sizeof(io_req->Pad));
> +
> +	io_req_len = be32_to_cpu(io_req->hdr.smb_buf_length) + sizeof(io_req->hdr.smb_buf_length);
> +
> +	/* NT IOCTL response contains one-word long output setup buffer with size of output data. */
> +	io_req->MaxSetupCount = 1;
> +	/* NT IOCTL response does not contain output parameters. */
> +	io_req->MaxParameterCount = cpu_to_le32(0);
> +	/* FSCTL_SET_REPARSE_POINT response contains empty output data. */
> +	io_req->MaxDataCount = cpu_to_le32(0);
> +
> +	io_req->TotalParameterCount = cpu_to_le32(0);
> +	io_req->TotalDataCount = cpu_to_le32(reparse_iov->iov_len);
> +	io_req->ParameterCount = io_req->TotalParameterCount;
> +	io_req->ParameterOffset = cpu_to_le32(0);
> +	io_req->DataCount = io_req->TotalDataCount;
> +	io_req->DataOffset = cpu_to_le32(offsetof(typeof(*io_req), Data) -
> +					 sizeof(io_req->hdr.smb_buf_length));
> +	io_req->SetupCount = 4;
> +	io_req->SubCommand = cpu_to_le16(NT_TRANSACT_IOCTL);
> +	io_req->FunctionCode = cpu_to_le32(FSCTL_SET_REPARSE_POINT);
> +	io_req->Fid = fid.netfid;
> +	io_req->IsFsctl = 1;
> +	io_req->IsRootFlag = 0;
> +	io_req->ByteCount = cpu_to_le32(le32_to_cpu(io_req->DataCount) + sizeof(io_req->Pad));

Robot found there endianity issue. ByteCount is only 16-bit LE, so
cpu_to_le16() needs to be used.

> +
> +	inc_rfc1001_len(io_req, reparse_iov->iov_len);
> +
> +	in_iov[0].iov_base = (char *)io_req;
> +	in_iov[0].iov_len = io_req_len;
> +	in_iov[1] = *reparse_iov;
> +	rc = SendReceive2(xid, tcon->ses, in_iov, ARRAY_SIZE(in_iov), &buf_type,
> +			  CIFS_NO_RSP_BUF, &out_iov);
> +
> +	cifs_buf_release(io_req);
> +
> +	if (!rc)
> +		rc = cifs_get_inode_info(&new, full_path, data, sb, xid, NULL);
> +
> +out_close:
> +	CIFSSMBClose(xid, tcon, fid.netfid);
> +
> +	/*
> +	 * If CREATE was successful but FSCTL_SET_REPARSE_POINT failed then
> +	 * remove the intermediate object created by CREATE. Otherwise
> +	 * empty object stay on the server when reparse call failed.
> +	 */
> +	if (rc)
> +		CIFSSMBDelFile(xid, tcon, full_path, cifs_sb, NULL);
> +
> +	return rc ? ERR_PTR(rc) : new;
> +}
> +
>  int
>  CIFSSMB_set_compression(const unsigned int xid, struct cifs_tcon *tcon,
>  		    __u16 fid)
> diff --git a/fs/smb/client/link.c b/fs/smb/client/link.c
> index a88253668286..b1a346e20b07 100644
> --- a/fs/smb/client/link.c
> +++ b/fs/smb/client/link.c
> @@ -19,6 +19,7 @@
>  #include "smb2proto.h"
>  #include "cifs_ioctl.h"
>  #include "fs_context.h"
> +#include "reparse.h"
>  
>  /*
>   * M-F Symlink Functions - Begin
> @@ -570,7 +571,6 @@ cifs_symlink(struct mnt_idmap *idmap, struct inode *inode,
>  	int rc = -EOPNOTSUPP;
>  	unsigned int xid;
>  	struct cifs_sb_info *cifs_sb = CIFS_SB(inode->i_sb);
> -	struct TCP_Server_Info *server;
>  	struct tcon_link *tlink;
>  	struct cifs_tcon *pTcon;
>  	const char *full_path;
> @@ -593,7 +593,6 @@ cifs_symlink(struct mnt_idmap *idmap, struct inode *inode,
>  		goto symlink_exit;
>  	}
>  	pTcon = tlink_tcon(tlink);
> -	server = cifs_pick_channel(pTcon->ses);
>  
>  	full_path = build_path_from_dentry(direntry, page);
>  	if (IS_ERR(full_path)) {
> @@ -643,13 +642,9 @@ cifs_symlink(struct mnt_idmap *idmap, struct inode *inode,
>  	case CIFS_SYMLINK_TYPE_NATIVE:
>  	case CIFS_SYMLINK_TYPE_NFS:
>  	case CIFS_SYMLINK_TYPE_WSL:
> -		if (server->ops->create_reparse_symlink &&
> -		    (le32_to_cpu(pTcon->fsAttrInfo.Attributes) & FILE_SUPPORTS_REPARSE_POINTS)) {
> -			rc = server->ops->create_reparse_symlink(xid, inode,
> -								 direntry,
> -								 pTcon,
> -								 full_path,
> -								 symname);
> +		if (le32_to_cpu(pTcon->fsAttrInfo.Attributes) & FILE_SUPPORTS_REPARSE_POINTS) {
> +			rc = create_reparse_symlink(xid, inode, direntry, pTcon,
> +						    full_path, symname);
>  			goto symlink_exit;
>  		}
>  		break;
> diff --git a/fs/smb/client/reparse.c b/fs/smb/client/reparse.c
> index 9e40f5709c7f..69efbcae6683 100644
> --- a/fs/smb/client/reparse.c
> +++ b/fs/smb/client/reparse.c
> @@ -34,7 +34,7 @@ static int detect_directory_symlink_target(struct cifs_sb_info *cifs_sb,
>  					   const char *symname,
>  					   bool *directory);
>  
> -int smb2_create_reparse_symlink(const unsigned int xid, struct inode *inode,
> +int create_reparse_symlink(const unsigned int xid, struct inode *inode,
>  				struct dentry *dentry, struct cifs_tcon *tcon,
>  				const char *full_path, const char *symname)
>  {
> @@ -225,7 +225,8 @@ static int create_native_symlink(const unsigned int xid, struct inode *inode,
>  
>  	iov.iov_base = buf;
>  	iov.iov_len = len;
> -	new = smb2_get_reparse_inode(&data, inode->i_sb, xid,
> +	new = tcon->ses->server->ops->create_reparse_inode(
> +				     &data, inode->i_sb, xid,
>  				     tcon, full_path, directory,
>  				     &iov, NULL);
>  	if (!IS_ERR(new))
> @@ -397,7 +398,8 @@ static int create_native_socket(const unsigned int xid, struct inode *inode,
>  	struct inode *new;
>  	int rc = 0;
>  
> -	new = smb2_get_reparse_inode(&data, inode->i_sb, xid,
> +	new = tcon->ses->server->ops->create_reparse_inode(
> +				     &data, inode->i_sb, xid,
>  				     tcon, full_path, false, &iov, NULL);
>  	if (!IS_ERR(new))
>  		d_instantiate(dentry, new);
> @@ -490,7 +492,8 @@ static int mknod_nfs(unsigned int xid, struct inode *inode,
>  		.symlink_target = kstrdup(symname, GFP_KERNEL),
>  	};
>  
> -	new = smb2_get_reparse_inode(&data, inode->i_sb, xid,
> +	new = tcon->ses->server->ops->create_reparse_inode(
> +				     &data, inode->i_sb, xid,
>  				     tcon, full_path, false, &iov, NULL);
>  	if (!IS_ERR(new))
>  		d_instantiate(dentry, new);
> @@ -683,7 +686,8 @@ static int mknod_wsl(unsigned int xid, struct inode *inode,
>  	memcpy(data.wsl.eas, &cc->ea, len);
>  	data.wsl.eas_len = len;
>  
> -	new = smb2_get_reparse_inode(&data, inode->i_sb,
> +	new = tcon->ses->server->ops->create_reparse_inode(
> +				     &data, inode->i_sb,
>  				     xid, tcon, full_path, false,
>  				     &reparse_iov, &xattr_iov);
>  	if (!IS_ERR(new))
> @@ -696,7 +700,7 @@ static int mknod_wsl(unsigned int xid, struct inode *inode,
>  	return rc;
>  }
>  
> -int smb2_mknod_reparse(unsigned int xid, struct inode *inode,
> +int mknod_reparse(unsigned int xid, struct inode *inode,
>  		       struct dentry *dentry, struct cifs_tcon *tcon,
>  		       const char *full_path, umode_t mode, dev_t dev)
>  {
> diff --git a/fs/smb/client/reparse.h b/fs/smb/client/reparse.h
> index c17130657def..8cb11db076a7 100644
> --- a/fs/smb/client/reparse.h
> +++ b/fs/smb/client/reparse.h
> @@ -113,10 +113,10 @@ static inline bool cifs_open_data_reparse(struct cifs_open_info_data *data)
>  bool cifs_reparse_point_to_fattr(struct cifs_sb_info *cifs_sb,
>  				 struct cifs_fattr *fattr,
>  				 struct cifs_open_info_data *data);
> -int smb2_create_reparse_symlink(const unsigned int xid, struct inode *inode,
> +int create_reparse_symlink(const unsigned int xid, struct inode *inode,
>  				struct dentry *dentry, struct cifs_tcon *tcon,
>  				const char *full_path, const char *symname);
> -int smb2_mknod_reparse(unsigned int xid, struct inode *inode,
> +int mknod_reparse(unsigned int xid, struct inode *inode,
>  		       struct dentry *dentry, struct cifs_tcon *tcon,
>  		       const char *full_path, umode_t mode, dev_t dev);
>  struct reparse_data_buffer *smb2_get_reparse_point_buffer(const struct kvec *rsp_iov, u32 *len);
> diff --git a/fs/smb/client/smb1ops.c b/fs/smb/client/smb1ops.c
> index c52fc4c1557c..a0a15dda0949 100644
> --- a/fs/smb/client/smb1ops.c
> +++ b/fs/smb/client/smb1ops.c
> @@ -16,6 +16,7 @@
>  #include "fs_context.h"
>  #include "nterr.h"
>  #include "smberr.h"
> +#include "reparse.h"
>  
>  /*
>   * An NT cancel request header looks just like the original request except:
> @@ -1076,17 +1077,26 @@ cifs_make_node(unsigned int xid, struct inode *inode,
>  		if (rc == 0)
>  			d_instantiate(dentry, newinode);
>  		return rc;
> +	} else if (cifs_sb->mnt_cifs_flags & CIFS_MOUNT_UNX_EMUL) {
> +		/*
> +		 * Check if mounted with mount parm 'sfu' mount parm.
> +		 * SFU emulation should work with all servers
> +		 * and was used by default in earlier versions of Windows.
> +		 */
> +		return cifs_sfu_make_node(xid, inode, dentry, tcon,
> +					  full_path, mode, dev);
> +	} else if (le32_to_cpu(tcon->fsAttrInfo.Attributes) & FILE_SUPPORTS_REPARSE_POINTS) {
> +		/*
> +		 * mknod via reparse points requires server support for
> +		 * storing reparse points, which is available since
> +		 * Windows 2000, but was not widely used until release
> +		 * of Windows Server 2012 by the Windows NFS server.
> +		 */
> +		return mknod_reparse(xid, inode, dentry, tcon,
> +				     full_path, mode, dev);
> +	} else {
> +		return -EOPNOTSUPP;
>  	}
> -	/*
> -	 * Check if mounted with mount parm 'sfu' mount parm.
> -	 * SFU emulation should work with all servers, but only
> -	 * supports block and char device, socket & fifo,
> -	 * and was used by default in earlier versions of Windows
> -	 */
> -	if (!(cifs_sb->mnt_cifs_flags & CIFS_MOUNT_UNX_EMUL))
> -		return -EPERM;
> -	return cifs_sfu_make_node(xid, inode, dentry, tcon,
> -				  full_path, mode, dev);
>  }
>  
>  static bool
> @@ -1183,6 +1193,7 @@ struct smb_version_operations smb1_operations = {
>  	.create_hardlink = CIFSCreateHardLink,
>  	.query_symlink = cifs_query_symlink,
>  	.get_reparse_point_buffer = cifs_get_reparse_point_buffer,
> +	.create_reparse_inode = cifs_create_reparse_inode,
>  	.open = cifs_open_file,
>  	.set_fid = cifs_set_fid,
>  	.close = cifs_close_file,
> diff --git a/fs/smb/client/smb2inode.c b/fs/smb/client/smb2inode.c
> index 426dbaff270a..0b8d6d8f724d 100644
> --- a/fs/smb/client/smb2inode.c
> +++ b/fs/smb/client/smb2inode.c
> @@ -1305,7 +1305,7 @@ smb2_set_file_info(struct inode *inode, const char *full_path,
>  	return rc;
>  }
>  
> -struct inode *smb2_get_reparse_inode(struct cifs_open_info_data *data,
> +struct inode *smb2_create_reparse_inode(struct cifs_open_info_data *data,
>  				     struct super_block *sb,
>  				     const unsigned int xid,
>  				     struct cifs_tcon *tcon,
> diff --git a/fs/smb/client/smb2ops.c b/fs/smb/client/smb2ops.c
> index ba81b662f5c7..4aa9f3ac4c34 100644
> --- a/fs/smb/client/smb2ops.c
> +++ b/fs/smb/client/smb2ops.c
> @@ -5232,7 +5232,7 @@ static int smb2_make_node(unsigned int xid, struct inode *inode,
>  		rc = cifs_sfu_make_node(xid, inode, dentry, tcon,
>  					full_path, mode, dev);
>  	} else if (le32_to_cpu(tcon->fsAttrInfo.Attributes) & FILE_SUPPORTS_REPARSE_POINTS) {
> -		rc = smb2_mknod_reparse(xid, inode, dentry, tcon,
> +		rc = mknod_reparse(xid, inode, dentry, tcon,
>  					full_path, mode, dev);
>  	}
>  	return rc;
> @@ -5291,7 +5291,7 @@ struct smb_version_operations smb20_operations = {
>  	.get_reparse_point_buffer = smb2_get_reparse_point_buffer,
>  	.query_mf_symlink = smb3_query_mf_symlink,
>  	.create_mf_symlink = smb3_create_mf_symlink,
> -	.create_reparse_symlink = smb2_create_reparse_symlink,
> +	.create_reparse_inode = smb2_create_reparse_inode,
>  	.open = smb2_open_file,
>  	.set_fid = smb2_set_fid,
>  	.close = smb2_close_file,
> @@ -5394,7 +5394,7 @@ struct smb_version_operations smb21_operations = {
>  	.get_reparse_point_buffer = smb2_get_reparse_point_buffer,
>  	.query_mf_symlink = smb3_query_mf_symlink,
>  	.create_mf_symlink = smb3_create_mf_symlink,
> -	.create_reparse_symlink = smb2_create_reparse_symlink,
> +	.create_reparse_inode = smb2_create_reparse_inode,
>  	.open = smb2_open_file,
>  	.set_fid = smb2_set_fid,
>  	.close = smb2_close_file,
> @@ -5501,7 +5501,7 @@ struct smb_version_operations smb30_operations = {
>  	.get_reparse_point_buffer = smb2_get_reparse_point_buffer,
>  	.query_mf_symlink = smb3_query_mf_symlink,
>  	.create_mf_symlink = smb3_create_mf_symlink,
> -	.create_reparse_symlink = smb2_create_reparse_symlink,
> +	.create_reparse_inode = smb2_create_reparse_inode,
>  	.open = smb2_open_file,
>  	.set_fid = smb2_set_fid,
>  	.close = smb2_close_file,
> @@ -5617,7 +5617,7 @@ struct smb_version_operations smb311_operations = {
>  	.get_reparse_point_buffer = smb2_get_reparse_point_buffer,
>  	.query_mf_symlink = smb3_query_mf_symlink,
>  	.create_mf_symlink = smb3_create_mf_symlink,
> -	.create_reparse_symlink = smb2_create_reparse_symlink,
> +	.create_reparse_inode = smb2_create_reparse_inode,
>  	.open = smb2_open_file,
>  	.set_fid = smb2_set_fid,
>  	.close = smb2_close_file,
> diff --git a/fs/smb/client/smb2proto.h b/fs/smb/client/smb2proto.h
> index 2336dfb23f36..cec5921bfdd2 100644
> --- a/fs/smb/client/smb2proto.h
> +++ b/fs/smb/client/smb2proto.h
> @@ -54,7 +54,7 @@ extern int smb3_handle_read_data(struct TCP_Server_Info *server,
>  extern int smb2_query_reparse_tag(const unsigned int xid, struct cifs_tcon *tcon,
>  				struct cifs_sb_info *cifs_sb, const char *path,
>  				__u32 *reparse_tag);
> -struct inode *smb2_get_reparse_inode(struct cifs_open_info_data *data,
> +struct inode *smb2_create_reparse_inode(struct cifs_open_info_data *data,
>  				     struct super_block *sb,
>  				     const unsigned int xid,
>  				     struct cifs_tcon *tcon,
> @@ -317,9 +317,6 @@ int smb311_posix_query_path_info(const unsigned int xid,
>  int posix_info_parse(const void *beg, const void *end,
>  		     struct smb2_posix_info_parsed *out);
>  int posix_info_sid_size(const void *beg, const void *end);
> -int smb2_create_reparse_symlink(const unsigned int xid, struct inode *inode,
> -				struct dentry *dentry, struct cifs_tcon *tcon,
> -				const char *full_path, const char *symname);
>  int smb2_make_nfs_node(unsigned int xid, struct inode *inode,
>  		       struct dentry *dentry, struct cifs_tcon *tcon,
>  		       const char *full_path, umode_t mode, dev_t dev);
> -- 
> 2.20.1
> 




[Linux USB Devel]     [Video for Linux]     [Linux Audio Users]     [Yosemite News]     [Linux Kernel]     [Linux SCSI]

  Powered by Linux