aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorSteve French <steve.french@primarydata.com>2015-07-04 19:40:10 -0400
committerSteve French <smfrench@gmail.com>2015-08-20 11:19:25 -0400
commit0de1f4c6f6c028249579d8d80fa0a4f6322b2227 (patch)
treedd543b57f54bcf408d6f8e598b31f3777cb136de
parent1b647a166f07dcf08709c8606470f4b17a4aa11d (diff)
Add way to query server fs info for smb3
The server exports information about the share and underlying device under an SMB3 export, including its attributes and capabilities, which is stored by cifs.ko when first connecting to the share. Add ioctl to cifs.ko to allow user space smb3 helper utilities (in cifs-utils) to display this (e.g. via smb3util). This information is also useful for debugging and for resolving configuration errors. Signed-off-by: Steve French <steve.french@primarydata.com>
-rw-r--r--fs/cifs/cifs_ioctl.h42
-rw-r--r--fs/cifs/cifspdu.h14
-rw-r--r--fs/cifs/ioctl.c48
3 files changed, 98 insertions, 6 deletions
diff --git a/fs/cifs/cifs_ioctl.h b/fs/cifs/cifs_ioctl.h
new file mode 100644
index 000000000000..0065256881d8
--- /dev/null
+++ b/fs/cifs/cifs_ioctl.h
@@ -0,0 +1,42 @@
1/*
2 * fs/cifs/cifs_ioctl.h
3 *
4 * Structure definitions for io control for cifs/smb3
5 *
6 * Copyright (c) 2015 Steve French <steve.french@primarydata.com>
7 *
8 * This library is free software; you can redistribute it and/or modify
9 * it under the terms of the GNU Lesser General Public License as published
10 * by the Free Software Foundation; either version 2.1 of the License, or
11 * (at your option) any later version.
12 *
13 * This library is distributed in the hope that it will be useful,
14 * but WITHOUT ANY WARRANTY; without even the implied warranty of
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See
16 * the GNU Lesser General Public License for more details.
17 *
18 */
19
20struct smb_mnt_fs_info {
21 __u32 version; /* 0001 */
22 __u16 protocol_id;
23 __u16 tcon_flags;
24 __u32 vol_serial_number;
25 __u32 vol_create_time;
26 __u32 share_caps;
27 __u32 share_flags;
28 __u32 sector_flags;
29 __u32 optimal_sector_size;
30 __u32 max_bytes_chunk;
31 __u32 fs_attributes;
32 __u32 max_path_component;
33 __u32 device_type;
34 __u32 device_characteristics;
35 __u32 maximal_access;
36 __u64 cifs_posix_caps;
37} __packed;
38
39#define CIFS_IOCTL_MAGIC 0xCF
40#define CIFS_IOC_COPYCHUNK_FILE _IOW(CIFS_IOCTL_MAGIC, 3, int)
41#define CIFS_IOC_SET_INTEGRITY _IO(CIFS_IOCTL_MAGIC, 4)
42#define CIFS_IOC_GET_MNT_INFO _IOR(CIFS_IOCTL_MAGIC, 5, struct smb_mnt_fs_info)
diff --git a/fs/cifs/cifspdu.h b/fs/cifs/cifspdu.h
index 47b030da0781..f5b87303ce46 100644
--- a/fs/cifs/cifspdu.h
+++ b/fs/cifs/cifspdu.h
@@ -2245,6 +2245,20 @@ typedef struct {
2245#define FILE_DEVICE_VIRTUAL_DISK 0x00000024 2245#define FILE_DEVICE_VIRTUAL_DISK 0x00000024
2246#define FILE_DEVICE_NETWORK_REDIRECTOR 0x00000028 2246#define FILE_DEVICE_NETWORK_REDIRECTOR 0x00000028
2247 2247
2248/* Device Characteristics */
2249#define FILE_REMOVABLE_MEDIA 0x00000001
2250#define FILE_READ_ONLY_DEVICE 0x00000002
2251#define FILE_FLOPPY_DISKETTE 0x00000004
2252#define FILE_WRITE_ONCE_MEDIA 0x00000008
2253#define FILE_REMOTE_DEVICE 0x00000010
2254#define FILE_DEVICE_IS_MOUNTED 0x00000020
2255#define FILE_VIRTUAL_VOLUME 0x00000040
2256#define FILE_DEVICE_SECURE_OPEN 0x00000100
2257#define FILE_CHARACTERISTIC_TS_DEVICE 0x00001000
2258#define FILE_CHARACTERISTIC_WEBDAV_DEVICE 0x00002000
2259#define FILE_PORTABLE_DEVICE 0x00004000
2260#define FILE_DEVICE_ALLOW_APPCONTAINER_TRAVERSAL 0x00020000
2261
2248typedef struct { 2262typedef struct {
2249 __le32 DeviceType; 2263 __le32 DeviceType;
2250 __le32 DeviceCharacteristics; 2264 __le32 DeviceCharacteristics;
diff --git a/fs/cifs/ioctl.c b/fs/cifs/ioctl.c
index 49b8b6e41a18..c63f5227b681 100644
--- a/fs/cifs/ioctl.c
+++ b/fs/cifs/ioctl.c
@@ -31,12 +31,9 @@
31#include "cifsproto.h" 31#include "cifsproto.h"
32#include "cifs_debug.h" 32#include "cifs_debug.h"
33#include "cifsfs.h" 33#include "cifsfs.h"
34#include "cifs_ioctl.h"
34#include <linux/btrfs.h> 35#include <linux/btrfs.h>
35 36
36#define CIFS_IOCTL_MAGIC 0xCF
37#define CIFS_IOC_COPYCHUNK_FILE _IOW(CIFS_IOCTL_MAGIC, 3, int)
38#define CIFS_IOC_SET_INTEGRITY _IO(CIFS_IOCTL_MAGIC, 4)
39
40static long cifs_ioctl_clone(unsigned int xid, struct file *dst_file, 37static long cifs_ioctl_clone(unsigned int xid, struct file *dst_file,
41 unsigned long srcfd, u64 off, u64 len, u64 destoff, 38 unsigned long srcfd, u64 off, u64 len, u64 destoff,
42 bool dup_extents) 39 bool dup_extents)
@@ -135,6 +132,43 @@ out_drop_write:
135 return rc; 132 return rc;
136} 133}
137 134
135static long smb_mnt_get_fsinfo(unsigned int xid, struct cifs_tcon *tcon,
136 void __user *arg)
137{
138 int rc = 0;
139 struct smb_mnt_fs_info *fsinf;
140
141 fsinf = kzalloc(sizeof(struct smb_mnt_fs_info), GFP_KERNEL);
142 if (fsinf == NULL)
143 return -ENOMEM;
144
145 fsinf->version = 1;
146 fsinf->protocol_id = tcon->ses->server->vals->protocol_id;
147 fsinf->device_characteristics =
148 le32_to_cpu(tcon->fsDevInfo.DeviceCharacteristics);
149 fsinf->device_type = le32_to_cpu(tcon->fsDevInfo.DeviceType);
150 fsinf->fs_attributes = le32_to_cpu(tcon->fsAttrInfo.Attributes);
151 fsinf->max_path_component =
152 le32_to_cpu(tcon->fsAttrInfo.MaxPathNameComponentLength);
153#ifdef CONFIG_CIFS_SMB2
154 fsinf->vol_serial_number = tcon->vol_serial_number;
155 fsinf->vol_create_time = le64_to_cpu(tcon->vol_create_time);
156 fsinf->share_flags = tcon->share_flags;
157 fsinf->share_caps = le32_to_cpu(tcon->capabilities);
158 fsinf->sector_flags = tcon->ss_flags;
159 fsinf->optimal_sector_size = tcon->perf_sector_size;
160 fsinf->max_bytes_chunk = tcon->max_bytes_chunk;
161 fsinf->maximal_access = tcon->maximal_access;
162#endif /* SMB2 */
163 fsinf->cifs_posix_caps = le64_to_cpu(tcon->fsUnixInfo.Capability);
164
165 if (copy_to_user(arg, fsinf, sizeof(struct smb_mnt_fs_info)))
166 rc = -EFAULT;
167
168 kfree(fsinf);
169 return rc;
170}
171
138long cifs_ioctl(struct file *filep, unsigned int command, unsigned long arg) 172long cifs_ioctl(struct file *filep, unsigned int command, unsigned long arg)
139{ 173{
140 struct inode *inode = file_inode(filep); 174 struct inode *inode = file_inode(filep);
@@ -148,8 +182,6 @@ long cifs_ioctl(struct file *filep, unsigned int command, unsigned long arg)
148 182
149 xid = get_xid(); 183 xid = get_xid();
150 184
151 cifs_dbg(FYI, "ioctl file %p cmd %u arg %lu\n", filep, command, arg);
152
153 cifs_sb = CIFS_SB(inode->i_sb); 185 cifs_sb = CIFS_SB(inode->i_sb);
154 186
155 switch (command) { 187 switch (command) {
@@ -228,6 +260,10 @@ long cifs_ioctl(struct file *filep, unsigned int command, unsigned long arg)
228 else 260 else
229 rc = -EOPNOTSUPP; 261 rc = -EOPNOTSUPP;
230 break; 262 break;
263 case CIFS_IOC_GET_MNT_INFO:
264 tcon = tlink_tcon(pSMBFile->tlink);
265 rc = smb_mnt_get_fsinfo(xid, tcon, (void __user *)arg);
266 break;
231 default: 267 default:
232 cifs_dbg(FYI, "unsupported ioctl\n"); 268 cifs_dbg(FYI, "unsupported ioctl\n");
233 break; 269 break;