Add the DragonFly cvs id and perform general cleanups on cvs/rcs/sccs ids. Most
[dragonfly.git] / sys / vfs / gnu / ext2fs / ext2_alloc.c
1 /*
2  *  modified for Lites 1.1
3  *
4  *  Aug 1995, Godmar Back (gback@cs.utah.edu)
5  *  University of Utah, Department of Computer Science
6  */
7 /*
8  * Copyright (c) 1982, 1986, 1989, 1993
9  *      The Regents of the University of California.  All rights reserved.
10  *
11  * Redistribution and use in source and binary forms, with or without
12  * modification, are permitted provided that the following conditions
13  * are met:
14  * 1. Redistributions of source code must retain the above copyright
15  *    notice, this list of conditions and the following disclaimer.
16  * 2. Redistributions in binary form must reproduce the above copyright
17  *    notice, this list of conditions and the following disclaimer in the
18  *    documentation and/or other materials provided with the distribution.
19  * 3. All advertising materials mentioning features or use of this software
20  *    must display the following acknowledgement:
21  *      This product includes software developed by the University of
22  *      California, Berkeley and its contributors.
23  * 4. Neither the name of the University nor the names of its contributors
24  *    may be used to endorse or promote products derived from this software
25  *    without specific prior written permission.
26  *
27  * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
28  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
29  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
30  * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
31  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
32  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
33  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
34  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
35  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
36  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
37  * SUCH DAMAGE.
38  *
39  *      @(#)ext2_alloc.c        8.8 (Berkeley) 2/21/94
40  * $FreeBSD: src/sys/gnu/ext2fs/ext2_alloc.c,v 1.28.2.2 2002/07/01 00:18:51 iedowse Exp $
41  * $DragonFly: src/sys/vfs/gnu/ext2fs/ext2_alloc.c,v 1.2 2003/06/17 04:28:33 dillon Exp $
42  */
43
44 #include "opt_quota.h"
45
46 #include <sys/param.h>
47 #include <sys/systm.h>
48 #include <sys/conf.h>
49 #include <sys/vnode.h>
50 #include <sys/stat.h>
51 #include <sys/mount.h>
52 #include <sys/syslog.h>
53
54 #include <ufs/ufs/quota.h>
55 #include <ufs/ufs/inode.h>
56 #include <ufs/ufs/ufsmount.h>
57
58 #include <gnu/ext2fs/ext2_fs.h>
59 #include <gnu/ext2fs/ext2_fs_sb.h>
60 #include <gnu/ext2fs/fs.h>
61 #include <gnu/ext2fs/ext2_extern.h>
62
63 static void     ext2_fserr __P((struct ext2_sb_info *, u_int, char *));
64
65 /*
66  * Linux calls this functions at the following locations:
67  * (1) the inode is freed
68  * (2) a preallocation miss occurs
69  * (3) truncate is called
70  * (4) release_file is called and f_mode & 2
71  *
72  * I call it in ext2_inactive, ext2_truncate, ext2_vfree and in (2)
73  * the call in vfree might be redundant
74  */
75 void
76 ext2_discard_prealloc(ip)
77         struct inode * ip;
78 {
79 #ifdef EXT2_PREALLOCATE
80         if (ip->i_prealloc_count) {
81                 int i = ip->i_prealloc_count;
82                 ip->i_prealloc_count = 0;
83                 ext2_free_blocks (ITOV(ip)->v_mount,
84                                   ip->i_prealloc_block,
85                                   i);
86         }
87 #endif
88 }
89
90 /*
91  * Allocate a block in the file system.
92  * 
93  * this takes the framework from ffs_alloc. To implement the
94  * actual allocation, it calls ext2_new_block, the ported version
95  * of the same Linux routine.
96  *
97  * we note that this is always called in connection with ext2_blkpref
98  *
99  * preallocation is done as Linux does it
100  */
101 int
102 ext2_alloc(ip, lbn, bpref, size, cred, bnp)
103         register struct inode *ip;
104         daddr_t lbn, bpref;
105         int size;
106         struct ucred *cred;
107         daddr_t *bnp;
108 {
109         register struct ext2_sb_info *fs;
110         daddr_t bno;
111 #if QUOTA
112         int error;
113 #endif
114         
115         *bnp = 0;
116         fs = ip->i_e2fs;
117 #if DIAGNOSTIC
118         if ((u_int)size > fs->s_blocksize || blkoff(fs, size) != 0) {
119                 printf("dev = %s, bsize = %lu, size = %d, fs = %s\n",
120                     devtoname(ip->i_dev), fs->s_blocksize, size, fs->fs_fsmnt);
121                 panic("ext2_alloc: bad size");
122         }
123         if (cred == NOCRED)
124                 panic("ext2_alloc: missing credential");
125 #endif /* DIAGNOSTIC */
126         if (size == fs->s_blocksize && fs->s_es->s_free_blocks_count == 0)
127                 goto nospace;
128         if (cred->cr_uid != 0 && 
129                 fs->s_es->s_free_blocks_count < fs->s_es->s_r_blocks_count)
130                 goto nospace;
131 #if QUOTA
132         if ((error = chkdq(ip, (long)btodb(size), cred, 0)) != 0)
133                 return (error);
134 #endif
135         if (bpref >= fs->s_es->s_blocks_count)
136                 bpref = 0;
137         /* call the Linux code */
138 #ifdef EXT2_PREALLOCATE
139         /* To have a preallocation hit, we must
140          * - have at least one block preallocated
141          * - and our preferred block must have that block number or one below
142          */
143         if (ip->i_prealloc_count &&
144             (bpref == ip->i_prealloc_block ||
145              bpref + 1 == ip->i_prealloc_block))
146         {
147                 bno = ip->i_prealloc_block++;
148                 ip->i_prealloc_count--;
149                 /* ext2_debug ("preallocation hit (%lu/%lu).\n",
150                             ++alloc_hits, ++alloc_attempts); */
151
152                 /* Linux gets, clears, and releases the buffer at this
153                    point - we don't have to that; we leave it to the caller
154                  */
155         } else {
156                 ext2_discard_prealloc (ip);
157                 /* ext2_debug ("preallocation miss (%lu/%lu).\n",
158                             alloc_hits, ++alloc_attempts); */
159                 if (S_ISREG(ip->i_mode))
160                         bno = ext2_new_block
161                                 (ITOV(ip)->v_mount, bpref,
162                                  &ip->i_prealloc_count,
163                                  &ip->i_prealloc_block);
164                 else
165                         bno = (daddr_t)ext2_new_block(ITOV(ip)->v_mount, 
166                                         bpref, 0, 0);
167         }
168 #else
169         bno = (daddr_t)ext2_new_block(ITOV(ip)->v_mount, bpref, 0, 0);
170 #endif
171
172         if (bno > 0) {
173                 /* set next_alloc fields as done in block_getblk */
174                 ip->i_next_alloc_block = lbn;
175                 ip->i_next_alloc_goal = bno;
176
177                 ip->i_blocks += btodb(size);
178                 ip->i_flag |= IN_CHANGE | IN_UPDATE;
179                 *bnp = bno;
180                 return (0);
181         }
182 #if QUOTA
183         /*
184          * Restore user's disk quota because allocation failed.
185          */
186         (void) chkdq(ip, (long)-btodb(size), cred, FORCE);
187 #endif
188 nospace:
189         ext2_fserr(fs, cred->cr_uid, "file system full");
190         uprintf("\n%s: write failed, file system is full\n", fs->fs_fsmnt);
191         return (ENOSPC);
192 }
193
194 /*
195  * Reallocate a sequence of blocks into a contiguous sequence of blocks.
196  *
197  * The vnode and an array of buffer pointers for a range of sequential
198  * logical blocks to be made contiguous is given. The allocator attempts
199  * to find a range of sequential blocks starting as close as possible to
200  * an fs_rotdelay offset from the end of the allocation for the logical
201  * block immediately preceeding the current range. If successful, the
202  * physical block numbers in the buffer pointers and in the inode are
203  * changed to reflect the new allocation. If unsuccessful, the allocation
204  * is left unchanged. The success in doing the reallocation is returned.
205  * Note that the error return is not reflected back to the user. Rather
206  * the previous block allocation will be used.
207  */
208
209 #ifdef FANCY_REALLOC
210 #include <sys/sysctl.h>
211 static int doasyncfree = 1;
212 #ifdef  OPT_DEBUG
213 SYSCTL_INT(_debug, 14, doasyncfree, CTLFLAG_RW, &doasyncfree, 0, "");
214 #endif  /* OPT_DEBUG */
215 #endif
216
217 int
218 ext2_reallocblks(ap)
219         struct vop_reallocblks_args /* {
220                 struct vnode *a_vp;
221                 struct cluster_save *a_buflist;
222         } */ *ap;
223 {
224 #ifndef FANCY_REALLOC
225 /* printf("ext2_reallocblks not implemented\n"); */
226 return ENOSPC;
227 #else
228
229         struct ext2_sb_info *fs;
230         struct inode *ip;
231         struct vnode *vp;
232         struct buf *sbp, *ebp;
233         daddr_t *bap, *sbap, *ebap;
234         struct cluster_save *buflist;
235         daddr_t start_lbn, end_lbn, soff, eoff, newblk, blkno;
236         struct indir start_ap[NIADDR + 1], end_ap[NIADDR + 1], *idp;
237         int i, len, start_lvl, end_lvl, pref, ssize;
238
239         vp = ap->a_vp;
240         ip = VTOI(vp);
241         fs = ip->i_e2fs;
242 #ifdef UNKLAR
243         if (fs->fs_contigsumsize <= 0)
244                 return (ENOSPC);
245 #endif
246         buflist = ap->a_buflist;
247         len = buflist->bs_nchildren;
248         start_lbn = buflist->bs_children[0]->b_lblkno;
249         end_lbn = start_lbn + len - 1;
250 #if DIAGNOSTIC
251         for (i = 1; i < len; i++)
252                 if (buflist->bs_children[i]->b_lblkno != start_lbn + i)
253                         panic("ext2_reallocblks: non-cluster");
254 #endif
255         /*
256          * If the latest allocation is in a new cylinder group, assume that
257          * the filesystem has decided to move and do not force it back to
258          * the previous cylinder group.
259          */
260         if (dtog(fs, dbtofsb(fs, buflist->bs_children[0]->b_blkno)) !=
261             dtog(fs, dbtofsb(fs, buflist->bs_children[len - 1]->b_blkno)))
262                 return (ENOSPC);
263         if (ufs_getlbns(vp, start_lbn, start_ap, &start_lvl) ||
264             ufs_getlbns(vp, end_lbn, end_ap, &end_lvl))
265                 return (ENOSPC);
266         /*
267          * Get the starting offset and block map for the first block.
268          */
269         if (start_lvl == 0) {
270                 sbap = &ip->i_db[0];
271                 soff = start_lbn;
272         } else {
273                 idp = &start_ap[start_lvl - 1];
274                 if (bread(vp, idp->in_lbn, (int)fs->s_blocksize, NOCRED, &sbp)) {
275                         brelse(sbp);
276                         return (ENOSPC);
277                 }
278                 sbap = (daddr_t *)sbp->b_data;
279                 soff = idp->in_off;
280         }
281         /*
282          * Find the preferred location for the cluster.
283          */
284         pref = ext2_blkpref(ip, start_lbn, soff, sbap);
285         /*
286          * If the block range spans two block maps, get the second map.
287          */
288         if (end_lvl == 0 || (idp = &end_ap[end_lvl - 1])->in_off + 1 >= len) {
289                 ssize = len;
290         } else {
291 #if DIAGNOSTIC
292                 if (start_ap[start_lvl-1].in_lbn == idp->in_lbn)
293                         panic("ext2_reallocblk: start == end");
294 #endif
295                 ssize = len - (idp->in_off + 1);
296                 if (bread(vp, idp->in_lbn, (int)fs->s_blocksize, NOCRED, &ebp))
297                         goto fail;
298                 ebap = (daddr_t *)ebp->b_data;
299         }
300         /*
301          * Search the block map looking for an allocation of the desired size.
302          */
303         if ((newblk = (daddr_t)ext2_hashalloc(ip, dtog(fs, pref), (long)pref,
304             len, (u_long (*)())ext2_clusteralloc)) == 0)
305                 goto fail;
306         /*
307          * We have found a new contiguous block.
308          *
309          * First we have to replace the old block pointers with the new
310          * block pointers in the inode and indirect blocks associated
311          * with the file.
312          */
313         blkno = newblk;
314         for (bap = &sbap[soff], i = 0; i < len; i++, blkno += fs->s_frags_per_block) {
315                 if (i == ssize)
316                         bap = ebap;
317 #if DIAGNOSTIC
318                 if (buflist->bs_children[i]->b_blkno != fsbtodb(fs, *bap))
319                         panic("ext2_reallocblks: alloc mismatch");
320 #endif
321                 *bap++ = blkno;
322         }
323         /*
324          * Next we must write out the modified inode and indirect blocks.
325          * For strict correctness, the writes should be synchronous since
326          * the old block values may have been written to disk. In practise
327          * they are almost never written, but if we are concerned about 
328          * strict correctness, the `doasyncfree' flag should be set to zero.
329          *
330          * The test on `doasyncfree' should be changed to test a flag
331          * that shows whether the associated buffers and inodes have
332          * been written. The flag should be set when the cluster is
333          * started and cleared whenever the buffer or inode is flushed.
334          * We can then check below to see if it is set, and do the
335          * synchronous write only when it has been cleared.
336          */
337         if (sbap != &ip->i_db[0]) {
338                 if (doasyncfree)
339                         bdwrite(sbp);
340                 else
341                         bwrite(sbp);
342         } else {
343                 ip->i_flag |= IN_CHANGE | IN_UPDATE;
344                 if (!doasyncfree)
345                         UFS_UPDATE(vp, 1);
346         }
347         if (ssize < len)
348                 if (doasyncfree)
349                         bdwrite(ebp);
350                 else
351                         bwrite(ebp);
352         /*
353          * Last, free the old blocks and assign the new blocks to the buffers.
354          */
355         for (blkno = newblk, i = 0; i < len; i++, blkno += fs->s_frags_per_block) {
356                 ext2_blkfree(ip, dbtofsb(fs, buflist->bs_children[i]->b_blkno),
357                     fs->s_blocksize);
358                 buflist->bs_children[i]->b_blkno = fsbtodb(fs, blkno);
359         }
360         return (0);
361
362 fail:
363         if (ssize < len)
364                 brelse(ebp);
365         if (sbap != &ip->i_db[0])
366                 brelse(sbp);
367         return (ENOSPC);
368
369 #endif /* FANCY_REALLOC */
370 }
371
372 /*
373  * Allocate an inode in the file system.
374  * 
375  * we leave the actual allocation strategy to the (modified)
376  * ext2_new_inode(), to make sure we get the policies right
377  */
378 int
379 ext2_valloc(pvp, mode, cred, vpp)
380         struct vnode *pvp;
381         int mode;
382         struct ucred *cred;
383         struct vnode **vpp;
384 {
385         register struct inode *pip;
386         register struct ext2_sb_info *fs;
387         register struct inode *ip;
388         ino_t ino;
389         int i, error;
390         
391         *vpp = NULL;
392         pip = VTOI(pvp);
393         fs = pip->i_e2fs;
394         if (fs->s_es->s_free_inodes_count == 0)
395                 goto noinodes;
396
397         /* call the Linux routine - it returns the inode number only */
398         ino = ext2_new_inode(pip, mode);
399
400         if (ino == 0)
401                 goto noinodes;
402         error = VFS_VGET(pvp->v_mount, ino, vpp);
403         if (error) {
404                 UFS_VFREE(pvp, ino, mode);
405                 return (error);
406         }
407         ip = VTOI(*vpp);
408
409         /* 
410           the question is whether using VGET was such good idea at all -
411           Linux doesn't read the old inode in when it's allocating a
412           new one. I will set at least i_size & i_blocks the zero. 
413         */ 
414         ip->i_mode = 0;
415         ip->i_size = 0;
416         ip->i_blocks = 0;
417         ip->i_flags = 0;
418         /* now we want to make sure that the block pointers are zeroed out */
419         for (i = 0; i < NDADDR; i++)
420                 ip->i_db[i] = 0;
421         for (i = 0; i < NIADDR; i++)
422                 ip->i_ib[i] = 0;
423
424         /*
425          * Set up a new generation number for this inode.
426          * XXX check if this makes sense in ext2
427          */
428         if (ip->i_gen == 0 || ++ip->i_gen == 0)
429                 ip->i_gen = random() / 2 + 1;
430 /*
431 printf("ext2_valloc: allocated inode %d\n", ino);
432 */
433         return (0);
434 noinodes:
435         ext2_fserr(fs, cred->cr_uid, "out of inodes");
436         uprintf("\n%s: create/symlink failed, no inodes free\n", fs->fs_fsmnt);
437         return (ENOSPC);
438 }
439
440 /*
441  * Select the desired position for the next block in a file.  
442  *
443  * we try to mimic what Remy does in inode_getblk/block_getblk
444  *
445  * we note: blocknr == 0 means that we're about to allocate either
446  * a direct block or a pointer block at the first level of indirection
447  * (In other words, stuff that will go in i_db[] or i_ib[])
448  *
449  * blocknr != 0 means that we're allocating a block that is none
450  * of the above. Then, blocknr tells us the number of the block
451  * that will hold the pointer
452  */
453 daddr_t
454 ext2_blkpref(ip, lbn, indx, bap, blocknr)
455         struct inode *ip;
456         daddr_t lbn;
457         int indx;
458         daddr_t *bap;
459         daddr_t blocknr;
460 {
461         int     tmp;
462
463         /* if the next block is actually what we thought it is,
464            then set the goal to what we thought it should be
465         */
466         if(ip->i_next_alloc_block == lbn)
467                 return ip->i_next_alloc_goal;
468
469         /* now check whether we were provided with an array that basically
470            tells us previous blocks to which we want to stay closeby
471         */
472         if(bap) 
473                 for (tmp = indx - 1; tmp >= 0; tmp--) 
474                         if (bap[tmp]) 
475                                 return bap[tmp];
476
477         /* else let's fall back to the blocknr, or, if there is none,
478            follow the rule that a block should be allocated near its inode
479         */
480         return blocknr ? blocknr :
481                         (daddr_t)(ip->i_block_group * 
482                         EXT2_BLOCKS_PER_GROUP(ip->i_e2fs)) + 
483                         ip->i_e2fs->s_es->s_first_data_block;
484 }
485
486 /*
487  * Free a block or fragment.
488  *
489  * pass on to the Linux code
490  */
491 void
492 ext2_blkfree(ip, bno, size)
493         register struct inode *ip;
494         daddr_t bno;
495         long size;
496 {
497         register struct ext2_sb_info *fs;
498
499         fs = ip->i_e2fs;
500         /*
501          *      call Linux code with mount *, block number, count
502          */
503         ext2_free_blocks(ITOV(ip)->v_mount, bno, size / fs->s_frag_size);
504 }
505
506 /*
507  * Free an inode.
508  *
509  * the maintenance of the actual bitmaps is again up to the linux code
510  */
511 int
512 ext2_vfree(pvp, ino, mode)
513         struct vnode *pvp;
514         ino_t ino;
515         int mode;
516 {
517         register struct ext2_sb_info *fs;
518         register struct inode *pip;
519         register mode_t save_i_mode;
520
521         pip = VTOI(pvp);
522         fs = pip->i_e2fs;
523         if ((u_int)ino > fs->s_inodes_per_group * fs->s_groups_count)
524                 panic("ext2_vfree: range: dev = (%d, %d), ino = %d, fs = %s",
525                     major(pip->i_dev), minor(pip->i_dev), ino, fs->fs_fsmnt);
526
527 /* ext2_debug("ext2_vfree (%d, %d) called\n", pip->i_number, mode);
528  */
529         ext2_discard_prealloc(pip);
530
531         /* we need to make sure that ext2_free_inode can adjust the
532            used_dir_counts in the group summary information - I'd
533            really like to know what the rationale behind this
534            'set i_mode to zero to denote an unused inode' is
535          */
536         save_i_mode = pip->i_mode;
537         pip->i_mode = mode;
538         ext2_free_inode(pip);   
539         pip->i_mode = save_i_mode;
540         return (0);
541 }
542
543 /*
544  * Fserr prints the name of a file system with an error diagnostic.
545  * 
546  * The form of the error message is:
547  *      fs: error message
548  */
549 static void
550 ext2_fserr(fs, uid, cp)
551         struct ext2_sb_info *fs;
552         u_int uid;
553         char *cp;
554 {
555
556         log(LOG_ERR, "uid %d on %s: %s\n", uid, fs->fs_fsmnt, cp);
557 }