xfs_file.c 13.7 KB
Newer Older
L
Linus Torvalds 已提交
1
/*
2 3
 * Copyright (c) 2000-2005 Silicon Graphics, Inc.
 * All Rights Reserved.
L
Linus Torvalds 已提交
4
 *
5 6
 * This program is free software; you can redistribute it and/or
 * modify it under the terms of the GNU General Public License as
L
Linus Torvalds 已提交
7 8
 * published by the Free Software Foundation.
 *
9 10 11 12
 * 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.
L
Linus Torvalds 已提交
13
 *
14 15 16
 * 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
L
Linus Torvalds 已提交
17 18
 */
#include "xfs.h"
19
#include "xfs_bit.h"
L
Linus Torvalds 已提交
20
#include "xfs_log.h"
21
#include "xfs_inum.h"
L
Linus Torvalds 已提交
22
#include "xfs_sb.h"
23
#include "xfs_ag.h"
L
Linus Torvalds 已提交
24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43
#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_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>

44
static struct vm_operations_struct xfs_file_vm_ops;
45
#ifdef CONFIG_XFS_DMAPI
46
static struct vm_operations_struct xfs_dmapi_file_vm_ops;
47
#endif
L
Linus Torvalds 已提交
48 49

STATIC inline ssize_t
50
__xfs_file_read(
L
Linus Torvalds 已提交
51 52 53 54 55 56 57 58
	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;
59
	bhv_vnode_t		*vp = vn_from_inode(file->f_dentry->d_inode);
L
Linus Torvalds 已提交
60 61 62 63

	BUG_ON(iocb->ki_pos != pos);
	if (unlikely(file->f_flags & O_DIRECT))
		ioflags |= IO_ISDIRECT;
64
	return bhv_vop_read(vp, iocb, &iov, 1, &iocb->ki_pos, ioflags, NULL);
L
Linus Torvalds 已提交
65 66 67
}

STATIC ssize_t
68
xfs_file_aio_read(
L
Linus Torvalds 已提交
69 70 71 72 73
	struct kiocb		*iocb,
	char			__user *buf,
	size_t			count,
	loff_t			pos)
{
74
	return __xfs_file_read(iocb, buf, IO_ISAIO, count, pos);
L
Linus Torvalds 已提交
75 76 77
}

STATIC ssize_t
78
xfs_file_aio_read_invis(
L
Linus Torvalds 已提交
79 80 81 82 83
	struct kiocb		*iocb,
	char			__user *buf,
	size_t			count,
	loff_t			pos)
{
84
	return __xfs_file_read(iocb, buf, IO_ISAIO|IO_INVIS, count, pos);
L
Linus Torvalds 已提交
85 86 87
}

STATIC inline ssize_t
88
__xfs_file_write(
L
Linus Torvalds 已提交
89 90 91 92 93 94 95 96 97
	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;
98
	bhv_vnode_t	*vp = vn_from_inode(inode);
L
Linus Torvalds 已提交
99 100 101 102

	BUG_ON(iocb->ki_pos != pos);
	if (unlikely(file->f_flags & O_DIRECT))
		ioflags |= IO_ISDIRECT;
103
	return bhv_vop_write(vp, iocb, &iov, 1, &iocb->ki_pos, ioflags, NULL);
L
Linus Torvalds 已提交
104 105 106
}

STATIC ssize_t
107
xfs_file_aio_write(
L
Linus Torvalds 已提交
108 109 110 111 112
	struct kiocb		*iocb,
	const char		__user *buf,
	size_t			count,
	loff_t			pos)
{
113
	return __xfs_file_write(iocb, buf, IO_ISAIO, count, pos);
L
Linus Torvalds 已提交
114 115 116
}

STATIC ssize_t
117
xfs_file_aio_write_invis(
L
Linus Torvalds 已提交
118 119 120 121 122
	struct kiocb		*iocb,
	const char		__user *buf,
	size_t			count,
	loff_t			pos)
{
123
	return __xfs_file_write(iocb, buf, IO_ISAIO|IO_INVIS, count, pos);
L
Linus Torvalds 已提交
124 125 126
}

STATIC inline ssize_t
127
__xfs_file_readv(
L
Linus Torvalds 已提交
128 129 130 131 132 133 134
	struct file		*file,
	const struct iovec 	*iov,
	int			ioflags,
	unsigned long		nr_segs,
	loff_t			*ppos)
{
	struct inode	*inode = file->f_mapping->host;
135
	bhv_vnode_t	*vp = vn_from_inode(inode);
136
	struct kiocb	kiocb;
L
Linus Torvalds 已提交
137 138
	ssize_t		rval;

139 140
	init_sync_kiocb(&kiocb, file);
	kiocb.ki_pos = *ppos;
L
Linus Torvalds 已提交
141 142 143

	if (unlikely(file->f_flags & O_DIRECT))
		ioflags |= IO_ISDIRECT;
144 145
	rval = bhv_vop_read(vp, &kiocb, iov, nr_segs,
				&kiocb.ki_pos, ioflags, NULL);
L
Linus Torvalds 已提交
146

147
	*ppos = kiocb.ki_pos;
L
Linus Torvalds 已提交
148 149 150 151
	return rval;
}

STATIC ssize_t
152
xfs_file_readv(
L
Linus Torvalds 已提交
153 154 155 156 157
	struct file		*file,
	const struct iovec 	*iov,
	unsigned long		nr_segs,
	loff_t			*ppos)
{
158
	return __xfs_file_readv(file, iov, 0, nr_segs, ppos);
L
Linus Torvalds 已提交
159 160 161
}

STATIC ssize_t
162
xfs_file_readv_invis(
L
Linus Torvalds 已提交
163 164 165 166 167
	struct file		*file,
	const struct iovec 	*iov,
	unsigned long		nr_segs,
	loff_t			*ppos)
{
168
	return __xfs_file_readv(file, iov, IO_INVIS, nr_segs, ppos);
L
Linus Torvalds 已提交
169 170 171
}

STATIC inline ssize_t
172
__xfs_file_writev(
L
Linus Torvalds 已提交
173 174 175 176 177 178 179
	struct file		*file,
	const struct iovec 	*iov,
	int			ioflags,
	unsigned long		nr_segs,
	loff_t			*ppos)
{
	struct inode	*inode = file->f_mapping->host;
180
	bhv_vnode_t	*vp = vn_from_inode(inode);
181
	struct kiocb	kiocb;
L
Linus Torvalds 已提交
182 183
	ssize_t		rval;

184 185
	init_sync_kiocb(&kiocb, file);
	kiocb.ki_pos = *ppos;
L
Linus Torvalds 已提交
186 187 188
	if (unlikely(file->f_flags & O_DIRECT))
		ioflags |= IO_ISDIRECT;

189 190
	rval = bhv_vop_write(vp, &kiocb, iov, nr_segs,
				 &kiocb.ki_pos, ioflags, NULL);
L
Linus Torvalds 已提交
191

192
	*ppos = kiocb.ki_pos;
L
Linus Torvalds 已提交
193 194 195 196
	return rval;
}

STATIC ssize_t
197
xfs_file_writev(
L
Linus Torvalds 已提交
198 199 200 201 202
	struct file		*file,
	const struct iovec 	*iov,
	unsigned long		nr_segs,
	loff_t			*ppos)
{
203
	return __xfs_file_writev(file, iov, 0, nr_segs, ppos);
L
Linus Torvalds 已提交
204 205 206
}

STATIC ssize_t
207
xfs_file_writev_invis(
L
Linus Torvalds 已提交
208 209 210 211 212
	struct file		*file,
	const struct iovec 	*iov,
	unsigned long		nr_segs,
	loff_t			*ppos)
{
213
	return __xfs_file_writev(file, iov, IO_INVIS, nr_segs, ppos);
L
Linus Torvalds 已提交
214 215 216
}

STATIC ssize_t
217
xfs_file_sendfile(
L
Linus Torvalds 已提交
218
	struct file		*filp,
219
	loff_t			*pos,
L
Linus Torvalds 已提交
220 221 222 223
	size_t			count,
	read_actor_t		actor,
	void			*target)
{
224 225
	return bhv_vop_sendfile(vn_from_inode(filp->f_dentry->d_inode),
				filp, pos, 0, count, actor, target, NULL);
L
Linus Torvalds 已提交
226 227
}

228 229 230 231 232 233 234 235
STATIC ssize_t
xfs_file_sendfile_invis(
	struct file		*filp,
	loff_t			*pos,
	size_t			count,
	read_actor_t		actor,
	void			*target)
{
236 237
	return bhv_vop_sendfile(vn_from_inode(filp->f_dentry->d_inode),
				filp, pos, IO_INVIS, count, actor, target, NULL);
238 239 240 241 242
}

STATIC ssize_t
xfs_file_splice_read(
	struct file		*infilp,
243
	loff_t			*ppos,
244
	struct pipe_inode_info	*pipe,
245 246 247
	size_t			len,
	unsigned int		flags)
{
248 249
	return bhv_vop_splice_read(vn_from_inode(infilp->f_dentry->d_inode),
				   infilp, ppos, pipe, len, flags, 0, NULL);
250 251 252 253 254
}

STATIC ssize_t
xfs_file_splice_read_invis(
	struct file		*infilp,
255
	loff_t			*ppos,
256
	struct pipe_inode_info	*pipe,
257 258 259
	size_t			len,
	unsigned int		flags)
{
260 261 262
	return bhv_vop_splice_read(vn_from_inode(infilp->f_dentry->d_inode),
				   infilp, ppos, pipe, len, flags, IO_INVIS,
				   NULL);
263 264 265 266
}

STATIC ssize_t
xfs_file_splice_write(
267
	struct pipe_inode_info	*pipe,
268
	struct file		*outfilp,
269
	loff_t			*ppos,
270 271 272
	size_t			len,
	unsigned int		flags)
{
273 274
	return bhv_vop_splice_write(vn_from_inode(outfilp->f_dentry->d_inode),
				    pipe, outfilp, ppos, len, flags, 0, NULL);
275 276 277 278
}

STATIC ssize_t
xfs_file_splice_write_invis(
279
	struct pipe_inode_info	*pipe,
280
	struct file		*outfilp,
281
	loff_t			*ppos,
282 283 284
	size_t			len,
	unsigned int		flags)
{
285 286 287
	return bhv_vop_splice_write(vn_from_inode(outfilp->f_dentry->d_inode),
				    pipe, outfilp, ppos, len, flags, IO_INVIS,
				    NULL);
288
}
L
Linus Torvalds 已提交
289 290

STATIC int
291
xfs_file_open(
L
Linus Torvalds 已提交
292 293 294 295 296
	struct inode	*inode,
	struct file	*filp)
{
	if (!(filp->f_flags & O_LARGEFILE) && i_size_read(inode) > MAX_NON_LFS)
		return -EFBIG;
297
	return -bhv_vop_open(vn_from_inode(inode), NULL);
L
Linus Torvalds 已提交
298 299
}

300 301 302 303
STATIC int
xfs_file_close(
	struct file	*filp)
{
304 305
	return -bhv_vop_close(vn_from_inode(filp->f_dentry->d_inode), 0,
				file_count(filp) > 1 ? L_FALSE : L_TRUE, NULL);
306 307
}

L
Linus Torvalds 已提交
308
STATIC int
309
xfs_file_release(
L
Linus Torvalds 已提交
310 311 312
	struct inode	*inode,
	struct file	*filp)
{
313
	bhv_vnode_t	*vp = vn_from_inode(inode);
L
Linus Torvalds 已提交
314 315

	if (vp)
316 317
		return -bhv_vop_release(vp);
	return 0;
L
Linus Torvalds 已提交
318 319 320
}

STATIC int
321
xfs_file_fsync(
L
Linus Torvalds 已提交
322 323 324 325
	struct file	*filp,
	struct dentry	*dentry,
	int		datasync)
{
326
	bhv_vnode_t	*vp = vn_from_inode(dentry->d_inode);
L
Linus Torvalds 已提交
327 328 329 330
	int		flags = FSYNC_WAIT;

	if (datasync)
		flags |= FSYNC_DATA;
331 332
	if (VN_TRUNC(vp))
		VUNTRUNCATE(vp);
333
	return -bhv_vop_fsync(vp, flags, NULL, (xfs_off_t)0, (xfs_off_t)-1);
L
Linus Torvalds 已提交
334 335
}

336 337
#ifdef CONFIG_XFS_DMAPI
STATIC struct page *
338
xfs_vm_nopage(
339 340 341 342 343
	struct vm_area_struct	*area,
	unsigned long		address,
	int			*type)
{
	struct inode	*inode = area->vm_file->f_dentry->d_inode;
344
	bhv_vnode_t	*vp = vn_from_inode(inode);
345 346

	ASSERT_ALWAYS(vp->v_vfsp->vfs_flag & VFS_DMI);
347
	if (XFS_SEND_MMAP(XFS_VFSTOM(vp->v_vfsp), area, 0))
348 349 350 351 352
		return NULL;
	return filemap_nopage(area, address, type);
}
#endif /* CONFIG_XFS_DMAPI */

L
Linus Torvalds 已提交
353
STATIC int
354
xfs_file_readdir(
L
Linus Torvalds 已提交
355 356 357 358 359
	struct file	*filp,
	void		*dirent,
	filldir_t	filldir)
{
	int		error = 0;
360
	bhv_vnode_t	*vp = vn_from_inode(filp->f_dentry->d_inode);
L
Linus Torvalds 已提交
361 362 363 364 365 366 367 368 369 370 371 372 373 374 375 376 377 378 379 380 381 382 383 384 385 386 387 388 389 390 391 392 393 394
	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;

395
		error = bhv_vop_readdir(vp, &uio, NULL, &eof);
L
Linus Torvalds 已提交
396 397 398 399 400 401 402 403 404 405 406 407 408 409 410 411 412 413
		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 */;
414
			dbp = (xfs_dirent_t *)((char *)dbp + dbp->d_reclen);
L
Linus Torvalds 已提交
415 416 417 418 419 420 421 422 423 424 425 426 427 428 429
		}
	}
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
430
xfs_file_mmap(
L
Linus Torvalds 已提交
431 432 433
	struct file	*filp,
	struct vm_area_struct *vma)
{
434
	vma->vm_ops = &xfs_file_vm_ops;
435 436

#ifdef CONFIG_XFS_DMAPI
437
	if (vn_from_inode(filp->f_dentry->d_inode)->v_vfsp->vfs_flag & VFS_DMI)
438
		vma->vm_ops = &xfs_dmapi_file_vm_ops;
439
#endif /* CONFIG_XFS_DMAPI */
L
Linus Torvalds 已提交
440

441
	file_accessed(filp);
L
Linus Torvalds 已提交
442 443 444 445
	return 0;
}

STATIC long
446
xfs_file_ioctl(
L
Linus Torvalds 已提交
447 448
	struct file	*filp,
	unsigned int	cmd,
449
	unsigned long	p)
L
Linus Torvalds 已提交
450 451
{
	int		error;
452
	struct inode	*inode = filp->f_dentry->d_inode;
453
	bhv_vnode_t	*vp = vn_from_inode(inode);
L
Linus Torvalds 已提交
454

455
	error = bhv_vop_ioctl(vp, inode, filp, 0, cmd, (void __user *)p);
L
Linus Torvalds 已提交
456 457 458 459 460 461 462 463 464 465 466 467
	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
468
xfs_file_ioctl_invis(
L
Linus Torvalds 已提交
469 470
	struct file	*filp,
	unsigned int	cmd,
471
	unsigned long	p)
L
Linus Torvalds 已提交
472
{
473
	int		error;
474 475
	struct inode	*inode = filp->f_dentry->d_inode;
	bhv_vnode_t	*vp = vn_from_inode(inode);
L
Linus Torvalds 已提交
476

477
	error = bhv_vop_ioctl(vp, inode, filp, IO_INVIS, cmd, (void __user *)p);
L
Linus Torvalds 已提交
478 479 480 481 482 483 484 485 486 487 488
	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;
}

489
#ifdef CONFIG_XFS_DMAPI
L
Linus Torvalds 已提交
490 491
#ifdef HAVE_VMOP_MPROTECT
STATIC int
492
xfs_vm_mprotect(
L
Linus Torvalds 已提交
493 494 495
	struct vm_area_struct *vma,
	unsigned int	newflags)
{
496
	bhv_vnode_t	*vp = vn_from_inode(vma->vm_file->f_dentry->d_inode);
L
Linus Torvalds 已提交
497 498 499 500 501 502 503 504 505 506 507 508 509
	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 */
510
#endif /* CONFIG_XFS_DMAPI */
L
Linus Torvalds 已提交
511 512 513 514 515 516 517 518

#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
519
xfs_file_open_exec(
L
Linus Torvalds 已提交
520 521
	struct inode	*inode)
{
522
	bhv_vnode_t	*vp = vn_from_inode(inode);
L
Linus Torvalds 已提交
523

524 525 526 527 528 529 530 531
	if (unlikely(vp->v_vfsp->vfs_flag & VFS_DMI)) {
		xfs_mount_t	*mp = XFS_VFSTOM(vp->v_vfsp);
		xfs_inode_t	*ip = xfs_vtoi(vp);

		if (!ip)
			return -EINVAL;
		if (DM_EVENT_ENABLED(vp->v_vfsp, ip, DM_EVENT_READ))
			return -XFS_SEND_DATA(mp, DM_EVENT_READ, vp,
L
Linus Torvalds 已提交
532 533
					       0, 0, 0, NULL);
	}
534
	return 0;
L
Linus Torvalds 已提交
535 536 537
}
#endif /* HAVE_FOP_OPEN_EXEC */

538
const struct file_operations xfs_file_operations = {
L
Linus Torvalds 已提交
539 540
	.llseek		= generic_file_llseek,
	.read		= do_sync_read,
541
	.write		= do_sync_write,
542 543 544 545 546
	.readv		= xfs_file_readv,
	.writev		= xfs_file_writev,
	.aio_read	= xfs_file_aio_read,
	.aio_write	= xfs_file_aio_write,
	.sendfile	= xfs_file_sendfile,
547 548
	.splice_read	= xfs_file_splice_read,
	.splice_write	= xfs_file_splice_write,
549
	.unlocked_ioctl	= xfs_file_ioctl,
L
Linus Torvalds 已提交
550
#ifdef CONFIG_COMPAT
551
	.compat_ioctl	= xfs_file_compat_ioctl,
L
Linus Torvalds 已提交
552
#endif
553 554
	.mmap		= xfs_file_mmap,
	.open		= xfs_file_open,
555
	.flush		= xfs_file_close,
556 557
	.release	= xfs_file_release,
	.fsync		= xfs_file_fsync,
L
Linus Torvalds 已提交
558
#ifdef HAVE_FOP_OPEN_EXEC
559
	.open_exec	= xfs_file_open_exec,
L
Linus Torvalds 已提交
560 561 562
#endif
};

563
const struct file_operations xfs_invis_file_operations = {
L
Linus Torvalds 已提交
564 565
	.llseek		= generic_file_llseek,
	.read		= do_sync_read,
566
	.write		= do_sync_write,
567 568 569 570
	.readv		= xfs_file_readv_invis,
	.writev		= xfs_file_writev_invis,
	.aio_read	= xfs_file_aio_read_invis,
	.aio_write	= xfs_file_aio_write_invis,
571 572 573
	.sendfile	= xfs_file_sendfile_invis,
	.splice_read	= xfs_file_splice_read_invis,
	.splice_write	= xfs_file_splice_write_invis,
574
	.unlocked_ioctl	= xfs_file_ioctl_invis,
L
Linus Torvalds 已提交
575
#ifdef CONFIG_COMPAT
576
	.compat_ioctl	= xfs_file_compat_invis_ioctl,
L
Linus Torvalds 已提交
577
#endif
578 579
	.mmap		= xfs_file_mmap,
	.open		= xfs_file_open,
580
	.flush		= xfs_file_close,
581 582
	.release	= xfs_file_release,
	.fsync		= xfs_file_fsync,
L
Linus Torvalds 已提交
583 584 585
};


586
const struct file_operations xfs_dir_file_operations = {
L
Linus Torvalds 已提交
587
	.read		= generic_read_dir,
588 589
	.readdir	= xfs_file_readdir,
	.unlocked_ioctl	= xfs_file_ioctl,
590
#ifdef CONFIG_COMPAT
591
	.compat_ioctl	= xfs_file_compat_ioctl,
592
#endif
593
	.fsync		= xfs_file_fsync,
L
Linus Torvalds 已提交
594 595
};

596
static struct vm_operations_struct xfs_file_vm_ops = {
L
Linus Torvalds 已提交
597 598
	.nopage		= filemap_nopage,
	.populate	= filemap_populate,
599 600 601
};

#ifdef CONFIG_XFS_DMAPI
602 603
static struct vm_operations_struct xfs_dmapi_file_vm_ops = {
	.nopage		= xfs_vm_nopage,
604
	.populate	= filemap_populate,
L
Linus Torvalds 已提交
605
#ifdef HAVE_VMOP_MPROTECT
606
	.mprotect	= xfs_vm_mprotect,
L
Linus Torvalds 已提交
607 608
#endif
};
609
#endif /* CONFIG_XFS_DMAPI */