Commit f999a5bf authored by Christoph Hellwig's avatar Christoph Hellwig Committed by Niv Sardi
Browse files

[XFS] wire up ->open for directories



Currently there's no ->open method set for directories on XFS.  That
means we don't perform any check for opening too large directories
without O_LARGEFILE, we don't check for shut down filesystems, and we
don't actually do the readahead for the first block in the directory.

Instead of just setting the directories open routine to xfs_file_open
we merge the shutdown check directly into xfs_file_open and create
a new xfs_dir_open that first calls xfs_file_open and then performs
the readahead for block 0.

(First sent on September 29th)

Signed-off-by: default avatarChristoph Hellwig <hch@lst.de>
Reviewed-by: default avatarDave Chinner <david@fromorbit.com>
Signed-off-by: default avatarNiv Sardi <xaiki@sgi.com>
parent bac8dca9
Loading
Loading
Loading
Loading
+31 −3
Original line number Diff line number Diff line
@@ -38,6 +38,7 @@
#include "xfs_rw.h"
#include "xfs_ioctl32.h"
#include "xfs_vnodeops.h"
#include "xfs_da_btree.h"

#include <linux/dcache.h>
#include <linux/smp_lock.h>
@@ -169,11 +170,37 @@ xfs_file_splice_write_invis(
STATIC int
xfs_file_open(
	struct inode	*inode,
	struct file	*filp)
	struct file	*file)
{
	if (!(filp->f_flags & O_LARGEFILE) && i_size_read(inode) > MAX_NON_LFS)
	if (!(file->f_flags & O_LARGEFILE) && i_size_read(inode) > MAX_NON_LFS)
		return -EFBIG;
	return -xfs_open(XFS_I(inode));
	if (XFS_FORCED_SHUTDOWN(XFS_M(inode->i_sb)))
		return -EIO;
	return 0;
}

STATIC int
xfs_dir_open(
	struct inode	*inode,
	struct file	*file)
{
	struct xfs_inode *ip = XFS_I(inode);
	int		mode;
	int		error;

	error = xfs_file_open(inode, file);
	if (error)
		return error;

	/*
	 * If there are any blocks, read-ahead block 0 as we're almost
	 * certain to have the next operation be a read there.
	 */
	mode = xfs_ilock_map_shared(ip);
	if (ip->i_d.di_nextents > 0)
		xfs_da_reada_buf(NULL, ip, 0, XFS_DATA_FORK);
	xfs_iunlock(ip, mode);
	return 0;
}

STATIC int
@@ -345,6 +372,7 @@ const struct file_operations xfs_invis_file_operations = {


const struct file_operations xfs_dir_file_operations = {
	.open		= xfs_dir_open,
	.read		= generic_read_dir,
	.readdir	= xfs_file_readdir,
	.llseek		= generic_file_llseek,
+0 −22
Original line number Diff line number Diff line
@@ -53,28 +53,6 @@
#include "xfs_filestream.h"
#include "xfs_vnodeops.h"

int
xfs_open(
	xfs_inode_t	*ip)
{
	int		mode;

	if (XFS_FORCED_SHUTDOWN(ip->i_mount))
		return XFS_ERROR(EIO);

	/*
	 * If it's a directory with any blocks, read-ahead block 0
	 * as we're almost certain to have the next operation be a read there.
	 */
	if (S_ISDIR(ip->i_d.di_mode) && ip->i_d.di_nextents > 0) {
		mode = xfs_ilock_map_shared(ip);
		if (ip->i_d.di_nextents > 0)
			(void)xfs_da_reada_buf(NULL, ip, 0, XFS_DATA_FORK);
		xfs_iunlock(ip, mode);
	}
	return 0;
}

int
xfs_setattr(
	struct xfs_inode	*ip,
+0 −1
Original line number Diff line number Diff line
@@ -14,7 +14,6 @@ struct xfs_inode;
struct xfs_iomap;


int xfs_open(struct xfs_inode *ip);
int xfs_setattr(struct xfs_inode *ip, struct iattr *vap, int flags);
#define	XFS_ATTR_DMI		0x01	/* invocation from a DMI function */
#define	XFS_ATTR_NONBLOCK	0x02	/* return EAGAIN if operation would block */