History

Merge tag '5.8-rc-smb3-fixes-part2' of git://git.samba.org/sfrench/cifs-2.6

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

Linus Torvalds committed 6 years ago

Commit f82e7b52 parents 4f9b3a3 a7a519a19 files · +571 −57Browse files

Unified · Split

19 files
  1. fs/cifs/cache.c +2 −7
  2. fs/cifs/cifs_debug.c +1 −3
  3. fs/cifs/cifsacl.c +64 −15
  4. fs/cifs/cifsacl.h +15 −0
  5. fs/cifs/cifsfs.c +1 −1
  6. fs/cifs/cifsglob.h +18 −0
  7. fs/cifs/cifsproto.h +3 −0
  8. fs/cifs/dir.c +4 −1
  9. fs/cifs/file.c +4 −1
  10. fs/cifs/fscache.c +15 −2
  11. fs/cifs/fscache.h +9 −0
  12. fs/cifs/inode.c +182 −3
  13. fs/cifs/link.c +3 −1
  14. fs/cifs/smb2glob.h +1 −0
  15. fs/cifs/smb2inode.c +105 −0
  16. fs/cifs/smb2pdu.c +109 −22
  17. fs/cifs/smb2pdu.h +26 −1
  18. fs/cifs/smb2proto.h +6 −0
  19. fs/cifs/trace.h +3 −0
fs/cifs/cache.c+2−7
@@ -53,13 +53,6 @@ const struct fscache_cookie_def cifs_fscache_server_index_def = { · 52 unmodified lines
5353 .type = FSCACHE_COOKIE_TYPE_INDEX,
5454 };
5555
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−
6356 char *extract_sharename(const char *treename)
6457 {
6558 const char *src;
@@ -98,6 +91,8 @@ fscache_checkaux cifs_fscache_super_check_aux(void *cookie_netfs_data, · 32 unmodified lines
9891
9992 memset(&auxdata, 0, sizeof(auxdata));
10093 auxdata.resource_id = tcon->resource_id;
94+ auxdata.vol_create_time = tcon->vol_create_time;
95+ auxdata.vol_serial_number = tcon->vol_serial_number;
10196
10297 if (memcmp(data, &auxdata, datalen) != 0)
10398 return FSCACHE_CHECKAUX_OBSOLETE;
fs/cifs/cifs_debug.c+1−3
@@ -221,8 +221,6 @@ static int cifs_debug_data_proc_show(struct seq_file *m, void *v) · 220 unmodified lines
221221 struct cifs_ses *ses;
222222 struct cifs_tcon *tcon;
223223 int i, j;
224− const char *security_types[] = {"Unspecified", "LANMAN", "NTLM",
225− "NTLMv2", "RawNTLMSSP", "Kerberos"};
226224
227225 seq_puts(m,
228226 "Display Internal CIFS Data Structures for Debugging\n"
@@ -379,7 +377,7 @@ skip_rdma: · 150 unmodified lines
379377 }
380378
381379 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)));
383381
384382 if (server->rdma)
385383 seq_printf(m, "RDMA\n\t");
fs/cifs/cifsacl.c+64−15
@@ -849,6 +849,28 @@ unsigned int setup_special_mode_ACE(struct cifs_ace *pntace, __u64 nmode) · 848 unmodified lines
849849 return ace_size;
850850 }
851851
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+
852874 static int set_chmod_dacl(struct cifs_acl *pndacl, struct cifs_sid *pownersid,
853875 struct cifs_sid *pgrpsid, __u64 nmode, bool modefromsid)
854876 {
@@ -978,7 +1000,7 @@ static int parse_sec_desc(struct cifs_sb_info *cifs_sb, · 123 unmodified lines
9781000 /* Convert permission bits from mode to equivalent CIFS ACL */
9791001 static int build_sec_desc(struct cifs_ntsd *pntsd, struct cifs_ntsd *pnntsd,
9801002 __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)
9821004 {
9831005 int rc = 0;
9841006 __u32 dacloffset;
@@ -1019,12 +1041,23 @@ static int build_sec_desc(struct cifs_ntsd *pntsd, struct cifs_ntsd *pnntsd, · 34 unmodified lines
10191041 if (!nowner_sid_ptr)
10201042 return -ENOMEM;
10211043 id = from_kuid(&init_user_ns, uid);
1022− rc = id_to_sid(id, SIDOWNER, nowner_sid_ptr);
1023− if (rc) {
1024− cifs_dbg(FYI, "%s: Mapping error %d for owner id %d\n",
1025− __func__, rc, id);
1026− kfree(nowner_sid_ptr);
1027− return rc;
1044+ if (id_from_sid) {
1045+ struct owner_sid *osid = (struct owner_sid *)nowner_sid_ptr;
1046+ /* Populate the user ownership fields S-1-5-88-1 */
1047+ osid->Revision = 1;
1048+ osid->NumAuth = 3;
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+ }
10281061 }
10291062 cifs_copy_sid(owner_sid_ptr, nowner_sid_ptr);
10301063 kfree(nowner_sid_ptr);
@@ -1039,12 +1072,23 @@ static int build_sec_desc(struct cifs_ntsd *pntsd, struct cifs_ntsd *pnntsd, · 8 unmodified lines
10391072 if (!ngroup_sid_ptr)
10401073 return -ENOMEM;
10411074 id = from_kgid(&init_user_ns, gid);
1042− rc = id_to_sid(id, SIDGROUP, ngroup_sid_ptr);
1043− if (rc) {
1044− cifs_dbg(FYI, "%s: Mapping error %d for group id %d\n",
1045− __func__, rc, id);
1046− kfree(ngroup_sid_ptr);
1047− return rc;
1075+ if (id_from_sid) {
1076+ struct owner_sid *gsid = (struct owner_sid *)ngroup_sid_ptr;
1077+ /* Populate the group ownership fields S-1-5-88-2 */
1078+ gsid->Revision = 1;
1079+ gsid->NumAuth = 3;
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+ }
10481092 }
10491093 cifs_copy_sid(group_sid_ptr, ngroup_sid_ptr);
10501094 kfree(ngroup_sid_ptr);
@@ -1247,7 +1291,7 @@ id_mode_to_cifs_acl(struct inode *inode, const char *path, __u64 nmode, · 196 unmodified lines
12471291 struct cifs_sb_info *cifs_sb = CIFS_SB(inode->i_sb);
12481292 struct tcon_link *tlink = cifs_sb_tlink(cifs_sb);
12491293 struct smb_version_operations *ops;
1250− bool mode_from_sid;
1294+ bool mode_from_sid, id_from_sid;
12511295
12521296 if (IS_ERR(tlink))
12531297 return PTR_ERR(tlink);
@@ -1290,8 +1334,13 @@ id_mode_to_cifs_acl(struct inode *inode, const char *path, __u64 nmode, · 36 unmodified lines
12901334 else
12911335 mode_from_sid = false;
12921336
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+
12931342 rc = build_sec_desc(pntsd, pnntsd, secdesclen, nmode, uid, gid,
1294− mode_from_sid, &aclflag);
1343+ mode_from_sid, id_from_sid, &aclflag);
12951344
12961345 cifs_dbg(NOISY, "build_sec_desc rc: %d\n", rc);
12971346
fs/cifs/cifsacl.h+15−0
@@ -176,6 +176,21 @@ struct smb3_acl { · 175 unmodified lines
176176 __le16 Sbz2; /* MBZ */
177177 } __packed;
178178
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;
179194
180195 /*
181196 * Minimum security identifier can be one for system defined Users
fs/cifs/cifsfs.c+1−1
@@ -623,7 +623,7 @@ cifs_show_options(struct seq_file *s, struct dentry *root) · 622 unmodified lines
623623 seq_printf(s, ",actimeo=%lu", cifs_sb->actimeo / HZ);
624624
625625 if (tcon->ses->chan_max > 1)
626− seq_printf(s, ",multichannel,max_channel=%zu",
626+ seq_printf(s, ",multichannel,max_channels=%zu",
627627 tcon->ses->chan_max);
628628
629629 return 0;
fs/cifs/cifsglob.h+18−0
@@ -2008,6 +2008,24 @@ extern struct smb_version_values smb302_values; · 2007 unmodified lines
20082008 extern struct smb_version_operations smb311_operations;
20092009 extern struct smb_version_values smb311_values;
20102010
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+
20112029 static inline bool is_smb1_server(struct TCP_Server_Info *server)
20122030 {
20132031 return strcmp(server->vals->version_string, SMB1_VERSION_STRING) == 0;
fs/cifs/cifsproto.h+3−0
@@ -198,6 +198,8 @@ extern struct inode *cifs_iget(struct super_block *sb, · 197 unmodified lines
198198 extern int cifs_get_inode_info(struct inode **inode, const char *full_path,
199199 FILE_ALL_INFO *data, struct super_block *sb,
200200 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);
201203 extern int cifs_get_inode_info_unix(struct inode **pinode,
202204 const unsigned char *search_path,
203205 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
220222 const char *, int);
221223 extern unsigned int setup_authusers_ACE(struct cifs_ace *pace);
222224 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);
223226
224227 extern void dequeue_mid(struct mid_q_entry *mid, bool malformed);
225228 extern int cifs_read_from_socket(struct TCP_Server_Info *server, char *buf,
fs/cifs/dir.c+4−1
@@ -411,6 +411,7 @@ cifs_create_get_file_info: · 410 unmodified lines
411411 rc = cifs_get_inode_info_unix(&newinode, full_path, inode->i_sb,
412412 xid);
413413 else {
414+ /* TODO: Add support for calling POSIX query info here, but passing in fid */
414415 rc = cifs_get_inode_info(&newinode, full_path, buf, inode->i_sb,
415416 xid, fid);
416417 if (newinode) {
@@ -700,7 +701,9 @@ cifs_lookup(struct inode *parent_dir_inode, struct dentry *direntry, · 283 unmodified lines
700701 cifs_dbg(FYI, "Full path: %s inode = 0x%p\n",
701702 full_path, d_inode(direntry));
702703
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) {
704707 rc = cifs_get_inode_info_unix(&newInode, full_path,
705708 parent_dir_inode->i_sb, xid);
706709 } else {
fs/cifs/file.c+4−1
@@ -243,6 +243,7 @@ cifs_nt_open(char *full_path, struct inode *inode, struct cifs_sb_info *cifs_sb, · 242 unmodified lines
243243 if (rc)
244244 goto out;
245245
246+ /* TODO: Add support for calling posix query info but with passing in fid */
246247 if (tcon->unix_ext)
247248 rc = cifs_get_inode_info_unix(&inode, full_path, inode->i_sb,
248249 xid);
@@ -800,7 +801,9 @@ reopen_success: · 551 unmodified lines
800801 if (!is_interrupt_error(rc))
801802 mapping_set_error(inode->i_mapping, rc);
802803
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)
804807 rc = cifs_get_inode_info_unix(&inode, full_path,
805808 inode->i_sb, xid);
806809 else
fs/cifs/fscache.c+15−2
@@ -96,6 +96,7 @@ void cifs_fscache_get_super_cookie(struct cifs_tcon *tcon) · 95 unmodified lines
9696 {
9797 struct TCP_Server_Info *server = tcon->ses->server;
9898 char *sharename;
99+ struct cifs_fscache_super_auxdata auxdata;
99100
100101 sharename = extract_sharename(tcon->treeName);
101102 if (IS_ERR(sharename)) {
@@ -104,11 +105,16 @@ void cifs_fscache_get_super_cookie(struct cifs_tcon *tcon) · 2 unmodified lines
104105 return;
105106 }
106107
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+
107113 tcon->fscache =
108114 fscache_acquire_cookie(server->fscache,
109115 &cifs_fscache_super_index_def,
110116 sharename, strlen(sharename),
111− &tcon->resource_id, sizeof(tcon->resource_id),
117+ &auxdata, sizeof(auxdata),
112118 tcon, 0, true);
113119 kfree(sharename);
114120 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
117123
118124 void cifs_fscache_release_super_cookie(struct cifs_tcon *tcon)
119125 {
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+
120133 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);
122135 tcon->fscache = NULL;
123136 }
124137
fs/cifs/fscache.h+9−0
@@ -27,6 +27,15 @@ · 26 unmodified lines
2727
2828 #ifdef CONFIG_CIFS_FSCACHE
2929
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+
3039 /*
3140 * Auxiliary data attached to CIFS inode within the cache
3241 */
fs/cifs/inode.c+182−3
@@ -32,6 +32,7 @@ · 31 unmodified lines
3232 #include "cifspdu.h"
3333 #include "cifsglob.h"
3434 #include "cifsproto.h"
35+#include "smb2proto.h"
3536 #include "cifs_debug.h"
3637 #include "cifs_fs_sb.h"
3738 #include "cifs_unicode.h"
@@ -595,6 +596,62 @@ static int cifs_sfu_mode(struct cifs_fattr *fattr, const unsigned char *path, · 557 unmodified lines
595596 #endif
596597 }
597598
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+
598655 /* Fill a cifs_fattr struct with info from FILE_ALL_INFO */
599656 static void
600657 cifs_all_info_to_fattr(struct cifs_fattr *fattr, FILE_ALL_INFO *info,
@@ -1023,6 +1080,121 @@ out: · 422 unmodified lines
10231080 return rc;
10241081 }
10251082
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+
10261198 static const struct inode_operations cifs_ipc_inode_ops = {
10271199 .lookup = cifs_lookup,
10281200 };
@@ -1161,7 +1333,10 @@ struct inode *cifs_root_iget(struct super_block *sb) · 132 unmodified lines
11611333 }
11621334
11631335 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);
11651340
11661341 iget_no_retry:
11671342 if (!inode) {
@@ -1517,7 +1692,9 @@ cifs_mkdir_qinfo(struct inode *parent, struct dentry *dentry, umode_t mode, · 349 unmodified lines
15171692 int rc = 0;
15181693 struct inode *inode = NULL;
15191694
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)
15211698 rc = cifs_get_inode_info_unix(&inode, full_path, parent->i_sb,
15221699 xid);
15231700 else
@@ -2114,7 +2291,9 @@ int cifs_revalidate_dentry_attr(struct dentry *dentry) · 590 unmodified lines
21142291 dentry, cifs_get_time(dentry), jiffies);
21152292
21162293 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)
21182297 rc = cifs_get_inode_info_unix(&inode, full_path, sb, xid);
21192298 else
21202299 rc = cifs_get_inode_info(&inode, full_path, NULL, sb,
fs/cifs/link.c+3−1
@@ -701,7 +701,9 @@ cifs_symlink(struct inode *inode, struct dentry *direntry, const char *symname) · 700 unmodified lines
701701 cifs_sb_target->local_nls); */
702702
703703 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)
705707 rc = cifs_get_inode_info_unix(&newinode, full_path,
706708 inode->i_sb, xid);
707709 else
fs/cifs/smb2glob.h+1−0
@@ -45,6 +45,7 @@ · 44 unmodified lines
4545 #define SMB2_OP_HARDLINK 8
4646 #define SMB2_OP_SET_EOF 9
4747 #define SMB2_OP_RMDIR 10
48+#define SMB2_OP_POSIX_QUERY_INFO 11
4849
4950 /* Used when constructing chained read requests. */
5051 #define CHAINED_REQUEST 1
fs/cifs/smb2inode.c+105−0
@@ -166,6 +166,40 @@ smb2_compound_op(const unsigned int xid, struct cifs_tcon *tcon, · 165 unmodified lines
166166 trace_smb3_query_info_compound_enter(xid, ses->Suid, tcon->tid,
167167 full_path);
168168 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;
169203 case SMB2_OP_DELETE:
170204 trace_smb3_delete_enter(xid, ses->Suid, tcon->tid, full_path);
171205 break;
@@ -379,6 +413,24 @@ smb2_compound_op(const unsigned int xid, struct cifs_tcon *tcon, · 207 unmodified lines
379413 trace_smb3_query_info_compound_done(xid, ses->Suid,
380414 tcon->tid);
381415 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;
382434 case SMB2_OP_DELETE:
383435 if (rc)
384436 trace_smb3_delete_err(xid, ses->Suid, tcon->tid, rc);
@@ -512,6 +564,59 @@ out: · 127 unmodified lines
512564 return rc;
513565 }
514566
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+
515620 int
516621 smb2_mkdir(const unsigned int xid, struct inode *parent_inode, umode_t mode,
517622 struct cifs_tcon *tcon, const char *name,
fs/cifs/smb2pdu.c+109−22
@@ -2317,28 +2317,75 @@ add_twarp_context(struct kvec *iov, unsigned int *num_iovec, __u64 timewarp) · 2316 unmodified lines
23172317 return 0;
23182318 }
23192319
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+
23202344 /* See MS-SMB2 2.2.13.2.2 and MS-DTYP 2.4.6 */
23212345 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)
23232347 {
23242348 struct crt_sd_ctxt *buf;
23252349 struct cifs_ace *pace;
23262350 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+ }
23272363
2328− *len = roundup(sizeof(struct crt_sd_ctxt) + sizeof(struct cifs_ace) * 2,
2329− 8);
23302364 buf = kzalloc(*len, GFP_KERNEL);
23312365 if (buf == NULL)
23322366 return buf;
23332367
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+
23342377 sdlen = sizeof(struct smb3_sd) + sizeof(struct smb3_acl) +
23352378 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+ }
23362384
23372385 buf->ccontext.DataOffset = cpu_to_le16(offsetof
23382386 (struct crt_sd_ctxt, sd));
23392387 buf->ccontext.DataLength = cpu_to_le32(sdlen);
2340− buf->ccontext.NameOffset = cpu_to_le16(offsetof
2341− (struct crt_sd_ctxt, Name));
2388+ buf->ccontext.NameOffset = cpu_to_le16(offsetof(struct crt_sd_ctxt, Name));
23422389 buf->ccontext.NameLength = cpu_to_le16(4);
23432390 /* SMB2_CREATE_SD_BUFFER_TOKEN is "SecD" */
23442391 buf->Name[0] = 'S';
@@ -2359,23 +2406,34 @@ create_sd_buf(umode_t mode, unsigned int *len) · 14 unmodified lines
23592406 /* create one ACE to hold the mode embedded in reserved special SID */
23602407 pace = (struct cifs_ace *)(sizeof(struct crt_sd_ctxt) + (char *)buf);
23612408 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+
23622419 /* and one more ACE to allow access for authenticated users */
23632420 pace = (struct cifs_ace *)(acelen + (sizeof(struct crt_sd_ctxt) +
23642421 (char *)buf));
23652422 acelen += setup_authusers_ACE(pace);
2423+
23662424 buf->acl.AclSize = cpu_to_le16(sizeof(struct cifs_acl) + acelen);
2367− buf->acl.AceCount = cpu_to_le16(2);
2425+
23682426 return buf;
23692427 }
23702428
23712429 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)
23732431 {
23742432 struct smb2_create_req *req = iov[0].iov_base;
23752433 unsigned int num = *num_iovec;
23762434 unsigned int len = 0;
23772435
2378− iov[num].iov_base = create_sd_buf(mode, &len);
2436+ iov[num].iov_base = create_sd_buf(mode, set_owner, &len);
23792437 if (iov[num].iov_base == NULL)
23802438 return -ENOMEM;
23812439 iov[num].iov_len = len;
@@ -2764,21 +2822,35 @@ SMB2_open_init(struct cifs_tcon *tcon, struct TCP_Server_Info *server, · 382 unmodified lines
27642822 return rc;
27652823 }
27662824
2767− if ((oparms->disposition != FILE_OPEN) &&
2768− (oparms->cifs_sb) &&
2769− (oparms->cifs_sb->mnt_cifs_flags & CIFS_MOUNT_MODE_FROM_SID) &&
2770− (oparms->mode != ACL_NO_MODE)) {
2771− if (n_iov > 2) {
2772− struct create_context *ccontext =
2773− (struct create_context *)iov[n_iov-1].iov_base;
2774− ccontext->Next =
2775− cpu_to_le32(iov[n_iov-1].iov_len);
2825+ if ((oparms->disposition != FILE_OPEN) && (oparms->cifs_sb)) {
2826+ bool set_mode;
2827+ bool set_owner;
2828+
2829+ if ((oparms->cifs_sb->mnt_cifs_flags & CIFS_MOUNT_MODE_FROM_SID) &&
2830+ (oparms->mode != ACL_NO_MODE))
2831+ set_mode = true;
2832+ else {
2833+ set_mode = false;
2834+ oparms->mode = ACL_NO_MODE;
27762835 }
27772836
2778− cifs_dbg(FYI, "add sd with mode 0x%x\n", oparms->mode);
2779− rc = add_sd_context(iov, &n_iov, oparms->mode);
2780− if (rc)
2781− return rc;
2837+ if (oparms->cifs_sb->mnt_cifs_flags & CIFS_MOUNT_UID_FROM_ACL)
2838+ set_owner = true;
2839+ else
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+ }
27822854 }
27832855
27842856 if (n_iov > 2) {
@@ -2973,7 +3045,9 @@ SMB2_ioctl_init(struct cifs_tcon *tcon, struct TCP_Server_Info *server, · 188 unmodified lines
29733045 * response size smaller.
29743046 */
29753047 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));
29773051 if (is_fsctl)
29783052 req->Flags = cpu_to_le32(SMB2_0_IOCTL_IS_FSCTL);
29793053 else
@@ -3456,6 +3530,19 @@ int SMB2_query_info(const unsigned int xid, struct cifs_tcon *tcon, · 476 unmodified lines
34563530 NULL);
34573531 }
34583532
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+
34593546 int
34603547 SMB2_query_acl(const unsigned int xid, struct cifs_tcon *tcon,
34613548 u64 persistent_fid, u64 volatile_fid,
fs/cifs/smb2pdu.h+26−1
@@ -1653,7 +1653,7 @@ struct create_posix_rsp { · 1652 unmodified lines
16531653 } __packed;
16541654
16551655 /*
1656− * SMB2-only POSIX info level
1656+ * SMB2-only POSIX info level for query dir
16571657 *
16581658 * See posix_info_sid_size(), posix_info_extra_size() and
16591659 * posix_info_parse() to help with the handling of this struct.
@@ -1683,6 +1683,31 @@ struct smb2_posix_info { · 23 unmodified lines
16831683 */
16841684 } __packed;
16851685
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+
16861711 /*
16871712 * Parsed version of the above struct. Allows direct access to the
16881713 * variable length fields
fs/cifs/smb2proto.h+6−0
@@ -182,6 +182,8 @@ extern int SMB2_flush_init(const unsigned int xid, struct smb_rqst *rqst, · 181 unmodified lines
182182 struct TCP_Server_Info *server,
183183 u64 persistent_file_id, u64 volatile_file_id);
184184 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);
185187 extern int SMB2_query_info(const unsigned int xid, struct cifs_tcon *tcon,
186188 u64 persistent_file_id, u64 volatile_file_id,
187189 struct smb2_file_all_info *data);
@@ -289,6 +291,10 @@ extern int smb2_query_info_compound(const unsigned int xid, · 101 unmodified lines
289291 u32 class, u32 type, u32 output_len,
290292 struct kvec *rsp, int *buftype,
291293 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);
292298 int posix_info_parse(const void *beg, const void *end,
293299 struct smb2_posix_info_parsed *out);
294300 int posix_info_sid_size(const void *beg, const void *end);
fs/cifs/trace.h+3−0
@@ -318,6 +318,7 @@ DEFINE_EVENT(smb3_inf_compound_enter_class, smb3_##name, \ · 317 unmodified lines
318318 TP_ARGS(xid, tid, sesid, full_path))
319319
320320 DEFINE_SMB3_INF_COMPOUND_ENTER_EVENT(query_info_compound_enter);
321+DEFINE_SMB3_INF_COMPOUND_ENTER_EVENT(posix_query_info_compound_enter);
321322 DEFINE_SMB3_INF_COMPOUND_ENTER_EVENT(hardlink_enter);
322323 DEFINE_SMB3_INF_COMPOUND_ENTER_EVENT(rename_enter);
323324 DEFINE_SMB3_INF_COMPOUND_ENTER_EVENT(rmdir_enter);
@@ -354,6 +355,7 @@ DEFINE_EVENT(smb3_inf_compound_done_class, smb3_##name, \ · 30 unmodified lines
354355 TP_ARGS(xid, tid, sesid))
355356
356357 DEFINE_SMB3_INF_COMPOUND_DONE_EVENT(query_info_compound_done);
358+DEFINE_SMB3_INF_COMPOUND_DONE_EVENT(posix_query_info_compound_done);
357359 DEFINE_SMB3_INF_COMPOUND_DONE_EVENT(hardlink_done);
358360 DEFINE_SMB3_INF_COMPOUND_DONE_EVENT(rename_done);
359361 DEFINE_SMB3_INF_COMPOUND_DONE_EVENT(rmdir_done);
@@ -395,6 +397,7 @@ DEFINE_EVENT(smb3_inf_compound_err_class, smb3_##name, \ · 35 unmodified lines
395397 TP_ARGS(xid, tid, sesid, rc))
396398
397399 DEFINE_SMB3_INF_COMPOUND_ERR_EVENT(query_info_compound_err);
400+DEFINE_SMB3_INF_COMPOUND_ERR_EVENT(posix_query_info_compound_err);
398401 DEFINE_SMB3_INF_COMPOUND_ERR_EVENT(hardlink_err);
399402 DEFINE_SMB3_INF_COMPOUND_ERR_EVENT(rename_err);
400403 DEFINE_SMB3_INF_COMPOUND_ERR_EVENT(rmdir_err);

Keyboard shortcuts

General

Show keyboard shortcuts
?
Focus the current search
/

Issues and pull requests

Open filters
f

Issues, pull requests and Inbox

Select next item
j↓
Select previous item
k↑
Open selected item
Enter
Dismiss filters or clear selection
Esc

Repository code

Go to file
t