Skip to content

Commit 666753c

Browse files
committed
[CIFS] Fix SMB2 mounts so they don't try to set or get xattrs via cifs
When mounting with smb2 (or smb2.1 or smb3) we need to check to make sure that attempts to query or set extended attributes do not attempt to send the request with the older cifs protocol instead (eventually we also need to add the support in SMB2 to query/set extended attributes but this patch prevents us from using the wrong protocol for extended attribute operations). Signed-off-by: Steve French <[email protected]>
1 parent d81b8a4 commit 666753c

File tree

2 files changed

+36
-19
lines changed

2 files changed

+36
-19
lines changed

fs/cifs/cifsglob.h

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -389,6 +389,12 @@ struct smb_version_operations {
389389
struct cifsFileInfo *target_file, u64 src_off, u64 len,
390390
u64 dest_off);
391391
int (*validate_negotiate)(const unsigned int, struct cifs_tcon *);
392+
ssize_t (*query_all_EAs)(const unsigned int, struct cifs_tcon *,
393+
const unsigned char *, const unsigned char *, char *,
394+
size_t, const struct nls_table *, int);
395+
int (*set_EA)(const unsigned int, struct cifs_tcon *, const char *,
396+
const char *, const void *, const __u16,
397+
const struct nls_table *, int);
392398
};
393399

394400
struct smb_version_values {

fs/cifs/xattr.c

Lines changed: 30 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -82,9 +82,11 @@ int cifs_removexattr(struct dentry *direntry, const char *ea_name)
8282
goto remove_ea_exit;
8383

8484
ea_name += XATTR_USER_PREFIX_LEN; /* skip past user. prefix */
85-
rc = CIFSSMBSetEA(xid, pTcon, full_path, ea_name, NULL,
86-
(__u16)0, cifs_sb->local_nls,
87-
cifs_sb->mnt_cifs_flags & CIFS_MOUNT_MAP_SPECIAL_CHR);
85+
if (pTcon->ses->server->ops->set_EA)
86+
rc = pTcon->ses->server->ops->set_EA(xid, pTcon,
87+
full_path, ea_name, NULL, (__u16)0,
88+
cifs_sb->local_nls, cifs_sb->mnt_cifs_flags &
89+
CIFS_MOUNT_MAP_SPECIAL_CHR);
8890
}
8991
remove_ea_exit:
9092
kfree(full_path);
@@ -149,18 +151,22 @@ int cifs_setxattr(struct dentry *direntry, const char *ea_name,
149151
cifs_dbg(FYI, "attempt to set cifs inode metadata\n");
150152

151153
ea_name += XATTR_USER_PREFIX_LEN; /* skip past user. prefix */
152-
rc = CIFSSMBSetEA(xid, pTcon, full_path, ea_name, ea_value,
153-
(__u16)value_size, cifs_sb->local_nls,
154-
cifs_sb->mnt_cifs_flags & CIFS_MOUNT_MAP_SPECIAL_CHR);
154+
if (pTcon->ses->server->ops->set_EA)
155+
rc = pTcon->ses->server->ops->set_EA(xid, pTcon,
156+
full_path, ea_name, ea_value, (__u16)value_size,
157+
cifs_sb->local_nls, cifs_sb->mnt_cifs_flags &
158+
CIFS_MOUNT_MAP_SPECIAL_CHR);
155159
} else if (strncmp(ea_name, XATTR_OS2_PREFIX, XATTR_OS2_PREFIX_LEN)
156160
== 0) {
157161
if (cifs_sb->mnt_cifs_flags & CIFS_MOUNT_NO_XATTR)
158162
goto set_ea_exit;
159163

160164
ea_name += XATTR_OS2_PREFIX_LEN; /* skip past os2. prefix */
161-
rc = CIFSSMBSetEA(xid, pTcon, full_path, ea_name, ea_value,
162-
(__u16)value_size, cifs_sb->local_nls,
163-
cifs_sb->mnt_cifs_flags & CIFS_MOUNT_MAP_SPECIAL_CHR);
165+
if (pTcon->ses->server->ops->set_EA)
166+
rc = pTcon->ses->server->ops->set_EA(xid, pTcon,
167+
full_path, ea_name, ea_value, (__u16)value_size,
168+
cifs_sb->local_nls, cifs_sb->mnt_cifs_flags &
169+
CIFS_MOUNT_MAP_SPECIAL_CHR);
164170
} else if (strncmp(ea_name, CIFS_XATTR_CIFS_ACL,
165171
strlen(CIFS_XATTR_CIFS_ACL)) == 0) {
166172
#ifdef CONFIG_CIFS_ACL
@@ -272,17 +278,21 @@ ssize_t cifs_getxattr(struct dentry *direntry, const char *ea_name,
272278
/* revalidate/getattr then populate from inode */
273279
} /* BB add else when above is implemented */
274280
ea_name += XATTR_USER_PREFIX_LEN; /* skip past user. prefix */
275-
rc = CIFSSMBQAllEAs(xid, pTcon, full_path, ea_name, ea_value,
276-
buf_size, cifs_sb->local_nls,
277-
cifs_sb->mnt_cifs_flags & CIFS_MOUNT_MAP_SPECIAL_CHR);
281+
if (pTcon->ses->server->ops->query_all_EAs)
282+
rc = pTcon->ses->server->ops->query_all_EAs(xid, pTcon,
283+
full_path, ea_name, ea_value, buf_size,
284+
cifs_sb->local_nls, cifs_sb->mnt_cifs_flags &
285+
CIFS_MOUNT_MAP_SPECIAL_CHR);
278286
} else if (strncmp(ea_name, XATTR_OS2_PREFIX, XATTR_OS2_PREFIX_LEN) == 0) {
279287
if (cifs_sb->mnt_cifs_flags & CIFS_MOUNT_NO_XATTR)
280288
goto get_ea_exit;
281289

282290
ea_name += XATTR_OS2_PREFIX_LEN; /* skip past os2. prefix */
283-
rc = CIFSSMBQAllEAs(xid, pTcon, full_path, ea_name, ea_value,
284-
buf_size, cifs_sb->local_nls,
285-
cifs_sb->mnt_cifs_flags & CIFS_MOUNT_MAP_SPECIAL_CHR);
291+
if (pTcon->ses->server->ops->query_all_EAs)
292+
rc = pTcon->ses->server->ops->query_all_EAs(xid, pTcon,
293+
full_path, ea_name, ea_value, buf_size,
294+
cifs_sb->local_nls, cifs_sb->mnt_cifs_flags &
295+
CIFS_MOUNT_MAP_SPECIAL_CHR);
286296
} else if (strncmp(ea_name, POSIX_ACL_XATTR_ACCESS,
287297
strlen(POSIX_ACL_XATTR_ACCESS)) == 0) {
288298
#ifdef CONFIG_CIFS_POSIX
@@ -400,11 +410,12 @@ ssize_t cifs_listxattr(struct dentry *direntry, char *data, size_t buf_size)
400410
/* if proc/fs/cifs/streamstoxattr is set then
401411
search server for EAs or streams to
402412
returns as xattrs */
403-
rc = CIFSSMBQAllEAs(xid, pTcon, full_path, NULL, data,
404-
buf_size, cifs_sb->local_nls,
405-
cifs_sb->mnt_cifs_flags &
406-
CIFS_MOUNT_MAP_SPECIAL_CHR);
407413

414+
if (pTcon->ses->server->ops->query_all_EAs)
415+
rc = pTcon->ses->server->ops->query_all_EAs(xid, pTcon,
416+
full_path, NULL, data, buf_size,
417+
cifs_sb->local_nls, cifs_sb->mnt_cifs_flags &
418+
CIFS_MOUNT_MAP_SPECIAL_CHR);
408419
list_ea_exit:
409420
kfree(full_path);
410421
free_xid(xid);

0 commit comments

Comments
 (0)