479 lines
17 KiB
Diff
479 lines
17 KiB
Diff
From 1b49e1eaff6d1d665cacad667a1fc03c38fc8533 Mon Sep 17 00:00:00 2001
|
|
From: =?UTF-8?q?Pali=20Roh=C3=A1r?= <pali@kernel.org>
|
|
Date: Thu, 26 Dec 2024 00:43:22 +0100
|
|
Subject: cifs: Add support for creating reparse points over SMB1
|
|
MIME-Version: 1.0
|
|
Content-Type: text/plain; charset=UTF-8
|
|
Content-Transfer-Encoding: 8bit
|
|
|
|
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@kernel.org>
|
|
Signed-off-by: Steve French <stfrench@microsoft.com>
|
|
---
|
|
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(-)
|
|
|
|
--- a/fs/smb/client/cifsglob.h
|
|
+++ b/fs/smb/client/cifsglob.h
|
|
@@ -627,12 +627,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 {
|
|
--- a/fs/smb/client/cifsproto.h
|
|
+++ b/fs/smb/client/cifsproto.h
|
|
@@ -483,6 +483,14 @@ extern int cifs_query_reparse_point(cons
|
|
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,
|
|
--- a/fs/smb/client/cifssmb.c
|
|
+++ b/fs/smb/client/cifssmb.c
|
|
@@ -2851,6 +2851,134 @@ error:
|
|
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_le16(le32_to_cpu(io_req->DataCount) + sizeof(io_req->Pad));
|
|
+
|
|
+ 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)
|
|
--- 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, st
|
|
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, st
|
|
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)) {
|
|
@@ -636,13 +635,9 @@ cifs_symlink(struct mnt_idmap *idmap, st
|
|
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;
|
|
--- a/fs/smb/client/reparse.c
|
|
+++ b/fs/smb/client/reparse.c
|
|
@@ -34,7 +34,7 @@ static int detect_directory_symlink_targ
|
|
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)
|
|
{
|
|
@@ -227,7 +227,8 @@ static int create_native_symlink(const u
|
|
|
|
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))
|
|
@@ -399,7 +400,8 @@ static int create_native_socket(const un
|
|
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);
|
|
@@ -492,7 +494,8 @@ static int mknod_nfs(unsigned int xid, s
|
|
.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);
|
|
@@ -685,7 +688,8 @@ static int mknod_wsl(unsigned int xid, s
|
|
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))
|
|
@@ -698,7 +702,7 @@ static int mknod_wsl(unsigned int xid, s
|
|
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)
|
|
{
|
|
--- a/fs/smb/client/reparse.h
|
|
+++ b/fs/smb/client/reparse.h
|
|
@@ -129,10 +129,10 @@ static inline bool cifs_open_data_repars
|
|
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);
|
|
--- 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:
|
|
@@ -1263,17 +1264,26 @@ cifs_make_node(unsigned int xid, struct
|
|
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
|
|
@@ -1370,6 +1380,7 @@ struct smb_version_operations smb1_opera
|
|
.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,
|
|
--- a/fs/smb/client/smb2inode.c
|
|
+++ b/fs/smb/client/smb2inode.c
|
|
@@ -1323,7 +1323,7 @@ smb2_set_file_info(struct inode *inode,
|
|
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,
|
|
--- a/fs/smb/client/smb2ops.c
|
|
+++ b/fs/smb/client/smb2ops.c
|
|
@@ -5271,7 +5271,7 @@ static int smb2_make_node(unsigned int x
|
|
full_path, mode, dev);
|
|
} else if ((le32_to_cpu(tcon->fsAttrInfo.Attributes) & FILE_SUPPORTS_REPARSE_POINTS)
|
|
|| (tcon->posix_extensions)) {
|
|
- rc = smb2_mknod_reparse(xid, inode, dentry, tcon,
|
|
+ rc = mknod_reparse(xid, inode, dentry, tcon,
|
|
full_path, mode, dev);
|
|
}
|
|
return rc;
|
|
@@ -5330,7 +5330,7 @@ struct smb_version_operations smb20_oper
|
|
.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,
|
|
@@ -5433,7 +5433,7 @@ struct smb_version_operations smb21_oper
|
|
.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,
|
|
@@ -5540,7 +5540,7 @@ struct smb_version_operations smb30_oper
|
|
.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,
|
|
@@ -5656,7 +5656,7 @@ struct smb_version_operations smb311_ope
|
|
.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,
|
|
--- a/fs/smb/client/smb2proto.h
|
|
+++ b/fs/smb/client/smb2proto.h
|
|
@@ -54,7 +54,7 @@ extern int smb3_handle_read_data(struct
|
|
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,
|
|
@@ -314,9 +314,6 @@ int smb311_posix_query_path_info(const u
|
|
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);
|