]> err.no Git - linux-2.6/blob - fs/xfs/linux-2.6/xfs_file.c
[XFS] Remove unnecessary local from open_exec dmapi path.
[linux-2.6] / fs / xfs / linux-2.6 / xfs_file.c
1 /*
2  * Copyright (c) 2000-2005 Silicon Graphics, Inc.
3  * All Rights Reserved.
4  *
5  * This program is free software; you can redistribute it and/or
6  * modify it under the terms of the GNU General Public License as
7  * published by the Free Software Foundation.
8  *
9  * This program is distributed in the hope that it would be useful,
10  * but WITHOUT ANY WARRANTY; without even the implied warranty of
11  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
12  * GNU General Public License for more details.
13  *
14  * You should have received a copy of the GNU General Public License
15  * along with this program; if not, write the Free Software Foundation,
16  * Inc.,  51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
17  */
18 #include "xfs.h"
19 #include "xfs_bit.h"
20 #include "xfs_log.h"
21 #include "xfs_inum.h"
22 #include "xfs_sb.h"
23 #include "xfs_ag.h"
24 #include "xfs_dir.h"
25 #include "xfs_dir2.h"
26 #include "xfs_trans.h"
27 #include "xfs_dmapi.h"
28 #include "xfs_mount.h"
29 #include "xfs_bmap_btree.h"
30 #include "xfs_alloc_btree.h"
31 #include "xfs_ialloc_btree.h"
32 #include "xfs_alloc.h"
33 #include "xfs_btree.h"
34 #include "xfs_attr_sf.h"
35 #include "xfs_dir_sf.h"
36 #include "xfs_dir2_sf.h"
37 #include "xfs_dinode.h"
38 #include "xfs_inode.h"
39 #include "xfs_error.h"
40 #include "xfs_rw.h"
41 #include "xfs_ioctl32.h"
42
43 #include <linux/dcache.h>
44 #include <linux/smp_lock.h>
45
46 static struct vm_operations_struct xfs_file_vm_ops;
47 #ifdef CONFIG_XFS_DMAPI
48 static struct vm_operations_struct xfs_dmapi_file_vm_ops;
49 #endif
50
51 STATIC inline ssize_t
52 __xfs_file_read(
53         struct kiocb            *iocb,
54         char                    __user *buf,
55         int                     ioflags,
56         size_t                  count,
57         loff_t                  pos)
58 {
59         struct iovec            iov = {buf, count};
60         struct file             *file = iocb->ki_filp;
61         bhv_vnode_t             *vp = vn_from_inode(file->f_dentry->d_inode);
62
63         BUG_ON(iocb->ki_pos != pos);
64         if (unlikely(file->f_flags & O_DIRECT))
65                 ioflags |= IO_ISDIRECT;
66         return bhv_vop_read(vp, iocb, &iov, 1, &iocb->ki_pos, ioflags, NULL);
67 }
68
69 STATIC ssize_t
70 xfs_file_aio_read(
71         struct kiocb            *iocb,
72         char                    __user *buf,
73         size_t                  count,
74         loff_t                  pos)
75 {
76         return __xfs_file_read(iocb, buf, IO_ISAIO, count, pos);
77 }
78
79 STATIC ssize_t
80 xfs_file_aio_read_invis(
81         struct kiocb            *iocb,
82         char                    __user *buf,
83         size_t                  count,
84         loff_t                  pos)
85 {
86         return __xfs_file_read(iocb, buf, IO_ISAIO|IO_INVIS, count, pos);
87 }
88
89 STATIC inline ssize_t
90 __xfs_file_write(
91         struct kiocb    *iocb,
92         const char      __user *buf,
93         int             ioflags,
94         size_t          count,
95         loff_t          pos)
96 {
97         struct iovec    iov = {(void __user *)buf, count};
98         struct file     *file = iocb->ki_filp;
99         struct inode    *inode = file->f_mapping->host;
100         bhv_vnode_t     *vp = vn_from_inode(inode);
101
102         BUG_ON(iocb->ki_pos != pos);
103         if (unlikely(file->f_flags & O_DIRECT))
104                 ioflags |= IO_ISDIRECT;
105         return bhv_vop_write(vp, iocb, &iov, 1, &iocb->ki_pos, ioflags, NULL);
106 }
107
108 STATIC ssize_t
109 xfs_file_aio_write(
110         struct kiocb            *iocb,
111         const char              __user *buf,
112         size_t                  count,
113         loff_t                  pos)
114 {
115         return __xfs_file_write(iocb, buf, IO_ISAIO, count, pos);
116 }
117
118 STATIC ssize_t
119 xfs_file_aio_write_invis(
120         struct kiocb            *iocb,
121         const char              __user *buf,
122         size_t                  count,
123         loff_t                  pos)
124 {
125         return __xfs_file_write(iocb, buf, IO_ISAIO|IO_INVIS, count, pos);
126 }
127
128 STATIC inline ssize_t
129 __xfs_file_readv(
130         struct file             *file,
131         const struct iovec      *iov,
132         int                     ioflags,
133         unsigned long           nr_segs,
134         loff_t                  *ppos)
135 {
136         struct inode    *inode = file->f_mapping->host;
137         bhv_vnode_t     *vp = vn_from_inode(inode);
138         struct kiocb    kiocb;
139         ssize_t         rval;
140
141         init_sync_kiocb(&kiocb, file);
142         kiocb.ki_pos = *ppos;
143
144         if (unlikely(file->f_flags & O_DIRECT))
145                 ioflags |= IO_ISDIRECT;
146         rval = bhv_vop_read(vp, &kiocb, iov, nr_segs,
147                                 &kiocb.ki_pos, ioflags, NULL);
148
149         *ppos = kiocb.ki_pos;
150         return rval;
151 }
152
153 STATIC ssize_t
154 xfs_file_readv(
155         struct file             *file,
156         const struct iovec      *iov,
157         unsigned long           nr_segs,
158         loff_t                  *ppos)
159 {
160         return __xfs_file_readv(file, iov, 0, nr_segs, ppos);
161 }
162
163 STATIC ssize_t
164 xfs_file_readv_invis(
165         struct file             *file,
166         const struct iovec      *iov,
167         unsigned long           nr_segs,
168         loff_t                  *ppos)
169 {
170         return __xfs_file_readv(file, iov, IO_INVIS, nr_segs, ppos);
171 }
172
173 STATIC inline ssize_t
174 __xfs_file_writev(
175         struct file             *file,
176         const struct iovec      *iov,
177         int                     ioflags,
178         unsigned long           nr_segs,
179         loff_t                  *ppos)
180 {
181         struct inode    *inode = file->f_mapping->host;
182         bhv_vnode_t     *vp = vn_from_inode(inode);
183         struct kiocb    kiocb;
184         ssize_t         rval;
185
186         init_sync_kiocb(&kiocb, file);
187         kiocb.ki_pos = *ppos;
188         if (unlikely(file->f_flags & O_DIRECT))
189                 ioflags |= IO_ISDIRECT;
190
191         rval = bhv_vop_write(vp, &kiocb, iov, nr_segs,
192                                  &kiocb.ki_pos, ioflags, NULL);
193
194         *ppos = kiocb.ki_pos;
195         return rval;
196 }
197
198 STATIC ssize_t
199 xfs_file_writev(
200         struct file             *file,
201         const struct iovec      *iov,
202         unsigned long           nr_segs,
203         loff_t                  *ppos)
204 {
205         return __xfs_file_writev(file, iov, 0, nr_segs, ppos);
206 }
207
208 STATIC ssize_t
209 xfs_file_writev_invis(
210         struct file             *file,
211         const struct iovec      *iov,
212         unsigned long           nr_segs,
213         loff_t                  *ppos)
214 {
215         return __xfs_file_writev(file, iov, IO_INVIS, nr_segs, ppos);
216 }
217
218 STATIC ssize_t
219 xfs_file_sendfile(
220         struct file             *filp,
221         loff_t                  *pos,
222         size_t                  count,
223         read_actor_t            actor,
224         void                    *target)
225 {
226         return bhv_vop_sendfile(vn_from_inode(filp->f_dentry->d_inode),
227                                 filp, pos, 0, count, actor, target, NULL);
228 }
229
230 STATIC ssize_t
231 xfs_file_sendfile_invis(
232         struct file             *filp,
233         loff_t                  *pos,
234         size_t                  count,
235         read_actor_t            actor,
236         void                    *target)
237 {
238         return bhv_vop_sendfile(vn_from_inode(filp->f_dentry->d_inode),
239                                 filp, pos, IO_INVIS, count, actor, target, NULL);
240 }
241
242 STATIC ssize_t
243 xfs_file_splice_read(
244         struct file             *infilp,
245         loff_t                  *ppos,
246         struct pipe_inode_info  *pipe,
247         size_t                  len,
248         unsigned int            flags)
249 {
250         return bhv_vop_splice_read(vn_from_inode(infilp->f_dentry->d_inode),
251                                    infilp, ppos, pipe, len, flags, 0, NULL);
252 }
253
254 STATIC ssize_t
255 xfs_file_splice_read_invis(
256         struct file             *infilp,
257         loff_t                  *ppos,
258         struct pipe_inode_info  *pipe,
259         size_t                  len,
260         unsigned int            flags)
261 {
262         return bhv_vop_splice_read(vn_from_inode(infilp->f_dentry->d_inode),
263                                    infilp, ppos, pipe, len, flags, IO_INVIS,
264                                    NULL);
265 }
266
267 STATIC ssize_t
268 xfs_file_splice_write(
269         struct pipe_inode_info  *pipe,
270         struct file             *outfilp,
271         loff_t                  *ppos,
272         size_t                  len,
273         unsigned int            flags)
274 {
275         return bhv_vop_splice_write(vn_from_inode(outfilp->f_dentry->d_inode),
276                                     pipe, outfilp, ppos, len, flags, 0, NULL);
277 }
278
279 STATIC ssize_t
280 xfs_file_splice_write_invis(
281         struct pipe_inode_info  *pipe,
282         struct file             *outfilp,
283         loff_t                  *ppos,
284         size_t                  len,
285         unsigned int            flags)
286 {
287         return bhv_vop_splice_write(vn_from_inode(outfilp->f_dentry->d_inode),
288                                     pipe, outfilp, ppos, len, flags, IO_INVIS,
289                                     NULL);
290 }
291
292 STATIC int
293 xfs_file_open(
294         struct inode    *inode,
295         struct file     *filp)
296 {
297         if (!(filp->f_flags & O_LARGEFILE) && i_size_read(inode) > MAX_NON_LFS)
298                 return -EFBIG;
299         return -bhv_vop_open(vn_from_inode(inode), NULL);
300 }
301
302 STATIC int
303 xfs_file_close(
304         struct file     *filp)
305 {
306         return -bhv_vop_close(vn_from_inode(filp->f_dentry->d_inode), 0,
307                                 file_count(filp) > 1 ? L_FALSE : L_TRUE, NULL);
308 }
309
310 STATIC int
311 xfs_file_release(
312         struct inode    *inode,
313         struct file     *filp)
314 {
315         bhv_vnode_t     *vp = vn_from_inode(inode);
316
317         if (vp)
318                 return -bhv_vop_release(vp);
319         return 0;
320 }
321
322 STATIC int
323 xfs_file_fsync(
324         struct file     *filp,
325         struct dentry   *dentry,
326         int             datasync)
327 {
328         bhv_vnode_t     *vp = vn_from_inode(dentry->d_inode);
329         int             flags = FSYNC_WAIT;
330
331         if (datasync)
332                 flags |= FSYNC_DATA;
333         if (VN_TRUNC(vp))
334                 VUNTRUNCATE(vp);
335         return -bhv_vop_fsync(vp, flags, NULL, (xfs_off_t)0, (xfs_off_t)-1);
336 }
337
338 #ifdef CONFIG_XFS_DMAPI
339 STATIC struct page *
340 xfs_vm_nopage(
341         struct vm_area_struct   *area,
342         unsigned long           address,
343         int                     *type)
344 {
345         struct inode    *inode = area->vm_file->f_dentry->d_inode;
346         bhv_vnode_t     *vp = vn_from_inode(inode);
347
348         ASSERT_ALWAYS(vp->v_vfsp->vfs_flag & VFS_DMI);
349         if (XFS_SEND_MMAP(XFS_VFSTOM(vp->v_vfsp), area, 0))
350                 return NULL;
351         return filemap_nopage(area, address, type);
352 }
353 #endif /* CONFIG_XFS_DMAPI */
354
355 STATIC int
356 xfs_file_readdir(
357         struct file     *filp,
358         void            *dirent,
359         filldir_t       filldir)
360 {
361         int             error = 0;
362         bhv_vnode_t     *vp = vn_from_inode(filp->f_dentry->d_inode);
363         uio_t           uio;
364         iovec_t         iov;
365         int             eof = 0;
366         caddr_t         read_buf;
367         int             namelen, size = 0;
368         size_t          rlen = PAGE_CACHE_SIZE;
369         xfs_off_t       start_offset, curr_offset;
370         xfs_dirent_t    *dbp = NULL;
371
372         /* Try fairly hard to get memory */
373         do {
374                 if ((read_buf = (caddr_t)kmalloc(rlen, GFP_KERNEL)))
375                         break;
376                 rlen >>= 1;
377         } while (rlen >= 1024);
378
379         if (read_buf == NULL)
380                 return -ENOMEM;
381
382         uio.uio_iov = &iov;
383         uio.uio_segflg = UIO_SYSSPACE;
384         curr_offset = filp->f_pos;
385         if (filp->f_pos != 0x7fffffff)
386                 uio.uio_offset = filp->f_pos;
387         else
388                 uio.uio_offset = 0xffffffff;
389
390         while (!eof) {
391                 uio.uio_resid = iov.iov_len = rlen;
392                 iov.iov_base = read_buf;
393                 uio.uio_iovcnt = 1;
394
395                 start_offset = uio.uio_offset;
396
397                 error = bhv_vop_readdir(vp, &uio, NULL, &eof);
398                 if ((uio.uio_offset == start_offset) || error) {
399                         size = 0;
400                         break;
401                 }
402
403                 size = rlen - uio.uio_resid;
404                 dbp = (xfs_dirent_t *)read_buf;
405                 while (size > 0) {
406                         namelen = strlen(dbp->d_name);
407
408                         if (filldir(dirent, dbp->d_name, namelen,
409                                         (loff_t) curr_offset & 0x7fffffff,
410                                         (ino_t) dbp->d_ino,
411                                         DT_UNKNOWN)) {
412                                 goto done;
413                         }
414                         size -= dbp->d_reclen;
415                         curr_offset = (loff_t)dbp->d_off /* & 0x7fffffff */;
416                         dbp = (xfs_dirent_t *)((char *)dbp + dbp->d_reclen);
417                 }
418         }
419 done:
420         if (!error) {
421                 if (size == 0)
422                         filp->f_pos = uio.uio_offset & 0x7fffffff;
423                 else if (dbp)
424                         filp->f_pos = curr_offset;
425         }
426
427         kfree(read_buf);
428         return -error;
429 }
430
431 STATIC int
432 xfs_file_mmap(
433         struct file     *filp,
434         struct vm_area_struct *vma)
435 {
436         vma->vm_ops = &xfs_file_vm_ops;
437
438 #ifdef CONFIG_XFS_DMAPI
439         if (vn_from_inode(filp->f_dentry->d_inode)->v_vfsp->vfs_flag & VFS_DMI)
440                 vma->vm_ops = &xfs_dmapi_file_vm_ops;
441 #endif /* CONFIG_XFS_DMAPI */
442
443         file_accessed(filp);
444         return 0;
445 }
446
447 STATIC long
448 xfs_file_ioctl(
449         struct file     *filp,
450         unsigned int    cmd,
451         unsigned long   p)
452 {
453         int             error;
454         struct inode    *inode = filp->f_dentry->d_inode;
455         bhv_vnode_t     *vp = vn_from_inode(inode);
456
457         error = bhv_vop_ioctl(vp, inode, filp, 0, cmd, (void __user *)p);
458         VMODIFY(vp);
459
460         /* NOTE:  some of the ioctl's return positive #'s as a
461          *        byte count indicating success, such as
462          *        readlink_by_handle.  So we don't "sign flip"
463          *        like most other routines.  This means true
464          *        errors need to be returned as a negative value.
465          */
466         return error;
467 }
468
469 STATIC long
470 xfs_file_ioctl_invis(
471         struct file     *filp,
472         unsigned int    cmd,
473         unsigned long   p)
474 {
475         int             error;
476         struct inode    *inode = filp->f_dentry->d_inode;
477         bhv_vnode_t     *vp = vn_from_inode(inode);
478
479         error = bhv_vop_ioctl(vp, inode, filp, IO_INVIS, cmd, (void __user *)p);
480         VMODIFY(vp);
481
482         /* NOTE:  some of the ioctl's return positive #'s as a
483          *        byte count indicating success, such as
484          *        readlink_by_handle.  So we don't "sign flip"
485          *        like most other routines.  This means true
486          *        errors need to be returned as a negative value.
487          */
488         return error;
489 }
490
491 #ifdef CONFIG_XFS_DMAPI
492 #ifdef HAVE_VMOP_MPROTECT
493 STATIC int
494 xfs_vm_mprotect(
495         struct vm_area_struct *vma,
496         unsigned int    newflags)
497 {
498         bhv_vnode_t     *vp = vn_from_inode(vma->vm_file->f_dentry->d_inode);
499         int             error = 0;
500
501         if (vp->v_vfsp->vfs_flag & VFS_DMI) {
502                 if ((vma->vm_flags & VM_MAYSHARE) &&
503                     (newflags & VM_WRITE) && !(vma->vm_flags & VM_WRITE)) {
504                         xfs_mount_t     *mp = XFS_VFSTOM(vp->v_vfsp);
505
506                         error = XFS_SEND_MMAP(mp, vma, VM_WRITE);
507                     }
508         }
509         return error;
510 }
511 #endif /* HAVE_VMOP_MPROTECT */
512 #endif /* CONFIG_XFS_DMAPI */
513
514 #ifdef HAVE_FOP_OPEN_EXEC
515 /* If the user is attempting to execute a file that is offline then
516  * we have to trigger a DMAPI READ event before the file is marked as busy
517  * otherwise the invisible I/O will not be able to write to the file to bring
518  * it back online.
519  */
520 STATIC int
521 xfs_file_open_exec(
522         struct inode    *inode)
523 {
524         bhv_vnode_t     *vp = vn_from_inode(inode);
525
526         if (unlikely(vp->v_vfsp->vfs_flag & VFS_DMI)) {
527                 xfs_mount_t     *mp = XFS_VFSTOM(vp->v_vfsp);
528                 xfs_inode_t     *ip = xfs_vtoi(vp);
529
530                 if (!ip)
531                         return -EINVAL;
532                 if (DM_EVENT_ENABLED(vp->v_vfsp, ip, DM_EVENT_READ))
533                         return -XFS_SEND_DATA(mp, DM_EVENT_READ, vp,
534                                                0, 0, 0, NULL);
535         }
536         return 0;
537 }
538 #endif /* HAVE_FOP_OPEN_EXEC */
539
540 const struct file_operations xfs_file_operations = {
541         .llseek         = generic_file_llseek,
542         .read           = do_sync_read,
543         .write          = do_sync_write,
544         .readv          = xfs_file_readv,
545         .writev         = xfs_file_writev,
546         .aio_read       = xfs_file_aio_read,
547         .aio_write      = xfs_file_aio_write,
548         .sendfile       = xfs_file_sendfile,
549         .splice_read    = xfs_file_splice_read,
550         .splice_write   = xfs_file_splice_write,
551         .unlocked_ioctl = xfs_file_ioctl,
552 #ifdef CONFIG_COMPAT
553         .compat_ioctl   = xfs_file_compat_ioctl,
554 #endif
555         .mmap           = xfs_file_mmap,
556         .open           = xfs_file_open,
557         .flush          = xfs_file_close,
558         .release        = xfs_file_release,
559         .fsync          = xfs_file_fsync,
560 #ifdef HAVE_FOP_OPEN_EXEC
561         .open_exec      = xfs_file_open_exec,
562 #endif
563 };
564
565 const struct file_operations xfs_invis_file_operations = {
566         .llseek         = generic_file_llseek,
567         .read           = do_sync_read,
568         .write          = do_sync_write,
569         .readv          = xfs_file_readv_invis,
570         .writev         = xfs_file_writev_invis,
571         .aio_read       = xfs_file_aio_read_invis,
572         .aio_write      = xfs_file_aio_write_invis,
573         .sendfile       = xfs_file_sendfile_invis,
574         .splice_read    = xfs_file_splice_read_invis,
575         .splice_write   = xfs_file_splice_write_invis,
576         .unlocked_ioctl = xfs_file_ioctl_invis,
577 #ifdef CONFIG_COMPAT
578         .compat_ioctl   = xfs_file_compat_invis_ioctl,
579 #endif
580         .mmap           = xfs_file_mmap,
581         .open           = xfs_file_open,
582         .flush          = xfs_file_close,
583         .release        = xfs_file_release,
584         .fsync          = xfs_file_fsync,
585 };
586
587
588 const struct file_operations xfs_dir_file_operations = {
589         .read           = generic_read_dir,
590         .readdir        = xfs_file_readdir,
591         .unlocked_ioctl = xfs_file_ioctl,
592 #ifdef CONFIG_COMPAT
593         .compat_ioctl   = xfs_file_compat_ioctl,
594 #endif
595         .fsync          = xfs_file_fsync,
596 };
597
598 static struct vm_operations_struct xfs_file_vm_ops = {
599         .nopage         = filemap_nopage,
600         .populate       = filemap_populate,
601 };
602
603 #ifdef CONFIG_XFS_DMAPI
604 static struct vm_operations_struct xfs_dmapi_file_vm_ops = {
605         .nopage         = xfs_vm_nopage,
606         .populate       = filemap_populate,
607 #ifdef HAVE_VMOP_MPROTECT
608         .mprotect       = xfs_vm_mprotect,
609 #endif
610 };
611 #endif /* CONFIG_XFS_DMAPI */