* non-NULL cases, the area is of _IOC_SIZE(cmd) bytes.
*
* Introduced in version 2.8
+ *
+ * Note : the unsigned long request submitted by the application
+ * is truncated to 32 bits, and forwarded as a signed int.
*/
int (*ioctl) (const char *, int cmd, void *arg,
struct fuse_file_info *, unsigned int flags, void *data);
*
* Introduced in version 2.8
*
+ * Note : the unsigned long request submitted by the application
+ * is truncated to 32 bits, and forwarded as a signed int.
+ *
* Valid replies:
* fuse_reply_ioctl_retry
* fuse_reply_ioctl
s64 offset);
int (*sync)(struct ntfs_device *dev);
int (*stat)(struct ntfs_device *dev, struct stat *buf);
- int (*ioctl)(struct ntfs_device *dev, int request, void *argp);
+ int (*ioctl)(struct ntfs_device *dev, unsigned long request,
+ void *argp);
};
extern struct ntfs_device *ntfs_device_alloc(const char *name, const long state,
#ifndef IOCTL_H
#define IOCTL_H
-int ntfs_ioctl(ntfs_inode *ni, int cmd, void *arg,
+/*
+ * Using an "unsigned long cmd" internally, like in <sys/ioctl.h> for Linux
+ * Note however that fuse truncates the arg to 32 bits, and that
+ * some commands (e.g. FITRIM) do not fit in a signed 32 bit field.
+ */
+int ntfs_ioctl(ntfs_inode *ni, unsigned long cmd, void *arg,
unsigned int flags, void *data);
#endif /* IOCTL_H */
*
* Returns:
*/
-static int ntfs_device_unix_io_ioctl(struct ntfs_device *dev, int request,
- void *argp)
+static int ntfs_device_unix_io_ioctl(struct ntfs_device *dev,
+ unsigned long request, void *argp)
{
return ioctl(DEV_FD(dev), request, argp);
}
return -1;
}
-static int ntfs_device_win32_ioctl(struct ntfs_device *dev, int request,
- void *argp)
+static int ntfs_device_win32_ioctl(struct ntfs_device *dev,
+ unsigned long request, void *argp)
{
#if defined(BLKGETSIZE) | defined(BLKGETSIZE64)
win32_fd *fd = (win32_fd *)dev->d_private;
#endif
- ntfs_log_trace("win32_ioctl(%d) called.\n", request);
+ ntfs_log_trace("win32_ioctl(0x%lx) called.\n", request);
switch (request) {
#if defined(BLKGETSIZE)
case BLKGETSIZE:
return 0;
#endif
default:
- ntfs_log_debug("unimplemented ioctl %d.\n", request);
+ ntfs_log_debug("unimplemented ioctl 0x%lx.\n", request);
errno = EOPNOTSUPP;
return -1;
}
}
memcpy(buf, data, in_bufsz);
}
- ret = ntfs_ioctl(ni, cmd, arg, flags, buf);
+ /*
+ * Linux defines the request argument of ioctl() to be an
+ * unsigned long, which fuse 2.x forwards as a signed int
+ * into which the request sometimes does not fit.
+ * So we must expand the value and make sure it is not
+ * sign-extended.
+ */
+ ret = ntfs_ioctl(ni, (unsigned int)cmd, arg, flags, buf);
if (ntfs_inode_close (ni))
set_fuse_error(&ret);
}
if (!ni)
return -errno;
- ret = ntfs_ioctl(ni, cmd, arg, flags, data);
+ /*
+ * Linux defines the request argument of ioctl() to be an
+ * unsigned long, which fuse 2.x forwards as a signed int into
+ * which the request sometimes does not fit.
+ * So we must expand the value and make sure it is not sign-extended.
+ */
+ ret = ntfs_ioctl(ni, (unsigned int)cmd, arg, flags, data);
if (ntfs_inode_close (ni))
set_fuse_error(&ret);