diff options
author | Ronnie Sahlberg <lsahlber@redhat.com> | 2018-10-16 21:47:58 +0200 |
---|---|---|
committer | Steve French <stfrench@microsoft.com> | 2018-10-24 04:16:05 +0200 |
commit | 8d8b26e58432cb2840048b9f8aea286be6f75de5 (patch) | |
tree | 0434bc93a5769be50353d7407a68c9d85dff0588 /fs/cifs/ioctl.c | |
parent | cifs: fallback to older infolevels on findfirst queryinfo retry (diff) | |
download | linux-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.c | 43 |
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, |