smb: client: allow creating special files via reparse points
authorSteve French <stfrench@microsoft.com>
Sun, 28 Jan 2024 18:13:23 +0000 (12:13 -0600)
committerSteve French <stfrench@microsoft.com>
Sun, 28 Jan 2024 18:13:23 +0000 (12:13 -0600)
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>
fs/cifs/cifsproto.h
fs/cifs/dir.c
fs/cifs/file.c
fs/cifs/inode.c
fs/cifs/link.c
fs/cifs/smb2glob.h
fs/cifs/smb2inode.c
fs/cifs/smb2ops.c
fs/cifs/smb2proto.h
fs/cifs/trace.h

index ddfb671170c936e200bc2432ca5c43e64ac3da33..fc177b7ffe9089e2ce6b168ee001a0bbd8e41e3c 100644 (file)
@@ -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);
index 1384b55677ca957a162008630a0edbd65b46104e..e90812c99774d2330b316df14737b61ace5727c3 100644 (file)
@@ -675,9 +675,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 {
index f7dceef8bdfdb2f8fe6b7ce04a5b5a628eba8036..e5fa0d8ce7a78e6541e03077df1b6625140b81ce 100644 (file)
@@ -889,14 +889,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
index 57f7bcb4131a8e9f69a2e315919a6fc3b481ce22..38b556b1afbbf077fce4e6122bfc4783aa1af402 100644 (file)
@@ -1055,7 +1055,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);
@@ -1086,7 +1088,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,
@@ -1095,7 +1098,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;
@@ -1146,7 +1152,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);
                }
@@ -1284,18 +1291,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))
@@ -1303,12 +1311,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)
@@ -1316,7 +1326,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 */
@@ -1347,12 +1364,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;
@@ -1362,7 +1382,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;
 
@@ -1513,7 +1533,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);
 
@@ -1885,16 +1905,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:
index 0119e1fdfd2f2ebd0c5c73f30a3bff79266ea03b..ffb6ec9c1d4506df8f94154a10c79f7264d06132 100644 (file)
@@ -614,14 +614,16 @@ cifs_symlink(struct user_namespace *mnt_userns, 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",
index 82e916ad167c00b9fac7c5ea36756302b867287e..ca87a0011c337deef5a204e9d9b8f4b91dcd1bf9 100644 (file)
  * 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
index 98fa4f02fbd344353f7dbba174f5ea8194a46f50..d662bad3b70308b1e3f5d38c3bedf24634f9a9d7 100644 (file)
@@ -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;
+}
index e2eea8577ad9805b6d1ce3dfe52c9abf65c97108..e4e138e597a4c2d3c3dbd4cd2fb79e87cdedbb82 100644 (file)
@@ -5184,11 +5184,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.
@@ -5196,15 +5273,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
index 0e371f7e2854b924053cbec235ef3b94f9244551..709324cff7129cd2d1bb41625f29eeebc6230857 100644 (file)
@@ -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 */
index de199ec9f7263daf369639d2bda1df453f225e59..34f507584274bd920c3da54be7c8e03c5e33d219 100644 (file)
@@ -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);