|
|
|
@ -28,6 +28,7 @@ |
|
|
|
|
#include "cifs_unicode.h" |
|
|
|
|
#include "smb2status.h" |
|
|
|
|
#include "smb2glob.h" |
|
|
|
|
#include "cifs_ioctl.h" |
|
|
|
|
|
|
|
|
|
static int |
|
|
|
|
change_conf(struct TCP_Server_Info *server) |
|
|
|
@ -894,6 +895,50 @@ smb3_set_integrity(const unsigned int xid, struct cifs_tcon *tcon, |
|
|
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
static int |
|
|
|
|
smb3_enum_snapshots(const unsigned int xid, struct cifs_tcon *tcon, |
|
|
|
|
struct cifsFileInfo *cfile, void __user *ioc_buf) |
|
|
|
|
{ |
|
|
|
|
char *retbuf = NULL; |
|
|
|
|
unsigned int ret_data_len = 0; |
|
|
|
|
int rc; |
|
|
|
|
struct smb_snapshot_array snapshot_in; |
|
|
|
|
|
|
|
|
|
rc = SMB2_ioctl(xid, tcon, cfile->fid.persistent_fid, |
|
|
|
|
cfile->fid.volatile_fid, |
|
|
|
|
FSCTL_SRV_ENUMERATE_SNAPSHOTS, |
|
|
|
|
true /* is_fsctl */, NULL, 0 /* no input data */, |
|
|
|
|
(char **)&retbuf, |
|
|
|
|
&ret_data_len); |
|
|
|
|
cifs_dbg(FYI, "enum snaphots ioctl returned %d and ret buflen is %d\n", |
|
|
|
|
rc, ret_data_len); |
|
|
|
|
if (rc) |
|
|
|
|
return rc; |
|
|
|
|
|
|
|
|
|
if (ret_data_len && (ioc_buf != NULL) && (retbuf != NULL)) { |
|
|
|
|
/* Fixup buffer */ |
|
|
|
|
if (copy_from_user(&snapshot_in, ioc_buf, |
|
|
|
|
sizeof(struct smb_snapshot_array))) { |
|
|
|
|
rc = -EFAULT; |
|
|
|
|
kfree(retbuf); |
|
|
|
|
return rc; |
|
|
|
|
} |
|
|
|
|
if (snapshot_in.snapshot_array_size < sizeof(struct smb_snapshot_array)) { |
|
|
|
|
rc = -ERANGE; |
|
|
|
|
return rc; |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
if (ret_data_len > snapshot_in.snapshot_array_size) |
|
|
|
|
ret_data_len = snapshot_in.snapshot_array_size; |
|
|
|
|
|
|
|
|
|
if (copy_to_user(ioc_buf, retbuf, ret_data_len)) |
|
|
|
|
rc = -EFAULT; |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
kfree(retbuf); |
|
|
|
|
return rc; |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
static int |
|
|
|
|
smb2_query_dir_first(const unsigned int xid, struct cifs_tcon *tcon, |
|
|
|
|
const char *path, struct cifs_sb_info *cifs_sb, |
|
|
|
@ -1659,6 +1704,7 @@ struct smb_version_operations smb21_operations = { |
|
|
|
|
.clone_range = smb2_clone_range, |
|
|
|
|
.wp_retry_size = smb2_wp_retry_size, |
|
|
|
|
.dir_needs_close = smb2_dir_needs_close, |
|
|
|
|
.enum_snapshots = smb3_enum_snapshots, |
|
|
|
|
}; |
|
|
|
|
|
|
|
|
|
struct smb_version_operations smb30_operations = { |
|
|
|
@ -1745,6 +1791,7 @@ struct smb_version_operations smb30_operations = { |
|
|
|
|
.wp_retry_size = smb2_wp_retry_size, |
|
|
|
|
.dir_needs_close = smb2_dir_needs_close, |
|
|
|
|
.fallocate = smb3_fallocate, |
|
|
|
|
.enum_snapshots = smb3_enum_snapshots, |
|
|
|
|
}; |
|
|
|
|
|
|
|
|
|
#ifdef CONFIG_CIFS_SMB311 |
|
|
|
@ -1832,6 +1879,7 @@ struct smb_version_operations smb311_operations = { |
|
|
|
|
.wp_retry_size = smb2_wp_retry_size, |
|
|
|
|
.dir_needs_close = smb2_dir_needs_close, |
|
|
|
|
.fallocate = smb3_fallocate, |
|
|
|
|
.enum_snapshots = smb3_enum_snapshots, |
|
|
|
|
}; |
|
|
|
|
#endif /* CIFS_SMB311 */ |
|
|
|
|
|
|
|
|
|