From: Christoph Hellwig <hch@lst.de>
To: Arnd Bergmann <arnd@arndb.de>
Cc: Christoph Hellwig <hch@infradead.org>,
mfasheh@suse.com, joel.becker@oracle.com,
linux-kernel@vger.kernel.org, xfs-masters@oss.sgi.com,
Al Viro <viro@zeniv.linux.org.uk>, Ankit Jain <me@ankitjain.org>,
linux-fsdevel@vger.kernel.org, xfs@oss.sgi.com,
ocfs2-devel@oss.oracle.com
Subject: Re: [xfs-masters] [PATCH] fs: Add new pre-allocation ioctls to vfs for compatibility with legacy xfs ioctls
Date: Sun, 21 Jun 2009 20:41:55 +0200 [thread overview]
Message-ID: <20090621184154.GA3471@lst.de> (raw)
In-Reply-To: <200906200813.59793.arnd@arndb.de>
On Sat, Jun 20, 2009 at 08:13:59AM +0000, Arnd Bergmann wrote:
> I'd just define this using compat_s64 instead of __s64 __packed so we can
> use the same code on all architectures, even at the small cost of extra
> text size on non-x86 architectures.
I'm not a big fan of imposing the translation overhead to all
architectures, but doing it allows using the good old HANDLE_IOCTL
and futher simplifying things.
Index: linux-2.6/fs/compat_ioctl.c
===================================================================
--- linux-2.6.orig/fs/compat_ioctl.c 2009-06-20 20:19:47.035930201 +0200
+++ linux-2.6/fs/compat_ioctl.c 2009-06-20 20:20:43.821833210 +0200
@@ -31,6 +31,7 @@
#include <linux/skbuff.h>
#include <linux/netlink.h>
#include <linux/vt.h>
+#include <linux/falloc.h>
#include <linux/fs.h>
#include <linux/file.h>
#include <linux/ppp_defs.h>
@@ -1820,6 +1821,38 @@ lp_timeout_trans(unsigned int fd, unsign
return sys_ioctl(fd, cmd, (unsigned long)tn);
}
+/* on ia32 l_start is on a 32-bit boundary */
+struct space_resv_32 {
+ __s16 l_type;
+ __s16 l_whence;
+ compat_s64 l_start;
+ compat_s64 l_len; /* len == 0 means until end of file */
+ __s32 l_sysid;
+ __u32 l_pid;
+ __s32 l_pad[4]; /* reserve area */
+};
+
+#define FS_IOC_RESVSP_32 _IOW ('X', 40, struct space_resv_32)
+#define FS_IOC_RESVSP64_32 _IOW ('X', 42, struct space_resv_32)
+
+/* just account for different alignment */
+static int compat_ioctl_resvsp(unsigned fd, unsigned cmd, unsigned long arg)
+{
+ struct space_resv_32 __user *p32 = (void __user *)arg;
+ struct space_resv __user *p = compat_alloc_user_space(sizeof(*p));
+
+ if (copy_in_user(&p->l_type, &p32->l_type, sizeof(s16)) ||
+ copy_in_user(&p->l_whence, &p32->l_whence, sizeof(s16)) ||
+ copy_in_user(&p->l_start, &p32->l_start, sizeof(s64)) ||
+ copy_in_user(&p->l_len, &p32->l_len, sizeof(s64)) ||
+ copy_in_user(&p->l_sysid, &p32->l_sysid, sizeof(s32)) ||
+ copy_in_user(&p->l_pid, &p32->l_pid, sizeof(u32)) ||
+ copy_in_user(&p->l_pad, &p32->l_pad, 4*sizeof(u32)))
+ return -EFAULT;
+
+ return sys_ioctl(fd, FS_IOC_RESVSP, p);
+}
+
typedef int (*ioctl_trans_handler_t)(unsigned int, unsigned int,
unsigned long, struct file *);
@@ -1915,6 +1948,8 @@ COMPATIBLE_IOCTL(FIGETBSZ)
/* 'X' - originally XFS but some now in the VFS */
COMPATIBLE_IOCTL(FIFREEZE)
COMPATIBLE_IOCTL(FITHAW)
+HANDLE_IOCTL(FS_IOC_RESVSP_32, compat_ioctl_resvsp)
+HANDLE_IOCTL(FS_IOC_RESVSP64_32, compat_ioctl_resvsp)
/* RAID */
COMPATIBLE_IOCTL(RAID_VERSION)
COMPATIBLE_IOCTL(GET_ARRAY_INFO)
Index: linux-2.6/fs/ioctl.c
===================================================================
--- linux-2.6.orig/fs/ioctl.c 2009-06-20 20:19:47.040930349 +0200
+++ linux-2.6/fs/ioctl.c 2009-06-20 20:20:43.821833210 +0200
@@ -15,6 +15,7 @@
#include <linux/uaccess.h>
#include <linux/writeback.h>
#include <linux/buffer_head.h>
+#include <linux/falloc.h>
#include <asm/ioctls.h>
@@ -403,6 +404,37 @@ EXPORT_SYMBOL(generic_block_fiemap);
#endif /* CONFIG_BLOCK */
+/*
+ * This provides compatibility with legacy XFS pre-allocation ioctls
+ * which predate the fallocate syscall.
+ *
+ * Only the l_start, l_len and l_whence fields of the 'struct space_resv'
+ * are used here, rest are ignored.
+ */
+static int ioctl_resvsp(struct file *filp, void __user *argp)
+{
+ struct inode *inode = filp->f_path.dentry->d_inode;
+ struct space_resv sr;
+
+ if (copy_from_user(&sr, argp, sizeof(sr)))
+ return -EFAULT;
+
+ switch (sr.l_whence) {
+ case SEEK_SET:
+ break;
+ case SEEK_CUR:
+ sr.l_start += filp->f_pos;
+ break;
+ case SEEK_END:
+ sr.l_start += i_size_read(inode);
+ break;
+ default:
+ return -EINVAL;
+ }
+
+ return do_fallocate(filp, FALLOC_FL_KEEP_SIZE, sr.l_start, sr.l_len);
+}
+
static int file_ioctl(struct file *filp, unsigned int cmd,
unsigned long arg)
{
@@ -414,6 +446,9 @@ static int file_ioctl(struct file *filp,
return ioctl_fibmap(filp, p);
case FIONREAD:
return put_user(i_size_read(inode) - filp->f_pos, p);
+ case FS_IOC_RESVSP:
+ case FS_IOC_RESVSP64:
+ return ioctl_resvsp(filp, p);
}
return vfs_ioctl(filp, cmd, arg);
Index: linux-2.6/fs/open.c
===================================================================
--- linux-2.6.orig/fs/open.c 2009-06-20 20:19:47.054929896 +0200
+++ linux-2.6/fs/open.c 2009-06-20 20:20:43.822836760 +0200
@@ -378,63 +378,63 @@ SYSCALL_ALIAS(sys_ftruncate64, SyS_ftrun
#endif
#endif /* BITS_PER_LONG == 32 */
-SYSCALL_DEFINE(fallocate)(int fd, int mode, loff_t offset, loff_t len)
+
+int do_fallocate(struct file *file, int mode, loff_t offset, loff_t len)
{
- struct file *file;
- struct inode *inode;
- long ret = -EINVAL;
+ struct inode *inode = file->f_path.dentry->d_inode;
+ long ret;
if (offset < 0 || len <= 0)
- goto out;
+ return -EINVAL;
/* Return error if mode is not supported */
- ret = -EOPNOTSUPP;
if (mode && !(mode & FALLOC_FL_KEEP_SIZE))
- goto out;
+ return -EOPNOTSUPP;
- ret = -EBADF;
- file = fget(fd);
- if (!file)
- goto out;
if (!(file->f_mode & FMODE_WRITE))
- goto out_fput;
+ return -EBADF;
/*
* Revalidate the write permissions, in case security policy has
* changed since the files were opened.
*/
ret = security_file_permission(file, MAY_WRITE);
if (ret)
- goto out_fput;
+ return ret;
- inode = file->f_path.dentry->d_inode;
-
- ret = -ESPIPE;
if (S_ISFIFO(inode->i_mode))
- goto out_fput;
+ return -ESPIPE;
- ret = -ENODEV;
/*
* Let individual file system decide if it supports preallocation
* for directories or not.
*/
if (!S_ISREG(inode->i_mode) && !S_ISDIR(inode->i_mode))
- goto out_fput;
+ return -ENODEV;
- ret = -EFBIG;
/* Check for wrap through zero too */
if (((offset + len) > inode->i_sb->s_maxbytes) || ((offset + len) < 0))
- goto out_fput;
+ return -EFBIG;
- if (inode->i_op->fallocate)
- ret = inode->i_op->fallocate(inode, mode, offset, len);
- else
- ret = -EOPNOTSUPP;
+ if (!inode->i_op->fallocate)
+ return -EOPNOTSUPP;
-out_fput:
- fput(file);
-out:
- return ret;
+ return inode->i_op->fallocate(inode, mode, offset, len);
}
+
+SYSCALL_DEFINE(fallocate)(int fd, int mode, loff_t offset, loff_t len)
+{
+ struct file *file;
+ int error = -EBADF;
+
+ file = fget(fd);
+ if (file) {
+ error = do_fallocate(file, mode, offset, len);
+ fput(file);
+ }
+
+ return error;
+}
+
#ifdef CONFIG_HAVE_SYSCALL_WRAPPERS
asmlinkage long SyS_fallocate(long fd, long mode, loff_t offset, loff_t len)
{
Index: linux-2.6/include/linux/falloc.h
===================================================================
--- linux-2.6.orig/include/linux/falloc.h 2009-06-20 20:19:47.059930323 +0200
+++ linux-2.6/include/linux/falloc.h 2009-06-20 20:20:43.822836760 +0200
@@ -3,4 +3,25 @@
#define FALLOC_FL_KEEP_SIZE 0x01 /* default is extend size */
+#ifdef __KERNEL__
+
+/*
+ * Space reservation ioctls and argument structure
+ * are designed to be compatible with the legacy XFS ioctls.
+ */
+struct space_resv {
+ __s16 l_type;
+ __s16 l_whence;
+ __s64 l_start;
+ __s64 l_len; /* len == 0 means until end of file */
+ __s32 l_sysid;
+ __u32 l_pid;
+ __s32 l_pad[4]; /* reserved area */
+};
+
+#define FS_IOC_RESVSP _IOW('X', 40, struct space_resv)
+#define FS_IOC_RESVSP64 _IOW('X', 42, struct space_resv)
+
+#endif /* __KERNEL__ */
+
#endif /* _FALLOC_H_ */
Index: linux-2.6/include/linux/fs.h
===================================================================
--- linux-2.6.orig/include/linux/fs.h 2009-06-20 20:19:47.065929969 +0200
+++ linux-2.6/include/linux/fs.h 2009-06-20 20:20:43.823832557 +0200
@@ -1905,6 +1905,8 @@ static inline int break_lease(struct ino
extern int do_truncate(struct dentry *, loff_t start, unsigned int time_attrs,
struct file *filp);
+extern int do_fallocate(struct file *file, int mode, loff_t offset,
+ loff_t len);
extern long do_sys_open(int dfd, const char __user *filename, int flags,
int mode);
extern struct file *filp_open(const char *, int, int);
prev parent reply other threads:[~2009-06-21 18:46 UTC|newest]
Thread overview: 25+ messages / expand[flat|nested] mbox.gz Atom feed top
2009-01-28 20:59 [PATCH] fs: Add new pre-allocation ioctls to vfs for compatibility with legacy xfs ioctls Ankit Jain
2009-01-31 0:22 ` Andrew Morton
2009-01-31 0:38 ` Arnd Bergmann
2009-01-31 1:14 ` Andrew Morton
2009-01-31 1:48 ` Arnd Bergmann
2009-02-01 9:48 ` Boaz Harrosh
2009-02-01 10:05 ` Geert Uytterhoeven
2009-02-01 10:39 ` Boaz Harrosh
2009-02-01 10:59 ` Geert Uytterhoeven
2009-02-01 12:32 ` Boaz Harrosh
2009-02-01 15:37 ` [xfs-masters] " Eric Sandeen
2009-02-01 16:25 ` Boaz Harrosh
2009-02-01 16:35 ` Eric Sandeen
2009-02-01 16:41 ` Christoph Hellwig
2009-02-01 16:57 ` Boaz Harrosh
2009-02-02 0:31 ` Arnd Bergmann
2009-02-02 8:29 ` Boaz Harrosh
2009-02-02 8:45 ` Geert Uytterhoeven
2009-02-02 9:33 ` Boaz Harrosh
2009-02-02 20:51 ` Jamie Lokier
2009-02-03 7:31 ` Boaz Harrosh
2009-02-03 11:21 ` Jamie Lokier
2009-06-19 18:28 ` Christoph Hellwig
2009-06-20 8:13 ` Arnd Bergmann
2009-06-21 18:41 ` Christoph Hellwig [this message]
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=20090621184154.GA3471@lst.de \
--to=hch@lst.de \
--cc=arnd@arndb.de \
--cc=hch@infradead.org \
--cc=joel.becker@oracle.com \
--cc=linux-fsdevel@vger.kernel.org \
--cc=linux-kernel@vger.kernel.org \
--cc=me@ankitjain.org \
--cc=mfasheh@suse.com \
--cc=ocfs2-devel@oss.oracle.com \
--cc=viro@zeniv.linux.org.uk \
--cc=xfs-masters@oss.sgi.com \
--cc=xfs@oss.sgi.com \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).