2005-04-17 02:20:36 +04:00
/*
2005-11-02 06:58:39 +03:00
* Copyright ( c ) 2000 - 2005 Silicon Graphics , Inc .
* All Rights Reserved .
2005-04-17 02:20:36 +04:00
*
2005-11-02 06:58:39 +03:00
* This program is free software ; you can redistribute it and / or
* modify it under the terms of the GNU General Public License as
2005-04-17 02:20:36 +04:00
* published by the Free Software Foundation .
*
2005-11-02 06:58:39 +03:00
* This program is distributed in the hope that it would be useful ,
* but WITHOUT ANY WARRANTY ; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE . See the
* GNU General Public License for more details .
2005-04-17 02:20:36 +04:00
*
2005-11-02 06:58:39 +03:00
* You should have received a copy of the GNU General Public License
* along with this program ; if not , write the Free Software Foundation ,
* Inc . , 51 Franklin St , Fifth Floor , Boston , MA 02110 - 1301 USA
2005-04-17 02:20:36 +04:00
*/
# include "xfs.h"
2005-11-02 06:38:42 +03:00
# include "xfs_bit.h"
2005-04-17 02:20:36 +04:00
# include "xfs_log.h"
2005-11-02 06:38:42 +03:00
# include "xfs_inum.h"
2005-04-17 02:20:36 +04:00
# include "xfs_sb.h"
2005-11-02 06:38:42 +03:00
# include "xfs_ag.h"
2005-04-17 02:20:36 +04:00
# include "xfs_dir.h"
# include "xfs_dir2.h"
# include "xfs_trans.h"
# include "xfs_dmapi.h"
# include "xfs_mount.h"
# include "xfs_bmap_btree.h"
# include "xfs_alloc_btree.h"
# include "xfs_ialloc_btree.h"
# include "xfs_alloc.h"
# include "xfs_btree.h"
# include "xfs_attr_sf.h"
# include "xfs_dir_sf.h"
# include "xfs_dir2_sf.h"
# include "xfs_dinode.h"
# include "xfs_inode.h"
# include "xfs_error.h"
# include "xfs_rw.h"
# include "xfs_ioctl32.h"
# include <linux/dcache.h>
# include <linux/smp_lock.h>
2006-03-14 06:00:35 +03:00
static struct vm_operations_struct xfs_file_vm_ops ;
2005-06-21 08:07:45 +04:00
# ifdef CONFIG_XFS_DMAPI
2006-03-14 06:00:35 +03:00
static struct vm_operations_struct xfs_dmapi_file_vm_ops ;
2005-06-21 08:07:45 +04:00
# endif
2005-04-17 02:20:36 +04:00
STATIC inline ssize_t
2006-03-14 06:00:35 +03:00
__xfs_file_read (
2005-04-17 02:20:36 +04:00
struct kiocb * iocb ,
char __user * buf ,
int ioflags ,
size_t count ,
loff_t pos )
{
struct iovec iov = { buf , count } ;
struct file * file = iocb - > ki_filp ;
2006-03-17 09:25:36 +03:00
vnode_t * vp = vn_from_inode ( file - > f_dentry - > d_inode ) ;
2005-04-17 02:20:36 +04:00
ssize_t rval ;
BUG_ON ( iocb - > ki_pos ! = pos ) ;
if ( unlikely ( file - > f_flags & O_DIRECT ) )
ioflags | = IO_ISDIRECT ;
VOP_READ ( vp , iocb , & iov , 1 , & iocb - > ki_pos , ioflags , NULL , rval ) ;
return rval ;
}
STATIC ssize_t
2006-03-14 06:00:35 +03:00
xfs_file_aio_read (
2005-04-17 02:20:36 +04:00
struct kiocb * iocb ,
char __user * buf ,
size_t count ,
loff_t pos )
{
2006-03-14 06:00:35 +03:00
return __xfs_file_read ( iocb , buf , IO_ISAIO , count , pos ) ;
2005-04-17 02:20:36 +04:00
}
STATIC ssize_t
2006-03-14 06:00:35 +03:00
xfs_file_aio_read_invis (
2005-04-17 02:20:36 +04:00
struct kiocb * iocb ,
char __user * buf ,
size_t count ,
loff_t pos )
{
2006-03-14 06:00:35 +03:00
return __xfs_file_read ( iocb , buf , IO_ISAIO | IO_INVIS , count , pos ) ;
2005-04-17 02:20:36 +04:00
}
STATIC inline ssize_t
2006-03-14 06:00:35 +03:00
__xfs_file_write (
2005-04-17 02:20:36 +04:00
struct kiocb * iocb ,
const char __user * buf ,
int ioflags ,
size_t count ,
loff_t pos )
{
struct iovec iov = { ( void __user * ) buf , count } ;
struct file * file = iocb - > ki_filp ;
struct inode * inode = file - > f_mapping - > host ;
2006-03-17 09:25:36 +03:00
vnode_t * vp = vn_from_inode ( inode ) ;
2005-04-17 02:20:36 +04:00
ssize_t rval ;
BUG_ON ( iocb - > ki_pos ! = pos ) ;
if ( unlikely ( file - > f_flags & O_DIRECT ) )
ioflags | = IO_ISDIRECT ;
VOP_WRITE ( vp , iocb , & iov , 1 , & iocb - > ki_pos , ioflags , NULL , rval ) ;
return rval ;
}
STATIC ssize_t
2006-03-14 06:00:35 +03:00
xfs_file_aio_write (
2005-04-17 02:20:36 +04:00
struct kiocb * iocb ,
const char __user * buf ,
size_t count ,
loff_t pos )
{
2006-03-14 06:00:35 +03:00
return __xfs_file_write ( iocb , buf , IO_ISAIO , count , pos ) ;
2005-04-17 02:20:36 +04:00
}
STATIC ssize_t
2006-03-14 06:00:35 +03:00
xfs_file_aio_write_invis (
2005-04-17 02:20:36 +04:00
struct kiocb * iocb ,
const char __user * buf ,
size_t count ,
loff_t pos )
{
2006-03-14 06:00:35 +03:00
return __xfs_file_write ( iocb , buf , IO_ISAIO | IO_INVIS , count , pos ) ;
2005-04-17 02:20:36 +04:00
}
STATIC inline ssize_t
2006-03-14 06:00:35 +03:00
__xfs_file_readv (
2005-04-17 02:20:36 +04:00
struct file * file ,
const struct iovec * iov ,
int ioflags ,
unsigned long nr_segs ,
loff_t * ppos )
{
struct inode * inode = file - > f_mapping - > host ;
2006-03-17 09:25:36 +03:00
vnode_t * vp = vn_from_inode ( inode ) ;
2006-03-14 06:07:53 +03:00
struct kiocb kiocb ;
2005-04-17 02:20:36 +04:00
ssize_t rval ;
2006-03-14 06:07:53 +03:00
init_sync_kiocb ( & kiocb , file ) ;
kiocb . ki_pos = * ppos ;
2005-04-17 02:20:36 +04:00
if ( unlikely ( file - > f_flags & O_DIRECT ) )
ioflags | = IO_ISDIRECT ;
2006-03-14 06:07:53 +03:00
VOP_READ ( vp , & kiocb , iov , nr_segs , & kiocb . ki_pos , ioflags , NULL , rval ) ;
2005-04-17 02:20:36 +04:00
2006-03-14 06:07:53 +03:00
* ppos = kiocb . ki_pos ;
2005-04-17 02:20:36 +04:00
return rval ;
}
STATIC ssize_t
2006-03-14 06:00:35 +03:00
xfs_file_readv (
2005-04-17 02:20:36 +04:00
struct file * file ,
const struct iovec * iov ,
unsigned long nr_segs ,
loff_t * ppos )
{
2006-03-14 06:00:35 +03:00
return __xfs_file_readv ( file , iov , 0 , nr_segs , ppos ) ;
2005-04-17 02:20:36 +04:00
}
STATIC ssize_t
2006-03-14 06:00:35 +03:00
xfs_file_readv_invis (
2005-04-17 02:20:36 +04:00
struct file * file ,
const struct iovec * iov ,
unsigned long nr_segs ,
loff_t * ppos )
{
2006-03-14 06:00:35 +03:00
return __xfs_file_readv ( file , iov , IO_INVIS , nr_segs , ppos ) ;
2005-04-17 02:20:36 +04:00
}
STATIC inline ssize_t
2006-03-14 06:00:35 +03:00
__xfs_file_writev (
2005-04-17 02:20:36 +04:00
struct file * file ,
const struct iovec * iov ,
int ioflags ,
unsigned long nr_segs ,
loff_t * ppos )
{
struct inode * inode = file - > f_mapping - > host ;
2006-03-17 09:25:36 +03:00
vnode_t * vp = vn_from_inode ( inode ) ;
2006-03-14 06:07:53 +03:00
struct kiocb kiocb ;
2005-04-17 02:20:36 +04:00
ssize_t rval ;
2006-03-14 06:07:53 +03:00
init_sync_kiocb ( & kiocb , file ) ;
kiocb . ki_pos = * ppos ;
2005-04-17 02:20:36 +04:00
if ( unlikely ( file - > f_flags & O_DIRECT ) )
ioflags | = IO_ISDIRECT ;
2006-03-14 06:07:53 +03:00
VOP_WRITE ( vp , & kiocb , iov , nr_segs , & kiocb . ki_pos , ioflags , NULL , rval ) ;
2005-04-17 02:20:36 +04:00
2006-03-14 06:07:53 +03:00
* ppos = kiocb . ki_pos ;
2005-04-17 02:20:36 +04:00
return rval ;
}
STATIC ssize_t
2006-03-14 06:00:35 +03:00
xfs_file_writev (
2005-04-17 02:20:36 +04:00
struct file * file ,
const struct iovec * iov ,
unsigned long nr_segs ,
loff_t * ppos )
{
2006-03-14 06:00:35 +03:00
return __xfs_file_writev ( file , iov , 0 , nr_segs , ppos ) ;
2005-04-17 02:20:36 +04:00
}
STATIC ssize_t
2006-03-14 06:00:35 +03:00
xfs_file_writev_invis (
2005-04-17 02:20:36 +04:00
struct file * file ,
const struct iovec * iov ,
unsigned long nr_segs ,
loff_t * ppos )
{
2006-03-14 06:00:35 +03:00
return __xfs_file_writev ( file , iov , IO_INVIS , nr_segs , ppos ) ;
2005-04-17 02:20:36 +04:00
}
STATIC ssize_t
2006-03-14 06:00:35 +03:00
xfs_file_sendfile (
2005-04-17 02:20:36 +04:00
struct file * filp ,
2006-03-31 07:08:59 +04:00
loff_t * pos ,
2005-04-17 02:20:36 +04:00
size_t count ,
read_actor_t actor ,
void * target )
{
2006-03-17 09:25:36 +03:00
vnode_t * vp = vn_from_inode ( filp - > f_dentry - > d_inode ) ;
2005-04-17 02:20:36 +04:00
ssize_t rval ;
2006-03-31 07:08:59 +04:00
VOP_SENDFILE ( vp , filp , pos , 0 , count , actor , target , NULL , rval ) ;
2005-04-17 02:20:36 +04:00
return rval ;
}
2006-03-31 07:08:59 +04:00
STATIC ssize_t
xfs_file_sendfile_invis (
struct file * filp ,
loff_t * pos ,
size_t count ,
read_actor_t actor ,
void * target )
{
vnode_t * vp = vn_from_inode ( filp - > f_dentry - > d_inode ) ;
ssize_t rval ;
VOP_SENDFILE ( vp , filp , pos , IO_INVIS , count , actor , target , NULL , rval ) ;
return rval ;
}
STATIC ssize_t
xfs_file_splice_read (
struct file * infilp ,
2006-04-11 16:57:50 +04:00
loff_t * ppos ,
2006-04-10 17:18:35 +04:00
struct pipe_inode_info * pipe ,
2006-03-31 07:08:59 +04:00
size_t len ,
unsigned int flags )
{
vnode_t * vp = vn_from_inode ( infilp - > f_dentry - > d_inode ) ;
ssize_t rval ;
2006-04-11 16:57:50 +04:00
VOP_SPLICE_READ ( vp , infilp , ppos , pipe , len , flags , 0 , NULL , rval ) ;
2006-03-31 07:08:59 +04:00
return rval ;
}
STATIC ssize_t
xfs_file_splice_read_invis (
struct file * infilp ,
2006-04-11 16:57:50 +04:00
loff_t * ppos ,
2006-04-10 17:18:35 +04:00
struct pipe_inode_info * pipe ,
2006-03-31 07:08:59 +04:00
size_t len ,
unsigned int flags )
{
vnode_t * vp = vn_from_inode ( infilp - > f_dentry - > d_inode ) ;
ssize_t rval ;
2006-04-11 16:57:50 +04:00
VOP_SPLICE_READ ( vp , infilp , ppos , pipe , len , flags , IO_INVIS , NULL , rval ) ;
2006-03-31 07:08:59 +04:00
return rval ;
}
STATIC ssize_t
xfs_file_splice_write (
2006-04-10 17:18:35 +04:00
struct pipe_inode_info * pipe ,
2006-03-31 07:08:59 +04:00
struct file * outfilp ,
2006-04-11 16:57:50 +04:00
loff_t * ppos ,
2006-03-31 07:08:59 +04:00
size_t len ,
unsigned int flags )
{
vnode_t * vp = vn_from_inode ( outfilp - > f_dentry - > d_inode ) ;
ssize_t rval ;
2006-04-11 16:57:50 +04:00
VOP_SPLICE_WRITE ( vp , pipe , outfilp , ppos , len , flags , 0 , NULL , rval ) ;
2006-03-31 07:08:59 +04:00
return rval ;
}
STATIC ssize_t
xfs_file_splice_write_invis (
2006-04-10 17:18:35 +04:00
struct pipe_inode_info * pipe ,
2006-03-31 07:08:59 +04:00
struct file * outfilp ,
2006-04-11 16:57:50 +04:00
loff_t * ppos ,
2006-03-31 07:08:59 +04:00
size_t len ,
unsigned int flags )
{
vnode_t * vp = vn_from_inode ( outfilp - > f_dentry - > d_inode ) ;
ssize_t rval ;
2006-04-11 16:57:50 +04:00
VOP_SPLICE_WRITE ( vp , pipe , outfilp , ppos , len , flags , IO_INVIS , NULL , rval ) ;
2006-03-31 07:08:59 +04:00
return rval ;
}
2005-04-17 02:20:36 +04:00
STATIC int
2006-03-14 06:00:35 +03:00
xfs_file_open (
2005-04-17 02:20:36 +04:00
struct inode * inode ,
struct file * filp )
{
2006-03-17 09:25:36 +03:00
vnode_t * vp = vn_from_inode ( inode ) ;
2005-04-17 02:20:36 +04:00
int error ;
if ( ! ( filp - > f_flags & O_LARGEFILE ) & & i_size_read ( inode ) > MAX_NON_LFS )
return - EFBIG ;
VOP_OPEN ( vp , NULL , error ) ;
return - error ;
}
STATIC int
2006-03-14 06:00:35 +03:00
xfs_file_release (
2005-04-17 02:20:36 +04:00
struct inode * inode ,
struct file * filp )
{
2006-03-17 09:25:36 +03:00
vnode_t * vp = vn_from_inode ( inode ) ;
2005-04-17 02:20:36 +04:00
int error = 0 ;
if ( vp )
VOP_RELEASE ( vp , error ) ;
return - error ;
}
STATIC int
2006-03-14 06:00:35 +03:00
xfs_file_fsync (
2005-04-17 02:20:36 +04:00
struct file * filp ,
struct dentry * dentry ,
int datasync )
{
struct inode * inode = dentry - > d_inode ;
2006-03-17 09:25:36 +03:00
vnode_t * vp = vn_from_inode ( inode ) ;
2005-04-17 02:20:36 +04:00
int error ;
int flags = FSYNC_WAIT ;
if ( datasync )
flags | = FSYNC_DATA ;
VOP_FSYNC ( vp , flags , NULL , ( xfs_off_t ) 0 , ( xfs_off_t ) - 1 , error ) ;
return - error ;
}
2005-09-02 09:43:05 +04:00
# ifdef CONFIG_XFS_DMAPI
STATIC struct page *
2006-03-14 06:00:35 +03:00
xfs_vm_nopage (
2005-09-02 09:43:05 +04:00
struct vm_area_struct * area ,
unsigned long address ,
int * type )
{
struct inode * inode = area - > vm_file - > f_dentry - > d_inode ;
2006-03-17 09:25:36 +03:00
vnode_t * vp = vn_from_inode ( inode ) ;
2005-09-02 09:43:05 +04:00
xfs_mount_t * mp = XFS_VFSTOM ( vp - > v_vfsp ) ;
int error ;
ASSERT_ALWAYS ( vp - > v_vfsp - > vfs_flag & VFS_DMI ) ;
error = XFS_SEND_MMAP ( mp , area , 0 ) ;
if ( error )
return NULL ;
return filemap_nopage ( area , address , type ) ;
}
# endif /* CONFIG_XFS_DMAPI */
2005-04-17 02:20:36 +04:00
STATIC int
2006-03-14 06:00:35 +03:00
xfs_file_readdir (
2005-04-17 02:20:36 +04:00
struct file * filp ,
void * dirent ,
filldir_t filldir )
{
int error = 0 ;
2006-03-31 07:08:59 +04:00
vnode_t * vp = vn_from_inode ( filp - > f_dentry - > d_inode ) ;
2005-04-17 02:20:36 +04:00
uio_t uio ;
iovec_t iov ;
int eof = 0 ;
caddr_t read_buf ;
int namelen , size = 0 ;
size_t rlen = PAGE_CACHE_SIZE ;
xfs_off_t start_offset , curr_offset ;
xfs_dirent_t * dbp = NULL ;
/* Try fairly hard to get memory */
do {
if ( ( read_buf = ( caddr_t ) kmalloc ( rlen , GFP_KERNEL ) ) )
break ;
rlen > > = 1 ;
} while ( rlen > = 1024 ) ;
if ( read_buf = = NULL )
return - ENOMEM ;
uio . uio_iov = & iov ;
uio . uio_segflg = UIO_SYSSPACE ;
curr_offset = filp - > f_pos ;
if ( filp - > f_pos ! = 0x7fffffff )
uio . uio_offset = filp - > f_pos ;
else
uio . uio_offset = 0xffffffff ;
while ( ! eof ) {
uio . uio_resid = iov . iov_len = rlen ;
iov . iov_base = read_buf ;
uio . uio_iovcnt = 1 ;
start_offset = uio . uio_offset ;
VOP_READDIR ( vp , & uio , NULL , & eof , error ) ;
if ( ( uio . uio_offset = = start_offset ) | | error ) {
size = 0 ;
break ;
}
size = rlen - uio . uio_resid ;
dbp = ( xfs_dirent_t * ) read_buf ;
while ( size > 0 ) {
namelen = strlen ( dbp - > d_name ) ;
if ( filldir ( dirent , dbp - > d_name , namelen ,
( loff_t ) curr_offset & 0x7fffffff ,
( ino_t ) dbp - > d_ino ,
DT_UNKNOWN ) ) {
goto done ;
}
size - = dbp - > d_reclen ;
curr_offset = ( loff_t ) dbp - > d_off /* & 0x7fffffff */ ;
2006-03-31 07:08:59 +04:00
dbp = ( xfs_dirent_t * ) ( ( char * ) dbp + dbp - > d_reclen ) ;
2005-04-17 02:20:36 +04:00
}
}
done :
if ( ! error ) {
if ( size = = 0 )
filp - > f_pos = uio . uio_offset & 0x7fffffff ;
else if ( dbp )
filp - > f_pos = curr_offset ;
}
kfree ( read_buf ) ;
return - error ;
}
STATIC int
2006-03-14 06:00:35 +03:00
xfs_file_mmap (
2005-04-17 02:20:36 +04:00
struct file * filp ,
struct vm_area_struct * vma )
{
struct inode * ip = filp - > f_dentry - > d_inode ;
2006-03-17 09:25:36 +03:00
vnode_t * vp = vn_from_inode ( ip ) ;
2006-03-14 06:07:53 +03:00
vattr_t vattr ;
2005-04-17 02:20:36 +04:00
int error ;
2006-03-14 06:00:35 +03:00
vma - > vm_ops = & xfs_file_vm_ops ;
2005-06-21 08:07:45 +04:00
# ifdef CONFIG_XFS_DMAPI
2005-09-02 09:43:05 +04:00
if ( vp - > v_vfsp - > vfs_flag & VFS_DMI ) {
2006-03-14 06:00:35 +03:00
vma - > vm_ops = & xfs_dmapi_file_vm_ops ;
2005-04-17 02:20:36 +04:00
}
2005-09-02 09:43:05 +04:00
# endif /* CONFIG_XFS_DMAPI */
2005-04-17 02:20:36 +04:00
2006-03-14 06:07:53 +03:00
vattr . va_mask = XFS_AT_UPDATIME ;
VOP_SETATTR ( vp , & vattr , XFS_AT_UPDATIME , NULL , error ) ;
2006-03-14 05:33:36 +03:00
if ( likely ( ! error ) )
2006-03-14 06:07:53 +03:00
__vn_revalidate ( vp , & vattr ) ; /* update flags */
2005-04-17 02:20:36 +04:00
return 0 ;
}
STATIC long
2006-03-14 06:00:35 +03:00
xfs_file_ioctl (
2005-04-17 02:20:36 +04:00
struct file * filp ,
unsigned int cmd ,
unsigned long arg )
{
int error ;
2006-03-14 05:30:48 +03:00
struct inode * inode = filp - > f_dentry - > d_inode ;
2006-03-17 09:25:36 +03:00
vnode_t * vp = vn_from_inode ( inode ) ;
2005-04-17 02:20:36 +04:00
VOP_IOCTL ( vp , inode , filp , 0 , cmd , ( void __user * ) arg , error ) ;
VMODIFY ( vp ) ;
/* 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
2006-03-14 06:00:35 +03:00
xfs_file_ioctl_invis (
2005-04-17 02:20:36 +04:00
struct file * filp ,
unsigned int cmd ,
unsigned long arg )
{
2006-03-14 05:30:48 +03:00
struct inode * inode = filp - > f_dentry - > d_inode ;
2006-03-17 09:25:36 +03:00
vnode_t * vp = vn_from_inode ( inode ) ;
2006-03-31 07:08:59 +04:00
int error ;
2005-04-17 02:20:36 +04:00
VOP_IOCTL ( vp , inode , filp , IO_INVIS , cmd , ( void __user * ) arg , error ) ;
VMODIFY ( vp ) ;
/* 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 ;
}
2005-09-02 09:43:05 +04:00
# ifdef CONFIG_XFS_DMAPI
2005-04-17 02:20:36 +04:00
# ifdef HAVE_VMOP_MPROTECT
STATIC int
2006-03-14 06:00:35 +03:00
xfs_vm_mprotect (
2005-04-17 02:20:36 +04:00
struct vm_area_struct * vma ,
unsigned int newflags )
{
2006-03-17 09:25:36 +03:00
vnode_t * vp = vn_from_inode ( vma - > vm_file - > f_dentry - > d_inode ) ;
2005-04-17 02:20:36 +04:00
int error = 0 ;
if ( vp - > v_vfsp - > vfs_flag & VFS_DMI ) {
if ( ( vma - > vm_flags & VM_MAYSHARE ) & &
( newflags & VM_WRITE ) & & ! ( vma - > vm_flags & VM_WRITE ) ) {
xfs_mount_t * mp = XFS_VFSTOM ( vp - > v_vfsp ) ;
error = XFS_SEND_MMAP ( mp , vma , VM_WRITE ) ;
}
}
return error ;
}
# endif /* HAVE_VMOP_MPROTECT */
2005-09-02 09:43:05 +04:00
# endif /* CONFIG_XFS_DMAPI */
2005-04-17 02:20:36 +04:00
# ifdef HAVE_FOP_OPEN_EXEC
/* If the user is attempting to execute a file that is offline then
* we have to trigger a DMAPI READ event before the file is marked as busy
* otherwise the invisible I / O will not be able to write to the file to bring
* it back online .
*/
STATIC int
2006-03-14 06:00:35 +03:00
xfs_file_open_exec (
2005-04-17 02:20:36 +04:00
struct inode * inode )
{
2006-03-17 09:25:36 +03:00
vnode_t * vp = vn_from_inode ( inode ) ;
2005-04-17 02:20:36 +04:00
xfs_mount_t * mp = XFS_VFSTOM ( vp - > v_vfsp ) ;
int error = 0 ;
xfs_inode_t * ip ;
if ( vp - > v_vfsp - > vfs_flag & VFS_DMI ) {
2006-01-11 12:58:44 +03:00
ip = xfs_vtoi ( vp ) ;
if ( ! ip ) {
2005-04-17 02:20:36 +04:00
error = - EINVAL ;
goto open_exec_out ;
}
if ( DM_EVENT_ENABLED ( vp - > v_vfsp , ip , DM_EVENT_READ ) ) {
error = - XFS_SEND_DATA ( mp , DM_EVENT_READ , vp ,
0 , 0 , 0 , NULL ) ;
}
}
open_exec_out :
return error ;
}
# endif /* HAVE_FOP_OPEN_EXEC */
2006-03-28 13:56:42 +04:00
const struct file_operations xfs_file_operations = {
2005-04-17 02:20:36 +04:00
. llseek = generic_file_llseek ,
. read = do_sync_read ,
2005-09-02 09:43:05 +04:00
. write = do_sync_write ,
2006-03-14 06:00:35 +03:00
. readv = xfs_file_readv ,
. writev = xfs_file_writev ,
. aio_read = xfs_file_aio_read ,
. aio_write = xfs_file_aio_write ,
. sendfile = xfs_file_sendfile ,
2006-03-31 07:08:59 +04:00
. splice_read = xfs_file_splice_read ,
. splice_write = xfs_file_splice_write ,
2006-03-14 06:00:35 +03:00
. unlocked_ioctl = xfs_file_ioctl ,
2005-04-17 02:20:36 +04:00
# ifdef CONFIG_COMPAT
2006-03-14 06:00:35 +03:00
. compat_ioctl = xfs_file_compat_ioctl ,
2005-04-17 02:20:36 +04:00
# endif
2006-03-14 06:00:35 +03:00
. mmap = xfs_file_mmap ,
. open = xfs_file_open ,
. release = xfs_file_release ,
. fsync = xfs_file_fsync ,
2005-04-17 02:20:36 +04:00
# ifdef HAVE_FOP_OPEN_EXEC
2006-03-14 06:00:35 +03:00
. open_exec = xfs_file_open_exec ,
2005-04-17 02:20:36 +04:00
# endif
} ;
2006-03-28 13:56:42 +04:00
const struct file_operations xfs_invis_file_operations = {
2005-04-17 02:20:36 +04:00
. llseek = generic_file_llseek ,
. read = do_sync_read ,
2005-09-02 09:43:05 +04:00
. write = do_sync_write ,
2006-03-14 06:00:35 +03:00
. readv = xfs_file_readv_invis ,
. writev = xfs_file_writev_invis ,
. aio_read = xfs_file_aio_read_invis ,
. aio_write = xfs_file_aio_write_invis ,
2006-03-31 07:08:59 +04:00
. sendfile = xfs_file_sendfile_invis ,
. splice_read = xfs_file_splice_read_invis ,
. splice_write = xfs_file_splice_write_invis ,
2006-03-14 06:00:35 +03:00
. unlocked_ioctl = xfs_file_ioctl_invis ,
2005-04-17 02:20:36 +04:00
# ifdef CONFIG_COMPAT
2006-03-14 06:00:35 +03:00
. compat_ioctl = xfs_file_compat_invis_ioctl ,
2005-04-17 02:20:36 +04:00
# endif
2006-03-14 06:00:35 +03:00
. mmap = xfs_file_mmap ,
. open = xfs_file_open ,
. release = xfs_file_release ,
. fsync = xfs_file_fsync ,
2005-04-17 02:20:36 +04:00
} ;
2006-03-28 13:56:42 +04:00
const struct file_operations xfs_dir_file_operations = {
2005-04-17 02:20:36 +04:00
. read = generic_read_dir ,
2006-03-14 06:00:35 +03:00
. readdir = xfs_file_readdir ,
. unlocked_ioctl = xfs_file_ioctl ,
2005-05-06 17:44:46 +04:00
# ifdef CONFIG_COMPAT
2006-03-14 06:00:35 +03:00
. compat_ioctl = xfs_file_compat_ioctl ,
2005-05-06 17:44:46 +04:00
# endif
2006-03-14 06:00:35 +03:00
. fsync = xfs_file_fsync ,
2005-04-17 02:20:36 +04:00
} ;
2006-03-14 06:00:35 +03:00
static struct vm_operations_struct xfs_file_vm_ops = {
2005-04-17 02:20:36 +04:00
. nopage = filemap_nopage ,
. populate = filemap_populate ,
2005-06-21 08:07:45 +04:00
} ;
# ifdef CONFIG_XFS_DMAPI
2006-03-14 06:00:35 +03:00
static struct vm_operations_struct xfs_dmapi_file_vm_ops = {
. nopage = xfs_vm_nopage ,
2005-06-21 08:07:45 +04:00
. populate = filemap_populate ,
2005-04-17 02:20:36 +04:00
# ifdef HAVE_VMOP_MPROTECT
2006-03-14 06:00:35 +03:00
. mprotect = xfs_vm_mprotect ,
2005-04-17 02:20:36 +04:00
# endif
} ;
2005-06-21 08:07:45 +04:00
# endif /* CONFIG_XFS_DMAPI */