summaryrefslogtreecommitdiffstats
path: root/fs/cifs/ioctl.c
diff options
context:
space:
mode:
authorRonnie Sahlberg <lsahlber@redhat.com>2018-10-16 21:47:58 +0200
committerSteve French <stfrench@microsoft.com>2018-10-24 04:16:05 +0200
commit8d8b26e58432cb2840048b9f8aea286be6f75de5 (patch)
tree0434bc93a5769be50353d7407a68c9d85dff0588 /fs/cifs/ioctl.c
parentcifs: fallback to older infolevels on findfirst queryinfo retry (diff)
downloadlinux-8d8b26e58432cb2840048b9f8aea286be6f75de5.tar.xz
linux-8d8b26e58432cb2840048b9f8aea286be6f75de5.zip
cifs: add support for ioctl on directories
We do not call cifs_open_file() for directories and thus we do not have a pSMBFile we can extract the FIDs from. Solve this by instead always using a compounded open/query/close for the passthrough ioctl. Signed-off-by: Ronnie Sahlberg <lsahlber@redhat.com> Signed-off-by: Steve French <stfrench@microsoft.com>
Diffstat (limited to 'fs/cifs/ioctl.c')
-rw-r--r--fs/cifs/ioctl.c43
1 files changed, 34 insertions, 9 deletions
diff --git a/fs/cifs/ioctl.c b/fs/cifs/ioctl.c
index 77c7a5796dfd..76ddd98b6298 100644
--- a/fs/cifs/ioctl.c
+++ b/fs/cifs/ioctl.c
@@ -32,24 +32,49 @@
#include "cifs_debug.h"
#include "cifsfs.h"
#include "cifs_ioctl.h"
+#include "smb2proto.h"
#include <linux/btrfs.h>
static long cifs_ioctl_query_info(unsigned int xid, struct file *filep,
unsigned long p)
{
- struct cifsFileInfo *pSMBFile = filep->private_data;
- struct cifs_tcon *tcon;
+ struct inode *inode = file_inode(filep);
+ struct cifs_sb_info *cifs_sb = CIFS_SB(inode->i_sb);
+ struct cifs_tcon *tcon = cifs_sb_master_tcon(cifs_sb);
+ struct dentry *dentry = filep->f_path.dentry;
+ unsigned char *path;
+ __le16 *utf16_path = NULL, root_path;
+ int rc = 0;
+
+ path = build_path_from_dentry(dentry);
+ if (path == NULL)
+ return -ENOMEM;
+
+ cifs_dbg(FYI, "%s %s\n", __func__, path);
- cifs_dbg(FYI, "%s %p\n", __func__, pSMBFile);
- if (pSMBFile == NULL)
- return -EISDIR;
- tcon = tlink_tcon(pSMBFile->tlink);
+ if (!path[0]) {
+ root_path = 0;
+ utf16_path = &root_path;
+ } else {
+ utf16_path = cifs_convert_path_to_utf16(path + 1, cifs_sb);
+ if (!utf16_path) {
+ rc = -ENOMEM;
+ goto ici_exit;
+ }
+ }
if (tcon->ses->server->ops->ioctl_query_info)
- return tcon->ses->server->ops->ioctl_query_info(
- xid, pSMBFile, p);
+ rc = tcon->ses->server->ops->ioctl_query_info(
+ xid, tcon, utf16_path,
+ filep->private_data ? 0 : 1, p);
else
- return -EOPNOTSUPP;
+ rc = -EOPNOTSUPP;
+
+ ici_exit:
+ if (utf16_path != &root_path)
+ kfree(utf16_path);
+ kfree(path);
+ return rc;
}
static long cifs_ioctl_copychunk(unsigned int xid, struct file *dst_file,