diff options
Diffstat (limited to 'fs/xfs/linux-2.6/xfs_file.c')
-rw-r--r-- | fs/xfs/linux-2.6/xfs_file.c | 174 |
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 | ||
67 | STATIC ssize_t | 67 | STATIC 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 | ||
106 | STATIC ssize_t | 104 | STATIC 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 | ||
138 | STATIC ssize_t | 136 | STATIC 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 | ||
151 | STATIC ssize_t | 148 | STATIC 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 | ||
163 | STATIC ssize_t | 160 | STATIC 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 | ||
176 | STATIC int | 172 | STATIC 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 | ||
186 | STATIC int | 182 | STATIC 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 | ||
198 | STATIC int | 190 | STATIC 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 | } | ||
294 | done: | ||
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 | ||
306 | STATIC int | 253 | STATIC 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 | |||
397 | xfs_file_open_exec( | 340 | xfs_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 */ |