xfs_file.c 13.8 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 44 45
#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>

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

#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
521
xfs_file_open_exec(
L
Linus Torvalds 已提交
522 523
	struct inode	*inode)
{
524
	bhv_vnode_t	*vp = vn_from_inode(inode);
L
Linus Torvalds 已提交
525 526 527 528 529
	xfs_mount_t	*mp = XFS_VFSTOM(vp->v_vfsp);
	int		error = 0;
	xfs_inode_t	*ip;

	if (vp->v_vfsp->vfs_flag & VFS_DMI) {
530 531
		ip = xfs_vtoi(vp);
		if (!ip) {
L
Linus Torvalds 已提交
532 533 534 535 536 537 538 539 540 541 542 543 544
			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 */

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

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


593
const struct file_operations xfs_dir_file_operations = {
L
Linus Torvalds 已提交
594
	.read		= generic_read_dir,
595 596
	.readdir	= xfs_file_readdir,
	.unlocked_ioctl	= xfs_file_ioctl,
597
#ifdef CONFIG_COMPAT
598
	.compat_ioctl	= xfs_file_compat_ioctl,
599
#endif
600
	.fsync		= xfs_file_fsync,
L
Linus Torvalds 已提交
601 602
};

603
static struct vm_operations_struct xfs_file_vm_ops = {
L
Linus Torvalds 已提交
604 605
	.nopage		= filemap_nopage,
	.populate	= filemap_populate,
606 607 608
};

#ifdef CONFIG_XFS_DMAPI
609 610
static struct vm_operations_struct xfs_dmapi_file_vm_ops = {
	.nopage		= xfs_vm_nopage,
611
	.populate	= filemap_populate,
L
Linus Torvalds 已提交
612
#ifdef HAVE_VMOP_MPROTECT
613
	.mprotect	= xfs_vm_mprotect,
L
Linus Torvalds 已提交
614 615
#endif
};
616
#endif /* CONFIG_XFS_DMAPI */