aboutsummaryrefslogtreecommitdiffstats
path: root/fs/xfs/linux-2.6/xfs_file.c
diff options
context:
space:
mode:
authorLinus Torvalds <torvalds@woody.linux-foundation.org>2007-10-17 12:04:11 -0400
committerLinus Torvalds <torvalds@woody.linux-foundation.org>2007-10-17 12:04:11 -0400
commit347c53dca73fca317d57781f510f5ff4f6c0d0d7 (patch)
treecdc405ac049751da4d76085ce58750b6b2a22326 /fs/xfs/linux-2.6/xfs_file.c
parent5c8e191e8437616a498a8e1cc0af3dd0d32bbff2 (diff)
parent7f015072348a14f16d548be557ee58c5c55df0aa (diff)
Merge branch 'for-linus' of git://oss.sgi.com:8090/xfs/xfs-2.6
* 'for-linus' of git://oss.sgi.com:8090/xfs/xfs-2.6: (59 commits) [XFS] eagerly remove vmap mappings to avoid upsetting Xen [XFS] simplify validata_fields [XFS] no longer using io_vnode, as was remaining from 23 cherrypick [XFS] Remove STATIC which was missing from prior manual merge [XFS] Put back the QUEUE_ORDERED_NONE test in the barrier check. [XFS] Turn off XBF_ASYNC flag before re-reading superblock. [XFS] avoid race in sync_inodes() that can fail to write out all dirty data [XFS] This fix prevents bulkstat from spinning in an infinite loop. [XFS] simplify xfs_create/mknod/symlink prototype [XFS] avoid xfs_getattr in XFS_IOC_FSGETXATTR ioctl [XFS] get_bulkall() could return incorrect inode state [XFS] Kill unused IOMAP_EOF flag [XFS] fix when DMAPI mount option processing happens [XFS] ensure file size is logged on synchronous writes [XFS] growlock should be a mutex [XFS] replace some large xfs_log_priv.h macros by proper functions [XFS] kill struct bhv_vfs [XFS] move syncing related members from struct bhv_vfs to struct xfs_mount [XFS] kill the vfs_flags member in struct bhv_vfs [XFS] kill the vfs_fsid and vfs_altfsid members in struct bhv_vfs ...
Diffstat (limited to 'fs/xfs/linux-2.6/xfs_file.c')
-rw-r--r--fs/xfs/linux-2.6/xfs_file.c174
1 files changed, 58 insertions, 116 deletions
diff --git a/fs/xfs/linux-2.6/xfs_file.c b/fs/xfs/linux-2.6/xfs_file.c
index 0d4001eafd16..fb8dd34041eb 100644
--- a/fs/xfs/linux-2.6/xfs_file.c
+++ b/fs/xfs/linux-2.6/xfs_file.c
@@ -37,6 +37,7 @@
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" 39#include "xfs_ioctl32.h"
40#include "xfs_vnodeops.h"
40 41
41#include <linux/dcache.h> 42#include <linux/dcache.h>
42#include <linux/smp_lock.h> 43#include <linux/smp_lock.h>
@@ -55,13 +56,12 @@ __xfs_file_read(
55 loff_t pos) 56 loff_t pos)
56{ 57{
57 struct file *file = iocb->ki_filp; 58 struct file *file = iocb->ki_filp;
58 bhv_vnode_t *vp = vn_from_inode(file->f_path.dentry->d_inode);
59 59
60 BUG_ON(iocb->ki_pos != pos); 60 BUG_ON(iocb->ki_pos != pos);
61 if (unlikely(file->f_flags & O_DIRECT)) 61 if (unlikely(file->f_flags & O_DIRECT))
62 ioflags |= IO_ISDIRECT; 62 ioflags |= IO_ISDIRECT;
63 return bhv_vop_read(vp, iocb, iov, nr_segs, &iocb->ki_pos, 63 return xfs_read(XFS_I(file->f_path.dentry->d_inode), iocb, iov,
64 ioflags, NULL); 64 nr_segs, &iocb->ki_pos, ioflags);
65} 65}
66 66
67STATIC ssize_t 67STATIC ssize_t
@@ -93,14 +93,12 @@ __xfs_file_write(
93 loff_t pos) 93 loff_t pos)
94{ 94{
95 struct file *file = iocb->ki_filp; 95 struct file *file = iocb->ki_filp;
96 struct inode *inode = file->f_mapping->host;
97 bhv_vnode_t *vp = vn_from_inode(inode);
98 96
99 BUG_ON(iocb->ki_pos != pos); 97 BUG_ON(iocb->ki_pos != pos);
100 if (unlikely(file->f_flags & O_DIRECT)) 98 if (unlikely(file->f_flags & O_DIRECT))
101 ioflags |= IO_ISDIRECT; 99 ioflags |= IO_ISDIRECT;
102 return bhv_vop_write(vp, iocb, iov, nr_segs, &iocb->ki_pos, 100 return xfs_write(XFS_I(file->f_mapping->host), iocb, iov, nr_segs,
103 ioflags, NULL); 101 &iocb->ki_pos, ioflags);
104} 102}
105 103
106STATIC ssize_t 104STATIC ssize_t
@@ -131,8 +129,8 @@ xfs_file_splice_read(
131 size_t len, 129 size_t len,
132 unsigned int flags) 130 unsigned int flags)
133{ 131{
134 return bhv_vop_splice_read(vn_from_inode(infilp->f_path.dentry->d_inode), 132 return xfs_splice_read(XFS_I(infilp->f_path.dentry->d_inode),
135 infilp, ppos, pipe, len, flags, 0, NULL); 133 infilp, ppos, pipe, len, flags, 0);
136} 134}
137 135
138STATIC ssize_t 136STATIC ssize_t
@@ -143,9 +141,8 @@ xfs_file_splice_read_invis(
143 size_t len, 141 size_t len,
144 unsigned int flags) 142 unsigned int flags)
145{ 143{
146 return bhv_vop_splice_read(vn_from_inode(infilp->f_path.dentry->d_inode), 144 return xfs_splice_read(XFS_I(infilp->f_path.dentry->d_inode),
147 infilp, ppos, pipe, len, flags, IO_INVIS, 145 infilp, ppos, pipe, len, flags, IO_INVIS);
148 NULL);
149} 146}
150 147
151STATIC ssize_t 148STATIC ssize_t
@@ -156,8 +153,8 @@ xfs_file_splice_write(
156 size_t len, 153 size_t len,
157 unsigned int flags) 154 unsigned int flags)
158{ 155{
159 return bhv_vop_splice_write(vn_from_inode(outfilp->f_path.dentry->d_inode), 156 return xfs_splice_write(XFS_I(outfilp->f_path.dentry->d_inode),
160 pipe, outfilp, ppos, len, flags, 0, NULL); 157 pipe, outfilp, ppos, len, flags, 0);
161} 158}
162 159
163STATIC ssize_t 160STATIC ssize_t
@@ -168,9 +165,8 @@ xfs_file_splice_write_invis(
168 size_t len, 165 size_t len,
169 unsigned int flags) 166 unsigned int flags)
170{ 167{
171 return bhv_vop_splice_write(vn_from_inode(outfilp->f_path.dentry->d_inode), 168 return xfs_splice_write(XFS_I(outfilp->f_path.dentry->d_inode),
172 pipe, outfilp, ppos, len, flags, IO_INVIS, 169 pipe, outfilp, ppos, len, flags, IO_INVIS);
173 NULL);
174} 170}
175 171
176STATIC int 172STATIC int
@@ -180,7 +176,7 @@ xfs_file_open(
180{ 176{
181 if (!(filp->f_flags & O_LARGEFILE) && i_size_read(inode) > MAX_NON_LFS) 177 if (!(filp->f_flags & O_LARGEFILE) && i_size_read(inode) > MAX_NON_LFS)
182 return -EFBIG; 178 return -EFBIG;
183 return -bhv_vop_open(vn_from_inode(inode), NULL); 179 return -xfs_open(XFS_I(inode));
184} 180}
185 181
186STATIC int 182STATIC int
@@ -188,11 +184,7 @@ xfs_file_release(
188 struct inode *inode, 184 struct inode *inode,
189 struct file *filp) 185 struct file *filp)
190{ 186{
191 bhv_vnode_t *vp = vn_from_inode(inode); 187 return -xfs_release(XFS_I(inode));
192
193 if (vp)
194 return -bhv_vop_release(vp);
195 return 0;
196} 188}
197 189
198STATIC int 190STATIC int
@@ -201,14 +193,13 @@ xfs_file_fsync(
201 struct dentry *dentry, 193 struct dentry *dentry,
202 int datasync) 194 int datasync)
203{ 195{
204 bhv_vnode_t *vp = vn_from_inode(dentry->d_inode);
205 int flags = FSYNC_WAIT; 196 int flags = FSYNC_WAIT;
206 197
207 if (datasync) 198 if (datasync)
208 flags |= FSYNC_DATA; 199 flags |= FSYNC_DATA;
209 if (VN_TRUNC(vp)) 200 xfs_iflags_clear(XFS_I(dentry->d_inode), XFS_ITRUNCATED);
210 VUNTRUNCATE(vp); 201 return -xfs_fsync(XFS_I(dentry->d_inode), flags,
211 return -bhv_vop_fsync(vp, flags, NULL, (xfs_off_t)0, (xfs_off_t)-1); 202 (xfs_off_t)0, (xfs_off_t)-1);
212} 203}
213 204
214#ifdef CONFIG_XFS_DMAPI 205#ifdef CONFIG_XFS_DMAPI
@@ -233,74 +224,30 @@ xfs_file_readdir(
233 void *dirent, 224 void *dirent,
234 filldir_t filldir) 225 filldir_t filldir)
235{ 226{
236 int error = 0; 227 struct inode *inode = filp->f_path.dentry->d_inode;
237 bhv_vnode_t *vp = vn_from_inode(filp->f_path.dentry->d_inode); 228 xfs_inode_t *ip = XFS_I(inode);
238 uio_t uio; 229 int error;
239 iovec_t iov; 230 size_t bufsize;
240 int eof = 0; 231
241 caddr_t read_buf; 232 /*
242 int namelen, size = 0; 233 * The Linux API doesn't pass down the total size of the buffer
243 size_t rlen = PAGE_CACHE_SIZE; 234 * we read into down to the filesystem. With the filldir concept
244 xfs_off_t start_offset, curr_offset; 235 * it's not needed for correct information, but the XFS dir2 leaf
245 xfs_dirent_t *dbp = NULL; 236 * code wants an estimate of the buffer size to calculate it's
246 237 * readahead window and size the buffers used for mapping to
247 /* Try fairly hard to get memory */ 238 * physical blocks.
248 do { 239 *
249 if ((read_buf = kmalloc(rlen, GFP_KERNEL))) 240 * Try to give it an estimate that's good enough, maybe at some
250 break; 241 * point we can change the ->readdir prototype to include the
251 rlen >>= 1; 242 * buffer size.
252 } while (rlen >= 1024); 243 */
253 244 bufsize = (size_t)min_t(loff_t, PAGE_SIZE, inode->i_size);
254 if (read_buf == NULL)
255 return -ENOMEM;
256
257 uio.uio_iov = &iov;
258 uio.uio_segflg = UIO_SYSSPACE;
259 curr_offset = filp->f_pos;
260 if (filp->f_pos != 0x7fffffff)
261 uio.uio_offset = filp->f_pos;
262 else
263 uio.uio_offset = 0xffffffff;
264
265 while (!eof) {
266 uio.uio_resid = iov.iov_len = rlen;
267 iov.iov_base = read_buf;
268 uio.uio_iovcnt = 1;
269
270 start_offset = uio.uio_offset;
271
272 error = bhv_vop_readdir(vp, &uio, NULL, &eof);
273 if ((uio.uio_offset == start_offset) || error) {
274 size = 0;
275 break;
276 }
277
278 size = rlen - uio.uio_resid;
279 dbp = (xfs_dirent_t *)read_buf;
280 while (size > 0) {
281 namelen = strlen(dbp->d_name);
282
283 if (filldir(dirent, dbp->d_name, namelen,
284 (loff_t) curr_offset & 0x7fffffff,
285 (ino_t) dbp->d_ino,
286 DT_UNKNOWN)) {
287 goto done;
288 }
289 size -= dbp->d_reclen;
290 curr_offset = (loff_t)dbp->d_off /* & 0x7fffffff */;
291 dbp = (xfs_dirent_t *)((char *)dbp + dbp->d_reclen);
292 }
293 }
294done:
295 if (!error) {
296 if (size == 0)
297 filp->f_pos = uio.uio_offset & 0x7fffffff;
298 else if (dbp)
299 filp->f_pos = curr_offset;
300 }
301 245
302 kfree(read_buf); 246 error = xfs_readdir(ip, dirent, bufsize,
303 return -error; 247 (xfs_off_t *)&filp->f_pos, filldir);
248 if (error)
249 return -error;
250 return 0;
304} 251}
305 252
306STATIC int 253STATIC int
@@ -312,7 +259,7 @@ xfs_file_mmap(
312 vma->vm_flags |= VM_CAN_NONLINEAR; 259 vma->vm_flags |= VM_CAN_NONLINEAR;
313 260
314#ifdef CONFIG_XFS_DMAPI 261#ifdef CONFIG_XFS_DMAPI
315 if (vn_from_inode(filp->f_path.dentry->d_inode)->v_vfsp->vfs_flag & VFS_DMI) 262 if (XFS_M(filp->f_path.dentry->d_inode->i_sb)->m_flags & XFS_MOUNT_DMAPI)
316 vma->vm_ops = &xfs_dmapi_file_vm_ops; 263 vma->vm_ops = &xfs_dmapi_file_vm_ops;
317#endif /* CONFIG_XFS_DMAPI */ 264#endif /* CONFIG_XFS_DMAPI */
318 265
@@ -328,10 +275,9 @@ xfs_file_ioctl(
328{ 275{
329 int error; 276 int error;
330 struct inode *inode = filp->f_path.dentry->d_inode; 277 struct inode *inode = filp->f_path.dentry->d_inode;
331 bhv_vnode_t *vp = vn_from_inode(inode);
332 278
333 error = bhv_vop_ioctl(vp, inode, filp, 0, cmd, (void __user *)p); 279 error = xfs_ioctl(XFS_I(inode), filp, 0, cmd, (void __user *)p);
334 VMODIFY(vp); 280 xfs_iflags_set(XFS_I(inode), XFS_IMODIFIED);
335 281
336 /* NOTE: some of the ioctl's return positive #'s as a 282 /* NOTE: some of the ioctl's return positive #'s as a
337 * byte count indicating success, such as 283 * byte count indicating success, such as
@@ -350,10 +296,9 @@ xfs_file_ioctl_invis(
350{ 296{
351 int error; 297 int error;
352 struct inode *inode = filp->f_path.dentry->d_inode; 298 struct inode *inode = filp->f_path.dentry->d_inode;
353 bhv_vnode_t *vp = vn_from_inode(inode);
354 299
355 error = bhv_vop_ioctl(vp, inode, filp, IO_INVIS, cmd, (void __user *)p); 300 error = xfs_ioctl(XFS_I(inode), filp, IO_INVIS, cmd, (void __user *)p);
356 VMODIFY(vp); 301 xfs_iflags_set(XFS_I(inode), XFS_IMODIFIED);
357 302
358 /* NOTE: some of the ioctl's return positive #'s as a 303 /* NOTE: some of the ioctl's return positive #'s as a
359 * byte count indicating success, such as 304 * byte count indicating success, such as
@@ -371,16 +316,14 @@ xfs_vm_mprotect(
371 struct vm_area_struct *vma, 316 struct vm_area_struct *vma,
372 unsigned int newflags) 317 unsigned int newflags)
373{ 318{
374 bhv_vnode_t *vp = vn_from_inode(vma->vm_file->f_path.dentry->d_inode); 319 struct inode *inode = vma->vm_file->f_path.dentry->d_inode;
320 struct xfs_mount *mp = XFS_M(inode->i_sb);
375 int error = 0; 321 int error = 0;
376 322
377 if (vp->v_vfsp->vfs_flag & VFS_DMI) { 323 if (mp->m_flags & XFS_MOUNT_DMAPI) {
378 if ((vma->vm_flags & VM_MAYSHARE) && 324 if ((vma->vm_flags & VM_MAYSHARE) &&
379 (newflags & VM_WRITE) && !(vma->vm_flags & VM_WRITE)) { 325 (newflags & VM_WRITE) && !(vma->vm_flags & VM_WRITE))
380 xfs_mount_t *mp = XFS_VFSTOM(vp->v_vfsp);
381
382 error = XFS_SEND_MMAP(mp, vma, VM_WRITE); 326 error = XFS_SEND_MMAP(mp, vma, VM_WRITE);
383 }
384 } 327 }
385 return error; 328 return error;
386} 329}
@@ -397,18 +340,17 @@ STATIC int
397xfs_file_open_exec( 340xfs_file_open_exec(
398 struct inode *inode) 341 struct inode *inode)
399{ 342{
400 bhv_vnode_t *vp = vn_from_inode(inode); 343 struct xfs_mount *mp = XFS_M(inode->i_sb);
401 344
402 if (unlikely(vp->v_vfsp->vfs_flag & VFS_DMI)) { 345 if (unlikely(mp->m_flags & XFS_MOUNT_DMAPI)) {
403 xfs_mount_t *mp = XFS_VFSTOM(vp->v_vfsp); 346 if (DM_EVENT_ENABLED(XFS_I(inode), DM_EVENT_READ)) {
404 xfs_inode_t *ip = xfs_vtoi(vp); 347 bhv_vnode_t *vp = vn_from_inode(inode);
405 348
406 if (!ip) 349 return -XFS_SEND_DATA(mp, DM_EVENT_READ,
407 return -EINVAL; 350 vp, 0, 0, 0, NULL);
408 if (DM_EVENT_ENABLED(vp->v_vfsp, ip, DM_EVENT_READ)) 351 }
409 return -XFS_SEND_DATA(mp, DM_EVENT_READ, vp,
410 0, 0, 0, NULL);
411 } 352 }
353
412 return 0; 354 return 0;
413} 355}
414#endif /* HAVE_FOP_OPEN_EXEC */ 356#endif /* HAVE_FOP_OPEN_EXEC */