mirror of
https://github.com/torvalds/linux.git
synced 2024-11-12 23:23:03 +00:00
smb: client: allow creating special files via reparse points
Add support for creating special files (e.g. char/block devices, sockets, fifos) via NFS reparse points on SMB2+, which are fully supported by most SMB servers and documented in MS-FSCC. smb2_get_reparse_inode() creates the file with a corresponding reparse point buffer set in @iov through a single roundtrip to the server. Reported-by: kernel test robot <lkp@intel.com> Closes: https://lore.kernel.org/oe-kbuild-all/202311260746.HOJ039BV-lkp@intel.com/ Signed-off-by: Paulo Alcantara (SUSE) <pc@manguebit.com> Signed-off-by: Steve French <stfrench@microsoft.com>
This commit is contained in:
parent
3322960ce2
commit
102466f303
@ -211,8 +211,12 @@ int cifs_get_inode_info(struct inode **inode, const char *full_path,
|
||||
bool cifs_reparse_point_to_fattr(struct cifs_sb_info *cifs_sb,
|
||||
struct cifs_fattr *fattr,
|
||||
struct cifs_open_info_data *data);
|
||||
extern int smb311_posix_get_inode_info(struct inode **pinode, const char *search_path,
|
||||
struct super_block *sb, unsigned int xid);
|
||||
|
||||
extern int smb311_posix_get_inode_info(struct inode **inode,
|
||||
const char *full_path,
|
||||
struct cifs_open_info_data *data,
|
||||
struct super_block *sb,
|
||||
const unsigned int xid);
|
||||
extern int cifs_get_inode_info_unix(struct inode **pinode,
|
||||
const unsigned char *search_path,
|
||||
struct super_block *sb, unsigned int xid);
|
||||
|
@ -680,9 +680,10 @@ cifs_lookup(struct inode *parent_dir_inode, struct dentry *direntry,
|
||||
full_path, d_inode(direntry));
|
||||
|
||||
again:
|
||||
if (pTcon->posix_extensions)
|
||||
rc = smb311_posix_get_inode_info(&newInode, full_path, parent_dir_inode->i_sb, xid);
|
||||
else if (pTcon->unix_ext) {
|
||||
if (pTcon->posix_extensions) {
|
||||
rc = smb311_posix_get_inode_info(&newInode, full_path, NULL,
|
||||
parent_dir_inode->i_sb, xid);
|
||||
} else if (pTcon->unix_ext) {
|
||||
rc = cifs_get_inode_info_unix(&newInode, full_path,
|
||||
parent_dir_inode->i_sb, xid);
|
||||
} else {
|
||||
|
@ -1020,14 +1020,16 @@ reopen_success:
|
||||
if (!is_interrupt_error(rc))
|
||||
mapping_set_error(inode->i_mapping, rc);
|
||||
|
||||
if (tcon->posix_extensions)
|
||||
rc = smb311_posix_get_inode_info(&inode, full_path, inode->i_sb, xid);
|
||||
else if (tcon->unix_ext)
|
||||
if (tcon->posix_extensions) {
|
||||
rc = smb311_posix_get_inode_info(&inode, full_path,
|
||||
NULL, inode->i_sb, xid);
|
||||
} else if (tcon->unix_ext) {
|
||||
rc = cifs_get_inode_info_unix(&inode, full_path,
|
||||
inode->i_sb, xid);
|
||||
else
|
||||
} else {
|
||||
rc = cifs_get_inode_info(&inode, full_path, NULL,
|
||||
inode->i_sb, xid, NULL);
|
||||
}
|
||||
}
|
||||
/*
|
||||
* Else we are writing out data to server already and could deadlock if
|
||||
|
@ -1061,7 +1061,9 @@ static int reparse_info_to_fattr(struct cifs_open_info_data *data,
|
||||
const unsigned int xid,
|
||||
struct cifs_tcon *tcon,
|
||||
const char *full_path,
|
||||
struct cifs_fattr *fattr)
|
||||
struct cifs_fattr *fattr,
|
||||
struct cifs_sid *owner,
|
||||
struct cifs_sid *group)
|
||||
{
|
||||
struct TCP_Server_Info *server = tcon->ses->server;
|
||||
struct cifs_sb_info *cifs_sb = CIFS_SB(sb);
|
||||
@ -1092,7 +1094,8 @@ static int reparse_info_to_fattr(struct cifs_open_info_data *data,
|
||||
rc = 0;
|
||||
goto out;
|
||||
default:
|
||||
if (data->symlink_target) {
|
||||
/* Check for cached reparse point data */
|
||||
if (data->symlink_target || data->reparse.buf) {
|
||||
rc = 0;
|
||||
} else if (server->ops->parse_reparse_point) {
|
||||
rc = server->ops->parse_reparse_point(cifs_sb,
|
||||
@ -1101,7 +1104,10 @@ static int reparse_info_to_fattr(struct cifs_open_info_data *data,
|
||||
break;
|
||||
}
|
||||
|
||||
cifs_open_info_to_fattr(fattr, data, sb);
|
||||
if (tcon->posix_extensions)
|
||||
smb311_posix_info_to_fattr(fattr, data, owner, group, sb);
|
||||
else
|
||||
cifs_open_info_to_fattr(fattr, data, sb);
|
||||
out:
|
||||
free_rsp_buf(rsp_buftype, rsp_iov.iov_base);
|
||||
return rc;
|
||||
@ -1152,7 +1158,8 @@ static int cifs_get_fattr(struct cifs_open_info_data *data,
|
||||
*/
|
||||
if (cifs_open_data_reparse(data)) {
|
||||
rc = reparse_info_to_fattr(data, sb, xid, tcon,
|
||||
full_path, fattr);
|
||||
full_path, fattr,
|
||||
NULL, NULL);
|
||||
} else {
|
||||
cifs_open_info_to_fattr(fattr, data, sb);
|
||||
}
|
||||
@ -1290,18 +1297,19 @@ out:
|
||||
return rc;
|
||||
}
|
||||
|
||||
static int smb311_posix_get_fattr(struct cifs_fattr *fattr,
|
||||
static int smb311_posix_get_fattr(struct cifs_open_info_data *data,
|
||||
struct cifs_fattr *fattr,
|
||||
const char *full_path,
|
||||
struct super_block *sb,
|
||||
const unsigned int xid)
|
||||
{
|
||||
struct cifs_open_info_data data = {};
|
||||
struct cifs_open_info_data tmp_data = {};
|
||||
struct cifs_sb_info *cifs_sb = CIFS_SB(sb);
|
||||
struct cifs_tcon *tcon;
|
||||
struct tcon_link *tlink;
|
||||
struct cifs_sid owner, group;
|
||||
int tmprc;
|
||||
int rc;
|
||||
int rc = 0;
|
||||
|
||||
tlink = cifs_sb_tlink(cifs_sb);
|
||||
if (IS_ERR(tlink))
|
||||
@ -1309,12 +1317,14 @@ static int smb311_posix_get_fattr(struct cifs_fattr *fattr,
|
||||
tcon = tlink_tcon(tlink);
|
||||
|
||||
/*
|
||||
* 1. Fetch file metadata
|
||||
* 1. Fetch file metadata if not provided (data)
|
||||
*/
|
||||
|
||||
rc = smb311_posix_query_path_info(xid, tcon, cifs_sb,
|
||||
full_path, &data,
|
||||
&owner, &group);
|
||||
if (!data) {
|
||||
rc = smb311_posix_query_path_info(xid, tcon, cifs_sb,
|
||||
full_path, &tmp_data,
|
||||
&owner, &group);
|
||||
data = &tmp_data;
|
||||
}
|
||||
|
||||
/*
|
||||
* 2. Convert it to internal cifs metadata (fattr)
|
||||
@ -1322,7 +1332,14 @@ static int smb311_posix_get_fattr(struct cifs_fattr *fattr,
|
||||
|
||||
switch (rc) {
|
||||
case 0:
|
||||
smb311_posix_info_to_fattr(fattr, &data, &owner, &group, sb);
|
||||
if (cifs_open_data_reparse(data)) {
|
||||
rc = reparse_info_to_fattr(data, sb, xid, tcon,
|
||||
full_path, fattr,
|
||||
&owner, &group);
|
||||
} else {
|
||||
smb311_posix_info_to_fattr(fattr, data,
|
||||
&owner, &group, sb);
|
||||
}
|
||||
break;
|
||||
case -EREMOTE:
|
||||
/* DFS link, no metadata available on this server */
|
||||
@ -1353,12 +1370,15 @@ static int smb311_posix_get_fattr(struct cifs_fattr *fattr,
|
||||
|
||||
out:
|
||||
cifs_put_tlink(tlink);
|
||||
cifs_free_open_info(&data);
|
||||
cifs_free_open_info(data);
|
||||
return rc;
|
||||
}
|
||||
|
||||
int smb311_posix_get_inode_info(struct inode **inode, const char *full_path,
|
||||
struct super_block *sb, const unsigned int xid)
|
||||
int smb311_posix_get_inode_info(struct inode **inode,
|
||||
const char *full_path,
|
||||
struct cifs_open_info_data *data,
|
||||
struct super_block *sb,
|
||||
const unsigned int xid)
|
||||
{
|
||||
struct cifs_fattr fattr = {};
|
||||
int rc;
|
||||
@ -1368,7 +1388,7 @@ int smb311_posix_get_inode_info(struct inode **inode, const char *full_path,
|
||||
return 0;
|
||||
}
|
||||
|
||||
rc = smb311_posix_get_fattr(&fattr, full_path, sb, xid);
|
||||
rc = smb311_posix_get_fattr(data, &fattr, full_path, sb, xid);
|
||||
if (rc)
|
||||
goto out;
|
||||
|
||||
@ -1516,7 +1536,7 @@ struct inode *cifs_root_iget(struct super_block *sb)
|
||||
|
||||
convert_delimiter(path, CIFS_DIR_SEP(cifs_sb));
|
||||
if (tcon->posix_extensions)
|
||||
rc = smb311_posix_get_fattr(&fattr, path, sb, xid);
|
||||
rc = smb311_posix_get_fattr(NULL, &fattr, path, sb, xid);
|
||||
else
|
||||
rc = cifs_get_fattr(NULL, sb, xid, NULL, &fattr, &inode, path);
|
||||
|
||||
@ -1889,16 +1909,18 @@ cifs_mkdir_qinfo(struct inode *parent, struct dentry *dentry, umode_t mode,
|
||||
int rc = 0;
|
||||
struct inode *inode = NULL;
|
||||
|
||||
if (tcon->posix_extensions)
|
||||
rc = smb311_posix_get_inode_info(&inode, full_path, parent->i_sb, xid);
|
||||
if (tcon->posix_extensions) {
|
||||
rc = smb311_posix_get_inode_info(&inode, full_path,
|
||||
NULL, parent->i_sb, xid);
|
||||
#ifdef CONFIG_CIFS_ALLOW_INSECURE_LEGACY
|
||||
else if (tcon->unix_ext)
|
||||
} else if (tcon->unix_ext) {
|
||||
rc = cifs_get_inode_info_unix(&inode, full_path, parent->i_sb,
|
||||
xid);
|
||||
#endif /* CONFIG_CIFS_ALLOW_INSECURE_LEGACY */
|
||||
else
|
||||
} else {
|
||||
rc = cifs_get_inode_info(&inode, full_path, NULL, parent->i_sb,
|
||||
xid, NULL);
|
||||
}
|
||||
|
||||
if (rc)
|
||||
return rc;
|
||||
@ -2579,13 +2601,15 @@ int cifs_revalidate_dentry_attr(struct dentry *dentry)
|
||||
dentry, cifs_get_time(dentry), jiffies);
|
||||
|
||||
again:
|
||||
if (cifs_sb_master_tcon(CIFS_SB(sb))->posix_extensions)
|
||||
rc = smb311_posix_get_inode_info(&inode, full_path, sb, xid);
|
||||
else if (cifs_sb_master_tcon(CIFS_SB(sb))->unix_ext)
|
||||
if (cifs_sb_master_tcon(CIFS_SB(sb))->posix_extensions) {
|
||||
rc = smb311_posix_get_inode_info(&inode, full_path,
|
||||
NULL, sb, xid);
|
||||
} else if (cifs_sb_master_tcon(CIFS_SB(sb))->unix_ext) {
|
||||
rc = cifs_get_inode_info_unix(&inode, full_path, sb, xid);
|
||||
else
|
||||
} else {
|
||||
rc = cifs_get_inode_info(&inode, full_path, NULL, sb,
|
||||
xid, NULL);
|
||||
}
|
||||
if (rc == -EAGAIN && count++ < 10)
|
||||
goto again;
|
||||
out:
|
||||
|
@ -614,14 +614,16 @@ cifs_symlink(struct mnt_idmap *idmap, struct inode *inode,
|
||||
cifs_sb_target->local_nls); */
|
||||
|
||||
if (rc == 0) {
|
||||
if (pTcon->posix_extensions)
|
||||
rc = smb311_posix_get_inode_info(&newinode, full_path, inode->i_sb, xid);
|
||||
else if (pTcon->unix_ext)
|
||||
if (pTcon->posix_extensions) {
|
||||
rc = smb311_posix_get_inode_info(&newinode, full_path,
|
||||
NULL, inode->i_sb, xid);
|
||||
} else if (pTcon->unix_ext) {
|
||||
rc = cifs_get_inode_info_unix(&newinode, full_path,
|
||||
inode->i_sb, xid);
|
||||
else
|
||||
} else {
|
||||
rc = cifs_get_inode_info(&newinode, full_path, NULL,
|
||||
inode->i_sb, xid, NULL);
|
||||
}
|
||||
|
||||
if (rc != 0) {
|
||||
cifs_dbg(FYI, "Create symlink ok, getinodeinfo fail rc = %d\n",
|
||||
|
@ -23,17 +23,20 @@
|
||||
* Identifiers for functions that use the open, operation, close pattern
|
||||
* in smb2inode.c:smb2_compound_op()
|
||||
*/
|
||||
#define SMB2_OP_SET_DELETE 1
|
||||
#define SMB2_OP_SET_INFO 2
|
||||
#define SMB2_OP_QUERY_INFO 3
|
||||
#define SMB2_OP_QUERY_DIR 4
|
||||
#define SMB2_OP_MKDIR 5
|
||||
#define SMB2_OP_RENAME 6
|
||||
#define SMB2_OP_DELETE 7
|
||||
#define SMB2_OP_HARDLINK 8
|
||||
#define SMB2_OP_SET_EOF 9
|
||||
#define SMB2_OP_RMDIR 10
|
||||
#define SMB2_OP_POSIX_QUERY_INFO 11
|
||||
enum smb2_compound_ops {
|
||||
SMB2_OP_SET_DELETE = 1,
|
||||
SMB2_OP_SET_INFO,
|
||||
SMB2_OP_QUERY_INFO,
|
||||
SMB2_OP_QUERY_DIR,
|
||||
SMB2_OP_MKDIR,
|
||||
SMB2_OP_RENAME,
|
||||
SMB2_OP_DELETE,
|
||||
SMB2_OP_HARDLINK,
|
||||
SMB2_OP_SET_EOF,
|
||||
SMB2_OP_RMDIR,
|
||||
SMB2_OP_POSIX_QUERY_INFO,
|
||||
SMB2_OP_SET_REPARSE
|
||||
};
|
||||
|
||||
/* Used when constructing chained read requests. */
|
||||
#define CHAINED_REQUEST 1
|
||||
|
@ -347,6 +347,22 @@ static int smb2_compound_op(const unsigned int xid, struct cifs_tcon *tcon,
|
||||
smb2_set_related(&rqst[num_rqst++]);
|
||||
trace_smb3_hardlink_enter(xid, ses->Suid, tcon->tid, full_path);
|
||||
break;
|
||||
case SMB2_OP_SET_REPARSE:
|
||||
rqst[num_rqst].rq_iov = vars->io_iov;
|
||||
rqst[num_rqst].rq_nvec = ARRAY_SIZE(vars->io_iov);
|
||||
|
||||
rc = SMB2_ioctl_init(tcon, server, &rqst[num_rqst],
|
||||
COMPOUND_FID, COMPOUND_FID,
|
||||
FSCTL_SET_REPARSE_POINT,
|
||||
in_iov[i].iov_base,
|
||||
in_iov[i].iov_len, 0);
|
||||
if (rc)
|
||||
goto finished;
|
||||
smb2_set_next_command(tcon, &rqst[num_rqst]);
|
||||
smb2_set_related(&rqst[num_rqst++]);
|
||||
trace_smb3_set_reparse_compound_enter(xid, ses->Suid,
|
||||
tcon->tid, full_path);
|
||||
break;
|
||||
default:
|
||||
cifs_dbg(VFS, "Invalid command\n");
|
||||
rc = -EINVAL;
|
||||
@ -503,6 +519,16 @@ finished:
|
||||
tcon->tid);
|
||||
SMB2_set_info_free(&rqst[num_rqst++]);
|
||||
break;
|
||||
case SMB2_OP_SET_REPARSE:
|
||||
if (rc) {
|
||||
trace_smb3_set_reparse_compound_err(xid, ses->Suid,
|
||||
tcon->tid, rc);
|
||||
} else {
|
||||
trace_smb3_set_reparse_compound_done(xid, ses->Suid,
|
||||
tcon->tid);
|
||||
}
|
||||
SMB2_ioctl_free(&rqst[num_rqst++]);
|
||||
break;
|
||||
}
|
||||
}
|
||||
SMB2_close_free(&rqst[num_rqst]);
|
||||
@ -887,3 +913,52 @@ smb2_set_file_info(struct inode *inode, const char *full_path,
|
||||
cifs_put_tlink(tlink);
|
||||
return rc;
|
||||
}
|
||||
|
||||
struct inode *smb2_get_reparse_inode(struct cifs_open_info_data *data,
|
||||
struct super_block *sb,
|
||||
const unsigned int xid,
|
||||
struct cifs_tcon *tcon,
|
||||
const char *full_path,
|
||||
struct kvec *iov)
|
||||
{
|
||||
struct cifs_sb_info *cifs_sb = CIFS_SB(sb);
|
||||
struct cifsFileInfo *cfile;
|
||||
struct inode *new = NULL;
|
||||
struct kvec in_iov[2];
|
||||
int cmds[2];
|
||||
int da, co, cd;
|
||||
int rc;
|
||||
|
||||
da = SYNCHRONIZE | DELETE |
|
||||
FILE_READ_ATTRIBUTES |
|
||||
FILE_WRITE_ATTRIBUTES;
|
||||
co = CREATE_NOT_DIR | OPEN_REPARSE_POINT;
|
||||
cd = FILE_CREATE;
|
||||
cmds[0] = SMB2_OP_SET_REPARSE;
|
||||
in_iov[0] = *iov;
|
||||
in_iov[1].iov_base = data;
|
||||
in_iov[1].iov_len = sizeof(*data);
|
||||
|
||||
if (tcon->posix_extensions) {
|
||||
cmds[1] = SMB2_OP_POSIX_QUERY_INFO;
|
||||
cifs_get_writable_path(tcon, full_path, FIND_WR_ANY, &cfile);
|
||||
rc = smb2_compound_op(xid, tcon, cifs_sb, full_path,
|
||||
da, cd, co, ACL_NO_MODE, in_iov,
|
||||
cmds, 2, cfile, NULL, NULL, NULL, NULL);
|
||||
if (!rc) {
|
||||
rc = smb311_posix_get_inode_info(&new, full_path,
|
||||
data, sb, xid);
|
||||
}
|
||||
} else {
|
||||
cmds[1] = SMB2_OP_QUERY_INFO;
|
||||
cifs_get_writable_path(tcon, full_path, FIND_WR_ANY, &cfile);
|
||||
rc = smb2_compound_op(xid, tcon, cifs_sb, full_path,
|
||||
da, cd, co, ACL_NO_MODE, in_iov,
|
||||
cmds, 2, cfile, NULL, NULL, NULL, NULL);
|
||||
if (!rc) {
|
||||
rc = cifs_get_inode_info(&new, full_path,
|
||||
data, sb, xid, NULL);
|
||||
}
|
||||
}
|
||||
return rc ? ERR_PTR(rc) : new;
|
||||
}
|
||||
|
@ -5171,11 +5171,88 @@ int cifs_sfu_make_node(unsigned int xid, struct inode *inode,
|
||||
return rc;
|
||||
}
|
||||
|
||||
static inline u64 mode_nfs_type(mode_t mode)
|
||||
{
|
||||
switch (mode & S_IFMT) {
|
||||
case S_IFBLK: return NFS_SPECFILE_BLK;
|
||||
case S_IFCHR: return NFS_SPECFILE_CHR;
|
||||
case S_IFIFO: return NFS_SPECFILE_FIFO;
|
||||
case S_IFSOCK: return NFS_SPECFILE_SOCK;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int nfs_set_reparse_buf(struct reparse_posix_data *buf,
|
||||
mode_t mode, dev_t dev,
|
||||
struct kvec *iov)
|
||||
{
|
||||
u64 type;
|
||||
u16 len, dlen;
|
||||
|
||||
len = sizeof(*buf);
|
||||
|
||||
switch ((type = mode_nfs_type(mode))) {
|
||||
case NFS_SPECFILE_BLK:
|
||||
case NFS_SPECFILE_CHR:
|
||||
dlen = sizeof(__le64);
|
||||
break;
|
||||
case NFS_SPECFILE_FIFO:
|
||||
case NFS_SPECFILE_SOCK:
|
||||
dlen = 0;
|
||||
break;
|
||||
default:
|
||||
return -EOPNOTSUPP;
|
||||
}
|
||||
|
||||
buf->ReparseTag = cpu_to_le32(IO_REPARSE_TAG_NFS);
|
||||
buf->Reserved = 0;
|
||||
buf->InodeType = cpu_to_le64(type);
|
||||
buf->ReparseDataLength = cpu_to_le16(len + dlen -
|
||||
sizeof(struct reparse_data_buffer));
|
||||
*(__le64 *)buf->DataBuffer = cpu_to_le64(((u64)MAJOR(dev) << 32) |
|
||||
MINOR(dev));
|
||||
iov->iov_base = buf;
|
||||
iov->iov_len = len + dlen;
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int nfs_make_node(unsigned int xid, struct inode *inode,
|
||||
struct dentry *dentry, struct cifs_tcon *tcon,
|
||||
const char *full_path, umode_t mode, dev_t dev)
|
||||
{
|
||||
struct cifs_open_info_data data;
|
||||
struct reparse_posix_data *p;
|
||||
struct inode *new;
|
||||
struct kvec iov;
|
||||
__u8 buf[sizeof(*p) + sizeof(__le64)];
|
||||
int rc;
|
||||
|
||||
p = (struct reparse_posix_data *)buf;
|
||||
rc = nfs_set_reparse_buf(p, mode, dev, &iov);
|
||||
if (rc)
|
||||
return rc;
|
||||
|
||||
data = (struct cifs_open_info_data) {
|
||||
.reparse_point = true,
|
||||
.reparse = { .tag = IO_REPARSE_TAG_NFS, .posix = p, },
|
||||
};
|
||||
|
||||
new = smb2_get_reparse_inode(&data, inode->i_sb, xid,
|
||||
tcon, full_path, &iov);
|
||||
if (!IS_ERR(new))
|
||||
d_instantiate(dentry, new);
|
||||
else
|
||||
rc = PTR_ERR(new);
|
||||
cifs_free_open_info(&data);
|
||||
return rc;
|
||||
}
|
||||
|
||||
static int smb2_make_node(unsigned int xid, struct inode *inode,
|
||||
struct dentry *dentry, struct cifs_tcon *tcon,
|
||||
const char *full_path, umode_t mode, dev_t dev)
|
||||
{
|
||||
struct cifs_sb_info *cifs_sb = CIFS_SB(inode->i_sb);
|
||||
int rc;
|
||||
|
||||
/*
|
||||
* Check if mounted with mount parm 'sfu' mount parm.
|
||||
@ -5183,15 +5260,14 @@ static int smb2_make_node(unsigned int xid, struct inode *inode,
|
||||
* supports block and char device (no socket & fifo),
|
||||
* and was used by default in earlier versions of Windows
|
||||
*/
|
||||
if (!(cifs_sb->mnt_cifs_flags & CIFS_MOUNT_UNX_EMUL))
|
||||
return -EPERM;
|
||||
/*
|
||||
* TODO: Add ability to create instead via reparse point. Windows (e.g.
|
||||
* their current NFS server) uses this approach to expose special files
|
||||
* over SMB2/SMB3 and Samba will do this with SMB3.1.1 POSIX Extensions
|
||||
*/
|
||||
return cifs_sfu_make_node(xid, inode, dentry, tcon,
|
||||
full_path, mode, dev);
|
||||
if (cifs_sb->mnt_cifs_flags & CIFS_MOUNT_UNX_EMUL) {
|
||||
rc = cifs_sfu_make_node(xid, inode, dentry, tcon,
|
||||
full_path, mode, dev);
|
||||
} else {
|
||||
rc = nfs_make_node(xid, inode, dentry, tcon,
|
||||
full_path, mode, dev);
|
||||
}
|
||||
return rc;
|
||||
}
|
||||
|
||||
#ifdef CONFIG_CIFS_ALLOW_INSECURE_LEGACY
|
||||
|
@ -56,6 +56,12 @@ 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 super_block *sb,
|
||||
const unsigned int xid,
|
||||
struct cifs_tcon *tcon,
|
||||
const char *full_path,
|
||||
struct kvec *iov);
|
||||
int smb2_query_path_info(const unsigned int xid,
|
||||
struct cifs_tcon *tcon,
|
||||
struct cifs_sb_info *cifs_sb,
|
||||
@ -289,4 +295,5 @@ 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);
|
||||
|
||||
#endif /* _SMB2PROTO_H */
|
||||
|
@ -370,11 +370,11 @@ DEFINE_SMB3_INF_COMPOUND_ENTER_EVENT(rename_enter);
|
||||
DEFINE_SMB3_INF_COMPOUND_ENTER_EVENT(rmdir_enter);
|
||||
DEFINE_SMB3_INF_COMPOUND_ENTER_EVENT(set_eof_enter);
|
||||
DEFINE_SMB3_INF_COMPOUND_ENTER_EVENT(set_info_compound_enter);
|
||||
DEFINE_SMB3_INF_COMPOUND_ENTER_EVENT(set_reparse_compound_enter);
|
||||
DEFINE_SMB3_INF_COMPOUND_ENTER_EVENT(delete_enter);
|
||||
DEFINE_SMB3_INF_COMPOUND_ENTER_EVENT(mkdir_enter);
|
||||
DEFINE_SMB3_INF_COMPOUND_ENTER_EVENT(tdis_enter);
|
||||
|
||||
|
||||
DECLARE_EVENT_CLASS(smb3_inf_compound_done_class,
|
||||
TP_PROTO(unsigned int xid,
|
||||
__u32 tid,
|
||||
@ -408,6 +408,7 @@ DEFINE_SMB3_INF_COMPOUND_DONE_EVENT(rename_done);
|
||||
DEFINE_SMB3_INF_COMPOUND_DONE_EVENT(rmdir_done);
|
||||
DEFINE_SMB3_INF_COMPOUND_DONE_EVENT(set_eof_done);
|
||||
DEFINE_SMB3_INF_COMPOUND_DONE_EVENT(set_info_compound_done);
|
||||
DEFINE_SMB3_INF_COMPOUND_DONE_EVENT(set_reparse_compound_done);
|
||||
DEFINE_SMB3_INF_COMPOUND_DONE_EVENT(delete_done);
|
||||
DEFINE_SMB3_INF_COMPOUND_DONE_EVENT(mkdir_done);
|
||||
DEFINE_SMB3_INF_COMPOUND_DONE_EVENT(tdis_done);
|
||||
@ -451,6 +452,7 @@ DEFINE_SMB3_INF_COMPOUND_ERR_EVENT(rename_err);
|
||||
DEFINE_SMB3_INF_COMPOUND_ERR_EVENT(rmdir_err);
|
||||
DEFINE_SMB3_INF_COMPOUND_ERR_EVENT(set_eof_err);
|
||||
DEFINE_SMB3_INF_COMPOUND_ERR_EVENT(set_info_compound_err);
|
||||
DEFINE_SMB3_INF_COMPOUND_ERR_EVENT(set_reparse_compound_err);
|
||||
DEFINE_SMB3_INF_COMPOUND_ERR_EVENT(mkdir_err);
|
||||
DEFINE_SMB3_INF_COMPOUND_ERR_EVENT(delete_err);
|
||||
DEFINE_SMB3_INF_COMPOUND_ERR_EVENT(tdis_err);
|
||||
|
Loading…
Reference in New Issue
Block a user