Merge to Fedora kernel-2.6.18-1.2224_FC5 patched with stable patch-2.6.18.1-vs2.0...
[linux-2.6.git] / fs / xfs / linux-2.6 / xfs_vfs.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_fs.h"
20 #include "xfs_inum.h"
21 #include "xfs_log.h"
22 #include "xfs_clnt.h"
23 #include "xfs_trans.h"
24 #include "xfs_sb.h"
25 #include "xfs_ag.h"
26 #include "xfs_dir2.h"
27 #include "xfs_imap.h"
28 #include "xfs_alloc.h"
29 #include "xfs_dmapi.h"
30 #include "xfs_mount.h"
31 #include "xfs_quota.h"
32
33 int
34 vfs_mount(
35         struct bhv_desc         *bdp,
36         struct xfs_mount_args   *args,
37         struct cred             *cr)
38 {
39         struct bhv_desc         *next = bdp;
40
41         ASSERT(next);
42         while (! (bhvtovfsops(next))->vfs_mount)
43                 next = BHV_NEXT(next);
44         return ((*bhvtovfsops(next)->vfs_mount)(next, args, cr));
45 }
46
47 int
48 vfs_parseargs(
49         struct bhv_desc         *bdp,
50         char                    *s,
51         struct xfs_mount_args   *args,
52         int                     f)
53 {
54         struct bhv_desc         *next = bdp;
55
56         ASSERT(next);
57         while (! (bhvtovfsops(next))->vfs_parseargs)
58                 next = BHV_NEXT(next);
59         return ((*bhvtovfsops(next)->vfs_parseargs)(next, s, args, f));
60 }
61
62 int
63 vfs_showargs(
64         struct bhv_desc         *bdp,
65         struct seq_file         *m)
66 {
67         struct bhv_desc         *next = bdp;
68
69         ASSERT(next);
70         while (! (bhvtovfsops(next))->vfs_showargs)
71                 next = BHV_NEXT(next);
72         return ((*bhvtovfsops(next)->vfs_showargs)(next, m));
73 }
74
75 int
76 vfs_unmount(
77         struct bhv_desc         *bdp,
78         int                     fl,
79         struct cred             *cr)
80 {
81         struct bhv_desc         *next = bdp;
82
83         ASSERT(next);
84         while (! (bhvtovfsops(next))->vfs_unmount)
85                 next = BHV_NEXT(next);
86         return ((*bhvtovfsops(next)->vfs_unmount)(next, fl, cr));
87 }
88
89 int
90 vfs_mntupdate(
91         struct bhv_desc         *bdp,
92         int                     *fl,
93         struct xfs_mount_args   *args)
94 {
95         struct bhv_desc         *next = bdp;
96
97         ASSERT(next);
98         while (! (bhvtovfsops(next))->vfs_mntupdate)
99                 next = BHV_NEXT(next);
100         return ((*bhvtovfsops(next)->vfs_mntupdate)(next, fl, args));
101 }
102
103 int
104 vfs_root(
105         struct bhv_desc         *bdp,
106         struct bhv_vnode        **vpp)
107 {
108         struct bhv_desc         *next = bdp;
109
110         ASSERT(next);
111         while (! (bhvtovfsops(next))->vfs_root)
112                 next = BHV_NEXT(next);
113         return ((*bhvtovfsops(next)->vfs_root)(next, vpp));
114 }
115
116 int
117 vfs_statvfs(
118         struct bhv_desc         *bdp,
119         bhv_statvfs_t           *statp,
120         struct bhv_vnode        *vp)
121 {
122         struct bhv_desc         *next = bdp;
123
124         ASSERT(next);
125         while (! (bhvtovfsops(next))->vfs_statvfs)
126                 next = BHV_NEXT(next);
127         return ((*bhvtovfsops(next)->vfs_statvfs)(next, statp, vp));
128 }
129
130 int
131 vfs_sync(
132         struct bhv_desc         *bdp,
133         int                     fl,
134         struct cred             *cr)
135 {
136         struct bhv_desc         *next = bdp;
137
138         ASSERT(next);
139         while (! (bhvtovfsops(next))->vfs_sync)
140                 next = BHV_NEXT(next);
141         return ((*bhvtovfsops(next)->vfs_sync)(next, fl, cr));
142 }
143
144 int
145 vfs_vget(
146         struct bhv_desc         *bdp,
147         struct bhv_vnode        **vpp,
148         struct fid              *fidp)
149 {
150         struct bhv_desc         *next = bdp;
151
152         ASSERT(next);
153         while (! (bhvtovfsops(next))->vfs_vget)
154                 next = BHV_NEXT(next);
155         return ((*bhvtovfsops(next)->vfs_vget)(next, vpp, fidp));
156 }
157
158 int
159 vfs_dmapiops(
160         struct bhv_desc         *bdp,
161         caddr_t                 addr)
162 {
163         struct bhv_desc         *next = bdp;
164
165         ASSERT(next);
166         while (! (bhvtovfsops(next))->vfs_dmapiops)
167                 next = BHV_NEXT(next);
168         return ((*bhvtovfsops(next)->vfs_dmapiops)(next, addr));
169 }
170
171 int
172 vfs_quotactl(
173         struct bhv_desc         *bdp,
174         int                     cmd,
175         int                     id,
176         caddr_t                 addr)
177 {
178         struct bhv_desc         *next = bdp;
179
180         ASSERT(next);
181         while (! (bhvtovfsops(next))->vfs_quotactl)
182                 next = BHV_NEXT(next);
183         return ((*bhvtovfsops(next)->vfs_quotactl)(next, cmd, id, addr));
184 }
185
186 void
187 vfs_init_vnode(
188         struct bhv_desc         *bdp,
189         struct bhv_vnode        *vp,
190         struct bhv_desc         *bp,
191         int                     unlock)
192 {
193         struct bhv_desc         *next = bdp;
194
195         ASSERT(next);
196         while (! (bhvtovfsops(next))->vfs_init_vnode)
197                 next = BHV_NEXT(next);
198         ((*bhvtovfsops(next)->vfs_init_vnode)(next, vp, bp, unlock));
199 }
200
201 void
202 vfs_force_shutdown(
203         struct bhv_desc         *bdp,
204         int                     fl,
205         char                    *file,
206         int                     line)
207 {
208         struct bhv_desc         *next = bdp;
209
210         ASSERT(next);
211         while (! (bhvtovfsops(next))->vfs_force_shutdown)
212                 next = BHV_NEXT(next);
213         ((*bhvtovfsops(next)->vfs_force_shutdown)(next, fl, file, line));
214 }
215
216 void
217 vfs_freeze(
218         struct bhv_desc         *bdp)
219 {
220         struct bhv_desc         *next = bdp;
221
222         ASSERT(next);
223         while (! (bhvtovfsops(next))->vfs_freeze)
224                 next = BHV_NEXT(next);
225         ((*bhvtovfsops(next)->vfs_freeze)(next));
226 }
227
228 bhv_vfs_t *
229 vfs_allocate(
230         struct super_block      *sb)
231 {
232         struct bhv_vfs          *vfsp;
233
234         vfsp = kmem_zalloc(sizeof(bhv_vfs_t), KM_SLEEP);
235         bhv_head_init(VFS_BHVHEAD(vfsp), "vfs");
236         INIT_LIST_HEAD(&vfsp->vfs_sync_list);
237         spin_lock_init(&vfsp->vfs_sync_lock);
238         init_waitqueue_head(&vfsp->vfs_wait_single_sync_task);
239
240         vfsp->vfs_super = sb;
241         sb->s_fs_info = vfsp;
242
243         if (sb->s_flags & MS_RDONLY)
244                 vfsp->vfs_flag |= VFS_RDONLY;
245
246         return vfsp;
247 }
248
249 bhv_vfs_t *
250 vfs_from_sb(
251         struct super_block      *sb)
252 {
253         return (bhv_vfs_t *)sb->s_fs_info;
254 }
255
256 void
257 vfs_deallocate(
258         struct bhv_vfs          *vfsp)
259 {
260         bhv_head_destroy(VFS_BHVHEAD(vfsp));
261         kmem_free(vfsp, sizeof(bhv_vfs_t));
262 }
263
264 void
265 vfs_insertops(
266         struct bhv_vfs          *vfsp,
267         struct bhv_module_vfsops *vfsops)
268 {
269         struct bhv_desc         *bdp;
270
271         bdp = kmem_alloc(sizeof(struct bhv_desc), KM_SLEEP);
272         bhv_desc_init(bdp, NULL, vfsp, vfsops);
273         bhv_insert(&vfsp->vfs_bh, bdp);
274 }
275
276 void
277 vfs_insertbhv(
278         struct bhv_vfs          *vfsp,
279         struct bhv_desc         *bdp,
280         struct bhv_vfsops       *vfsops,
281         void                    *mount)
282 {
283         bhv_desc_init(bdp, mount, vfsp, vfsops);
284         bhv_insert_initial(&vfsp->vfs_bh, bdp);
285 }
286
287 void
288 bhv_remove_vfsops(
289         struct bhv_vfs          *vfsp,
290         int                     pos)
291 {
292         struct bhv_desc         *bhv;
293
294         bhv = bhv_lookup_range(&vfsp->vfs_bh, pos, pos);
295         if (!bhv)
296                 return;
297         bhv_remove(&vfsp->vfs_bh, bhv);
298         kmem_free(bhv, sizeof(*bhv));
299 }
300
301 void
302 bhv_remove_all_vfsops(
303         struct bhv_vfs          *vfsp,
304         int                     freebase)
305 {
306         struct xfs_mount        *mp;
307
308         bhv_remove_vfsops(vfsp, VFS_POSITION_QM);
309         bhv_remove_vfsops(vfsp, VFS_POSITION_DM);
310         if (!freebase)
311                 return;
312         mp = XFS_VFSTOM(vfsp);
313         VFS_REMOVEBHV(vfsp, &mp->m_bhv);
314         xfs_mount_free(mp, 0);
315 }
316
317 void
318 bhv_insert_all_vfsops(
319         struct bhv_vfs          *vfsp)
320 {
321         struct xfs_mount        *mp;
322
323         mp = xfs_mount_init();
324         vfs_insertbhv(vfsp, &mp->m_bhv, &xfs_vfsops, mp);
325         vfs_insertdmapi(vfsp);
326         vfs_insertquota(vfsp);
327 }