* [PATCH] add a FMODE flag to make XFS invisible I/O less hacky
@ 2008-11-28 11:24 Christoph Hellwig
2008-11-28 11:30 ` Al Viro
2008-11-28 22:58 ` Andreas Dilger
0 siblings, 2 replies; 7+ messages in thread
From: Christoph Hellwig @ 2008-11-28 11:24 UTC (permalink / raw)
To: viro; +Cc: linux-fsdevel
XFS has a mode called invisble I/O that doesn't update any of the
timestamps. It's used for HSM-style applications and exposed through
the nasty open by handle ioctl.
Instead of doing directly assignment of file operations that set an
internal flag for it add a new FMODE_INVISIBLE flag that we can check
in the normal file operations.
Signed-off-by: Christoph Hellwig <hch@lst.de>
--
fs/xfs/linux-2.6/xfs_file.c | 134 +++++++------------------------------------
fs/xfs/linux-2.6/xfs_ioctl.c | 3
fs/xfs/linux-2.6/xfs_iops.h | 1
include/linux/fs.h | 2
4 files changed, 28 insertions(+), 112 deletions(-)
Index: linux-2.6/fs/xfs/linux-2.6/xfs_ioctl.c
===================================================================
--- linux-2.6.orig/fs/xfs/linux-2.6/xfs_ioctl.c 2008-11-12 00:59:25.000000000 +0530
+++ linux-2.6/fs/xfs/linux-2.6/xfs_ioctl.c 2008-11-28 16:11:30.000000000 +0530
@@ -326,10 +326,11 @@ xfs_open_by_handle(
put_unused_fd(new_fd);
return -XFS_ERROR(-PTR_ERR(filp));
}
+
if (inode->i_mode & S_IFREG) {
/* invisible operation should not change atime */
filp->f_flags |= O_NOATIME;
- filp->f_op = &xfs_invis_file_operations;
+ filp->f_mode |= FMODE_INVISIBLE;
}
fd_install(new_fd, filp);
Index: linux-2.6/include/linux/fs.h
===================================================================
--- linux-2.6.orig/include/linux/fs.h 2008-11-28 16:04:52.000000000 +0530
+++ linux-2.6/include/linux/fs.h 2008-11-28 16:04:53.000000000 +0530
@@ -81,6 +81,8 @@ extern int dir_notify_enable;
/* File is opened using open(.., 3, ..) and is writeable only for ioctls
(specialy hack for floppy.c) */
#define FMODE_WRITE_IOCTL ((__force fmode_t)128)
+/* Invisible I/O - special hack for XFS ioctls */
+#define FMODE_INVISIBLE ((__force fmode_t)256)
#define RW_MASK 1
#define RWA_MASK 2
Index: linux-2.6/fs/xfs/linux-2.6/xfs_file.c
===================================================================
--- linux-2.6.orig/fs/xfs/linux-2.6/xfs_file.c 2008-11-28 16:04:59.000000000 +0530
+++ linux-2.6/fs/xfs/linux-2.6/xfs_file.c 2008-11-28 16:08:27.000000000 +0530
@@ -44,81 +44,45 @@
static struct vm_operations_struct xfs_file_vm_ops;
-STATIC_INLINE ssize_t
-__xfs_file_read(
+STATIC ssize_t
+xfs_file_aio_read(
struct kiocb *iocb,
const struct iovec *iov,
unsigned long nr_segs,
- int ioflags,
loff_t pos)
{
struct file *file = iocb->ki_filp;
+ int ioflags = IO_ISAIO;
BUG_ON(iocb->ki_pos != pos);
if (unlikely(file->f_flags & O_DIRECT))
ioflags |= IO_ISDIRECT;
+ if (file->f_mode |= FMODE_INVISIBLE)
+ ioflags |= IO_INVIS;
return xfs_read(XFS_I(file->f_path.dentry->d_inode), iocb, iov,
nr_segs, &iocb->ki_pos, ioflags);
}
STATIC ssize_t
-xfs_file_aio_read(
- struct kiocb *iocb,
- const struct iovec *iov,
- unsigned long nr_segs,
- loff_t pos)
-{
- return __xfs_file_read(iocb, iov, nr_segs, IO_ISAIO, pos);
-}
-
-STATIC ssize_t
-xfs_file_aio_read_invis(
- struct kiocb *iocb,
- const struct iovec *iov,
- unsigned long nr_segs,
- loff_t pos)
-{
- return __xfs_file_read(iocb, iov, nr_segs, IO_ISAIO|IO_INVIS, pos);
-}
-
-STATIC_INLINE ssize_t
-__xfs_file_write(
+xfs_file_aio_write(
struct kiocb *iocb,
const struct iovec *iov,
unsigned long nr_segs,
- int ioflags,
loff_t pos)
{
- struct file *file = iocb->ki_filp;
+ struct file *file = iocb->ki_filp;
+ int ioflags = IO_ISAIO;
BUG_ON(iocb->ki_pos != pos);
if (unlikely(file->f_flags & O_DIRECT))
ioflags |= IO_ISDIRECT;
+ if (file->f_mode |= FMODE_INVISIBLE)
+ ioflags |= IO_INVIS;
return xfs_write(XFS_I(file->f_mapping->host), iocb, iov, nr_segs,
&iocb->ki_pos, ioflags);
}
STATIC ssize_t
-xfs_file_aio_write(
- struct kiocb *iocb,
- const struct iovec *iov,
- unsigned long nr_segs,
- loff_t pos)
-{
- return __xfs_file_write(iocb, iov, nr_segs, IO_ISAIO, pos);
-}
-
-STATIC ssize_t
-xfs_file_aio_write_invis(
- struct kiocb *iocb,
- const struct iovec *iov,
- unsigned long nr_segs,
- loff_t pos)
-{
- return __xfs_file_write(iocb, iov, nr_segs, IO_ISAIO|IO_INVIS, pos);
-}
-
-STATIC ssize_t
xfs_file_splice_read(
struct file *infilp,
loff_t *ppos,
@@ -126,20 +90,13 @@ xfs_file_splice_read(
size_t len,
unsigned int flags)
{
- return xfs_splice_read(XFS_I(infilp->f_path.dentry->d_inode),
- infilp, ppos, pipe, len, flags, 0);
-}
+ int ioflags = 0;
+
+ if (infilp->f_mode |= FMODE_INVISIBLE)
+ ioflags |= IO_INVIS;
-STATIC ssize_t
-xfs_file_splice_read_invis(
- struct file *infilp,
- loff_t *ppos,
- struct pipe_inode_info *pipe,
- size_t len,
- unsigned int flags)
-{
return xfs_splice_read(XFS_I(infilp->f_path.dentry->d_inode),
- infilp, ppos, pipe, len, flags, IO_INVIS);
+ infilp, ppos, pipe, len, flags, ioflags);
}
STATIC ssize_t
@@ -150,20 +107,13 @@ xfs_file_splice_write(
size_t len,
unsigned int flags)
{
- return xfs_splice_write(XFS_I(outfilp->f_path.dentry->d_inode),
- pipe, outfilp, ppos, len, flags, 0);
-}
+ int ioflags = 0;
+
+ if (outfilp->f_mode |= FMODE_INVISIBLE)
+ ioflags |= IO_INVIS;
-STATIC ssize_t
-xfs_file_splice_write_invis(
- struct pipe_inode_info *pipe,
- struct file *outfilp,
- loff_t *ppos,
- size_t len,
- unsigned int flags)
-{
return xfs_splice_write(XFS_I(outfilp->f_path.dentry->d_inode),
- pipe, outfilp, ppos, len, flags, IO_INVIS);
+ pipe, outfilp, ppos, len, flags, ioflags);
}
STATIC int
@@ -256,29 +206,12 @@ xfs_file_ioctl(
{
int error;
struct inode *inode = filp->f_path.dentry->d_inode;
+ int ioflags = 0;
- error = xfs_ioctl(XFS_I(inode), filp, 0, cmd, (void __user *)p);
- xfs_iflags_set(XFS_I(inode), XFS_IMODIFIED);
+ if (filp->f_mode |= FMODE_INVISIBLE)
+ ioflags |= IO_INVIS;
- /* NOTE: some of the ioctl's return positive #'s as a
- * byte count indicating success, such as
- * readlink_by_handle. So we don't "sign flip"
- * like most other routines. This means true
- * errors need to be returned as a negative value.
- */
- return error;
-}
-
-STATIC long
-xfs_file_ioctl_invis(
- struct file *filp,
- unsigned int cmd,
- unsigned long p)
-{
- int error;
- struct inode *inode = filp->f_path.dentry->d_inode;
-
- error = xfs_ioctl(XFS_I(inode), filp, IO_INVIS, cmd, (void __user *)p);
+ error = xfs_ioctl(XFS_I(inode), filp, ioflags, cmd, (void __user *)p);
xfs_iflags_set(XFS_I(inode), XFS_IMODIFIED);
/* NOTE: some of the ioctl's return positive #'s as a
@@ -325,25 +258,6 @@ const struct file_operations xfs_file_op
#endif
};
-const struct file_operations xfs_invis_file_operations = {
- .llseek = generic_file_llseek,
- .read = do_sync_read,
- .write = do_sync_write,
- .aio_read = xfs_file_aio_read_invis,
- .aio_write = xfs_file_aio_write_invis,
- .splice_read = xfs_file_splice_read_invis,
- .splice_write = xfs_file_splice_write_invis,
- .unlocked_ioctl = xfs_file_ioctl_invis,
-#ifdef CONFIG_COMPAT
- .compat_ioctl = xfs_file_compat_invis_ioctl,
-#endif
- .mmap = xfs_file_mmap,
- .open = xfs_file_open,
- .release = xfs_file_release,
- .fsync = xfs_file_fsync,
-};
-
-
const struct file_operations xfs_dir_file_operations = {
.read = generic_read_dir,
.readdir = xfs_file_readdir,
Index: linux-2.6/fs/xfs/linux-2.6/xfs_iops.h
===================================================================
--- linux-2.6.orig/fs/xfs/linux-2.6/xfs_iops.h 2008-11-28 16:08:37.000000000 +0530
+++ linux-2.6/fs/xfs/linux-2.6/xfs_iops.h 2008-11-28 16:08:42.000000000 +0530
@@ -22,7 +22,6 @@ struct xfs_inode;
extern const struct file_operations xfs_file_operations;
extern const struct file_operations xfs_dir_file_operations;
-extern const struct file_operations xfs_invis_file_operations;
extern ssize_t xfs_vn_listxattr(struct dentry *, char *data, size_t size);
^ permalink raw reply [flat|nested] 7+ messages in thread
* Re: [PATCH] add a FMODE flag to make XFS invisible I/O less hacky
2008-11-28 11:24 [PATCH] add a FMODE flag to make XFS invisible I/O less hacky Christoph Hellwig
@ 2008-11-28 11:30 ` Al Viro
2008-11-30 9:16 ` Christoph Hellwig
2008-11-28 22:58 ` Andreas Dilger
1 sibling, 1 reply; 7+ messages in thread
From: Al Viro @ 2008-11-28 11:30 UTC (permalink / raw)
To: Christoph Hellwig; +Cc: linux-fsdevel
On Fri, Nov 28, 2008 at 12:24:02PM +0100, Christoph Hellwig wrote:
> XFS has a mode called invisble I/O that doesn't update any of the
> timestamps. It's used for HSM-style applications and exposed through
> the nasty open by handle ioctl.
>
> Instead of doing directly assignment of file operations that set an
> internal flag for it add a new FMODE_INVISIBLE flag that we can check
> in the normal file operations.
Seeing that it's similar to O_NOATIME, why not do it in O_... space?
^ permalink raw reply [flat|nested] 7+ messages in thread
* Re: [PATCH] add a FMODE flag to make XFS invisible I/O less hacky
2008-11-28 11:24 [PATCH] add a FMODE flag to make XFS invisible I/O less hacky Christoph Hellwig
2008-11-28 11:30 ` Al Viro
@ 2008-11-28 22:58 ` Andreas Dilger
2008-11-30 9:18 ` Christoph Hellwig
1 sibling, 1 reply; 7+ messages in thread
From: Andreas Dilger @ 2008-11-28 22:58 UTC (permalink / raw)
To: Christoph Hellwig; +Cc: viro, linux-fsdevel
On Nov 28, 2008 12:24 +0100, Christoph Hellwig wrote:
> XFS has a mode called invisble I/O that doesn't update any of the
> timestamps. It's used for HSM-style applications and exposed through
> the nasty open by handle ioctl.
>
> Instead of doing directly assignment of file operations that set an
> internal flag for it add a new FMODE_INVISIBLE flag that we can check
> in the normal file operations.
Why not call this "FMODE_NOCMTIME" similar to the inode flag "S_NOCMTIME"
that already exists, and . That makes it more clear what is being done,
instead of calling it "INVISIBLE".
It should also not be possible to skip ctime updates for non-root users,
as that provides some forensic trail if files have been modified by users.
Not sure if that is relevant here though (it looks like this is only used
internally), but worth mentioning in any case.
Cheers, Andreas
--
Andreas Dilger
Sr. Staff Engineer, Lustre Group
Sun Microsystems of Canada, Inc.
^ permalink raw reply [flat|nested] 7+ messages in thread
* Re: [PATCH] add a FMODE flag to make XFS invisible I/O less hacky
2008-11-28 11:30 ` Al Viro
@ 2008-11-30 9:16 ` Christoph Hellwig
2008-12-02 10:19 ` Christoph Hellwig
0 siblings, 1 reply; 7+ messages in thread
From: Christoph Hellwig @ 2008-11-30 9:16 UTC (permalink / raw)
To: Al Viro; +Cc: Christoph Hellwig, linux-fsdevel
On Fri, Nov 28, 2008 at 11:30:52AM +0000, Al Viro wrote:
> On Fri, Nov 28, 2008 at 12:24:02PM +0100, Christoph Hellwig wrote:
> > XFS has a mode called invisble I/O that doesn't update any of the
> > timestamps. It's used for HSM-style applications and exposed through
> > the nasty open by handle ioctl.
> >
> > Instead of doing directly assignment of file operations that set an
> > internal flag for it add a new FMODE_INVISIBLE flag that we can check
> > in the normal file operations.
>
> Seeing that it's similar to O_NOATIME, why not do it in O_... space?
For now I just want to get rid of the horrible hack in XFS. Adding this
as a user-visible feature might be a good idea that those who need it
can submit.
^ permalink raw reply [flat|nested] 7+ messages in thread
* Re: [PATCH] add a FMODE flag to make XFS invisible I/O less hacky
2008-11-28 22:58 ` Andreas Dilger
@ 2008-11-30 9:18 ` Christoph Hellwig
0 siblings, 0 replies; 7+ messages in thread
From: Christoph Hellwig @ 2008-11-30 9:18 UTC (permalink / raw)
To: Andreas Dilger; +Cc: Christoph Hellwig, viro, linux-fsdevel
On Fri, Nov 28, 2008 at 03:58:42PM -0700, Andreas Dilger wrote:
> On Nov 28, 2008 12:24 +0100, Christoph Hellwig wrote:
> > XFS has a mode called invisble I/O that doesn't update any of the
> > timestamps. It's used for HSM-style applications and exposed through
> > the nasty open by handle ioctl.
> >
> > Instead of doing directly assignment of file operations that set an
> > internal flag for it add a new FMODE_INVISIBLE flag that we can check
> > in the normal file operations.
>
> Why not call this "FMODE_NOCMTIME" similar to the inode flag "S_NOCMTIME"
> that already exists, and . That makes it more clear what is being done,
> instead of calling it "INVISIBLE".
The flag is called invisible inside XFS because it also has the
implication of not sending HSM notification when you have dmapi enabled.
Doesn't matter too much on mainline, but for now I'd keep the semantics
the same as the old one, at least as long as it's not exposed to
userland (which Al's suggestions of doing it in the O_ namespace would)
> It should also not be possible to skip ctime updates for non-root users,
> as that provides some forensic trail if files have been modified by users.
> Not sure if that is relevant here though (it looks like this is only used
> internally), but worth mentioning in any case.
Yes, the open by handle ioctl which sets this flag requires CAP_SYS_ADMIN.
^ permalink raw reply [flat|nested] 7+ messages in thread
* Re: [PATCH] add a FMODE flag to make XFS invisible I/O less hacky
2008-11-30 9:16 ` Christoph Hellwig
@ 2008-12-02 10:19 ` Christoph Hellwig
0 siblings, 0 replies; 7+ messages in thread
From: Christoph Hellwig @ 2008-12-02 10:19 UTC (permalink / raw)
To: Al Viro; +Cc: Christoph Hellwig, linux-fsdevel
On Sun, Nov 30, 2008 at 10:16:04AM +0100, Christoph Hellwig wrote:
> On Fri, Nov 28, 2008 at 11:30:52AM +0000, Al Viro wrote:
> > On Fri, Nov 28, 2008 at 12:24:02PM +0100, Christoph Hellwig wrote:
> > > XFS has a mode called invisble I/O that doesn't update any of the
> > > timestamps. It's used for HSM-style applications and exposed through
> > > the nasty open by handle ioctl.
> > >
> > > Instead of doing directly assignment of file operations that set an
> > > internal flag for it add a new FMODE_INVISIBLE flag that we can check
> > > in the normal file operations.
> >
> > Seeing that it's similar to O_NOATIME, why not do it in O_... space?
>
> For now I just want to get rid of the horrible hack in XFS. Adding this
> as a user-visible feature might be a good idea that those who need it
> can submit.
Taking about that submission, any chance I could just put in this with a
flag allocated high enough to not clash in the XFS tree and then sort
out things once the vfs and xfs trees get merged for 2.6.29? That's
help making progress on the XFS side a lot, as there would be tons of
merge conflicts there othwerwise. (compat_ioctl handling just got a big
rework, touch just 2/3s of the hunks of this patch)
^ permalink raw reply [flat|nested] 7+ messages in thread
* [PATCH] add a FMODE flag to make XFS invisible I/O less hacky
@ 2008-12-03 17:45 Christoph Hellwig
0 siblings, 0 replies; 7+ messages in thread
From: Christoph Hellwig @ 2008-12-03 17:45 UTC (permalink / raw)
To: xfs; +Cc: viro, linux-fsdevel
XFS has a mode called invisble I/O that doesn't update any of the
timestamps. It's used for HSM-style applications and exposed through
the nasty open by handle ioctl.
Instead of doing directly assignment of file operations that set an
internal flag for it add a new FMODE_NOCMTIME flag that we can check
in the normal file operations.
Note that I'd like to get this into 2.6.29 via the XFS tree as there
are a lot changes in XFS that would cause conflicts otherwise.
For 2.6.30 I'll plan turning it into a proper O_ flag available via
open(2), but for now I just want to sort out the XFS issues.
Signed-off-by: Christoph Hellwig <hch@lst.de>
Index: xfs/fs/xfs/linux-2.6/xfs_ioctl32.c
===================================================================
--- xfs.orig/fs/xfs/linux-2.6/xfs_ioctl32.c 2008-12-03 18:30:14.000000000 +0100
+++ xfs/fs/xfs/linux-2.6/xfs_ioctl32.c 2008-12-03 18:30:34.000000000 +0100
@@ -599,19 +599,24 @@ out:
return error;
}
-STATIC long
-xfs_compat_ioctl(
- xfs_inode_t *ip,
- struct file *filp,
- int ioflags,
- unsigned cmd,
- void __user *arg)
+long
+xfs_file_compat_ioctl(
+ struct file *filp,
+ unsigned cmd,
+ unsigned long p)
{
- struct inode *inode = filp->f_path.dentry->d_inode;
- xfs_mount_t *mp = ip->i_mount;
- int error;
+ struct inode *inode = filp->f_path.dentry->d_inode;
+ struct xfs_inode *ip = XFS_I(inode);
+ struct xfs_mount *mp = ip->i_mount;
+ void __user *arg = (void __user *)p;
+ int ioflags = 0;
+ int error;
+
+ if (filp->f_mode & FMODE_NOCMTIME)
+ ioflags |= IO_INVIS;
+
+ xfs_itrace_entry(ip);
- xfs_itrace_entry(XFS_I(inode));
switch (cmd) {
/* No size or alignment issues on any arch */
case XFS_IOC_DIOINFO:
@@ -632,7 +637,7 @@ xfs_compat_ioctl(
case XFS_IOC_GOINGDOWN:
case XFS_IOC_ERROR_INJECTION:
case XFS_IOC_ERROR_CLEARALL:
- return xfs_ioctl(ip, filp, ioflags, cmd, arg);
+ return xfs_file_ioctl(filp, cmd, p);
#ifndef BROKEN_X86_ALIGNMENT
/* These are handled fine if no alignment issues */
case XFS_IOC_ALLOCSP:
@@ -646,7 +651,7 @@ xfs_compat_ioctl(
case XFS_IOC_FSGEOMETRY_V1:
case XFS_IOC_FSGROWFSDATA:
case XFS_IOC_FSGROWFSRT:
- return xfs_ioctl(ip, filp, ioflags, cmd, arg);
+ return xfs_file_ioctl(filp, cmd, p);
#else
case XFS_IOC_ALLOCSP_32:
case XFS_IOC_FREESP_32:
@@ -687,7 +692,7 @@ xfs_compat_ioctl(
case XFS_IOC_SETXFLAGS_32:
case XFS_IOC_GETVERSION_32:
cmd = _NATIVE_IOC(cmd, long);
- return xfs_ioctl(ip, filp, ioflags, cmd, arg);
+ return xfs_file_ioctl(filp, cmd, p);
case XFS_IOC_SWAPEXT: {
struct xfs_swapext sxp;
struct compat_xfs_swapext __user *sxu = arg;
@@ -738,26 +743,3 @@ xfs_compat_ioctl(
return -XFS_ERROR(ENOIOCTLCMD);
}
}
-
-long
-xfs_file_compat_ioctl(
- struct file *filp,
- unsigned int cmd,
- unsigned long p)
-{
- struct inode *inode = filp->f_path.dentry->d_inode;
-
- return xfs_compat_ioctl(XFS_I(inode), filp, 0, cmd, (void __user *)p);
-}
-
-long
-xfs_file_compat_invis_ioctl(
- struct file *filp,
- unsigned int cmd,
- unsigned long p)
-{
- struct inode *inode = filp->f_path.dentry->d_inode;
-
- return xfs_compat_ioctl(XFS_I(inode), filp, IO_INVIS, cmd,
- (void __user *)p);
-}
Index: xfs/fs/xfs/linux-2.6/xfs_file.c
===================================================================
--- xfs.orig/fs/xfs/linux-2.6/xfs_file.c 2008-12-03 18:30:14.000000000 +0100
+++ xfs/fs/xfs/linux-2.6/xfs_file.c 2008-12-03 18:30:34.000000000 +0100
@@ -45,81 +45,45 @@
static struct vm_operations_struct xfs_file_vm_ops;
-STATIC_INLINE ssize_t
-__xfs_file_read(
+STATIC ssize_t
+xfs_file_aio_read(
struct kiocb *iocb,
const struct iovec *iov,
unsigned long nr_segs,
- int ioflags,
loff_t pos)
{
struct file *file = iocb->ki_filp;
+ int ioflags = IO_ISAIO;
BUG_ON(iocb->ki_pos != pos);
if (unlikely(file->f_flags & O_DIRECT))
ioflags |= IO_ISDIRECT;
+ if (file->f_mode & FMODE_NOCMTIME)
+ ioflags |= IO_INVIS;
return xfs_read(XFS_I(file->f_path.dentry->d_inode), iocb, iov,
nr_segs, &iocb->ki_pos, ioflags);
}
STATIC ssize_t
-xfs_file_aio_read(
- struct kiocb *iocb,
- const struct iovec *iov,
- unsigned long nr_segs,
- loff_t pos)
-{
- return __xfs_file_read(iocb, iov, nr_segs, IO_ISAIO, pos);
-}
-
-STATIC ssize_t
-xfs_file_aio_read_invis(
- struct kiocb *iocb,
- const struct iovec *iov,
- unsigned long nr_segs,
- loff_t pos)
-{
- return __xfs_file_read(iocb, iov, nr_segs, IO_ISAIO|IO_INVIS, pos);
-}
-
-STATIC_INLINE ssize_t
-__xfs_file_write(
+xfs_file_aio_write(
struct kiocb *iocb,
const struct iovec *iov,
unsigned long nr_segs,
- int ioflags,
loff_t pos)
{
- struct file *file = iocb->ki_filp;
+ struct file *file = iocb->ki_filp;
+ int ioflags = IO_ISAIO;
BUG_ON(iocb->ki_pos != pos);
if (unlikely(file->f_flags & O_DIRECT))
ioflags |= IO_ISDIRECT;
+ if (file->f_mode & FMODE_NOCMTIME)
+ ioflags |= IO_INVIS;
return xfs_write(XFS_I(file->f_mapping->host), iocb, iov, nr_segs,
&iocb->ki_pos, ioflags);
}
STATIC ssize_t
-xfs_file_aio_write(
- struct kiocb *iocb,
- const struct iovec *iov,
- unsigned long nr_segs,
- loff_t pos)
-{
- return __xfs_file_write(iocb, iov, nr_segs, IO_ISAIO, pos);
-}
-
-STATIC ssize_t
-xfs_file_aio_write_invis(
- struct kiocb *iocb,
- const struct iovec *iov,
- unsigned long nr_segs,
- loff_t pos)
-{
- return __xfs_file_write(iocb, iov, nr_segs, IO_ISAIO|IO_INVIS, pos);
-}
-
-STATIC ssize_t
xfs_file_splice_read(
struct file *infilp,
loff_t *ppos,
@@ -127,20 +91,13 @@ xfs_file_splice_read(
size_t len,
unsigned int flags)
{
- return xfs_splice_read(XFS_I(infilp->f_path.dentry->d_inode),
- infilp, ppos, pipe, len, flags, 0);
-}
+ int ioflags = 0;
+
+ if (infilp->f_mode & FMODE_NOCMTIME)
+ ioflags |= IO_INVIS;
-STATIC ssize_t
-xfs_file_splice_read_invis(
- struct file *infilp,
- loff_t *ppos,
- struct pipe_inode_info *pipe,
- size_t len,
- unsigned int flags)
-{
return xfs_splice_read(XFS_I(infilp->f_path.dentry->d_inode),
- infilp, ppos, pipe, len, flags, IO_INVIS);
+ infilp, ppos, pipe, len, flags, ioflags);
}
STATIC ssize_t
@@ -151,20 +108,13 @@ xfs_file_splice_write(
size_t len,
unsigned int flags)
{
- return xfs_splice_write(XFS_I(outfilp->f_path.dentry->d_inode),
- pipe, outfilp, ppos, len, flags, 0);
-}
+ int ioflags = 0;
+
+ if (outfilp->f_mode & FMODE_NOCMTIME)
+ ioflags |= IO_INVIS;
-STATIC ssize_t
-xfs_file_splice_write_invis(
- struct pipe_inode_info *pipe,
- struct file *outfilp,
- loff_t *ppos,
- size_t len,
- unsigned int flags)
-{
return xfs_splice_write(XFS_I(outfilp->f_path.dentry->d_inode),
- pipe, outfilp, ppos, len, flags, IO_INVIS);
+ pipe, outfilp, ppos, len, flags, ioflags);
}
STATIC int
@@ -275,42 +225,6 @@ xfs_file_mmap(
return 0;
}
-STATIC long
-xfs_file_ioctl(
- struct file *filp,
- unsigned int cmd,
- unsigned long p)
-{
- struct inode *inode = filp->f_path.dentry->d_inode;
-
-
- /* NOTE: some of the ioctl's return positive #'s as a
- * byte count indicating success, such as
- * readlink_by_handle. So we don't "sign flip"
- * like most other routines. This means true
- * errors need to be returned as a negative value.
- */
- return xfs_ioctl(XFS_I(inode), filp, 0, cmd, (void __user *)p);
-}
-
-STATIC long
-xfs_file_ioctl_invis(
- struct file *filp,
- unsigned int cmd,
- unsigned long p)
-{
- struct inode *inode = filp->f_path.dentry->d_inode;
-
-
- /* NOTE: some of the ioctl's return positive #'s as a
- * byte count indicating success, such as
- * readlink_by_handle. So we don't "sign flip"
- * like most other routines. This means true
- * errors need to be returned as a negative value.
- */
- return xfs_ioctl(XFS_I(inode), filp, IO_INVIS, cmd, (void __user *)p);
-}
-
/*
* mmap()d file has taken write protection fault and is being made
* writable. We can set the page state up correctly for a writable
@@ -346,25 +260,6 @@ const struct file_operations xfs_file_op
#endif
};
-const struct file_operations xfs_invis_file_operations = {
- .llseek = generic_file_llseek,
- .read = do_sync_read,
- .write = do_sync_write,
- .aio_read = xfs_file_aio_read_invis,
- .aio_write = xfs_file_aio_write_invis,
- .splice_read = xfs_file_splice_read_invis,
- .splice_write = xfs_file_splice_write_invis,
- .unlocked_ioctl = xfs_file_ioctl_invis,
-#ifdef CONFIG_COMPAT
- .compat_ioctl = xfs_file_compat_invis_ioctl,
-#endif
- .mmap = xfs_file_mmap,
- .open = xfs_file_open,
- .release = xfs_file_release,
- .fsync = xfs_file_fsync,
-};
-
-
const struct file_operations xfs_dir_file_operations = {
.open = xfs_dir_open,
.read = generic_read_dir,
Index: xfs/fs/xfs/linux-2.6/xfs_ioctl.c
===================================================================
--- xfs.orig/fs/xfs/linux-2.6/xfs_ioctl.c 2008-12-03 18:30:14.000000000 +0100
+++ xfs/fs/xfs/linux-2.6/xfs_ioctl.c 2008-12-03 18:30:34.000000000 +0100
@@ -319,10 +319,11 @@ xfs_open_by_handle(
put_unused_fd(new_fd);
return -XFS_ERROR(-PTR_ERR(filp));
}
+
if (inode->i_mode & S_IFREG) {
/* invisible operation should not change atime */
filp->f_flags |= O_NOATIME;
- filp->f_op = &xfs_invis_file_operations;
+ filp->f_mode |= FMODE_NOCMTIME;
}
fd_install(new_fd, filp);
@@ -1328,21 +1329,31 @@ xfs_ioc_getbmapx(
return 0;
}
-int
-xfs_ioctl(
- xfs_inode_t *ip,
+/*
+ * Note: some of the ioctl's return positive numbers as a
+ * byte count indicating success, such as readlink_by_handle.
+ * So we don't "sign flip" like most other routines. This means
+ * true errors need to be returned as a negative value.
+ */
+long
+xfs_file_ioctl(
struct file *filp,
- int ioflags,
unsigned int cmd,
- void __user *arg)
+ unsigned long p)
{
struct inode *inode = filp->f_path.dentry->d_inode;
- xfs_mount_t *mp = ip->i_mount;
+ struct xfs_inode *ip = XFS_I(inode);
+ struct xfs_mount *mp = ip->i_mount;
+ void __user *arg = (void __user *)p;
+ int ioflags = 0;
int error;
- xfs_itrace_entry(XFS_I(inode));
- switch (cmd) {
+ if (filp->f_mode & FMODE_NOCMTIME)
+ ioflags |= IO_INVIS;
+ xfs_itrace_entry(ip);
+
+ switch (cmd) {
case XFS_IOC_ALLOCSP:
case XFS_IOC_FREESP:
case XFS_IOC_RESVSP:
Index: xfs/fs/xfs/linux-2.6/xfs_iops.h
===================================================================
--- xfs.orig/fs/xfs/linux-2.6/xfs_iops.h 2008-12-03 18:30:14.000000000 +0100
+++ xfs/fs/xfs/linux-2.6/xfs_iops.h 2008-12-03 18:30:34.000000000 +0100
@@ -22,7 +22,6 @@ struct xfs_inode;
extern const struct file_operations xfs_file_operations;
extern const struct file_operations xfs_dir_file_operations;
-extern const struct file_operations xfs_invis_file_operations;
extern ssize_t xfs_vn_listxattr(struct dentry *, char *data, size_t size);
Index: xfs/include/linux/fs.h
===================================================================
--- xfs.orig/include/linux/fs.h 2008-12-03 18:30:14.000000000 +0100
+++ xfs/include/linux/fs.h 2008-12-03 18:31:58.000000000 +0100
@@ -81,6 +81,14 @@ extern int dir_notify_enable;
#define FMODE_WRITE_IOCTL ((__force fmode_t)128)
#define FMODE_NDELAY_NOW ((__force fmode_t)256)
+/*
+ * Don't update ctime and mtime.
+ *
+ * Currently a special hack for the XFS open_by_handle ioctl, but we'll
+ * hopefully graduate it to a proper O_CMTIME flag supported by open(2) soon.
+ */
+#define FMODE_NOCMTIME ((__force fmode_t)2048)
+
#define RW_MASK 1
#define RWA_MASK 2
#define READ 0
Index: xfs/fs/xfs/linux-2.6/xfs_ioctl.h
===================================================================
--- xfs.orig/fs/xfs/linux-2.6/xfs_ioctl.h 2008-12-03 18:30:14.000000000 +0100
+++ xfs/fs/xfs/linux-2.6/xfs_ioctl.h 2008-12-03 18:30:34.000000000 +0100
@@ -68,13 +68,13 @@ xfs_attrmulti_attr_remove(
__uint32_t flags);
extern long
-xfs_file_compat_ioctl(
- struct file *file,
+xfs_file_ioctl(
+ struct file *filp,
unsigned int cmd,
- unsigned long arg);
+ unsigned long p);
extern long
-xfs_file_compat_ioctl_invis(
+xfs_file_compat_ioctl(
struct file *file,
unsigned int cmd,
unsigned long arg);
Index: xfs/fs/xfs/xfs_vnodeops.h
===================================================================
--- xfs.orig/fs/xfs/xfs_vnodeops.h 2008-12-03 18:30:14.000000000 +0100
+++ xfs/fs/xfs/xfs_vnodeops.h 2008-12-03 18:30:34.000000000 +0100
@@ -53,8 +53,6 @@ int xfs_attr_set(struct xfs_inode *dp, c
int xfs_attr_remove(struct xfs_inode *dp, const char *name, int flags);
int xfs_attr_list(struct xfs_inode *dp, char *buffer, int bufsize,
int flags, struct attrlist_cursor_kern *cursor);
-int xfs_ioctl(struct xfs_inode *ip, struct file *filp,
- int ioflags, unsigned int cmd, void __user *arg);
ssize_t xfs_read(struct xfs_inode *ip, struct kiocb *iocb,
const struct iovec *iovp, unsigned int segs,
loff_t *offset, int ioflags);
^ permalink raw reply [flat|nested] 7+ messages in thread
end of thread, other threads:[~2008-12-03 17:45 UTC | newest]
Thread overview: 7+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2008-11-28 11:24 [PATCH] add a FMODE flag to make XFS invisible I/O less hacky Christoph Hellwig
2008-11-28 11:30 ` Al Viro
2008-11-30 9:16 ` Christoph Hellwig
2008-12-02 10:19 ` Christoph Hellwig
2008-11-28 22:58 ` Andreas Dilger
2008-11-30 9:18 ` Christoph Hellwig
-- strict thread matches above, loose matches on Subject: below --
2008-12-03 17:45 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).