forked from luck/tmp_suning_uos_patched
Query file system attributes from server on SMB2, not just cifs, mounts
Currently SMB2 and SMB3 mounts do not query the file system attributes from the server at mount time as is done for cifs. These can be useful for debugging. Signed-off-by: Steve French <smfrench@gmail.com>
This commit is contained in:
parent
64a5cfa6db
commit
34f626406c
@ -2215,6 +2215,9 @@ typedef struct {
|
||||
__le32 DeviceCharacteristics;
|
||||
} __attribute__((packed)) FILE_SYSTEM_DEVICE_INFO; /* device info level 0x104 */
|
||||
|
||||
/* minimum includes first three fields, and empty FS Name */
|
||||
#define MIN_FS_ATTR_INFO_SIZE 12
|
||||
|
||||
typedef struct {
|
||||
__le32 Attributes;
|
||||
__le32 MaxPathNameComponentLength;
|
||||
|
@ -209,6 +209,31 @@ smb2_negotiate_rsize(struct cifs_tcon *tcon, struct smb_vol *volume_info)
|
||||
return rsize;
|
||||
}
|
||||
|
||||
static void
|
||||
smb2_qfs_tcon(const unsigned int xid, struct cifs_tcon *tcon)
|
||||
{
|
||||
int rc;
|
||||
__le16 srch_path = 0; /* Null - open root of share */
|
||||
u8 oplock = SMB2_OPLOCK_LEVEL_NONE;
|
||||
struct cifs_open_parms oparms;
|
||||
struct cifs_fid fid;
|
||||
|
||||
oparms.tcon = tcon;
|
||||
oparms.desired_access = FILE_READ_ATTRIBUTES;
|
||||
oparms.disposition = FILE_OPEN;
|
||||
oparms.create_options = 0;
|
||||
oparms.fid = &fid;
|
||||
oparms.reconnect = false;
|
||||
|
||||
rc = SMB2_open(xid, &oparms, &srch_path, &oplock, NULL, NULL);
|
||||
if (rc)
|
||||
return;
|
||||
|
||||
SMB2_QFS_attr(xid, tcon, fid.persistent_fid, fid.volatile_fid);
|
||||
SMB2_close(xid, tcon, fid.persistent_fid, fid.volatile_fid);
|
||||
return;
|
||||
}
|
||||
|
||||
static int
|
||||
smb2_is_path_accessible(const unsigned int xid, struct cifs_tcon *tcon,
|
||||
struct cifs_sb_info *cifs_sb, const char *full_path)
|
||||
@ -873,6 +898,7 @@ struct smb_version_operations smb20_operations = {
|
||||
.logoff = SMB2_logoff,
|
||||
.tree_connect = SMB2_tcon,
|
||||
.tree_disconnect = SMB2_tdis,
|
||||
.qfs_tcon = smb2_qfs_tcon,
|
||||
.is_path_accessible = smb2_is_path_accessible,
|
||||
.can_echo = smb2_can_echo,
|
||||
.echo = SMB2_echo,
|
||||
@ -945,6 +971,7 @@ struct smb_version_operations smb21_operations = {
|
||||
.logoff = SMB2_logoff,
|
||||
.tree_connect = SMB2_tcon,
|
||||
.tree_disconnect = SMB2_tdis,
|
||||
.qfs_tcon = smb2_qfs_tcon,
|
||||
.is_path_accessible = smb2_is_path_accessible,
|
||||
.can_echo = smb2_can_echo,
|
||||
.echo = SMB2_echo,
|
||||
@ -1018,6 +1045,7 @@ struct smb_version_operations smb30_operations = {
|
||||
.logoff = SMB2_logoff,
|
||||
.tree_connect = SMB2_tcon,
|
||||
.tree_disconnect = SMB2_tdis,
|
||||
.qfs_tcon = smb2_qfs_tcon,
|
||||
.is_path_accessible = smb2_is_path_accessible,
|
||||
.can_echo = smb2_can_echo,
|
||||
.echo = SMB2_echo,
|
||||
|
@ -2339,7 +2339,7 @@ SMB2_QFS_info(const unsigned int xid, struct cifs_tcon *tcon,
|
||||
rc = SendReceive2(xid, ses, &iov, 1, &resp_buftype, 0);
|
||||
if (rc) {
|
||||
cifs_stats_fail_inc(tcon, SMB2_QUERY_INFO_HE);
|
||||
goto qinf_exit;
|
||||
goto qfsinf_exit;
|
||||
}
|
||||
rsp = (struct smb2_query_info_rsp *)iov.iov_base;
|
||||
|
||||
@ -2351,7 +2351,45 @@ SMB2_QFS_info(const unsigned int xid, struct cifs_tcon *tcon,
|
||||
if (!rc)
|
||||
copy_fs_info_to_kstatfs(info, fsdata);
|
||||
|
||||
qinf_exit:
|
||||
qfsinf_exit:
|
||||
free_rsp_buf(resp_buftype, iov.iov_base);
|
||||
return rc;
|
||||
}
|
||||
|
||||
int
|
||||
SMB2_QFS_attr(const unsigned int xid, struct cifs_tcon *tcon,
|
||||
u64 persistent_fid, u64 volatile_fid)
|
||||
{
|
||||
struct smb2_query_info_rsp *rsp = NULL;
|
||||
struct kvec iov;
|
||||
int rc = 0;
|
||||
int resp_buftype;
|
||||
struct cifs_ses *ses = tcon->ses;
|
||||
unsigned int rsp_len, offset;
|
||||
|
||||
rc = build_qfs_info_req(&iov, tcon, SMB_QUERY_FS_ATTRIBUTE_INFO,
|
||||
sizeof(FILE_SYSTEM_ATTRIBUTE_INFO),
|
||||
persistent_fid, volatile_fid);
|
||||
if (rc)
|
||||
return rc;
|
||||
|
||||
rc = SendReceive2(xid, ses, &iov, 1, &resp_buftype, 0);
|
||||
if (rc) {
|
||||
cifs_stats_fail_inc(tcon, SMB2_QUERY_INFO_HE);
|
||||
goto qfsattr_exit;
|
||||
}
|
||||
rsp = (struct smb2_query_info_rsp *)iov.iov_base;
|
||||
|
||||
rsp_len = le32_to_cpu(rsp->OutputBufferLength);
|
||||
offset = le16_to_cpu(rsp->OutputBufferOffset);
|
||||
rc = validate_buf(offset, rsp_len, &rsp->hdr, MIN_FS_ATTR_INFO_SIZE);
|
||||
if (!rc) {
|
||||
memcpy(&tcon->fsAttrInfo, 4 /* RFC1001 len */ + offset
|
||||
+ (char *)&rsp->hdr, min_t(unsigned int,
|
||||
rsp_len, sizeof(FILE_SYSTEM_ATTRIBUTE_INFO)));
|
||||
}
|
||||
|
||||
qfsattr_exit:
|
||||
free_rsp_buf(resp_buftype, iov.iov_base);
|
||||
return rc;
|
||||
}
|
||||
|
@ -150,6 +150,8 @@ extern int SMB2_oplock_break(const unsigned int xid, struct cifs_tcon *tcon,
|
||||
extern int SMB2_QFS_info(const unsigned int xid, struct cifs_tcon *tcon,
|
||||
u64 persistent_file_id, u64 volatile_file_id,
|
||||
struct kstatfs *FSData);
|
||||
extern int SMB2_QFS_attr(const unsigned int xid, struct cifs_tcon *tcon,
|
||||
u64 persistent_file_id, u64 volatile_file_id);
|
||||
extern int SMB2_lock(const unsigned int xid, struct cifs_tcon *tcon,
|
||||
const __u64 persist_fid, const __u64 volatile_fid,
|
||||
const __u32 pid, const __u64 length, const __u64 offset,
|
||||
|
Loading…
Reference in New Issue
Block a user