Merge branch 'for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/tj/percpu
[pandora-kernel.git] / fs / xfs / linux-2.6 / xfs_fs_subr.c
1 /*
2  * Copyright (c) 2000-2002,2005-2006 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_vnodeops.h"
20 #include "xfs_bmap_btree.h"
21 #include "xfs_inode.h"
22 #include "xfs_trace.h"
23
24 /*
25  * note: all filemap functions return negative error codes. These
26  * need to be inverted before returning to the xfs core functions.
27  */
28 void
29 xfs_tosspages(
30         xfs_inode_t     *ip,
31         xfs_off_t       first,
32         xfs_off_t       last,
33         int             fiopt)
34 {
35         struct address_space *mapping = VFS_I(ip)->i_mapping;
36
37         if (mapping->nrpages)
38                 truncate_inode_pages(mapping, first);
39 }
40
41 int
42 xfs_flushinval_pages(
43         xfs_inode_t     *ip,
44         xfs_off_t       first,
45         xfs_off_t       last,
46         int             fiopt)
47 {
48         struct address_space *mapping = VFS_I(ip)->i_mapping;
49         int             ret = 0;
50
51         trace_xfs_pagecache_inval(ip, first, last);
52
53         if (mapping->nrpages) {
54                 xfs_iflags_clear(ip, XFS_ITRUNCATED);
55                 ret = filemap_write_and_wait(mapping);
56                 if (!ret)
57                         truncate_inode_pages(mapping, first);
58         }
59         return -ret;
60 }
61
62 int
63 xfs_flush_pages(
64         xfs_inode_t     *ip,
65         xfs_off_t       first,
66         xfs_off_t       last,
67         uint64_t        flags,
68         int             fiopt)
69 {
70         struct address_space *mapping = VFS_I(ip)->i_mapping;
71         int             ret = 0;
72         int             ret2;
73
74         if (mapping_tagged(mapping, PAGECACHE_TAG_DIRTY)) {
75                 xfs_iflags_clear(ip, XFS_ITRUNCATED);
76                 ret = -filemap_fdatawrite(mapping);
77         }
78         if (flags & XBF_ASYNC)
79                 return ret;
80         ret2 = xfs_wait_on_pages(ip, first, last);
81         if (!ret)
82                 ret = ret2;
83         return ret;
84 }
85
86 int
87 xfs_wait_on_pages(
88         xfs_inode_t     *ip,
89         xfs_off_t       first,
90         xfs_off_t       last)
91 {
92         struct address_space *mapping = VFS_I(ip)->i_mapping;
93
94         if (mapping_tagged(mapping, PAGECACHE_TAG_WRITEBACK))
95                 return -filemap_fdatawait(mapping);
96         return 0;
97 }