diff options
author | Christoph Hellwig <hch@infradead.org> | 2008-11-27 22:23:32 -0500 |
---|---|---|
committer | Niv Sardi <xaiki@sgi.com> | 2008-11-30 19:07:08 -0500 |
commit | f999a5bf3fa6b3d11334c3ba1e9dcfed5ff9f8a6 (patch) | |
tree | 6ee512a3e292b13dca507cc1bc1528cded8b5abe /fs | |
parent | bac8dca9f9b1dfcf9c4ecb4f9ca17185b828cc20 (diff) |
[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: Christoph Hellwig <hch@lst.de>
Reviewed-by: Dave Chinner <david@fromorbit.com>
Signed-off-by: Niv Sardi <xaiki@sgi.com>
Diffstat (limited to 'fs')
-rw-r--r-- | fs/xfs/linux-2.6/xfs_file.c | 34 | ||||
-rw-r--r-- | fs/xfs/xfs_vnodeops.c | 22 | ||||
-rw-r--r-- | fs/xfs/xfs_vnodeops.h | 1 |
3 files changed, 31 insertions, 26 deletions
diff --git a/fs/xfs/linux-2.6/xfs_file.c b/fs/xfs/linux-2.6/xfs_file.c index 3fee790f138b..72fc8d8c8bc1 100644 --- a/fs/xfs/linux-2.6/xfs_file.c +++ b/fs/xfs/linux-2.6/xfs_file.c | |||
@@ -38,6 +38,7 @@ | |||
38 | #include "xfs_rw.h" | 38 | #include "xfs_rw.h" |
39 | #include "xfs_ioctl32.h" | 39 | #include "xfs_ioctl32.h" |
40 | #include "xfs_vnodeops.h" | 40 | #include "xfs_vnodeops.h" |
41 | #include "xfs_da_btree.h" | ||
41 | 42 | ||
42 | #include <linux/dcache.h> | 43 | #include <linux/dcache.h> |
43 | #include <linux/smp_lock.h> | 44 | #include <linux/smp_lock.h> |
@@ -169,11 +170,37 @@ xfs_file_splice_write_invis( | |||
169 | STATIC int | 170 | STATIC int |
170 | xfs_file_open( | 171 | xfs_file_open( |
171 | struct inode *inode, | 172 | struct inode *inode, |
172 | struct file *filp) | 173 | struct file *file) |
173 | { | 174 | { |
174 | if (!(filp->f_flags & O_LARGEFILE) && i_size_read(inode) > MAX_NON_LFS) | 175 | if (!(file->f_flags & O_LARGEFILE) && i_size_read(inode) > MAX_NON_LFS) |
175 | return -EFBIG; | 176 | return -EFBIG; |
176 | return -xfs_open(XFS_I(inode)); | 177 | if (XFS_FORCED_SHUTDOWN(XFS_M(inode->i_sb))) |
178 | return -EIO; | ||
179 | return 0; | ||
180 | } | ||
181 | |||
182 | STATIC int | ||
183 | xfs_dir_open( | ||
184 | struct inode *inode, | ||
185 | struct file *file) | ||
186 | { | ||
187 | struct xfs_inode *ip = XFS_I(inode); | ||
188 | int mode; | ||
189 | int error; | ||
190 | |||
191 | error = xfs_file_open(inode, file); | ||
192 | if (error) | ||
193 | return error; | ||
194 | |||
195 | /* | ||
196 | * If there are any blocks, read-ahead block 0 as we're almost | ||
197 | * certain to have the next operation be a read there. | ||
198 | */ | ||
199 | mode = xfs_ilock_map_shared(ip); | ||
200 | if (ip->i_d.di_nextents > 0) | ||
201 | xfs_da_reada_buf(NULL, ip, 0, XFS_DATA_FORK); | ||
202 | xfs_iunlock(ip, mode); | ||
203 | return 0; | ||
177 | } | 204 | } |
178 | 205 | ||
179 | STATIC int | 206 | STATIC int |
@@ -345,6 +372,7 @@ const struct file_operations xfs_invis_file_operations = { | |||
345 | 372 | ||
346 | 373 | ||
347 | const struct file_operations xfs_dir_file_operations = { | 374 | const struct file_operations xfs_dir_file_operations = { |
375 | .open = xfs_dir_open, | ||
348 | .read = generic_read_dir, | 376 | .read = generic_read_dir, |
349 | .readdir = xfs_file_readdir, | 377 | .readdir = xfs_file_readdir, |
350 | .llseek = generic_file_llseek, | 378 | .llseek = generic_file_llseek, |
diff --git a/fs/xfs/xfs_vnodeops.c b/fs/xfs/xfs_vnodeops.c index 0574aadc4d3c..c055bdb11cb7 100644 --- a/fs/xfs/xfs_vnodeops.c +++ b/fs/xfs/xfs_vnodeops.c | |||
@@ -54,28 +54,6 @@ | |||
54 | #include "xfs_vnodeops.h" | 54 | #include "xfs_vnodeops.h" |
55 | 55 | ||
56 | int | 56 | int |
57 | xfs_open( | ||
58 | xfs_inode_t *ip) | ||
59 | { | ||
60 | int mode; | ||
61 | |||
62 | if (XFS_FORCED_SHUTDOWN(ip->i_mount)) | ||
63 | return XFS_ERROR(EIO); | ||
64 | |||
65 | /* | ||
66 | * If it's a directory with any blocks, read-ahead block 0 | ||
67 | * as we're almost certain to have the next operation be a read there. | ||
68 | */ | ||
69 | if (S_ISDIR(ip->i_d.di_mode) && ip->i_d.di_nextents > 0) { | ||
70 | mode = xfs_ilock_map_shared(ip); | ||
71 | if (ip->i_d.di_nextents > 0) | ||
72 | (void)xfs_da_reada_buf(NULL, ip, 0, XFS_DATA_FORK); | ||
73 | xfs_iunlock(ip, mode); | ||
74 | } | ||
75 | return 0; | ||
76 | } | ||
77 | |||
78 | int | ||
79 | xfs_setattr( | 57 | xfs_setattr( |
80 | struct xfs_inode *ip, | 58 | struct xfs_inode *ip, |
81 | struct iattr *iattr, | 59 | struct iattr *iattr, |
diff --git a/fs/xfs/xfs_vnodeops.h b/fs/xfs/xfs_vnodeops.h index b1ae8e3f4043..a559400aeae0 100644 --- a/fs/xfs/xfs_vnodeops.h +++ b/fs/xfs/xfs_vnodeops.h | |||
@@ -14,7 +14,6 @@ struct xfs_inode; | |||
14 | struct xfs_iomap; | 14 | struct xfs_iomap; |
15 | 15 | ||
16 | 16 | ||
17 | int xfs_open(struct xfs_inode *ip); | ||
18 | int xfs_setattr(struct xfs_inode *ip, struct iattr *vap, int flags); | 17 | int xfs_setattr(struct xfs_inode *ip, struct iattr *vap, int flags); |
19 | #define XFS_ATTR_DMI 0x01 /* invocation from a DMI function */ | 18 | #define XFS_ATTR_DMI 0x01 /* invocation from a DMI function */ |
20 | #define XFS_ATTR_NONBLOCK 0x02 /* return EAGAIN if operation would block */ | 19 | #define XFS_ATTR_NONBLOCK 0x02 /* return EAGAIN if operation would block */ |