* [PATCH v2] fs: Add new pre-allocation ioctls to vfs for compatibility with legacy xfs ioctls
@ 2008-12-18 21:21 Ankit Jain
2008-12-19 4:37 ` Dave Chinner
0 siblings, 1 reply; 3+ messages in thread
From: Ankit Jain @ 2008-12-18 21:21 UTC (permalink / raw)
To: Al Viro
Cc: Christoph Hellwig, linux-fsdevel, mfasheh, joel.becker,
ocfs2-devel, linux-kernel, xfs-masters, xfs
This patch adds ioctls to vfs for compatibility with legacy XFS
pre-allocation ioctls (XFS_IOC_*RESVP*). The implementation
effectively invokes sys_fallocate for the new ioctls.
Note: These legacy ioctls are also implemented by OCFS2.
Changes in v2:
- Dropped the incorrect handling of *UNRESVSP* ioctl.
- Made the ioctl and argument structure kernel only (__KERNEL__)
Signed-off-by: Ankit Jain <me@ankitjain.org>
---
fs/ioctl.c | 35 ++++++++++++++++++++++++++
fs/open.c | 51 ++++++++++++++++++-------------------
include/linux/falloc.h | 21 +++++++++++++++
include/linux/fs.h | 2 +
4 files changed, 83 insertions(+), 26 deletions(-)
diff --git a/fs/ioctl.c b/fs/ioctl.c
index 43e8b2c..2b3fae7 100644
--- a/fs/ioctl.c
+++ b/fs/ioctl.c
@@ -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>
@@ -346,6 +347,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_preallocate(struct file *filp, unsigned long arg)
+{
+ struct inode *inode = filp->f_path.dentry->d_inode;
+ struct space_resv sr;
+
+ if (copy_from_user(&sr, (struct space_resv __user *) arg, 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)
{
@@ -361,6 +393,9 @@ static int file_ioctl(struct file *filp, unsigned int cmd,
return put_user(inode->i_sb->s_blocksize, p);
case FIONREAD:
return put_user(i_size_read(inode) - filp->f_pos, p);
+ case F_IOC_RESVSP:
+ case F_IOC_RESVSP64:
+ return ioctl_preallocate(filp, arg);
}
return vfs_ioctl(filp, cmd, arg);
diff --git a/fs/open.c b/fs/open.c
index 83cdb9d..0703bcb 100644
--- a/fs/open.c
+++ b/fs/open.c
@@ -360,62 +360,61 @@ asmlinkage long sys_ftruncate64(unsigned int fd, loff_t length)
}
#endif
-asmlinkage long sys_fallocate(int fd, int mode, loff_t offset, loff_t len)
+long do_fallocate(struct file *file, int mode, loff_t offset, loff_t len)
{
- struct file *file;
struct inode *inode;
- long ret = -EINVAL;
+ 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;
+ if (!file || !(file->f_mode & FMODE_WRITE))
+ 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 && inode->i_op->fallocate)
- ret = inode->i_op->fallocate(inode, mode, offset, len);
+ return inode->i_op->fallocate(inode, mode, offset, len);
else
- ret = -EOPNOTSUPP;
+ return -EOPNOTSUPP;
+}
-out_fput:
- fput(file);
-out:
- return ret;
+asmlinkage long sys_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;
}
/*
diff --git a/include/linux/falloc.h b/include/linux/falloc.h
index 8e912ab..c4bf904 100644
--- a/include/linux/falloc.h
+++ b/include/linux/falloc.h
@@ -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]; /* reserve area */
+};
+
+#define F_IOC_RESVSP _IOW('X', 40, struct space_resv)
+#define F_IOC_RESVSP64 _IOW('X', 42, struct space_resv)
+
+#endif
+
#endif /* _FALLOC_H_ */
diff --git a/include/linux/fs.h b/include/linux/fs.h
index 4a853ef..b1d8f12 100644
--- a/include/linux/fs.h
+++ b/include/linux/fs.h
@@ -1671,6 +1671,8 @@ static inline int break_lease(struct inode *inode, unsigned int mode)
extern int do_truncate(struct dentry *, loff_t start, unsigned int time_attrs,
struct file *filp);
+extern long 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);
^ permalink raw reply related [flat|nested] 3+ messages in thread
* Re: [PATCH v2] fs: Add new pre-allocation ioctls to vfs for compatibility with legacy xfs ioctls
2008-12-18 21:21 [PATCH v2] fs: Add new pre-allocation ioctls to vfs for compatibility with legacy xfs ioctls Ankit Jain
@ 2008-12-19 4:37 ` Dave Chinner
2008-12-19 8:59 ` Christoph Hellwig
0 siblings, 1 reply; 3+ messages in thread
From: Dave Chinner @ 2008-12-19 4:37 UTC (permalink / raw)
To: Ankit Jain
Cc: Al Viro, mfasheh, linux-kernel, joel.becker, Christoph Hellwig,
xfs-masters, linux-fsdevel, xfs, ocfs2-devel
On Fri, Dec 19, 2008 at 02:51:00AM +0530, Ankit Jain wrote:
> This patch adds ioctls to vfs for compatibility with legacy XFS
> pre-allocation ioctls (XFS_IOC_*RESVP*). The implementation
> effectively invokes sys_fallocate for the new ioctls.
> Note: These legacy ioctls are also implemented by OCFS2.
>
> Changes in v2:
> - Dropped the incorrect handling of *UNRESVSP* ioctl.
> - Made the ioctl and argument structure kernel only (__KERNEL__)
>
> Signed-off-by: Ankit Jain <me@ankitjain.org>
.....
> @@ -361,6 +393,9 @@ static int file_ioctl(struct file *filp, unsigned int cmd,
> return put_user(inode->i_sb->s_blocksize, p);
> case FIONREAD:
> return put_user(i_size_read(inode) - filp->f_pos, p);
> + case F_IOC_RESVSP:
> + case F_IOC_RESVSP64:
> + return ioctl_preallocate(filp, arg);
> }
>
> return vfs_ioctl(filp, cmd, arg);
Adding this here breaks XFS_IOC_RESVSP in subtle and interesting
ways.
XFS_IOC_RESVSP supports invisible I/O, and that means
XFS_IOC_RESVSP needs to be passed through to vfs_ioctl()
to vector to XFS to handle.
This happenѕ because:
> +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]; /* reserve area */
> +};
> +
> +#define F_IOC_RESVSP _IOW('X', 40, struct space_resv)
> +#define F_IOC_RESVSP64 _IOW('X', 42, struct space_resv)
Is the same as:
#define XFS_IOC_RESVSP _IOW ('X', 40, struct xfs_flock64)
#define XFS_IOC_RESVSP64 _IOW ('X', 42, struct xfs_flock64)
because:
typedef struct xfs_flock64 {
__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]; /* reserve area */
} xfs_flock64_t;
is the same size as struct space_resv. Hence existing calls to
XFS_IOC_RESVSP will now vector incorrectly down the fallocate path
resulting in invisible operations will now be visible....
Cheers,
Dave.
--
Dave Chinner
david@fromorbit.com
--
To unsubscribe from this list: send the line "unsubscribe linux-fsdevel" in
the body of a message to majordomo@vger.kernel.org
More majordomo info at http://vger.kernel.org/majordomo-info.html
^ permalink raw reply [flat|nested] 3+ messages in thread
* Re: [PATCH v2] fs: Add new pre-allocation ioctls to vfs for compatibility with legacy xfs ioctls
2008-12-19 4:37 ` Dave Chinner
@ 2008-12-19 8:59 ` Christoph Hellwig
0 siblings, 0 replies; 3+ messages in thread
From: Christoph Hellwig @ 2008-12-19 8:59 UTC (permalink / raw)
To: Ankit Jain, Al Viro, mfasheh, linux-kernel, joel.becker,
Christoph Hellwig, xfs-ma
On Fri, Dec 19, 2008 at 03:37:44PM +1100, Dave Chinner wrote:
> XFS_IOC_RESVSP supports invisible I/O, and that means
> XFS_IOC_RESVSP needs to be passed through to vfs_ioctl()
> to vector to XFS to handle.
When the current XFS git tree gets merged to mainline before this
patch. invisible I/O handling is now FMODE_NOCMTIME in file->f_flags
which this patch will pass through to the filesystem. We just need
to chage xfs_vn_fallocate ot honour it.
^ permalink raw reply [flat|nested] 3+ messages in thread
end of thread, other threads:[~2008-12-19 8:59 UTC | newest]
Thread overview: 3+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2008-12-18 21:21 [PATCH v2] fs: Add new pre-allocation ioctls to vfs for compatibility with legacy xfs ioctls Ankit Jain
2008-12-19 4:37 ` Dave Chinner
2008-12-19 8:59 ` Christoph Hellwig
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).