Merge rsync://bughost.org/repos/ieee80211-delta/
[linux-2.6] / 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( void )
231 {
232         struct vfs              *vfsp;
233
234         vfsp = kmem_zalloc(sizeof(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         return vfsp;
240 }
241
242 void
243 vfs_deallocate(
244         struct vfs              *vfsp)
245 {
246         bhv_head_destroy(VFS_BHVHEAD(vfsp));
247         kmem_free(vfsp, sizeof(vfs_t));
248 }
249
250 void
251 vfs_insertops(
252         struct vfs              *vfsp,
253         struct bhv_vfsops       *vfsops)
254 {
255         struct bhv_desc         *bdp;
256
257         bdp = kmem_alloc(sizeof(struct bhv_desc), KM_SLEEP);
258         bhv_desc_init(bdp, NULL, vfsp, vfsops);
259         bhv_insert(&vfsp->vfs_bh, bdp);
260 }
261
262 void
263 vfs_insertbhv(
264         struct vfs              *vfsp,
265         struct bhv_desc         *bdp,
266         struct vfsops           *vfsops,
267         void                    *mount)
268 {
269         bhv_desc_init(bdp, mount, vfsp, vfsops);
270         bhv_insert_initial(&vfsp->vfs_bh, bdp);
271 }
272
273 void
274 bhv_remove_vfsops(
275         struct vfs              *vfsp,
276         int                     pos)
277 {
278         struct bhv_desc         *bhv;
279
280         bhv = bhv_lookup_range(&vfsp->vfs_bh, pos, pos);
281         if (!bhv)
282                 return;
283         bhv_remove(&vfsp->vfs_bh, bhv);
284         kmem_free(bhv, sizeof(*bhv));
285 }
286
287 void
288 bhv_remove_all_vfsops(
289         struct vfs              *vfsp,
290         int                     freebase)
291 {
292         struct xfs_mount        *mp;
293
294         bhv_remove_vfsops(vfsp, VFS_POSITION_QM);
295         bhv_remove_vfsops(vfsp, VFS_POSITION_DM);
296         if (!freebase)
297                 return;
298         mp = XFS_BHVTOM(bhv_lookup(VFS_BHVHEAD(vfsp), &xfs_vfsops));
299         VFS_REMOVEBHV(vfsp, &mp->m_bhv);
300         xfs_mount_free(mp, 0);
301 }
302
303 void
304 bhv_insert_all_vfsops(
305         struct vfs              *vfsp)
306 {
307         struct xfs_mount        *mp;
308
309         mp = xfs_mount_init();
310         vfs_insertbhv(vfsp, &mp->m_bhv, &xfs_vfsops, mp);
311         vfs_insertdmapi(vfsp);
312         vfs_insertquota(vfsp);
313 }