Pull more cifs updates from Steve French: "12 cifs/smb3 fixes, 2 for stable. - add support for idsfromsid on create and chgrp/chown allowing ability to save owner information more naturally for some workloads - improve query info (getattr) when SMB3.1.1 posix extensions are negotiated by using new query info level" * tag '5.8-rc-smb3-fixes-part2' of git://git.samba.org/sfrench/cifs-2.6: smb3: Add debug message for new file creation with idsfromsid mount option cifs: fix chown and chgrp when idsfromsid mount option enabled smb3: allow uid and gid owners to be set on create with idsfromsid mount option smb311: Add tracepoints for new compound posix query info smb311: add support for using info level for posix extensions query smb311: Add support for lookup with posix extensions query info smb311: Add support for SMB311 query info (non-compounded) SMB311: Add support for query info using posix extensions (level 100) smb3: add indatalen that can be a non-zero value to calculation of credit charge in smb2 ioctl smb3: fix typo in mount options displayed in /proc/mounts cifs: Add get_security_type_str function to return sec type. smb3: extend fscache mount volume coherency check
Unified · Split
| @@ -53,13 +53,6 @@ const struct fscache_cookie_def cifs_fscache_server_index_def = { · 52 unmodified lines | |||
| 53 | .type = FSCACHE_COOKIE_TYPE_INDEX, | 53 | .type = FSCACHE_COOKIE_TYPE_INDEX, |
| 54 | }; | 54 | }; |
| 55 | 55 | ||
| 56 | /* | ||
| 57 | * Auxiliary data attached to CIFS superblock within the cache | ||
| 58 | */ | ||
| 59 | struct cifs_fscache_super_auxdata { | ||
| 60 | u64 resource_id; /* unique server resource id */ | ||
| 61 | }; | ||
| 62 | |||
| 63 | char *extract_sharename(const char *treename) | 56 | char *extract_sharename(const char *treename) |
| 64 | { | 57 | { |
| 65 | const char *src; | 58 | const char *src; |
| @@ -98,6 +91,8 @@ fscache_checkaux cifs_fscache_super_check_aux(void *cookie_netfs_data, · 32 unmodified lines | |||
| 98 | 91 | ||
| 99 | memset(&auxdata, 0, sizeof(auxdata)); | 92 | memset(&auxdata, 0, sizeof(auxdata)); |
| 100 | auxdata.resource_id = tcon->resource_id; | 93 | auxdata.resource_id = tcon->resource_id; |
| 94 | auxdata.vol_create_time = tcon->vol_create_time; | ||
| 95 | auxdata.vol_serial_number = tcon->vol_serial_number; | ||
| 101 | 96 | ||
| 102 | if (memcmp(data, &auxdata, datalen) != 0) | 97 | if (memcmp(data, &auxdata, datalen) != 0) |
| 103 | return FSCACHE_CHECKAUX_OBSOLETE; | 98 | return FSCACHE_CHECKAUX_OBSOLETE; |
| @@ -221,8 +221,6 @@ static int cifs_debug_data_proc_show(struct seq_file *m, void *v) · 220 unmodified lines | |||
| 221 | struct cifs_ses *ses; | 221 | struct cifs_ses *ses; |
| 222 | struct cifs_tcon *tcon; | 222 | struct cifs_tcon *tcon; |
| 223 | int i, j; | 223 | int i, j; |
| 224 | const char *security_types[] = {"Unspecified", "LANMAN", "NTLM", | ||
| 225 | "NTLMv2", "RawNTLMSSP", "Kerberos"}; | ||
| 226 | 224 | ||
| 227 | seq_puts(m, | 225 | seq_puts(m, |
| 228 | "Display Internal CIFS Data Structures for Debugging\n" | 226 | "Display Internal CIFS Data Structures for Debugging\n" |
| @@ -379,7 +377,7 @@ skip_rdma: · 150 unmodified lines | |||
| 379 | } | 377 | } |
| 380 | 378 | ||
| 381 | seq_printf(m,"Security type: %s\n", | 379 | seq_printf(m,"Security type: %s\n", |
| 382 | security_types[server->ops->select_sectype(server, ses->sectype)]); | 380 | get_security_type_str(server->ops->select_sectype(server, ses->sectype))); |
| 383 | 381 | ||
| 384 | if (server->rdma) | 382 | if (server->rdma) |
| 385 | seq_printf(m, "RDMA\n\t"); | 383 | seq_printf(m, "RDMA\n\t"); |
| @@ -849,6 +849,28 @@ unsigned int setup_special_mode_ACE(struct cifs_ace *pntace, __u64 nmode) · 848 unmodified lines | |||
| 849 | return ace_size; | 849 | return ace_size; |
| 850 | } | 850 | } |
| 851 | 851 | ||
| 852 | unsigned int setup_special_user_owner_ACE(struct cifs_ace *pntace) | ||
| 853 | { | ||
| 854 | int i; | ||
| 855 | unsigned int ace_size = 28; | ||
| 856 | |||
| 857 | pntace->type = ACCESS_ALLOWED_ACE_TYPE; | ||
| 858 | pntace->flags = 0x0; | ||
| 859 | pntace->access_req = cpu_to_le32(GENERIC_ALL); | ||
| 860 | pntace->sid.num_subauth = 3; | ||
| 861 | pntace->sid.revision = 1; | ||
| 862 | for (i = 0; i < NUM_AUTHS; i++) | ||
| 863 | pntace->sid.authority[i] = sid_unix_NFS_users.authority[i]; | ||
| 864 | |||
| 865 | pntace->sid.sub_auth[0] = sid_unix_NFS_users.sub_auth[0]; | ||
| 866 | pntace->sid.sub_auth[1] = sid_unix_NFS_users.sub_auth[1]; | ||
| 867 | pntace->sid.sub_auth[2] = cpu_to_le32(current_fsgid().val); | ||
| 868 | |||
| 869 | /* size = 1 + 1 + 2 + 4 + 1 + 1 + 6 + (psid->num_subauth*4) */ | ||
| 870 | pntace->size = cpu_to_le16(ace_size); | ||
| 871 | return ace_size; | ||
| 872 | } | ||
| 873 | |||
| 852 | static int set_chmod_dacl(struct cifs_acl *pndacl, struct cifs_sid *pownersid, | 874 | static int set_chmod_dacl(struct cifs_acl *pndacl, struct cifs_sid *pownersid, |
| 853 | struct cifs_sid *pgrpsid, __u64 nmode, bool modefromsid) | 875 | struct cifs_sid *pgrpsid, __u64 nmode, bool modefromsid) |
| 854 | { | 876 | { |
| @@ -978,7 +1000,7 @@ static int parse_sec_desc(struct cifs_sb_info *cifs_sb, · 123 unmodified lines | |||
| 978 | /* Convert permission bits from mode to equivalent CIFS ACL */ | 1000 | /* Convert permission bits from mode to equivalent CIFS ACL */ |
| 979 | static int build_sec_desc(struct cifs_ntsd *pntsd, struct cifs_ntsd *pnntsd, | 1001 | static int build_sec_desc(struct cifs_ntsd *pntsd, struct cifs_ntsd *pnntsd, |
| 980 | __u32 secdesclen, __u64 nmode, kuid_t uid, kgid_t gid, | 1002 | __u32 secdesclen, __u64 nmode, kuid_t uid, kgid_t gid, |
| 981 | bool mode_from_sid, int *aclflag) | 1003 | bool mode_from_sid, bool id_from_sid, int *aclflag) |
| 982 | { | 1004 | { |
| 983 | int rc = 0; | 1005 | int rc = 0; |
| 984 | __u32 dacloffset; | 1006 | __u32 dacloffset; |
| @@ -1019,12 +1041,23 @@ static int build_sec_desc(struct cifs_ntsd *pntsd, struct cifs_ntsd *pnntsd, · 34 unmodified lines | |||
| 1019 | if (!nowner_sid_ptr) | 1041 | if (!nowner_sid_ptr) |
| 1020 | return -ENOMEM; | 1042 | return -ENOMEM; |
| 1021 | id = from_kuid(&init_user_ns, uid); | 1043 | id = from_kuid(&init_user_ns, uid); |
| 1022 | rc = id_to_sid(id, SIDOWNER, nowner_sid_ptr); | 1044 | if (id_from_sid) { |
| 1023 | if (rc) { | 1045 | struct owner_sid *osid = (struct owner_sid *)nowner_sid_ptr; |
| 1024 | cifs_dbg(FYI, "%s: Mapping error %d for owner id %d\n", | 1046 | /* Populate the user ownership fields S-1-5-88-1 */ |
| 1025 | __func__, rc, id); | 1047 | osid->Revision = 1; |
| 1026 | kfree(nowner_sid_ptr); | 1048 | osid->NumAuth = 3; |
| 1027 | return rc; | 1049 | osid->Authority[5] = 5; |
| 1050 | osid->SubAuthorities[0] = cpu_to_le32(88); | ||
| 1051 | osid->SubAuthorities[1] = cpu_to_le32(1); | ||
| 1052 | osid->SubAuthorities[2] = cpu_to_le32(id); | ||
| 1053 | } else { /* lookup sid with upcall */ | ||
| 1054 | rc = id_to_sid(id, SIDOWNER, nowner_sid_ptr); | ||
| 1055 | if (rc) { | ||
| 1056 | cifs_dbg(FYI, "%s: Mapping error %d for owner id %d\n", | ||
| 1057 | __func__, rc, id); | ||
| 1058 | kfree(nowner_sid_ptr); | ||
| 1059 | return rc; | ||
| 1060 | } | ||
| 1028 | } | 1061 | } |
| 1029 | cifs_copy_sid(owner_sid_ptr, nowner_sid_ptr); | 1062 | cifs_copy_sid(owner_sid_ptr, nowner_sid_ptr); |
| 1030 | kfree(nowner_sid_ptr); | 1063 | kfree(nowner_sid_ptr); |
| @@ -1039,12 +1072,23 @@ static int build_sec_desc(struct cifs_ntsd *pntsd, struct cifs_ntsd *pnntsd, · 8 unmodified lines | |||
| 1039 | if (!ngroup_sid_ptr) | 1072 | if (!ngroup_sid_ptr) |
| 1040 | return -ENOMEM; | 1073 | return -ENOMEM; |
| 1041 | id = from_kgid(&init_user_ns, gid); | 1074 | id = from_kgid(&init_user_ns, gid); |
| 1042 | rc = id_to_sid(id, SIDGROUP, ngroup_sid_ptr); | 1075 | if (id_from_sid) { |
| 1043 | if (rc) { | 1076 | struct owner_sid *gsid = (struct owner_sid *)ngroup_sid_ptr; |
| 1044 | cifs_dbg(FYI, "%s: Mapping error %d for group id %d\n", | 1077 | /* Populate the group ownership fields S-1-5-88-2 */ |
| 1045 | __func__, rc, id); | 1078 | gsid->Revision = 1; |
| 1046 | kfree(ngroup_sid_ptr); | 1079 | gsid->NumAuth = 3; |
| 1047 | return rc; | 1080 | gsid->Authority[5] = 5; |
| 1081 | gsid->SubAuthorities[0] = cpu_to_le32(88); | ||
| 1082 | gsid->SubAuthorities[1] = cpu_to_le32(2); | ||
| 1083 | gsid->SubAuthorities[2] = cpu_to_le32(id); | ||
| 1084 | } else { /* lookup sid with upcall */ | ||
| 1085 | rc = id_to_sid(id, SIDGROUP, ngroup_sid_ptr); | ||
| 1086 | if (rc) { | ||
| 1087 | cifs_dbg(FYI, "%s: Mapping error %d for group id %d\n", | ||
| 1088 | __func__, rc, id); | ||
| 1089 | kfree(ngroup_sid_ptr); | ||
| 1090 | return rc; | ||
| 1091 | } | ||
| 1048 | } | 1092 | } |
| 1049 | cifs_copy_sid(group_sid_ptr, ngroup_sid_ptr); | 1093 | cifs_copy_sid(group_sid_ptr, ngroup_sid_ptr); |
| 1050 | kfree(ngroup_sid_ptr); | 1094 | kfree(ngroup_sid_ptr); |
| @@ -1247,7 +1291,7 @@ id_mode_to_cifs_acl(struct inode *inode, const char *path, __u64 nmode, · 196 unmodified lines | |||
| 1247 | struct cifs_sb_info *cifs_sb = CIFS_SB(inode->i_sb); | 1291 | struct cifs_sb_info *cifs_sb = CIFS_SB(inode->i_sb); |
| 1248 | struct tcon_link *tlink = cifs_sb_tlink(cifs_sb); | 1292 | struct tcon_link *tlink = cifs_sb_tlink(cifs_sb); |
| 1249 | struct smb_version_operations *ops; | 1293 | struct smb_version_operations *ops; |
| 1250 | bool mode_from_sid; | 1294 | bool mode_from_sid, id_from_sid; |
| 1251 | 1295 | ||
| 1252 | if (IS_ERR(tlink)) | 1296 | if (IS_ERR(tlink)) |
| 1253 | return PTR_ERR(tlink); | 1297 | return PTR_ERR(tlink); |
| @@ -1290,8 +1334,13 @@ id_mode_to_cifs_acl(struct inode *inode, const char *path, __u64 nmode, · 36 unmodified lines | |||
| 1290 | else | 1334 | else |
| 1291 | mode_from_sid = false; | 1335 | mode_from_sid = false; |
| 1292 | 1336 | ||
| 1337 | if (cifs_sb->mnt_cifs_flags & CIFS_MOUNT_UID_FROM_ACL) | ||
| 1338 | id_from_sid = true; | ||
| 1339 | else | ||
| 1340 | id_from_sid = false; | ||
| 1341 | |||
| 1293 | rc = build_sec_desc(pntsd, pnntsd, secdesclen, nmode, uid, gid, | 1342 | rc = build_sec_desc(pntsd, pnntsd, secdesclen, nmode, uid, gid, |
| 1294 | mode_from_sid, &aclflag); | 1343 | mode_from_sid, id_from_sid, &aclflag); |
| 1295 | 1344 | ||
| 1296 | cifs_dbg(NOISY, "build_sec_desc rc: %d\n", rc); | 1345 | cifs_dbg(NOISY, "build_sec_desc rc: %d\n", rc); |
| 1297 | 1346 | ||
| @@ -176,6 +176,21 @@ struct smb3_acl { · 175 unmodified lines | |||
| 176 | __le16 Sbz2; /* MBZ */ | 176 | __le16 Sbz2; /* MBZ */ |
| 177 | } __packed; | 177 | } __packed; |
| 178 | 178 | ||
| 179 | /* | ||
| 180 | * Used to store the special 'NFS SIDs' used to persist the POSIX uid and gid | ||
| 181 | * See See http://technet.microsoft.com/en-us/library/hh509017(v=ws.10).aspx | ||
| 182 | */ | ||
| 183 | struct owner_sid { | ||
| 184 | u8 Revision; | ||
| 185 | u8 NumAuth; | ||
| 186 | u8 Authority[6]; | ||
| 187 | __le32 SubAuthorities[3]; | ||
| 188 | } __packed; | ||
| 189 | |||
| 190 | struct owner_group_sids { | ||
| 191 | struct owner_sid owner; | ||
| 192 | struct owner_sid group; | ||
| 193 | } __packed; | ||
| 179 | 194 | ||
| 180 | /* | 195 | /* |
| 181 | * Minimum security identifier can be one for system defined Users | 196 | * Minimum security identifier can be one for system defined Users |
| @@ -623,7 +623,7 @@ cifs_show_options(struct seq_file *s, struct dentry *root) · 622 unmodified lines | |||
| 623 | seq_printf(s, ",actimeo=%lu", cifs_sb->actimeo / HZ); | 623 | seq_printf(s, ",actimeo=%lu", cifs_sb->actimeo / HZ); |
| 624 | 624 | ||
| 625 | if (tcon->ses->chan_max > 1) | 625 | if (tcon->ses->chan_max > 1) |
| 626 | seq_printf(s, ",multichannel,max_channel=%zu", | 626 | seq_printf(s, ",multichannel,max_channels=%zu", |
| 627 | tcon->ses->chan_max); | 627 | tcon->ses->chan_max); |
| 628 | 628 | ||
| 629 | return 0; | 629 | return 0; |
| @@ -2008,6 +2008,24 @@ extern struct smb_version_values smb302_values; · 2007 unmodified lines | |||
| 2008 | extern struct smb_version_operations smb311_operations; | 2008 | extern struct smb_version_operations smb311_operations; |
| 2009 | extern struct smb_version_values smb311_values; | 2009 | extern struct smb_version_values smb311_values; |
| 2010 | 2010 | ||
| 2011 | static inline char *get_security_type_str(enum securityEnum sectype) | ||
| 2012 | { | ||
| 2013 | switch (sectype) { | ||
| 2014 | case RawNTLMSSP: | ||
| 2015 | return "RawNTLMSSP"; | ||
| 2016 | case Kerberos: | ||
| 2017 | return "Kerberos"; | ||
| 2018 | case NTLMv2: | ||
| 2019 | return "NTLMv2"; | ||
| 2020 | case NTLM: | ||
| 2021 | return "NTLM"; | ||
| 2022 | case LANMAN: | ||
| 2023 | return "LANMAN"; | ||
| 2024 | default: | ||
| 2025 | return "Unknown"; | ||
| 2026 | } | ||
| 2027 | } | ||
| 2028 | |||
| 2011 | static inline bool is_smb1_server(struct TCP_Server_Info *server) | 2029 | static inline bool is_smb1_server(struct TCP_Server_Info *server) |
| 2012 | { | 2030 | { |
| 2013 | return strcmp(server->vals->version_string, SMB1_VERSION_STRING) == 0; | 2031 | return strcmp(server->vals->version_string, SMB1_VERSION_STRING) == 0; |
| @@ -198,6 +198,8 @@ extern struct inode *cifs_iget(struct super_block *sb, · 197 unmodified lines | |||
| 198 | extern int cifs_get_inode_info(struct inode **inode, const char *full_path, | 198 | extern int cifs_get_inode_info(struct inode **inode, const char *full_path, |
| 199 | FILE_ALL_INFO *data, struct super_block *sb, | 199 | FILE_ALL_INFO *data, struct super_block *sb, |
| 200 | int xid, const struct cifs_fid *fid); | 200 | int xid, const struct cifs_fid *fid); |
| 201 | extern int smb311_posix_get_inode_info(struct inode **pinode, const char *search_path, | ||
| 202 | struct super_block *sb, unsigned int xid); | ||
| 201 | extern int cifs_get_inode_info_unix(struct inode **pinode, | 203 | extern int cifs_get_inode_info_unix(struct inode **pinode, |
| 202 | const unsigned char *search_path, | 204 | const unsigned char *search_path, |
| 203 | struct super_block *sb, unsigned int xid); | 205 | struct super_block *sb, unsigned int xid); |
| @@ -220,6 +222,7 @@ extern int set_cifs_acl(struct cifs_ntsd *, __u32, struct inode *, · 16 unmodified lines | |||
| 220 | const char *, int); | 222 | const char *, int); |
| 221 | extern unsigned int setup_authusers_ACE(struct cifs_ace *pace); | 223 | extern unsigned int setup_authusers_ACE(struct cifs_ace *pace); |
| 222 | extern unsigned int setup_special_mode_ACE(struct cifs_ace *pace, __u64 nmode); | 224 | extern unsigned int setup_special_mode_ACE(struct cifs_ace *pace, __u64 nmode); |
| 225 | extern unsigned int setup_special_user_owner_ACE(struct cifs_ace *pace); | ||
| 223 | 226 | ||
| 224 | extern void dequeue_mid(struct mid_q_entry *mid, bool malformed); | 227 | extern void dequeue_mid(struct mid_q_entry *mid, bool malformed); |
| 225 | extern int cifs_read_from_socket(struct TCP_Server_Info *server, char *buf, | 228 | extern int cifs_read_from_socket(struct TCP_Server_Info *server, char *buf, |
| @@ -411,6 +411,7 @@ cifs_create_get_file_info: · 410 unmodified lines | |||
| 411 | rc = cifs_get_inode_info_unix(&newinode, full_path, inode->i_sb, | 411 | rc = cifs_get_inode_info_unix(&newinode, full_path, inode->i_sb, |
| 412 | xid); | 412 | xid); |
| 413 | else { | 413 | else { |
| 414 | /* TODO: Add support for calling POSIX query info here, but passing in fid */ | ||
| 414 | rc = cifs_get_inode_info(&newinode, full_path, buf, inode->i_sb, | 415 | rc = cifs_get_inode_info(&newinode, full_path, buf, inode->i_sb, |
| 415 | xid, fid); | 416 | xid, fid); |
| 416 | if (newinode) { | 417 | if (newinode) { |
| @@ -700,7 +701,9 @@ cifs_lookup(struct inode *parent_dir_inode, struct dentry *direntry, · 283 unmodified lines | |||
| 700 | cifs_dbg(FYI, "Full path: %s inode = 0x%p\n", | 701 | cifs_dbg(FYI, "Full path: %s inode = 0x%p\n", |
| 701 | full_path, d_inode(direntry)); | 702 | full_path, d_inode(direntry)); |
| 702 | 703 | ||
| 703 | if (pTcon->unix_ext) { | 704 | if (pTcon->posix_extensions) |
| 705 | rc = smb311_posix_get_inode_info(&newInode, full_path, parent_dir_inode->i_sb, xid); | ||
| 706 | else if (pTcon->unix_ext) { | ||
| 704 | rc = cifs_get_inode_info_unix(&newInode, full_path, | 707 | rc = cifs_get_inode_info_unix(&newInode, full_path, |
| 705 | parent_dir_inode->i_sb, xid); | 708 | parent_dir_inode->i_sb, xid); |
| 706 | } else { | 709 | } else { |
| @@ -243,6 +243,7 @@ cifs_nt_open(char *full_path, struct inode *inode, struct cifs_sb_info *cifs_sb, · 242 unmodified lines | |||
| 243 | if (rc) | 243 | if (rc) |
| 244 | goto out; | 244 | goto out; |
| 245 | 245 | ||
| 246 | /* TODO: Add support for calling posix query info but with passing in fid */ | ||
| 246 | if (tcon->unix_ext) | 247 | if (tcon->unix_ext) |
| 247 | rc = cifs_get_inode_info_unix(&inode, full_path, inode->i_sb, | 248 | rc = cifs_get_inode_info_unix(&inode, full_path, inode->i_sb, |
| 248 | xid); | 249 | xid); |
| @@ -800,7 +801,9 @@ reopen_success: · 551 unmodified lines | |||
| 800 | if (!is_interrupt_error(rc)) | 801 | if (!is_interrupt_error(rc)) |
| 801 | mapping_set_error(inode->i_mapping, rc); | 802 | mapping_set_error(inode->i_mapping, rc); |
| 802 | 803 | ||
| 803 | if (tcon->unix_ext) | 804 | if (tcon->posix_extensions) |
| 805 | rc = smb311_posix_get_inode_info(&inode, full_path, inode->i_sb, xid); | ||
| 806 | else if (tcon->unix_ext) | ||
| 804 | rc = cifs_get_inode_info_unix(&inode, full_path, | 807 | rc = cifs_get_inode_info_unix(&inode, full_path, |
| 805 | inode->i_sb, xid); | 808 | inode->i_sb, xid); |
| 806 | else | 809 | else |
| @@ -96,6 +96,7 @@ void cifs_fscache_get_super_cookie(struct cifs_tcon *tcon) · 95 unmodified lines | |||
| 96 | { | 96 | { |
| 97 | struct TCP_Server_Info *server = tcon->ses->server; | 97 | struct TCP_Server_Info *server = tcon->ses->server; |
| 98 | char *sharename; | 98 | char *sharename; |
| 99 | struct cifs_fscache_super_auxdata auxdata; | ||
| 99 | 100 | ||
| 100 | sharename = extract_sharename(tcon->treeName); | 101 | sharename = extract_sharename(tcon->treeName); |
| 101 | if (IS_ERR(sharename)) { | 102 | if (IS_ERR(sharename)) { |
| @@ -104,11 +105,16 @@ void cifs_fscache_get_super_cookie(struct cifs_tcon *tcon) · 2 unmodified lines | |||
| 104 | return; | 105 | return; |
| 105 | } | 106 | } |
| 106 | 107 | ||
| 108 | memset(&auxdata, 0, sizeof(auxdata)); | ||
| 109 | auxdata.resource_id = tcon->resource_id; | ||
| 110 | auxdata.vol_create_time = tcon->vol_create_time; | ||
| 111 | auxdata.vol_serial_number = tcon->vol_serial_number; | ||
| 112 | |||
| 107 | tcon->fscache = | 113 | tcon->fscache = |
| 108 | fscache_acquire_cookie(server->fscache, | 114 | fscache_acquire_cookie(server->fscache, |
| 109 | &cifs_fscache_super_index_def, | 115 | &cifs_fscache_super_index_def, |
| 110 | sharename, strlen(sharename), | 116 | sharename, strlen(sharename), |
| 111 | &tcon->resource_id, sizeof(tcon->resource_id), | 117 | &auxdata, sizeof(auxdata), |
| 112 | tcon, 0, true); | 118 | tcon, 0, true); |
| 113 | kfree(sharename); | 119 | kfree(sharename); |
| 114 | cifs_dbg(FYI, "%s: (0x%p/0x%p)\n", | 120 | cifs_dbg(FYI, "%s: (0x%p/0x%p)\n", |
| @@ -117,8 +123,15 @@ void cifs_fscache_get_super_cookie(struct cifs_tcon *tcon) · 2 unmodified lines | |||
| 117 | 123 | ||
| 118 | void cifs_fscache_release_super_cookie(struct cifs_tcon *tcon) | 124 | void cifs_fscache_release_super_cookie(struct cifs_tcon *tcon) |
| 119 | { | 125 | { |
| 126 | struct cifs_fscache_super_auxdata auxdata; | ||
| 127 | |||
| 128 | memset(&auxdata, 0, sizeof(auxdata)); | ||
| 129 | auxdata.resource_id = tcon->resource_id; | ||
| 130 | auxdata.vol_create_time = tcon->vol_create_time; | ||
| 131 | auxdata.vol_serial_number = tcon->vol_serial_number; | ||
| 132 | |||
| 120 | cifs_dbg(FYI, "%s: (0x%p)\n", __func__, tcon->fscache); | 133 | cifs_dbg(FYI, "%s: (0x%p)\n", __func__, tcon->fscache); |
| 121 | fscache_relinquish_cookie(tcon->fscache, &tcon->resource_id, false); | 134 | fscache_relinquish_cookie(tcon->fscache, &auxdata, false); |
| 122 | tcon->fscache = NULL; | 135 | tcon->fscache = NULL; |
| 123 | } | 136 | } |
| 124 | 137 | ||
| @@ -27,6 +27,15 @@ · 26 unmodified lines | |||
| 27 | 27 | ||
| 28 | #ifdef CONFIG_CIFS_FSCACHE | 28 | #ifdef CONFIG_CIFS_FSCACHE |
| 29 | 29 | ||
| 30 | /* | ||
| 31 | * Auxiliary data attached to CIFS superblock within the cache | ||
| 32 | */ | ||
| 33 | struct cifs_fscache_super_auxdata { | ||
| 34 | u64 resource_id; /* unique server resource id */ | ||
| 35 | __le64 vol_create_time; | ||
| 36 | u32 vol_serial_number; | ||
| 37 | } __packed; | ||
| 38 | |||
| 30 | /* | 39 | /* |
| 31 | * Auxiliary data attached to CIFS inode within the cache | 40 | * Auxiliary data attached to CIFS inode within the cache |
| 32 | */ | 41 | */ |
| @@ -32,6 +32,7 @@ · 31 unmodified lines | |||
| 32 | #include "cifspdu.h" | 32 | #include "cifspdu.h" |
| 33 | #include "cifsglob.h" | 33 | #include "cifsglob.h" |
| 34 | #include "cifsproto.h" | 34 | #include "cifsproto.h" |
| 35 | #include "smb2proto.h" | ||
| 35 | #include "cifs_debug.h" | 36 | #include "cifs_debug.h" |
| 36 | #include "cifs_fs_sb.h" | 37 | #include "cifs_fs_sb.h" |
| 37 | #include "cifs_unicode.h" | 38 | #include "cifs_unicode.h" |
| @@ -595,6 +596,62 @@ static int cifs_sfu_mode(struct cifs_fattr *fattr, const unsigned char *path, · 557 unmodified lines | |||
| 595 | #endif | 596 | #endif |
| 596 | } | 597 | } |
| 597 | 598 | ||
| 599 | /* Fill a cifs_fattr struct with info from POSIX info struct */ | ||
| 600 | static void | ||
| 601 | smb311_posix_info_to_fattr(struct cifs_fattr *fattr, struct smb311_posix_qinfo *info, | ||
| 602 | struct super_block *sb, bool adjust_tz, bool symlink) | ||
| 603 | { | ||
| 604 | struct cifs_sb_info *cifs_sb = CIFS_SB(sb); | ||
| 605 | struct cifs_tcon *tcon = cifs_sb_master_tcon(cifs_sb); | ||
| 606 | |||
| 607 | memset(fattr, 0, sizeof(*fattr)); | ||
| 608 | |||
| 609 | /* no fattr->flags to set */ | ||
| 610 | fattr->cf_cifsattrs = le32_to_cpu(info->DosAttributes); | ||
| 611 | fattr->cf_uniqueid = le64_to_cpu(info->Inode); | ||
| 612 | |||
| 613 | if (info->LastAccessTime) | ||
| 614 | fattr->cf_atime = cifs_NTtimeToUnix(info->LastAccessTime); | ||
| 615 | else | ||
| 616 | ktime_get_coarse_real_ts64(&fattr->cf_atime); | ||
| 617 | |||
| 618 | fattr->cf_ctime = cifs_NTtimeToUnix(info->ChangeTime); | ||
| 619 | fattr->cf_mtime = cifs_NTtimeToUnix(info->LastWriteTime); | ||
| 620 | |||
| 621 | if (adjust_tz) { | ||
| 622 | fattr->cf_ctime.tv_sec += tcon->ses->server->timeAdj; | ||
| 623 | fattr->cf_mtime.tv_sec += tcon->ses->server->timeAdj; | ||
| 624 | } | ||
| 625 | |||
| 626 | fattr->cf_eof = le64_to_cpu(info->EndOfFile); | ||
| 627 | fattr->cf_bytes = le64_to_cpu(info->AllocationSize); | ||
| 628 | fattr->cf_createtime = le64_to_cpu(info->CreationTime); | ||
| 629 | |||
| 630 | fattr->cf_nlink = le32_to_cpu(info->HardLinks); | ||
| 631 | fattr->cf_mode = (umode_t) le32_to_cpu(info->Mode); | ||
| 632 | /* The srv fs device id is overridden on network mount so setting rdev isn't needed here */ | ||
| 633 | /* fattr->cf_rdev = le32_to_cpu(info->DeviceId); */ | ||
| 634 | |||
| 635 | if (symlink) { | ||
| 636 | fattr->cf_mode |= S_IFLNK; | ||
| 637 | fattr->cf_dtype = DT_LNK; | ||
| 638 | } else if (fattr->cf_cifsattrs & ATTR_DIRECTORY) { | ||
| 639 | fattr->cf_mode |= S_IFDIR; | ||
| 640 | fattr->cf_dtype = DT_DIR; | ||
| 641 | } else { /* file */ | ||
| 642 | fattr->cf_mode |= S_IFREG; | ||
| 643 | fattr->cf_dtype = DT_REG; | ||
| 644 | } | ||
| 645 | /* else if reparse point ... TODO: add support for FIFO and blk dev; special file types */ | ||
| 646 | |||
| 647 | fattr->cf_uid = cifs_sb->mnt_uid; /* TODO: map uid and gid from SID */ | ||
| 648 | fattr->cf_gid = cifs_sb->mnt_gid; | ||
| 649 | |||
| 650 | cifs_dbg(FYI, "POSIX query info: mode 0x%x uniqueid 0x%llx nlink %d\n", | ||
| 651 | fattr->cf_mode, fattr->cf_uniqueid, fattr->cf_nlink); | ||
| 652 | } | ||
| 653 | |||
| 654 | |||
| 598 | /* Fill a cifs_fattr struct with info from FILE_ALL_INFO */ | 655 | /* Fill a cifs_fattr struct with info from FILE_ALL_INFO */ |
| 599 | static void | 656 | static void |
| 600 | cifs_all_info_to_fattr(struct cifs_fattr *fattr, FILE_ALL_INFO *info, | 657 | cifs_all_info_to_fattr(struct cifs_fattr *fattr, FILE_ALL_INFO *info, |
| @@ -1023,6 +1080,121 @@ out: · 422 unmodified lines | |||
| 1023 | return rc; | 1080 | return rc; |
| 1024 | } | 1081 | } |
| 1025 | 1082 | ||
| 1083 | int | ||
| 1084 | smb311_posix_get_inode_info(struct inode **inode, | ||
| 1085 | const char *full_path, | ||
| 1086 | struct super_block *sb, unsigned int xid) | ||
| 1087 | { | ||
| 1088 | struct cifs_tcon *tcon; | ||
| 1089 | struct TCP_Server_Info *server; | ||
| 1090 | struct tcon_link *tlink; | ||
| 1091 | struct cifs_sb_info *cifs_sb = CIFS_SB(sb); | ||
| 1092 | bool adjust_tz = false; | ||
| 1093 | struct cifs_fattr fattr = {0}; | ||
| 1094 | bool symlink = false; | ||
| 1095 | struct smb311_posix_qinfo *data = NULL; | ||
| 1096 | int rc = 0; | ||
| 1097 | int tmprc = 0; | ||
| 1098 | |||
| 1099 | tlink = cifs_sb_tlink(cifs_sb); | ||
| 1100 | if (IS_ERR(tlink)) | ||
| 1101 | return PTR_ERR(tlink); | ||
| 1102 | tcon = tlink_tcon(tlink); | ||
| 1103 | server = tcon->ses->server; | ||
| 1104 | |||
| 1105 | /* | ||
| 1106 | * 1. Fetch file metadata | ||
| 1107 | */ | ||
| 1108 | |||
| 1109 | if (is_inode_cache_good(*inode)) { | ||
| 1110 | cifs_dbg(FYI, "No need to revalidate cached inode sizes\n"); | ||
| 1111 | goto out; | ||
| 1112 | } | ||
| 1113 | data = kmalloc(sizeof(struct smb311_posix_qinfo), GFP_KERNEL); | ||
| 1114 | if (!data) { | ||
| 1115 | rc = -ENOMEM; | ||
| 1116 | goto out; | ||
| 1117 | } | ||
| 1118 | |||
| 1119 | rc = smb311_posix_query_path_info(xid, tcon, cifs_sb, | ||
| 1120 | full_path, data, | ||
| 1121 | &adjust_tz, &symlink); | ||
| 1122 | |||
| 1123 | /* | ||
| 1124 | * 2. Convert it to internal cifs metadata (fattr) | ||
| 1125 | */ | ||
| 1126 | |||
| 1127 | switch (rc) { | ||
| 1128 | case 0: | ||
| 1129 | smb311_posix_info_to_fattr(&fattr, data, sb, adjust_tz, symlink); | ||
| 1130 | break; | ||
| 1131 | case -EREMOTE: | ||
| 1132 | /* DFS link, no metadata available on this server */ | ||
| 1133 | cifs_create_dfs_fattr(&fattr, sb); | ||
| 1134 | rc = 0; | ||
| 1135 | break; | ||
| 1136 | case -EACCES: | ||
| 1137 | /* | ||
| 1138 | * For SMB2 and later the backup intent flag | ||
| 1139 | * is already sent if needed on open and there | ||
| 1140 | * is no path based FindFirst operation to use | ||
| 1141 | * to retry with so nothing we can do, bail out | ||
| 1142 | */ | ||
| 1143 | goto out; | ||
| 1144 | default: | ||
| 1145 | cifs_dbg(FYI, "%s: unhandled err rc %d\n", __func__, rc); | ||
| 1146 | goto out; | ||
| 1147 | } | ||
| 1148 | |||
| 1149 | |||
| 1150 | /* | ||
| 1151 | * 3. Tweak fattr based on mount options | ||
| 1152 | */ | ||
| 1153 | |||
| 1154 | /* check for Minshall+French symlinks */ | ||
| 1155 | if (cifs_sb->mnt_cifs_flags & CIFS_MOUNT_MF_SYMLINKS) { | ||
| 1156 | tmprc = check_mf_symlink(xid, tcon, cifs_sb, &fattr, | ||
| 1157 | full_path); | ||
| 1158 | if (tmprc) | ||
| 1159 | cifs_dbg(FYI, "check_mf_symlink: %d\n", tmprc); | ||
| 1160 | } | ||
| 1161 | |||
| 1162 | /* | ||
| 1163 | * 4. Update inode with final fattr data | ||
| 1164 | */ | ||
| 1165 | |||
| 1166 | if (!*inode) { | ||
| 1167 | *inode = cifs_iget(sb, &fattr); | ||
| 1168 | if (!*inode) | ||
| 1169 | rc = -ENOMEM; | ||
| 1170 | } else { | ||
| 1171 | /* we already have inode, update it */ | ||
| 1172 | |||
| 1173 | /* if uniqueid is different, return error */ | ||
| 1174 | if (unlikely(cifs_sb->mnt_cifs_flags & CIFS_MOUNT_SERVER_INUM && | ||
| 1175 | CIFS_I(*inode)->uniqueid != fattr.cf_uniqueid)) { | ||
| 1176 | CIFS_I(*inode)->time = 0; /* force reval */ | ||
| 1177 | rc = -ESTALE; | ||
| 1178 | goto out; | ||
| 1179 | } | ||
| 1180 | |||
| 1181 | /* if filetype is different, return error */ | ||
| 1182 | if (unlikely(((*inode)->i_mode & S_IFMT) != | ||
| 1183 | (fattr.cf_mode & S_IFMT))) { | ||
| 1184 | CIFS_I(*inode)->time = 0; /* force reval */ | ||
| 1185 | rc = -ESTALE; | ||
| 1186 | goto out; | ||
| 1187 | } | ||
| 1188 | |||
| 1189 | cifs_fattr_to_inode(*inode, &fattr); | ||
| 1190 | } | ||
| 1191 | out: | ||
| 1192 | cifs_put_tlink(tlink); | ||
| 1193 | kfree(data); | ||
| 1194 | return rc; | ||
| 1195 | } | ||
| 1196 | |||
| 1197 | |||
| 1026 | static const struct inode_operations cifs_ipc_inode_ops = { | 1198 | static const struct inode_operations cifs_ipc_inode_ops = { |
| 1027 | .lookup = cifs_lookup, | 1199 | .lookup = cifs_lookup, |
| 1028 | }; | 1200 | }; |
| @@ -1161,7 +1333,10 @@ struct inode *cifs_root_iget(struct super_block *sb) · 132 unmodified lines | |||
| 1161 | } | 1333 | } |
| 1162 | 1334 | ||
| 1163 | convert_delimiter(path, CIFS_DIR_SEP(cifs_sb)); | 1335 | convert_delimiter(path, CIFS_DIR_SEP(cifs_sb)); |
| 1164 | rc = cifs_get_inode_info(&inode, path, NULL, sb, xid, NULL); | 1336 | if (tcon->posix_extensions) |
| 1337 | rc = smb311_posix_get_inode_info(&inode, path, sb, xid); | ||
| 1338 | else | ||
| 1339 | rc = cifs_get_inode_info(&inode, path, NULL, sb, xid, NULL); | ||
| 1165 | 1340 | ||
| 1166 | iget_no_retry: | 1341 | iget_no_retry: |
| 1167 | if (!inode) { | 1342 | if (!inode) { |
| @@ -1517,7 +1692,9 @@ cifs_mkdir_qinfo(struct inode *parent, struct dentry *dentry, umode_t mode, · 349 unmodified lines | |||
| 1517 | int rc = 0; | 1692 | int rc = 0; |
| 1518 | struct inode *inode = NULL; | 1693 | struct inode *inode = NULL; |
| 1519 | 1694 | ||
| 1520 | if (tcon->unix_ext) | 1695 | if (tcon->posix_extensions) |
| 1696 | rc = smb311_posix_get_inode_info(&inode, full_path, parent->i_sb, xid); | ||
| 1697 | else if (tcon->unix_ext) | ||
| 1521 | rc = cifs_get_inode_info_unix(&inode, full_path, parent->i_sb, | 1698 | rc = cifs_get_inode_info_unix(&inode, full_path, parent->i_sb, |
| 1522 | xid); | 1699 | xid); |
| 1523 | else | 1700 | else |
| @@ -2114,7 +2291,9 @@ int cifs_revalidate_dentry_attr(struct dentry *dentry) · 590 unmodified lines | |||
| 2114 | dentry, cifs_get_time(dentry), jiffies); | 2291 | dentry, cifs_get_time(dentry), jiffies); |
| 2115 | 2292 | ||
| 2116 | again: | 2293 | again: |
| 2117 | if (cifs_sb_master_tcon(CIFS_SB(sb))->unix_ext) | 2294 | if (cifs_sb_master_tcon(CIFS_SB(sb))->posix_extensions) |
| 2295 | rc = smb311_posix_get_inode_info(&inode, full_path, sb, xid); | ||
| 2296 | else if (cifs_sb_master_tcon(CIFS_SB(sb))->unix_ext) | ||
| 2118 | rc = cifs_get_inode_info_unix(&inode, full_path, sb, xid); | 2297 | rc = cifs_get_inode_info_unix(&inode, full_path, sb, xid); |
| 2119 | else | 2298 | else |
| 2120 | rc = cifs_get_inode_info(&inode, full_path, NULL, sb, | 2299 | rc = cifs_get_inode_info(&inode, full_path, NULL, sb, |
| @@ -701,7 +701,9 @@ cifs_symlink(struct inode *inode, struct dentry *direntry, const char *symname) · 700 unmodified lines | |||
| 701 | cifs_sb_target->local_nls); */ | 701 | cifs_sb_target->local_nls); */ |
| 702 | 702 | ||
| 703 | if (rc == 0) { | 703 | if (rc == 0) { |
| 704 | if (pTcon->unix_ext) | 704 | if (pTcon->posix_extensions) |
| 705 | rc = smb311_posix_get_inode_info(&newinode, full_path, inode->i_sb, xid); | ||
| 706 | else if (pTcon->unix_ext) | ||
| 705 | rc = cifs_get_inode_info_unix(&newinode, full_path, | 707 | rc = cifs_get_inode_info_unix(&newinode, full_path, |
| 706 | inode->i_sb, xid); | 708 | inode->i_sb, xid); |
| 707 | else | 709 | else |
| @@ -45,6 +45,7 @@ · 44 unmodified lines | |||
| 45 | #define SMB2_OP_HARDLINK 8 | 45 | #define SMB2_OP_HARDLINK 8 |
| 46 | #define SMB2_OP_SET_EOF 9 | 46 | #define SMB2_OP_SET_EOF 9 |
| 47 | #define SMB2_OP_RMDIR 10 | 47 | #define SMB2_OP_RMDIR 10 |
| 48 | #define SMB2_OP_POSIX_QUERY_INFO 11 | ||
| 48 | 49 | ||
| 49 | /* Used when constructing chained read requests. */ | 50 | /* Used when constructing chained read requests. */ |
| 50 | #define CHAINED_REQUEST 1 | 51 | #define CHAINED_REQUEST 1 |
| @@ -166,6 +166,40 @@ smb2_compound_op(const unsigned int xid, struct cifs_tcon *tcon, · 165 unmodified lines | |||
| 166 | trace_smb3_query_info_compound_enter(xid, ses->Suid, tcon->tid, | 166 | trace_smb3_query_info_compound_enter(xid, ses->Suid, tcon->tid, |
| 167 | full_path); | 167 | full_path); |
| 168 | break; | 168 | break; |
| 169 | case SMB2_OP_POSIX_QUERY_INFO: | ||
| 170 | rqst[num_rqst].rq_iov = &vars->qi_iov[0]; | ||
| 171 | rqst[num_rqst].rq_nvec = 1; | ||
| 172 | |||
| 173 | if (cfile) | ||
| 174 | rc = SMB2_query_info_init(tcon, server, | ||
| 175 | &rqst[num_rqst], | ||
| 176 | cfile->fid.persistent_fid, | ||
| 177 | cfile->fid.volatile_fid, | ||
| 178 | SMB_FIND_FILE_POSIX_INFO, | ||
| 179 | SMB2_O_INFO_FILE, 0, | ||
| 180 | /* TBD: fix following to allow for longer SIDs */ | ||
| 181 | sizeof(struct smb311_posix_qinfo *) + (PATH_MAX * 2) + | ||
| 182 | (sizeof(struct cifs_sid) * 2), 0, NULL); | ||
| 183 | else { | ||
| 184 | rc = SMB2_query_info_init(tcon, server, | ||
| 185 | &rqst[num_rqst], | ||
| 186 | COMPOUND_FID, | ||
| 187 | COMPOUND_FID, | ||
| 188 | SMB_FIND_FILE_POSIX_INFO, | ||
| 189 | SMB2_O_INFO_FILE, 0, | ||
| 190 | sizeof(struct smb311_posix_qinfo *) + (PATH_MAX * 2) + | ||
| 191 | (sizeof(struct cifs_sid) * 2), 0, NULL); | ||
| 192 | if (!rc) { | ||
| 193 | smb2_set_next_command(tcon, &rqst[num_rqst]); | ||
| 194 | smb2_set_related(&rqst[num_rqst]); | ||
| 195 | } | ||
| 196 | } | ||
| 197 | |||
| 198 | if (rc) | ||
| 199 | goto finished; | ||
| 200 | num_rqst++; | ||
| 201 | trace_smb3_posix_query_info_compound_enter(xid, ses->Suid, tcon->tid, full_path); | ||
| 202 | break; | ||
| 169 | case SMB2_OP_DELETE: | 203 | case SMB2_OP_DELETE: |
| 170 | trace_smb3_delete_enter(xid, ses->Suid, tcon->tid, full_path); | 204 | trace_smb3_delete_enter(xid, ses->Suid, tcon->tid, full_path); |
| 171 | break; | 205 | break; |
| @@ -379,6 +413,24 @@ smb2_compound_op(const unsigned int xid, struct cifs_tcon *tcon, · 207 unmodified lines | |||
| 379 | trace_smb3_query_info_compound_done(xid, ses->Suid, | 413 | trace_smb3_query_info_compound_done(xid, ses->Suid, |
| 380 | tcon->tid); | 414 | tcon->tid); |
| 381 | break; | 415 | break; |
| 416 | case SMB2_OP_POSIX_QUERY_INFO: | ||
| 417 | if (rc == 0) { | ||
| 418 | qi_rsp = (struct smb2_query_info_rsp *) | ||
| 419 | rsp_iov[1].iov_base; | ||
| 420 | rc = smb2_validate_and_copy_iov( | ||
| 421 | le16_to_cpu(qi_rsp->OutputBufferOffset), | ||
| 422 | le32_to_cpu(qi_rsp->OutputBufferLength), | ||
| 423 | &rsp_iov[1], sizeof(struct smb311_posix_qinfo) /* add SIDs */, ptr); | ||
| 424 | } | ||
| 425 | if (rqst[1].rq_iov) | ||
| 426 | SMB2_query_info_free(&rqst[1]); | ||
| 427 | if (rqst[2].rq_iov) | ||
| 428 | SMB2_close_free(&rqst[2]); | ||
| 429 | if (rc) | ||
| 430 | trace_smb3_posix_query_info_compound_err(xid, ses->Suid, tcon->tid, rc); | ||
| 431 | else | ||
| 432 | trace_smb3_posix_query_info_compound_done(xid, ses->Suid, tcon->tid); | ||
| 433 | break; | ||
| 382 | case SMB2_OP_DELETE: | 434 | case SMB2_OP_DELETE: |
| 383 | if (rc) | 435 | if (rc) |
| 384 | trace_smb3_delete_err(xid, ses->Suid, tcon->tid, rc); | 436 | trace_smb3_delete_err(xid, ses->Suid, tcon->tid, rc); |
| @@ -512,6 +564,59 @@ out: · 127 unmodified lines | |||
| 512 | return rc; | 564 | return rc; |
| 513 | } | 565 | } |
| 514 | 566 | ||
| 567 | |||
| 568 | int | ||
| 569 | smb311_posix_query_path_info(const unsigned int xid, struct cifs_tcon *tcon, | ||
| 570 | struct cifs_sb_info *cifs_sb, const char *full_path, | ||
| 571 | struct smb311_posix_qinfo *data, bool *adjust_tz, bool *symlink) | ||
| 572 | { | ||
| 573 | int rc; | ||
| 574 | __u32 create_options = 0; | ||
| 575 | struct cifsFileInfo *cfile; | ||
| 576 | struct smb311_posix_qinfo *smb2_data; | ||
| 577 | |||
| 578 | *adjust_tz = false; | ||
| 579 | *symlink = false; | ||
| 580 | |||
| 581 | /* BB TODO: Make struct larger when add support for parsing owner SIDs */ | ||
| 582 | smb2_data = kzalloc(sizeof(struct smb311_posix_qinfo), | ||
| 583 | GFP_KERNEL); | ||
| 584 | if (smb2_data == NULL) | ||
| 585 | return -ENOMEM; | ||
| 586 | |||
| 587 | /* | ||
| 588 | * BB TODO: Add support for using the cached root handle. | ||
| 589 | * Create SMB2_query_posix_info worker function to do non-compounded query | ||
| 590 | * when we already have an open file handle for this. For now this is fast enough | ||
| 591 | * (always using the compounded version). | ||
| 592 | */ | ||
| 593 | |||
| 594 | cifs_get_readable_path(tcon, full_path, &cfile); | ||
| 595 | rc = smb2_compound_op(xid, tcon, cifs_sb, full_path, | ||
| 596 | FILE_READ_ATTRIBUTES, FILE_OPEN, create_options, | ||
| 597 | ACL_NO_MODE, smb2_data, SMB2_OP_POSIX_QUERY_INFO, cfile); | ||
| 598 | if (rc == -EOPNOTSUPP) { | ||
| 599 | /* BB TODO: When support for special files added to Samba re-verify this path */ | ||
| 600 | *symlink = true; | ||
| 601 | create_options |= OPEN_REPARSE_POINT; | ||
| 602 | |||
| 603 | /* Failed on a symbolic link - query a reparse point info */ | ||
| 604 | rc = smb2_compound_op(xid, tcon, cifs_sb, full_path, | ||
| 605 | FILE_READ_ATTRIBUTES, FILE_OPEN, | ||
| 606 | create_options, ACL_NO_MODE, | ||
| 607 | smb2_data, SMB2_OP_POSIX_QUERY_INFO, NULL); | ||
| 608 | } | ||
| 609 | if (rc) | ||
| 610 | goto out; | ||
| 611 | |||
| 612 | /* TODO: will need to allow for the 2 SIDs when add support for getting owner UID/GID */ | ||
| 613 | memcpy(data, smb2_data, sizeof(struct smb311_posix_qinfo)); | ||
| 614 | |||
| 615 | out: | ||
| 616 | kfree(smb2_data); | ||
| 617 | return rc; | ||
| 618 | } | ||
| 619 | |||
| 515 | int | 620 | int |
| 516 | smb2_mkdir(const unsigned int xid, struct inode *parent_inode, umode_t mode, | 621 | smb2_mkdir(const unsigned int xid, struct inode *parent_inode, umode_t mode, |
| 517 | struct cifs_tcon *tcon, const char *name, | 622 | struct cifs_tcon *tcon, const char *name, |
| @@ -2317,28 +2317,75 @@ add_twarp_context(struct kvec *iov, unsigned int *num_iovec, __u64 timewarp) · 2316 unmodified lines | |||
| 2317 | return 0; | 2317 | return 0; |
| 2318 | } | 2318 | } |
| 2319 | 2319 | ||
| 2320 | /* See See http://technet.microsoft.com/en-us/library/hh509017(v=ws.10).aspx */ | ||
| 2321 | static void setup_owner_group_sids(char *buf) | ||
| 2322 | { | ||
| 2323 | struct owner_group_sids *sids = (struct owner_group_sids *)buf; | ||
| 2324 | |||
| 2325 | /* Populate the user ownership fields S-1-5-88-1 */ | ||
| 2326 | sids->owner.Revision = 1; | ||
| 2327 | sids->owner.NumAuth = 3; | ||
| 2328 | sids->owner.Authority[5] = 5; | ||
| 2329 | sids->owner.SubAuthorities[0] = cpu_to_le32(88); | ||
| 2330 | sids->owner.SubAuthorities[1] = cpu_to_le32(1); | ||
| 2331 | sids->owner.SubAuthorities[2] = cpu_to_le32(current_fsuid().val); | ||
| 2332 | |||
| 2333 | /* Populate the group ownership fields S-1-5-88-2 */ | ||
| 2334 | sids->group.Revision = 1; | ||
| 2335 | sids->group.NumAuth = 3; | ||
| 2336 | sids->group.Authority[5] = 5; | ||
| 2337 | sids->group.SubAuthorities[0] = cpu_to_le32(88); | ||
| 2338 | sids->group.SubAuthorities[1] = cpu_to_le32(2); | ||
| 2339 | sids->group.SubAuthorities[2] = cpu_to_le32(current_fsgid().val); | ||
| 2340 | |||
| 2341 | cifs_dbg(FYI, "owner S-1-5-88-1-%d, group S-1-5-88-2-%d\n", current_fsuid().val, current_fsgid().val); | ||
| 2342 | } | ||
| 2343 | |||
| 2320 | /* See MS-SMB2 2.2.13.2.2 and MS-DTYP 2.4.6 */ | 2344 | /* See MS-SMB2 2.2.13.2.2 and MS-DTYP 2.4.6 */ |
| 2321 | static struct crt_sd_ctxt * | 2345 | static struct crt_sd_ctxt * |
| 2322 | create_sd_buf(umode_t mode, unsigned int *len) | 2346 | create_sd_buf(umode_t mode, bool set_owner, unsigned int *len) |
| 2323 | { | 2347 | { |
| 2324 | struct crt_sd_ctxt *buf; | 2348 | struct crt_sd_ctxt *buf; |
| 2325 | struct cifs_ace *pace; | 2349 | struct cifs_ace *pace; |
| 2326 | unsigned int sdlen, acelen; | 2350 | unsigned int sdlen, acelen; |
| 2351 | unsigned int owner_offset = 0; | ||
| 2352 | unsigned int group_offset = 0; | ||
| 2353 | |||
| 2354 | *len = roundup(sizeof(struct crt_sd_ctxt) + (sizeof(struct cifs_ace) * 2), 8); | ||
| 2355 | |||
| 2356 | if (set_owner) { | ||
| 2357 | /* offset fields are from beginning of security descriptor not of create context */ | ||
| 2358 | owner_offset = sizeof(struct smb3_acl) + (sizeof(struct cifs_ace) * 2); | ||
| 2359 | |||
| 2360 | /* sizeof(struct owner_group_sids) is already multiple of 8 so no need to round */ | ||
| 2361 | *len += sizeof(struct owner_group_sids); | ||
| 2362 | } | ||
| 2327 | 2363 | ||
| 2328 | *len = roundup(sizeof(struct crt_sd_ctxt) + sizeof(struct cifs_ace) * 2, | ||
| 2329 | 8); | ||
| 2330 | buf = kzalloc(*len, GFP_KERNEL); | 2364 | buf = kzalloc(*len, GFP_KERNEL); |
| 2331 | if (buf == NULL) | 2365 | if (buf == NULL) |
| 2332 | return buf; | 2366 | return buf; |
| 2333 | 2367 | ||
| 2368 | if (set_owner) { | ||
| 2369 | buf->sd.OffsetOwner = cpu_to_le32(owner_offset); | ||
| 2370 | group_offset = owner_offset + sizeof(struct owner_sid); | ||
| 2371 | buf->sd.OffsetGroup = cpu_to_le32(group_offset); | ||
| 2372 | } else { | ||
| 2373 | buf->sd.OffsetOwner = 0; | ||
| 2374 | buf->sd.OffsetGroup = 0; | ||
| 2375 | } | ||
| 2376 | |||
| 2334 | sdlen = sizeof(struct smb3_sd) + sizeof(struct smb3_acl) + | 2377 | sdlen = sizeof(struct smb3_sd) + sizeof(struct smb3_acl) + |
| 2335 | 2 * sizeof(struct cifs_ace); | 2378 | 2 * sizeof(struct cifs_ace); |
| 2379 | if (set_owner) { | ||
| 2380 | sdlen += sizeof(struct owner_group_sids); | ||
| 2381 | setup_owner_group_sids(owner_offset + sizeof(struct create_context) + 8 /* name */ | ||
| 2382 | + (char *)buf); | ||
| 2383 | } | ||
| 2336 | 2384 | ||
| 2337 | buf->ccontext.DataOffset = cpu_to_le16(offsetof | 2385 | buf->ccontext.DataOffset = cpu_to_le16(offsetof |
| 2338 | (struct crt_sd_ctxt, sd)); | 2386 | (struct crt_sd_ctxt, sd)); |
| 2339 | buf->ccontext.DataLength = cpu_to_le32(sdlen); | 2387 | buf->ccontext.DataLength = cpu_to_le32(sdlen); |
| 2340 | buf->ccontext.NameOffset = cpu_to_le16(offsetof | 2388 | buf->ccontext.NameOffset = cpu_to_le16(offsetof(struct crt_sd_ctxt, Name)); |
| 2341 | (struct crt_sd_ctxt, Name)); | ||
| 2342 | buf->ccontext.NameLength = cpu_to_le16(4); | 2389 | buf->ccontext.NameLength = cpu_to_le16(4); |
| 2343 | /* SMB2_CREATE_SD_BUFFER_TOKEN is "SecD" */ | 2390 | /* SMB2_CREATE_SD_BUFFER_TOKEN is "SecD" */ |
| 2344 | buf->Name[0] = 'S'; | 2391 | buf->Name[0] = 'S'; |
| @@ -2359,23 +2406,34 @@ create_sd_buf(umode_t mode, unsigned int *len) · 14 unmodified lines | |||
| 2359 | /* create one ACE to hold the mode embedded in reserved special SID */ | 2406 | /* create one ACE to hold the mode embedded in reserved special SID */ |
| 2360 | pace = (struct cifs_ace *)(sizeof(struct crt_sd_ctxt) + (char *)buf); | 2407 | pace = (struct cifs_ace *)(sizeof(struct crt_sd_ctxt) + (char *)buf); |
| 2361 | acelen = setup_special_mode_ACE(pace, (__u64)mode); | 2408 | acelen = setup_special_mode_ACE(pace, (__u64)mode); |
| 2409 | |||
| 2410 | if (set_owner) { | ||
| 2411 | /* we do not need to reallocate buffer to add the two more ACEs. plenty of space */ | ||
| 2412 | pace = (struct cifs_ace *)(acelen + (sizeof(struct crt_sd_ctxt) + (char *)buf)); | ||
| 2413 | acelen += setup_special_user_owner_ACE(pace); | ||
| 2414 | /* it does not appear necessary to add an ACE for the NFS group SID */ | ||
| 2415 | buf->acl.AceCount = cpu_to_le16(3); | ||
| 2416 | } else | ||
| 2417 | buf->acl.AceCount = cpu_to_le16(2); | ||
| 2418 | |||
| 2362 | /* and one more ACE to allow access for authenticated users */ | 2419 | /* and one more ACE to allow access for authenticated users */ |
| 2363 | pace = (struct cifs_ace *)(acelen + (sizeof(struct crt_sd_ctxt) + | 2420 | pace = (struct cifs_ace *)(acelen + (sizeof(struct crt_sd_ctxt) + |
| 2364 | (char *)buf)); | 2421 | (char *)buf)); |
| 2365 | acelen += setup_authusers_ACE(pace); | 2422 | acelen += setup_authusers_ACE(pace); |
| 2423 | |||
| 2366 | buf->acl.AclSize = cpu_to_le16(sizeof(struct cifs_acl) + acelen); | 2424 | buf->acl.AclSize = cpu_to_le16(sizeof(struct cifs_acl) + acelen); |
| 2367 | buf->acl.AceCount = cpu_to_le16(2); | 2425 | |
| 2368 | return buf; | 2426 | return buf; |
| 2369 | } | 2427 | } |
| 2370 | 2428 | ||
| 2371 | static int | 2429 | static int |
| 2372 | add_sd_context(struct kvec *iov, unsigned int *num_iovec, umode_t mode) | 2430 | add_sd_context(struct kvec *iov, unsigned int *num_iovec, umode_t mode, bool set_owner) |
| 2373 | { | 2431 | { |
| 2374 | struct smb2_create_req *req = iov[0].iov_base; | 2432 | struct smb2_create_req *req = iov[0].iov_base; |
| 2375 | unsigned int num = *num_iovec; | 2433 | unsigned int num = *num_iovec; |
| 2376 | unsigned int len = 0; | 2434 | unsigned int len = 0; |
| 2377 | 2435 | ||
| 2378 | iov[num].iov_base = create_sd_buf(mode, &len); | 2436 | iov[num].iov_base = create_sd_buf(mode, set_owner, &len); |
| 2379 | if (iov[num].iov_base == NULL) | 2437 | if (iov[num].iov_base == NULL) |
| 2380 | return -ENOMEM; | 2438 | return -ENOMEM; |
| 2381 | iov[num].iov_len = len; | 2439 | iov[num].iov_len = len; |
| @@ -2764,21 +2822,35 @@ SMB2_open_init(struct cifs_tcon *tcon, struct TCP_Server_Info *server, · 382 unmodified lines | |||
| 2764 | return rc; | 2822 | return rc; |
| 2765 | } | 2823 | } |
| 2766 | 2824 | ||
| 2767 | if ((oparms->disposition != FILE_OPEN) && | 2825 | if ((oparms->disposition != FILE_OPEN) && (oparms->cifs_sb)) { |
| 2768 | (oparms->cifs_sb) && | 2826 | bool set_mode; |
| 2769 | (oparms->cifs_sb->mnt_cifs_flags & CIFS_MOUNT_MODE_FROM_SID) && | 2827 | bool set_owner; |
| 2770 | (oparms->mode != ACL_NO_MODE)) { | 2828 | |
| 2771 | if (n_iov > 2) { | 2829 | if ((oparms->cifs_sb->mnt_cifs_flags & CIFS_MOUNT_MODE_FROM_SID) && |
| 2772 | struct create_context *ccontext = | 2830 | (oparms->mode != ACL_NO_MODE)) |
| 2773 | (struct create_context *)iov[n_iov-1].iov_base; | 2831 | set_mode = true; |
| 2774 | ccontext->Next = | 2832 | else { |
| 2775 | cpu_to_le32(iov[n_iov-1].iov_len); | 2833 | set_mode = false; |
| 2834 | oparms->mode = ACL_NO_MODE; | ||
| 2776 | } | 2835 | } |
| 2777 | 2836 | ||
| 2778 | cifs_dbg(FYI, "add sd with mode 0x%x\n", oparms->mode); | 2837 | if (oparms->cifs_sb->mnt_cifs_flags & CIFS_MOUNT_UID_FROM_ACL) |
| 2779 | rc = add_sd_context(iov, &n_iov, oparms->mode); | 2838 | set_owner = true; |
| 2780 | if (rc) | 2839 | else |
| 2781 | return rc; | 2840 | set_owner = false; |
| 2841 | |||
| 2842 | if (set_owner | set_mode) { | ||
| 2843 | if (n_iov > 2) { | ||
| 2844 | struct create_context *ccontext = | ||
| 2845 | (struct create_context *)iov[n_iov-1].iov_base; | ||
| 2846 | ccontext->Next = cpu_to_le32(iov[n_iov-1].iov_len); | ||
| 2847 | } | ||
| 2848 | |||
| 2849 | cifs_dbg(FYI, "add sd with mode 0x%x\n", oparms->mode); | ||
| 2850 | rc = add_sd_context(iov, &n_iov, oparms->mode, set_owner); | ||
| 2851 | if (rc) | ||
| 2852 | return rc; | ||
| 2853 | } | ||
| 2782 | } | 2854 | } |
| 2783 | 2855 | ||
| 2784 | if (n_iov > 2) { | 2856 | if (n_iov > 2) { |
| @@ -2973,7 +3045,9 @@ SMB2_ioctl_init(struct cifs_tcon *tcon, struct TCP_Server_Info *server, · 188 unmodified lines | |||
| 2973 | * response size smaller. | 3045 | * response size smaller. |
| 2974 | */ | 3046 | */ |
| 2975 | req->MaxOutputResponse = cpu_to_le32(max_response_size); | 3047 | req->MaxOutputResponse = cpu_to_le32(max_response_size); |
| 2976 | req->sync_hdr.CreditCharge = cpu_to_le16(DIV_ROUND_UP(max_response_size, SMB2_MAX_BUFFER_SIZE)); | 3048 | req->sync_hdr.CreditCharge = |
| 3049 | cpu_to_le16(DIV_ROUND_UP(max(indatalen, max_response_size), | ||
| 3050 | SMB2_MAX_BUFFER_SIZE)); | ||
| 2977 | if (is_fsctl) | 3051 | if (is_fsctl) |
| 2978 | req->Flags = cpu_to_le32(SMB2_0_IOCTL_IS_FSCTL); | 3052 | req->Flags = cpu_to_le32(SMB2_0_IOCTL_IS_FSCTL); |
| 2979 | else | 3053 | else |
| @@ -3456,6 +3530,19 @@ int SMB2_query_info(const unsigned int xid, struct cifs_tcon *tcon, · 476 unmodified lines | |||
| 3456 | NULL); | 3530 | NULL); |
| 3457 | } | 3531 | } |
| 3458 | 3532 | ||
| 3533 | int | ||
| 3534 | SMB311_posix_query_info(const unsigned int xid, struct cifs_tcon *tcon, | ||
| 3535 | u64 persistent_fid, u64 volatile_fid, struct smb311_posix_qinfo *data, u32 *plen) | ||
| 3536 | { | ||
| 3537 | size_t output_len = sizeof(struct smb311_posix_qinfo *) + | ||
| 3538 | (sizeof(struct cifs_sid) * 2) + (PATH_MAX * 2); | ||
| 3539 | *plen = 0; | ||
| 3540 | |||
| 3541 | return query_info(xid, tcon, persistent_fid, volatile_fid, | ||
| 3542 | SMB_FIND_FILE_POSIX_INFO, SMB2_O_INFO_FILE, 0, | ||
| 3543 | output_len, sizeof(struct smb311_posix_qinfo), (void **)&data, plen); | ||
| 3544 | } | ||
| 3545 | |||
| 3459 | int | 3546 | int |
| 3460 | SMB2_query_acl(const unsigned int xid, struct cifs_tcon *tcon, | 3547 | SMB2_query_acl(const unsigned int xid, struct cifs_tcon *tcon, |
| 3461 | u64 persistent_fid, u64 volatile_fid, | 3548 | u64 persistent_fid, u64 volatile_fid, |
| @@ -1653,7 +1653,7 @@ struct create_posix_rsp { · 1652 unmodified lines | |||
| 1653 | } __packed; | 1653 | } __packed; |
| 1654 | 1654 | ||
| 1655 | /* | 1655 | /* |
| 1656 | * SMB2-only POSIX info level | 1656 | * SMB2-only POSIX info level for query dir |
| 1657 | * | 1657 | * |
| 1658 | * See posix_info_sid_size(), posix_info_extra_size() and | 1658 | * See posix_info_sid_size(), posix_info_extra_size() and |
| 1659 | * posix_info_parse() to help with the handling of this struct. | 1659 | * posix_info_parse() to help with the handling of this struct. |
| @@ -1683,6 +1683,31 @@ struct smb2_posix_info { · 23 unmodified lines | |||
| 1683 | */ | 1683 | */ |
| 1684 | } __packed; | 1684 | } __packed; |
| 1685 | 1685 | ||
| 1686 | /* Level 100 query info */ | ||
| 1687 | struct smb311_posix_qinfo { | ||
| 1688 | __le64 CreationTime; | ||
| 1689 | __le64 LastAccessTime; | ||
| 1690 | __le64 LastWriteTime; | ||
| 1691 | __le64 ChangeTime; | ||
| 1692 | __le64 EndOfFile; | ||
| 1693 | __le64 AllocationSize; | ||
| 1694 | __le32 DosAttributes; | ||
| 1695 | __le64 Inode; | ||
| 1696 | __le32 DeviceId; | ||
| 1697 | __le32 Zero; | ||
| 1698 | /* beginning of POSIX Create Context Response */ | ||
| 1699 | __le32 HardLinks; | ||
| 1700 | __le32 ReparseTag; | ||
| 1701 | __le32 Mode; | ||
| 1702 | u8 Sids[]; | ||
| 1703 | /* | ||
| 1704 | * var sized owner SID | ||
| 1705 | * var sized group SID | ||
| 1706 | * le32 filenamelength | ||
| 1707 | * u8 filename[] | ||
| 1708 | */ | ||
| 1709 | } __packed; | ||
| 1710 | |||
| 1686 | /* | 1711 | /* |
| 1687 | * Parsed version of the above struct. Allows direct access to the | 1712 | * Parsed version of the above struct. Allows direct access to the |
| 1688 | * variable length fields | 1713 | * variable length fields |
| @@ -182,6 +182,8 @@ extern int SMB2_flush_init(const unsigned int xid, struct smb_rqst *rqst, · 181 unmodified lines | |||
| 182 | struct TCP_Server_Info *server, | 182 | struct TCP_Server_Info *server, |
| 183 | u64 persistent_file_id, u64 volatile_file_id); | 183 | u64 persistent_file_id, u64 volatile_file_id); |
| 184 | extern void SMB2_flush_free(struct smb_rqst *rqst); | 184 | extern void SMB2_flush_free(struct smb_rqst *rqst); |
| 185 | extern int SMB311_posix_query_info(const unsigned int xid, struct cifs_tcon *tcon, | ||
| 186 | u64 persistent_fid, u64 volatile_fid, struct smb311_posix_qinfo *data, u32 *plen); | ||
| 185 | extern int SMB2_query_info(const unsigned int xid, struct cifs_tcon *tcon, | 187 | extern int SMB2_query_info(const unsigned int xid, struct cifs_tcon *tcon, |
| 186 | u64 persistent_file_id, u64 volatile_file_id, | 188 | u64 persistent_file_id, u64 volatile_file_id, |
| 187 | struct smb2_file_all_info *data); | 189 | struct smb2_file_all_info *data); |
| @@ -289,6 +291,10 @@ extern int smb2_query_info_compound(const unsigned int xid, · 101 unmodified lines | |||
| 289 | u32 class, u32 type, u32 output_len, | 291 | u32 class, u32 type, u32 output_len, |
| 290 | struct kvec *rsp, int *buftype, | 292 | struct kvec *rsp, int *buftype, |
| 291 | struct cifs_sb_info *cifs_sb); | 293 | struct cifs_sb_info *cifs_sb); |
| 294 | /* query path info from the server using SMB311 POSIX extensions*/ | ||
| 295 | extern int smb311_posix_query_path_info(const unsigned int xid, struct cifs_tcon *tcon, | ||
| 296 | struct cifs_sb_info *sb, const char *path, struct smb311_posix_qinfo *qinf, | ||
| 297 | bool *adjust_tx, bool *symlink); | ||
| 292 | int posix_info_parse(const void *beg, const void *end, | 298 | int posix_info_parse(const void *beg, const void *end, |
| 293 | struct smb2_posix_info_parsed *out); | 299 | struct smb2_posix_info_parsed *out); |
| 294 | int posix_info_sid_size(const void *beg, const void *end); | 300 | int posix_info_sid_size(const void *beg, const void *end); |
| @@ -318,6 +318,7 @@ DEFINE_EVENT(smb3_inf_compound_enter_class, smb3_##name, \ · 317 unmodified lines | |||
| 318 | TP_ARGS(xid, tid, sesid, full_path)) | 318 | TP_ARGS(xid, tid, sesid, full_path)) |
| 319 | 319 | ||
| 320 | DEFINE_SMB3_INF_COMPOUND_ENTER_EVENT(query_info_compound_enter); | 320 | DEFINE_SMB3_INF_COMPOUND_ENTER_EVENT(query_info_compound_enter); |
| 321 | DEFINE_SMB3_INF_COMPOUND_ENTER_EVENT(posix_query_info_compound_enter); | ||
| 321 | DEFINE_SMB3_INF_COMPOUND_ENTER_EVENT(hardlink_enter); | 322 | DEFINE_SMB3_INF_COMPOUND_ENTER_EVENT(hardlink_enter); |
| 322 | DEFINE_SMB3_INF_COMPOUND_ENTER_EVENT(rename_enter); | 323 | DEFINE_SMB3_INF_COMPOUND_ENTER_EVENT(rename_enter); |
| 323 | DEFINE_SMB3_INF_COMPOUND_ENTER_EVENT(rmdir_enter); | 324 | DEFINE_SMB3_INF_COMPOUND_ENTER_EVENT(rmdir_enter); |
| @@ -354,6 +355,7 @@ DEFINE_EVENT(smb3_inf_compound_done_class, smb3_##name, \ · 30 unmodified lines | |||
| 354 | TP_ARGS(xid, tid, sesid)) | 355 | TP_ARGS(xid, tid, sesid)) |
| 355 | 356 | ||
| 356 | DEFINE_SMB3_INF_COMPOUND_DONE_EVENT(query_info_compound_done); | 357 | DEFINE_SMB3_INF_COMPOUND_DONE_EVENT(query_info_compound_done); |
| 358 | DEFINE_SMB3_INF_COMPOUND_DONE_EVENT(posix_query_info_compound_done); | ||
| 357 | DEFINE_SMB3_INF_COMPOUND_DONE_EVENT(hardlink_done); | 359 | DEFINE_SMB3_INF_COMPOUND_DONE_EVENT(hardlink_done); |
| 358 | DEFINE_SMB3_INF_COMPOUND_DONE_EVENT(rename_done); | 360 | DEFINE_SMB3_INF_COMPOUND_DONE_EVENT(rename_done); |
| 359 | DEFINE_SMB3_INF_COMPOUND_DONE_EVENT(rmdir_done); | 361 | DEFINE_SMB3_INF_COMPOUND_DONE_EVENT(rmdir_done); |
| @@ -395,6 +397,7 @@ DEFINE_EVENT(smb3_inf_compound_err_class, smb3_##name, \ · 35 unmodified lines | |||
| 395 | TP_ARGS(xid, tid, sesid, rc)) | 397 | TP_ARGS(xid, tid, sesid, rc)) |
| 396 | 398 | ||
| 397 | DEFINE_SMB3_INF_COMPOUND_ERR_EVENT(query_info_compound_err); | 399 | DEFINE_SMB3_INF_COMPOUND_ERR_EVENT(query_info_compound_err); |
| 400 | DEFINE_SMB3_INF_COMPOUND_ERR_EVENT(posix_query_info_compound_err); | ||
| 398 | DEFINE_SMB3_INF_COMPOUND_ERR_EVENT(hardlink_err); | 401 | DEFINE_SMB3_INF_COMPOUND_ERR_EVENT(hardlink_err); |
| 399 | DEFINE_SMB3_INF_COMPOUND_ERR_EVENT(rename_err); | 402 | DEFINE_SMB3_INF_COMPOUND_ERR_EVENT(rename_err); |
| 400 | DEFINE_SMB3_INF_COMPOUND_ERR_EVENT(rmdir_err); | 403 | DEFINE_SMB3_INF_COMPOUND_ERR_EVENT(rmdir_err); |