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