diff options
Diffstat (limited to 'fs/xfs/linux-2.6/xfs_file.c')
-rw-r--r-- | fs/xfs/linux-2.6/xfs_file.c | 189 |
1 files changed, 53 insertions, 136 deletions
diff --git a/fs/xfs/linux-2.6/xfs_file.c b/fs/xfs/linux-2.6/xfs_file.c index 3fee790f138b..e14c4e3aea0c 100644 --- a/fs/xfs/linux-2.6/xfs_file.c +++ b/fs/xfs/linux-2.6/xfs_file.c | |||
@@ -36,89 +36,54 @@ | |||
36 | #include "xfs_inode.h" | 36 | #include "xfs_inode.h" |
37 | #include "xfs_error.h" | 37 | #include "xfs_error.h" |
38 | #include "xfs_rw.h" | 38 | #include "xfs_rw.h" |
39 | #include "xfs_ioctl32.h" | ||
40 | #include "xfs_vnodeops.h" | 39 | #include "xfs_vnodeops.h" |
40 | #include "xfs_da_btree.h" | ||
41 | #include "xfs_ioctl.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> |
44 | 45 | ||
45 | static struct vm_operations_struct xfs_file_vm_ops; | 46 | static struct vm_operations_struct xfs_file_vm_ops; |
46 | 47 | ||
47 | STATIC_INLINE ssize_t | 48 | STATIC ssize_t |
48 | __xfs_file_read( | 49 | xfs_file_aio_read( |
49 | struct kiocb *iocb, | 50 | struct kiocb *iocb, |
50 | const struct iovec *iov, | 51 | const struct iovec *iov, |
51 | unsigned long nr_segs, | 52 | unsigned long nr_segs, |
52 | int ioflags, | ||
53 | loff_t pos) | 53 | loff_t pos) |
54 | { | 54 | { |
55 | struct file *file = iocb->ki_filp; | 55 | struct file *file = iocb->ki_filp; |
56 | int ioflags = IO_ISAIO; | ||
56 | 57 | ||
57 | BUG_ON(iocb->ki_pos != pos); | 58 | BUG_ON(iocb->ki_pos != pos); |
58 | if (unlikely(file->f_flags & O_DIRECT)) | 59 | if (unlikely(file->f_flags & O_DIRECT)) |
59 | ioflags |= IO_ISDIRECT; | 60 | ioflags |= IO_ISDIRECT; |
61 | if (file->f_mode & FMODE_NOCMTIME) | ||
62 | ioflags |= IO_INVIS; | ||
60 | return xfs_read(XFS_I(file->f_path.dentry->d_inode), iocb, iov, | 63 | return xfs_read(XFS_I(file->f_path.dentry->d_inode), iocb, iov, |
61 | nr_segs, &iocb->ki_pos, ioflags); | 64 | nr_segs, &iocb->ki_pos, ioflags); |
62 | } | 65 | } |
63 | 66 | ||
64 | STATIC ssize_t | 67 | STATIC ssize_t |
65 | xfs_file_aio_read( | 68 | xfs_file_aio_write( |
66 | struct kiocb *iocb, | ||
67 | const struct iovec *iov, | ||
68 | unsigned long nr_segs, | ||
69 | loff_t pos) | ||
70 | { | ||
71 | return __xfs_file_read(iocb, iov, nr_segs, IO_ISAIO, pos); | ||
72 | } | ||
73 | |||
74 | STATIC ssize_t | ||
75 | xfs_file_aio_read_invis( | ||
76 | struct kiocb *iocb, | ||
77 | const struct iovec *iov, | ||
78 | unsigned long nr_segs, | ||
79 | loff_t pos) | ||
80 | { | ||
81 | return __xfs_file_read(iocb, iov, nr_segs, IO_ISAIO|IO_INVIS, pos); | ||
82 | } | ||
83 | |||
84 | STATIC_INLINE ssize_t | ||
85 | __xfs_file_write( | ||
86 | struct kiocb *iocb, | 69 | struct kiocb *iocb, |
87 | const struct iovec *iov, | 70 | const struct iovec *iov, |
88 | unsigned long nr_segs, | 71 | unsigned long nr_segs, |
89 | int ioflags, | ||
90 | loff_t pos) | 72 | loff_t pos) |
91 | { | 73 | { |
92 | struct file *file = iocb->ki_filp; | 74 | struct file *file = iocb->ki_filp; |
75 | int ioflags = IO_ISAIO; | ||
93 | 76 | ||
94 | BUG_ON(iocb->ki_pos != pos); | 77 | BUG_ON(iocb->ki_pos != pos); |
95 | if (unlikely(file->f_flags & O_DIRECT)) | 78 | if (unlikely(file->f_flags & O_DIRECT)) |
96 | ioflags |= IO_ISDIRECT; | 79 | ioflags |= IO_ISDIRECT; |
80 | if (file->f_mode & FMODE_NOCMTIME) | ||
81 | ioflags |= IO_INVIS; | ||
97 | return xfs_write(XFS_I(file->f_mapping->host), iocb, iov, nr_segs, | 82 | return xfs_write(XFS_I(file->f_mapping->host), iocb, iov, nr_segs, |
98 | &iocb->ki_pos, ioflags); | 83 | &iocb->ki_pos, ioflags); |
99 | } | 84 | } |
100 | 85 | ||
101 | STATIC ssize_t | 86 | STATIC ssize_t |
102 | xfs_file_aio_write( | ||
103 | struct kiocb *iocb, | ||
104 | const struct iovec *iov, | ||
105 | unsigned long nr_segs, | ||
106 | loff_t pos) | ||
107 | { | ||
108 | return __xfs_file_write(iocb, iov, nr_segs, IO_ISAIO, pos); | ||
109 | } | ||
110 | |||
111 | STATIC ssize_t | ||
112 | xfs_file_aio_write_invis( | ||
113 | struct kiocb *iocb, | ||
114 | const struct iovec *iov, | ||
115 | unsigned long nr_segs, | ||
116 | loff_t pos) | ||
117 | { | ||
118 | return __xfs_file_write(iocb, iov, nr_segs, IO_ISAIO|IO_INVIS, pos); | ||
119 | } | ||
120 | |||
121 | STATIC ssize_t | ||
122 | xfs_file_splice_read( | 87 | xfs_file_splice_read( |
123 | struct file *infilp, | 88 | struct file *infilp, |
124 | loff_t *ppos, | 89 | loff_t *ppos, |
@@ -126,20 +91,13 @@ xfs_file_splice_read( | |||
126 | size_t len, | 91 | size_t len, |
127 | unsigned int flags) | 92 | unsigned int flags) |
128 | { | 93 | { |
129 | return xfs_splice_read(XFS_I(infilp->f_path.dentry->d_inode), | 94 | int ioflags = 0; |
130 | infilp, ppos, pipe, len, flags, 0); | 95 | |
131 | } | 96 | if (infilp->f_mode & FMODE_NOCMTIME) |
97 | ioflags |= IO_INVIS; | ||
132 | 98 | ||
133 | STATIC ssize_t | ||
134 | xfs_file_splice_read_invis( | ||
135 | struct file *infilp, | ||
136 | loff_t *ppos, | ||
137 | struct pipe_inode_info *pipe, | ||
138 | size_t len, | ||
139 | unsigned int flags) | ||
140 | { | ||
141 | return xfs_splice_read(XFS_I(infilp->f_path.dentry->d_inode), | 99 | return xfs_splice_read(XFS_I(infilp->f_path.dentry->d_inode), |
142 | infilp, ppos, pipe, len, flags, IO_INVIS); | 100 | infilp, ppos, pipe, len, flags, ioflags); |
143 | } | 101 | } |
144 | 102 | ||
145 | STATIC ssize_t | 103 | STATIC ssize_t |
@@ -150,30 +108,49 @@ xfs_file_splice_write( | |||
150 | size_t len, | 108 | size_t len, |
151 | unsigned int flags) | 109 | unsigned int flags) |
152 | { | 110 | { |
153 | return xfs_splice_write(XFS_I(outfilp->f_path.dentry->d_inode), | 111 | int ioflags = 0; |
154 | pipe, outfilp, ppos, len, flags, 0); | 112 | |
155 | } | 113 | if (outfilp->f_mode & FMODE_NOCMTIME) |
114 | ioflags |= IO_INVIS; | ||
156 | 115 | ||
157 | STATIC ssize_t | ||
158 | xfs_file_splice_write_invis( | ||
159 | struct pipe_inode_info *pipe, | ||
160 | struct file *outfilp, | ||
161 | loff_t *ppos, | ||
162 | size_t len, | ||
163 | unsigned int flags) | ||
164 | { | ||
165 | return xfs_splice_write(XFS_I(outfilp->f_path.dentry->d_inode), | 116 | return xfs_splice_write(XFS_I(outfilp->f_path.dentry->d_inode), |
166 | pipe, outfilp, ppos, len, flags, IO_INVIS); | 117 | pipe, outfilp, ppos, len, flags, ioflags); |
167 | } | 118 | } |
168 | 119 | ||
169 | STATIC int | 120 | STATIC int |
170 | xfs_file_open( | 121 | xfs_file_open( |
171 | struct inode *inode, | 122 | struct inode *inode, |
172 | struct file *filp) | 123 | struct file *file) |
173 | { | 124 | { |
174 | if (!(filp->f_flags & O_LARGEFILE) && i_size_read(inode) > MAX_NON_LFS) | 125 | if (!(file->f_flags & O_LARGEFILE) && i_size_read(inode) > MAX_NON_LFS) |
175 | return -EFBIG; | 126 | return -EFBIG; |
176 | return -xfs_open(XFS_I(inode)); | 127 | if (XFS_FORCED_SHUTDOWN(XFS_M(inode->i_sb))) |
128 | return -EIO; | ||
129 | return 0; | ||
130 | } | ||
131 | |||
132 | STATIC int | ||
133 | xfs_dir_open( | ||
134 | struct inode *inode, | ||
135 | struct file *file) | ||
136 | { | ||
137 | struct xfs_inode *ip = XFS_I(inode); | ||
138 | int mode; | ||
139 | int error; | ||
140 | |||
141 | error = xfs_file_open(inode, file); | ||
142 | if (error) | ||
143 | return error; | ||
144 | |||
145 | /* | ||
146 | * If there are any blocks, read-ahead block 0 as we're almost | ||
147 | * certain to have the next operation be a read there. | ||
148 | */ | ||
149 | mode = xfs_ilock_map_shared(ip); | ||
150 | if (ip->i_d.di_nextents > 0) | ||
151 | xfs_da_reada_buf(NULL, ip, 0, XFS_DATA_FORK); | ||
152 | xfs_iunlock(ip, mode); | ||
153 | return 0; | ||
177 | } | 154 | } |
178 | 155 | ||
179 | STATIC int | 156 | STATIC int |
@@ -227,7 +204,7 @@ xfs_file_readdir( | |||
227 | * point we can change the ->readdir prototype to include the | 204 | * point we can change the ->readdir prototype to include the |
228 | * buffer size. | 205 | * buffer size. |
229 | */ | 206 | */ |
230 | bufsize = (size_t)min_t(loff_t, PAGE_SIZE, inode->i_size); | 207 | bufsize = (size_t)min_t(loff_t, PAGE_SIZE, ip->i_d.di_size); |
231 | 208 | ||
232 | error = xfs_readdir(ip, dirent, bufsize, | 209 | error = xfs_readdir(ip, dirent, bufsize, |
233 | (xfs_off_t *)&filp->f_pos, filldir); | 210 | (xfs_off_t *)&filp->f_pos, filldir); |
@@ -248,48 +225,6 @@ xfs_file_mmap( | |||
248 | return 0; | 225 | return 0; |
249 | } | 226 | } |
250 | 227 | ||
251 | STATIC long | ||
252 | xfs_file_ioctl( | ||
253 | struct file *filp, | ||
254 | unsigned int cmd, | ||
255 | unsigned long p) | ||
256 | { | ||
257 | int error; | ||
258 | struct inode *inode = filp->f_path.dentry->d_inode; | ||
259 | |||
260 | error = xfs_ioctl(XFS_I(inode), filp, 0, cmd, (void __user *)p); | ||
261 | xfs_iflags_set(XFS_I(inode), XFS_IMODIFIED); | ||
262 | |||
263 | /* NOTE: some of the ioctl's return positive #'s as a | ||
264 | * byte count indicating success, such as | ||
265 | * readlink_by_handle. So we don't "sign flip" | ||
266 | * like most other routines. This means true | ||
267 | * errors need to be returned as a negative value. | ||
268 | */ | ||
269 | return error; | ||
270 | } | ||
271 | |||
272 | STATIC long | ||
273 | xfs_file_ioctl_invis( | ||
274 | struct file *filp, | ||
275 | unsigned int cmd, | ||
276 | unsigned long p) | ||
277 | { | ||
278 | int error; | ||
279 | struct inode *inode = filp->f_path.dentry->d_inode; | ||
280 | |||
281 | error = xfs_ioctl(XFS_I(inode), filp, IO_INVIS, cmd, (void __user *)p); | ||
282 | xfs_iflags_set(XFS_I(inode), XFS_IMODIFIED); | ||
283 | |||
284 | /* NOTE: some of the ioctl's return positive #'s as a | ||
285 | * byte count indicating success, such as | ||
286 | * readlink_by_handle. So we don't "sign flip" | ||
287 | * like most other routines. This means true | ||
288 | * errors need to be returned as a negative value. | ||
289 | */ | ||
290 | return error; | ||
291 | } | ||
292 | |||
293 | /* | 228 | /* |
294 | * mmap()d file has taken write protection fault and is being made | 229 | * mmap()d file has taken write protection fault and is being made |
295 | * writable. We can set the page state up correctly for a writable | 230 | * writable. We can set the page state up correctly for a writable |
@@ -325,26 +260,8 @@ const struct file_operations xfs_file_operations = { | |||
325 | #endif | 260 | #endif |
326 | }; | 261 | }; |
327 | 262 | ||
328 | const struct file_operations xfs_invis_file_operations = { | ||
329 | .llseek = generic_file_llseek, | ||
330 | .read = do_sync_read, | ||
331 | .write = do_sync_write, | ||
332 | .aio_read = xfs_file_aio_read_invis, | ||
333 | .aio_write = xfs_file_aio_write_invis, | ||
334 | .splice_read = xfs_file_splice_read_invis, | ||
335 | .splice_write = xfs_file_splice_write_invis, | ||
336 | .unlocked_ioctl = xfs_file_ioctl_invis, | ||
337 | #ifdef CONFIG_COMPAT | ||
338 | .compat_ioctl = xfs_file_compat_invis_ioctl, | ||
339 | #endif | ||
340 | .mmap = xfs_file_mmap, | ||
341 | .open = xfs_file_open, | ||
342 | .release = xfs_file_release, | ||
343 | .fsync = xfs_file_fsync, | ||
344 | }; | ||
345 | |||
346 | |||
347 | const struct file_operations xfs_dir_file_operations = { | 263 | const struct file_operations xfs_dir_file_operations = { |
264 | .open = xfs_dir_open, | ||
348 | .read = generic_read_dir, | 265 | .read = generic_read_dir, |
349 | .readdir = xfs_file_readdir, | 266 | .readdir = xfs_file_readdir, |
350 | .llseek = generic_file_llseek, | 267 | .llseek = generic_file_llseek, |