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
STATIC int
xfs_file_close(
302 303
	struct file	*filp,
	fl_owner_t	id)
304
{
305 306
	return -bhv_vop_close(vn_from_inode(filp->f_dentry->d_inode), 0,
				file_count(filp) > 1 ? L_FALSE : L_TRUE, NULL);
307 308
}

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

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

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

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

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

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

L
Linus Torvalds 已提交
354
STATIC int
355
xfs_file_readdir(
L
Linus Torvalds 已提交
356 357 358 359 360
	struct file	*filp,
	void		*dirent,
	filldir_t	filldir)
{
	int		error = 0;
361
	bhv_vnode_t	*vp = vn_from_inode(filp->f_dentry->d_inode);
L
Linus Torvalds 已提交
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 395
	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;

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

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

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

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

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

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

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

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

525 526 527 528 529 530 531 532
	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 已提交
533 534
					       0, 0, 0, NULL);
	}
535
	return 0;
L
Linus Torvalds 已提交
536 537 538
}
#endif /* HAVE_FOP_OPEN_EXEC */

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

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


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

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

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