~ubuntu-branches/debian/jessie/ufsutils/jessie

« back to all changes in this revision

Viewing changes to sys/ufs/ffs/ffs_softdep.c

  • Committer: Package Import Robot
  • Author(s): Robert Millan
  • Date: 2013-11-29 14:21:12 UTC
  • mfrom: (11.1.1 experimental)
  • Revision ID: package-import@ubuntu.com-20131129142112-5tz5g7a4b6prb0dt
Tags: 9.2-2
* Avoid kfreebsd-kernel-headers versions prior to ino_t fix.
* Remove gratuitous dependency on libtermcap / libtinfo.

Show diffs side-by-side

added added

removed removed

Lines of Context:
1
1
/*-
2
 
 * Copyright 1998, 2000 Marshall Kirk McKusick. All Rights Reserved.
 
2
 * Copyright 1998, 2000 Marshall Kirk McKusick.
 
3
 * Copyright 2009, 2010 Jeffrey W. Roberson <jeff@FreeBSD.org>
 
4
 * All rights reserved.
3
5
 *
4
6
 * The soft updates code is derived from the appendix of a University
5
7
 * of Michigan technical report (Gregory R. Ganger and Yale N. Patt,
23
25
 *    notice, this list of conditions and the following disclaimer in the
24
26
 *    documentation and/or other materials provided with the distribution.
25
27
 *
26
 
 * THIS SOFTWARE IS PROVIDED BY MARSHALL KIRK MCKUSICK ``AS IS'' AND ANY
27
 
 * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
28
 
 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
29
 
 * DISCLAIMED.  IN NO EVENT SHALL MARSHALL KIRK MCKUSICK BE LIABLE FOR
30
 
 * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
31
 
 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
32
 
 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
33
 
 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
34
 
 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
35
 
 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
36
 
 * SUCH DAMAGE.
 
28
 * THIS SOFTWARE IS PROVIDED BY THE AUTHORS ``AS IS'' AND ANY EXPRESS OR
 
29
 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
 
30
 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
 
31
 * IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR ANY DIRECT, INDIRECT,
 
32
 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
 
33
 * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
 
34
 * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
 
35
 * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR
 
36
 * TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE
 
37
 * USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
37
38
 *
38
39
 *      from: @(#)ffs_softdep.c 9.59 (McKusick) 6/21/00
39
40
 */
42
43
__FBSDID("$FreeBSD$");
43
44
 
44
45
#include "opt_ffs.h"
 
46
#include "opt_quota.h"
45
47
#include "opt_ddb.h"
46
48
 
47
49
/*
58
60
#include <sys/buf.h>
59
61
#include <sys/kdb.h>
60
62
#include <sys/kthread.h>
 
63
#include <sys/ktr.h>
 
64
#include <sys/limits.h>
61
65
#include <sys/lock.h>
62
66
#include <sys/malloc.h>
63
67
#include <sys/mount.h>
64
68
#include <sys/mutex.h>
 
69
#include <sys/namei.h>
 
70
#include <sys/priv.h>
65
71
#include <sys/proc.h>
66
72
#include <sys/stat.h>
67
73
#include <sys/sysctl.h>
68
74
#include <sys/syslog.h>
69
75
#include <sys/vnode.h>
70
76
#include <sys/conf.h>
 
77
 
71
78
#include <ufs/ufs/dir.h>
72
79
#include <ufs/ufs/extattr.h>
73
80
#include <ufs/ufs/quota.h>
79
86
#include <ufs/ufs/ufs_extern.h>
80
87
 
81
88
#include <vm/vm.h>
 
89
#include <vm/vm_extern.h>
 
90
#include <vm/vm_object.h>
 
91
 
 
92
#include <geom/geom.h>
82
93
 
83
94
#include <ddb/ddb.h>
84
95
 
 
96
#define KTR_SUJ 0       /* Define to KTR_SPARE. */
 
97
 
85
98
#ifndef SOFTUPDATES
86
99
 
87
100
int
120
133
}
121
134
 
122
135
void
123
 
softdep_setup_inomapdep(bp, ip, newinum)
 
136
softdep_unmount(mp)
 
137
        struct mount *mp;
 
138
{
 
139
 
 
140
}
 
141
 
 
142
void
 
143
softdep_setup_sbupdate(ump, fs, bp)
 
144
        struct ufsmount *ump;
 
145
        struct fs *fs;
 
146
        struct buf *bp;
 
147
{
 
148
}
 
149
 
 
150
void
 
151
softdep_setup_inomapdep(bp, ip, newinum, mode)
124
152
        struct buf *bp;
125
153
        struct inode *ip;
126
154
        ino_t newinum;
 
155
        int mode;
127
156
{
128
157
 
129
158
        panic("softdep_setup_inomapdep called");
130
159
}
131
160
 
132
161
void
133
 
softdep_setup_blkmapdep(bp, mp, newblkno)
 
162
softdep_setup_blkmapdep(bp, mp, newblkno, frags, oldfrags)
134
163
        struct buf *bp;
135
164
        struct mount *mp;
136
165
        ufs2_daddr_t newblkno;
 
166
        int frags;
 
167
        int oldfrags;
137
168
{
138
169
 
139
170
        panic("softdep_setup_blkmapdep called");
194
225
}
195
226
 
196
227
void
 
228
softdep_journal_freeblocks(ip, cred, length, flags)
 
229
        struct inode *ip;
 
230
        struct ucred *cred;
 
231
        off_t length;
 
232
        int flags;
 
233
{
 
234
        
 
235
        panic("softdep_journal_freeblocks called");
 
236
}
 
237
 
 
238
void
 
239
softdep_journal_fsync(ip)
 
240
        struct inode *ip;
 
241
{
 
242
 
 
243
        panic("softdep_journal_fsync called");
 
244
}
 
245
 
 
246
void
197
247
softdep_setup_freeblocks(ip, length, flags)
198
248
        struct inode *ip;
199
249
        off_t length;
227
277
}
228
278
 
229
279
void 
230
 
softdep_change_directoryentry_offset(dp, base, oldloc, newloc, entrysize)
 
280
softdep_change_directoryentry_offset(bp, dp, base, oldloc, newloc, entrysize)
 
281
        struct buf *bp;
231
282
        struct inode *dp;
232
283
        caddr_t base;
233
284
        caddr_t oldloc;
262
313
}
263
314
 
264
315
void
 
316
softdep_setup_blkfree(mp, bp, blkno, frags, wkhd)
 
317
        struct mount *mp;
 
318
        struct buf *bp;
 
319
        ufs2_daddr_t blkno;
 
320
        int frags;
 
321
        struct workhead *wkhd;
 
322
{
 
323
 
 
324
        panic("%s called", __FUNCTION__);
 
325
}
 
326
 
 
327
void
 
328
softdep_setup_inofree(mp, bp, ino, wkhd)
 
329
        struct mount *mp;
 
330
        struct buf *bp;
 
331
        ino_t ino;
 
332
        struct workhead *wkhd;
 
333
{
 
334
 
 
335
        panic("%s called", __FUNCTION__);
 
336
}
 
337
 
 
338
void
 
339
softdep_setup_unlink(dp, ip)
 
340
        struct inode *dp;
 
341
        struct inode *ip;
 
342
{
 
343
 
 
344
        panic("%s called", __FUNCTION__);
 
345
}
 
346
 
 
347
void
 
348
softdep_setup_link(dp, ip)
 
349
        struct inode *dp;
 
350
        struct inode *ip;
 
351
{
 
352
 
 
353
        panic("%s called", __FUNCTION__);
 
354
}
 
355
 
 
356
void
 
357
softdep_revert_link(dp, ip)
 
358
        struct inode *dp;
 
359
        struct inode *ip;
 
360
{
 
361
 
 
362
        panic("%s called", __FUNCTION__);
 
363
}
 
364
 
 
365
void
 
366
softdep_setup_rmdir(dp, ip)
 
367
        struct inode *dp;
 
368
        struct inode *ip;
 
369
{
 
370
 
 
371
        panic("%s called", __FUNCTION__);
 
372
}
 
373
 
 
374
void
 
375
softdep_revert_rmdir(dp, ip)
 
376
        struct inode *dp;
 
377
        struct inode *ip;
 
378
{
 
379
 
 
380
        panic("%s called", __FUNCTION__);
 
381
}
 
382
 
 
383
void
 
384
softdep_setup_create(dp, ip)
 
385
        struct inode *dp;
 
386
        struct inode *ip;
 
387
{
 
388
 
 
389
        panic("%s called", __FUNCTION__);
 
390
}
 
391
 
 
392
void
 
393
softdep_revert_create(dp, ip)
 
394
        struct inode *dp;
 
395
        struct inode *ip;
 
396
{
 
397
 
 
398
        panic("%s called", __FUNCTION__);
 
399
}
 
400
 
 
401
void
 
402
softdep_setup_mkdir(dp, ip)
 
403
        struct inode *dp;
 
404
        struct inode *ip;
 
405
{
 
406
 
 
407
        panic("%s called", __FUNCTION__);
 
408
}
 
409
 
 
410
void
 
411
softdep_revert_mkdir(dp, ip)
 
412
        struct inode *dp;
 
413
        struct inode *ip;
 
414
{
 
415
 
 
416
        panic("%s called", __FUNCTION__);
 
417
}
 
418
 
 
419
void
 
420
softdep_setup_dotdot_link(dp, ip)
 
421
        struct inode *dp;
 
422
        struct inode *ip;
 
423
{
 
424
 
 
425
        panic("%s called", __FUNCTION__);
 
426
}
 
427
 
 
428
int
 
429
softdep_prealloc(vp, waitok)
 
430
        struct vnode *vp;
 
431
        int waitok;
 
432
{
 
433
 
 
434
        panic("%s called", __FUNCTION__);
 
435
 
 
436
        return (0);
 
437
}
 
438
 
 
439
int
 
440
softdep_journal_lookup(mp, vpp)
 
441
        struct mount *mp;
 
442
        struct vnode **vpp;
 
443
{
 
444
 
 
445
        return (ENOENT);
 
446
}
 
447
 
 
448
void
265
449
softdep_change_linkcnt(ip)
266
450
        struct inode *ip;
267
451
{
322
506
}
323
507
 
324
508
int
 
509
softdep_sync_buf(struct vnode *vp, struct buf *bp, int waitfor)
 
510
{
 
511
 
 
512
        return (0);
 
513
}
 
514
 
 
515
int
325
516
softdep_slowdown(vp)
326
517
        struct vnode *vp;
327
518
{
338
529
}
339
530
 
340
531
int
341
 
softdep_request_cleanup(fs, vp)
 
532
softdep_request_cleanup(fs, vp, cred, resource)
342
533
        struct fs *fs;
343
534
        struct vnode *vp;
 
535
        struct ucred *cred;
 
536
        int resource;
344
537
{
345
538
 
346
539
        return (0);
398
591
        *softdepactiveaccp = 0;
399
592
}
400
593
 
 
594
void
 
595
softdep_buf_append(bp, wkhd)
 
596
        struct buf *bp;
 
597
        struct workhead *wkhd;
 
598
{
 
599
 
 
600
        panic("softdep_buf_appendwork called");
 
601
}
 
602
 
 
603
void
 
604
softdep_inode_append(ip, cred, wkhd)
 
605
        struct inode *ip;
 
606
        struct ucred *cred;
 
607
        struct workhead *wkhd;
 
608
{
 
609
 
 
610
        panic("softdep_inode_appendwork called");
 
611
}
 
612
 
 
613
void
 
614
softdep_freework(wkhd)
 
615
        struct workhead *wkhd;
 
616
{
 
617
 
 
618
        panic("softdep_freework called");
 
619
}
 
620
 
401
621
#else
 
622
 
 
623
FEATURE(softupdates, "FFS soft-updates support");
 
624
 
402
625
/*
403
626
 * These definitions need to be adapted to the system to which
404
627
 * this file is being ported.
405
628
 */
406
 
/*
407
 
 * malloc types defined for the softdep system.
408
 
 */
409
 
static MALLOC_DEFINE(M_PAGEDEP, "pagedep","File page dependencies");
410
 
static MALLOC_DEFINE(M_INODEDEP, "inodedep","Inode dependencies");
411
 
static MALLOC_DEFINE(M_NEWBLK, "newblk","New block allocation");
412
 
static MALLOC_DEFINE(M_BMSAFEMAP, "bmsafemap","Block or frag allocated from cyl group map");
413
 
static MALLOC_DEFINE(M_ALLOCDIRECT, "allocdirect","Block or frag dependency for an inode");
414
 
static MALLOC_DEFINE(M_INDIRDEP, "indirdep","Indirect block dependencies");
415
 
static MALLOC_DEFINE(M_ALLOCINDIR, "allocindir","Block dependency for an indirect block");
416
 
static MALLOC_DEFINE(M_FREEFRAG, "freefrag","Previously used frag for an inode");
417
 
static MALLOC_DEFINE(M_FREEBLKS, "freeblks","Blocks freed from an inode");
418
 
static MALLOC_DEFINE(M_FREEFILE, "freefile","Inode deallocated");
419
 
static MALLOC_DEFINE(M_DIRADD, "diradd","New directory entry");
420
 
static MALLOC_DEFINE(M_MKDIR, "mkdir","New directory");
421
 
static MALLOC_DEFINE(M_DIRREM, "dirrem","Directory entry deleted");
422
 
static MALLOC_DEFINE(M_NEWDIRBLK, "newdirblk","Unclaimed new directory block");
423
 
static MALLOC_DEFINE(M_SAVEDINO, "savedino","Saved inodes");
424
629
 
425
 
#define M_SOFTDEP_FLAGS (M_WAITOK | M_USE_RESERVE)
 
630
#define M_SOFTDEP_FLAGS (M_WAITOK)
426
631
 
427
632
#define D_PAGEDEP       0
428
633
#define D_INODEDEP      1
429
 
#define D_NEWBLK        2
430
 
#define D_BMSAFEMAP     3
 
634
#define D_BMSAFEMAP     2
 
635
#define D_NEWBLK        3
431
636
#define D_ALLOCDIRECT   4
432
637
#define D_INDIRDEP      5
433
638
#define D_ALLOCINDIR    6
438
643
#define D_MKDIR         11
439
644
#define D_DIRREM        12
440
645
#define D_NEWDIRBLK     13
441
 
#define D_LAST          D_NEWDIRBLK
 
646
#define D_FREEWORK      14
 
647
#define D_FREEDEP       15
 
648
#define D_JADDREF       16
 
649
#define D_JREMREF       17
 
650
#define D_JMVREF        18
 
651
#define D_JNEWBLK       19
 
652
#define D_JFREEBLK      20
 
653
#define D_JFREEFRAG     21
 
654
#define D_JSEG          22
 
655
#define D_JSEGDEP       23
 
656
#define D_SBDEP         24
 
657
#define D_JTRUNC        25
 
658
#define D_JFSYNC        26
 
659
#define D_SENTINEL      27
 
660
#define D_LAST          D_SENTINEL
 
661
 
 
662
unsigned long dep_current[D_LAST + 1];
 
663
unsigned long dep_total[D_LAST + 1];
 
664
unsigned long dep_write[D_LAST + 1];
 
665
 
 
666
 
 
667
static SYSCTL_NODE(_debug, OID_AUTO, softdep, CTLFLAG_RW, 0,
 
668
    "soft updates stats");
 
669
static SYSCTL_NODE(_debug_softdep, OID_AUTO, total, CTLFLAG_RW, 0,
 
670
    "total dependencies allocated");
 
671
static SYSCTL_NODE(_debug_softdep, OID_AUTO, current, CTLFLAG_RW, 0,
 
672
    "current dependencies allocated");
 
673
static SYSCTL_NODE(_debug_softdep, OID_AUTO, write, CTLFLAG_RW, 0,
 
674
    "current dependencies written");
 
675
 
 
676
#define SOFTDEP_TYPE(type, str, long)                                   \
 
677
    static MALLOC_DEFINE(M_ ## type, #str, long);                       \
 
678
    SYSCTL_ULONG(_debug_softdep_total, OID_AUTO, str, CTLFLAG_RD,       \
 
679
        &dep_total[D_ ## type], 0, "");                                 \
 
680
    SYSCTL_ULONG(_debug_softdep_current, OID_AUTO, str, CTLFLAG_RD,     \
 
681
        &dep_current[D_ ## type], 0, "");                               \
 
682
    SYSCTL_ULONG(_debug_softdep_write, OID_AUTO, str, CTLFLAG_RD,       \
 
683
        &dep_write[D_ ## type], 0, "");
 
684
 
 
685
SOFTDEP_TYPE(PAGEDEP, pagedep, "File page dependencies"); 
 
686
SOFTDEP_TYPE(INODEDEP, inodedep, "Inode dependencies");
 
687
SOFTDEP_TYPE(BMSAFEMAP, bmsafemap,
 
688
    "Block or frag allocated from cyl group map");
 
689
SOFTDEP_TYPE(NEWBLK, newblk, "New block or frag allocation dependency");
 
690
SOFTDEP_TYPE(ALLOCDIRECT, allocdirect, "Block or frag dependency for an inode");
 
691
SOFTDEP_TYPE(INDIRDEP, indirdep, "Indirect block dependencies");
 
692
SOFTDEP_TYPE(ALLOCINDIR, allocindir, "Block dependency for an indirect block");
 
693
SOFTDEP_TYPE(FREEFRAG, freefrag, "Previously used frag for an inode");
 
694
SOFTDEP_TYPE(FREEBLKS, freeblks, "Blocks freed from an inode");
 
695
SOFTDEP_TYPE(FREEFILE, freefile, "Inode deallocated");
 
696
SOFTDEP_TYPE(DIRADD, diradd, "New directory entry");
 
697
SOFTDEP_TYPE(MKDIR, mkdir, "New directory");
 
698
SOFTDEP_TYPE(DIRREM, dirrem, "Directory entry deleted");
 
699
SOFTDEP_TYPE(NEWDIRBLK, newdirblk, "Unclaimed new directory block");
 
700
SOFTDEP_TYPE(FREEWORK, freework, "free an inode block");
 
701
SOFTDEP_TYPE(FREEDEP, freedep, "track a block free");
 
702
SOFTDEP_TYPE(JADDREF, jaddref, "Journal inode ref add");
 
703
SOFTDEP_TYPE(JREMREF, jremref, "Journal inode ref remove");
 
704
SOFTDEP_TYPE(JMVREF, jmvref, "Journal inode ref move");
 
705
SOFTDEP_TYPE(JNEWBLK, jnewblk, "Journal new block");
 
706
SOFTDEP_TYPE(JFREEBLK, jfreeblk, "Journal free block");
 
707
SOFTDEP_TYPE(JFREEFRAG, jfreefrag, "Journal free frag");
 
708
SOFTDEP_TYPE(JSEG, jseg, "Journal segment");
 
709
SOFTDEP_TYPE(JSEGDEP, jsegdep, "Journal segment complete");
 
710
SOFTDEP_TYPE(SBDEP, sbdep, "Superblock write dependency");
 
711
SOFTDEP_TYPE(JTRUNC, jtrunc, "Journal inode truncation");
 
712
SOFTDEP_TYPE(JFSYNC, jfsync, "Journal fsync complete");
 
713
 
 
714
static MALLOC_DEFINE(M_SENTINEL, "sentinel", "Worklist sentinel");
 
715
 
 
716
static MALLOC_DEFINE(M_SAVEDINO, "savedino", "Saved inodes");
 
717
static MALLOC_DEFINE(M_JBLOCKS, "jblocks", "Journal block locations");
442
718
 
443
719
/* 
444
720
 * translate from workitem type to memory type
447
723
static struct malloc_type *memtype[] = {
448
724
        M_PAGEDEP,
449
725
        M_INODEDEP,
 
726
        M_BMSAFEMAP,
450
727
        M_NEWBLK,
451
 
        M_BMSAFEMAP,
452
728
        M_ALLOCDIRECT,
453
729
        M_INDIRDEP,
454
730
        M_ALLOCINDIR,
458
734
        M_DIRADD,
459
735
        M_MKDIR,
460
736
        M_DIRREM,
461
 
        M_NEWDIRBLK
 
737
        M_NEWDIRBLK,
 
738
        M_FREEWORK,
 
739
        M_FREEDEP,
 
740
        M_JADDREF,
 
741
        M_JREMREF,
 
742
        M_JMVREF,
 
743
        M_JNEWBLK,
 
744
        M_JFREEBLK,
 
745
        M_JFREEFRAG,
 
746
        M_JSEG,
 
747
        M_JSEGDEP,
 
748
        M_SBDEP,
 
749
        M_JTRUNC,
 
750
        M_JFSYNC,
 
751
        M_SENTINEL
462
752
};
463
753
 
 
754
static LIST_HEAD(mkdirlist, mkdir) mkdirlisthd;
 
755
 
464
756
#define DtoM(type) (memtype[type])
465
757
 
466
758
/*
467
759
 * Names of malloc types.
468
760
 */
469
761
#define TYPENAME(type)  \
470
 
        ((unsigned)(type) < D_LAST ? memtype[type]->ks_shortdesc : "???")
 
762
        ((unsigned)(type) <= D_LAST ? memtype[type]->ks_shortdesc : "???")
471
763
/*
472
764
 * End system adaptation definitions.
473
765
 */
474
766
 
 
767
#define DOTDOT_OFFSET   offsetof(struct dirtemplate, dotdot_ino)
 
768
#define DOT_OFFSET      offsetof(struct dirtemplate, dot_ino)
 
769
 
475
770
/*
476
771
 * Forward declarations.
477
772
 */
478
773
struct inodedep_hashhead;
479
774
struct newblk_hashhead;
480
775
struct pagedep_hashhead;
 
776
struct bmsafemap_hashhead;
 
777
 
 
778
/*
 
779
 * Private journaling structures.
 
780
 */
 
781
struct jblocks {
 
782
        struct jseglst  jb_segs;        /* TAILQ of current segments. */
 
783
        struct jseg     *jb_writeseg;   /* Next write to complete. */
 
784
        struct jseg     *jb_oldestseg;  /* Oldest segment with valid entries. */
 
785
        struct jextent  *jb_extent;     /* Extent array. */
 
786
        uint64_t        jb_nextseq;     /* Next sequence number. */
 
787
        uint64_t        jb_oldestwrseq; /* Oldest written sequence number. */
 
788
        uint8_t         jb_needseg;     /* Need a forced segment. */
 
789
        uint8_t         jb_suspended;   /* Did journal suspend writes? */
 
790
        int             jb_avail;       /* Available extents. */
 
791
        int             jb_used;        /* Last used extent. */
 
792
        int             jb_head;        /* Allocator head. */
 
793
        int             jb_off;         /* Allocator extent offset. */
 
794
        int             jb_blocks;      /* Total disk blocks covered. */
 
795
        int             jb_free;        /* Total disk blocks free. */
 
796
        int             jb_min;         /* Minimum free space. */
 
797
        int             jb_low;         /* Low on space. */
 
798
        int             jb_age;         /* Insertion time of oldest rec. */
 
799
};
 
800
 
 
801
struct jextent {
 
802
        ufs2_daddr_t    je_daddr;       /* Disk block address. */
 
803
        int             je_blocks;      /* Disk block count. */
 
804
};
481
805
 
482
806
/*
483
807
 * Internal function prototypes.
487
811
static  struct buf *getdirtybuf(struct buf *, struct mtx *, int);
488
812
static  void clear_remove(struct thread *);
489
813
static  void clear_inodedeps(struct thread *);
 
814
static  void unlinked_inodedep(struct mount *, struct inodedep *);
 
815
static  void clear_unlinked_inodedep(struct inodedep *);
 
816
static  struct inodedep *first_unlinked_inodedep(struct ufsmount *);
490
817
static  int flush_pagedep_deps(struct vnode *, struct mount *,
491
818
            struct diraddhd *);
492
 
static  int flush_inodedep_deps(struct mount *, ino_t);
 
819
static  int free_pagedep(struct pagedep *);
 
820
static  int flush_newblk_dep(struct vnode *, struct mount *, ufs_lbn_t);
 
821
static  int flush_inodedep_deps(struct vnode *, struct mount *, ino_t);
493
822
static  int flush_deplist(struct allocdirectlst *, int, int *);
 
823
static  int sync_cgs(struct mount *, int);
494
824
static  int handle_written_filepage(struct pagedep *, struct buf *);
 
825
static  int handle_written_sbdep(struct sbdep *, struct buf *);
 
826
static  void initiate_write_sbdep(struct sbdep *);
495
827
static  void diradd_inode_written(struct diradd *, struct inodedep *);
 
828
static  int handle_written_indirdep(struct indirdep *, struct buf *,
 
829
            struct buf**);
496
830
static  int handle_written_inodeblock(struct inodedep *, struct buf *);
497
 
static  void handle_allocdirect_partdone(struct allocdirect *);
 
831
static  int jnewblk_rollforward(struct jnewblk *, struct fs *, struct cg *,
 
832
            uint8_t *);
 
833
static  int handle_written_bmsafemap(struct bmsafemap *, struct buf *);
 
834
static  void handle_written_jaddref(struct jaddref *);
 
835
static  void handle_written_jremref(struct jremref *);
 
836
static  void handle_written_jseg(struct jseg *, struct buf *);
 
837
static  void handle_written_jnewblk(struct jnewblk *);
 
838
static  void handle_written_jblkdep(struct jblkdep *);
 
839
static  void handle_written_jfreefrag(struct jfreefrag *);
 
840
static  void complete_jseg(struct jseg *);
 
841
static  void complete_jsegs(struct jseg *);
 
842
static  void jseg_write(struct ufsmount *ump, struct jseg *, uint8_t *);
 
843
static  void jaddref_write(struct jaddref *, struct jseg *, uint8_t *);
 
844
static  void jremref_write(struct jremref *, struct jseg *, uint8_t *);
 
845
static  void jmvref_write(struct jmvref *, struct jseg *, uint8_t *);
 
846
static  void jtrunc_write(struct jtrunc *, struct jseg *, uint8_t *);
 
847
static  void jfsync_write(struct jfsync *, struct jseg *, uint8_t *data);
 
848
static  void jnewblk_write(struct jnewblk *, struct jseg *, uint8_t *);
 
849
static  void jfreeblk_write(struct jfreeblk *, struct jseg *, uint8_t *);
 
850
static  void jfreefrag_write(struct jfreefrag *, struct jseg *, uint8_t *);
 
851
static  inline void inoref_write(struct inoref *, struct jseg *,
 
852
            struct jrefrec *);
 
853
static  void handle_allocdirect_partdone(struct allocdirect *,
 
854
            struct workhead *);
 
855
static  struct jnewblk *cancel_newblk(struct newblk *, struct worklist *,
 
856
            struct workhead *);
 
857
static  void indirdep_complete(struct indirdep *);
 
858
static  int indirblk_lookup(struct mount *, ufs2_daddr_t);
 
859
static  void indirblk_insert(struct freework *);
 
860
static  void indirblk_remove(struct freework *);
498
861
static  void handle_allocindir_partdone(struct allocindir *);
499
862
static  void initiate_write_filepage(struct pagedep *, struct buf *);
 
863
static  void initiate_write_indirdep(struct indirdep*, struct buf *);
500
864
static  void handle_written_mkdir(struct mkdir *, int);
 
865
static  int jnewblk_rollback(struct jnewblk *, struct fs *, struct cg *,
 
866
            uint8_t *);
 
867
static  void initiate_write_bmsafemap(struct bmsafemap *, struct buf *);
501
868
static  void initiate_write_inodeblock_ufs1(struct inodedep *, struct buf *);
502
869
static  void initiate_write_inodeblock_ufs2(struct inodedep *, struct buf *);
503
870
static  void handle_workitem_freefile(struct freefile *);
504
 
static  void handle_workitem_remove(struct dirrem *, struct vnode *);
 
871
static  int handle_workitem_remove(struct dirrem *, int);
505
872
static  struct dirrem *newdirrem(struct buf *, struct inode *,
506
873
            struct inode *, int, struct dirrem **);
507
 
static  void free_diradd(struct diradd *);
508
 
static  void free_allocindir(struct allocindir *, struct inodedep *);
 
874
static  struct indirdep *indirdep_lookup(struct mount *, struct inode *,
 
875
            struct buf *);
 
876
static  void cancel_indirdep(struct indirdep *, struct buf *,
 
877
            struct freeblks *);
 
878
static  void free_indirdep(struct indirdep *);
 
879
static  void free_diradd(struct diradd *, struct workhead *);
 
880
static  void merge_diradd(struct inodedep *, struct diradd *);
 
881
static  void complete_diradd(struct diradd *);
 
882
static  struct diradd *diradd_lookup(struct pagedep *, int);
 
883
static  struct jremref *cancel_diradd_dotdot(struct inode *, struct dirrem *,
 
884
            struct jremref *);
 
885
static  struct jremref *cancel_mkdir_dotdot(struct inode *, struct dirrem *,
 
886
            struct jremref *);
 
887
static  void cancel_diradd(struct diradd *, struct dirrem *, struct jremref *,
 
888
            struct jremref *, struct jremref *);
 
889
static  void dirrem_journal(struct dirrem *, struct jremref *, struct jremref *,
 
890
            struct jremref *);
 
891
static  void cancel_allocindir(struct allocindir *, struct buf *bp,
 
892
            struct freeblks *, int);
 
893
static  int setup_trunc_indir(struct freeblks *, struct inode *,
 
894
            ufs_lbn_t, ufs_lbn_t, ufs2_daddr_t);
 
895
static  void complete_trunc_indir(struct freework *);
 
896
static  void trunc_indirdep(struct indirdep *, struct freeblks *, struct buf *,
 
897
            int);
 
898
static  void complete_mkdir(struct mkdir *);
509
899
static  void free_newdirblk(struct newdirblk *);
510
 
static  int indir_trunc(struct freeblks *, ufs2_daddr_t, int, ufs_lbn_t,
511
 
            ufs2_daddr_t *);
512
 
static  void deallocate_dependencies(struct buf *, struct inodedep *);
513
 
static  void free_allocdirect(struct allocdirectlst *,
514
 
            struct allocdirect *, int);
 
900
static  void free_jremref(struct jremref *);
 
901
static  void free_jaddref(struct jaddref *);
 
902
static  void free_jsegdep(struct jsegdep *);
 
903
static  void free_jsegs(struct jblocks *);
 
904
static  void rele_jseg(struct jseg *);
 
905
static  void free_jseg(struct jseg *, struct jblocks *);
 
906
static  void free_jnewblk(struct jnewblk *);
 
907
static  void free_jblkdep(struct jblkdep *);
 
908
static  void free_jfreefrag(struct jfreefrag *);
 
909
static  void free_freedep(struct freedep *);
 
910
static  void journal_jremref(struct dirrem *, struct jremref *,
 
911
            struct inodedep *);
 
912
static  void cancel_jnewblk(struct jnewblk *, struct workhead *);
 
913
static  int cancel_jaddref(struct jaddref *, struct inodedep *,
 
914
            struct workhead *);
 
915
static  void cancel_jfreefrag(struct jfreefrag *);
 
916
static  inline void setup_freedirect(struct freeblks *, struct inode *,
 
917
            int, int);
 
918
static  inline void setup_freeext(struct freeblks *, struct inode *, int, int);
 
919
static  inline void setup_freeindir(struct freeblks *, struct inode *, int,
 
920
            ufs_lbn_t, int);
 
921
static  inline struct freeblks *newfreeblks(struct mount *, struct inode *);
 
922
static  void freeblks_free(struct ufsmount *, struct freeblks *, int);
 
923
static  void indir_trunc(struct freework *, ufs2_daddr_t, ufs_lbn_t);
 
924
ufs2_daddr_t blkcount(struct fs *, ufs2_daddr_t, off_t);
 
925
static  int trunc_check_buf(struct buf *, int *, ufs_lbn_t, int, int);
 
926
static  void trunc_dependencies(struct inode *, struct freeblks *, ufs_lbn_t,
 
927
            int, int);
 
928
static  void trunc_pages(struct inode *, off_t, ufs2_daddr_t, int);
 
929
static  int cancel_pagedep(struct pagedep *, struct freeblks *, int);
 
930
static  int deallocate_dependencies(struct buf *, struct freeblks *, int);
 
931
static  void newblk_freefrag(struct newblk*);
 
932
static  void free_newblk(struct newblk *);
 
933
static  void cancel_allocdirect(struct allocdirectlst *,
 
934
            struct allocdirect *, struct freeblks *);
515
935
static  int check_inode_unwritten(struct inodedep *);
516
936
static  int free_inodedep(struct inodedep *);
517
 
static  void handle_workitem_freeblocks(struct freeblks *, int);
 
937
static  void freework_freeblock(struct freework *);
 
938
static  void freework_enqueue(struct freework *);
 
939
static  int handle_workitem_freeblocks(struct freeblks *, int);
 
940
static  int handle_complete_freeblocks(struct freeblks *, int);
 
941
static  void handle_workitem_indirblk(struct freework *);
 
942
static  void handle_written_freework(struct freework *);
518
943
static  void merge_inode_lists(struct allocdirectlst *,struct allocdirectlst *);
519
 
static  void setup_allocindir_phase2(struct buf *, struct inode *,
520
 
            struct allocindir *);
 
944
static  struct worklist *jnewblk_merge(struct worklist *, struct worklist *,
 
945
            struct workhead *);
 
946
static  struct freefrag *setup_allocindir_phase2(struct buf *, struct inode *,
 
947
            struct inodedep *, struct allocindir *, ufs_lbn_t);
521
948
static  struct allocindir *newallocindir(struct inode *, int, ufs2_daddr_t,
522
 
            ufs2_daddr_t);
 
949
            ufs2_daddr_t, ufs_lbn_t);
523
950
static  void handle_workitem_freefrag(struct freefrag *);
524
 
static  struct freefrag *newfreefrag(struct inode *, ufs2_daddr_t, long);
 
951
static  struct freefrag *newfreefrag(struct inode *, ufs2_daddr_t, long,
 
952
            ufs_lbn_t);
525
953
static  void allocdirect_merge(struct allocdirectlst *,
526
954
            struct allocdirect *, struct allocdirect *);
527
 
static  struct bmsafemap *bmsafemap_lookup(struct mount *, struct buf *);
528
 
static  int newblk_find(struct newblk_hashhead *, struct fs *, ufs2_daddr_t,
529
 
            struct newblk **);
530
 
static  int newblk_lookup(struct fs *, ufs2_daddr_t, int, struct newblk **);
 
955
static  struct freefrag *allocindir_merge(struct allocindir *,
 
956
            struct allocindir *);
 
957
static  int bmsafemap_find(struct bmsafemap_hashhead *, struct mount *, int,
 
958
            struct bmsafemap **);
 
959
static  struct bmsafemap *bmsafemap_lookup(struct mount *, struct buf *,
 
960
            int cg, struct bmsafemap *);
 
961
static  int newblk_find(struct newblk_hashhead *, struct mount *, ufs2_daddr_t,
 
962
            int, struct newblk **);
 
963
static  int newblk_lookup(struct mount *, ufs2_daddr_t, int, struct newblk **);
531
964
static  int inodedep_find(struct inodedep_hashhead *, struct fs *, ino_t,
532
965
            struct inodedep **);
533
966
static  int inodedep_lookup(struct mount *, ino_t, int, struct inodedep **);
534
 
static  int pagedep_lookup(struct inode *, ufs_lbn_t, int, struct pagedep **);
 
967
static  int pagedep_lookup(struct mount *, struct buf *bp, ino_t, ufs_lbn_t,
 
968
            int, struct pagedep **);
535
969
static  int pagedep_find(struct pagedep_hashhead *, ino_t, ufs_lbn_t,
536
970
            struct mount *mp, int, struct pagedep **);
537
971
static  void pause_timer(void *);
538
972
static  int request_cleanup(struct mount *, int);
539
 
static  int process_worklist_item(struct mount *, int);
540
 
static  void add_to_worklist(struct worklist *);
 
973
static  int process_worklist_item(struct mount *, int, int);
 
974
static  void process_removes(struct vnode *);
 
975
static  void process_truncates(struct vnode *);
 
976
static  void jwork_move(struct workhead *, struct workhead *);
 
977
static  void jwork_insert(struct workhead *, struct jsegdep *);
 
978
static  void add_to_worklist(struct worklist *, int);
 
979
static  void wake_worklist(struct worklist *);
 
980
static  void wait_worklist(struct worklist *, char *);
 
981
static  void remove_from_worklist(struct worklist *);
541
982
static  void softdep_flush(void);
 
983
static  void softdep_flushjournal(struct mount *);
542
984
static  int softdep_speedup(void);
 
985
static  void worklist_speedup(void);
 
986
static  int journal_mount(struct mount *, struct fs *, struct ucred *);
 
987
static  void journal_unmount(struct mount *);
 
988
static  int journal_space(struct ufsmount *, int);
 
989
static  void journal_suspend(struct ufsmount *);
 
990
static  int journal_unsuspend(struct ufsmount *ump);
 
991
static  void softdep_prelink(struct vnode *, struct vnode *);
 
992
static  void add_to_journal(struct worklist *);
 
993
static  void remove_from_journal(struct worklist *);
 
994
static  void softdep_process_journal(struct mount *, struct worklist *, int);
 
995
static  struct jremref *newjremref(struct dirrem *, struct inode *,
 
996
            struct inode *ip, off_t, nlink_t);
 
997
static  struct jaddref *newjaddref(struct inode *, ino_t, off_t, int16_t,
 
998
            uint16_t);
 
999
static  inline void newinoref(struct inoref *, ino_t, ino_t, off_t, nlink_t,
 
1000
            uint16_t);
 
1001
static  inline struct jsegdep *inoref_jseg(struct inoref *);
 
1002
static  struct jmvref *newjmvref(struct inode *, ino_t, off_t, off_t);
 
1003
static  struct jfreeblk *newjfreeblk(struct freeblks *, ufs_lbn_t,
 
1004
            ufs2_daddr_t, int);
 
1005
static  struct jtrunc *newjtrunc(struct freeblks *, off_t, int);
 
1006
static  void move_newblock_dep(struct jaddref *, struct inodedep *);
 
1007
static  void cancel_jfreeblk(struct freeblks *, ufs2_daddr_t);
 
1008
static  struct jfreefrag *newjfreefrag(struct freefrag *, struct inode *,
 
1009
            ufs2_daddr_t, long, ufs_lbn_t);
 
1010
static  struct freework *newfreework(struct ufsmount *, struct freeblks *,
 
1011
            struct freework *, ufs_lbn_t, ufs2_daddr_t, int, int, int);
 
1012
static  int jwait(struct worklist *, int);
 
1013
static  struct inodedep *inodedep_lookup_ip(struct inode *);
 
1014
static  int bmsafemap_backgroundwrite(struct bmsafemap *, struct buf *);
 
1015
static  struct freefile *handle_bufwait(struct inodedep *, struct workhead *);
 
1016
static  void handle_jwork(struct workhead *);
 
1017
static  struct mkdir *setup_newdir(struct diradd *, ino_t, ino_t, struct buf *,
 
1018
            struct mkdir **);
 
1019
static  struct jblocks *jblocks_create(void);
 
1020
static  ufs2_daddr_t jblocks_alloc(struct jblocks *, int, int *);
 
1021
static  void jblocks_free(struct jblocks *, struct mount *, int);
 
1022
static  void jblocks_destroy(struct jblocks *);
 
1023
static  void jblocks_add(struct jblocks *, ufs2_daddr_t, int);
543
1024
 
544
1025
/*
545
1026
 * Exported softdep operations.
556
1037
#define ACQUIRE_LOCK(lk)                mtx_lock(lk)
557
1038
#define FREE_LOCK(lk)                   mtx_unlock(lk)
558
1039
 
559
 
#define BUF_AREC(bp)    ((bp)->b_lock.lock_object.lo_flags |= LO_RECURSABLE)
560
 
#define BUF_NOREC(bp)   ((bp)->b_lock.lock_object.lo_flags &= ~LO_RECURSABLE)
 
1040
#define BUF_AREC(bp)                    lockallowrecurse(&(bp)->b_lock)
 
1041
#define BUF_NOREC(bp)                   lockdisablerecurse(&(bp)->b_lock)
561
1042
 
562
1043
/*
563
1044
 * Worklist queue management.
572
1053
        (item)->wk_state &= ~ONWORKLIST;        \
573
1054
        LIST_REMOVE(item, wk_list);             \
574
1055
} while (0)
 
1056
#define WORKLIST_INSERT_UNLOCKED        WORKLIST_INSERT
 
1057
#define WORKLIST_REMOVE_UNLOCKED        WORKLIST_REMOVE
 
1058
 
575
1059
#else /* DEBUG */
576
 
static  void worklist_insert(struct workhead *, struct worklist *);
577
 
static  void worklist_remove(struct worklist *);
 
1060
static  void worklist_insert(struct workhead *, struct worklist *, int);
 
1061
static  void worklist_remove(struct worklist *, int);
578
1062
 
579
 
#define WORKLIST_INSERT(head, item) worklist_insert(head, item)
580
 
#define WORKLIST_REMOVE(item) worklist_remove(item)
 
1063
#define WORKLIST_INSERT(head, item) worklist_insert(head, item, 1)
 
1064
#define WORKLIST_INSERT_UNLOCKED(head, item) worklist_insert(head, item, 0)
 
1065
#define WORKLIST_REMOVE(item) worklist_remove(item, 1)
 
1066
#define WORKLIST_REMOVE_UNLOCKED(item) worklist_remove(item, 0)
581
1067
 
582
1068
static void
583
 
worklist_insert(head, item)
 
1069
worklist_insert(head, item, locked)
584
1070
        struct workhead *head;
585
1071
        struct worklist *item;
 
1072
        int locked;
586
1073
{
587
1074
 
588
 
        mtx_assert(&lk, MA_OWNED);
 
1075
        if (locked)
 
1076
                mtx_assert(&lk, MA_OWNED);
589
1077
        if (item->wk_state & ONWORKLIST)
590
 
                panic("worklist_insert: already on list");
 
1078
                panic("worklist_insert: %p %s(0x%X) already on list",
 
1079
                    item, TYPENAME(item->wk_type), item->wk_state);
591
1080
        item->wk_state |= ONWORKLIST;
592
1081
        LIST_INSERT_HEAD(head, item, wk_list);
593
1082
}
594
1083
 
595
1084
static void
596
 
worklist_remove(item)
 
1085
worklist_remove(item, locked)
597
1086
        struct worklist *item;
 
1087
        int locked;
598
1088
{
599
1089
 
600
 
        mtx_assert(&lk, MA_OWNED);
 
1090
        if (locked)
 
1091
                mtx_assert(&lk, MA_OWNED);
601
1092
        if ((item->wk_state & ONWORKLIST) == 0)
602
 
                panic("worklist_remove: not on list");
 
1093
                panic("worklist_remove: %p %s(0x%X) not on list",
 
1094
                    item, TYPENAME(item->wk_type), item->wk_state);
603
1095
        item->wk_state &= ~ONWORKLIST;
604
1096
        LIST_REMOVE(item, wk_list);
605
1097
}
606
1098
#endif /* DEBUG */
607
1099
 
608
1100
/*
 
1101
 * Merge two jsegdeps keeping only the oldest one as newer references
 
1102
 * can't be discarded until after older references.
 
1103
 */
 
1104
static inline struct jsegdep *
 
1105
jsegdep_merge(struct jsegdep *one, struct jsegdep *two)
 
1106
{
 
1107
        struct jsegdep *swp;
 
1108
 
 
1109
        if (two == NULL)
 
1110
                return (one);
 
1111
 
 
1112
        if (one->jd_seg->js_seq > two->jd_seg->js_seq) {
 
1113
                swp = one;
 
1114
                one = two;
 
1115
                two = swp;
 
1116
        }
 
1117
        WORKLIST_REMOVE(&two->jd_list);
 
1118
        free_jsegdep(two);
 
1119
 
 
1120
        return (one);
 
1121
}
 
1122
 
 
1123
/*
 
1124
 * If two freedeps are compatible free one to reduce list size.
 
1125
 */
 
1126
static inline struct freedep *
 
1127
freedep_merge(struct freedep *one, struct freedep *two)
 
1128
{
 
1129
        if (two == NULL)
 
1130
                return (one);
 
1131
 
 
1132
        if (one->fd_freework == two->fd_freework) {
 
1133
                WORKLIST_REMOVE(&two->fd_list);
 
1134
                free_freedep(two);
 
1135
        }
 
1136
        return (one);
 
1137
}
 
1138
 
 
1139
/*
 
1140
 * Move journal work from one list to another.  Duplicate freedeps and
 
1141
 * jsegdeps are coalesced to keep the lists as small as possible.
 
1142
 */
 
1143
static void
 
1144
jwork_move(dst, src)
 
1145
        struct workhead *dst;
 
1146
        struct workhead *src;
 
1147
{
 
1148
        struct freedep *freedep;
 
1149
        struct jsegdep *jsegdep;
 
1150
        struct worklist *wkn;
 
1151
        struct worklist *wk;
 
1152
 
 
1153
        KASSERT(dst != src,
 
1154
            ("jwork_move: dst == src"));
 
1155
        freedep = NULL;
 
1156
        jsegdep = NULL;
 
1157
        LIST_FOREACH_SAFE(wk, dst, wk_list, wkn) {
 
1158
                if (wk->wk_type == D_JSEGDEP)
 
1159
                        jsegdep = jsegdep_merge(WK_JSEGDEP(wk), jsegdep);
 
1160
                if (wk->wk_type == D_FREEDEP)
 
1161
                        freedep = freedep_merge(WK_FREEDEP(wk), freedep);
 
1162
        }
 
1163
 
 
1164
        mtx_assert(&lk, MA_OWNED);
 
1165
        while ((wk = LIST_FIRST(src)) != NULL) {
 
1166
                WORKLIST_REMOVE(wk);
 
1167
                WORKLIST_INSERT(dst, wk);
 
1168
                if (wk->wk_type == D_JSEGDEP) {
 
1169
                        jsegdep = jsegdep_merge(WK_JSEGDEP(wk), jsegdep);
 
1170
                        continue;
 
1171
                }
 
1172
                if (wk->wk_type == D_FREEDEP)
 
1173
                        freedep = freedep_merge(WK_FREEDEP(wk), freedep);
 
1174
        }
 
1175
}
 
1176
 
 
1177
static void
 
1178
jwork_insert(dst, jsegdep)
 
1179
        struct workhead *dst;
 
1180
        struct jsegdep *jsegdep;
 
1181
{
 
1182
        struct jsegdep *jsegdepn;
 
1183
        struct worklist *wk;
 
1184
 
 
1185
        LIST_FOREACH(wk, dst, wk_list)
 
1186
                if (wk->wk_type == D_JSEGDEP)
 
1187
                        break;
 
1188
        if (wk == NULL) {
 
1189
                WORKLIST_INSERT(dst, &jsegdep->jd_list);
 
1190
                return;
 
1191
        }
 
1192
        jsegdepn = WK_JSEGDEP(wk);
 
1193
        if (jsegdep->jd_seg->js_seq < jsegdepn->jd_seg->js_seq) {
 
1194
                WORKLIST_REMOVE(wk);
 
1195
                free_jsegdep(jsegdepn);
 
1196
                WORKLIST_INSERT(dst, &jsegdep->jd_list);
 
1197
        } else
 
1198
                free_jsegdep(jsegdep);
 
1199
}
 
1200
 
 
1201
/*
609
1202
 * Routines for tracking and managing workitems.
610
1203
 */
611
1204
static  void workitem_free(struct worklist *, int);
623
1216
 
624
1217
#ifdef DEBUG
625
1218
        if (item->wk_state & ONWORKLIST)
626
 
                panic("workitem_free: still on list");
 
1219
                panic("workitem_free: %s(0x%X) still on list",
 
1220
                    TYPENAME(item->wk_type), item->wk_state);
627
1221
        if (item->wk_type != type)
628
 
                panic("workitem_free: type mismatch");
 
1222
                panic("workitem_free: type mismatch %s != %s",
 
1223
                    TYPENAME(item->wk_type), TYPENAME(type));
629
1224
#endif
 
1225
        if (item->wk_state & IOWAITING)
 
1226
                wakeup(item);
630
1227
        ump = VFSTOUFS(item->wk_mp);
631
1228
        if (--ump->softdep_deps == 0 && ump->softdep_req)
632
1229
                wakeup(&ump->softdep_deps);
 
1230
        dep_current[type]--;
633
1231
        free(item, DtoM(type));
634
1232
}
635
1233
 
639
1237
        int type;
640
1238
        struct mount *mp;
641
1239
{
 
1240
        struct ufsmount *ump;
 
1241
 
642
1242
        item->wk_type = type;
643
1243
        item->wk_mp = mp;
644
1244
        item->wk_state = 0;
 
1245
 
 
1246
        ump = VFSTOUFS(mp);
645
1247
        ACQUIRE_LOCK(&lk);
646
 
        VFSTOUFS(mp)->softdep_deps++;
647
 
        VFSTOUFS(mp)->softdep_accdeps++;
 
1248
        dep_current[type]++;
 
1249
        dep_total[type]++;
 
1250
        ump->softdep_deps++;
 
1251
        ump->softdep_accdeps++;
648
1252
        FREE_LOCK(&lk);
649
1253
}
650
1254
 
659
1263
static struct callout softdep_callout;
660
1264
static int req_pending;
661
1265
static int req_clear_inodedeps; /* syncer process flush some inodedeps */
662
 
#define FLUSH_INODES            1
663
1266
static int req_clear_remove;    /* syncer process flush some freeblks */
664
 
#define FLUSH_REMOVE            2
665
 
#define FLUSH_REMOVE_WAIT       3
666
 
static long num_freeblkdep;     /* number of freeblks workitems allocated */
 
1267
static int softdep_flushcache = 0; /* Should we do BIO_FLUSH? */
667
1268
 
668
1269
/*
669
1270
 * runtime statistics
678
1279
static int stat_inode_bitmap;   /* bufs redirtied as inode bitmap not written */
679
1280
static int stat_direct_blk_ptrs;/* bufs redirtied as direct ptrs not written */
680
1281
static int stat_dir_entry;      /* bufs redirtied as dir entry cannot write */
 
1282
static int stat_jaddref;        /* bufs redirtied as ino bitmap can not write */
 
1283
static int stat_jnewblk;        /* bufs redirtied as blk bitmap can not write */
 
1284
static int stat_journal_min;    /* Times hit journal min threshold */
 
1285
static int stat_journal_low;    /* Times hit journal low threshold */
 
1286
static int stat_journal_wait;   /* Times blocked in jwait(). */
 
1287
static int stat_jwait_filepage; /* Times blocked in jwait() for filepage. */
 
1288
static int stat_jwait_freeblks; /* Times blocked in jwait() for freeblks. */
 
1289
static int stat_jwait_inode;    /* Times blocked in jwait() for inodes. */
 
1290
static int stat_jwait_newblk;   /* Times blocked in jwait() for newblks. */
 
1291
static int stat_cleanup_high_delay; /* Maximum cleanup delay (in ticks) */
 
1292
static int stat_cleanup_blkrequests; /* Number of block cleanup requests */
 
1293
static int stat_cleanup_inorequests; /* Number of inode cleanup requests */
 
1294
static int stat_cleanup_retries; /* Number of cleanups that needed to flush */
 
1295
static int stat_cleanup_failures; /* Number of cleanup requests that failed */
681
1296
 
682
 
SYSCTL_INT(_debug, OID_AUTO, max_softdeps, CTLFLAG_RW, &max_softdeps, 0, "");
683
 
SYSCTL_INT(_debug, OID_AUTO, tickdelay, CTLFLAG_RW, &tickdelay, 0, "");
684
 
SYSCTL_INT(_debug, OID_AUTO, maxindirdeps, CTLFLAG_RW, &maxindirdeps, 0, "");
685
 
SYSCTL_INT(_debug, OID_AUTO, worklist_push, CTLFLAG_RW, &stat_worklist_push, 0,"");
686
 
SYSCTL_INT(_debug, OID_AUTO, blk_limit_push, CTLFLAG_RW, &stat_blk_limit_push, 0,"");
687
 
SYSCTL_INT(_debug, OID_AUTO, ino_limit_push, CTLFLAG_RW, &stat_ino_limit_push, 0,"");
688
 
SYSCTL_INT(_debug, OID_AUTO, blk_limit_hit, CTLFLAG_RW, &stat_blk_limit_hit, 0, "");
689
 
SYSCTL_INT(_debug, OID_AUTO, ino_limit_hit, CTLFLAG_RW, &stat_ino_limit_hit, 0, "");
690
 
SYSCTL_INT(_debug, OID_AUTO, sync_limit_hit, CTLFLAG_RW, &stat_sync_limit_hit, 0, "");
691
 
SYSCTL_INT(_debug, OID_AUTO, indir_blk_ptrs, CTLFLAG_RW, &stat_indir_blk_ptrs, 0, "");
692
 
SYSCTL_INT(_debug, OID_AUTO, inode_bitmap, CTLFLAG_RW, &stat_inode_bitmap, 0, "");
693
 
SYSCTL_INT(_debug, OID_AUTO, direct_blk_ptrs, CTLFLAG_RW, &stat_direct_blk_ptrs, 0, "");
694
 
SYSCTL_INT(_debug, OID_AUTO, dir_entry, CTLFLAG_RW, &stat_dir_entry, 0, "");
695
 
/* SYSCTL_INT(_debug, OID_AUTO, worklist_num, CTLFLAG_RD, &softdep_on_worklist, 0, ""); */
 
1297
SYSCTL_INT(_debug_softdep, OID_AUTO, max_softdeps, CTLFLAG_RW,
 
1298
    &max_softdeps, 0, "");
 
1299
SYSCTL_INT(_debug_softdep, OID_AUTO, tickdelay, CTLFLAG_RW,
 
1300
    &tickdelay, 0, "");
 
1301
SYSCTL_INT(_debug_softdep, OID_AUTO, maxindirdeps, CTLFLAG_RW,
 
1302
    &maxindirdeps, 0, "");
 
1303
SYSCTL_INT(_debug_softdep, OID_AUTO, worklist_push, CTLFLAG_RW,
 
1304
    &stat_worklist_push, 0,"");
 
1305
SYSCTL_INT(_debug_softdep, OID_AUTO, blk_limit_push, CTLFLAG_RW,
 
1306
    &stat_blk_limit_push, 0,"");
 
1307
SYSCTL_INT(_debug_softdep, OID_AUTO, ino_limit_push, CTLFLAG_RW,
 
1308
    &stat_ino_limit_push, 0,"");
 
1309
SYSCTL_INT(_debug_softdep, OID_AUTO, blk_limit_hit, CTLFLAG_RW,
 
1310
    &stat_blk_limit_hit, 0, "");
 
1311
SYSCTL_INT(_debug_softdep, OID_AUTO, ino_limit_hit, CTLFLAG_RW,
 
1312
    &stat_ino_limit_hit, 0, "");
 
1313
SYSCTL_INT(_debug_softdep, OID_AUTO, sync_limit_hit, CTLFLAG_RW,
 
1314
    &stat_sync_limit_hit, 0, "");
 
1315
SYSCTL_INT(_debug_softdep, OID_AUTO, indir_blk_ptrs, CTLFLAG_RW,
 
1316
    &stat_indir_blk_ptrs, 0, "");
 
1317
SYSCTL_INT(_debug_softdep, OID_AUTO, inode_bitmap, CTLFLAG_RW,
 
1318
    &stat_inode_bitmap, 0, "");
 
1319
SYSCTL_INT(_debug_softdep, OID_AUTO, direct_blk_ptrs, CTLFLAG_RW,
 
1320
    &stat_direct_blk_ptrs, 0, "");
 
1321
SYSCTL_INT(_debug_softdep, OID_AUTO, dir_entry, CTLFLAG_RW,
 
1322
    &stat_dir_entry, 0, "");
 
1323
SYSCTL_INT(_debug_softdep, OID_AUTO, jaddref_rollback, CTLFLAG_RW,
 
1324
    &stat_jaddref, 0, "");
 
1325
SYSCTL_INT(_debug_softdep, OID_AUTO, jnewblk_rollback, CTLFLAG_RW,
 
1326
    &stat_jnewblk, 0, "");
 
1327
SYSCTL_INT(_debug_softdep, OID_AUTO, journal_low, CTLFLAG_RW,
 
1328
    &stat_journal_low, 0, "");
 
1329
SYSCTL_INT(_debug_softdep, OID_AUTO, journal_min, CTLFLAG_RW,
 
1330
    &stat_journal_min, 0, "");
 
1331
SYSCTL_INT(_debug_softdep, OID_AUTO, journal_wait, CTLFLAG_RW,
 
1332
    &stat_journal_wait, 0, "");
 
1333
SYSCTL_INT(_debug_softdep, OID_AUTO, jwait_filepage, CTLFLAG_RW,
 
1334
    &stat_jwait_filepage, 0, "");
 
1335
SYSCTL_INT(_debug_softdep, OID_AUTO, jwait_freeblks, CTLFLAG_RW,
 
1336
    &stat_jwait_freeblks, 0, "");
 
1337
SYSCTL_INT(_debug_softdep, OID_AUTO, jwait_inode, CTLFLAG_RW,
 
1338
    &stat_jwait_inode, 0, "");
 
1339
SYSCTL_INT(_debug_softdep, OID_AUTO, jwait_newblk, CTLFLAG_RW,
 
1340
    &stat_jwait_newblk, 0, "");
 
1341
SYSCTL_INT(_debug_softdep, OID_AUTO, cleanup_blkrequests, CTLFLAG_RW,
 
1342
    &stat_cleanup_blkrequests, 0, "");
 
1343
SYSCTL_INT(_debug_softdep, OID_AUTO, cleanup_inorequests, CTLFLAG_RW,
 
1344
    &stat_cleanup_inorequests, 0, "");
 
1345
SYSCTL_INT(_debug_softdep, OID_AUTO, cleanup_high_delay, CTLFLAG_RW,
 
1346
    &stat_cleanup_high_delay, 0, "");
 
1347
SYSCTL_INT(_debug_softdep, OID_AUTO, cleanup_retries, CTLFLAG_RW,
 
1348
    &stat_cleanup_retries, 0, "");
 
1349
SYSCTL_INT(_debug_softdep, OID_AUTO, cleanup_failures, CTLFLAG_RW,
 
1350
    &stat_cleanup_failures, 0, "");
 
1351
SYSCTL_INT(_debug_softdep, OID_AUTO, flushcache, CTLFLAG_RW,
 
1352
    &softdep_flushcache, 0, "");
696
1353
 
697
1354
SYSCTL_DECL(_vfs_ffs);
698
1355
 
 
1356
LIST_HEAD(bmsafemap_hashhead, bmsafemap) *bmsafemap_hashtbl;
 
1357
static u_long   bmsafemap_hash; /* size of hash table - 1 */
 
1358
 
699
1359
static int compute_summary_at_mount = 0;        /* Whether to recompute the summary at mount time */
700
1360
SYSCTL_INT(_vfs_ffs, OID_AUTO, compute_summary_at_mount, CTLFLAG_RW,
701
1361
           &compute_summary_at_mount, 0, "Recompute summary at mount");
717
1377
        struct ufsmount *ump;
718
1378
        struct thread *td;
719
1379
        int remaining;
 
1380
        int progress;
720
1381
        int vfslocked;
721
1382
 
722
1383
        td = curthread;
741
1402
                }
742
1403
                FREE_LOCK(&lk);
743
1404
                VFS_UNLOCK_GIANT(vfslocked);
744
 
                remaining = 0;
 
1405
                remaining = progress = 0;
745
1406
                mtx_lock(&mountlist_mtx);
746
1407
                for (mp = TAILQ_FIRST(&mountlist); mp != NULL; mp = nmp)  {
747
1408
                        nmp = TAILQ_NEXT(mp, mnt_list);
748
 
                        if ((mp->mnt_flag & MNT_SOFTDEP) == 0)
 
1409
                        if (MOUNTEDSOFTDEP(mp) == 0)
749
1410
                                continue;
750
1411
                        if (vfs_busy(mp, MBF_NOWAIT | MBF_MNTLSTLOCK))
751
1412
                                continue;
752
1413
                        vfslocked = VFS_LOCK_GIANT(mp);
753
 
                        softdep_process_worklist(mp, 0);
 
1414
                        progress += softdep_process_worklist(mp, 0);
754
1415
                        ump = VFSTOUFS(mp);
755
 
                        remaining += ump->softdep_on_worklist -
756
 
                                ump->softdep_on_worklist_inprogress;
 
1416
                        remaining += ump->softdep_on_worklist;
757
1417
                        VFS_UNLOCK_GIANT(vfslocked);
758
1418
                        mtx_lock(&mountlist_mtx);
759
1419
                        nmp = TAILQ_NEXT(mp, mnt_list);
760
1420
                        vfs_unbusy(mp);
761
1421
                }
762
1422
                mtx_unlock(&mountlist_mtx);
763
 
                if (remaining)
 
1423
                if (remaining && progress)
764
1424
                        continue;
765
1425
                ACQUIRE_LOCK(&lk);
766
1426
                if (!req_pending)
770
1430
        }
771
1431
}
772
1432
 
773
 
static int
774
 
softdep_speedup(void)
 
1433
static void
 
1434
worklist_speedup(void)
775
1435
{
776
 
 
777
1436
        mtx_assert(&lk, MA_OWNED);
778
1437
        if (req_pending == 0) {
779
1438
                req_pending = 1;
780
1439
                wakeup(&req_pending);
781
1440
        }
782
 
 
 
1441
}
 
1442
 
 
1443
static int
 
1444
softdep_speedup(void)
 
1445
{
 
1446
 
 
1447
        worklist_speedup();
 
1448
        bd_speedup();
783
1449
        return speedup_syncer();
784
1450
}
785
1451
 
790
1456
 * The following routine is the only one that removes items
791
1457
 * and does so in order from first to last.
792
1458
 */
 
1459
 
 
1460
#define WK_HEAD         0x0001  /* Add to HEAD. */
 
1461
#define WK_NODELAY      0x0002  /* Process immediately. */
 
1462
 
793
1463
static void
794
 
add_to_worklist(wk)
 
1464
add_to_worklist(wk, flags)
795
1465
        struct worklist *wk;
 
1466
        int flags;
796
1467
{
797
1468
        struct ufsmount *ump;
798
1469
 
799
1470
        mtx_assert(&lk, MA_OWNED);
800
1471
        ump = VFSTOUFS(wk->wk_mp);
801
1472
        if (wk->wk_state & ONWORKLIST)
802
 
                panic("add_to_worklist: already on list");
 
1473
                panic("add_to_worklist: %s(0x%X) already on list",
 
1474
                    TYPENAME(wk->wk_type), wk->wk_state);
803
1475
        wk->wk_state |= ONWORKLIST;
804
 
        if (LIST_EMPTY(&ump->softdep_workitem_pending))
805
 
                LIST_INSERT_HEAD(&ump->softdep_workitem_pending, wk, wk_list);
806
 
        else
 
1476
        if (ump->softdep_on_worklist == 0) {
 
1477
                LIST_INSERT_HEAD(&ump->softdep_workitem_pending, wk, wk_list);
 
1478
                ump->softdep_worklist_tail = wk;
 
1479
        } else if (flags & WK_HEAD) {
 
1480
                LIST_INSERT_HEAD(&ump->softdep_workitem_pending, wk, wk_list);
 
1481
        } else {
807
1482
                LIST_INSERT_AFTER(ump->softdep_worklist_tail, wk, wk_list);
808
 
        ump->softdep_worklist_tail = wk;
 
1483
                ump->softdep_worklist_tail = wk;
 
1484
        }
809
1485
        ump->softdep_on_worklist += 1;
 
1486
        if (flags & WK_NODELAY)
 
1487
                worklist_speedup();
 
1488
}
 
1489
 
 
1490
/*
 
1491
 * Remove the item to be processed. If we are removing the last
 
1492
 * item on the list, we need to recalculate the tail pointer.
 
1493
 */
 
1494
static void
 
1495
remove_from_worklist(wk)
 
1496
        struct worklist *wk;
 
1497
{
 
1498
        struct ufsmount *ump;
 
1499
 
 
1500
        ump = VFSTOUFS(wk->wk_mp);
 
1501
        WORKLIST_REMOVE(wk);
 
1502
        if (ump->softdep_worklist_tail == wk)
 
1503
                ump->softdep_worklist_tail =
 
1504
                    (struct worklist *)wk->wk_list.le_prev;
 
1505
        ump->softdep_on_worklist -= 1;
 
1506
}
 
1507
 
 
1508
static void
 
1509
wake_worklist(wk)
 
1510
        struct worklist *wk;
 
1511
{
 
1512
        if (wk->wk_state & IOWAITING) {
 
1513
                wk->wk_state &= ~IOWAITING;
 
1514
                wakeup(wk);
 
1515
        }
 
1516
}
 
1517
 
 
1518
static void
 
1519
wait_worklist(wk, wmesg)
 
1520
        struct worklist *wk;
 
1521
        char *wmesg;
 
1522
{
 
1523
 
 
1524
        wk->wk_state |= IOWAITING;
 
1525
        msleep(wk, &lk, PVM, wmesg, 0);
810
1526
}
811
1527
 
812
1528
/*
824
1540
        int full;
825
1541
{
826
1542
        struct thread *td = curthread;
827
 
        int cnt, matchcnt, loopcount;
 
1543
        int cnt, matchcnt;
828
1544
        struct ufsmount *ump;
829
1545
        long starttime;
830
1546
 
836
1552
        matchcnt = 0;
837
1553
        ump = VFSTOUFS(mp);
838
1554
        ACQUIRE_LOCK(&lk);
839
 
        loopcount = 1;
840
1555
        starttime = time_second;
 
1556
        softdep_process_journal(mp, NULL, full?MNT_WAIT:0);
841
1557
        while (ump->softdep_on_worklist > 0) {
842
 
                if ((cnt = process_worklist_item(mp, 0)) == -1)
 
1558
                if ((cnt = process_worklist_item(mp, 10, LK_NOWAIT)) == 0)
843
1559
                        break;
844
1560
                else
845
1561
                        matchcnt += cnt;
860
1576
                 * We do not generally want to stop for buffer space, but if
861
1577
                 * we are really being a buffer hog, we will stop and wait.
862
1578
                 */
863
 
                if (loopcount++ % 128 == 0) {
 
1579
                if (should_yield()) {
864
1580
                        FREE_LOCK(&lk);
865
 
                        uio_yield();
 
1581
                        kern_yield(PRI_UNCHANGED);
866
1582
                        bwillwrite();
867
1583
                        ACQUIRE_LOCK(&lk);
868
1584
                }
871
1587
                 * second. Otherwise the other mountpoints may get
872
1588
                 * excessively backlogged.
873
1589
                 */
874
 
                if (!full && starttime != time_second) {
875
 
                        matchcnt = -1;
 
1590
                if (!full && starttime != time_second)
876
1591
                        break;
877
 
                }
878
1592
        }
 
1593
        if (full == 0)
 
1594
                journal_unsuspend(ump);
879
1595
        FREE_LOCK(&lk);
880
1596
        return (matchcnt);
881
1597
}
882
1598
 
883
1599
/*
 
1600
 * Process all removes associated with a vnode if we are running out of
 
1601
 * journal space.  Any other process which attempts to flush these will
 
1602
 * be unable as we have the vnodes locked.
 
1603
 */
 
1604
static void
 
1605
process_removes(vp)
 
1606
        struct vnode *vp;
 
1607
{
 
1608
        struct inodedep *inodedep;
 
1609
        struct dirrem *dirrem;
 
1610
        struct mount *mp;
 
1611
        ino_t inum;
 
1612
 
 
1613
        mtx_assert(&lk, MA_OWNED);
 
1614
 
 
1615
        mp = vp->v_mount;
 
1616
        inum = VTOI(vp)->i_number;
 
1617
        for (;;) {
 
1618
top:
 
1619
                if (inodedep_lookup(mp, inum, 0, &inodedep) == 0)
 
1620
                        return;
 
1621
                LIST_FOREACH(dirrem, &inodedep->id_dirremhd, dm_inonext) {
 
1622
                        /*
 
1623
                         * If another thread is trying to lock this vnode
 
1624
                         * it will fail but we must wait for it to do so
 
1625
                         * before we can proceed.
 
1626
                         */
 
1627
                        if (dirrem->dm_state & INPROGRESS) {
 
1628
                                wait_worklist(&dirrem->dm_list, "pwrwait");
 
1629
                                goto top;
 
1630
                        }
 
1631
                        if ((dirrem->dm_state & (COMPLETE | ONWORKLIST)) == 
 
1632
                            (COMPLETE | ONWORKLIST))
 
1633
                                break;
 
1634
                }
 
1635
                if (dirrem == NULL)
 
1636
                        return;
 
1637
                remove_from_worklist(&dirrem->dm_list);
 
1638
                FREE_LOCK(&lk);
 
1639
                if (vn_start_secondary_write(NULL, &mp, V_NOWAIT))
 
1640
                        panic("process_removes: suspended filesystem");
 
1641
                handle_workitem_remove(dirrem, 0);
 
1642
                vn_finished_secondary_write(mp);
 
1643
                ACQUIRE_LOCK(&lk);
 
1644
        }
 
1645
}
 
1646
 
 
1647
/*
 
1648
 * Process all truncations associated with a vnode if we are running out
 
1649
 * of journal space.  This is called when the vnode lock is already held
 
1650
 * and no other process can clear the truncation.  This function returns
 
1651
 * a value greater than zero if it did any work.
 
1652
 */
 
1653
static void
 
1654
process_truncates(vp)
 
1655
        struct vnode *vp;
 
1656
{
 
1657
        struct inodedep *inodedep;
 
1658
        struct freeblks *freeblks;
 
1659
        struct mount *mp;
 
1660
        ino_t inum;
 
1661
        int cgwait;
 
1662
 
 
1663
        mtx_assert(&lk, MA_OWNED);
 
1664
 
 
1665
        mp = vp->v_mount;
 
1666
        inum = VTOI(vp)->i_number;
 
1667
        for (;;) {
 
1668
                if (inodedep_lookup(mp, inum, 0, &inodedep) == 0)
 
1669
                        return;
 
1670
                cgwait = 0;
 
1671
                TAILQ_FOREACH(freeblks, &inodedep->id_freeblklst, fb_next) {
 
1672
                        /* Journal entries not yet written.  */
 
1673
                        if (!LIST_EMPTY(&freeblks->fb_jblkdephd)) {
 
1674
                                jwait(&LIST_FIRST(
 
1675
                                    &freeblks->fb_jblkdephd)->jb_list,
 
1676
                                    MNT_WAIT);
 
1677
                                break;
 
1678
                        }
 
1679
                        /* Another thread is executing this item. */
 
1680
                        if (freeblks->fb_state & INPROGRESS) {
 
1681
                                wait_worklist(&freeblks->fb_list, "ptrwait");
 
1682
                                break;
 
1683
                        }
 
1684
                        /* Freeblks is waiting on a inode write. */
 
1685
                        if ((freeblks->fb_state & COMPLETE) == 0) {
 
1686
                                FREE_LOCK(&lk);
 
1687
                                ffs_update(vp, 1);
 
1688
                                ACQUIRE_LOCK(&lk);
 
1689
                                break;
 
1690
                        }
 
1691
                        if ((freeblks->fb_state & (ALLCOMPLETE | ONWORKLIST)) ==
 
1692
                            (ALLCOMPLETE | ONWORKLIST)) {
 
1693
                                remove_from_worklist(&freeblks->fb_list);
 
1694
                                freeblks->fb_state |= INPROGRESS;
 
1695
                                FREE_LOCK(&lk);
 
1696
                                if (vn_start_secondary_write(NULL, &mp,
 
1697
                                    V_NOWAIT))
 
1698
                                        panic("process_truncates: "
 
1699
                                            "suspended filesystem");
 
1700
                                handle_workitem_freeblocks(freeblks, 0);
 
1701
                                vn_finished_secondary_write(mp);
 
1702
                                ACQUIRE_LOCK(&lk);
 
1703
                                break;
 
1704
                        }
 
1705
                        if (freeblks->fb_cgwait)
 
1706
                                cgwait++;
 
1707
                }
 
1708
                if (cgwait) {
 
1709
                        FREE_LOCK(&lk);
 
1710
                        sync_cgs(mp, MNT_WAIT);
 
1711
                        ffs_sync_snap(mp, MNT_WAIT);
 
1712
                        ACQUIRE_LOCK(&lk);
 
1713
                        continue;
 
1714
                }
 
1715
                if (freeblks == NULL)
 
1716
                        break;
 
1717
        }
 
1718
        return;
 
1719
}
 
1720
 
 
1721
/*
884
1722
 * Process one item on the worklist.
885
1723
 */
886
1724
static int
887
 
process_worklist_item(mp, flags)
 
1725
process_worklist_item(mp, target, flags)
888
1726
        struct mount *mp;
 
1727
        int target;
889
1728
        int flags;
890
1729
{
891
 
        struct worklist *wk, *wkend;
 
1730
        struct worklist sentinel;
 
1731
        struct worklist *wk;
892
1732
        struct ufsmount *ump;
893
 
        struct vnode *vp;
894
 
        int matchcnt = 0;
 
1733
        int matchcnt;
 
1734
        int error;
895
1735
 
896
1736
        mtx_assert(&lk, MA_OWNED);
897
1737
        KASSERT(mp != NULL, ("process_worklist_item: NULL mp"));
902
1742
         */
903
1743
        if (curthread->td_pflags & TDP_COWINPROGRESS)
904
1744
                return (-1);
905
 
        /*
906
 
         * Normally we just process each item on the worklist in order.
907
 
         * However, if we are in a situation where we cannot lock any
908
 
         * inodes, we have to skip over any dirrem requests whose
909
 
         * vnodes are resident and locked.
910
 
         */
 
1745
        PHOLD(curproc); /* Don't let the stack go away. */
911
1746
        ump = VFSTOUFS(mp);
912
 
        vp = NULL;
913
 
        LIST_FOREACH(wk, &ump->softdep_workitem_pending, wk_list) {
 
1747
        matchcnt = 0;
 
1748
        sentinel.wk_mp = NULL;
 
1749
        sentinel.wk_type = D_SENTINEL;
 
1750
        LIST_INSERT_HEAD(&ump->softdep_workitem_pending, &sentinel, wk_list);
 
1751
        for (wk = LIST_NEXT(&sentinel, wk_list); wk != NULL;
 
1752
            wk = LIST_NEXT(&sentinel, wk_list)) {
 
1753
                if (wk->wk_type == D_SENTINEL) {
 
1754
                        LIST_REMOVE(&sentinel, wk_list);
 
1755
                        LIST_INSERT_AFTER(wk, &sentinel, wk_list);
 
1756
                        continue;
 
1757
                }
914
1758
                if (wk->wk_state & INPROGRESS)
915
 
                        continue;
916
 
                if ((flags & LK_NOWAIT) == 0 || wk->wk_type != D_DIRREM)
917
 
                        break;
 
1759
                        panic("process_worklist_item: %p already in progress.",
 
1760
                            wk);
918
1761
                wk->wk_state |= INPROGRESS;
919
 
                ump->softdep_on_worklist_inprogress++;
 
1762
                remove_from_worklist(wk);
920
1763
                FREE_LOCK(&lk);
921
 
                ffs_vgetf(mp, WK_DIRREM(wk)->dm_oldinum,
922
 
                    LK_NOWAIT | LK_EXCLUSIVE, &vp, FFSV_FORCEINSMQ);
 
1764
                if (vn_start_secondary_write(NULL, &mp, V_NOWAIT))
 
1765
                        panic("process_worklist_item: suspended filesystem");
 
1766
                switch (wk->wk_type) {
 
1767
                case D_DIRREM:
 
1768
                        /* removal of a directory entry */
 
1769
                        error = handle_workitem_remove(WK_DIRREM(wk), flags);
 
1770
                        break;
 
1771
 
 
1772
                case D_FREEBLKS:
 
1773
                        /* releasing blocks and/or fragments from a file */
 
1774
                        error = handle_workitem_freeblocks(WK_FREEBLKS(wk),
 
1775
                            flags);
 
1776
                        break;
 
1777
 
 
1778
                case D_FREEFRAG:
 
1779
                        /* releasing a fragment when replaced as a file grows */
 
1780
                        handle_workitem_freefrag(WK_FREEFRAG(wk));
 
1781
                        error = 0;
 
1782
                        break;
 
1783
 
 
1784
                case D_FREEFILE:
 
1785
                        /* releasing an inode when its link count drops to 0 */
 
1786
                        handle_workitem_freefile(WK_FREEFILE(wk));
 
1787
                        error = 0;
 
1788
                        break;
 
1789
 
 
1790
                default:
 
1791
                        panic("%s_process_worklist: Unknown type %s",
 
1792
                            "softdep", TYPENAME(wk->wk_type));
 
1793
                        /* NOTREACHED */
 
1794
                }
 
1795
                vn_finished_secondary_write(mp);
923
1796
                ACQUIRE_LOCK(&lk);
 
1797
                if (error == 0) {
 
1798
                        if (++matchcnt == target)
 
1799
                                break;
 
1800
                        continue;
 
1801
                }
 
1802
                /*
 
1803
                 * We have to retry the worklist item later.  Wake up any
 
1804
                 * waiters who may be able to complete it immediately and
 
1805
                 * add the item back to the head so we don't try to execute
 
1806
                 * it again.
 
1807
                 */
924
1808
                wk->wk_state &= ~INPROGRESS;
925
 
                ump->softdep_on_worklist_inprogress--;
926
 
                if (vp != NULL)
927
 
                        break;
928
 
        }
929
 
        if (wk == 0)
930
 
                return (-1);
931
 
        /*
932
 
         * Remove the item to be processed. If we are removing the last
933
 
         * item on the list, we need to recalculate the tail pointer.
934
 
         * As this happens rarely and usually when the list is short,
935
 
         * we just run down the list to find it rather than tracking it
936
 
         * in the above loop.
937
 
         */
938
 
        WORKLIST_REMOVE(wk);
939
 
        if (wk == ump->softdep_worklist_tail) {
940
 
                LIST_FOREACH(wkend, &ump->softdep_workitem_pending, wk_list)
941
 
                        if (LIST_NEXT(wkend, wk_list) == NULL)
942
 
                                break;
943
 
                ump->softdep_worklist_tail = wkend;
944
 
        }
945
 
        ump->softdep_on_worklist -= 1;
946
 
        FREE_LOCK(&lk);
947
 
        if (vn_start_secondary_write(NULL, &mp, V_NOWAIT))
948
 
                panic("process_worklist_item: suspended filesystem");
949
 
        matchcnt++;
950
 
        switch (wk->wk_type) {
951
 
 
952
 
        case D_DIRREM:
953
 
                /* removal of a directory entry */
954
 
                handle_workitem_remove(WK_DIRREM(wk), vp);
955
 
                break;
956
 
 
957
 
        case D_FREEBLKS:
958
 
                /* releasing blocks and/or fragments from a file */
959
 
                handle_workitem_freeblocks(WK_FREEBLKS(wk), flags & LK_NOWAIT);
960
 
                break;
961
 
 
962
 
        case D_FREEFRAG:
963
 
                /* releasing a fragment when replaced as a file grows */
964
 
                handle_workitem_freefrag(WK_FREEFRAG(wk));
965
 
                break;
966
 
 
967
 
        case D_FREEFILE:
968
 
                /* releasing an inode when its link count drops to 0 */
969
 
                handle_workitem_freefile(WK_FREEFILE(wk));
970
 
                break;
971
 
 
972
 
        default:
973
 
                panic("%s_process_worklist: Unknown type %s",
974
 
                    "softdep", TYPENAME(wk->wk_type));
975
 
                /* NOTREACHED */
976
 
        }
977
 
        vn_finished_secondary_write(mp);
978
 
        ACQUIRE_LOCK(&lk);
 
1809
                wake_worklist(wk);
 
1810
                add_to_worklist(wk, WK_HEAD);
 
1811
        }
 
1812
        LIST_REMOVE(&sentinel, wk_list);
 
1813
        /* Sentinal could've become the tail from remove_from_worklist. */
 
1814
        if (ump->softdep_worklist_tail == &sentinel)
 
1815
                ump->softdep_worklist_tail =
 
1816
                    (struct worklist *)sentinel.wk_list.le_prev;
 
1817
        PRELE(curproc);
979
1818
        return (matchcnt);
980
1819
}
981
1820
 
982
1821
/*
983
1822
 * Move dependencies from one buffer to another.
984
1823
 */
985
 
void
 
1824
int
986
1825
softdep_move_dependencies(oldbp, newbp)
987
1826
        struct buf *oldbp;
988
1827
        struct buf *newbp;
989
1828
{
990
1829
        struct worklist *wk, *wktail;
 
1830
        int dirty;
991
1831
 
992
 
        if (!LIST_EMPTY(&newbp->b_dep))
993
 
                panic("softdep_move_dependencies: need merge code");
994
 
        wktail = 0;
 
1832
        dirty = 0;
 
1833
        wktail = NULL;
995
1834
        ACQUIRE_LOCK(&lk);
996
1835
        while ((wk = LIST_FIRST(&oldbp->b_dep)) != NULL) {
997
1836
                LIST_REMOVE(wk, wk_list);
 
1837
                if (wk->wk_type == D_BMSAFEMAP &&
 
1838
                    bmsafemap_backgroundwrite(WK_BMSAFEMAP(wk), newbp))
 
1839
                        dirty = 1;
998
1840
                if (wktail == 0)
999
1841
                        LIST_INSERT_HEAD(&newbp->b_dep, wk, wk_list);
1000
1842
                else
1002
1844
                wktail = wk;
1003
1845
        }
1004
1846
        FREE_LOCK(&lk);
 
1847
 
 
1848
        return (dirty);
1005
1849
}
1006
1850
 
1007
1851
/*
1073
1917
        int flags;
1074
1918
        struct thread *td;
1075
1919
{
1076
 
        int error, depcount, loopcnt, retry_flush_count, retry;
 
1920
#ifdef QUOTA
 
1921
        struct ufsmount *ump;
 
1922
        int i;
 
1923
#endif
 
1924
        int error, early, depcount, loopcnt, retry_flush_count, retry;
 
1925
        int morework;
1077
1926
 
1078
1927
        loopcnt = 10;
1079
1928
        retry_flush_count = 3;
1091
1940
                 * Do another flush in case any vnodes were brought in
1092
1941
                 * as part of the cleanup operations.
1093
1942
                 */
1094
 
                if ((error = ffs_flushfiles(oldmnt, flags, td)) != 0)
 
1943
                early = retry_flush_count == 1 || (oldmnt->mnt_kern_flag &
 
1944
                    MNTK_UNMOUNT) == 0 ? 0 : EARLYFLUSH;
 
1945
                if ((error = ffs_flushfiles(oldmnt, flags | early, td)) != 0)
1095
1946
                        break;
1096
1947
                if ((error = softdep_flushworklist(oldmnt, &depcount, td)) != 0 ||
1097
1948
                    depcount == 0)
1115
1966
                        MNT_ILOCK(oldmnt);
1116
1967
                        KASSERT((oldmnt->mnt_kern_flag & MNTK_NOINSMNTQ) != 0,
1117
1968
                            ("softdep_flushfiles: !MNTK_NOINSMNTQ"));
1118
 
                        if (oldmnt->mnt_nvnodelistsize > 0) {
 
1969
                        morework = oldmnt->mnt_nvnodelistsize > 0;
 
1970
#ifdef QUOTA
 
1971
                        ump = VFSTOUFS(oldmnt);
 
1972
                        UFS_LOCK(ump);
 
1973
                        for (i = 0; i < MAXQUOTAS; i++) {
 
1974
                                if (ump->um_quotas[i] != NULLVP)
 
1975
                                        morework = 1;
 
1976
                        }
 
1977
                        UFS_UNLOCK(ump);
 
1978
#endif
 
1979
                        if (morework) {
1119
1980
                                if (--retry_flush_count > 0) {
1120
1981
                                        retry = 1;
1121
1982
                                        loopcnt = 3;
1175
2036
{
1176
2037
        struct pagedep *pagedep;
1177
2038
 
1178
 
        LIST_FOREACH(pagedep, pagedephd, pd_hash)
1179
 
                if (ino == pagedep->pd_ino &&
1180
 
                    lbn == pagedep->pd_lbn &&
1181
 
                    mp == pagedep->pd_list.wk_mp)
1182
 
                        break;
1183
 
        if (pagedep) {
1184
 
                *pagedeppp = pagedep;
1185
 
                if ((flags & DEPALLOC) != 0 &&
1186
 
                    (pagedep->pd_state & ONWORKLIST) == 0)
1187
 
                        return (0);
1188
 
                return (1);
 
2039
        LIST_FOREACH(pagedep, pagedephd, pd_hash) {
 
2040
                if (ino == pagedep->pd_ino && lbn == pagedep->pd_lbn &&
 
2041
                    mp == pagedep->pd_list.wk_mp) {
 
2042
                        *pagedeppp = pagedep;
 
2043
                        return (1);
 
2044
                }
1189
2045
        }
1190
2046
        *pagedeppp = NULL;
1191
2047
        return (0);
1192
2048
}
1193
2049
/*
1194
 
 * Look up a pagedep. Return 1 if found, 0 if not found or found
1195
 
 * when asked to allocate but not associated with any buffer.
 
2050
 * Look up a pagedep. Return 1 if found, 0 otherwise.
1196
2051
 * If not found, allocate if DEPALLOC flag is passed.
1197
2052
 * Found or allocated entry is returned in pagedeppp.
1198
2053
 * This routine must be called with splbio interrupts blocked.
1199
2054
 */
1200
2055
static int
1201
 
pagedep_lookup(ip, lbn, flags, pagedeppp)
1202
 
        struct inode *ip;
 
2056
pagedep_lookup(mp, bp, ino, lbn, flags, pagedeppp)
 
2057
        struct mount *mp;
 
2058
        struct buf *bp;
 
2059
        ino_t ino;
1203
2060
        ufs_lbn_t lbn;
1204
2061
        int flags;
1205
2062
        struct pagedep **pagedeppp;
1206
2063
{
1207
2064
        struct pagedep *pagedep;
1208
2065
        struct pagedep_hashhead *pagedephd;
1209
 
        struct mount *mp;
 
2066
        struct worklist *wk;
1210
2067
        int ret;
1211
2068
        int i;
1212
2069
 
1213
2070
        mtx_assert(&lk, MA_OWNED);
1214
 
        mp = ITOV(ip)->v_mount;
1215
 
        pagedephd = PAGEDEP_HASH(mp, ip->i_number, lbn);
1216
 
 
1217
 
        ret = pagedep_find(pagedephd, ip->i_number, lbn, mp, flags, pagedeppp);
1218
 
        if (*pagedeppp || (flags & DEPALLOC) == 0)
1219
 
                return (ret);
 
2071
        if (bp) {
 
2072
                LIST_FOREACH(wk, &bp->b_dep, wk_list) {
 
2073
                        if (wk->wk_type == D_PAGEDEP) {
 
2074
                                *pagedeppp = WK_PAGEDEP(wk);
 
2075
                                return (1);
 
2076
                        }
 
2077
                }
 
2078
        }
 
2079
        pagedephd = PAGEDEP_HASH(mp, ino, lbn);
 
2080
        ret = pagedep_find(pagedephd, ino, lbn, mp, flags, pagedeppp);
 
2081
        if (ret) {
 
2082
                if (((*pagedeppp)->pd_state & ONWORKLIST) == 0 && bp)
 
2083
                        WORKLIST_INSERT(&bp->b_dep, &(*pagedeppp)->pd_list);
 
2084
                return (1);
 
2085
        }
 
2086
        if ((flags & DEPALLOC) == 0)
 
2087
                return (0);
1220
2088
        FREE_LOCK(&lk);
1221
2089
        pagedep = malloc(sizeof(struct pagedep),
1222
2090
            M_PAGEDEP, M_SOFTDEP_FLAGS|M_ZERO);
1223
2091
        workitem_alloc(&pagedep->pd_list, D_PAGEDEP, mp);
1224
2092
        ACQUIRE_LOCK(&lk);
1225
 
        ret = pagedep_find(pagedephd, ip->i_number, lbn, mp, flags, pagedeppp);
 
2093
        ret = pagedep_find(pagedephd, ino, lbn, mp, flags, pagedeppp);
1226
2094
        if (*pagedeppp) {
 
2095
                /*
 
2096
                 * This should never happen since we only create pagedeps
 
2097
                 * with the vnode lock held.  Could be an assert.
 
2098
                 */
1227
2099
                WORKITEM_FREE(pagedep, D_PAGEDEP);
1228
2100
                return (ret);
1229
2101
        }
1230
 
        pagedep->pd_ino = ip->i_number;
 
2102
        pagedep->pd_ino = ino;
1231
2103
        pagedep->pd_lbn = lbn;
1232
2104
        LIST_INIT(&pagedep->pd_dirremhd);
1233
2105
        LIST_INIT(&pagedep->pd_pendinghd);
1234
2106
        for (i = 0; i < DAHASHSZ; i++)
1235
2107
                LIST_INIT(&pagedep->pd_diraddhd[i]);
1236
2108
        LIST_INSERT_HEAD(pagedephd, pagedep, pd_hash);
 
2109
        WORKLIST_INSERT(&bp->b_dep, &pagedep->pd_list);
1237
2110
        *pagedeppp = pagedep;
1238
2111
        return (0);
1239
2112
}
1243
2116
 */
1244
2117
LIST_HEAD(inodedep_hashhead, inodedep) *inodedep_hashtbl;
1245
2118
static u_long   inodedep_hash;  /* size of hash table - 1 */
1246
 
static long     num_inodedep;   /* number of inodedep allocated */
1247
2119
#define INODEDEP_HASH(fs, inum) \
1248
2120
      (&inodedep_hashtbl[((((register_t)(fs)) >> 13) + (inum)) & inodedep_hash])
1249
2121
 
1295
2167
        /*
1296
2168
         * If we are over our limit, try to improve the situation.
1297
2169
         */
1298
 
        if (num_inodedep > max_softdeps && (flags & NODELAY) == 0)
 
2170
        if (dep_current[D_INODEDEP] > max_softdeps && (flags & NODELAY) == 0)
1299
2171
                request_cleanup(mp, FLUSH_INODES);
1300
2172
        FREE_LOCK(&lk);
1301
2173
        inodedep = malloc(sizeof(struct inodedep),
1306
2178
                WORKITEM_FREE(inodedep, D_INODEDEP);
1307
2179
                return (1);
1308
2180
        }
1309
 
        num_inodedep += 1;
1310
2181
        inodedep->id_fs = fs;
1311
2182
        inodedep->id_ino = inum;
1312
2183
        inodedep->id_state = ALLCOMPLETE;
1314
2185
        inodedep->id_savedino1 = NULL;
1315
2186
        inodedep->id_savedsize = -1;
1316
2187
        inodedep->id_savedextsize = -1;
1317
 
        inodedep->id_buf = NULL;
 
2188
        inodedep->id_savednlink = -1;
 
2189
        inodedep->id_bmsafemap = NULL;
 
2190
        inodedep->id_mkdiradd = NULL;
 
2191
        LIST_INIT(&inodedep->id_dirremhd);
1318
2192
        LIST_INIT(&inodedep->id_pendinghd);
1319
2193
        LIST_INIT(&inodedep->id_inowait);
1320
2194
        LIST_INIT(&inodedep->id_bufwait);
 
2195
        TAILQ_INIT(&inodedep->id_inoreflst);
1321
2196
        TAILQ_INIT(&inodedep->id_inoupdt);
1322
2197
        TAILQ_INIT(&inodedep->id_newinoupdt);
1323
2198
        TAILQ_INIT(&inodedep->id_extupdt);
1324
2199
        TAILQ_INIT(&inodedep->id_newextupdt);
 
2200
        TAILQ_INIT(&inodedep->id_freeblklst);
1325
2201
        LIST_INSERT_HEAD(inodedephd, inodedep, id_hash);
1326
2202
        *inodedeppp = inodedep;
1327
2203
        return (0);
1336
2212
        (&newblk_hashtbl[((((register_t)(fs)) >> 13) + (inum)) & newblk_hash])
1337
2213
 
1338
2214
static int
1339
 
newblk_find(newblkhd, fs, newblkno, newblkpp)
 
2215
newblk_find(newblkhd, mp, newblkno, flags, newblkpp)
1340
2216
        struct newblk_hashhead *newblkhd;
1341
 
        struct fs *fs;
 
2217
        struct mount *mp;
1342
2218
        ufs2_daddr_t newblkno;
 
2219
        int flags;
1343
2220
        struct newblk **newblkpp;
1344
2221
{
1345
2222
        struct newblk *newblk;
1346
2223
 
1347
 
        LIST_FOREACH(newblk, newblkhd, nb_hash)
1348
 
                if (newblkno == newblk->nb_newblkno && fs == newblk->nb_fs)
1349
 
                        break;
 
2224
        LIST_FOREACH(newblk, newblkhd, nb_hash) {
 
2225
                if (newblkno != newblk->nb_newblkno)
 
2226
                        continue;
 
2227
                if (mp != newblk->nb_list.wk_mp)
 
2228
                        continue;
 
2229
                /*
 
2230
                 * If we're creating a new dependency don't match those that
 
2231
                 * have already been converted to allocdirects.  This is for
 
2232
                 * a frag extend.
 
2233
                 */
 
2234
                if ((flags & DEPALLOC) && newblk->nb_list.wk_type != D_NEWBLK)
 
2235
                        continue;
 
2236
                break;
 
2237
        }
1350
2238
        if (newblk) {
1351
2239
                *newblkpp = newblk;
1352
2240
                return (1);
1361
2249
 * Found or allocated entry is returned in newblkpp.
1362
2250
 */
1363
2251
static int
1364
 
newblk_lookup(fs, newblkno, flags, newblkpp)
1365
 
        struct fs *fs;
 
2252
newblk_lookup(mp, newblkno, flags, newblkpp)
 
2253
        struct mount *mp;
1366
2254
        ufs2_daddr_t newblkno;
1367
2255
        int flags;
1368
2256
        struct newblk **newblkpp;
1370
2258
        struct newblk *newblk;
1371
2259
        struct newblk_hashhead *newblkhd;
1372
2260
 
1373
 
        newblkhd = NEWBLK_HASH(fs, newblkno);
1374
 
        if (newblk_find(newblkhd, fs, newblkno, newblkpp))
 
2261
        newblkhd = NEWBLK_HASH(VFSTOUFS(mp)->um_fs, newblkno);
 
2262
        if (newblk_find(newblkhd, mp, newblkno, flags, newblkpp))
1375
2263
                return (1);
1376
2264
        if ((flags & DEPALLOC) == 0)
1377
2265
                return (0);
1378
2266
        FREE_LOCK(&lk);
1379
 
        newblk = malloc(sizeof(struct newblk),
1380
 
                M_NEWBLK, M_SOFTDEP_FLAGS);
 
2267
        newblk = malloc(sizeof(union allblk), M_NEWBLK,
 
2268
            M_SOFTDEP_FLAGS | M_ZERO);
 
2269
        workitem_alloc(&newblk->nb_list, D_NEWBLK, mp);
1381
2270
        ACQUIRE_LOCK(&lk);
1382
 
        if (newblk_find(newblkhd, fs, newblkno, newblkpp)) {
1383
 
                free(newblk, M_NEWBLK);
 
2271
        if (newblk_find(newblkhd, mp, newblkno, flags, newblkpp)) {
 
2272
                WORKITEM_FREE(newblk, D_NEWBLK);
1384
2273
                return (1);
1385
2274
        }
1386
 
        newblk->nb_state = 0;
1387
 
        newblk->nb_fs = fs;
 
2275
        newblk->nb_freefrag = NULL;
 
2276
        LIST_INIT(&newblk->nb_indirdeps);
 
2277
        LIST_INIT(&newblk->nb_newdirblk);
 
2278
        LIST_INIT(&newblk->nb_jwork);
 
2279
        newblk->nb_state = ATTACHED;
1388
2280
        newblk->nb_newblkno = newblkno;
1389
2281
        LIST_INSERT_HEAD(newblkhd, newblk, nb_hash);
1390
2282
        *newblkpp = newblk;
1392
2284
}
1393
2285
 
1394
2286
/*
 
2287
 * Structures and routines associated with freed indirect block caching.
 
2288
 */
 
2289
struct freeworklst *indir_hashtbl;
 
2290
u_long  indir_hash;             /* size of hash table - 1 */
 
2291
#define INDIR_HASH(mp, blkno) \
 
2292
        (&indir_hashtbl[((((register_t)(mp)) >> 13) + (blkno)) & indir_hash])
 
2293
 
 
2294
/*
 
2295
 * Lookup an indirect block in the indir hash table.  The freework is
 
2296
 * removed and potentially freed.  The caller must do a blocking journal
 
2297
 * write before writing to the blkno.
 
2298
 */
 
2299
static int
 
2300
indirblk_lookup(mp, blkno)
 
2301
        struct mount *mp;
 
2302
        ufs2_daddr_t blkno;
 
2303
{
 
2304
        struct freework *freework;
 
2305
        struct freeworklst *wkhd;
 
2306
 
 
2307
        wkhd = INDIR_HASH(mp, blkno);
 
2308
        TAILQ_FOREACH(freework, wkhd, fw_next) {
 
2309
                if (freework->fw_blkno != blkno)
 
2310
                        continue;
 
2311
                if (freework->fw_list.wk_mp != mp)
 
2312
                        continue;
 
2313
                indirblk_remove(freework);
 
2314
                return (1);
 
2315
        }
 
2316
        return (0);
 
2317
}
 
2318
 
 
2319
/*
 
2320
 * Insert an indirect block represented by freework into the indirblk
 
2321
 * hash table so that it may prevent the block from being re-used prior
 
2322
 * to the journal being written.
 
2323
 */
 
2324
static void
 
2325
indirblk_insert(freework)
 
2326
        struct freework *freework;
 
2327
{
 
2328
        struct jblocks *jblocks;
 
2329
        struct jseg *jseg;
 
2330
 
 
2331
        jblocks = VFSTOUFS(freework->fw_list.wk_mp)->softdep_jblocks;
 
2332
        jseg = TAILQ_LAST(&jblocks->jb_segs, jseglst);
 
2333
        if (jseg == NULL)
 
2334
                return;
 
2335
        
 
2336
        LIST_INSERT_HEAD(&jseg->js_indirs, freework, fw_segs);
 
2337
        TAILQ_INSERT_HEAD(INDIR_HASH(freework->fw_list.wk_mp,
 
2338
            freework->fw_blkno), freework, fw_next);
 
2339
        freework->fw_state &= ~DEPCOMPLETE;
 
2340
}
 
2341
 
 
2342
static void
 
2343
indirblk_remove(freework)
 
2344
        struct freework *freework;
 
2345
{
 
2346
 
 
2347
        LIST_REMOVE(freework, fw_segs);
 
2348
        TAILQ_REMOVE(INDIR_HASH(freework->fw_list.wk_mp,
 
2349
            freework->fw_blkno), freework, fw_next);
 
2350
        freework->fw_state |= DEPCOMPLETE;
 
2351
        if ((freework->fw_state & ALLCOMPLETE) == ALLCOMPLETE)
 
2352
                WORKITEM_FREE(freework, D_FREEWORK);
 
2353
}
 
2354
 
 
2355
/*
1395
2356
 * Executed during filesystem system initialization before
1396
2357
 * mounting any filesystems.
1397
2358
 */
1398
2359
void 
1399
2360
softdep_initialize()
1400
2361
{
 
2362
        int i;
1401
2363
 
1402
2364
        LIST_INIT(&mkdirlisthd);
1403
2365
        max_softdeps = desiredvnodes * 4;
1404
 
        pagedep_hashtbl = hashinit(desiredvnodes / 5, M_PAGEDEP,
1405
 
            &pagedep_hash);
 
2366
        pagedep_hashtbl = hashinit(desiredvnodes / 5, M_PAGEDEP, &pagedep_hash);
1406
2367
        inodedep_hashtbl = hashinit(desiredvnodes, M_INODEDEP, &inodedep_hash);
1407
 
        newblk_hashtbl = hashinit(64, M_NEWBLK, &newblk_hash);
 
2368
        newblk_hashtbl = hashinit(desiredvnodes / 5,  M_NEWBLK, &newblk_hash);
 
2369
        bmsafemap_hashtbl = hashinit(1024, M_BMSAFEMAP, &bmsafemap_hash);
 
2370
        i = 1 << (ffs(desiredvnodes / 10) - 1);
 
2371
        indir_hashtbl = malloc(i * sizeof(indir_hashtbl[0]), M_FREEWORK,
 
2372
            M_WAITOK);
 
2373
        indir_hash = i - 1;
 
2374
        for (i = 0; i <= indir_hash; i++)
 
2375
                TAILQ_INIT(&indir_hashtbl[i]);
1408
2376
 
1409
2377
        /* initialise bioops hack */
1410
2378
        bioops.io_start = softdep_disk_io_initiation;
1428
2396
        hashdestroy(pagedep_hashtbl, M_PAGEDEP, pagedep_hash);
1429
2397
        hashdestroy(inodedep_hashtbl, M_INODEDEP, inodedep_hash);
1430
2398
        hashdestroy(newblk_hashtbl, M_NEWBLK, newblk_hash);
 
2399
        hashdestroy(bmsafemap_hashtbl, M_BMSAFEMAP, bmsafemap_hash);
 
2400
        free(indir_hashtbl, M_FREEWORK);
1431
2401
}
1432
2402
 
1433
2403
/*
1451
2421
        mp->mnt_flag = (mp->mnt_flag & ~MNT_ASYNC) | MNT_SOFTDEP;
1452
2422
        if ((mp->mnt_kern_flag & MNTK_SOFTDEP) == 0) {
1453
2423
                mp->mnt_kern_flag = (mp->mnt_kern_flag & ~MNTK_ASYNC) | 
1454
 
                        MNTK_SOFTDEP;
1455
 
                mp->mnt_noasync++;
 
2424
                        MNTK_SOFTDEP | MNTK_NOASYNC;
1456
2425
        }
1457
2426
        MNT_IUNLOCK(mp);
1458
2427
        ump = VFSTOUFS(mp);
1459
2428
        LIST_INIT(&ump->softdep_workitem_pending);
 
2429
        LIST_INIT(&ump->softdep_journal_pending);
 
2430
        TAILQ_INIT(&ump->softdep_unlinked);
 
2431
        LIST_INIT(&ump->softdep_dirtycg);
1460
2432
        ump->softdep_worklist_tail = NULL;
1461
2433
        ump->softdep_on_worklist = 0;
1462
2434
        ump->softdep_deps = 0;
 
2435
        if ((fs->fs_flags & FS_SUJ) &&
 
2436
            (error = journal_mount(mp, fs, cred)) != 0) {
 
2437
                printf("Failed to start journal: %d\n", error);
 
2438
                return (error);
 
2439
        }
1463
2440
        /*
1464
2441
         * When doing soft updates, the counters in the
1465
2442
         * superblock may have gotten out of sync. Recomputation
1493
2470
        return (0);
1494
2471
}
1495
2472
 
 
2473
void
 
2474
softdep_unmount(mp)
 
2475
        struct mount *mp;
 
2476
{
 
2477
 
 
2478
        MNT_ILOCK(mp);
 
2479
        mp->mnt_flag &= ~MNT_SOFTDEP;
 
2480
        if (MOUNTEDSUJ(mp) == 0) {
 
2481
                MNT_IUNLOCK(mp);
 
2482
                return;
 
2483
        }
 
2484
        mp->mnt_flag &= ~MNT_SUJ;
 
2485
        MNT_IUNLOCK(mp);
 
2486
        journal_unmount(mp);
 
2487
}
 
2488
 
 
2489
static struct jblocks *
 
2490
jblocks_create(void)
 
2491
{
 
2492
        struct jblocks *jblocks;
 
2493
 
 
2494
        jblocks = malloc(sizeof(*jblocks), M_JBLOCKS, M_WAITOK | M_ZERO);
 
2495
        TAILQ_INIT(&jblocks->jb_segs);
 
2496
        jblocks->jb_avail = 10;
 
2497
        jblocks->jb_extent = malloc(sizeof(struct jextent) * jblocks->jb_avail,
 
2498
            M_JBLOCKS, M_WAITOK | M_ZERO);
 
2499
 
 
2500
        return (jblocks);
 
2501
}
 
2502
 
 
2503
static ufs2_daddr_t
 
2504
jblocks_alloc(jblocks, bytes, actual)
 
2505
        struct jblocks *jblocks;
 
2506
        int bytes;
 
2507
        int *actual;
 
2508
{
 
2509
        ufs2_daddr_t daddr;
 
2510
        struct jextent *jext;
 
2511
        int freecnt;
 
2512
        int blocks;
 
2513
 
 
2514
        blocks = bytes / DEV_BSIZE;
 
2515
        jext = &jblocks->jb_extent[jblocks->jb_head];
 
2516
        freecnt = jext->je_blocks - jblocks->jb_off;
 
2517
        if (freecnt == 0) {
 
2518
                jblocks->jb_off = 0;
 
2519
                if (++jblocks->jb_head > jblocks->jb_used)
 
2520
                        jblocks->jb_head = 0;
 
2521
                jext = &jblocks->jb_extent[jblocks->jb_head];
 
2522
                freecnt = jext->je_blocks;
 
2523
        }
 
2524
        if (freecnt > blocks)
 
2525
                freecnt = blocks;
 
2526
        *actual = freecnt * DEV_BSIZE;
 
2527
        daddr = jext->je_daddr + jblocks->jb_off;
 
2528
        jblocks->jb_off += freecnt;
 
2529
        jblocks->jb_free -= freecnt;
 
2530
 
 
2531
        return (daddr);
 
2532
}
 
2533
 
 
2534
static void
 
2535
jblocks_free(jblocks, mp, bytes)
 
2536
        struct jblocks *jblocks;
 
2537
        struct mount *mp;
 
2538
        int bytes;
 
2539
{
 
2540
 
 
2541
        jblocks->jb_free += bytes / DEV_BSIZE;
 
2542
        if (jblocks->jb_suspended)
 
2543
                worklist_speedup();
 
2544
        wakeup(jblocks);
 
2545
}
 
2546
 
 
2547
static void
 
2548
jblocks_destroy(jblocks)
 
2549
        struct jblocks *jblocks;
 
2550
{
 
2551
 
 
2552
        if (jblocks->jb_extent)
 
2553
                free(jblocks->jb_extent, M_JBLOCKS);
 
2554
        free(jblocks, M_JBLOCKS);
 
2555
}
 
2556
 
 
2557
static void
 
2558
jblocks_add(jblocks, daddr, blocks)
 
2559
        struct jblocks *jblocks;
 
2560
        ufs2_daddr_t daddr;
 
2561
        int blocks;
 
2562
{
 
2563
        struct jextent *jext;
 
2564
 
 
2565
        jblocks->jb_blocks += blocks;
 
2566
        jblocks->jb_free += blocks;
 
2567
        jext = &jblocks->jb_extent[jblocks->jb_used];
 
2568
        /* Adding the first block. */
 
2569
        if (jext->je_daddr == 0) {
 
2570
                jext->je_daddr = daddr;
 
2571
                jext->je_blocks = blocks;
 
2572
                return;
 
2573
        }
 
2574
        /* Extending the last extent. */
 
2575
        if (jext->je_daddr + jext->je_blocks == daddr) {
 
2576
                jext->je_blocks += blocks;
 
2577
                return;
 
2578
        }
 
2579
        /* Adding a new extent. */
 
2580
        if (++jblocks->jb_used == jblocks->jb_avail) {
 
2581
                jblocks->jb_avail *= 2;
 
2582
                jext = malloc(sizeof(struct jextent) * jblocks->jb_avail,
 
2583
                    M_JBLOCKS, M_WAITOK | M_ZERO);
 
2584
                memcpy(jext, jblocks->jb_extent,
 
2585
                    sizeof(struct jextent) * jblocks->jb_used);
 
2586
                free(jblocks->jb_extent, M_JBLOCKS);
 
2587
                jblocks->jb_extent = jext;
 
2588
        }
 
2589
        jext = &jblocks->jb_extent[jblocks->jb_used];
 
2590
        jext->je_daddr = daddr;
 
2591
        jext->je_blocks = blocks;
 
2592
        return;
 
2593
}
 
2594
 
 
2595
int
 
2596
softdep_journal_lookup(mp, vpp)
 
2597
        struct mount *mp;
 
2598
        struct vnode **vpp;
 
2599
{
 
2600
        struct componentname cnp;
 
2601
        struct vnode *dvp;
 
2602
        ino_t sujournal;
 
2603
        int error;
 
2604
 
 
2605
        error = VFS_VGET(mp, ROOTINO, LK_EXCLUSIVE, &dvp);
 
2606
        if (error)
 
2607
                return (error);
 
2608
        bzero(&cnp, sizeof(cnp));
 
2609
        cnp.cn_nameiop = LOOKUP;
 
2610
        cnp.cn_flags = ISLASTCN;
 
2611
        cnp.cn_thread = curthread;
 
2612
        cnp.cn_cred = curthread->td_ucred;
 
2613
        cnp.cn_pnbuf = SUJ_FILE;
 
2614
        cnp.cn_nameptr = SUJ_FILE;
 
2615
        cnp.cn_namelen = strlen(SUJ_FILE);
 
2616
        error = ufs_lookup_ino(dvp, NULL, &cnp, &sujournal);
 
2617
        vput(dvp);
 
2618
        if (error != 0)
 
2619
                return (error);
 
2620
        error = VFS_VGET(mp, sujournal, LK_EXCLUSIVE, vpp);
 
2621
        return (error);
 
2622
}
 
2623
 
 
2624
/*
 
2625
 * Open and verify the journal file.
 
2626
 */
 
2627
static int
 
2628
journal_mount(mp, fs, cred)
 
2629
        struct mount *mp;
 
2630
        struct fs *fs;
 
2631
        struct ucred *cred;
 
2632
{
 
2633
        struct jblocks *jblocks;
 
2634
        struct vnode *vp;
 
2635
        struct inode *ip;
 
2636
        ufs2_daddr_t blkno;
 
2637
        int bcount;
 
2638
        int error;
 
2639
        int i;
 
2640
 
 
2641
        error = softdep_journal_lookup(mp, &vp);
 
2642
        if (error != 0) {
 
2643
                printf("Failed to find journal.  Use tunefs to create one\n");
 
2644
                return (error);
 
2645
        }
 
2646
        ip = VTOI(vp);
 
2647
        if (ip->i_size < SUJ_MIN) {
 
2648
                error = ENOSPC;
 
2649
                goto out;
 
2650
        }
 
2651
        bcount = lblkno(fs, ip->i_size);        /* Only use whole blocks. */
 
2652
        jblocks = jblocks_create();
 
2653
        for (i = 0; i < bcount; i++) {
 
2654
                error = ufs_bmaparray(vp, i, &blkno, NULL, NULL, NULL);
 
2655
                if (error)
 
2656
                        break;
 
2657
                jblocks_add(jblocks, blkno, fsbtodb(fs, fs->fs_frag));
 
2658
        }
 
2659
        if (error) {
 
2660
                jblocks_destroy(jblocks);
 
2661
                goto out;
 
2662
        }
 
2663
        jblocks->jb_low = jblocks->jb_free / 3; /* Reserve 33%. */
 
2664
        jblocks->jb_min = jblocks->jb_free / 10; /* Suspend at 10%. */
 
2665
        VFSTOUFS(mp)->softdep_jblocks = jblocks;
 
2666
out:
 
2667
        if (error == 0) {
 
2668
                MNT_ILOCK(mp);
 
2669
                mp->mnt_flag |= MNT_SUJ;
 
2670
                mp->mnt_flag &= ~MNT_SOFTDEP;
 
2671
                MNT_IUNLOCK(mp);
 
2672
                /*
 
2673
                 * Only validate the journal contents if the
 
2674
                 * filesystem is clean, otherwise we write the logs
 
2675
                 * but they'll never be used.  If the filesystem was
 
2676
                 * still dirty when we mounted it the journal is
 
2677
                 * invalid and a new journal can only be valid if it
 
2678
                 * starts from a clean mount.
 
2679
                 */
 
2680
                if (fs->fs_clean) {
 
2681
                        DIP_SET(ip, i_modrev, fs->fs_mtime);
 
2682
                        ip->i_flags |= IN_MODIFIED;
 
2683
                        ffs_update(vp, 1);
 
2684
                }
 
2685
        }
 
2686
        vput(vp);
 
2687
        return (error);
 
2688
}
 
2689
 
 
2690
static void
 
2691
journal_unmount(mp)
 
2692
        struct mount *mp;
 
2693
{
 
2694
        struct ufsmount *ump;
 
2695
 
 
2696
        ump = VFSTOUFS(mp);
 
2697
        if (ump->softdep_jblocks)
 
2698
                jblocks_destroy(ump->softdep_jblocks);
 
2699
        ump->softdep_jblocks = NULL;
 
2700
}
 
2701
 
 
2702
/*
 
2703
 * Called when a journal record is ready to be written.  Space is allocated
 
2704
 * and the journal entry is created when the journal is flushed to stable
 
2705
 * store.
 
2706
 */
 
2707
static void
 
2708
add_to_journal(wk)
 
2709
        struct worklist *wk;
 
2710
{
 
2711
        struct ufsmount *ump;
 
2712
 
 
2713
        mtx_assert(&lk, MA_OWNED);
 
2714
        ump = VFSTOUFS(wk->wk_mp);
 
2715
        if (wk->wk_state & ONWORKLIST)
 
2716
                panic("add_to_journal: %s(0x%X) already on list",
 
2717
                    TYPENAME(wk->wk_type), wk->wk_state);
 
2718
        wk->wk_state |= ONWORKLIST | DEPCOMPLETE;
 
2719
        if (LIST_EMPTY(&ump->softdep_journal_pending)) {
 
2720
                ump->softdep_jblocks->jb_age = ticks;
 
2721
                LIST_INSERT_HEAD(&ump->softdep_journal_pending, wk, wk_list);
 
2722
        } else
 
2723
                LIST_INSERT_AFTER(ump->softdep_journal_tail, wk, wk_list);
 
2724
        ump->softdep_journal_tail = wk;
 
2725
        ump->softdep_on_journal += 1;
 
2726
}
 
2727
 
 
2728
/*
 
2729
 * Remove an arbitrary item for the journal worklist maintain the tail
 
2730
 * pointer.  This happens when a new operation obviates the need to
 
2731
 * journal an old operation.
 
2732
 */
 
2733
static void
 
2734
remove_from_journal(wk)
 
2735
        struct worklist *wk;
 
2736
{
 
2737
        struct ufsmount *ump;
 
2738
 
 
2739
        mtx_assert(&lk, MA_OWNED);
 
2740
        ump = VFSTOUFS(wk->wk_mp);
 
2741
#ifdef SUJ_DEBUG
 
2742
        {
 
2743
                struct worklist *wkn;
 
2744
 
 
2745
                LIST_FOREACH(wkn, &ump->softdep_journal_pending, wk_list)
 
2746
                        if (wkn == wk)
 
2747
                                break;
 
2748
                if (wkn == NULL)
 
2749
                        panic("remove_from_journal: %p is not in journal", wk);
 
2750
        }
 
2751
#endif
 
2752
        /*
 
2753
         * We emulate a TAILQ to save space in most structures which do not
 
2754
         * require TAILQ semantics.  Here we must update the tail position
 
2755
         * when removing the tail which is not the final entry. This works
 
2756
         * only if the worklist linkage are at the beginning of the structure.
 
2757
         */
 
2758
        if (ump->softdep_journal_tail == wk)
 
2759
                ump->softdep_journal_tail =
 
2760
                    (struct worklist *)wk->wk_list.le_prev;
 
2761
 
 
2762
        WORKLIST_REMOVE(wk);
 
2763
        ump->softdep_on_journal -= 1;
 
2764
}
 
2765
 
 
2766
/*
 
2767
 * Check for journal space as well as dependency limits so the prelink
 
2768
 * code can throttle both journaled and non-journaled filesystems.
 
2769
 * Threshold is 0 for low and 1 for min.
 
2770
 */
 
2771
static int
 
2772
journal_space(ump, thresh)
 
2773
        struct ufsmount *ump;
 
2774
        int thresh;
 
2775
{
 
2776
        struct jblocks *jblocks;
 
2777
        int avail;
 
2778
 
 
2779
        jblocks = ump->softdep_jblocks;
 
2780
        if (jblocks == NULL)
 
2781
                return (1);
 
2782
        /*
 
2783
         * We use a tighter restriction here to prevent request_cleanup()
 
2784
         * running in threads from running into locks we currently hold.
 
2785
         */
 
2786
        if (dep_current[D_INODEDEP] > (max_softdeps / 10) * 9)
 
2787
                return (0);
 
2788
        if (thresh)
 
2789
                thresh = jblocks->jb_min;
 
2790
        else
 
2791
                thresh = jblocks->jb_low;
 
2792
        avail = (ump->softdep_on_journal * JREC_SIZE) / DEV_BSIZE;
 
2793
        avail = jblocks->jb_free - avail;
 
2794
 
 
2795
        return (avail > thresh);
 
2796
}
 
2797
 
 
2798
static void
 
2799
journal_suspend(ump)
 
2800
        struct ufsmount *ump;
 
2801
{
 
2802
        struct jblocks *jblocks;
 
2803
        struct mount *mp;
 
2804
 
 
2805
        mp = UFSTOVFS(ump);
 
2806
        jblocks = ump->softdep_jblocks;
 
2807
        MNT_ILOCK(mp);
 
2808
        if ((mp->mnt_kern_flag & MNTK_SUSPEND) == 0) {
 
2809
                stat_journal_min++;
 
2810
                mp->mnt_kern_flag |= MNTK_SUSPEND;
 
2811
                mp->mnt_susp_owner = FIRST_THREAD_IN_PROC(softdepproc);
 
2812
        }
 
2813
        jblocks->jb_suspended = 1;
 
2814
        MNT_IUNLOCK(mp);
 
2815
}
 
2816
 
 
2817
static int
 
2818
journal_unsuspend(struct ufsmount *ump)
 
2819
{
 
2820
        struct jblocks *jblocks;
 
2821
        struct mount *mp;
 
2822
 
 
2823
        mp = UFSTOVFS(ump);
 
2824
        jblocks = ump->softdep_jblocks;
 
2825
 
 
2826
        if (jblocks != NULL && jblocks->jb_suspended &&
 
2827
            journal_space(ump, jblocks->jb_min)) {
 
2828
                jblocks->jb_suspended = 0;
 
2829
                FREE_LOCK(&lk);
 
2830
                mp->mnt_susp_owner = curthread;
 
2831
                vfs_write_resume(mp);
 
2832
                ACQUIRE_LOCK(&lk);
 
2833
                return (1);
 
2834
        }
 
2835
        return (0);
 
2836
}
 
2837
 
 
2838
/*
 
2839
 * Called before any allocation function to be certain that there is
 
2840
 * sufficient space in the journal prior to creating any new records.
 
2841
 * Since in the case of block allocation we may have multiple locked
 
2842
 * buffers at the time of the actual allocation we can not block
 
2843
 * when the journal records are created.  Doing so would create a deadlock
 
2844
 * if any of these buffers needed to be flushed to reclaim space.  Instead
 
2845
 * we require a sufficiently large amount of available space such that
 
2846
 * each thread in the system could have passed this allocation check and
 
2847
 * still have sufficient free space.  With 20% of a minimum journal size
 
2848
 * of 1MB we have 6553 records available.
 
2849
 */
 
2850
int
 
2851
softdep_prealloc(vp, waitok)
 
2852
        struct vnode *vp;
 
2853
        int waitok;
 
2854
{
 
2855
        struct ufsmount *ump;
 
2856
 
 
2857
        /*
 
2858
         * Nothing to do if we are not running journaled soft updates.
 
2859
         * If we currently hold the snapshot lock, we must avoid handling
 
2860
         * other resources that could cause deadlock.
 
2861
         */
 
2862
        if (DOINGSUJ(vp) == 0 || IS_SNAPSHOT(VTOI(vp)))
 
2863
                return (0);
 
2864
        ump = VFSTOUFS(vp->v_mount);
 
2865
        ACQUIRE_LOCK(&lk);
 
2866
        if (journal_space(ump, 0)) {
 
2867
                FREE_LOCK(&lk);
 
2868
                return (0);
 
2869
        }
 
2870
        stat_journal_low++;
 
2871
        FREE_LOCK(&lk);
 
2872
        if (waitok == MNT_NOWAIT)
 
2873
                return (ENOSPC);
 
2874
        /*
 
2875
         * Attempt to sync this vnode once to flush any journal
 
2876
         * work attached to it.
 
2877
         */
 
2878
        if ((curthread->td_pflags & TDP_COWINPROGRESS) == 0)
 
2879
                ffs_syncvnode(vp, waitok, 0);
 
2880
        ACQUIRE_LOCK(&lk);
 
2881
        process_removes(vp);
 
2882
        process_truncates(vp);
 
2883
        if (journal_space(ump, 0) == 0) {
 
2884
                softdep_speedup();
 
2885
                if (journal_space(ump, 1) == 0)
 
2886
                        journal_suspend(ump);
 
2887
        }
 
2888
        FREE_LOCK(&lk);
 
2889
 
 
2890
        return (0);
 
2891
}
 
2892
 
 
2893
/*
 
2894
 * Before adjusting a link count on a vnode verify that we have sufficient
 
2895
 * journal space.  If not, process operations that depend on the currently
 
2896
 * locked pair of vnodes to try to flush space as the syncer, buf daemon,
 
2897
 * and softdep flush threads can not acquire these locks to reclaim space.
 
2898
 */
 
2899
static void
 
2900
softdep_prelink(dvp, vp)
 
2901
        struct vnode *dvp;
 
2902
        struct vnode *vp;
 
2903
{
 
2904
        struct ufsmount *ump;
 
2905
 
 
2906
        ump = VFSTOUFS(dvp->v_mount);
 
2907
        mtx_assert(&lk, MA_OWNED);
 
2908
        /*
 
2909
         * Nothing to do if we have sufficient journal space.
 
2910
         * If we currently hold the snapshot lock, we must avoid
 
2911
         * handling other resources that could cause deadlock.
 
2912
         */
 
2913
        if (journal_space(ump, 0) || (vp && IS_SNAPSHOT(VTOI(vp))))
 
2914
                return;
 
2915
        stat_journal_low++;
 
2916
        FREE_LOCK(&lk);
 
2917
        if (vp)
 
2918
                ffs_syncvnode(vp, MNT_NOWAIT, 0);
 
2919
        ffs_syncvnode(dvp, MNT_WAIT, 0);
 
2920
        ACQUIRE_LOCK(&lk);
 
2921
        /* Process vp before dvp as it may create .. removes. */
 
2922
        if (vp) {
 
2923
                process_removes(vp);
 
2924
                process_truncates(vp);
 
2925
        }
 
2926
        process_removes(dvp);
 
2927
        process_truncates(dvp);
 
2928
        softdep_speedup();
 
2929
        process_worklist_item(UFSTOVFS(ump), 2, LK_NOWAIT);
 
2930
        if (journal_space(ump, 0) == 0) {
 
2931
                softdep_speedup();
 
2932
                if (journal_space(ump, 1) == 0)
 
2933
                        journal_suspend(ump);
 
2934
        }
 
2935
}
 
2936
 
 
2937
static void
 
2938
jseg_write(ump, jseg, data)
 
2939
        struct ufsmount *ump;
 
2940
        struct jseg *jseg;
 
2941
        uint8_t *data;
 
2942
{
 
2943
        struct jsegrec *rec;
 
2944
 
 
2945
        rec = (struct jsegrec *)data;
 
2946
        rec->jsr_seq = jseg->js_seq;
 
2947
        rec->jsr_oldest = jseg->js_oldseq;
 
2948
        rec->jsr_cnt = jseg->js_cnt;
 
2949
        rec->jsr_blocks = jseg->js_size / ump->um_devvp->v_bufobj.bo_bsize;
 
2950
        rec->jsr_crc = 0;
 
2951
        rec->jsr_time = ump->um_fs->fs_mtime;
 
2952
}
 
2953
 
 
2954
static inline void
 
2955
inoref_write(inoref, jseg, rec)
 
2956
        struct inoref *inoref;
 
2957
        struct jseg *jseg;
 
2958
        struct jrefrec *rec;
 
2959
{
 
2960
 
 
2961
        inoref->if_jsegdep->jd_seg = jseg;
 
2962
        rec->jr_ino = inoref->if_ino;
 
2963
        rec->jr_parent = inoref->if_parent;
 
2964
        rec->jr_nlink = inoref->if_nlink;
 
2965
        rec->jr_mode = inoref->if_mode;
 
2966
        rec->jr_diroff = inoref->if_diroff;
 
2967
}
 
2968
 
 
2969
static void
 
2970
jaddref_write(jaddref, jseg, data)
 
2971
        struct jaddref *jaddref;
 
2972
        struct jseg *jseg;
 
2973
        uint8_t *data;
 
2974
{
 
2975
        struct jrefrec *rec;
 
2976
 
 
2977
        rec = (struct jrefrec *)data;
 
2978
        rec->jr_op = JOP_ADDREF;
 
2979
        inoref_write(&jaddref->ja_ref, jseg, rec);
 
2980
}
 
2981
 
 
2982
static void
 
2983
jremref_write(jremref, jseg, data)
 
2984
        struct jremref *jremref;
 
2985
        struct jseg *jseg;
 
2986
        uint8_t *data;
 
2987
{
 
2988
        struct jrefrec *rec;
 
2989
 
 
2990
        rec = (struct jrefrec *)data;
 
2991
        rec->jr_op = JOP_REMREF;
 
2992
        inoref_write(&jremref->jr_ref, jseg, rec);
 
2993
}
 
2994
 
 
2995
static void
 
2996
jmvref_write(jmvref, jseg, data)
 
2997
        struct jmvref *jmvref;
 
2998
        struct jseg *jseg;
 
2999
        uint8_t *data;
 
3000
{
 
3001
        struct jmvrec *rec;
 
3002
 
 
3003
        rec = (struct jmvrec *)data;
 
3004
        rec->jm_op = JOP_MVREF;
 
3005
        rec->jm_ino = jmvref->jm_ino;
 
3006
        rec->jm_parent = jmvref->jm_parent;
 
3007
        rec->jm_oldoff = jmvref->jm_oldoff;
 
3008
        rec->jm_newoff = jmvref->jm_newoff;
 
3009
}
 
3010
 
 
3011
static void
 
3012
jnewblk_write(jnewblk, jseg, data)
 
3013
        struct jnewblk *jnewblk;
 
3014
        struct jseg *jseg;
 
3015
        uint8_t *data;
 
3016
{
 
3017
        struct jblkrec *rec;
 
3018
 
 
3019
        jnewblk->jn_jsegdep->jd_seg = jseg;
 
3020
        rec = (struct jblkrec *)data;
 
3021
        rec->jb_op = JOP_NEWBLK;
 
3022
        rec->jb_ino = jnewblk->jn_ino;
 
3023
        rec->jb_blkno = jnewblk->jn_blkno;
 
3024
        rec->jb_lbn = jnewblk->jn_lbn;
 
3025
        rec->jb_frags = jnewblk->jn_frags;
 
3026
        rec->jb_oldfrags = jnewblk->jn_oldfrags;
 
3027
}
 
3028
 
 
3029
static void
 
3030
jfreeblk_write(jfreeblk, jseg, data)
 
3031
        struct jfreeblk *jfreeblk;
 
3032
        struct jseg *jseg;
 
3033
        uint8_t *data;
 
3034
{
 
3035
        struct jblkrec *rec;
 
3036
 
 
3037
        jfreeblk->jf_dep.jb_jsegdep->jd_seg = jseg;
 
3038
        rec = (struct jblkrec *)data;
 
3039
        rec->jb_op = JOP_FREEBLK;
 
3040
        rec->jb_ino = jfreeblk->jf_ino;
 
3041
        rec->jb_blkno = jfreeblk->jf_blkno;
 
3042
        rec->jb_lbn = jfreeblk->jf_lbn;
 
3043
        rec->jb_frags = jfreeblk->jf_frags;
 
3044
        rec->jb_oldfrags = 0;
 
3045
}
 
3046
 
 
3047
static void
 
3048
jfreefrag_write(jfreefrag, jseg, data)
 
3049
        struct jfreefrag *jfreefrag;
 
3050
        struct jseg *jseg;
 
3051
        uint8_t *data;
 
3052
{
 
3053
        struct jblkrec *rec;
 
3054
 
 
3055
        jfreefrag->fr_jsegdep->jd_seg = jseg;
 
3056
        rec = (struct jblkrec *)data;
 
3057
        rec->jb_op = JOP_FREEBLK;
 
3058
        rec->jb_ino = jfreefrag->fr_ino;
 
3059
        rec->jb_blkno = jfreefrag->fr_blkno;
 
3060
        rec->jb_lbn = jfreefrag->fr_lbn;
 
3061
        rec->jb_frags = jfreefrag->fr_frags;
 
3062
        rec->jb_oldfrags = 0;
 
3063
}
 
3064
 
 
3065
static void
 
3066
jtrunc_write(jtrunc, jseg, data)
 
3067
        struct jtrunc *jtrunc;
 
3068
        struct jseg *jseg;
 
3069
        uint8_t *data;
 
3070
{
 
3071
        struct jtrncrec *rec;
 
3072
 
 
3073
        jtrunc->jt_dep.jb_jsegdep->jd_seg = jseg;
 
3074
        rec = (struct jtrncrec *)data;
 
3075
        rec->jt_op = JOP_TRUNC;
 
3076
        rec->jt_ino = jtrunc->jt_ino;
 
3077
        rec->jt_size = jtrunc->jt_size;
 
3078
        rec->jt_extsize = jtrunc->jt_extsize;
 
3079
}
 
3080
 
 
3081
static void
 
3082
jfsync_write(jfsync, jseg, data)
 
3083
        struct jfsync *jfsync;
 
3084
        struct jseg *jseg;
 
3085
        uint8_t *data;
 
3086
{
 
3087
        struct jtrncrec *rec;
 
3088
 
 
3089
        rec = (struct jtrncrec *)data;
 
3090
        rec->jt_op = JOP_SYNC;
 
3091
        rec->jt_ino = jfsync->jfs_ino;
 
3092
        rec->jt_size = jfsync->jfs_size;
 
3093
        rec->jt_extsize = jfsync->jfs_extsize;
 
3094
}
 
3095
 
 
3096
static void
 
3097
softdep_flushjournal(mp)
 
3098
        struct mount *mp;
 
3099
{
 
3100
        struct jblocks *jblocks;
 
3101
        struct ufsmount *ump;
 
3102
 
 
3103
        if (MOUNTEDSUJ(mp) == 0)
 
3104
                return;
 
3105
        ump = VFSTOUFS(mp);
 
3106
        jblocks = ump->softdep_jblocks;
 
3107
        ACQUIRE_LOCK(&lk);
 
3108
        while (ump->softdep_on_journal) {
 
3109
                jblocks->jb_needseg = 1;
 
3110
                softdep_process_journal(mp, NULL, MNT_WAIT);
 
3111
        }
 
3112
        FREE_LOCK(&lk);
 
3113
}
 
3114
 
 
3115
static void softdep_synchronize_completed(struct bio *);
 
3116
static void softdep_synchronize(struct bio *, struct ufsmount *, void *);
 
3117
 
 
3118
static void
 
3119
softdep_synchronize_completed(bp)
 
3120
        struct bio *bp;
 
3121
{
 
3122
        struct jseg *oldest;
 
3123
        struct jseg *jseg;
 
3124
 
 
3125
        /*
 
3126
         * caller1 marks the last segment written before we issued the
 
3127
         * synchronize cache.
 
3128
         */
 
3129
        jseg = bp->bio_caller1;
 
3130
        oldest = NULL;
 
3131
        ACQUIRE_LOCK(&lk);
 
3132
        /*
 
3133
         * Mark all the journal entries waiting on the synchronize cache
 
3134
         * as completed so they may continue on.
 
3135
         */
 
3136
        while (jseg != NULL && (jseg->js_state & COMPLETE) == 0) {
 
3137
                jseg->js_state |= COMPLETE;
 
3138
                oldest = jseg;
 
3139
                jseg = TAILQ_PREV(jseg, jseglst, js_next);
 
3140
        }
 
3141
        /*
 
3142
         * Restart deferred journal entry processing from the oldest
 
3143
         * completed jseg.
 
3144
         */
 
3145
        if (oldest)
 
3146
                complete_jsegs(oldest);
 
3147
 
 
3148
        FREE_LOCK(&lk);
 
3149
        g_destroy_bio(bp);
 
3150
}
 
3151
 
 
3152
/*
 
3153
 * Send BIO_FLUSH/SYNCHRONIZE CACHE to the device to enforce write ordering
 
3154
 * barriers.  The journal must be written prior to any blocks that depend
 
3155
 * on it and the journal can not be released until the blocks have be
 
3156
 * written.  This code handles both barriers simultaneously.
 
3157
 */
 
3158
static void
 
3159
softdep_synchronize(bp, ump, caller1)
 
3160
        struct bio *bp;
 
3161
        struct ufsmount *ump;
 
3162
        void *caller1;
 
3163
{
 
3164
 
 
3165
        bp->bio_cmd = BIO_FLUSH;
 
3166
        bp->bio_flags |= BIO_ORDERED;
 
3167
        bp->bio_data = NULL;
 
3168
        bp->bio_offset = ump->um_cp->provider->mediasize;
 
3169
        bp->bio_length = 0;
 
3170
        bp->bio_done = softdep_synchronize_completed;
 
3171
        bp->bio_caller1 = caller1;
 
3172
        g_io_request(bp,
 
3173
            (struct g_consumer *)ump->um_devvp->v_bufobj.bo_private);
 
3174
}
 
3175
 
 
3176
/*
 
3177
 * Flush some journal records to disk.
 
3178
 */
 
3179
static void
 
3180
softdep_process_journal(mp, needwk, flags)
 
3181
        struct mount *mp;
 
3182
        struct worklist *needwk;
 
3183
        int flags;
 
3184
{
 
3185
        struct jblocks *jblocks;
 
3186
        struct ufsmount *ump;
 
3187
        struct worklist *wk;
 
3188
        struct jseg *jseg;
 
3189
        struct buf *bp;
 
3190
        struct bio *bio;
 
3191
        uint8_t *data;
 
3192
        struct fs *fs;
 
3193
        int shouldflush;
 
3194
        int segwritten;
 
3195
        int jrecmin;    /* Minimum records per block. */
 
3196
        int jrecmax;    /* Maximum records per block. */
 
3197
        int size;
 
3198
        int cnt;
 
3199
        int off;
 
3200
        int devbsize;
 
3201
 
 
3202
        if (MOUNTEDSUJ(mp) == 0)
 
3203
                return;
 
3204
        shouldflush = softdep_flushcache;
 
3205
        bio = NULL;
 
3206
        jseg = NULL;
 
3207
        ump = VFSTOUFS(mp);
 
3208
        fs = ump->um_fs;
 
3209
        jblocks = ump->softdep_jblocks;
 
3210
        devbsize = ump->um_devvp->v_bufobj.bo_bsize;
 
3211
        /*
 
3212
         * We write anywhere between a disk block and fs block.  The upper
 
3213
         * bound is picked to prevent buffer cache fragmentation and limit
 
3214
         * processing time per I/O.
 
3215
         */
 
3216
        jrecmin = (devbsize / JREC_SIZE) - 1; /* -1 for seg header */
 
3217
        jrecmax = (fs->fs_bsize / devbsize) * jrecmin;
 
3218
        segwritten = 0;
 
3219
        for (;;) {
 
3220
                cnt = ump->softdep_on_journal;
 
3221
                /*
 
3222
                 * Criteria for writing a segment:
 
3223
                 * 1) We have a full block.
 
3224
                 * 2) We're called from jwait() and haven't found the
 
3225
                 *    journal item yet.
 
3226
                 * 3) Always write if needseg is set.
 
3227
                 * 4) If we are called from process_worklist and have
 
3228
                 *    not yet written anything we write a partial block
 
3229
                 *    to enforce a 1 second maximum latency on journal
 
3230
                 *    entries.
 
3231
                 */
 
3232
                if (cnt < (jrecmax - 1) && needwk == NULL &&
 
3233
                    jblocks->jb_needseg == 0 && (segwritten || cnt == 0))
 
3234
                        break;
 
3235
                cnt++;
 
3236
                /*
 
3237
                 * Verify some free journal space.  softdep_prealloc() should
 
3238
                 * guarantee that we don't run out so this is indicative of
 
3239
                 * a problem with the flow control.  Try to recover
 
3240
                 * gracefully in any event.
 
3241
                 */
 
3242
                while (jblocks->jb_free == 0) {
 
3243
                        if (flags != MNT_WAIT)
 
3244
                                break;
 
3245
                        printf("softdep: Out of journal space!\n");
 
3246
                        softdep_speedup();
 
3247
                        msleep(jblocks, &lk, PRIBIO, "jblocks", hz);
 
3248
                }
 
3249
                FREE_LOCK(&lk);
 
3250
                jseg = malloc(sizeof(*jseg), M_JSEG, M_SOFTDEP_FLAGS);
 
3251
                workitem_alloc(&jseg->js_list, D_JSEG, mp);
 
3252
                LIST_INIT(&jseg->js_entries);
 
3253
                LIST_INIT(&jseg->js_indirs);
 
3254
                jseg->js_state = ATTACHED;
 
3255
                if (shouldflush == 0)
 
3256
                        jseg->js_state |= COMPLETE;
 
3257
                else if (bio == NULL)
 
3258
                        bio = g_alloc_bio();
 
3259
                jseg->js_jblocks = jblocks;
 
3260
                bp = geteblk(fs->fs_bsize, 0);
 
3261
                ACQUIRE_LOCK(&lk);
 
3262
                /*
 
3263
                 * If there was a race while we were allocating the block
 
3264
                 * and jseg the entry we care about was likely written.
 
3265
                 * We bail out in both the WAIT and NOWAIT case and assume
 
3266
                 * the caller will loop if the entry it cares about is
 
3267
                 * not written.
 
3268
                 */
 
3269
                cnt = ump->softdep_on_journal;
 
3270
                if (cnt + jblocks->jb_needseg == 0 || jblocks->jb_free == 0) {
 
3271
                        bp->b_flags |= B_INVAL | B_NOCACHE;
 
3272
                        WORKITEM_FREE(jseg, D_JSEG);
 
3273
                        FREE_LOCK(&lk);
 
3274
                        brelse(bp);
 
3275
                        ACQUIRE_LOCK(&lk);
 
3276
                        break;
 
3277
                }
 
3278
                /*
 
3279
                 * Calculate the disk block size required for the available
 
3280
                 * records rounded to the min size.
 
3281
                 */
 
3282
                if (cnt == 0)
 
3283
                        size = devbsize;
 
3284
                else if (cnt < jrecmax)
 
3285
                        size = howmany(cnt, jrecmin) * devbsize;
 
3286
                else
 
3287
                        size = fs->fs_bsize;
 
3288
                /*
 
3289
                 * Allocate a disk block for this journal data and account
 
3290
                 * for truncation of the requested size if enough contiguous
 
3291
                 * space was not available.
 
3292
                 */
 
3293
                bp->b_blkno = jblocks_alloc(jblocks, size, &size);
 
3294
                bp->b_lblkno = bp->b_blkno;
 
3295
                bp->b_offset = bp->b_blkno * DEV_BSIZE;
 
3296
                bp->b_bcount = size;
 
3297
                bp->b_bufobj = &ump->um_devvp->v_bufobj;
 
3298
                bp->b_flags &= ~B_INVAL;
 
3299
                bp->b_flags |= B_VALIDSUSPWRT | B_NOCOPY;
 
3300
                /*
 
3301
                 * Initialize our jseg with cnt records.  Assign the next
 
3302
                 * sequence number to it and link it in-order.
 
3303
                 */
 
3304
                cnt = MIN(cnt, (size / devbsize) * jrecmin);
 
3305
                jseg->js_buf = bp;
 
3306
                jseg->js_cnt = cnt;
 
3307
                jseg->js_refs = cnt + 1;        /* Self ref. */
 
3308
                jseg->js_size = size;
 
3309
                jseg->js_seq = jblocks->jb_nextseq++;
 
3310
                if (jblocks->jb_oldestseg == NULL)
 
3311
                        jblocks->jb_oldestseg = jseg;
 
3312
                jseg->js_oldseq = jblocks->jb_oldestseg->js_seq;
 
3313
                TAILQ_INSERT_TAIL(&jblocks->jb_segs, jseg, js_next);
 
3314
                if (jblocks->jb_writeseg == NULL)
 
3315
                        jblocks->jb_writeseg = jseg;
 
3316
                /*
 
3317
                 * Start filling in records from the pending list.
 
3318
                 */
 
3319
                data = bp->b_data;
 
3320
                off = 0;
 
3321
                while ((wk = LIST_FIRST(&ump->softdep_journal_pending))
 
3322
                    != NULL) {
 
3323
                        if (cnt == 0)
 
3324
                                break;
 
3325
                        /* Place a segment header on every device block. */
 
3326
                        if ((off % devbsize) == 0) {
 
3327
                                jseg_write(ump, jseg, data);
 
3328
                                off += JREC_SIZE;
 
3329
                                data = bp->b_data + off;
 
3330
                        }
 
3331
                        if (wk == needwk)
 
3332
                                needwk = NULL;
 
3333
                        remove_from_journal(wk);
 
3334
                        wk->wk_state |= INPROGRESS;
 
3335
                        WORKLIST_INSERT(&jseg->js_entries, wk);
 
3336
                        switch (wk->wk_type) {
 
3337
                        case D_JADDREF:
 
3338
                                jaddref_write(WK_JADDREF(wk), jseg, data);
 
3339
                                break;
 
3340
                        case D_JREMREF:
 
3341
                                jremref_write(WK_JREMREF(wk), jseg, data);
 
3342
                                break;
 
3343
                        case D_JMVREF:
 
3344
                                jmvref_write(WK_JMVREF(wk), jseg, data);
 
3345
                                break;
 
3346
                        case D_JNEWBLK:
 
3347
                                jnewblk_write(WK_JNEWBLK(wk), jseg, data);
 
3348
                                break;
 
3349
                        case D_JFREEBLK:
 
3350
                                jfreeblk_write(WK_JFREEBLK(wk), jseg, data);
 
3351
                                break;
 
3352
                        case D_JFREEFRAG:
 
3353
                                jfreefrag_write(WK_JFREEFRAG(wk), jseg, data);
 
3354
                                break;
 
3355
                        case D_JTRUNC:
 
3356
                                jtrunc_write(WK_JTRUNC(wk), jseg, data);
 
3357
                                break;
 
3358
                        case D_JFSYNC:
 
3359
                                jfsync_write(WK_JFSYNC(wk), jseg, data);
 
3360
                                break;
 
3361
                        default:
 
3362
                                panic("process_journal: Unknown type %s",
 
3363
                                    TYPENAME(wk->wk_type));
 
3364
                                /* NOTREACHED */
 
3365
                        }
 
3366
                        off += JREC_SIZE;
 
3367
                        data = bp->b_data + off;
 
3368
                        cnt--;
 
3369
                }
 
3370
                /*
 
3371
                 * Write this one buffer and continue.
 
3372
                 */
 
3373
                segwritten = 1;
 
3374
                jblocks->jb_needseg = 0;
 
3375
                WORKLIST_INSERT(&bp->b_dep, &jseg->js_list);
 
3376
                FREE_LOCK(&lk);
 
3377
                BO_LOCK(bp->b_bufobj);
 
3378
                bgetvp(ump->um_devvp, bp);
 
3379
                BO_UNLOCK(bp->b_bufobj);
 
3380
                /*
 
3381
                 * We only do the blocking wait once we find the journal
 
3382
                 * entry we're looking for.
 
3383
                 */
 
3384
                if (needwk == NULL && flags == MNT_WAIT)
 
3385
                        bwrite(bp);
 
3386
                else
 
3387
                        bawrite(bp);
 
3388
                ACQUIRE_LOCK(&lk);
 
3389
        }
 
3390
        /*
 
3391
         * If we wrote a segment issue a synchronize cache so the journal
 
3392
         * is reflected on disk before the data is written.  Since reclaiming
 
3393
         * journal space also requires writing a journal record this
 
3394
         * process also enforces a barrier before reclamation.
 
3395
         */
 
3396
        if (segwritten && shouldflush) {
 
3397
                softdep_synchronize(bio, ump, 
 
3398
                    TAILQ_LAST(&jblocks->jb_segs, jseglst));
 
3399
        } else if (bio)
 
3400
                g_destroy_bio(bio);
 
3401
        /*
 
3402
         * If we've suspended the filesystem because we ran out of journal
 
3403
         * space either try to sync it here to make some progress or
 
3404
         * unsuspend it if we already have.
 
3405
         */
 
3406
        if (flags == 0 && jblocks->jb_suspended) {
 
3407
                if (journal_unsuspend(ump))
 
3408
                        return;
 
3409
                FREE_LOCK(&lk);
 
3410
                VFS_SYNC(mp, MNT_NOWAIT);
 
3411
                ffs_sbupdate(ump, MNT_WAIT, 0);
 
3412
                ACQUIRE_LOCK(&lk);
 
3413
        }
 
3414
}
 
3415
 
 
3416
/*
 
3417
 * Complete a jseg, allowing all dependencies awaiting journal writes
 
3418
 * to proceed.  Each journal dependency also attaches a jsegdep to dependent
 
3419
 * structures so that the journal segment can be freed to reclaim space.
 
3420
 */
 
3421
static void
 
3422
complete_jseg(jseg)
 
3423
        struct jseg *jseg;
 
3424
{
 
3425
        struct worklist *wk;
 
3426
        struct jmvref *jmvref;
 
3427
        int waiting;
 
3428
#ifdef INVARIANTS
 
3429
        int i = 0;
 
3430
#endif
 
3431
 
 
3432
        while ((wk = LIST_FIRST(&jseg->js_entries)) != NULL) {
 
3433
                WORKLIST_REMOVE(wk);
 
3434
                waiting = wk->wk_state & IOWAITING;
 
3435
                wk->wk_state &= ~(INPROGRESS | IOWAITING);
 
3436
                wk->wk_state |= COMPLETE;
 
3437
                KASSERT(i++ < jseg->js_cnt,
 
3438
                    ("handle_written_jseg: overflow %d >= %d",
 
3439
                    i - 1, jseg->js_cnt));
 
3440
                switch (wk->wk_type) {
 
3441
                case D_JADDREF:
 
3442
                        handle_written_jaddref(WK_JADDREF(wk));
 
3443
                        break;
 
3444
                case D_JREMREF:
 
3445
                        handle_written_jremref(WK_JREMREF(wk));
 
3446
                        break;
 
3447
                case D_JMVREF:
 
3448
                        rele_jseg(jseg);        /* No jsegdep. */
 
3449
                        jmvref = WK_JMVREF(wk);
 
3450
                        LIST_REMOVE(jmvref, jm_deps);
 
3451
                        if ((jmvref->jm_pagedep->pd_state & ONWORKLIST) == 0)
 
3452
                                free_pagedep(jmvref->jm_pagedep);
 
3453
                        WORKITEM_FREE(jmvref, D_JMVREF);
 
3454
                        break;
 
3455
                case D_JNEWBLK:
 
3456
                        handle_written_jnewblk(WK_JNEWBLK(wk));
 
3457
                        break;
 
3458
                case D_JFREEBLK:
 
3459
                        handle_written_jblkdep(&WK_JFREEBLK(wk)->jf_dep);
 
3460
                        break;
 
3461
                case D_JTRUNC:
 
3462
                        handle_written_jblkdep(&WK_JTRUNC(wk)->jt_dep);
 
3463
                        break;
 
3464
                case D_JFSYNC:
 
3465
                        rele_jseg(jseg);        /* No jsegdep. */
 
3466
                        WORKITEM_FREE(wk, D_JFSYNC);
 
3467
                        break;
 
3468
                case D_JFREEFRAG:
 
3469
                        handle_written_jfreefrag(WK_JFREEFRAG(wk));
 
3470
                        break;
 
3471
                default:
 
3472
                        panic("handle_written_jseg: Unknown type %s",
 
3473
                            TYPENAME(wk->wk_type));
 
3474
                        /* NOTREACHED */
 
3475
                }
 
3476
                if (waiting)
 
3477
                        wakeup(wk);
 
3478
        }
 
3479
        /* Release the self reference so the structure may be freed. */
 
3480
        rele_jseg(jseg);
 
3481
}
 
3482
 
 
3483
/*
 
3484
 * Determine which jsegs are ready for completion processing.  Waits for
 
3485
 * synchronize cache to complete as well as forcing in-order completion
 
3486
 * of journal entries.
 
3487
 */
 
3488
static void
 
3489
complete_jsegs(jseg)
 
3490
        struct jseg *jseg;
 
3491
{
 
3492
        struct jblocks *jblocks;
 
3493
        struct jseg *jsegn;
 
3494
 
 
3495
        jblocks = jseg->js_jblocks;
 
3496
        /*
 
3497
         * Don't allow out of order completions.  If this isn't the first
 
3498
         * block wait for it to write before we're done.
 
3499
         */
 
3500
        if (jseg != jblocks->jb_writeseg)
 
3501
                return;
 
3502
        /* Iterate through available jsegs processing their entries. */
 
3503
        while (jseg && (jseg->js_state & ALLCOMPLETE) == ALLCOMPLETE) {
 
3504
                jblocks->jb_oldestwrseq = jseg->js_oldseq;
 
3505
                jsegn = TAILQ_NEXT(jseg, js_next);
 
3506
                complete_jseg(jseg);
 
3507
                jseg = jsegn;
 
3508
        }
 
3509
        jblocks->jb_writeseg = jseg;
 
3510
        /*
 
3511
         * Attempt to free jsegs now that oldestwrseq may have advanced. 
 
3512
         */
 
3513
        free_jsegs(jblocks);
 
3514
}
 
3515
 
 
3516
/*
 
3517
 * Mark a jseg as DEPCOMPLETE and throw away the buffer.  Attempt to handle
 
3518
 * the final completions.
 
3519
 */
 
3520
static void
 
3521
handle_written_jseg(jseg, bp)
 
3522
        struct jseg *jseg;
 
3523
        struct buf *bp;
 
3524
{
 
3525
 
 
3526
        if (jseg->js_refs == 0)
 
3527
                panic("handle_written_jseg: No self-reference on %p", jseg);
 
3528
        jseg->js_state |= DEPCOMPLETE;
 
3529
        /*
 
3530
         * We'll never need this buffer again, set flags so it will be
 
3531
         * discarded.
 
3532
         */
 
3533
        bp->b_flags |= B_INVAL | B_NOCACHE;
 
3534
        complete_jsegs(jseg);
 
3535
}
 
3536
 
 
3537
static inline struct jsegdep *
 
3538
inoref_jseg(inoref)
 
3539
        struct inoref *inoref;
 
3540
{
 
3541
        struct jsegdep *jsegdep;
 
3542
 
 
3543
        jsegdep = inoref->if_jsegdep;
 
3544
        inoref->if_jsegdep = NULL;
 
3545
 
 
3546
        return (jsegdep);
 
3547
}
 
3548
 
 
3549
/*
 
3550
 * Called once a jremref has made it to stable store.  The jremref is marked
 
3551
 * complete and we attempt to free it.  Any pagedeps writes sleeping waiting
 
3552
 * for the jremref to complete will be awoken by free_jremref.
 
3553
 */
 
3554
static void
 
3555
handle_written_jremref(jremref)
 
3556
        struct jremref *jremref;
 
3557
{
 
3558
        struct inodedep *inodedep;
 
3559
        struct jsegdep *jsegdep;
 
3560
        struct dirrem *dirrem;
 
3561
 
 
3562
        /* Grab the jsegdep. */
 
3563
        jsegdep = inoref_jseg(&jremref->jr_ref);
 
3564
        /*
 
3565
         * Remove us from the inoref list.
 
3566
         */
 
3567
        if (inodedep_lookup(jremref->jr_list.wk_mp, jremref->jr_ref.if_ino,
 
3568
            0, &inodedep) == 0)
 
3569
                panic("handle_written_jremref: Lost inodedep");
 
3570
        TAILQ_REMOVE(&inodedep->id_inoreflst, &jremref->jr_ref, if_deps);
 
3571
        /*
 
3572
         * Complete the dirrem.
 
3573
         */
 
3574
        dirrem = jremref->jr_dirrem;
 
3575
        jremref->jr_dirrem = NULL;
 
3576
        LIST_REMOVE(jremref, jr_deps);
 
3577
        jsegdep->jd_state |= jremref->jr_state & MKDIR_PARENT;
 
3578
        jwork_insert(&dirrem->dm_jwork, jsegdep);
 
3579
        if (LIST_EMPTY(&dirrem->dm_jremrefhd) &&
 
3580
            (dirrem->dm_state & COMPLETE) != 0)
 
3581
                add_to_worklist(&dirrem->dm_list, 0);
 
3582
        free_jremref(jremref);
 
3583
}
 
3584
 
 
3585
/*
 
3586
 * Called once a jaddref has made it to stable store.  The dependency is
 
3587
 * marked complete and any dependent structures are added to the inode
 
3588
 * bufwait list to be completed as soon as it is written.  If a bitmap write
 
3589
 * depends on this entry we move the inode into the inodedephd of the
 
3590
 * bmsafemap dependency and attempt to remove the jaddref from the bmsafemap.
 
3591
 */
 
3592
static void
 
3593
handle_written_jaddref(jaddref)
 
3594
        struct jaddref *jaddref;
 
3595
{
 
3596
        struct jsegdep *jsegdep;
 
3597
        struct inodedep *inodedep;
 
3598
        struct diradd *diradd;
 
3599
        struct mkdir *mkdir;
 
3600
 
 
3601
        /* Grab the jsegdep. */
 
3602
        jsegdep = inoref_jseg(&jaddref->ja_ref);
 
3603
        mkdir = NULL;
 
3604
        diradd = NULL;
 
3605
        if (inodedep_lookup(jaddref->ja_list.wk_mp, jaddref->ja_ino,
 
3606
            0, &inodedep) == 0)
 
3607
                panic("handle_written_jaddref: Lost inodedep.");
 
3608
        if (jaddref->ja_diradd == NULL)
 
3609
                panic("handle_written_jaddref: No dependency");
 
3610
        if (jaddref->ja_diradd->da_list.wk_type == D_DIRADD) {
 
3611
                diradd = jaddref->ja_diradd;
 
3612
                WORKLIST_INSERT(&inodedep->id_bufwait, &diradd->da_list);
 
3613
        } else if (jaddref->ja_state & MKDIR_PARENT) {
 
3614
                mkdir = jaddref->ja_mkdir;
 
3615
                WORKLIST_INSERT(&inodedep->id_bufwait, &mkdir->md_list);
 
3616
        } else if (jaddref->ja_state & MKDIR_BODY)
 
3617
                mkdir = jaddref->ja_mkdir;
 
3618
        else
 
3619
                panic("handle_written_jaddref: Unknown dependency %p",
 
3620
                    jaddref->ja_diradd);
 
3621
        jaddref->ja_diradd = NULL;      /* also clears ja_mkdir */
 
3622
        /*
 
3623
         * Remove us from the inode list.
 
3624
         */
 
3625
        TAILQ_REMOVE(&inodedep->id_inoreflst, &jaddref->ja_ref, if_deps);
 
3626
        /*
 
3627
         * The mkdir may be waiting on the jaddref to clear before freeing.
 
3628
         */
 
3629
        if (mkdir) {
 
3630
                KASSERT(mkdir->md_list.wk_type == D_MKDIR,
 
3631
                    ("handle_written_jaddref: Incorrect type for mkdir %s",
 
3632
                    TYPENAME(mkdir->md_list.wk_type)));
 
3633
                mkdir->md_jaddref = NULL;
 
3634
                diradd = mkdir->md_diradd;
 
3635
                mkdir->md_state |= DEPCOMPLETE;
 
3636
                complete_mkdir(mkdir);
 
3637
        }
 
3638
        jwork_insert(&diradd->da_jwork, jsegdep);
 
3639
        if (jaddref->ja_state & NEWBLOCK) {
 
3640
                inodedep->id_state |= ONDEPLIST;
 
3641
                LIST_INSERT_HEAD(&inodedep->id_bmsafemap->sm_inodedephd,
 
3642
                    inodedep, id_deps);
 
3643
        }
 
3644
        free_jaddref(jaddref);
 
3645
}
 
3646
 
 
3647
/*
 
3648
 * Called once a jnewblk journal is written.  The allocdirect or allocindir
 
3649
 * is placed in the bmsafemap to await notification of a written bitmap.  If
 
3650
 * the operation was canceled we add the segdep to the appropriate
 
3651
 * dependency to free the journal space once the canceling operation
 
3652
 * completes.
 
3653
 */
 
3654
static void
 
3655
handle_written_jnewblk(jnewblk)
 
3656
        struct jnewblk *jnewblk;
 
3657
{
 
3658
        struct bmsafemap *bmsafemap;
 
3659
        struct freefrag *freefrag;
 
3660
        struct freework *freework;
 
3661
        struct jsegdep *jsegdep;
 
3662
        struct newblk *newblk;
 
3663
 
 
3664
        /* Grab the jsegdep. */
 
3665
        jsegdep = jnewblk->jn_jsegdep;
 
3666
        jnewblk->jn_jsegdep = NULL;
 
3667
        if (jnewblk->jn_dep == NULL) 
 
3668
                panic("handle_written_jnewblk: No dependency for the segdep.");
 
3669
        switch (jnewblk->jn_dep->wk_type) {
 
3670
        case D_NEWBLK:
 
3671
        case D_ALLOCDIRECT:
 
3672
        case D_ALLOCINDIR:
 
3673
                /*
 
3674
                 * Add the written block to the bmsafemap so it can
 
3675
                 * be notified when the bitmap is on disk.
 
3676
                 */
 
3677
                newblk = WK_NEWBLK(jnewblk->jn_dep);
 
3678
                newblk->nb_jnewblk = NULL;
 
3679
                if ((newblk->nb_state & GOINGAWAY) == 0) {
 
3680
                        bmsafemap = newblk->nb_bmsafemap;
 
3681
                        newblk->nb_state |= ONDEPLIST;
 
3682
                        LIST_INSERT_HEAD(&bmsafemap->sm_newblkhd, newblk,
 
3683
                            nb_deps);
 
3684
                }
 
3685
                jwork_insert(&newblk->nb_jwork, jsegdep);
 
3686
                break;
 
3687
        case D_FREEFRAG:
 
3688
                /*
 
3689
                 * A newblock being removed by a freefrag when replaced by
 
3690
                 * frag extension.
 
3691
                 */
 
3692
                freefrag = WK_FREEFRAG(jnewblk->jn_dep);
 
3693
                freefrag->ff_jdep = NULL;
 
3694
                jwork_insert(&freefrag->ff_jwork, jsegdep);
 
3695
                break;
 
3696
        case D_FREEWORK:
 
3697
                /*
 
3698
                 * A direct block was removed by truncate.
 
3699
                 */
 
3700
                freework = WK_FREEWORK(jnewblk->jn_dep);
 
3701
                freework->fw_jnewblk = NULL;
 
3702
                jwork_insert(&freework->fw_freeblks->fb_jwork, jsegdep);
 
3703
                break;
 
3704
        default:
 
3705
                panic("handle_written_jnewblk: Unknown type %d.",
 
3706
                    jnewblk->jn_dep->wk_type);
 
3707
        }
 
3708
        jnewblk->jn_dep = NULL;
 
3709
        free_jnewblk(jnewblk);
 
3710
}
 
3711
 
 
3712
/*
 
3713
 * Cancel a jfreefrag that won't be needed, probably due to colliding with
 
3714
 * an in-flight allocation that has not yet been committed.  Divorce us
 
3715
 * from the freefrag and mark it DEPCOMPLETE so that it may be added
 
3716
 * to the worklist.
 
3717
 */
 
3718
static void
 
3719
cancel_jfreefrag(jfreefrag)
 
3720
        struct jfreefrag *jfreefrag;
 
3721
{
 
3722
        struct freefrag *freefrag;
 
3723
 
 
3724
        if (jfreefrag->fr_jsegdep) {
 
3725
                free_jsegdep(jfreefrag->fr_jsegdep);
 
3726
                jfreefrag->fr_jsegdep = NULL;
 
3727
        }
 
3728
        freefrag = jfreefrag->fr_freefrag;
 
3729
        jfreefrag->fr_freefrag = NULL;
 
3730
        free_jfreefrag(jfreefrag);
 
3731
        freefrag->ff_state |= DEPCOMPLETE;
 
3732
        CTR1(KTR_SUJ, "cancel_jfreefrag: blkno %jd", freefrag->ff_blkno);
 
3733
}
 
3734
 
 
3735
/*
 
3736
 * Free a jfreefrag when the parent freefrag is rendered obsolete.
 
3737
 */
 
3738
static void
 
3739
free_jfreefrag(jfreefrag)
 
3740
        struct jfreefrag *jfreefrag;
 
3741
{
 
3742
 
 
3743
        if (jfreefrag->fr_state & INPROGRESS)
 
3744
                WORKLIST_REMOVE(&jfreefrag->fr_list);
 
3745
        else if (jfreefrag->fr_state & ONWORKLIST)
 
3746
                remove_from_journal(&jfreefrag->fr_list);
 
3747
        if (jfreefrag->fr_freefrag != NULL)
 
3748
                panic("free_jfreefrag:  Still attached to a freefrag.");
 
3749
        WORKITEM_FREE(jfreefrag, D_JFREEFRAG);
 
3750
}
 
3751
 
 
3752
/*
 
3753
 * Called when the journal write for a jfreefrag completes.  The parent
 
3754
 * freefrag is added to the worklist if this completes its dependencies.
 
3755
 */
 
3756
static void
 
3757
handle_written_jfreefrag(jfreefrag)
 
3758
        struct jfreefrag *jfreefrag;
 
3759
{
 
3760
        struct jsegdep *jsegdep;
 
3761
        struct freefrag *freefrag;
 
3762
 
 
3763
        /* Grab the jsegdep. */
 
3764
        jsegdep = jfreefrag->fr_jsegdep;
 
3765
        jfreefrag->fr_jsegdep = NULL;
 
3766
        freefrag = jfreefrag->fr_freefrag;
 
3767
        if (freefrag == NULL)
 
3768
                panic("handle_written_jfreefrag: No freefrag.");
 
3769
        freefrag->ff_state |= DEPCOMPLETE;
 
3770
        freefrag->ff_jdep = NULL;
 
3771
        jwork_insert(&freefrag->ff_jwork, jsegdep);
 
3772
        if ((freefrag->ff_state & ALLCOMPLETE) == ALLCOMPLETE)
 
3773
                add_to_worklist(&freefrag->ff_list, 0);
 
3774
        jfreefrag->fr_freefrag = NULL;
 
3775
        free_jfreefrag(jfreefrag);
 
3776
}
 
3777
 
 
3778
/*
 
3779
 * Called when the journal write for a jfreeblk completes.  The jfreeblk
 
3780
 * is removed from the freeblks list of pending journal writes and the
 
3781
 * jsegdep is moved to the freeblks jwork to be completed when all blocks
 
3782
 * have been reclaimed.
 
3783
 */
 
3784
static void
 
3785
handle_written_jblkdep(jblkdep)
 
3786
        struct jblkdep *jblkdep;
 
3787
{
 
3788
        struct freeblks *freeblks;
 
3789
        struct jsegdep *jsegdep;
 
3790
 
 
3791
        /* Grab the jsegdep. */
 
3792
        jsegdep = jblkdep->jb_jsegdep;
 
3793
        jblkdep->jb_jsegdep = NULL;
 
3794
        freeblks = jblkdep->jb_freeblks;
 
3795
        LIST_REMOVE(jblkdep, jb_deps);
 
3796
        jwork_insert(&freeblks->fb_jwork, jsegdep);
 
3797
        /*
 
3798
         * If the freeblks is all journaled, we can add it to the worklist.
 
3799
         */
 
3800
        if (LIST_EMPTY(&freeblks->fb_jblkdephd) &&
 
3801
            (freeblks->fb_state & ALLCOMPLETE) == ALLCOMPLETE)
 
3802
                add_to_worklist(&freeblks->fb_list, WK_NODELAY);
 
3803
 
 
3804
        free_jblkdep(jblkdep);
 
3805
}
 
3806
 
 
3807
static struct jsegdep *
 
3808
newjsegdep(struct worklist *wk)
 
3809
{
 
3810
        struct jsegdep *jsegdep;
 
3811
 
 
3812
        jsegdep = malloc(sizeof(*jsegdep), M_JSEGDEP, M_SOFTDEP_FLAGS);
 
3813
        workitem_alloc(&jsegdep->jd_list, D_JSEGDEP, wk->wk_mp);
 
3814
        jsegdep->jd_seg = NULL;
 
3815
 
 
3816
        return (jsegdep);
 
3817
}
 
3818
 
 
3819
static struct jmvref *
 
3820
newjmvref(dp, ino, oldoff, newoff)
 
3821
        struct inode *dp;
 
3822
        ino_t ino;
 
3823
        off_t oldoff;
 
3824
        off_t newoff;
 
3825
{
 
3826
        struct jmvref *jmvref;
 
3827
 
 
3828
        jmvref = malloc(sizeof(*jmvref), M_JMVREF, M_SOFTDEP_FLAGS);
 
3829
        workitem_alloc(&jmvref->jm_list, D_JMVREF, UFSTOVFS(dp->i_ump));
 
3830
        jmvref->jm_list.wk_state = ATTACHED | DEPCOMPLETE;
 
3831
        jmvref->jm_parent = dp->i_number;
 
3832
        jmvref->jm_ino = ino;
 
3833
        jmvref->jm_oldoff = oldoff;
 
3834
        jmvref->jm_newoff = newoff;
 
3835
 
 
3836
        return (jmvref);
 
3837
}
 
3838
 
 
3839
/*
 
3840
 * Allocate a new jremref that tracks the removal of ip from dp with the
 
3841
 * directory entry offset of diroff.  Mark the entry as ATTACHED and
 
3842
 * DEPCOMPLETE as we have all the information required for the journal write
 
3843
 * and the directory has already been removed from the buffer.  The caller
 
3844
 * is responsible for linking the jremref into the pagedep and adding it
 
3845
 * to the journal to write.  The MKDIR_PARENT flag is set if we're doing
 
3846
 * a DOTDOT addition so handle_workitem_remove() can properly assign
 
3847
 * the jsegdep when we're done.
 
3848
 */
 
3849
static struct jremref *
 
3850
newjremref(struct dirrem *dirrem, struct inode *dp, struct inode *ip,
 
3851
    off_t diroff, nlink_t nlink)
 
3852
{
 
3853
        struct jremref *jremref;
 
3854
 
 
3855
        jremref = malloc(sizeof(*jremref), M_JREMREF, M_SOFTDEP_FLAGS);
 
3856
        workitem_alloc(&jremref->jr_list, D_JREMREF, UFSTOVFS(dp->i_ump));
 
3857
        jremref->jr_state = ATTACHED;
 
3858
        newinoref(&jremref->jr_ref, ip->i_number, dp->i_number, diroff,
 
3859
           nlink, ip->i_mode);
 
3860
        jremref->jr_dirrem = dirrem;
 
3861
 
 
3862
        return (jremref);
 
3863
}
 
3864
 
 
3865
static inline void
 
3866
newinoref(struct inoref *inoref, ino_t ino, ino_t parent, off_t diroff,
 
3867
    nlink_t nlink, uint16_t mode)
 
3868
{
 
3869
 
 
3870
        inoref->if_jsegdep = newjsegdep(&inoref->if_list);
 
3871
        inoref->if_diroff = diroff;
 
3872
        inoref->if_ino = ino;
 
3873
        inoref->if_parent = parent;
 
3874
        inoref->if_nlink = nlink;
 
3875
        inoref->if_mode = mode;
 
3876
}
 
3877
 
 
3878
/*
 
3879
 * Allocate a new jaddref to track the addition of ino to dp at diroff.  The
 
3880
 * directory offset may not be known until later.  The caller is responsible
 
3881
 * adding the entry to the journal when this information is available.  nlink
 
3882
 * should be the link count prior to the addition and mode is only required
 
3883
 * to have the correct FMT.
 
3884
 */
 
3885
static struct jaddref *
 
3886
newjaddref(struct inode *dp, ino_t ino, off_t diroff, int16_t nlink,
 
3887
    uint16_t mode)
 
3888
{
 
3889
        struct jaddref *jaddref;
 
3890
 
 
3891
        jaddref = malloc(sizeof(*jaddref), M_JADDREF, M_SOFTDEP_FLAGS);
 
3892
        workitem_alloc(&jaddref->ja_list, D_JADDREF, UFSTOVFS(dp->i_ump));
 
3893
        jaddref->ja_state = ATTACHED;
 
3894
        jaddref->ja_mkdir = NULL;
 
3895
        newinoref(&jaddref->ja_ref, ino, dp->i_number, diroff, nlink, mode);
 
3896
 
 
3897
        return (jaddref);
 
3898
}
 
3899
 
 
3900
/*
 
3901
 * Create a new free dependency for a freework.  The caller is responsible
 
3902
 * for adjusting the reference count when it has the lock held.  The freedep
 
3903
 * will track an outstanding bitmap write that will ultimately clear the
 
3904
 * freework to continue.
 
3905
 */
 
3906
static struct freedep *
 
3907
newfreedep(struct freework *freework)
 
3908
{
 
3909
        struct freedep *freedep;
 
3910
 
 
3911
        freedep = malloc(sizeof(*freedep), M_FREEDEP, M_SOFTDEP_FLAGS);
 
3912
        workitem_alloc(&freedep->fd_list, D_FREEDEP, freework->fw_list.wk_mp);
 
3913
        freedep->fd_freework = freework;
 
3914
 
 
3915
        return (freedep);
 
3916
}
 
3917
 
 
3918
/*
 
3919
 * Free a freedep structure once the buffer it is linked to is written.  If
 
3920
 * this is the last reference to the freework schedule it for completion.
 
3921
 */
 
3922
static void
 
3923
free_freedep(freedep)
 
3924
        struct freedep *freedep;
 
3925
{
 
3926
        struct freework *freework;
 
3927
 
 
3928
        freework = freedep->fd_freework;
 
3929
        freework->fw_freeblks->fb_cgwait--;
 
3930
        if (--freework->fw_ref == 0)
 
3931
                freework_enqueue(freework);
 
3932
        WORKITEM_FREE(freedep, D_FREEDEP);
 
3933
}
 
3934
 
 
3935
/*
 
3936
 * Allocate a new freework structure that may be a level in an indirect
 
3937
 * when parent is not NULL or a top level block when it is.  The top level
 
3938
 * freework structures are allocated without lk held and before the freeblks
 
3939
 * is visible outside of softdep_setup_freeblocks().
 
3940
 */
 
3941
static struct freework *
 
3942
newfreework(ump, freeblks, parent, lbn, nb, frags, off, journal)
 
3943
        struct ufsmount *ump;
 
3944
        struct freeblks *freeblks;
 
3945
        struct freework *parent;
 
3946
        ufs_lbn_t lbn;
 
3947
        ufs2_daddr_t nb;
 
3948
        int frags;
 
3949
        int off;
 
3950
        int journal;
 
3951
{
 
3952
        struct freework *freework;
 
3953
 
 
3954
        freework = malloc(sizeof(*freework), M_FREEWORK, M_SOFTDEP_FLAGS);
 
3955
        workitem_alloc(&freework->fw_list, D_FREEWORK, freeblks->fb_list.wk_mp);
 
3956
        freework->fw_state = ATTACHED;
 
3957
        freework->fw_jnewblk = NULL;
 
3958
        freework->fw_freeblks = freeblks;
 
3959
        freework->fw_parent = parent;
 
3960
        freework->fw_lbn = lbn;
 
3961
        freework->fw_blkno = nb;
 
3962
        freework->fw_frags = frags;
 
3963
        freework->fw_indir = NULL;
 
3964
        freework->fw_ref = (MOUNTEDSUJ(UFSTOVFS(ump)) == 0 || lbn >= -NXADDR)
 
3965
                ? 0 : NINDIR(ump->um_fs) + 1;
 
3966
        freework->fw_start = freework->fw_off = off;
 
3967
        if (journal)
 
3968
                newjfreeblk(freeblks, lbn, nb, frags);
 
3969
        if (parent == NULL) {
 
3970
                ACQUIRE_LOCK(&lk);
 
3971
                WORKLIST_INSERT(&freeblks->fb_freeworkhd, &freework->fw_list);
 
3972
                freeblks->fb_ref++;
 
3973
                FREE_LOCK(&lk);
 
3974
        }
 
3975
 
 
3976
        return (freework);
 
3977
}
 
3978
 
 
3979
/*
 
3980
 * Eliminate a jfreeblk for a block that does not need journaling.
 
3981
 */
 
3982
static void
 
3983
cancel_jfreeblk(freeblks, blkno)
 
3984
        struct freeblks *freeblks;
 
3985
        ufs2_daddr_t blkno;
 
3986
{
 
3987
        struct jfreeblk *jfreeblk;
 
3988
        struct jblkdep *jblkdep;
 
3989
 
 
3990
        LIST_FOREACH(jblkdep, &freeblks->fb_jblkdephd, jb_deps) {
 
3991
                if (jblkdep->jb_list.wk_type != D_JFREEBLK)
 
3992
                        continue;
 
3993
                jfreeblk = WK_JFREEBLK(&jblkdep->jb_list);
 
3994
                if (jfreeblk->jf_blkno == blkno)
 
3995
                        break;
 
3996
        }
 
3997
        if (jblkdep == NULL)
 
3998
                return;
 
3999
        CTR1(KTR_SUJ, "cancel_jfreeblk: blkno %jd", blkno);
 
4000
        free_jsegdep(jblkdep->jb_jsegdep);
 
4001
        LIST_REMOVE(jblkdep, jb_deps);
 
4002
        WORKITEM_FREE(jfreeblk, D_JFREEBLK);
 
4003
}
 
4004
 
 
4005
/*
 
4006
 * Allocate a new jfreeblk to journal top level block pointer when truncating
 
4007
 * a file.  The caller must add this to the worklist when lk is held.
 
4008
 */
 
4009
static struct jfreeblk *
 
4010
newjfreeblk(freeblks, lbn, blkno, frags)
 
4011
        struct freeblks *freeblks;
 
4012
        ufs_lbn_t lbn;
 
4013
        ufs2_daddr_t blkno;
 
4014
        int frags;
 
4015
{
 
4016
        struct jfreeblk *jfreeblk;
 
4017
 
 
4018
        jfreeblk = malloc(sizeof(*jfreeblk), M_JFREEBLK, M_SOFTDEP_FLAGS);
 
4019
        workitem_alloc(&jfreeblk->jf_dep.jb_list, D_JFREEBLK,
 
4020
            freeblks->fb_list.wk_mp);
 
4021
        jfreeblk->jf_dep.jb_jsegdep = newjsegdep(&jfreeblk->jf_dep.jb_list);
 
4022
        jfreeblk->jf_dep.jb_freeblks = freeblks;
 
4023
        jfreeblk->jf_ino = freeblks->fb_inum;
 
4024
        jfreeblk->jf_lbn = lbn;
 
4025
        jfreeblk->jf_blkno = blkno;
 
4026
        jfreeblk->jf_frags = frags;
 
4027
        LIST_INSERT_HEAD(&freeblks->fb_jblkdephd, &jfreeblk->jf_dep, jb_deps);
 
4028
 
 
4029
        return (jfreeblk);
 
4030
}
 
4031
 
 
4032
/*
 
4033
 * Allocate a new jtrunc to track a partial truncation.
 
4034
 */
 
4035
static struct jtrunc *
 
4036
newjtrunc(freeblks, size, extsize)
 
4037
        struct freeblks *freeblks;
 
4038
        off_t size;
 
4039
        int extsize;
 
4040
{
 
4041
        struct jtrunc *jtrunc;
 
4042
 
 
4043
        jtrunc = malloc(sizeof(*jtrunc), M_JTRUNC, M_SOFTDEP_FLAGS);
 
4044
        workitem_alloc(&jtrunc->jt_dep.jb_list, D_JTRUNC,
 
4045
            freeblks->fb_list.wk_mp);
 
4046
        jtrunc->jt_dep.jb_jsegdep = newjsegdep(&jtrunc->jt_dep.jb_list);
 
4047
        jtrunc->jt_dep.jb_freeblks = freeblks;
 
4048
        jtrunc->jt_ino = freeblks->fb_inum;
 
4049
        jtrunc->jt_size = size;
 
4050
        jtrunc->jt_extsize = extsize;
 
4051
        LIST_INSERT_HEAD(&freeblks->fb_jblkdephd, &jtrunc->jt_dep, jb_deps);
 
4052
 
 
4053
        return (jtrunc);
 
4054
}
 
4055
 
 
4056
/*
 
4057
 * If we're canceling a new bitmap we have to search for another ref
 
4058
 * to move into the bmsafemap dep.  This might be better expressed
 
4059
 * with another structure.
 
4060
 */
 
4061
static void
 
4062
move_newblock_dep(jaddref, inodedep)
 
4063
        struct jaddref *jaddref;
 
4064
        struct inodedep *inodedep;
 
4065
{
 
4066
        struct inoref *inoref;
 
4067
        struct jaddref *jaddrefn;
 
4068
 
 
4069
        jaddrefn = NULL;
 
4070
        for (inoref = TAILQ_NEXT(&jaddref->ja_ref, if_deps); inoref;
 
4071
            inoref = TAILQ_NEXT(inoref, if_deps)) {
 
4072
                if ((jaddref->ja_state & NEWBLOCK) &&
 
4073
                    inoref->if_list.wk_type == D_JADDREF) {
 
4074
                        jaddrefn = (struct jaddref *)inoref;
 
4075
                        break;
 
4076
                }
 
4077
        }
 
4078
        if (jaddrefn == NULL)
 
4079
                return;
 
4080
        jaddrefn->ja_state &= ~(ATTACHED | UNDONE);
 
4081
        jaddrefn->ja_state |= jaddref->ja_state &
 
4082
            (ATTACHED | UNDONE | NEWBLOCK);
 
4083
        jaddref->ja_state &= ~(ATTACHED | UNDONE | NEWBLOCK);
 
4084
        jaddref->ja_state |= ATTACHED;
 
4085
        LIST_REMOVE(jaddref, ja_bmdeps);
 
4086
        LIST_INSERT_HEAD(&inodedep->id_bmsafemap->sm_jaddrefhd, jaddrefn,
 
4087
            ja_bmdeps);
 
4088
}
 
4089
 
 
4090
/*
 
4091
 * Cancel a jaddref either before it has been written or while it is being
 
4092
 * written.  This happens when a link is removed before the add reaches
 
4093
 * the disk.  The jaddref dependency is kept linked into the bmsafemap
 
4094
 * and inode to prevent the link count or bitmap from reaching the disk
 
4095
 * until handle_workitem_remove() re-adjusts the counts and bitmaps as
 
4096
 * required.
 
4097
 *
 
4098
 * Returns 1 if the canceled addref requires journaling of the remove and
 
4099
 * 0 otherwise.
 
4100
 */
 
4101
static int
 
4102
cancel_jaddref(jaddref, inodedep, wkhd)
 
4103
        struct jaddref *jaddref;
 
4104
        struct inodedep *inodedep;
 
4105
        struct workhead *wkhd;
 
4106
{
 
4107
        struct inoref *inoref;
 
4108
        struct jsegdep *jsegdep;
 
4109
        int needsj;
 
4110
 
 
4111
        KASSERT((jaddref->ja_state & COMPLETE) == 0,
 
4112
            ("cancel_jaddref: Canceling complete jaddref"));
 
4113
        if (jaddref->ja_state & (INPROGRESS | COMPLETE))
 
4114
                needsj = 1;
 
4115
        else
 
4116
                needsj = 0;
 
4117
        if (inodedep == NULL)
 
4118
                if (inodedep_lookup(jaddref->ja_list.wk_mp, jaddref->ja_ino,
 
4119
                    0, &inodedep) == 0)
 
4120
                        panic("cancel_jaddref: Lost inodedep");
 
4121
        /*
 
4122
         * We must adjust the nlink of any reference operation that follows
 
4123
         * us so that it is consistent with the in-memory reference.  This
 
4124
         * ensures that inode nlink rollbacks always have the correct link.
 
4125
         */
 
4126
        if (needsj == 0) {
 
4127
                for (inoref = TAILQ_NEXT(&jaddref->ja_ref, if_deps); inoref;
 
4128
                    inoref = TAILQ_NEXT(inoref, if_deps)) {
 
4129
                        if (inoref->if_state & GOINGAWAY)
 
4130
                                break;
 
4131
                        inoref->if_nlink--;
 
4132
                }
 
4133
        }
 
4134
        jsegdep = inoref_jseg(&jaddref->ja_ref);
 
4135
        if (jaddref->ja_state & NEWBLOCK)
 
4136
                move_newblock_dep(jaddref, inodedep);
 
4137
        wake_worklist(&jaddref->ja_list);
 
4138
        jaddref->ja_mkdir = NULL;
 
4139
        if (jaddref->ja_state & INPROGRESS) {
 
4140
                jaddref->ja_state &= ~INPROGRESS;
 
4141
                WORKLIST_REMOVE(&jaddref->ja_list);
 
4142
                jwork_insert(wkhd, jsegdep);
 
4143
        } else {
 
4144
                free_jsegdep(jsegdep);
 
4145
                if (jaddref->ja_state & DEPCOMPLETE)
 
4146
                        remove_from_journal(&jaddref->ja_list);
 
4147
        }
 
4148
        jaddref->ja_state |= (GOINGAWAY | DEPCOMPLETE);
 
4149
        /*
 
4150
         * Leave NEWBLOCK jaddrefs on the inodedep so handle_workitem_remove
 
4151
         * can arrange for them to be freed with the bitmap.  Otherwise we
 
4152
         * no longer need this addref attached to the inoreflst and it
 
4153
         * will incorrectly adjust nlink if we leave it.
 
4154
         */
 
4155
        if ((jaddref->ja_state & NEWBLOCK) == 0) {
 
4156
                TAILQ_REMOVE(&inodedep->id_inoreflst, &jaddref->ja_ref,
 
4157
                    if_deps);
 
4158
                jaddref->ja_state |= COMPLETE;
 
4159
                free_jaddref(jaddref);
 
4160
                return (needsj);
 
4161
        }
 
4162
        /*
 
4163
         * Leave the head of the list for jsegdeps for fast merging.
 
4164
         */
 
4165
        if (LIST_FIRST(wkhd) != NULL) {
 
4166
                jaddref->ja_state |= ONWORKLIST;
 
4167
                LIST_INSERT_AFTER(LIST_FIRST(wkhd), &jaddref->ja_list, wk_list);
 
4168
        } else
 
4169
                WORKLIST_INSERT(wkhd, &jaddref->ja_list);
 
4170
 
 
4171
        return (needsj);
 
4172
}
 
4173
 
 
4174
/* 
 
4175
 * Attempt to free a jaddref structure when some work completes.  This
 
4176
 * should only succeed once the entry is written and all dependencies have
 
4177
 * been notified.
 
4178
 */
 
4179
static void
 
4180
free_jaddref(jaddref)
 
4181
        struct jaddref *jaddref;
 
4182
{
 
4183
 
 
4184
        if ((jaddref->ja_state & ALLCOMPLETE) != ALLCOMPLETE)
 
4185
                return;
 
4186
        if (jaddref->ja_ref.if_jsegdep)
 
4187
                panic("free_jaddref: segdep attached to jaddref %p(0x%X)\n",
 
4188
                    jaddref, jaddref->ja_state);
 
4189
        if (jaddref->ja_state & NEWBLOCK)
 
4190
                LIST_REMOVE(jaddref, ja_bmdeps);
 
4191
        if (jaddref->ja_state & (INPROGRESS | ONWORKLIST))
 
4192
                panic("free_jaddref: Bad state %p(0x%X)",
 
4193
                    jaddref, jaddref->ja_state);
 
4194
        if (jaddref->ja_mkdir != NULL)
 
4195
                panic("free_jaddref: Work pending, 0x%X\n", jaddref->ja_state);
 
4196
        WORKITEM_FREE(jaddref, D_JADDREF);
 
4197
}
 
4198
 
 
4199
/*
 
4200
 * Free a jremref structure once it has been written or discarded.
 
4201
 */
 
4202
static void
 
4203
free_jremref(jremref)
 
4204
        struct jremref *jremref;
 
4205
{
 
4206
 
 
4207
        if (jremref->jr_ref.if_jsegdep)
 
4208
                free_jsegdep(jremref->jr_ref.if_jsegdep);
 
4209
        if (jremref->jr_state & INPROGRESS)
 
4210
                panic("free_jremref: IO still pending");
 
4211
        WORKITEM_FREE(jremref, D_JREMREF);
 
4212
}
 
4213
 
 
4214
/*
 
4215
 * Free a jnewblk structure.
 
4216
 */
 
4217
static void
 
4218
free_jnewblk(jnewblk)
 
4219
        struct jnewblk *jnewblk;
 
4220
{
 
4221
 
 
4222
        if ((jnewblk->jn_state & ALLCOMPLETE) != ALLCOMPLETE)
 
4223
                return;
 
4224
        LIST_REMOVE(jnewblk, jn_deps);
 
4225
        if (jnewblk->jn_dep != NULL)
 
4226
                panic("free_jnewblk: Dependency still attached.");
 
4227
        WORKITEM_FREE(jnewblk, D_JNEWBLK);
 
4228
}
 
4229
 
 
4230
/*
 
4231
 * Cancel a jnewblk which has been been made redundant by frag extension.
 
4232
 */
 
4233
static void
 
4234
cancel_jnewblk(jnewblk, wkhd)
 
4235
        struct jnewblk *jnewblk;
 
4236
        struct workhead *wkhd;
 
4237
{
 
4238
        struct jsegdep *jsegdep;
 
4239
 
 
4240
        CTR1(KTR_SUJ, "cancel_jnewblk: blkno %jd", jnewblk->jn_blkno);
 
4241
        jsegdep = jnewblk->jn_jsegdep;
 
4242
        if (jnewblk->jn_jsegdep == NULL || jnewblk->jn_dep == NULL)
 
4243
                panic("cancel_jnewblk: Invalid state");
 
4244
        jnewblk->jn_jsegdep  = NULL;
 
4245
        jnewblk->jn_dep = NULL;
 
4246
        jnewblk->jn_state |= GOINGAWAY;
 
4247
        if (jnewblk->jn_state & INPROGRESS) {
 
4248
                jnewblk->jn_state &= ~INPROGRESS;
 
4249
                WORKLIST_REMOVE(&jnewblk->jn_list);
 
4250
                jwork_insert(wkhd, jsegdep);
 
4251
        } else {
 
4252
                free_jsegdep(jsegdep);
 
4253
                remove_from_journal(&jnewblk->jn_list);
 
4254
        }
 
4255
        wake_worklist(&jnewblk->jn_list);
 
4256
        WORKLIST_INSERT(wkhd, &jnewblk->jn_list);
 
4257
}
 
4258
 
 
4259
static void
 
4260
free_jblkdep(jblkdep)
 
4261
        struct jblkdep *jblkdep;
 
4262
{
 
4263
 
 
4264
        if (jblkdep->jb_list.wk_type == D_JFREEBLK)
 
4265
                WORKITEM_FREE(jblkdep, D_JFREEBLK);
 
4266
        else if (jblkdep->jb_list.wk_type == D_JTRUNC)
 
4267
                WORKITEM_FREE(jblkdep, D_JTRUNC);
 
4268
        else
 
4269
                panic("free_jblkdep: Unexpected type %s",
 
4270
                    TYPENAME(jblkdep->jb_list.wk_type));
 
4271
}
 
4272
 
 
4273
/*
 
4274
 * Free a single jseg once it is no longer referenced in memory or on
 
4275
 * disk.  Reclaim journal blocks and dependencies waiting for the segment
 
4276
 * to disappear.
 
4277
 */
 
4278
static void
 
4279
free_jseg(jseg, jblocks)
 
4280
        struct jseg *jseg;
 
4281
        struct jblocks *jblocks;
 
4282
{
 
4283
        struct freework *freework;
 
4284
 
 
4285
        /*
 
4286
         * Free freework structures that were lingering to indicate freed
 
4287
         * indirect blocks that forced journal write ordering on reallocate.
 
4288
         */
 
4289
        while ((freework = LIST_FIRST(&jseg->js_indirs)) != NULL)
 
4290
                indirblk_remove(freework);
 
4291
        if (jblocks->jb_oldestseg == jseg)
 
4292
                jblocks->jb_oldestseg = TAILQ_NEXT(jseg, js_next);
 
4293
        TAILQ_REMOVE(&jblocks->jb_segs, jseg, js_next);
 
4294
        jblocks_free(jblocks, jseg->js_list.wk_mp, jseg->js_size);
 
4295
        KASSERT(LIST_EMPTY(&jseg->js_entries),
 
4296
            ("free_jseg: Freed jseg has valid entries."));
 
4297
        WORKITEM_FREE(jseg, D_JSEG);
 
4298
}
 
4299
 
 
4300
/*
 
4301
 * Free all jsegs that meet the criteria for being reclaimed and update
 
4302
 * oldestseg.
 
4303
 */
 
4304
static void
 
4305
free_jsegs(jblocks)
 
4306
        struct jblocks *jblocks;
 
4307
{
 
4308
        struct jseg *jseg;
 
4309
 
 
4310
        /*
 
4311
         * Free only those jsegs which have none allocated before them to
 
4312
         * preserve the journal space ordering.
 
4313
         */
 
4314
        while ((jseg = TAILQ_FIRST(&jblocks->jb_segs)) != NULL) {
 
4315
                /*
 
4316
                 * Only reclaim space when nothing depends on this journal
 
4317
                 * set and another set has written that it is no longer
 
4318
                 * valid.
 
4319
                 */
 
4320
                if (jseg->js_refs != 0) {
 
4321
                        jblocks->jb_oldestseg = jseg;
 
4322
                        return;
 
4323
                }
 
4324
                if ((jseg->js_state & ALLCOMPLETE) != ALLCOMPLETE)
 
4325
                        break;
 
4326
                if (jseg->js_seq > jblocks->jb_oldestwrseq)
 
4327
                        break;
 
4328
                /*
 
4329
                 * We can free jsegs that didn't write entries when
 
4330
                 * oldestwrseq == js_seq.
 
4331
                 */
 
4332
                if (jseg->js_seq == jblocks->jb_oldestwrseq &&
 
4333
                    jseg->js_cnt != 0)
 
4334
                        break;
 
4335
                free_jseg(jseg, jblocks);
 
4336
        }
 
4337
        /*
 
4338
         * If we exited the loop above we still must discover the
 
4339
         * oldest valid segment.
 
4340
         */
 
4341
        if (jseg)
 
4342
                for (jseg = jblocks->jb_oldestseg; jseg != NULL;
 
4343
                     jseg = TAILQ_NEXT(jseg, js_next))
 
4344
                        if (jseg->js_refs != 0)
 
4345
                                break;
 
4346
        jblocks->jb_oldestseg = jseg;
 
4347
        /*
 
4348
         * The journal has no valid records but some jsegs may still be
 
4349
         * waiting on oldestwrseq to advance.  We force a small record
 
4350
         * out to permit these lingering records to be reclaimed.
 
4351
         */
 
4352
        if (jblocks->jb_oldestseg == NULL && !TAILQ_EMPTY(&jblocks->jb_segs))
 
4353
                jblocks->jb_needseg = 1;
 
4354
}
 
4355
 
 
4356
/*
 
4357
 * Release one reference to a jseg and free it if the count reaches 0.  This
 
4358
 * should eventually reclaim journal space as well.
 
4359
 */
 
4360
static void
 
4361
rele_jseg(jseg)
 
4362
        struct jseg *jseg;
 
4363
{
 
4364
 
 
4365
        KASSERT(jseg->js_refs > 0,
 
4366
            ("free_jseg: Invalid refcnt %d", jseg->js_refs));
 
4367
        if (--jseg->js_refs != 0)
 
4368
                return;
 
4369
        free_jsegs(jseg->js_jblocks);
 
4370
}
 
4371
 
 
4372
/*
 
4373
 * Release a jsegdep and decrement the jseg count.
 
4374
 */
 
4375
static void
 
4376
free_jsegdep(jsegdep)
 
4377
        struct jsegdep *jsegdep;
 
4378
{
 
4379
 
 
4380
        if (jsegdep->jd_seg)
 
4381
                rele_jseg(jsegdep->jd_seg);
 
4382
        WORKITEM_FREE(jsegdep, D_JSEGDEP);
 
4383
}
 
4384
 
 
4385
/*
 
4386
 * Wait for a journal item to make it to disk.  Initiate journal processing
 
4387
 * if required.
 
4388
 */
 
4389
static int
 
4390
jwait(wk, waitfor)
 
4391
        struct worklist *wk;
 
4392
        int waitfor;
 
4393
{
 
4394
 
 
4395
        /*
 
4396
         * Blocking journal waits cause slow synchronous behavior.  Record
 
4397
         * stats on the frequency of these blocking operations.
 
4398
         */
 
4399
        if (waitfor == MNT_WAIT) {
 
4400
                stat_journal_wait++;
 
4401
                switch (wk->wk_type) {
 
4402
                case D_JREMREF:
 
4403
                case D_JMVREF:
 
4404
                        stat_jwait_filepage++;
 
4405
                        break;
 
4406
                case D_JTRUNC:
 
4407
                case D_JFREEBLK:
 
4408
                        stat_jwait_freeblks++;
 
4409
                        break;
 
4410
                case D_JNEWBLK:
 
4411
                        stat_jwait_newblk++;
 
4412
                        break;
 
4413
                case D_JADDREF:
 
4414
                        stat_jwait_inode++;
 
4415
                        break;
 
4416
                default:
 
4417
                        break;
 
4418
                }
 
4419
        }
 
4420
        /*
 
4421
         * If IO has not started we process the journal.  We can't mark the
 
4422
         * worklist item as IOWAITING because we drop the lock while
 
4423
         * processing the journal and the worklist entry may be freed after
 
4424
         * this point.  The caller may call back in and re-issue the request.
 
4425
         */
 
4426
        if ((wk->wk_state & INPROGRESS) == 0) {
 
4427
                softdep_process_journal(wk->wk_mp, wk, waitfor);
 
4428
                if (waitfor != MNT_WAIT)
 
4429
                        return (EBUSY);
 
4430
                return (0);
 
4431
        }
 
4432
        if (waitfor != MNT_WAIT)
 
4433
                return (EBUSY);
 
4434
        wait_worklist(wk, "jwait");
 
4435
        return (0);
 
4436
}
 
4437
 
 
4438
/*
 
4439
 * Lookup an inodedep based on an inode pointer and set the nlinkdelta as
 
4440
 * appropriate.  This is a convenience function to reduce duplicate code
 
4441
 * for the setup and revert functions below.
 
4442
 */
 
4443
static struct inodedep *
 
4444
inodedep_lookup_ip(ip)
 
4445
        struct inode *ip;
 
4446
{
 
4447
        struct inodedep *inodedep;
 
4448
        int dflags;
 
4449
 
 
4450
        KASSERT(ip->i_nlink >= ip->i_effnlink,
 
4451
            ("inodedep_lookup_ip: bad delta"));
 
4452
        dflags = DEPALLOC;
 
4453
        if (IS_SNAPSHOT(ip))
 
4454
                dflags |= NODELAY;
 
4455
        (void) inodedep_lookup(UFSTOVFS(ip->i_ump), ip->i_number, dflags,
 
4456
            &inodedep);
 
4457
        inodedep->id_nlinkdelta = ip->i_nlink - ip->i_effnlink;
 
4458
        KASSERT((inodedep->id_state & UNLINKED) == 0, ("inode unlinked"));
 
4459
 
 
4460
        return (inodedep);
 
4461
}
 
4462
 
 
4463
/*
 
4464
 * Called prior to creating a new inode and linking it to a directory.  The
 
4465
 * jaddref structure must already be allocated by softdep_setup_inomapdep
 
4466
 * and it is discovered here so we can initialize the mode and update
 
4467
 * nlinkdelta.
 
4468
 */
 
4469
void
 
4470
softdep_setup_create(dp, ip)
 
4471
        struct inode *dp;
 
4472
        struct inode *ip;
 
4473
{
 
4474
        struct inodedep *inodedep;
 
4475
        struct jaddref *jaddref;
 
4476
        struct vnode *dvp;
 
4477
 
 
4478
        KASSERT(ip->i_nlink == 1,
 
4479
            ("softdep_setup_create: Invalid link count."));
 
4480
        dvp = ITOV(dp);
 
4481
        ACQUIRE_LOCK(&lk);
 
4482
        inodedep = inodedep_lookup_ip(ip);
 
4483
        if (DOINGSUJ(dvp)) {
 
4484
                jaddref = (struct jaddref *)TAILQ_LAST(&inodedep->id_inoreflst,
 
4485
                    inoreflst);
 
4486
                KASSERT(jaddref != NULL && jaddref->ja_parent == dp->i_number,
 
4487
                    ("softdep_setup_create: No addref structure present."));
 
4488
        }
 
4489
        softdep_prelink(dvp, NULL);
 
4490
        FREE_LOCK(&lk);
 
4491
}
 
4492
 
 
4493
/*
 
4494
 * Create a jaddref structure to track the addition of a DOTDOT link when
 
4495
 * we are reparenting an inode as part of a rename.  This jaddref will be
 
4496
 * found by softdep_setup_directory_change.  Adjusts nlinkdelta for
 
4497
 * non-journaling softdep.
 
4498
 */
 
4499
void
 
4500
softdep_setup_dotdot_link(dp, ip)
 
4501
        struct inode *dp;
 
4502
        struct inode *ip;
 
4503
{
 
4504
        struct inodedep *inodedep;
 
4505
        struct jaddref *jaddref;
 
4506
        struct vnode *dvp;
 
4507
        struct vnode *vp;
 
4508
 
 
4509
        dvp = ITOV(dp);
 
4510
        vp = ITOV(ip);
 
4511
        jaddref = NULL;
 
4512
        /*
 
4513
         * We don't set MKDIR_PARENT as this is not tied to a mkdir and
 
4514
         * is used as a normal link would be.
 
4515
         */
 
4516
        if (DOINGSUJ(dvp))
 
4517
                jaddref = newjaddref(ip, dp->i_number, DOTDOT_OFFSET,
 
4518
                    dp->i_effnlink - 1, dp->i_mode);
 
4519
        ACQUIRE_LOCK(&lk);
 
4520
        inodedep = inodedep_lookup_ip(dp);
 
4521
        if (jaddref)
 
4522
                TAILQ_INSERT_TAIL(&inodedep->id_inoreflst, &jaddref->ja_ref,
 
4523
                    if_deps);
 
4524
        softdep_prelink(dvp, ITOV(ip));
 
4525
        FREE_LOCK(&lk);
 
4526
}
 
4527
 
 
4528
/*
 
4529
 * Create a jaddref structure to track a new link to an inode.  The directory
 
4530
 * offset is not known until softdep_setup_directory_add or
 
4531
 * softdep_setup_directory_change.  Adjusts nlinkdelta for non-journaling
 
4532
 * softdep.
 
4533
 */
 
4534
void
 
4535
softdep_setup_link(dp, ip)
 
4536
        struct inode *dp;
 
4537
        struct inode *ip;
 
4538
{
 
4539
        struct inodedep *inodedep;
 
4540
        struct jaddref *jaddref;
 
4541
        struct vnode *dvp;
 
4542
 
 
4543
        dvp = ITOV(dp);
 
4544
        jaddref = NULL;
 
4545
        if (DOINGSUJ(dvp))
 
4546
                jaddref = newjaddref(dp, ip->i_number, 0, ip->i_effnlink - 1,
 
4547
                    ip->i_mode);
 
4548
        ACQUIRE_LOCK(&lk);
 
4549
        inodedep = inodedep_lookup_ip(ip);
 
4550
        if (jaddref)
 
4551
                TAILQ_INSERT_TAIL(&inodedep->id_inoreflst, &jaddref->ja_ref,
 
4552
                    if_deps);
 
4553
        softdep_prelink(dvp, ITOV(ip));
 
4554
        FREE_LOCK(&lk);
 
4555
}
 
4556
 
 
4557
/*
 
4558
 * Called to create the jaddref structures to track . and .. references as
 
4559
 * well as lookup and further initialize the incomplete jaddref created
 
4560
 * by softdep_setup_inomapdep when the inode was allocated.  Adjusts
 
4561
 * nlinkdelta for non-journaling softdep.
 
4562
 */
 
4563
void
 
4564
softdep_setup_mkdir(dp, ip)
 
4565
        struct inode *dp;
 
4566
        struct inode *ip;
 
4567
{
 
4568
        struct inodedep *inodedep;
 
4569
        struct jaddref *dotdotaddref;
 
4570
        struct jaddref *dotaddref;
 
4571
        struct jaddref *jaddref;
 
4572
        struct vnode *dvp;
 
4573
 
 
4574
        dvp = ITOV(dp);
 
4575
        dotaddref = dotdotaddref = NULL;
 
4576
        if (DOINGSUJ(dvp)) {
 
4577
                dotaddref = newjaddref(ip, ip->i_number, DOT_OFFSET, 1,
 
4578
                    ip->i_mode);
 
4579
                dotaddref->ja_state |= MKDIR_BODY;
 
4580
                dotdotaddref = newjaddref(ip, dp->i_number, DOTDOT_OFFSET,
 
4581
                    dp->i_effnlink - 1, dp->i_mode);
 
4582
                dotdotaddref->ja_state |= MKDIR_PARENT;
 
4583
        }
 
4584
        ACQUIRE_LOCK(&lk);
 
4585
        inodedep = inodedep_lookup_ip(ip);
 
4586
        if (DOINGSUJ(dvp)) {
 
4587
                jaddref = (struct jaddref *)TAILQ_LAST(&inodedep->id_inoreflst,
 
4588
                    inoreflst);
 
4589
                KASSERT(jaddref != NULL,
 
4590
                    ("softdep_setup_mkdir: No addref structure present."));
 
4591
                KASSERT(jaddref->ja_parent == dp->i_number, 
 
4592
                    ("softdep_setup_mkdir: bad parent %d",
 
4593
                    jaddref->ja_parent));
 
4594
                TAILQ_INSERT_BEFORE(&jaddref->ja_ref, &dotaddref->ja_ref,
 
4595
                    if_deps);
 
4596
        }
 
4597
        inodedep = inodedep_lookup_ip(dp);
 
4598
        if (DOINGSUJ(dvp))
 
4599
                TAILQ_INSERT_TAIL(&inodedep->id_inoreflst,
 
4600
                    &dotdotaddref->ja_ref, if_deps);
 
4601
        softdep_prelink(ITOV(dp), NULL);
 
4602
        FREE_LOCK(&lk);
 
4603
}
 
4604
 
 
4605
/*
 
4606
 * Called to track nlinkdelta of the inode and parent directories prior to
 
4607
 * unlinking a directory.
 
4608
 */
 
4609
void
 
4610
softdep_setup_rmdir(dp, ip)
 
4611
        struct inode *dp;
 
4612
        struct inode *ip;
 
4613
{
 
4614
        struct vnode *dvp;
 
4615
 
 
4616
        dvp = ITOV(dp);
 
4617
        ACQUIRE_LOCK(&lk);
 
4618
        (void) inodedep_lookup_ip(ip);
 
4619
        (void) inodedep_lookup_ip(dp);
 
4620
        softdep_prelink(dvp, ITOV(ip));
 
4621
        FREE_LOCK(&lk);
 
4622
}
 
4623
 
 
4624
/*
 
4625
 * Called to track nlinkdelta of the inode and parent directories prior to
 
4626
 * unlink.
 
4627
 */
 
4628
void
 
4629
softdep_setup_unlink(dp, ip)
 
4630
        struct inode *dp;
 
4631
        struct inode *ip;
 
4632
{
 
4633
        struct vnode *dvp;
 
4634
 
 
4635
        dvp = ITOV(dp);
 
4636
        ACQUIRE_LOCK(&lk);
 
4637
        (void) inodedep_lookup_ip(ip);
 
4638
        (void) inodedep_lookup_ip(dp);
 
4639
        softdep_prelink(dvp, ITOV(ip));
 
4640
        FREE_LOCK(&lk);
 
4641
}
 
4642
 
 
4643
/*
 
4644
 * Called to release the journal structures created by a failed non-directory
 
4645
 * creation.  Adjusts nlinkdelta for non-journaling softdep.
 
4646
 */
 
4647
void
 
4648
softdep_revert_create(dp, ip)
 
4649
        struct inode *dp;
 
4650
        struct inode *ip;
 
4651
{
 
4652
        struct inodedep *inodedep;
 
4653
        struct jaddref *jaddref;
 
4654
        struct vnode *dvp;
 
4655
 
 
4656
        dvp = ITOV(dp);
 
4657
        ACQUIRE_LOCK(&lk);
 
4658
        inodedep = inodedep_lookup_ip(ip);
 
4659
        if (DOINGSUJ(dvp)) {
 
4660
                jaddref = (struct jaddref *)TAILQ_LAST(&inodedep->id_inoreflst,
 
4661
                    inoreflst);
 
4662
                KASSERT(jaddref->ja_parent == dp->i_number,
 
4663
                    ("softdep_revert_create: addref parent mismatch"));
 
4664
                cancel_jaddref(jaddref, inodedep, &inodedep->id_inowait);
 
4665
        }
 
4666
        FREE_LOCK(&lk);
 
4667
}
 
4668
 
 
4669
/*
 
4670
 * Called to release the journal structures created by a failed dotdot link
 
4671
 * creation.  Adjusts nlinkdelta for non-journaling softdep.
 
4672
 */
 
4673
void
 
4674
softdep_revert_dotdot_link(dp, ip)
 
4675
        struct inode *dp;
 
4676
        struct inode *ip;
 
4677
{
 
4678
        struct inodedep *inodedep;
 
4679
        struct jaddref *jaddref;
 
4680
        struct vnode *dvp;
 
4681
 
 
4682
        dvp = ITOV(dp);
 
4683
        ACQUIRE_LOCK(&lk);
 
4684
        inodedep = inodedep_lookup_ip(dp);
 
4685
        if (DOINGSUJ(dvp)) {
 
4686
                jaddref = (struct jaddref *)TAILQ_LAST(&inodedep->id_inoreflst,
 
4687
                    inoreflst);
 
4688
                KASSERT(jaddref->ja_parent == ip->i_number,
 
4689
                    ("softdep_revert_dotdot_link: addref parent mismatch"));
 
4690
                cancel_jaddref(jaddref, inodedep, &inodedep->id_inowait);
 
4691
        }
 
4692
        FREE_LOCK(&lk);
 
4693
}
 
4694
 
 
4695
/*
 
4696
 * Called to release the journal structures created by a failed link
 
4697
 * addition.  Adjusts nlinkdelta for non-journaling softdep.
 
4698
 */
 
4699
void
 
4700
softdep_revert_link(dp, ip)
 
4701
        struct inode *dp;
 
4702
        struct inode *ip;
 
4703
{
 
4704
        struct inodedep *inodedep;
 
4705
        struct jaddref *jaddref;
 
4706
        struct vnode *dvp;
 
4707
 
 
4708
        dvp = ITOV(dp);
 
4709
        ACQUIRE_LOCK(&lk);
 
4710
        inodedep = inodedep_lookup_ip(ip);
 
4711
        if (DOINGSUJ(dvp)) {
 
4712
                jaddref = (struct jaddref *)TAILQ_LAST(&inodedep->id_inoreflst,
 
4713
                    inoreflst);
 
4714
                KASSERT(jaddref->ja_parent == dp->i_number,
 
4715
                    ("softdep_revert_link: addref parent mismatch"));
 
4716
                cancel_jaddref(jaddref, inodedep, &inodedep->id_inowait);
 
4717
        }
 
4718
        FREE_LOCK(&lk);
 
4719
}
 
4720
 
 
4721
/*
 
4722
 * Called to release the journal structures created by a failed mkdir
 
4723
 * attempt.  Adjusts nlinkdelta for non-journaling softdep.
 
4724
 */
 
4725
void
 
4726
softdep_revert_mkdir(dp, ip)
 
4727
        struct inode *dp;
 
4728
        struct inode *ip;
 
4729
{
 
4730
        struct inodedep *inodedep;
 
4731
        struct jaddref *jaddref;
 
4732
        struct jaddref *dotaddref;
 
4733
        struct vnode *dvp;
 
4734
 
 
4735
        dvp = ITOV(dp);
 
4736
 
 
4737
        ACQUIRE_LOCK(&lk);
 
4738
        inodedep = inodedep_lookup_ip(dp);
 
4739
        if (DOINGSUJ(dvp)) {
 
4740
                jaddref = (struct jaddref *)TAILQ_LAST(&inodedep->id_inoreflst,
 
4741
                    inoreflst);
 
4742
                KASSERT(jaddref->ja_parent == ip->i_number,
 
4743
                    ("softdep_revert_mkdir: dotdot addref parent mismatch"));
 
4744
                cancel_jaddref(jaddref, inodedep, &inodedep->id_inowait);
 
4745
        }
 
4746
        inodedep = inodedep_lookup_ip(ip);
 
4747
        if (DOINGSUJ(dvp)) {
 
4748
                jaddref = (struct jaddref *)TAILQ_LAST(&inodedep->id_inoreflst,
 
4749
                    inoreflst);
 
4750
                KASSERT(jaddref->ja_parent == dp->i_number,
 
4751
                    ("softdep_revert_mkdir: addref parent mismatch"));
 
4752
                dotaddref = (struct jaddref *)TAILQ_PREV(&jaddref->ja_ref,
 
4753
                    inoreflst, if_deps);
 
4754
                cancel_jaddref(jaddref, inodedep, &inodedep->id_inowait);
 
4755
                KASSERT(dotaddref->ja_parent == ip->i_number,
 
4756
                    ("softdep_revert_mkdir: dot addref parent mismatch"));
 
4757
                cancel_jaddref(dotaddref, inodedep, &inodedep->id_inowait);
 
4758
        }
 
4759
        FREE_LOCK(&lk);
 
4760
}
 
4761
 
 
4762
/* 
 
4763
 * Called to correct nlinkdelta after a failed rmdir.
 
4764
 */
 
4765
void
 
4766
softdep_revert_rmdir(dp, ip)
 
4767
        struct inode *dp;
 
4768
        struct inode *ip;
 
4769
{
 
4770
 
 
4771
        ACQUIRE_LOCK(&lk);
 
4772
        (void) inodedep_lookup_ip(ip);
 
4773
        (void) inodedep_lookup_ip(dp);
 
4774
        FREE_LOCK(&lk);
 
4775
}
 
4776
 
1496
4777
/*
1497
4778
 * Protecting the freemaps (or bitmaps).
1498
4779
 * 
1529
4810
 * Called just after updating the cylinder group block to allocate an inode.
1530
4811
 */
1531
4812
void
1532
 
softdep_setup_inomapdep(bp, ip, newinum)
 
4813
softdep_setup_inomapdep(bp, ip, newinum, mode)
1533
4814
        struct buf *bp;         /* buffer for cylgroup block with inode map */
1534
4815
        struct inode *ip;       /* inode related to allocation */
1535
4816
        ino_t newinum;          /* new inode number being allocated */
 
4817
        int mode;
1536
4818
{
1537
4819
        struct inodedep *inodedep;
1538
4820
        struct bmsafemap *bmsafemap;
 
4821
        struct jaddref *jaddref;
 
4822
        struct mount *mp;
 
4823
        struct fs *fs;
 
4824
 
 
4825
        mp = UFSTOVFS(ip->i_ump);
 
4826
        fs = ip->i_ump->um_fs;
 
4827
        jaddref = NULL;
 
4828
 
 
4829
        /*
 
4830
         * Allocate the journal reference add structure so that the bitmap
 
4831
         * can be dependent on it.
 
4832
         */
 
4833
        if (MOUNTEDSUJ(mp)) {
 
4834
                jaddref = newjaddref(ip, newinum, 0, 0, mode);
 
4835
                jaddref->ja_state |= NEWBLOCK;
 
4836
        }
1539
4837
 
1540
4838
        /*
1541
4839
         * Create a dependency for the newly allocated inode.
1542
4840
         * Panic if it already exists as something is seriously wrong.
1543
4841
         * Otherwise add it to the dependency list for the buffer holding
1544
4842
         * the cylinder group map from which it was allocated.
 
4843
         *
 
4844
         * We have to preallocate a bmsafemap entry in case it is needed
 
4845
         * in bmsafemap_lookup since once we allocate the inodedep, we
 
4846
         * have to finish initializing it before we can FREE_LOCK().
 
4847
         * By preallocating, we avoid FREE_LOCK() while doing a malloc
 
4848
         * in bmsafemap_lookup. We cannot call bmsafemap_lookup before
 
4849
         * creating the inodedep as it can be freed during the time
 
4850
         * that we FREE_LOCK() while allocating the inodedep. We must
 
4851
         * call workitem_alloc() before entering the locked section as
 
4852
         * it also acquires the lock and we must avoid trying doing so
 
4853
         * recursively.
1545
4854
         */
 
4855
        bmsafemap = malloc(sizeof(struct bmsafemap),
 
4856
            M_BMSAFEMAP, M_SOFTDEP_FLAGS);
 
4857
        workitem_alloc(&bmsafemap->sm_list, D_BMSAFEMAP, mp);
1546
4858
        ACQUIRE_LOCK(&lk);
1547
 
        if ((inodedep_lookup(UFSTOVFS(ip->i_ump), newinum, DEPALLOC|NODELAY,
1548
 
            &inodedep)))
1549
 
                panic("softdep_setup_inomapdep: dependency for new inode "
1550
 
                    "already exists");
1551
 
        inodedep->id_buf = bp;
 
4859
        if ((inodedep_lookup(mp, newinum, DEPALLOC | NODELAY, &inodedep)))
 
4860
                panic("softdep_setup_inomapdep: dependency %p for new"
 
4861
                    "inode already exists", inodedep);
 
4862
        bmsafemap = bmsafemap_lookup(mp, bp, ino_to_cg(fs, newinum), bmsafemap);
 
4863
        if (jaddref) {
 
4864
                LIST_INSERT_HEAD(&bmsafemap->sm_jaddrefhd, jaddref, ja_bmdeps);
 
4865
                TAILQ_INSERT_TAIL(&inodedep->id_inoreflst, &jaddref->ja_ref,
 
4866
                    if_deps);
 
4867
        } else {
 
4868
                inodedep->id_state |= ONDEPLIST;
 
4869
                LIST_INSERT_HEAD(&bmsafemap->sm_inodedephd, inodedep, id_deps);
 
4870
        }
 
4871
        inodedep->id_bmsafemap = bmsafemap;
1552
4872
        inodedep->id_state &= ~DEPCOMPLETE;
1553
 
        bmsafemap = bmsafemap_lookup(inodedep->id_list.wk_mp, bp);
1554
 
        LIST_INSERT_HEAD(&bmsafemap->sm_inodedephd, inodedep, id_deps);
1555
4873
        FREE_LOCK(&lk);
1556
4874
}
1557
4875
 
1560
4878
 * allocate block or fragment.
1561
4879
 */
1562
4880
void
1563
 
softdep_setup_blkmapdep(bp, mp, newblkno)
 
4881
softdep_setup_blkmapdep(bp, mp, newblkno, frags, oldfrags)
1564
4882
        struct buf *bp;         /* buffer for cylgroup block with block map */
1565
4883
        struct mount *mp;       /* filesystem doing allocation */
1566
4884
        ufs2_daddr_t newblkno;  /* number of newly allocated block */
 
4885
        int frags;              /* Number of fragments. */
 
4886
        int oldfrags;           /* Previous number of fragments for extend. */
1567
4887
{
1568
4888
        struct newblk *newblk;
1569
4889
        struct bmsafemap *bmsafemap;
 
4890
        struct jnewblk *jnewblk;
1570
4891
        struct fs *fs;
1571
4892
 
1572
4893
        fs = VFSTOUFS(mp)->um_fs;
 
4894
        jnewblk = NULL;
1573
4895
        /*
1574
4896
         * Create a dependency for the newly allocated block.
1575
4897
         * Add it to the dependency list for the buffer holding
1576
4898
         * the cylinder group map from which it was allocated.
1577
4899
         */
 
4900
        if (MOUNTEDSUJ(mp)) {
 
4901
                jnewblk = malloc(sizeof(*jnewblk), M_JNEWBLK, M_SOFTDEP_FLAGS);
 
4902
                workitem_alloc(&jnewblk->jn_list, D_JNEWBLK, mp);
 
4903
                jnewblk->jn_jsegdep = newjsegdep(&jnewblk->jn_list);
 
4904
                jnewblk->jn_state = ATTACHED;
 
4905
                jnewblk->jn_blkno = newblkno;
 
4906
                jnewblk->jn_frags = frags;
 
4907
                jnewblk->jn_oldfrags = oldfrags;
 
4908
#ifdef SUJ_DEBUG
 
4909
                {
 
4910
                        struct cg *cgp;
 
4911
                        uint8_t *blksfree;
 
4912
                        long bno;
 
4913
                        int i;
 
4914
        
 
4915
                        cgp = (struct cg *)bp->b_data;
 
4916
                        blksfree = cg_blksfree(cgp);
 
4917
                        bno = dtogd(fs, jnewblk->jn_blkno);
 
4918
                        for (i = jnewblk->jn_oldfrags; i < jnewblk->jn_frags;
 
4919
                            i++) {
 
4920
                                if (isset(blksfree, bno + i))
 
4921
                                        panic("softdep_setup_blkmapdep: "
 
4922
                                            "free fragment %d from %d-%d "
 
4923
                                            "state 0x%X dep %p", i,
 
4924
                                            jnewblk->jn_oldfrags,
 
4925
                                            jnewblk->jn_frags,
 
4926
                                            jnewblk->jn_state,
 
4927
                                            jnewblk->jn_dep);
 
4928
                        }
 
4929
                }
 
4930
#endif
 
4931
        }
 
4932
 
 
4933
        CTR3(KTR_SUJ,
 
4934
            "softdep_setup_blkmapdep: blkno %jd frags %d oldfrags %d",
 
4935
            newblkno, frags, oldfrags);
1578
4936
        ACQUIRE_LOCK(&lk);
1579
 
        if (newblk_lookup(fs, newblkno, DEPALLOC, &newblk) != 0)
 
4937
        if (newblk_lookup(mp, newblkno, DEPALLOC, &newblk) != 0)
1580
4938
                panic("softdep_setup_blkmapdep: found block");
1581
 
        newblk->nb_bmsafemap = bmsafemap = bmsafemap_lookup(mp, bp);
1582
 
        LIST_INSERT_HEAD(&bmsafemap->sm_newblkhd, newblk, nb_deps);
 
4939
        newblk->nb_bmsafemap = bmsafemap = bmsafemap_lookup(mp, bp,
 
4940
            dtog(fs, newblkno), NULL);
 
4941
        if (jnewblk) {
 
4942
                jnewblk->jn_dep = (struct worklist *)newblk;
 
4943
                LIST_INSERT_HEAD(&bmsafemap->sm_jnewblkhd, jnewblk, jn_deps);
 
4944
        } else {
 
4945
                newblk->nb_state |= ONDEPLIST;
 
4946
                LIST_INSERT_HEAD(&bmsafemap->sm_newblkhd, newblk, nb_deps);
 
4947
        }
 
4948
        newblk->nb_bmsafemap = bmsafemap;
 
4949
        newblk->nb_jnewblk = jnewblk;
1583
4950
        FREE_LOCK(&lk);
1584
4951
}
1585
4952
 
 
4953
#define BMSAFEMAP_HASH(fs, cg) \
 
4954
      (&bmsafemap_hashtbl[((((register_t)(fs)) >> 13) + (cg)) & bmsafemap_hash])
 
4955
 
 
4956
static int
 
4957
bmsafemap_find(bmsafemaphd, mp, cg, bmsafemapp)
 
4958
        struct bmsafemap_hashhead *bmsafemaphd;
 
4959
        struct mount *mp;
 
4960
        int cg;
 
4961
        struct bmsafemap **bmsafemapp;
 
4962
{
 
4963
        struct bmsafemap *bmsafemap;
 
4964
 
 
4965
        LIST_FOREACH(bmsafemap, bmsafemaphd, sm_hash)
 
4966
                if (bmsafemap->sm_list.wk_mp == mp && bmsafemap->sm_cg == cg)
 
4967
                        break;
 
4968
        if (bmsafemap) {
 
4969
                *bmsafemapp = bmsafemap;
 
4970
                return (1);
 
4971
        }
 
4972
        *bmsafemapp = NULL;
 
4973
 
 
4974
        return (0);
 
4975
}
 
4976
 
1586
4977
/*
1587
4978
 * Find the bmsafemap associated with a cylinder group buffer.
1588
4979
 * If none exists, create one. The buffer must be locked when
1589
4980
 * this routine is called and this routine must be called with
1590
 
 * splbio interrupts blocked.
 
4981
 * the softdep lock held. To avoid giving up the lock while
 
4982
 * allocating a new bmsafemap, a preallocated bmsafemap may be
 
4983
 * provided. If it is provided but not needed, it is freed.
1591
4984
 */
1592
4985
static struct bmsafemap *
1593
 
bmsafemap_lookup(mp, bp)
 
4986
bmsafemap_lookup(mp, bp, cg, newbmsafemap)
1594
4987
        struct mount *mp;
1595
4988
        struct buf *bp;
 
4989
        int cg;
 
4990
        struct bmsafemap *newbmsafemap;
1596
4991
{
1597
 
        struct bmsafemap *bmsafemap;
 
4992
        struct bmsafemap_hashhead *bmsafemaphd;
 
4993
        struct bmsafemap *bmsafemap, *collision;
1598
4994
        struct worklist *wk;
 
4995
        struct fs *fs;
1599
4996
 
1600
4997
        mtx_assert(&lk, MA_OWNED);
1601
 
        LIST_FOREACH(wk, &bp->b_dep, wk_list)
1602
 
                if (wk->wk_type == D_BMSAFEMAP)
 
4998
        KASSERT(bp != NULL, ("bmsafemap_lookup: missing buffer"));
 
4999
        LIST_FOREACH(wk, &bp->b_dep, wk_list) {
 
5000
                if (wk->wk_type == D_BMSAFEMAP) {
 
5001
                        if (newbmsafemap)
 
5002
                                WORKITEM_FREE(newbmsafemap, D_BMSAFEMAP);
1603
5003
                        return (WK_BMSAFEMAP(wk));
1604
 
        FREE_LOCK(&lk);
1605
 
        bmsafemap = malloc(sizeof(struct bmsafemap),
1606
 
                M_BMSAFEMAP, M_SOFTDEP_FLAGS);
1607
 
        workitem_alloc(&bmsafemap->sm_list, D_BMSAFEMAP, mp);
 
5004
                }
 
5005
        }
 
5006
        fs = VFSTOUFS(mp)->um_fs;
 
5007
        bmsafemaphd = BMSAFEMAP_HASH(fs, cg);
 
5008
        if (bmsafemap_find(bmsafemaphd, mp, cg, &bmsafemap) == 1) {
 
5009
                if (newbmsafemap)
 
5010
                        WORKITEM_FREE(newbmsafemap, D_BMSAFEMAP);
 
5011
                return (bmsafemap);
 
5012
        }
 
5013
        if (newbmsafemap) {
 
5014
                bmsafemap = newbmsafemap;
 
5015
        } else {
 
5016
                FREE_LOCK(&lk);
 
5017
                bmsafemap = malloc(sizeof(struct bmsafemap),
 
5018
                        M_BMSAFEMAP, M_SOFTDEP_FLAGS);
 
5019
                workitem_alloc(&bmsafemap->sm_list, D_BMSAFEMAP, mp);
 
5020
                ACQUIRE_LOCK(&lk);
 
5021
        }
1608
5022
        bmsafemap->sm_buf = bp;
1609
 
        LIST_INIT(&bmsafemap->sm_allocdirecthd);
1610
 
        LIST_INIT(&bmsafemap->sm_allocindirhd);
1611
5023
        LIST_INIT(&bmsafemap->sm_inodedephd);
 
5024
        LIST_INIT(&bmsafemap->sm_inodedepwr);
1612
5025
        LIST_INIT(&bmsafemap->sm_newblkhd);
1613
 
        ACQUIRE_LOCK(&lk);
 
5026
        LIST_INIT(&bmsafemap->sm_newblkwr);
 
5027
        LIST_INIT(&bmsafemap->sm_jaddrefhd);
 
5028
        LIST_INIT(&bmsafemap->sm_jnewblkhd);
 
5029
        LIST_INIT(&bmsafemap->sm_freehd);
 
5030
        LIST_INIT(&bmsafemap->sm_freewr);
 
5031
        if (bmsafemap_find(bmsafemaphd, mp, cg, &collision) == 1) {
 
5032
                WORKITEM_FREE(bmsafemap, D_BMSAFEMAP);
 
5033
                return (collision);
 
5034
        }
 
5035
        bmsafemap->sm_cg = cg;
 
5036
        LIST_INSERT_HEAD(bmsafemaphd, bmsafemap, sm_hash);
 
5037
        LIST_INSERT_HEAD(&VFSTOUFS(mp)->softdep_dirtycg, bmsafemap, sm_next);
1614
5038
        WORKLIST_INSERT(&bp->b_dep, &bmsafemap->sm_list);
1615
5039
        return (bmsafemap);
1616
5040
}
1645
5069
 * unreferenced fragments.
1646
5070
 */ 
1647
5071
void 
1648
 
softdep_setup_allocdirect(ip, lbn, newblkno, oldblkno, newsize, oldsize, bp)
 
5072
softdep_setup_allocdirect(ip, off, newblkno, oldblkno, newsize, oldsize, bp)
1649
5073
        struct inode *ip;       /* inode to which block is being added */
1650
 
        ufs_lbn_t lbn;          /* block pointer within inode */
 
5074
        ufs_lbn_t off;          /* block pointer within inode */
1651
5075
        ufs2_daddr_t newblkno;  /* disk block number being added */
1652
5076
        ufs2_daddr_t oldblkno;  /* previous block number, 0 unless frag */
1653
5077
        long newsize;           /* size of new block */
1656
5080
{
1657
5081
        struct allocdirect *adp, *oldadp;
1658
5082
        struct allocdirectlst *adphead;
1659
 
        struct bmsafemap *bmsafemap;
 
5083
        struct freefrag *freefrag;
1660
5084
        struct inodedep *inodedep;
1661
5085
        struct pagedep *pagedep;
 
5086
        struct jnewblk *jnewblk;
1662
5087
        struct newblk *newblk;
1663
5088
        struct mount *mp;
 
5089
        ufs_lbn_t lbn;
1664
5090
 
 
5091
        lbn = bp->b_lblkno;
1665
5092
        mp = UFSTOVFS(ip->i_ump);
1666
 
        adp = malloc(sizeof(struct allocdirect),
1667
 
                M_ALLOCDIRECT, M_SOFTDEP_FLAGS|M_ZERO);
1668
 
        workitem_alloc(&adp->ad_list, D_ALLOCDIRECT, mp);
1669
 
        adp->ad_lbn = lbn;
1670
 
        adp->ad_newblkno = newblkno;
1671
 
        adp->ad_oldblkno = oldblkno;
1672
 
        adp->ad_newsize = newsize;
1673
 
        adp->ad_oldsize = oldsize;
1674
 
        adp->ad_state = ATTACHED;
1675
 
        LIST_INIT(&adp->ad_newdirblk);
1676
 
        if (newblkno == oldblkno)
1677
 
                adp->ad_freefrag = NULL;
 
5093
        if (oldblkno && oldblkno != newblkno)
 
5094
                freefrag = newfreefrag(ip, oldblkno, oldsize, lbn);
1678
5095
        else
1679
 
                adp->ad_freefrag = newfreefrag(ip, oldblkno, oldsize);
 
5096
                freefrag = NULL;
1680
5097
 
 
5098
        CTR6(KTR_SUJ,
 
5099
            "softdep_setup_allocdirect: ino %d blkno %jd oldblkno %jd "
 
5100
            "off %jd newsize %ld oldsize %d",
 
5101
            ip->i_number, newblkno, oldblkno, off, newsize, oldsize);
1681
5102
        ACQUIRE_LOCK(&lk);
1682
 
        if (lbn >= NDADDR) {
 
5103
        if (off >= NDADDR) {
 
5104
                if (lbn > 0)
 
5105
                        panic("softdep_setup_allocdirect: bad lbn %jd, off %jd",
 
5106
                            lbn, off);
1683
5107
                /* allocating an indirect block */
1684
5108
                if (oldblkno != 0)
1685
5109
                        panic("softdep_setup_allocdirect: non-zero indir");
1686
5110
        } else {
 
5111
                if (off != lbn)
 
5112
                        panic("softdep_setup_allocdirect: lbn %jd != off %jd",
 
5113
                            lbn, off);
1687
5114
                /*
1688
5115
                 * Allocating a direct block.
1689
5116
                 *
1691
5118
                 * allocate an associated pagedep to track additions and
1692
5119
                 * deletions.
1693
5120
                 */
1694
 
                if ((ip->i_mode & IFMT) == IFDIR &&
1695
 
                    pagedep_lookup(ip, lbn, DEPALLOC, &pagedep) == 0)
1696
 
                        WORKLIST_INSERT(&bp->b_dep, &pagedep->pd_list);
 
5121
                if ((ip->i_mode & IFMT) == IFDIR)
 
5122
                        pagedep_lookup(mp, bp, ip->i_number, off, DEPALLOC,
 
5123
                            &pagedep);
1697
5124
        }
1698
 
        if (newblk_lookup(ip->i_fs, newblkno, 0, &newblk) == 0)
 
5125
        if (newblk_lookup(mp, newblkno, 0, &newblk) == 0)
1699
5126
                panic("softdep_setup_allocdirect: lost block");
1700
 
        if (newblk->nb_state == DEPCOMPLETE) {
1701
 
                adp->ad_state |= DEPCOMPLETE;
1702
 
                adp->ad_buf = NULL;
1703
 
        } else {
1704
 
                bmsafemap = newblk->nb_bmsafemap;
1705
 
                adp->ad_buf = bmsafemap->sm_buf;
1706
 
                LIST_REMOVE(newblk, nb_deps);
1707
 
                LIST_INSERT_HEAD(&bmsafemap->sm_allocdirecthd, adp, ad_deps);
 
5127
        KASSERT(newblk->nb_list.wk_type == D_NEWBLK,
 
5128
            ("softdep_setup_allocdirect: newblk already initialized"));
 
5129
        /*
 
5130
         * Convert the newblk to an allocdirect.
 
5131
         */
 
5132
        newblk->nb_list.wk_type = D_ALLOCDIRECT;
 
5133
        adp = (struct allocdirect *)newblk;
 
5134
        newblk->nb_freefrag = freefrag;
 
5135
        adp->ad_offset = off;
 
5136
        adp->ad_oldblkno = oldblkno;
 
5137
        adp->ad_newsize = newsize;
 
5138
        adp->ad_oldsize = oldsize;
 
5139
 
 
5140
        /*
 
5141
         * Finish initializing the journal.
 
5142
         */
 
5143
        if ((jnewblk = newblk->nb_jnewblk) != NULL) {
 
5144
                jnewblk->jn_ino = ip->i_number;
 
5145
                jnewblk->jn_lbn = lbn;
 
5146
                add_to_journal(&jnewblk->jn_list);
1708
5147
        }
1709
 
        LIST_REMOVE(newblk, nb_hash);
1710
 
        free(newblk, M_NEWBLK);
1711
 
 
 
5148
        if (freefrag && freefrag->ff_jdep != NULL &&
 
5149
            freefrag->ff_jdep->wk_type == D_JFREEFRAG)
 
5150
                add_to_journal(freefrag->ff_jdep);
1712
5151
        inodedep_lookup(mp, ip->i_number, DEPALLOC | NODELAY, &inodedep);
1713
5152
        adp->ad_inodedep = inodedep;
1714
 
        WORKLIST_INSERT(&bp->b_dep, &adp->ad_list);
 
5153
 
 
5154
        WORKLIST_INSERT(&bp->b_dep, &newblk->nb_list);
1715
5155
        /*
1716
5156
         * The list of allocdirects must be kept in sorted and ascending
1717
5157
         * order so that the rollback routines can quickly determine the
1726
5166
         */
1727
5167
        adphead = &inodedep->id_newinoupdt;
1728
5168
        oldadp = TAILQ_LAST(adphead, allocdirectlst);
1729
 
        if (oldadp == NULL || oldadp->ad_lbn <= lbn) {
 
5169
        if (oldadp == NULL || oldadp->ad_offset <= off) {
1730
5170
                /* insert at end of list */
1731
5171
                TAILQ_INSERT_TAIL(adphead, adp, ad_next);
1732
 
                if (oldadp != NULL && oldadp->ad_lbn == lbn)
 
5172
                if (oldadp != NULL && oldadp->ad_offset == off)
1733
5173
                        allocdirect_merge(adphead, adp, oldadp);
1734
5174
                FREE_LOCK(&lk);
1735
5175
                return;
1736
5176
        }
1737
5177
        TAILQ_FOREACH(oldadp, adphead, ad_next) {
1738
 
                if (oldadp->ad_lbn >= lbn)
 
5178
                if (oldadp->ad_offset >= off)
1739
5179
                        break;
1740
5180
        }
1741
5181
        if (oldadp == NULL)
1742
5182
                panic("softdep_setup_allocdirect: lost entry");
1743
5183
        /* insert in middle of list */
1744
5184
        TAILQ_INSERT_BEFORE(oldadp, adp, ad_next);
1745
 
        if (oldadp->ad_lbn == lbn)
 
5185
        if (oldadp->ad_offset == off)
1746
5186
                allocdirect_merge(adphead, adp, oldadp);
 
5187
 
1747
5188
        FREE_LOCK(&lk);
1748
5189
}
1749
5190
 
1750
5191
/*
 
5192
 * Merge a newer and older journal record to be stored either in a
 
5193
 * newblock or freefrag.  This handles aggregating journal records for
 
5194
 * fragment allocation into a second record as well as replacing a
 
5195
 * journal free with an aborted journal allocation.  A segment for the
 
5196
 * oldest record will be placed on wkhd if it has been written.  If not
 
5197
 * the segment for the newer record will suffice.
 
5198
 */
 
5199
static struct worklist *
 
5200
jnewblk_merge(new, old, wkhd)
 
5201
        struct worklist *new;
 
5202
        struct worklist *old;
 
5203
        struct workhead *wkhd;
 
5204
{
 
5205
        struct jnewblk *njnewblk;
 
5206
        struct jnewblk *jnewblk;
 
5207
 
 
5208
        /* Handle NULLs to simplify callers. */
 
5209
        if (new == NULL)
 
5210
                return (old);
 
5211
        if (old == NULL)
 
5212
                return (new);
 
5213
        /* Replace a jfreefrag with a jnewblk. */
 
5214
        if (new->wk_type == D_JFREEFRAG) {
 
5215
                if (WK_JNEWBLK(old)->jn_blkno != WK_JFREEFRAG(new)->fr_blkno)
 
5216
                        panic("jnewblk_merge: blkno mismatch: %p, %p",
 
5217
                            old, new);
 
5218
                cancel_jfreefrag(WK_JFREEFRAG(new));
 
5219
                return (old);
 
5220
        }
 
5221
        if (old->wk_type != D_JNEWBLK || new->wk_type != D_JNEWBLK)
 
5222
                panic("jnewblk_merge: Bad type: old %d new %d\n",
 
5223
                    old->wk_type, new->wk_type);
 
5224
        /*
 
5225
         * Handle merging of two jnewblk records that describe
 
5226
         * different sets of fragments in the same block.
 
5227
         */
 
5228
        jnewblk = WK_JNEWBLK(old);
 
5229
        njnewblk = WK_JNEWBLK(new);
 
5230
        if (jnewblk->jn_blkno != njnewblk->jn_blkno)
 
5231
                panic("jnewblk_merge: Merging disparate blocks.");
 
5232
        /*
 
5233
         * The record may be rolled back in the cg.
 
5234
         */
 
5235
        if (jnewblk->jn_state & UNDONE) {
 
5236
                jnewblk->jn_state &= ~UNDONE;
 
5237
                njnewblk->jn_state |= UNDONE;
 
5238
                njnewblk->jn_state &= ~ATTACHED;
 
5239
        }
 
5240
        /*
 
5241
         * We modify the newer addref and free the older so that if neither
 
5242
         * has been written the most up-to-date copy will be on disk.  If
 
5243
         * both have been written but rolled back we only temporarily need
 
5244
         * one of them to fix the bits when the cg write completes.
 
5245
         */
 
5246
        jnewblk->jn_state |= ATTACHED | COMPLETE;
 
5247
        njnewblk->jn_oldfrags = jnewblk->jn_oldfrags;
 
5248
        cancel_jnewblk(jnewblk, wkhd);
 
5249
        WORKLIST_REMOVE(&jnewblk->jn_list);
 
5250
        free_jnewblk(jnewblk);
 
5251
        return (new);
 
5252
}
 
5253
 
 
5254
/*
1751
5255
 * Replace an old allocdirect dependency with a newer one.
1752
5256
 * This routine must be called with splbio interrupts blocked.
1753
5257
 */
1759
5263
{
1760
5264
        struct worklist *wk;
1761
5265
        struct freefrag *freefrag;
1762
 
        struct newdirblk *newdirblk;
1763
5266
 
 
5267
        freefrag = NULL;
1764
5268
        mtx_assert(&lk, MA_OWNED);
1765
5269
        if (newadp->ad_oldblkno != oldadp->ad_newblkno ||
1766
5270
            newadp->ad_oldsize != oldadp->ad_newsize ||
1767
 
            newadp->ad_lbn >= NDADDR)
 
5271
            newadp->ad_offset >= NDADDR)
1768
5272
                panic("%s %jd != new %jd || old size %ld != new %ld",
1769
5273
                    "allocdirect_merge: old blkno",
1770
5274
                    (intmax_t)newadp->ad_oldblkno,
1779
5283
         * This action is done by swapping the freefrag dependencies.
1780
5284
         * The new dependency gains the old one's freefrag, and the
1781
5285
         * old one gets the new one and then immediately puts it on
1782
 
         * the worklist when it is freed by free_allocdirect. It is
 
5286
         * the worklist when it is freed by free_newblk. It is
1783
5287
         * not possible to do this swap when the old dependency had a
1784
5288
         * non-zero size but no previous fragment to free. This condition
1785
5289
         * arises when the new block is an extension of the old block.
1788
5292
         * the old dependency, so cannot legitimately be freed until the
1789
5293
         * conditions for the new dependency are fulfilled.
1790
5294
         */
 
5295
        freefrag = newadp->ad_freefrag;
1791
5296
        if (oldadp->ad_freefrag != NULL || oldadp->ad_oldblkno == 0) {
1792
 
                freefrag = newadp->ad_freefrag;
1793
5297
                newadp->ad_freefrag = oldadp->ad_freefrag;
1794
5298
                oldadp->ad_freefrag = freefrag;
1795
5299
        }
1798
5302
         * move it from the old allocdirect to the new allocdirect.
1799
5303
         */
1800
5304
        if ((wk = LIST_FIRST(&oldadp->ad_newdirblk)) != NULL) {
1801
 
                newdirblk = WK_NEWDIRBLK(wk);
1802
 
                WORKLIST_REMOVE(&newdirblk->db_list);
 
5305
                WORKLIST_REMOVE(wk);
1803
5306
                if (!LIST_EMPTY(&oldadp->ad_newdirblk))
1804
5307
                        panic("allocdirect_merge: extra newdirblk");
1805
 
                WORKLIST_INSERT(&newadp->ad_newdirblk, &newdirblk->db_list);
1806
 
        }
1807
 
        free_allocdirect(adphead, oldadp, 0);
1808
 
}
1809
 
                
1810
 
/*
1811
 
 * Allocate a new freefrag structure if needed.
 
5308
                WORKLIST_INSERT(&newadp->ad_newdirblk, wk);
 
5309
        }
 
5310
        TAILQ_REMOVE(adphead, oldadp, ad_next);
 
5311
        /*
 
5312
         * We need to move any journal dependencies over to the freefrag
 
5313
         * that releases this block if it exists.  Otherwise we are
 
5314
         * extending an existing block and we'll wait until that is
 
5315
         * complete to release the journal space and extend the
 
5316
         * new journal to cover this old space as well.
 
5317
         */
 
5318
        if (freefrag == NULL) {
 
5319
                if (oldadp->ad_newblkno != newadp->ad_newblkno)
 
5320
                        panic("allocdirect_merge: %jd != %jd",
 
5321
                            oldadp->ad_newblkno, newadp->ad_newblkno);
 
5322
                newadp->ad_block.nb_jnewblk = (struct jnewblk *)
 
5323
                    jnewblk_merge(&newadp->ad_block.nb_jnewblk->jn_list, 
 
5324
                    &oldadp->ad_block.nb_jnewblk->jn_list,
 
5325
                    &newadp->ad_block.nb_jwork);
 
5326
                oldadp->ad_block.nb_jnewblk = NULL;
 
5327
                cancel_newblk(&oldadp->ad_block, NULL,
 
5328
                    &newadp->ad_block.nb_jwork);
 
5329
        } else {
 
5330
                wk = (struct worklist *) cancel_newblk(&oldadp->ad_block,
 
5331
                    &freefrag->ff_list, &freefrag->ff_jwork);
 
5332
                freefrag->ff_jdep = jnewblk_merge(freefrag->ff_jdep, wk,
 
5333
                    &freefrag->ff_jwork);
 
5334
        }
 
5335
        free_newblk(&oldadp->ad_block);
 
5336
}
 
5337
 
 
5338
/*
 
5339
 * Allocate a jfreefrag structure to journal a single block free.
 
5340
 */
 
5341
static struct jfreefrag *
 
5342
newjfreefrag(freefrag, ip, blkno, size, lbn)
 
5343
        struct freefrag *freefrag;
 
5344
        struct inode *ip;
 
5345
        ufs2_daddr_t blkno;
 
5346
        long size;
 
5347
        ufs_lbn_t lbn;
 
5348
{
 
5349
        struct jfreefrag *jfreefrag;
 
5350
        struct fs *fs;
 
5351
 
 
5352
        fs = ip->i_fs;
 
5353
        jfreefrag = malloc(sizeof(struct jfreefrag), M_JFREEFRAG,
 
5354
            M_SOFTDEP_FLAGS);
 
5355
        workitem_alloc(&jfreefrag->fr_list, D_JFREEFRAG, UFSTOVFS(ip->i_ump));
 
5356
        jfreefrag->fr_jsegdep = newjsegdep(&jfreefrag->fr_list);
 
5357
        jfreefrag->fr_state = ATTACHED | DEPCOMPLETE;
 
5358
        jfreefrag->fr_ino = ip->i_number;
 
5359
        jfreefrag->fr_lbn = lbn;
 
5360
        jfreefrag->fr_blkno = blkno;
 
5361
        jfreefrag->fr_frags = numfrags(fs, size);
 
5362
        jfreefrag->fr_freefrag = freefrag;
 
5363
 
 
5364
        return (jfreefrag);
 
5365
}
 
5366
 
 
5367
/*
 
5368
 * Allocate a new freefrag structure.
1812
5369
 */
1813
5370
static struct freefrag *
1814
 
newfreefrag(ip, blkno, size)
 
5371
newfreefrag(ip, blkno, size, lbn)
1815
5372
        struct inode *ip;
1816
5373
        ufs2_daddr_t blkno;
1817
5374
        long size;
 
5375
        ufs_lbn_t lbn;
1818
5376
{
1819
5377
        struct freefrag *freefrag;
1820
5378
        struct fs *fs;
1821
5379
 
1822
 
        if (blkno == 0)
1823
 
                return (NULL);
 
5380
        CTR4(KTR_SUJ, "newfreefrag: ino %d blkno %jd size %ld lbn %jd",
 
5381
            ip->i_number, blkno, size, lbn);
1824
5382
        fs = ip->i_fs;
1825
5383
        if (fragnum(fs, blkno) + numfrags(fs, size) > fs->fs_frag)
1826
5384
                panic("newfreefrag: frag size");
1827
5385
        freefrag = malloc(sizeof(struct freefrag),
1828
 
                M_FREEFRAG, M_SOFTDEP_FLAGS);
 
5386
            M_FREEFRAG, M_SOFTDEP_FLAGS);
1829
5387
        workitem_alloc(&freefrag->ff_list, D_FREEFRAG, UFSTOVFS(ip->i_ump));
 
5388
        freefrag->ff_state = ATTACHED;
 
5389
        LIST_INIT(&freefrag->ff_jwork);
1830
5390
        freefrag->ff_inum = ip->i_number;
 
5391
        freefrag->ff_vtype = ITOV(ip)->v_type;
1831
5392
        freefrag->ff_blkno = blkno;
1832
5393
        freefrag->ff_fragsize = size;
 
5394
 
 
5395
        if (MOUNTEDSUJ(UFSTOVFS(ip->i_ump))) {
 
5396
                freefrag->ff_jdep = (struct worklist *)
 
5397
                    newjfreefrag(freefrag, ip, blkno, size, lbn);
 
5398
        } else {
 
5399
                freefrag->ff_state |= DEPCOMPLETE;
 
5400
                freefrag->ff_jdep = NULL;
 
5401
        }
 
5402
 
1833
5403
        return (freefrag);
1834
5404
}
1835
5405
 
1842
5412
        struct freefrag *freefrag;
1843
5413
{
1844
5414
        struct ufsmount *ump = VFSTOUFS(freefrag->ff_list.wk_mp);
 
5415
        struct workhead wkhd;
1845
5416
 
 
5417
        CTR3(KTR_SUJ,
 
5418
            "handle_workitem_freefrag: ino %d blkno %jd size %ld",
 
5419
            freefrag->ff_inum, freefrag->ff_blkno, freefrag->ff_fragsize);
 
5420
        /*
 
5421
         * It would be illegal to add new completion items to the
 
5422
         * freefrag after it was schedule to be done so it must be
 
5423
         * safe to modify the list head here.
 
5424
         */
 
5425
        LIST_INIT(&wkhd);
 
5426
        ACQUIRE_LOCK(&lk);
 
5427
        LIST_SWAP(&freefrag->ff_jwork, &wkhd, worklist, wk_list);
 
5428
        /*
 
5429
         * If the journal has not been written we must cancel it here.
 
5430
         */
 
5431
        if (freefrag->ff_jdep) {
 
5432
                if (freefrag->ff_jdep->wk_type != D_JNEWBLK)
 
5433
                        panic("handle_workitem_freefrag: Unexpected type %d\n",
 
5434
                            freefrag->ff_jdep->wk_type);
 
5435
                cancel_jnewblk(WK_JNEWBLK(freefrag->ff_jdep), &wkhd);
 
5436
        }
 
5437
        FREE_LOCK(&lk);
1846
5438
        ffs_blkfree(ump, ump->um_fs, ump->um_devvp, freefrag->ff_blkno,
1847
 
            freefrag->ff_fragsize, freefrag->ff_inum);
 
5439
           freefrag->ff_fragsize, freefrag->ff_inum, freefrag->ff_vtype, &wkhd);
1848
5440
        ACQUIRE_LOCK(&lk);
1849
5441
        WORKITEM_FREE(freefrag, D_FREEFRAG);
1850
5442
        FREE_LOCK(&lk);
1856
5448
 * See the description of softdep_setup_allocdirect above for details.
1857
5449
 */
1858
5450
void 
1859
 
softdep_setup_allocext(ip, lbn, newblkno, oldblkno, newsize, oldsize, bp)
 
5451
softdep_setup_allocext(ip, off, newblkno, oldblkno, newsize, oldsize, bp)
1860
5452
        struct inode *ip;
1861
 
        ufs_lbn_t lbn;
 
5453
        ufs_lbn_t off;
1862
5454
        ufs2_daddr_t newblkno;
1863
5455
        ufs2_daddr_t oldblkno;
1864
5456
        long newsize;
1867
5459
{
1868
5460
        struct allocdirect *adp, *oldadp;
1869
5461
        struct allocdirectlst *adphead;
1870
 
        struct bmsafemap *bmsafemap;
 
5462
        struct freefrag *freefrag;
1871
5463
        struct inodedep *inodedep;
 
5464
        struct jnewblk *jnewblk;
1872
5465
        struct newblk *newblk;
1873
5466
        struct mount *mp;
1874
 
 
 
5467
        ufs_lbn_t lbn;
 
5468
 
 
5469
        if (off >= NXADDR)
 
5470
                panic("softdep_setup_allocext: lbn %lld > NXADDR",
 
5471
                    (long long)off);
 
5472
 
 
5473
        lbn = bp->b_lblkno;
1875
5474
        mp = UFSTOVFS(ip->i_ump);
1876
 
        adp = malloc(sizeof(struct allocdirect),
1877
 
                M_ALLOCDIRECT, M_SOFTDEP_FLAGS|M_ZERO);
1878
 
        workitem_alloc(&adp->ad_list, D_ALLOCDIRECT, mp);
1879
 
        adp->ad_lbn = lbn;
1880
 
        adp->ad_newblkno = newblkno;
1881
 
        adp->ad_oldblkno = oldblkno;
1882
 
        adp->ad_newsize = newsize;
1883
 
        adp->ad_oldsize = oldsize;
1884
 
        adp->ad_state = ATTACHED | EXTDATA;
1885
 
        LIST_INIT(&adp->ad_newdirblk);
1886
 
        if (newblkno == oldblkno)
1887
 
                adp->ad_freefrag = NULL;
 
5475
        if (oldblkno && oldblkno != newblkno)
 
5476
                freefrag = newfreefrag(ip, oldblkno, oldsize, lbn);
1888
5477
        else
1889
 
                adp->ad_freefrag = newfreefrag(ip, oldblkno, oldsize);
 
5478
                freefrag = NULL;
1890
5479
 
1891
5480
        ACQUIRE_LOCK(&lk);
1892
 
        if (newblk_lookup(ip->i_fs, newblkno, 0, &newblk) == 0)
 
5481
        if (newblk_lookup(mp, newblkno, 0, &newblk) == 0)
1893
5482
                panic("softdep_setup_allocext: lost block");
 
5483
        KASSERT(newblk->nb_list.wk_type == D_NEWBLK,
 
5484
            ("softdep_setup_allocext: newblk already initialized"));
 
5485
        /*
 
5486
         * Convert the newblk to an allocdirect.
 
5487
         */
 
5488
        newblk->nb_list.wk_type = D_ALLOCDIRECT;
 
5489
        adp = (struct allocdirect *)newblk;
 
5490
        newblk->nb_freefrag = freefrag;
 
5491
        adp->ad_offset = off;
 
5492
        adp->ad_oldblkno = oldblkno;
 
5493
        adp->ad_newsize = newsize;
 
5494
        adp->ad_oldsize = oldsize;
 
5495
        adp->ad_state |=  EXTDATA;
1894
5496
 
 
5497
        /*
 
5498
         * Finish initializing the journal.
 
5499
         */
 
5500
        if ((jnewblk = newblk->nb_jnewblk) != NULL) {
 
5501
                jnewblk->jn_ino = ip->i_number;
 
5502
                jnewblk->jn_lbn = lbn;
 
5503
                add_to_journal(&jnewblk->jn_list);
 
5504
        }
 
5505
        if (freefrag && freefrag->ff_jdep != NULL &&
 
5506
            freefrag->ff_jdep->wk_type == D_JFREEFRAG)
 
5507
                add_to_journal(freefrag->ff_jdep);
1895
5508
        inodedep_lookup(mp, ip->i_number, DEPALLOC | NODELAY, &inodedep);
1896
5509
        adp->ad_inodedep = inodedep;
1897
5510
 
1898
 
        if (newblk->nb_state == DEPCOMPLETE) {
1899
 
                adp->ad_state |= DEPCOMPLETE;
1900
 
                adp->ad_buf = NULL;
1901
 
        } else {
1902
 
                bmsafemap = newblk->nb_bmsafemap;
1903
 
                adp->ad_buf = bmsafemap->sm_buf;
1904
 
                LIST_REMOVE(newblk, nb_deps);
1905
 
                LIST_INSERT_HEAD(&bmsafemap->sm_allocdirecthd, adp, ad_deps);
1906
 
        }
1907
 
        LIST_REMOVE(newblk, nb_hash);
1908
 
        free(newblk, M_NEWBLK);
1909
 
 
1910
 
        WORKLIST_INSERT(&bp->b_dep, &adp->ad_list);
1911
 
        if (lbn >= NXADDR)
1912
 
                panic("softdep_setup_allocext: lbn %lld > NXADDR",
1913
 
                    (long long)lbn);
 
5511
        WORKLIST_INSERT(&bp->b_dep, &newblk->nb_list);
1914
5512
        /*
1915
5513
         * The list of allocdirects must be kept in sorted and ascending
1916
5514
         * order so that the rollback routines can quickly determine the
1925
5523
         */
1926
5524
        adphead = &inodedep->id_newextupdt;
1927
5525
        oldadp = TAILQ_LAST(adphead, allocdirectlst);
1928
 
        if (oldadp == NULL || oldadp->ad_lbn <= lbn) {
 
5526
        if (oldadp == NULL || oldadp->ad_offset <= off) {
1929
5527
                /* insert at end of list */
1930
5528
                TAILQ_INSERT_TAIL(adphead, adp, ad_next);
1931
 
                if (oldadp != NULL && oldadp->ad_lbn == lbn)
 
5529
                if (oldadp != NULL && oldadp->ad_offset == off)
1932
5530
                        allocdirect_merge(adphead, adp, oldadp);
1933
5531
                FREE_LOCK(&lk);
1934
5532
                return;
1935
5533
        }
1936
5534
        TAILQ_FOREACH(oldadp, adphead, ad_next) {
1937
 
                if (oldadp->ad_lbn >= lbn)
 
5535
                if (oldadp->ad_offset >= off)
1938
5536
                        break;
1939
5537
        }
1940
5538
        if (oldadp == NULL)
1941
5539
                panic("softdep_setup_allocext: lost entry");
1942
5540
        /* insert in middle of list */
1943
5541
        TAILQ_INSERT_BEFORE(oldadp, adp, ad_next);
1944
 
        if (oldadp->ad_lbn == lbn)
 
5542
        if (oldadp->ad_offset == off)
1945
5543
                allocdirect_merge(adphead, adp, oldadp);
1946
5544
        FREE_LOCK(&lk);
1947
5545
}
1975
5573
 * Allocate a new allocindir structure.
1976
5574
 */
1977
5575
static struct allocindir *
1978
 
newallocindir(ip, ptrno, newblkno, oldblkno)
 
5576
newallocindir(ip, ptrno, newblkno, oldblkno, lbn)
1979
5577
        struct inode *ip;       /* inode for file being extended */
1980
5578
        int ptrno;              /* offset of pointer in indirect block */
1981
5579
        ufs2_daddr_t newblkno;  /* disk block number being added */
1982
5580
        ufs2_daddr_t oldblkno;  /* previous block number, 0 if none */
 
5581
        ufs_lbn_t lbn;
1983
5582
{
 
5583
        struct newblk *newblk;
1984
5584
        struct allocindir *aip;
 
5585
        struct freefrag *freefrag;
 
5586
        struct jnewblk *jnewblk;
1985
5587
 
1986
 
        aip = malloc(sizeof(struct allocindir),
1987
 
                M_ALLOCINDIR, M_SOFTDEP_FLAGS|M_ZERO);
1988
 
        workitem_alloc(&aip->ai_list, D_ALLOCINDIR, UFSTOVFS(ip->i_ump));
1989
 
        aip->ai_state = ATTACHED;
 
5588
        if (oldblkno)
 
5589
                freefrag = newfreefrag(ip, oldblkno, ip->i_fs->fs_bsize, lbn);
 
5590
        else
 
5591
                freefrag = NULL;
 
5592
        ACQUIRE_LOCK(&lk);
 
5593
        if (newblk_lookup(UFSTOVFS(ip->i_ump), newblkno, 0, &newblk) == 0)
 
5594
                panic("new_allocindir: lost block");
 
5595
        KASSERT(newblk->nb_list.wk_type == D_NEWBLK,
 
5596
            ("newallocindir: newblk already initialized"));
 
5597
        newblk->nb_list.wk_type = D_ALLOCINDIR;
 
5598
        newblk->nb_freefrag = freefrag;
 
5599
        aip = (struct allocindir *)newblk;
1990
5600
        aip->ai_offset = ptrno;
1991
 
        aip->ai_newblkno = newblkno;
1992
5601
        aip->ai_oldblkno = oldblkno;
1993
 
        aip->ai_freefrag = newfreefrag(ip, oldblkno, ip->i_fs->fs_bsize);
 
5602
        aip->ai_lbn = lbn;
 
5603
        if ((jnewblk = newblk->nb_jnewblk) != NULL) {
 
5604
                jnewblk->jn_ino = ip->i_number;
 
5605
                jnewblk->jn_lbn = lbn;
 
5606
                add_to_journal(&jnewblk->jn_list);
 
5607
        }
 
5608
        if (freefrag && freefrag->ff_jdep != NULL &&
 
5609
            freefrag->ff_jdep->wk_type == D_JFREEFRAG)
 
5610
                add_to_journal(freefrag->ff_jdep);
1994
5611
        return (aip);
1995
5612
}
1996
5613
 
2008
5625
        ufs2_daddr_t oldblkno;  /* previous block number, 0 if none */
2009
5626
        struct buf *nbp;        /* buffer holding allocated page */
2010
5627
{
 
5628
        struct inodedep *inodedep;
 
5629
        struct freefrag *freefrag;
2011
5630
        struct allocindir *aip;
2012
5631
        struct pagedep *pagedep;
 
5632
        struct mount *mp;
 
5633
        int dflags;
2013
5634
 
 
5635
        if (lbn != nbp->b_lblkno)
 
5636
                panic("softdep_setup_allocindir_page: lbn %jd != lblkno %jd",
 
5637
                    lbn, bp->b_lblkno);
 
5638
        CTR4(KTR_SUJ,
 
5639
            "softdep_setup_allocindir_page: ino %d blkno %jd oldblkno %jd "
 
5640
            "lbn %jd", ip->i_number, newblkno, oldblkno, lbn);
2014
5641
        ASSERT_VOP_LOCKED(ITOV(ip), "softdep_setup_allocindir_page");
2015
 
        aip = newallocindir(ip, ptrno, newblkno, oldblkno);
2016
 
        ACQUIRE_LOCK(&lk);
 
5642
        mp = UFSTOVFS(ip->i_ump);
 
5643
        aip = newallocindir(ip, ptrno, newblkno, oldblkno, lbn);
 
5644
        dflags = DEPALLOC;
 
5645
        if (IS_SNAPSHOT(ip))
 
5646
                dflags |= NODELAY;
 
5647
        (void) inodedep_lookup(mp, ip->i_number, dflags, &inodedep);
2017
5648
        /*
2018
5649
         * If we are allocating a directory page, then we must
2019
5650
         * allocate an associated pagedep to track additions and
2020
5651
         * deletions.
2021
5652
         */
2022
 
        if ((ip->i_mode & IFMT) == IFDIR &&
2023
 
            pagedep_lookup(ip, lbn, DEPALLOC, &pagedep) == 0)
2024
 
                WORKLIST_INSERT(&nbp->b_dep, &pagedep->pd_list);
2025
 
        WORKLIST_INSERT(&nbp->b_dep, &aip->ai_list);
2026
 
        setup_allocindir_phase2(bp, ip, aip);
 
5653
        if ((ip->i_mode & IFMT) == IFDIR)
 
5654
                pagedep_lookup(mp, nbp, ip->i_number, lbn, DEPALLOC, &pagedep);
 
5655
        WORKLIST_INSERT(&nbp->b_dep, &aip->ai_block.nb_list);
 
5656
        freefrag = setup_allocindir_phase2(bp, ip, inodedep, aip, lbn);
2027
5657
        FREE_LOCK(&lk);
 
5658
        if (freefrag)
 
5659
                handle_workitem_freefrag(freefrag);
2028
5660
}
2029
5661
 
2030
5662
/*
2039
5671
        int ptrno;              /* offset of pointer in indirect block */
2040
5672
        ufs2_daddr_t newblkno;  /* disk block number being added */
2041
5673
{
 
5674
        struct inodedep *inodedep;
2042
5675
        struct allocindir *aip;
 
5676
        ufs_lbn_t lbn;
 
5677
        int dflags;
2043
5678
 
 
5679
        CTR3(KTR_SUJ,
 
5680
            "softdep_setup_allocindir_meta: ino %d blkno %jd ptrno %d",
 
5681
            ip->i_number, newblkno, ptrno);
 
5682
        lbn = nbp->b_lblkno;
2044
5683
        ASSERT_VOP_LOCKED(ITOV(ip), "softdep_setup_allocindir_meta");
2045
 
        aip = newallocindir(ip, ptrno, newblkno, 0);
2046
 
        ACQUIRE_LOCK(&lk);
2047
 
        WORKLIST_INSERT(&nbp->b_dep, &aip->ai_list);
2048
 
        setup_allocindir_phase2(bp, ip, aip);
 
5684
        aip = newallocindir(ip, ptrno, newblkno, 0, lbn);
 
5685
        dflags = DEPALLOC;
 
5686
        if (IS_SNAPSHOT(ip))
 
5687
                dflags |= NODELAY;
 
5688
        inodedep_lookup(UFSTOVFS(ip->i_ump), ip->i_number, dflags, &inodedep);
 
5689
        WORKLIST_INSERT(&nbp->b_dep, &aip->ai_block.nb_list);
 
5690
        if (setup_allocindir_phase2(bp, ip, inodedep, aip, lbn))
 
5691
                panic("softdep_setup_allocindir_meta: Block already existed");
2049
5692
        FREE_LOCK(&lk);
2050
5693
}
2051
5694
 
2052
 
/*
2053
 
 * Called to finish the allocation of the "aip" allocated
2054
 
 * by one of the two routines above.
2055
 
 */
2056
 
static void 
2057
 
setup_allocindir_phase2(bp, ip, aip)
2058
 
        struct buf *bp;         /* in-memory copy of the indirect block */
2059
 
        struct inode *ip;       /* inode for file being extended */
2060
 
        struct allocindir *aip; /* allocindir allocated by the above routines */
2061
 
{
2062
 
        struct worklist *wk;
 
5695
static void
 
5696
indirdep_complete(indirdep)
 
5697
        struct indirdep *indirdep;
 
5698
{
 
5699
        struct allocindir *aip;
 
5700
 
 
5701
        LIST_REMOVE(indirdep, ir_next);
 
5702
        indirdep->ir_state |= DEPCOMPLETE;
 
5703
 
 
5704
        while ((aip = LIST_FIRST(&indirdep->ir_completehd)) != NULL) {
 
5705
                LIST_REMOVE(aip, ai_next);
 
5706
                free_newblk(&aip->ai_block);
 
5707
        }
 
5708
        /*
 
5709
         * If this indirdep is not attached to a buf it was simply waiting
 
5710
         * on completion to clear completehd.  free_indirdep() asserts
 
5711
         * that nothing is dangling.
 
5712
         */
 
5713
        if ((indirdep->ir_state & ONWORKLIST) == 0)
 
5714
                free_indirdep(indirdep);
 
5715
}
 
5716
 
 
5717
static struct indirdep *
 
5718
indirdep_lookup(mp, ip, bp)
 
5719
        struct mount *mp;
 
5720
        struct inode *ip;
 
5721
        struct buf *bp;
 
5722
{
2063
5723
        struct indirdep *indirdep, *newindirdep;
2064
 
        struct bmsafemap *bmsafemap;
2065
 
        struct allocindir *oldaip;
2066
 
        struct freefrag *freefrag;
2067
5724
        struct newblk *newblk;
 
5725
        struct worklist *wk;
 
5726
        struct fs *fs;
2068
5727
        ufs2_daddr_t blkno;
2069
5728
 
2070
5729
        mtx_assert(&lk, MA_OWNED);
2071
 
        if (bp->b_lblkno >= 0)
2072
 
                panic("setup_allocindir_phase2: not indir blk");
2073
 
        for (indirdep = NULL, newindirdep = NULL; ; ) {
 
5730
        indirdep = NULL;
 
5731
        newindirdep = NULL;
 
5732
        fs = ip->i_fs;
 
5733
        for (;;) {
2074
5734
                LIST_FOREACH(wk, &bp->b_dep, wk_list) {
2075
5735
                        if (wk->wk_type != D_INDIRDEP)
2076
5736
                                continue;
2077
5737
                        indirdep = WK_INDIRDEP(wk);
2078
5738
                        break;
2079
5739
                }
2080
 
                if (indirdep == NULL && newindirdep) {
2081
 
                        indirdep = newindirdep;
2082
 
                        WORKLIST_INSERT(&bp->b_dep, &indirdep->ir_list);
2083
 
                        newindirdep = NULL;
2084
 
                }
2085
 
                if (indirdep) {
2086
 
                        if (newblk_lookup(ip->i_fs, aip->ai_newblkno, 0,
2087
 
                            &newblk) == 0)
2088
 
                                panic("setup_allocindir: lost block");
2089
 
                        if (newblk->nb_state == DEPCOMPLETE) {
2090
 
                                aip->ai_state |= DEPCOMPLETE;
2091
 
                                aip->ai_buf = NULL;
2092
 
                        } else {
2093
 
                                bmsafemap = newblk->nb_bmsafemap;
2094
 
                                aip->ai_buf = bmsafemap->sm_buf;
2095
 
                                LIST_REMOVE(newblk, nb_deps);
2096
 
                                LIST_INSERT_HEAD(&bmsafemap->sm_allocindirhd,
2097
 
                                    aip, ai_deps);
2098
 
                        }
2099
 
                        LIST_REMOVE(newblk, nb_hash);
2100
 
                        free(newblk, M_NEWBLK);
2101
 
                        aip->ai_indirdep = indirdep;
2102
 
                        /*
2103
 
                         * Check to see if there is an existing dependency
2104
 
                         * for this block. If there is, merge the old
2105
 
                         * dependency into the new one.
2106
 
                         */
2107
 
                        if (aip->ai_oldblkno == 0)
2108
 
                                oldaip = NULL;
2109
 
                        else
2110
 
 
2111
 
                                LIST_FOREACH(oldaip, &indirdep->ir_deplisthd, ai_next)
2112
 
                                        if (oldaip->ai_offset == aip->ai_offset)
2113
 
                                                break;
2114
 
                        freefrag = NULL;
2115
 
                        if (oldaip != NULL) {
2116
 
                                if (oldaip->ai_newblkno != aip->ai_oldblkno)
2117
 
                                        panic("setup_allocindir_phase2: blkno");
2118
 
                                aip->ai_oldblkno = oldaip->ai_oldblkno;
2119
 
                                freefrag = aip->ai_freefrag;
2120
 
                                aip->ai_freefrag = oldaip->ai_freefrag;
2121
 
                                oldaip->ai_freefrag = NULL;
2122
 
                                free_allocindir(oldaip, NULL);
2123
 
                        }
2124
 
                        LIST_INSERT_HEAD(&indirdep->ir_deplisthd, aip, ai_next);
2125
 
                        if (ip->i_ump->um_fstype == UFS1)
2126
 
                                ((ufs1_daddr_t *)indirdep->ir_savebp->b_data)
2127
 
                                    [aip->ai_offset] = aip->ai_oldblkno;
2128
 
                        else
2129
 
                                ((ufs2_daddr_t *)indirdep->ir_savebp->b_data)
2130
 
                                    [aip->ai_offset] = aip->ai_oldblkno;
2131
 
                        FREE_LOCK(&lk);
2132
 
                        if (freefrag != NULL)
2133
 
                                handle_workitem_freefrag(freefrag);
2134
 
                } else
2135
 
                        FREE_LOCK(&lk);
2136
 
                if (newindirdep) {
2137
 
                        newindirdep->ir_savebp->b_flags |= B_INVAL | B_NOCACHE;
2138
 
                        brelse(newindirdep->ir_savebp);
2139
 
                        ACQUIRE_LOCK(&lk);
2140
 
                        WORKITEM_FREE((caddr_t)newindirdep, D_INDIRDEP);
2141
 
                        if (indirdep)
2142
 
                                break;
2143
 
                        FREE_LOCK(&lk);
2144
 
                }
2145
 
                if (indirdep) {
2146
 
                        ACQUIRE_LOCK(&lk);
 
5740
                /* Found on the buffer worklist, no new structure to free. */
 
5741
                if (indirdep != NULL && newindirdep == NULL)
 
5742
                        return (indirdep);
 
5743
                if (indirdep != NULL && newindirdep != NULL)
 
5744
                        panic("indirdep_lookup: simultaneous create");
 
5745
                /* None found on the buffer and a new structure is ready. */
 
5746
                if (indirdep == NULL && newindirdep != NULL)
2147
5747
                        break;
2148
 
                }
 
5748
                /* None found and no new structure available. */
 
5749
                FREE_LOCK(&lk);
2149
5750
                newindirdep = malloc(sizeof(struct indirdep),
2150
 
                        M_INDIRDEP, M_SOFTDEP_FLAGS);
2151
 
                workitem_alloc(&newindirdep->ir_list, D_INDIRDEP,
2152
 
                    UFSTOVFS(ip->i_ump));
 
5751
                    M_INDIRDEP, M_SOFTDEP_FLAGS);
 
5752
                workitem_alloc(&newindirdep->ir_list, D_INDIRDEP, mp);
2153
5753
                newindirdep->ir_state = ATTACHED;
2154
5754
                if (ip->i_ump->um_fstype == UFS1)
2155
5755
                        newindirdep->ir_state |= UFS1FMT;
 
5756
                TAILQ_INIT(&newindirdep->ir_trunc);
 
5757
                newindirdep->ir_saveddata = NULL;
2156
5758
                LIST_INIT(&newindirdep->ir_deplisthd);
2157
5759
                LIST_INIT(&newindirdep->ir_donehd);
 
5760
                LIST_INIT(&newindirdep->ir_writehd);
 
5761
                LIST_INIT(&newindirdep->ir_completehd);
2158
5762
                if (bp->b_blkno == bp->b_lblkno) {
2159
5763
                        ufs_bmaparray(bp->b_vp, bp->b_lblkno, &blkno, bp,
2160
5764
                            NULL, NULL);
2161
5765
                        bp->b_blkno = blkno;
2162
5766
                }
 
5767
                newindirdep->ir_freeblks = NULL;
2163
5768
                newindirdep->ir_savebp =
2164
5769
                    getblk(ip->i_devvp, bp->b_blkno, bp->b_bcount, 0, 0, 0);
 
5770
                newindirdep->ir_bp = bp;
2165
5771
                BUF_KERNPROC(newindirdep->ir_savebp);
2166
5772
                bcopy(bp->b_data, newindirdep->ir_savebp->b_data, bp->b_bcount);
2167
5773
                ACQUIRE_LOCK(&lk);
2168
5774
        }
 
5775
        indirdep = newindirdep;
 
5776
        WORKLIST_INSERT(&bp->b_dep, &indirdep->ir_list);
 
5777
        /*
 
5778
         * If the block is not yet allocated we don't set DEPCOMPLETE so
 
5779
         * that we don't free dependencies until the pointers are valid.
 
5780
         * This could search b_dep for D_ALLOCDIRECT/D_ALLOCINDIR rather
 
5781
         * than using the hash.
 
5782
         */
 
5783
        if (newblk_lookup(mp, dbtofsb(fs, bp->b_blkno), 0, &newblk))
 
5784
                LIST_INSERT_HEAD(&newblk->nb_indirdeps, indirdep, ir_next);
 
5785
        else
 
5786
                indirdep->ir_state |= DEPCOMPLETE;
 
5787
        return (indirdep);
 
5788
}
 
5789
 
 
5790
/*
 
5791
 * Called to finish the allocation of the "aip" allocated
 
5792
 * by one of the two routines above.
 
5793
 */
 
5794
static struct freefrag *
 
5795
setup_allocindir_phase2(bp, ip, inodedep, aip, lbn)
 
5796
        struct buf *bp;         /* in-memory copy of the indirect block */
 
5797
        struct inode *ip;       /* inode for file being extended */
 
5798
        struct inodedep *inodedep; /* Inodedep for ip */
 
5799
        struct allocindir *aip; /* allocindir allocated by the above routines */
 
5800
        ufs_lbn_t lbn;          /* Logical block number for this block. */
 
5801
{
 
5802
        struct fs *fs;
 
5803
        struct indirdep *indirdep;
 
5804
        struct allocindir *oldaip;
 
5805
        struct freefrag *freefrag;
 
5806
        struct mount *mp;
 
5807
 
 
5808
        mtx_assert(&lk, MA_OWNED);
 
5809
        mp = UFSTOVFS(ip->i_ump);
 
5810
        fs = ip->i_fs;
 
5811
        if (bp->b_lblkno >= 0)
 
5812
                panic("setup_allocindir_phase2: not indir blk");
 
5813
        KASSERT(aip->ai_offset >= 0 && aip->ai_offset < NINDIR(fs),
 
5814
            ("setup_allocindir_phase2: Bad offset %d", aip->ai_offset));
 
5815
        indirdep = indirdep_lookup(mp, ip, bp);
 
5816
        KASSERT(indirdep->ir_savebp != NULL,
 
5817
            ("setup_allocindir_phase2 NULL ir_savebp"));
 
5818
        aip->ai_indirdep = indirdep;
 
5819
        /*
 
5820
         * Check for an unwritten dependency for this indirect offset.  If
 
5821
         * there is, merge the old dependency into the new one.  This happens
 
5822
         * as a result of reallocblk only.
 
5823
         */
 
5824
        freefrag = NULL;
 
5825
        if (aip->ai_oldblkno != 0) {
 
5826
                LIST_FOREACH(oldaip, &indirdep->ir_deplisthd, ai_next) {
 
5827
                        if (oldaip->ai_offset == aip->ai_offset) {
 
5828
                                freefrag = allocindir_merge(aip, oldaip);
 
5829
                                goto done;
 
5830
                        }
 
5831
                }
 
5832
                LIST_FOREACH(oldaip, &indirdep->ir_donehd, ai_next) {
 
5833
                        if (oldaip->ai_offset == aip->ai_offset) {
 
5834
                                freefrag = allocindir_merge(aip, oldaip);
 
5835
                                goto done;
 
5836
                        }
 
5837
                }
 
5838
        }
 
5839
done:
 
5840
        LIST_INSERT_HEAD(&indirdep->ir_deplisthd, aip, ai_next);
 
5841
        return (freefrag);
 
5842
}
 
5843
 
 
5844
/*
 
5845
 * Merge two allocindirs which refer to the same block.  Move newblock
 
5846
 * dependencies and setup the freefrags appropriately.
 
5847
 */
 
5848
static struct freefrag *
 
5849
allocindir_merge(aip, oldaip)
 
5850
        struct allocindir *aip;
 
5851
        struct allocindir *oldaip;
 
5852
{
 
5853
        struct freefrag *freefrag;
 
5854
        struct worklist *wk;
 
5855
 
 
5856
        if (oldaip->ai_newblkno != aip->ai_oldblkno)
 
5857
                panic("allocindir_merge: blkno");
 
5858
        aip->ai_oldblkno = oldaip->ai_oldblkno;
 
5859
        freefrag = aip->ai_freefrag;
 
5860
        aip->ai_freefrag = oldaip->ai_freefrag;
 
5861
        oldaip->ai_freefrag = NULL;
 
5862
        KASSERT(freefrag != NULL, ("setup_allocindir_phase2: No freefrag"));
 
5863
        /*
 
5864
         * If we are tracking a new directory-block allocation,
 
5865
         * move it from the old allocindir to the new allocindir.
 
5866
         */
 
5867
        if ((wk = LIST_FIRST(&oldaip->ai_newdirblk)) != NULL) {
 
5868
                WORKLIST_REMOVE(wk);
 
5869
                if (!LIST_EMPTY(&oldaip->ai_newdirblk))
 
5870
                        panic("allocindir_merge: extra newdirblk");
 
5871
                WORKLIST_INSERT(&aip->ai_newdirblk, wk);
 
5872
        }
 
5873
        /*
 
5874
         * We can skip journaling for this freefrag and just complete
 
5875
         * any pending journal work for the allocindir that is being
 
5876
         * removed after the freefrag completes.
 
5877
         */
 
5878
        if (freefrag->ff_jdep)
 
5879
                cancel_jfreefrag(WK_JFREEFRAG(freefrag->ff_jdep));
 
5880
        LIST_REMOVE(oldaip, ai_next);
 
5881
        freefrag->ff_jdep = (struct worklist *)cancel_newblk(&oldaip->ai_block,
 
5882
            &freefrag->ff_list, &freefrag->ff_jwork);
 
5883
        free_newblk(&oldaip->ai_block);
 
5884
 
 
5885
        return (freefrag);
 
5886
}
 
5887
 
 
5888
static inline void
 
5889
setup_freedirect(freeblks, ip, i, needj)
 
5890
        struct freeblks *freeblks;
 
5891
        struct inode *ip;
 
5892
        int i;
 
5893
        int needj;
 
5894
{
 
5895
        ufs2_daddr_t blkno;
 
5896
        int frags;
 
5897
 
 
5898
        blkno = DIP(ip, i_db[i]);
 
5899
        if (blkno == 0)
 
5900
                return;
 
5901
        DIP_SET(ip, i_db[i], 0);
 
5902
        frags = sblksize(ip->i_fs, ip->i_size, i);
 
5903
        frags = numfrags(ip->i_fs, frags);
 
5904
        newfreework(ip->i_ump, freeblks, NULL, i, blkno, frags, 0, needj);
 
5905
}
 
5906
 
 
5907
static inline void
 
5908
setup_freeext(freeblks, ip, i, needj)
 
5909
        struct freeblks *freeblks;
 
5910
        struct inode *ip;
 
5911
        int i;
 
5912
        int needj;
 
5913
{
 
5914
        ufs2_daddr_t blkno;
 
5915
        int frags;
 
5916
 
 
5917
        blkno = ip->i_din2->di_extb[i];
 
5918
        if (blkno == 0)
 
5919
                return;
 
5920
        ip->i_din2->di_extb[i] = 0;
 
5921
        frags = sblksize(ip->i_fs, ip->i_din2->di_extsize, i);
 
5922
        frags = numfrags(ip->i_fs, frags);
 
5923
        newfreework(ip->i_ump, freeblks, NULL, -1 - i, blkno, frags, 0, needj);
 
5924
}
 
5925
 
 
5926
static inline void
 
5927
setup_freeindir(freeblks, ip, i, lbn, needj)
 
5928
        struct freeblks *freeblks;
 
5929
        struct inode *ip;
 
5930
        int i;
 
5931
        ufs_lbn_t lbn;
 
5932
        int needj;
 
5933
{
 
5934
        ufs2_daddr_t blkno;
 
5935
 
 
5936
        blkno = DIP(ip, i_ib[i]);
 
5937
        if (blkno == 0)
 
5938
                return;
 
5939
        DIP_SET(ip, i_ib[i], 0);
 
5940
        newfreework(ip->i_ump, freeblks, NULL, lbn, blkno, ip->i_fs->fs_frag,
 
5941
            0, needj);
 
5942
}
 
5943
 
 
5944
static inline struct freeblks *
 
5945
newfreeblks(mp, ip)
 
5946
        struct mount *mp;
 
5947
        struct inode *ip;
 
5948
{
 
5949
        struct freeblks *freeblks;
 
5950
 
 
5951
        freeblks = malloc(sizeof(struct freeblks),
 
5952
                M_FREEBLKS, M_SOFTDEP_FLAGS|M_ZERO);
 
5953
        workitem_alloc(&freeblks->fb_list, D_FREEBLKS, mp);
 
5954
        LIST_INIT(&freeblks->fb_jblkdephd);
 
5955
        LIST_INIT(&freeblks->fb_jwork);
 
5956
        freeblks->fb_ref = 0;
 
5957
        freeblks->fb_cgwait = 0;
 
5958
        freeblks->fb_state = ATTACHED;
 
5959
        freeblks->fb_uid = ip->i_uid;
 
5960
        freeblks->fb_inum = ip->i_number;
 
5961
        freeblks->fb_vtype = ITOV(ip)->v_type;
 
5962
        freeblks->fb_modrev = DIP(ip, i_modrev);
 
5963
        freeblks->fb_devvp = ip->i_devvp;
 
5964
        freeblks->fb_chkcnt = 0;
 
5965
        freeblks->fb_len = 0;
 
5966
 
 
5967
        return (freeblks);
 
5968
}
 
5969
 
 
5970
static void
 
5971
trunc_indirdep(indirdep, freeblks, bp, off)
 
5972
        struct indirdep *indirdep;
 
5973
        struct freeblks *freeblks;
 
5974
        struct buf *bp;
 
5975
        int off;
 
5976
{
 
5977
        struct allocindir *aip, *aipn;
 
5978
 
 
5979
        /*
 
5980
         * The first set of allocindirs won't be in savedbp.
 
5981
         */
 
5982
        LIST_FOREACH_SAFE(aip, &indirdep->ir_deplisthd, ai_next, aipn)
 
5983
                if (aip->ai_offset > off)
 
5984
                        cancel_allocindir(aip, bp, freeblks, 1);
 
5985
        LIST_FOREACH_SAFE(aip, &indirdep->ir_donehd, ai_next, aipn)
 
5986
                if (aip->ai_offset > off)
 
5987
                        cancel_allocindir(aip, bp, freeblks, 1);
 
5988
        /*
 
5989
         * These will exist in savedbp.
 
5990
         */
 
5991
        LIST_FOREACH_SAFE(aip, &indirdep->ir_writehd, ai_next, aipn)
 
5992
                if (aip->ai_offset > off)
 
5993
                        cancel_allocindir(aip, NULL, freeblks, 0);
 
5994
        LIST_FOREACH_SAFE(aip, &indirdep->ir_completehd, ai_next, aipn)
 
5995
                if (aip->ai_offset > off)
 
5996
                        cancel_allocindir(aip, NULL, freeblks, 0);
 
5997
}
 
5998
 
 
5999
/*
 
6000
 * Follow the chain of indirects down to lastlbn creating a freework
 
6001
 * structure for each.  This will be used to start indir_trunc() at
 
6002
 * the right offset and create the journal records for the parrtial
 
6003
 * truncation.  A second step will handle the truncated dependencies.
 
6004
 */
 
6005
static int
 
6006
setup_trunc_indir(freeblks, ip, lbn, lastlbn, blkno)
 
6007
        struct freeblks *freeblks;
 
6008
        struct inode *ip;
 
6009
        ufs_lbn_t lbn;
 
6010
        ufs_lbn_t lastlbn;
 
6011
        ufs2_daddr_t blkno;
 
6012
{
 
6013
        struct indirdep *indirdep;
 
6014
        struct indirdep *indirn;
 
6015
        struct freework *freework;
 
6016
        struct newblk *newblk;
 
6017
        struct mount *mp;
 
6018
        struct buf *bp;
 
6019
        uint8_t *start;
 
6020
        uint8_t *end;
 
6021
        ufs_lbn_t lbnadd;
 
6022
        int level;
 
6023
        int error;
 
6024
        int off;
 
6025
 
 
6026
 
 
6027
        freework = NULL;
 
6028
        if (blkno == 0)
 
6029
                return (0);
 
6030
        mp = freeblks->fb_list.wk_mp;
 
6031
        bp = getblk(ITOV(ip), lbn, mp->mnt_stat.f_iosize, 0, 0, 0);
 
6032
        if ((bp->b_flags & B_CACHE) == 0) {
 
6033
                bp->b_blkno = blkptrtodb(VFSTOUFS(mp), blkno);
 
6034
                bp->b_iocmd = BIO_READ;
 
6035
                bp->b_flags &= ~B_INVAL;
 
6036
                bp->b_ioflags &= ~BIO_ERROR;
 
6037
                vfs_busy_pages(bp, 0);
 
6038
                bp->b_iooffset = dbtob(bp->b_blkno);
 
6039
                bstrategy(bp);
 
6040
                curthread->td_ru.ru_inblock++;
 
6041
                error = bufwait(bp);
 
6042
                if (error) {
 
6043
                        brelse(bp);
 
6044
                        return (error);
 
6045
                }
 
6046
        }
 
6047
        level = lbn_level(lbn);
 
6048
        lbnadd = lbn_offset(ip->i_fs, level);
 
6049
        /*
 
6050
         * Compute the offset of the last block we want to keep.  Store
 
6051
         * in the freework the first block we want to completely free.
 
6052
         */
 
6053
        off = (lastlbn - -(lbn + level)) / lbnadd;
 
6054
        if (off + 1 == NINDIR(ip->i_fs))
 
6055
                goto nowork;
 
6056
        freework = newfreework(ip->i_ump, freeblks, NULL, lbn, blkno, 0, off+1,
 
6057
            0);
 
6058
        /*
 
6059
         * Link the freework into the indirdep.  This will prevent any new
 
6060
         * allocations from proceeding until we are finished with the
 
6061
         * truncate and the block is written.
 
6062
         */
 
6063
        ACQUIRE_LOCK(&lk);
 
6064
        indirdep = indirdep_lookup(mp, ip, bp);
 
6065
        if (indirdep->ir_freeblks)
 
6066
                panic("setup_trunc_indir: indirdep already truncated.");
 
6067
        TAILQ_INSERT_TAIL(&indirdep->ir_trunc, freework, fw_next);
 
6068
        freework->fw_indir = indirdep;
 
6069
        /*
 
6070
         * Cancel any allocindirs that will not make it to disk.
 
6071
         * We have to do this for all copies of the indirdep that
 
6072
         * live on this newblk.
 
6073
         */
 
6074
        if ((indirdep->ir_state & DEPCOMPLETE) == 0) {
 
6075
                newblk_lookup(mp, dbtofsb(ip->i_fs, bp->b_blkno), 0, &newblk);
 
6076
                LIST_FOREACH(indirn, &newblk->nb_indirdeps, ir_next)
 
6077
                        trunc_indirdep(indirn, freeblks, bp, off);
 
6078
        } else
 
6079
                trunc_indirdep(indirdep, freeblks, bp, off);
 
6080
        FREE_LOCK(&lk);
 
6081
        /*
 
6082
         * Creation is protected by the buf lock. The saveddata is only
 
6083
         * needed if a full truncation follows a partial truncation but it
 
6084
         * is difficult to allocate in that case so we fetch it anyway.
 
6085
         */
 
6086
        if (indirdep->ir_saveddata == NULL)
 
6087
                indirdep->ir_saveddata = malloc(bp->b_bcount, M_INDIRDEP,
 
6088
                    M_SOFTDEP_FLAGS);
 
6089
nowork:
 
6090
        /* Fetch the blkno of the child and the zero start offset. */
 
6091
        if (ip->i_ump->um_fstype == UFS1) {
 
6092
                blkno = ((ufs1_daddr_t *)bp->b_data)[off];
 
6093
                start = (uint8_t *)&((ufs1_daddr_t *)bp->b_data)[off+1];
 
6094
        } else {
 
6095
                blkno = ((ufs2_daddr_t *)bp->b_data)[off];
 
6096
                start = (uint8_t *)&((ufs2_daddr_t *)bp->b_data)[off+1];
 
6097
        }
 
6098
        if (freework) {
 
6099
                /* Zero the truncated pointers. */
 
6100
                end = bp->b_data + bp->b_bcount;
 
6101
                bzero(start, end - start);
 
6102
                bdwrite(bp);
 
6103
        } else
 
6104
                bqrelse(bp);
 
6105
        if (level == 0)
 
6106
                return (0);
 
6107
        lbn++; /* adjust level */
 
6108
        lbn -= (off * lbnadd);
 
6109
        return setup_trunc_indir(freeblks, ip, lbn, lastlbn, blkno);
 
6110
}
 
6111
 
 
6112
/*
 
6113
 * Complete the partial truncation of an indirect block setup by
 
6114
 * setup_trunc_indir().  This zeros the truncated pointers in the saved
 
6115
 * copy and writes them to disk before the freeblks is allowed to complete.
 
6116
 */
 
6117
static void
 
6118
complete_trunc_indir(freework)
 
6119
        struct freework *freework;
 
6120
{
 
6121
        struct freework *fwn;
 
6122
        struct indirdep *indirdep;
 
6123
        struct buf *bp;
 
6124
        uintptr_t start;
 
6125
        int count;
 
6126
 
 
6127
        indirdep = freework->fw_indir;
 
6128
        for (;;) {
 
6129
                bp = indirdep->ir_bp;
 
6130
                /* See if the block was discarded. */
 
6131
                if (bp == NULL)
 
6132
                        break;
 
6133
                /* Inline part of getdirtybuf().  We dont want bremfree. */
 
6134
                if (BUF_LOCK(bp, LK_EXCLUSIVE | LK_NOWAIT, NULL) == 0)
 
6135
                        break;
 
6136
                if (BUF_LOCK(bp,
 
6137
                    LK_EXCLUSIVE | LK_SLEEPFAIL | LK_INTERLOCK, &lk) == 0)
 
6138
                        BUF_UNLOCK(bp);
 
6139
                ACQUIRE_LOCK(&lk);
 
6140
        }
 
6141
        mtx_assert(&lk, MA_OWNED);
 
6142
        freework->fw_state |= DEPCOMPLETE;
 
6143
        TAILQ_REMOVE(&indirdep->ir_trunc, freework, fw_next);
 
6144
        /*
 
6145
         * Zero the pointers in the saved copy.
 
6146
         */
 
6147
        if (indirdep->ir_state & UFS1FMT)
 
6148
                start = sizeof(ufs1_daddr_t);
 
6149
        else
 
6150
                start = sizeof(ufs2_daddr_t);
 
6151
        start *= freework->fw_start;
 
6152
        count = indirdep->ir_savebp->b_bcount - start;
 
6153
        start += (uintptr_t)indirdep->ir_savebp->b_data;
 
6154
        bzero((char *)start, count);
 
6155
        /*
 
6156
         * We need to start the next truncation in the list if it has not
 
6157
         * been started yet.
 
6158
         */
 
6159
        fwn = TAILQ_FIRST(&indirdep->ir_trunc);
 
6160
        if (fwn != NULL) {
 
6161
                if (fwn->fw_freeblks == indirdep->ir_freeblks)
 
6162
                        TAILQ_REMOVE(&indirdep->ir_trunc, fwn, fw_next);
 
6163
                if ((fwn->fw_state & ONWORKLIST) == 0)
 
6164
                        freework_enqueue(fwn);
 
6165
        }
 
6166
        /*
 
6167
         * If bp is NULL the block was fully truncated, restore
 
6168
         * the saved block list otherwise free it if it is no
 
6169
         * longer needed.
 
6170
         */
 
6171
        if (TAILQ_EMPTY(&indirdep->ir_trunc)) {
 
6172
                if (bp == NULL)
 
6173
                        bcopy(indirdep->ir_saveddata,
 
6174
                            indirdep->ir_savebp->b_data,
 
6175
                            indirdep->ir_savebp->b_bcount);
 
6176
                free(indirdep->ir_saveddata, M_INDIRDEP);
 
6177
                indirdep->ir_saveddata = NULL;
 
6178
        }
 
6179
        /*
 
6180
         * When bp is NULL there is a full truncation pending.  We
 
6181
         * must wait for this full truncation to be journaled before
 
6182
         * we can release this freework because the disk pointers will
 
6183
         * never be written as zero.
 
6184
         */
 
6185
        if (bp == NULL)  {
 
6186
                if (LIST_EMPTY(&indirdep->ir_freeblks->fb_jblkdephd))
 
6187
                        handle_written_freework(freework);
 
6188
                else
 
6189
                        WORKLIST_INSERT(&indirdep->ir_freeblks->fb_freeworkhd,
 
6190
                           &freework->fw_list);
 
6191
        } else {
 
6192
                /* Complete when the real copy is written. */
 
6193
                WORKLIST_INSERT(&bp->b_dep, &freework->fw_list);
 
6194
                BUF_UNLOCK(bp);
 
6195
        }
 
6196
}
 
6197
 
 
6198
/*
 
6199
 * Calculate the number of blocks we are going to release where datablocks
 
6200
 * is the current total and length is the new file size.
 
6201
 */
 
6202
ufs2_daddr_t
 
6203
blkcount(fs, datablocks, length)
 
6204
        struct fs *fs;
 
6205
        ufs2_daddr_t datablocks;
 
6206
        off_t length;
 
6207
{
 
6208
        off_t totblks, numblks;
 
6209
 
 
6210
        totblks = 0;
 
6211
        numblks = howmany(length, fs->fs_bsize);
 
6212
        if (numblks <= NDADDR) {
 
6213
                totblks = howmany(length, fs->fs_fsize);
 
6214
                goto out;
 
6215
        }
 
6216
        totblks = blkstofrags(fs, numblks);
 
6217
        numblks -= NDADDR;
 
6218
        /*
 
6219
         * Count all single, then double, then triple indirects required.
 
6220
         * Subtracting one indirects worth of blocks for each pass
 
6221
         * acknowledges one of each pointed to by the inode.
 
6222
         */
 
6223
        for (;;) {
 
6224
                totblks += blkstofrags(fs, howmany(numblks, NINDIR(fs)));
 
6225
                numblks -= NINDIR(fs);
 
6226
                if (numblks <= 0)
 
6227
                        break;
 
6228
                numblks = howmany(numblks, NINDIR(fs));
 
6229
        }
 
6230
out:
 
6231
        totblks = fsbtodb(fs, totblks);
 
6232
        /*
 
6233
         * Handle sparse files.  We can't reclaim more blocks than the inode
 
6234
         * references.  We will correct it later in handle_complete_freeblks()
 
6235
         * when we know the real count.
 
6236
         */
 
6237
        if (totblks > datablocks)
 
6238
                return (0);
 
6239
        return (datablocks - totblks);
 
6240
}
 
6241
 
 
6242
/*
 
6243
 * Handle freeblocks for journaled softupdate filesystems.
 
6244
 *
 
6245
 * Contrary to normal softupdates, we must preserve the block pointers in
 
6246
 * indirects until their subordinates are free.  This is to avoid journaling
 
6247
 * every block that is freed which may consume more space than the journal
 
6248
 * itself.  The recovery program will see the free block journals at the
 
6249
 * base of the truncated area and traverse them to reclaim space.  The
 
6250
 * pointers in the inode may be cleared immediately after the journal
 
6251
 * records are written because each direct and indirect pointer in the
 
6252
 * inode is recorded in a journal.  This permits full truncation to proceed
 
6253
 * asynchronously.  The write order is journal -> inode -> cgs -> indirects.
 
6254
 *
 
6255
 * The algorithm is as follows:
 
6256
 * 1) Traverse the in-memory state and create journal entries to release
 
6257
 *    the relevant blocks and full indirect trees.
 
6258
 * 2) Traverse the indirect block chain adding partial truncation freework
 
6259
 *    records to indirects in the path to lastlbn.  The freework will
 
6260
 *    prevent new allocation dependencies from being satisfied in this
 
6261
 *    indirect until the truncation completes.
 
6262
 * 3) Read and lock the inode block, performing an update with the new size
 
6263
 *    and pointers.  This prevents truncated data from becoming valid on
 
6264
 *    disk through step 4.
 
6265
 * 4) Reap unsatisfied dependencies that are beyond the truncated area,
 
6266
 *    eliminate journal work for those records that do not require it.
 
6267
 * 5) Schedule the journal records to be written followed by the inode block.
 
6268
 * 6) Allocate any necessary frags for the end of file.
 
6269
 * 7) Zero any partially truncated blocks.
 
6270
 *
 
6271
 * From this truncation proceeds asynchronously using the freework and
 
6272
 * indir_trunc machinery.  The file will not be extended again into a
 
6273
 * partially truncated indirect block until all work is completed but
 
6274
 * the normal dependency mechanism ensures that it is rolled back/forward
 
6275
 * as appropriate.  Further truncation may occur without delay and is
 
6276
 * serialized in indir_trunc().
 
6277
 */
 
6278
void
 
6279
softdep_journal_freeblocks(ip, cred, length, flags)
 
6280
        struct inode *ip;       /* The inode whose length is to be reduced */
 
6281
        struct ucred *cred;
 
6282
        off_t length;           /* The new length for the file */
 
6283
        int flags;              /* IO_EXT and/or IO_NORMAL */
 
6284
{
 
6285
        struct freeblks *freeblks, *fbn;
 
6286
        struct worklist *wk, *wkn;
 
6287
        struct inodedep *inodedep;
 
6288
        struct jblkdep *jblkdep;
 
6289
        struct allocdirect *adp, *adpn;
 
6290
        struct fs *fs;
 
6291
        struct buf *bp;
 
6292
        struct vnode *vp;
 
6293
        struct mount *mp;
 
6294
        ufs2_daddr_t extblocks, datablocks;
 
6295
        ufs_lbn_t tmpval, lbn, lastlbn;
 
6296
        int frags, lastoff, iboff, allocblock, needj, dflags, error, i;
 
6297
 
 
6298
        fs = ip->i_fs;
 
6299
        mp = UFSTOVFS(ip->i_ump);
 
6300
        vp = ITOV(ip);
 
6301
        needj = 1;
 
6302
        iboff = -1;
 
6303
        allocblock = 0;
 
6304
        extblocks = 0;
 
6305
        datablocks = 0;
 
6306
        frags = 0;
 
6307
        freeblks = newfreeblks(mp, ip);
 
6308
        ACQUIRE_LOCK(&lk);
 
6309
        /*
 
6310
         * If we're truncating a removed file that will never be written
 
6311
         * we don't need to journal the block frees.  The canceled journals
 
6312
         * for the allocations will suffice.
 
6313
         */
 
6314
        dflags = DEPALLOC;
 
6315
        if (IS_SNAPSHOT(ip))
 
6316
                dflags |= NODELAY;
 
6317
        inodedep_lookup(mp, ip->i_number, dflags, &inodedep);
 
6318
        if ((inodedep->id_state & (UNLINKED | DEPCOMPLETE)) == UNLINKED &&
 
6319
            length == 0)
 
6320
                needj = 0;
 
6321
        CTR3(KTR_SUJ, "softdep_journal_freeblks: ip %d length %ld needj %d",
 
6322
            ip->i_number, length, needj);
 
6323
        FREE_LOCK(&lk);
 
6324
        /*
 
6325
         * Calculate the lbn that we are truncating to.  This results in -1
 
6326
         * if we're truncating the 0 bytes.  So it is the last lbn we want
 
6327
         * to keep, not the first lbn we want to truncate.
 
6328
         */
 
6329
        lastlbn = lblkno(fs, length + fs->fs_bsize - 1) - 1;
 
6330
        lastoff = blkoff(fs, length);
 
6331
        /*
 
6332
         * Compute frags we are keeping in lastlbn.  0 means all.
 
6333
         */
 
6334
        if (lastlbn >= 0 && lastlbn < NDADDR) {
 
6335
                frags = fragroundup(fs, lastoff);
 
6336
                /* adp offset of last valid allocdirect. */
 
6337
                iboff = lastlbn;
 
6338
        } else if (lastlbn > 0)
 
6339
                iboff = NDADDR;
 
6340
        if (fs->fs_magic == FS_UFS2_MAGIC)
 
6341
                extblocks = btodb(fragroundup(fs, ip->i_din2->di_extsize));
 
6342
        /*
 
6343
         * Handle normal data blocks and indirects.  This section saves
 
6344
         * values used after the inode update to complete frag and indirect
 
6345
         * truncation.
 
6346
         */
 
6347
        if ((flags & IO_NORMAL) != 0) {
 
6348
                /*
 
6349
                 * Handle truncation of whole direct and indirect blocks.
 
6350
                 */
 
6351
                for (i = iboff + 1; i < NDADDR; i++)
 
6352
                        setup_freedirect(freeblks, ip, i, needj);
 
6353
                for (i = 0, tmpval = NINDIR(fs), lbn = NDADDR; i < NIADDR;
 
6354
                    i++, lbn += tmpval, tmpval *= NINDIR(fs)) {
 
6355
                        /* Release a whole indirect tree. */
 
6356
                        if (lbn > lastlbn) {
 
6357
                                setup_freeindir(freeblks, ip, i, -lbn -i,
 
6358
                                    needj);
 
6359
                                continue;
 
6360
                        }
 
6361
                        iboff = i + NDADDR;
 
6362
                        /*
 
6363
                         * Traverse partially truncated indirect tree.
 
6364
                         */
 
6365
                        if (lbn <= lastlbn && lbn + tmpval - 1 > lastlbn)
 
6366
                                setup_trunc_indir(freeblks, ip, -lbn - i,
 
6367
                                    lastlbn, DIP(ip, i_ib[i]));
 
6368
                }
 
6369
                /*
 
6370
                 * Handle partial truncation to a frag boundary.
 
6371
                 */
 
6372
                if (frags) {
 
6373
                        ufs2_daddr_t blkno;
 
6374
                        long oldfrags;
 
6375
 
 
6376
                        oldfrags = blksize(fs, ip, lastlbn);
 
6377
                        blkno = DIP(ip, i_db[lastlbn]);
 
6378
                        if (blkno && oldfrags != frags) {
 
6379
                                oldfrags -= frags;
 
6380
                                oldfrags = numfrags(ip->i_fs, oldfrags);
 
6381
                                blkno += numfrags(ip->i_fs, frags);
 
6382
                                newfreework(ip->i_ump, freeblks, NULL, lastlbn,
 
6383
                                    blkno, oldfrags, 0, needj);
 
6384
                        } else if (blkno == 0)
 
6385
                                allocblock = 1;
 
6386
                }
 
6387
                /*
 
6388
                 * Add a journal record for partial truncate if we are
 
6389
                 * handling indirect blocks.  Non-indirects need no extra
 
6390
                 * journaling.
 
6391
                 */
 
6392
                if (length != 0 && lastlbn >= NDADDR) {
 
6393
                        ip->i_flag |= IN_TRUNCATED;
 
6394
                        newjtrunc(freeblks, length, 0);
 
6395
                }
 
6396
                ip->i_size = length;
 
6397
                DIP_SET(ip, i_size, ip->i_size);
 
6398
                datablocks = DIP(ip, i_blocks) - extblocks;
 
6399
                if (length != 0)
 
6400
                        datablocks = blkcount(ip->i_fs, datablocks, length);
 
6401
                freeblks->fb_len = length;
 
6402
        }
 
6403
        if ((flags & IO_EXT) != 0) {
 
6404
                for (i = 0; i < NXADDR; i++)
 
6405
                        setup_freeext(freeblks, ip, i, needj);
 
6406
                ip->i_din2->di_extsize = 0;
 
6407
                datablocks += extblocks;
 
6408
        }
 
6409
#ifdef QUOTA
 
6410
        /* Reference the quotas in case the block count is wrong in the end. */
 
6411
        quotaref(vp, freeblks->fb_quota);
 
6412
        (void) chkdq(ip, -datablocks, NOCRED, 0);
 
6413
#endif
 
6414
        freeblks->fb_chkcnt = -datablocks;
 
6415
        UFS_LOCK(ip->i_ump);
 
6416
        fs->fs_pendingblocks += datablocks;
 
6417
        UFS_UNLOCK(ip->i_ump);
 
6418
        DIP_SET(ip, i_blocks, DIP(ip, i_blocks) - datablocks);
 
6419
        /*
 
6420
         * Handle truncation of incomplete alloc direct dependencies.  We
 
6421
         * hold the inode block locked to prevent incomplete dependencies
 
6422
         * from reaching the disk while we are eliminating those that
 
6423
         * have been truncated.  This is a partially inlined ffs_update().
 
6424
         */
 
6425
        ufs_itimes(vp);
 
6426
        ip->i_flag &= ~(IN_LAZYACCESS | IN_LAZYMOD | IN_MODIFIED);
 
6427
        error = bread(ip->i_devvp, fsbtodb(fs, ino_to_fsba(fs, ip->i_number)),
 
6428
            (int)fs->fs_bsize, cred, &bp);
 
6429
        if (error) {
 
6430
                brelse(bp);
 
6431
                softdep_error("softdep_journal_freeblocks", error);
 
6432
                return;
 
6433
        }
 
6434
        if (bp->b_bufsize == fs->fs_bsize)
 
6435
                bp->b_flags |= B_CLUSTEROK;
 
6436
        softdep_update_inodeblock(ip, bp, 0);
 
6437
        if (ip->i_ump->um_fstype == UFS1)
 
6438
                *((struct ufs1_dinode *)bp->b_data +
 
6439
                    ino_to_fsbo(fs, ip->i_number)) = *ip->i_din1;
 
6440
        else
 
6441
                *((struct ufs2_dinode *)bp->b_data +
 
6442
                    ino_to_fsbo(fs, ip->i_number)) = *ip->i_din2;
 
6443
        ACQUIRE_LOCK(&lk);
 
6444
        (void) inodedep_lookup(mp, ip->i_number, dflags, &inodedep);
 
6445
        if ((inodedep->id_state & IOSTARTED) != 0)
 
6446
                panic("softdep_setup_freeblocks: inode busy");
 
6447
        /*
 
6448
         * Add the freeblks structure to the list of operations that
 
6449
         * must await the zero'ed inode being written to disk. If we
 
6450
         * still have a bitmap dependency (needj), then the inode
 
6451
         * has never been written to disk, so we can process the
 
6452
         * freeblks below once we have deleted the dependencies.
 
6453
         */
 
6454
        if (needj)
 
6455
                WORKLIST_INSERT(&bp->b_dep, &freeblks->fb_list);
 
6456
        else
 
6457
                freeblks->fb_state |= COMPLETE;
 
6458
        if ((flags & IO_NORMAL) != 0) {
 
6459
                TAILQ_FOREACH_SAFE(adp, &inodedep->id_inoupdt, ad_next, adpn) {
 
6460
                        if (adp->ad_offset > iboff)
 
6461
                                cancel_allocdirect(&inodedep->id_inoupdt, adp,
 
6462
                                    freeblks);
 
6463
                        /*
 
6464
                         * Truncate the allocdirect.  We could eliminate
 
6465
                         * or modify journal records as well.
 
6466
                         */
 
6467
                        else if (adp->ad_offset == iboff && frags)
 
6468
                                adp->ad_newsize = frags;
 
6469
                }
 
6470
        }
 
6471
        if ((flags & IO_EXT) != 0)
 
6472
                while ((adp = TAILQ_FIRST(&inodedep->id_extupdt)) != 0)
 
6473
                        cancel_allocdirect(&inodedep->id_extupdt, adp,
 
6474
                            freeblks);
 
6475
        /*
 
6476
         * Scan the bufwait list for newblock dependencies that will never
 
6477
         * make it to disk.
 
6478
         */
 
6479
        LIST_FOREACH_SAFE(wk, &inodedep->id_bufwait, wk_list, wkn) {
 
6480
                if (wk->wk_type != D_ALLOCDIRECT)
 
6481
                        continue;
 
6482
                adp = WK_ALLOCDIRECT(wk);
 
6483
                if (((flags & IO_NORMAL) != 0 && (adp->ad_offset > iboff)) ||
 
6484
                    ((flags & IO_EXT) != 0 && (adp->ad_state & EXTDATA))) {
 
6485
                        cancel_jfreeblk(freeblks, adp->ad_newblkno);
 
6486
                        cancel_newblk(WK_NEWBLK(wk), NULL, &freeblks->fb_jwork);
 
6487
                        WORKLIST_INSERT(&freeblks->fb_freeworkhd, wk);
 
6488
                }
 
6489
        }
 
6490
        /*
 
6491
         * Add journal work.
 
6492
         */
 
6493
        LIST_FOREACH(jblkdep, &freeblks->fb_jblkdephd, jb_deps)
 
6494
                add_to_journal(&jblkdep->jb_list);
 
6495
        FREE_LOCK(&lk);
 
6496
        bdwrite(bp);
 
6497
        /*
 
6498
         * Truncate dependency structures beyond length.
 
6499
         */
 
6500
        trunc_dependencies(ip, freeblks, lastlbn, frags, flags);
 
6501
        /*
 
6502
         * This is only set when we need to allocate a fragment because
 
6503
         * none existed at the end of a frag-sized file.  It handles only
 
6504
         * allocating a new, zero filled block.
 
6505
         */
 
6506
        if (allocblock) {
 
6507
                ip->i_size = length - lastoff;
 
6508
                DIP_SET(ip, i_size, ip->i_size);
 
6509
                error = UFS_BALLOC(vp, length - 1, 1, cred, BA_CLRBUF, &bp);
 
6510
                if (error != 0) {
 
6511
                        softdep_error("softdep_journal_freeblks", error);
 
6512
                        return;
 
6513
                }
 
6514
                ip->i_size = length;
 
6515
                DIP_SET(ip, i_size, length);
 
6516
                ip->i_flag |= IN_CHANGE | IN_UPDATE;
 
6517
                allocbuf(bp, frags);
 
6518
                ffs_update(vp, 0);
 
6519
                bawrite(bp);
 
6520
        } else if (lastoff != 0 && vp->v_type != VDIR) {
 
6521
                int size;
 
6522
 
 
6523
                /*
 
6524
                 * Zero the end of a truncated frag or block.
 
6525
                 */
 
6526
                size = sblksize(fs, length, lastlbn);
 
6527
                error = bread(vp, lastlbn, size, cred, &bp);
 
6528
                if (error) {
 
6529
                        softdep_error("softdep_journal_freeblks", error);
 
6530
                        return;
 
6531
                }
 
6532
                bzero((char *)bp->b_data + lastoff, size - lastoff);
 
6533
                bawrite(bp);
 
6534
 
 
6535
        }
 
6536
        ACQUIRE_LOCK(&lk);
 
6537
        inodedep_lookup(mp, ip->i_number, dflags, &inodedep);
 
6538
        TAILQ_INSERT_TAIL(&inodedep->id_freeblklst, freeblks, fb_next);
 
6539
        freeblks->fb_state |= DEPCOMPLETE | ONDEPLIST;
 
6540
        /*
 
6541
         * We zero earlier truncations so they don't erroneously
 
6542
         * update i_blocks.
 
6543
         */
 
6544
        if (freeblks->fb_len == 0 && (flags & IO_NORMAL) != 0)
 
6545
                TAILQ_FOREACH(fbn, &inodedep->id_freeblklst, fb_next)
 
6546
                        fbn->fb_len = 0;
 
6547
        if ((freeblks->fb_state & ALLCOMPLETE) == ALLCOMPLETE &&
 
6548
            LIST_EMPTY(&freeblks->fb_jblkdephd))
 
6549
                freeblks->fb_state |= INPROGRESS;
 
6550
        else
 
6551
                freeblks = NULL;
 
6552
        FREE_LOCK(&lk);
 
6553
        if (freeblks)
 
6554
                handle_workitem_freeblocks(freeblks, 0);
 
6555
        trunc_pages(ip, length, extblocks, flags);
 
6556
 
 
6557
}
 
6558
 
 
6559
/*
 
6560
 * Flush a JOP_SYNC to the journal.
 
6561
 */
 
6562
void
 
6563
softdep_journal_fsync(ip)
 
6564
        struct inode *ip;
 
6565
{
 
6566
        struct jfsync *jfsync;
 
6567
 
 
6568
        if ((ip->i_flag & IN_TRUNCATED) == 0)
 
6569
                return;
 
6570
        ip->i_flag &= ~IN_TRUNCATED;
 
6571
        jfsync = malloc(sizeof(*jfsync), M_JFSYNC, M_SOFTDEP_FLAGS | M_ZERO);
 
6572
        workitem_alloc(&jfsync->jfs_list, D_JFSYNC, UFSTOVFS(ip->i_ump));
 
6573
        jfsync->jfs_size = ip->i_size;
 
6574
        jfsync->jfs_ino = ip->i_number;
 
6575
        ACQUIRE_LOCK(&lk);
 
6576
        add_to_journal(&jfsync->jfs_list);
 
6577
        jwait(&jfsync->jfs_list, MNT_WAIT);
 
6578
        FREE_LOCK(&lk);
2169
6579
}
2170
6580
 
2171
6581
/*
2203
6613
        off_t length;           /* The new length for the file */
2204
6614
        int flags;              /* IO_EXT and/or IO_NORMAL */
2205
6615
{
 
6616
        struct ufs1_dinode *dp1;
 
6617
        struct ufs2_dinode *dp2;
2206
6618
        struct freeblks *freeblks;
2207
6619
        struct inodedep *inodedep;
2208
6620
        struct allocdirect *adp;
2209
 
        struct bufobj *bo;
2210
 
        struct vnode *vp;
2211
6621
        struct buf *bp;
2212
6622
        struct fs *fs;
2213
6623
        ufs2_daddr_t extblocks, datablocks;
2214
6624
        struct mount *mp;
2215
 
        int i, delay, error;
 
6625
        int i, delay, error, dflags;
 
6626
        ufs_lbn_t tmpval;
 
6627
        ufs_lbn_t lbn;
2216
6628
 
 
6629
        CTR2(KTR_SUJ, "softdep_setup_freeblks: ip %d length %ld",
 
6630
            ip->i_number, length);
2217
6631
        fs = ip->i_fs;
2218
6632
        mp = UFSTOVFS(ip->i_ump);
2219
6633
        if (length != 0)
2220
6634
                panic("softdep_setup_freeblocks: non-zero length");
2221
 
        freeblks = malloc(sizeof(struct freeblks),
2222
 
                M_FREEBLKS, M_SOFTDEP_FLAGS|M_ZERO);
2223
 
        workitem_alloc(&freeblks->fb_list, D_FREEBLKS, mp);
2224
 
        freeblks->fb_state = ATTACHED;
2225
 
        freeblks->fb_uid = ip->i_uid;
2226
 
        freeblks->fb_previousinum = ip->i_number;
2227
 
        freeblks->fb_devvp = ip->i_devvp;
2228
 
        ACQUIRE_LOCK(&lk);
2229
 
        num_freeblkdep++;
2230
 
        FREE_LOCK(&lk);
 
6635
        freeblks = newfreeblks(mp, ip);
2231
6636
        extblocks = 0;
 
6637
        datablocks = 0;
2232
6638
        if (fs->fs_magic == FS_UFS2_MAGIC)
2233
6639
                extblocks = btodb(fragroundup(fs, ip->i_din2->di_extsize));
2234
 
        datablocks = DIP(ip, i_blocks) - extblocks;
2235
 
        if ((flags & IO_NORMAL) == 0) {
2236
 
                freeblks->fb_oldsize = 0;
2237
 
                freeblks->fb_chkcnt = 0;
2238
 
        } else {
2239
 
                freeblks->fb_oldsize = ip->i_size;
 
6640
        if ((flags & IO_NORMAL) != 0) {
 
6641
                for (i = 0; i < NDADDR; i++)
 
6642
                        setup_freedirect(freeblks, ip, i, 0);
 
6643
                for (i = 0, tmpval = NINDIR(fs), lbn = NDADDR; i < NIADDR;
 
6644
                    i++, lbn += tmpval, tmpval *= NINDIR(fs))
 
6645
                        setup_freeindir(freeblks, ip, i, -lbn -i, 0);
2240
6646
                ip->i_size = 0;
2241
6647
                DIP_SET(ip, i_size, 0);
2242
 
                freeblks->fb_chkcnt = datablocks;
2243
 
                for (i = 0; i < NDADDR; i++) {
2244
 
                        freeblks->fb_dblks[i] = DIP(ip, i_db[i]);
2245
 
                        DIP_SET(ip, i_db[i], 0);
2246
 
                }
2247
 
                for (i = 0; i < NIADDR; i++) {
2248
 
                        freeblks->fb_iblks[i] = DIP(ip, i_ib[i]);
2249
 
                        DIP_SET(ip, i_ib[i], 0);
2250
 
                }
2251
 
                /*
2252
 
                 * If the file was removed, then the space being freed was
2253
 
                 * accounted for then (see softdep_releasefile()). If the
2254
 
                 * file is merely being truncated, then we account for it now.
2255
 
                 */
2256
 
                if ((ip->i_flag & IN_SPACECOUNTED) == 0) {
2257
 
                        UFS_LOCK(ip->i_ump);
2258
 
                        fs->fs_pendingblocks += datablocks;
2259
 
                        UFS_UNLOCK(ip->i_ump);
2260
 
                }
 
6648
                datablocks = DIP(ip, i_blocks) - extblocks;
2261
6649
        }
2262
 
        if ((flags & IO_EXT) == 0) {
2263
 
                freeblks->fb_oldextsize = 0;
2264
 
        } else {
2265
 
                freeblks->fb_oldextsize = ip->i_din2->di_extsize;
 
6650
        if ((flags & IO_EXT) != 0) {
 
6651
                for (i = 0; i < NXADDR; i++)
 
6652
                        setup_freeext(freeblks, ip, i, 0);
2266
6653
                ip->i_din2->di_extsize = 0;
2267
 
                freeblks->fb_chkcnt += extblocks;
2268
 
                for (i = 0; i < NXADDR; i++) {
2269
 
                        freeblks->fb_eblks[i] = ip->i_din2->di_extb[i];
2270
 
                        ip->i_din2->di_extb[i] = 0;
2271
 
                }
 
6654
                datablocks += extblocks;
2272
6655
        }
2273
 
        DIP_SET(ip, i_blocks, DIP(ip, i_blocks) - freeblks->fb_chkcnt);
 
6656
#ifdef QUOTA
 
6657
        /* Reference the quotas in case the block count is wrong in the end. */
 
6658
        quotaref(ITOV(ip), freeblks->fb_quota);
 
6659
        (void) chkdq(ip, -datablocks, NOCRED, 0);
 
6660
#endif
 
6661
        freeblks->fb_chkcnt = -datablocks;
 
6662
        UFS_LOCK(ip->i_ump);
 
6663
        fs->fs_pendingblocks += datablocks;
 
6664
        UFS_UNLOCK(ip->i_ump);
 
6665
        DIP_SET(ip, i_blocks, DIP(ip, i_blocks) - datablocks);
2274
6666
        /*
2275
6667
         * Push the zero'ed inode to to its disk buffer so that we are free
2276
6668
         * to delete its dependencies below. Once the dependencies are gone
2282
6674
                brelse(bp);
2283
6675
                softdep_error("softdep_setup_freeblocks", error);
2284
6676
        }
2285
 
        if (ip->i_ump->um_fstype == UFS1)
2286
 
                *((struct ufs1_dinode *)bp->b_data +
2287
 
                    ino_to_fsbo(fs, ip->i_number)) = *ip->i_din1;
2288
 
        else
2289
 
                *((struct ufs2_dinode *)bp->b_data +
2290
 
                    ino_to_fsbo(fs, ip->i_number)) = *ip->i_din2;
 
6677
        if (ip->i_ump->um_fstype == UFS1) {
 
6678
                dp1 = ((struct ufs1_dinode *)bp->b_data +
 
6679
                    ino_to_fsbo(fs, ip->i_number));
 
6680
                ip->i_din1->di_freelink = dp1->di_freelink;
 
6681
                *dp1 = *ip->i_din1;
 
6682
        } else {
 
6683
                dp2 = ((struct ufs2_dinode *)bp->b_data +
 
6684
                    ino_to_fsbo(fs, ip->i_number));
 
6685
                ip->i_din2->di_freelink = dp2->di_freelink;
 
6686
                *dp2 = *ip->i_din2;
 
6687
        }
2291
6688
        /*
2292
6689
         * Find and eliminate any inode dependencies.
2293
6690
         */
2294
6691
        ACQUIRE_LOCK(&lk);
2295
 
        (void) inodedep_lookup(mp, ip->i_number, DEPALLOC, &inodedep);
 
6692
        dflags = DEPALLOC;
 
6693
        if (IS_SNAPSHOT(ip))
 
6694
                dflags |= NODELAY;
 
6695
        (void) inodedep_lookup(mp, ip->i_number, dflags, &inodedep);
2296
6696
        if ((inodedep->id_state & IOSTARTED) != 0)
2297
6697
                panic("softdep_setup_freeblocks: inode busy");
2298
6698
        /*
2304
6704
         */
2305
6705
        delay = (inodedep->id_state & DEPCOMPLETE);
2306
6706
        if (delay)
2307
 
                WORKLIST_INSERT(&inodedep->id_bufwait, &freeblks->fb_list);
 
6707
                WORKLIST_INSERT(&bp->b_dep, &freeblks->fb_list);
 
6708
        else
 
6709
                freeblks->fb_state |= COMPLETE;
2308
6710
        /*
2309
6711
         * Because the file length has been truncated to zero, any
2310
6712
         * pending block allocation dependency structures associated
2318
6720
                merge_inode_lists(&inodedep->id_newinoupdt,
2319
6721
                    &inodedep->id_inoupdt);
2320
6722
                while ((adp = TAILQ_FIRST(&inodedep->id_inoupdt)) != 0)
2321
 
                        free_allocdirect(&inodedep->id_inoupdt, adp, delay);
 
6723
                        cancel_allocdirect(&inodedep->id_inoupdt, adp,
 
6724
                            freeblks);
2322
6725
        }
2323
6726
        if (flags & IO_EXT) {
2324
6727
                merge_inode_lists(&inodedep->id_newextupdt,
2325
6728
                    &inodedep->id_extupdt);
2326
6729
                while ((adp = TAILQ_FIRST(&inodedep->id_extupdt)) != 0)
2327
 
                        free_allocdirect(&inodedep->id_extupdt, adp, delay);
 
6730
                        cancel_allocdirect(&inodedep->id_extupdt, adp,
 
6731
                            freeblks);
2328
6732
        }
2329
6733
        FREE_LOCK(&lk);
2330
6734
        bdwrite(bp);
 
6735
        trunc_dependencies(ip, freeblks, -1, 0, flags);
 
6736
        ACQUIRE_LOCK(&lk);
 
6737
        if (inodedep_lookup(mp, ip->i_number, 0, &inodedep) != 0)
 
6738
                (void) free_inodedep(inodedep);
 
6739
        freeblks->fb_state |= DEPCOMPLETE;
 
6740
        /*
 
6741
         * If the inode with zeroed block pointers is now on disk
 
6742
         * we can start freeing blocks.
 
6743
         */  
 
6744
        if ((freeblks->fb_state & ALLCOMPLETE) == ALLCOMPLETE)
 
6745
                freeblks->fb_state |= INPROGRESS;
 
6746
        else
 
6747
                freeblks = NULL;
 
6748
        FREE_LOCK(&lk);
 
6749
        if (freeblks)
 
6750
                handle_workitem_freeblocks(freeblks, 0);
 
6751
        trunc_pages(ip, length, extblocks, flags);
 
6752
}
 
6753
 
 
6754
/*
 
6755
 * Eliminate pages from the page cache that back parts of this inode and
 
6756
 * adjust the vnode pager's idea of our size.  This prevents stale data
 
6757
 * from hanging around in the page cache.
 
6758
 */
 
6759
static void
 
6760
trunc_pages(ip, length, extblocks, flags)
 
6761
        struct inode *ip;
 
6762
        off_t length;
 
6763
        ufs2_daddr_t extblocks;
 
6764
        int flags;
 
6765
{
 
6766
        struct vnode *vp;
 
6767
        struct fs *fs;
 
6768
        ufs_lbn_t lbn;
 
6769
        off_t end, extend;
 
6770
 
 
6771
        vp = ITOV(ip);
 
6772
        fs = ip->i_fs;
 
6773
        extend = OFF_TO_IDX(lblktosize(fs, -extblocks));
 
6774
        if ((flags & IO_EXT) != 0)
 
6775
                vn_pages_remove(vp, extend, 0);
 
6776
        if ((flags & IO_NORMAL) == 0)
 
6777
                return;
 
6778
        BO_LOCK(&vp->v_bufobj);
 
6779
        drain_output(vp);
 
6780
        BO_UNLOCK(&vp->v_bufobj);
 
6781
        /*
 
6782
         * The vnode pager eliminates file pages we eliminate indirects
 
6783
         * below.
 
6784
         */
 
6785
        vnode_pager_setsize(vp, length);
 
6786
        /*
 
6787
         * Calculate the end based on the last indirect we want to keep.  If
 
6788
         * the block extends into indirects we can just use the negative of
 
6789
         * its lbn.  Doubles and triples exist at lower numbers so we must
 
6790
         * be careful not to remove those, if they exist.  double and triple
 
6791
         * indirect lbns do not overlap with others so it is not important
 
6792
         * to verify how many levels are required.
 
6793
         */
 
6794
        lbn = lblkno(fs, length);
 
6795
        if (lbn >= NDADDR) {
 
6796
                /* Calculate the virtual lbn of the triple indirect. */
 
6797
                lbn = -lbn - (NIADDR - 1);
 
6798
                end = OFF_TO_IDX(lblktosize(fs, lbn));
 
6799
        } else
 
6800
                end = extend;
 
6801
        vn_pages_remove(vp, OFF_TO_IDX(OFF_MAX), end);
 
6802
}
 
6803
 
 
6804
/*
 
6805
 * See if the buf bp is in the range eliminated by truncation.
 
6806
 */
 
6807
static int
 
6808
trunc_check_buf(bp, blkoffp, lastlbn, lastoff, flags)
 
6809
        struct buf *bp;
 
6810
        int *blkoffp;
 
6811
        ufs_lbn_t lastlbn;
 
6812
        int lastoff;
 
6813
        int flags;
 
6814
{
 
6815
        ufs_lbn_t lbn;
 
6816
 
 
6817
        *blkoffp = 0;
 
6818
        /* Only match ext/normal blocks as appropriate. */
 
6819
        if (((flags & IO_EXT) == 0 && (bp->b_xflags & BX_ALTDATA)) ||
 
6820
            ((flags & IO_NORMAL) == 0 && (bp->b_xflags & BX_ALTDATA) == 0))
 
6821
                return (0);
 
6822
        /* ALTDATA is always a full truncation. */
 
6823
        if ((bp->b_xflags & BX_ALTDATA) != 0)
 
6824
                return (1);
 
6825
        /* -1 is full truncation. */
 
6826
        if (lastlbn == -1)
 
6827
                return (1);
 
6828
        /*
 
6829
         * If this is a partial truncate we only want those
 
6830
         * blocks and indirect blocks that cover the range
 
6831
         * we're after.
 
6832
         */
 
6833
        lbn = bp->b_lblkno;
 
6834
        if (lbn < 0)
 
6835
                lbn = -(lbn + lbn_level(lbn));
 
6836
        if (lbn < lastlbn)
 
6837
                return (0);
 
6838
        /* Here we only truncate lblkno if it's partial. */
 
6839
        if (lbn == lastlbn) {
 
6840
                if (lastoff == 0)
 
6841
                        return (0);
 
6842
                *blkoffp = lastoff;
 
6843
        }
 
6844
        return (1);
 
6845
}
 
6846
 
 
6847
/*
 
6848
 * Eliminate any dependencies that exist in memory beyond lblkno:off
 
6849
 */
 
6850
static void
 
6851
trunc_dependencies(ip, freeblks, lastlbn, lastoff, flags)
 
6852
        struct inode *ip;
 
6853
        struct freeblks *freeblks;
 
6854
        ufs_lbn_t lastlbn;
 
6855
        int lastoff;
 
6856
        int flags;
 
6857
{
 
6858
        struct bufobj *bo;
 
6859
        struct vnode *vp;
 
6860
        struct buf *bp;
 
6861
        struct fs *fs;
 
6862
        int blkoff;
 
6863
 
2331
6864
        /*
2332
6865
         * We must wait for any I/O in progress to finish so that
2333
6866
         * all potential buffers on the dirty list will be visible.
2334
6867
         * Once they are all there, walk the list and get rid of
2335
6868
         * any dependencies.
2336
6869
         */
 
6870
        fs = ip->i_fs;
2337
6871
        vp = ITOV(ip);
2338
6872
        bo = &vp->v_bufobj;
2339
6873
        BO_LOCK(bo);
2340
6874
        drain_output(vp);
 
6875
        TAILQ_FOREACH(bp, &bo->bo_dirty.bv_hd, b_bobufs)
 
6876
                bp->b_vflags &= ~BV_SCANNED;
2341
6877
restart:
2342
6878
        TAILQ_FOREACH(bp, &bo->bo_dirty.bv_hd, b_bobufs) {
2343
 
                if (((flags & IO_EXT) == 0 && (bp->b_xflags & BX_ALTDATA)) ||
2344
 
                    ((flags & IO_NORMAL) == 0 &&
2345
 
                      (bp->b_xflags & BX_ALTDATA) == 0))
2346
 
                        continue;
 
6879
                if (bp->b_vflags & BV_SCANNED)
 
6880
                        continue;
 
6881
                if (!trunc_check_buf(bp, &blkoff, lastlbn, lastoff, flags)) {
 
6882
                        bp->b_vflags |= BV_SCANNED;
 
6883
                        continue;
 
6884
                }
2347
6885
                if ((bp = getdirtybuf(bp, BO_MTX(bo), MNT_WAIT)) == NULL)
2348
6886
                        goto restart;
2349
6887
                BO_UNLOCK(bo);
2350
 
                ACQUIRE_LOCK(&lk);
2351
 
                (void) inodedep_lookup(mp, ip->i_number, 0, &inodedep);
2352
 
                deallocate_dependencies(bp, inodedep);
2353
 
                FREE_LOCK(&lk);
2354
 
                bp->b_flags |= B_INVAL | B_NOCACHE;
2355
 
                brelse(bp);
 
6888
                if (deallocate_dependencies(bp, freeblks, blkoff))
 
6889
                        bqrelse(bp);
 
6890
                else
 
6891
                        brelse(bp);
2356
6892
                BO_LOCK(bo);
2357
6893
                goto restart;
2358
6894
        }
 
6895
        /*
 
6896
         * Now do the work of vtruncbuf while also matching indirect blocks.
 
6897
         */
 
6898
        TAILQ_FOREACH(bp, &bo->bo_clean.bv_hd, b_bobufs)
 
6899
                bp->b_vflags &= ~BV_SCANNED;
 
6900
cleanrestart:
 
6901
        TAILQ_FOREACH(bp, &bo->bo_clean.bv_hd, b_bobufs) {
 
6902
                if (bp->b_vflags & BV_SCANNED)
 
6903
                        continue;
 
6904
                if (!trunc_check_buf(bp, &blkoff, lastlbn, lastoff, flags)) {
 
6905
                        bp->b_vflags |= BV_SCANNED;
 
6906
                        continue;
 
6907
                }
 
6908
                if (BUF_LOCK(bp,
 
6909
                    LK_EXCLUSIVE | LK_SLEEPFAIL | LK_INTERLOCK,
 
6910
                    BO_MTX(bo)) == ENOLCK) {
 
6911
                        BO_LOCK(bo);
 
6912
                        goto cleanrestart;
 
6913
                }
 
6914
                bp->b_vflags |= BV_SCANNED;
 
6915
                BO_LOCK(bo);
 
6916
                bremfree(bp);
 
6917
                BO_UNLOCK(bo);
 
6918
                if (blkoff != 0) {
 
6919
                        allocbuf(bp, blkoff);
 
6920
                        bqrelse(bp);
 
6921
                } else {
 
6922
                        bp->b_flags |= B_INVAL | B_NOCACHE | B_RELBUF;
 
6923
                        brelse(bp);
 
6924
                }
 
6925
                BO_LOCK(bo);
 
6926
                goto cleanrestart;
 
6927
        }
 
6928
        drain_output(vp);
2359
6929
        BO_UNLOCK(bo);
2360
 
        ACQUIRE_LOCK(&lk);
2361
 
        if (inodedep_lookup(mp, ip->i_number, 0, &inodedep) != 0)
2362
 
                (void) free_inodedep(inodedep);
2363
 
 
2364
 
        if(delay) {
2365
 
                freeblks->fb_state |= DEPCOMPLETE;
 
6930
}
 
6931
 
 
6932
static int
 
6933
cancel_pagedep(pagedep, freeblks, blkoff)
 
6934
        struct pagedep *pagedep;
 
6935
        struct freeblks *freeblks;
 
6936
        int blkoff;
 
6937
{
 
6938
        struct jremref *jremref;
 
6939
        struct jmvref *jmvref;
 
6940
        struct dirrem *dirrem, *tmp;
 
6941
        int i;
 
6942
 
 
6943
        /*
 
6944
         * Copy any directory remove dependencies to the list
 
6945
         * to be processed after the freeblks proceeds.  If
 
6946
         * directory entry never made it to disk they
 
6947
         * can be dumped directly onto the work list.
 
6948
         */
 
6949
        LIST_FOREACH_SAFE(dirrem, &pagedep->pd_dirremhd, dm_next, tmp) {
 
6950
                /* Skip this directory removal if it is intended to remain. */
 
6951
                if (dirrem->dm_offset < blkoff)
 
6952
                        continue;
2366
6953
                /*
2367
 
                 * If the inode with zeroed block pointers is now on disk
2368
 
                 * we can start freeing blocks. Add freeblks to the worklist
2369
 
                 * instead of calling  handle_workitem_freeblocks directly as
2370
 
                 * it is more likely that additional IO is needed to complete
2371
 
                 * the request here than in the !delay case.
2372
 
                 */  
2373
 
                if ((freeblks->fb_state & ALLCOMPLETE) == ALLCOMPLETE)
2374
 
                        add_to_worklist(&freeblks->fb_list);
2375
 
        }
 
6954
                 * If there are any dirrems we wait for the journal write
 
6955
                 * to complete and then restart the buf scan as the lock
 
6956
                 * has been dropped.
 
6957
                 */
 
6958
                while ((jremref = LIST_FIRST(&dirrem->dm_jremrefhd)) != NULL) {
 
6959
                        jwait(&jremref->jr_list, MNT_WAIT);
 
6960
                        return (ERESTART);
 
6961
                }
 
6962
                LIST_REMOVE(dirrem, dm_next);
 
6963
                dirrem->dm_dirinum = pagedep->pd_ino;
 
6964
                WORKLIST_INSERT(&freeblks->fb_freeworkhd, &dirrem->dm_list);
 
6965
        }
 
6966
        while ((jmvref = LIST_FIRST(&pagedep->pd_jmvrefhd)) != NULL) {
 
6967
                jwait(&jmvref->jm_list, MNT_WAIT);
 
6968
                return (ERESTART);
 
6969
        }
 
6970
        /*
 
6971
         * When we're partially truncating a pagedep we just want to flush
 
6972
         * journal entries and return.  There can not be any adds in the
 
6973
         * truncated portion of the directory and newblk must remain if
 
6974
         * part of the block remains.
 
6975
         */
 
6976
        if (blkoff != 0) {
 
6977
                struct diradd *dap;
2376
6978
 
2377
 
        FREE_LOCK(&lk);
 
6979
                LIST_FOREACH(dap, &pagedep->pd_pendinghd, da_pdlist)
 
6980
                        if (dap->da_offset > blkoff)
 
6981
                                panic("cancel_pagedep: diradd %p off %d > %d",
 
6982
                                    dap, dap->da_offset, blkoff);
 
6983
                for (i = 0; i < DAHASHSZ; i++)
 
6984
                        LIST_FOREACH(dap, &pagedep->pd_diraddhd[i], da_pdlist)
 
6985
                                if (dap->da_offset > blkoff)
 
6986
                                        panic("cancel_pagedep: diradd %p off %d > %d",
 
6987
                                            dap, dap->da_offset, blkoff);
 
6988
                return (0);
 
6989
        }
2378
6990
        /*
2379
 
         * If the inode has never been written to disk (delay == 0),
2380
 
         * then we can process the freeblks now that we have deleted
2381
 
         * the dependencies.
 
6991
         * There should be no directory add dependencies present
 
6992
         * as the directory could not be truncated until all
 
6993
         * children were removed.
2382
6994
         */
2383
 
        if (!delay)
2384
 
                handle_workitem_freeblocks(freeblks, 0);
 
6995
        KASSERT(LIST_FIRST(&pagedep->pd_pendinghd) == NULL,
 
6996
            ("deallocate_dependencies: pendinghd != NULL"));
 
6997
        for (i = 0; i < DAHASHSZ; i++)
 
6998
                KASSERT(LIST_FIRST(&pagedep->pd_diraddhd[i]) == NULL,
 
6999
                    ("deallocate_dependencies: diraddhd != NULL"));
 
7000
        if ((pagedep->pd_state & NEWBLOCK) != 0)
 
7001
                free_newdirblk(pagedep->pd_newdirblk);
 
7002
        if (free_pagedep(pagedep) == 0)
 
7003
                panic("Failed to free pagedep %p", pagedep);
 
7004
        return (0);
2385
7005
}
2386
7006
 
2387
7007
/*
2391
7011
 * its associated dependencies. The mutex is held so that other I/O's
2392
7012
 * associated with related dependencies do not occur.
2393
7013
 */
2394
 
static void
2395
 
deallocate_dependencies(bp, inodedep)
 
7014
static int
 
7015
deallocate_dependencies(bp, freeblks, off)
2396
7016
        struct buf *bp;
2397
 
        struct inodedep *inodedep;
 
7017
        struct freeblks *freeblks;
 
7018
        int off;
2398
7019
{
2399
 
        struct worklist *wk;
2400
7020
        struct indirdep *indirdep;
2401
 
        struct allocindir *aip;
2402
7021
        struct pagedep *pagedep;
2403
 
        struct dirrem *dirrem;
2404
 
        struct diradd *dap;
2405
 
        int i;
 
7022
        struct allocdirect *adp;
 
7023
        struct worklist *wk, *wkn;
2406
7024
 
2407
 
        mtx_assert(&lk, MA_OWNED);
2408
 
        while ((wk = LIST_FIRST(&bp->b_dep)) != NULL) {
 
7025
        ACQUIRE_LOCK(&lk);
 
7026
        LIST_FOREACH_SAFE(wk, &bp->b_dep, wk_list, wkn) {
2409
7027
                switch (wk->wk_type) {
2410
 
 
2411
7028
                case D_INDIRDEP:
2412
7029
                        indirdep = WK_INDIRDEP(wk);
2413
 
                        /*
2414
 
                         * None of the indirect pointers will ever be visible,
2415
 
                         * so they can simply be tossed. GOINGAWAY ensures
2416
 
                         * that allocated pointers will be saved in the buffer
2417
 
                         * cache until they are freed. Note that they will
2418
 
                         * only be able to be found by their physical address
2419
 
                         * since the inode mapping the logical address will
2420
 
                         * be gone. The save buffer used for the safe copy
2421
 
                         * was allocated in setup_allocindir_phase2 using
2422
 
                         * the physical address so it could be used for this
2423
 
                         * purpose. Hence we swap the safe copy with the real
2424
 
                         * copy, allowing the safe copy to be freed and holding
2425
 
                         * on to the real copy for later use in indir_trunc.
2426
 
                         */
2427
 
                        if (indirdep->ir_state & GOINGAWAY)
2428
 
                                panic("deallocate_dependencies: already gone");
2429
 
                        indirdep->ir_state |= GOINGAWAY;
2430
 
                        VFSTOUFS(bp->b_vp->v_mount)->um_numindirdeps += 1;
2431
 
                        while ((aip = LIST_FIRST(&indirdep->ir_deplisthd)) != 0)
2432
 
                                free_allocindir(aip, inodedep);
2433
7030
                        if (bp->b_lblkno >= 0 ||
2434
7031
                            bp->b_blkno != indirdep->ir_savebp->b_lblkno)
2435
7032
                                panic("deallocate_dependencies: not indir");
2436
 
                        bcopy(bp->b_data, indirdep->ir_savebp->b_data,
2437
 
                            bp->b_bcount);
2438
 
                        WORKLIST_REMOVE(wk);
2439
 
                        WORKLIST_INSERT(&indirdep->ir_savebp->b_dep, wk);
 
7033
                        cancel_indirdep(indirdep, bp, freeblks);
2440
7034
                        continue;
2441
7035
 
2442
7036
                case D_PAGEDEP:
2443
7037
                        pagedep = WK_PAGEDEP(wk);
2444
 
                        /*
2445
 
                         * None of the directory additions will ever be
2446
 
                         * visible, so they can simply be tossed.
2447
 
                         */
2448
 
                        for (i = 0; i < DAHASHSZ; i++)
2449
 
                                while ((dap =
2450
 
                                    LIST_FIRST(&pagedep->pd_diraddhd[i])))
2451
 
                                        free_diradd(dap);
2452
 
                        while ((dap = LIST_FIRST(&pagedep->pd_pendinghd)) != 0)
2453
 
                                free_diradd(dap);
2454
 
                        /*
2455
 
                         * Copy any directory remove dependencies to the list
2456
 
                         * to be processed after the zero'ed inode is written.
2457
 
                         * If the inode has already been written, then they 
2458
 
                         * can be dumped directly onto the work list.
2459
 
                         */
2460
 
                        LIST_FOREACH(dirrem, &pagedep->pd_dirremhd, dm_next) {
2461
 
                                LIST_REMOVE(dirrem, dm_next);
2462
 
                                dirrem->dm_dirinum = pagedep->pd_ino;
2463
 
                                if (inodedep == NULL ||
2464
 
                                    (inodedep->id_state & ALLCOMPLETE) ==
2465
 
                                     ALLCOMPLETE)
2466
 
                                        add_to_worklist(&dirrem->dm_list);
2467
 
                                else
2468
 
                                        WORKLIST_INSERT(&inodedep->id_bufwait,
2469
 
                                            &dirrem->dm_list);
2470
 
                        }
2471
 
                        if ((pagedep->pd_state & NEWBLOCK) != 0) {
2472
 
                                LIST_FOREACH(wk, &inodedep->id_bufwait, wk_list)
2473
 
                                        if (wk->wk_type == D_NEWDIRBLK &&
2474
 
                                            WK_NEWDIRBLK(wk)->db_pagedep ==
2475
 
                                              pagedep)
2476
 
                                                break;
2477
 
                                if (wk != NULL) {
2478
 
                                        WORKLIST_REMOVE(wk);
2479
 
                                        free_newdirblk(WK_NEWDIRBLK(wk));
2480
 
                                } else
2481
 
                                        panic("deallocate_dependencies: "
2482
 
                                              "lost pagedep");
2483
 
                        }
2484
 
                        WORKLIST_REMOVE(&pagedep->pd_list);
2485
 
                        LIST_REMOVE(pagedep, pd_hash);
2486
 
                        WORKITEM_FREE(pagedep, D_PAGEDEP);
 
7038
                        if (cancel_pagedep(pagedep, freeblks, off)) {
 
7039
                                FREE_LOCK(&lk);
 
7040
                                return (ERESTART);
 
7041
                        }
2487
7042
                        continue;
2488
7043
 
2489
7044
                case D_ALLOCINDIR:
2490
 
                        free_allocindir(WK_ALLOCINDIR(wk), inodedep);
 
7045
                        /*
 
7046
                         * Simply remove the allocindir, we'll find it via
 
7047
                         * the indirdep where we can clear pointers if
 
7048
                         * needed.
 
7049
                         */
 
7050
                        WORKLIST_REMOVE(wk);
2491
7051
                        continue;
2492
7052
 
 
7053
                case D_FREEWORK:
 
7054
                        /*
 
7055
                         * A truncation is waiting for the zero'd pointers
 
7056
                         * to be written.  It can be freed when the freeblks
 
7057
                         * is journaled.
 
7058
                         */
 
7059
                        WORKLIST_REMOVE(wk);
 
7060
                        wk->wk_state |= ONDEPLIST;
 
7061
                        WORKLIST_INSERT(&freeblks->fb_freeworkhd, wk);
 
7062
                        break;
 
7063
 
2493
7064
                case D_ALLOCDIRECT:
2494
 
                case D_INODEDEP:
 
7065
                        adp = WK_ALLOCDIRECT(wk);
 
7066
                        if (off != 0)
 
7067
                                continue;
 
7068
                        /* FALLTHROUGH */
 
7069
                default:
2495
7070
                        panic("deallocate_dependencies: Unexpected type %s",
2496
7071
                            TYPENAME(wk->wk_type));
2497
7072
                        /* NOTREACHED */
2498
 
 
2499
 
                default:
2500
 
                        panic("deallocate_dependencies: Unknown type %s",
2501
 
                            TYPENAME(wk->wk_type));
2502
 
                        /* NOTREACHED */
2503
7073
                }
2504
7074
        }
 
7075
        FREE_LOCK(&lk);
 
7076
        /*
 
7077
         * Don't throw away this buf, we were partially truncating and
 
7078
         * some deps may always remain.
 
7079
         */
 
7080
        if (off) {
 
7081
                allocbuf(bp, off);
 
7082
                bp->b_vflags |= BV_SCANNED;
 
7083
                return (EBUSY);
 
7084
        }
 
7085
        bp->b_flags |= B_INVAL | B_NOCACHE;
 
7086
 
 
7087
        return (0);
2505
7088
}
2506
7089
 
2507
7090
/*
2508
 
 * Free an allocdirect. Generate a new freefrag work request if appropriate.
2509
 
 * This routine must be called with splbio interrupts blocked.
 
7091
 * An allocdirect is being canceled due to a truncate.  We must make sure
 
7092
 * the journal entry is released in concert with the blkfree that releases
 
7093
 * the storage.  Completed journal entries must not be released until the
 
7094
 * space is no longer pointed to by the inode or in the bitmap.
2510
7095
 */
2511
7096
static void
2512
 
free_allocdirect(adphead, adp, delay)
 
7097
cancel_allocdirect(adphead, adp, freeblks)
2513
7098
        struct allocdirectlst *adphead;
2514
7099
        struct allocdirect *adp;
2515
 
        int delay;
 
7100
        struct freeblks *freeblks;
2516
7101
{
2517
 
        struct newdirblk *newdirblk;
 
7102
        struct freework *freework;
 
7103
        struct newblk *newblk;
2518
7104
        struct worklist *wk;
2519
7105
 
2520
 
        mtx_assert(&lk, MA_OWNED);
2521
 
        if ((adp->ad_state & DEPCOMPLETE) == 0)
2522
 
                LIST_REMOVE(adp, ad_deps);
2523
7106
        TAILQ_REMOVE(adphead, adp, ad_next);
2524
 
        if ((adp->ad_state & COMPLETE) == 0)
2525
 
                WORKLIST_REMOVE(&adp->ad_list);
2526
 
        if (adp->ad_freefrag != NULL) {
2527
 
                if (delay)
2528
 
                        WORKLIST_INSERT(&adp->ad_inodedep->id_bufwait,
2529
 
                            &adp->ad_freefrag->ff_list);
2530
 
                else
2531
 
                        add_to_worklist(&adp->ad_freefrag->ff_list);
2532
 
        }
2533
 
        if ((wk = LIST_FIRST(&adp->ad_newdirblk)) != NULL) {
2534
 
                newdirblk = WK_NEWDIRBLK(wk);
2535
 
                WORKLIST_REMOVE(&newdirblk->db_list);
2536
 
                if (!LIST_EMPTY(&adp->ad_newdirblk))
2537
 
                        panic("free_allocdirect: extra newdirblk");
2538
 
                if (delay)
2539
 
                        WORKLIST_INSERT(&adp->ad_inodedep->id_bufwait,
2540
 
                            &newdirblk->db_list);
2541
 
                else
2542
 
                        free_newdirblk(newdirblk);
2543
 
        }
2544
 
        WORKITEM_FREE(adp, D_ALLOCDIRECT);
 
7107
        newblk = (struct newblk *)adp;
 
7108
        freework = NULL;
 
7109
        /*
 
7110
         * Find the correct freework structure.
 
7111
         */
 
7112
        LIST_FOREACH(wk, &freeblks->fb_freeworkhd, wk_list) {
 
7113
                if (wk->wk_type != D_FREEWORK)
 
7114
                        continue;
 
7115
                freework = WK_FREEWORK(wk);
 
7116
                if (freework->fw_blkno == newblk->nb_newblkno)
 
7117
                        break;
 
7118
        }
 
7119
        if (freework == NULL)
 
7120
                panic("cancel_allocdirect: Freework not found");
 
7121
        /*
 
7122
         * If a newblk exists at all we still have the journal entry that
 
7123
         * initiated the allocation so we do not need to journal the free.
 
7124
         */
 
7125
        cancel_jfreeblk(freeblks, freework->fw_blkno);
 
7126
        /*
 
7127
         * If the journal hasn't been written the jnewblk must be passed
 
7128
         * to the call to ffs_blkfree that reclaims the space.  We accomplish
 
7129
         * this by linking the journal dependency into the freework to be
 
7130
         * freed when freework_freeblock() is called.  If the journal has
 
7131
         * been written we can simply reclaim the journal space when the
 
7132
         * freeblks work is complete.
 
7133
         */
 
7134
        freework->fw_jnewblk = cancel_newblk(newblk, &freework->fw_list,
 
7135
            &freeblks->fb_jwork);
 
7136
        WORKLIST_INSERT(&freeblks->fb_freeworkhd, &newblk->nb_list);
 
7137
}
 
7138
 
 
7139
 
 
7140
/*
 
7141
 * Cancel a new block allocation.  May be an indirect or direct block.  We
 
7142
 * remove it from various lists and return any journal record that needs to
 
7143
 * be resolved by the caller.
 
7144
 *
 
7145
 * A special consideration is made for indirects which were never pointed
 
7146
 * at on disk and will never be found once this block is released.
 
7147
 */
 
7148
static struct jnewblk *
 
7149
cancel_newblk(newblk, wk, wkhd)
 
7150
        struct newblk *newblk;
 
7151
        struct worklist *wk;
 
7152
        struct workhead *wkhd;
 
7153
{
 
7154
        struct jnewblk *jnewblk;
 
7155
 
 
7156
        CTR1(KTR_SUJ, "cancel_newblk: blkno %jd", newblk->nb_newblkno);
 
7157
            
 
7158
        newblk->nb_state |= GOINGAWAY;
 
7159
        /*
 
7160
         * Previously we traversed the completedhd on each indirdep
 
7161
         * attached to this newblk to cancel them and gather journal
 
7162
         * work.  Since we need only the oldest journal segment and
 
7163
         * the lowest point on the tree will always have the oldest
 
7164
         * journal segment we are free to release the segments
 
7165
         * of any subordinates and may leave the indirdep list to
 
7166
         * indirdep_complete() when this newblk is freed.
 
7167
         */
 
7168
        if (newblk->nb_state & ONDEPLIST) {
 
7169
                newblk->nb_state &= ~ONDEPLIST;
 
7170
                LIST_REMOVE(newblk, nb_deps);
 
7171
        }
 
7172
        if (newblk->nb_state & ONWORKLIST)
 
7173
                WORKLIST_REMOVE(&newblk->nb_list);
 
7174
        /*
 
7175
         * If the journal entry hasn't been written we save a pointer to
 
7176
         * the dependency that frees it until it is written or the
 
7177
         * superseding operation completes.
 
7178
         */
 
7179
        jnewblk = newblk->nb_jnewblk;
 
7180
        if (jnewblk != NULL && wk != NULL) {
 
7181
                newblk->nb_jnewblk = NULL;
 
7182
                jnewblk->jn_dep = wk;
 
7183
        }
 
7184
        if (!LIST_EMPTY(&newblk->nb_jwork))
 
7185
                jwork_move(wkhd, &newblk->nb_jwork);
 
7186
        /*
 
7187
         * When truncating we must free the newdirblk early to remove
 
7188
         * the pagedep from the hash before returning.
 
7189
         */
 
7190
        if ((wk = LIST_FIRST(&newblk->nb_newdirblk)) != NULL)
 
7191
                free_newdirblk(WK_NEWDIRBLK(wk));
 
7192
        if (!LIST_EMPTY(&newblk->nb_newdirblk))
 
7193
                panic("cancel_newblk: extra newdirblk");
 
7194
 
 
7195
        return (jnewblk);
 
7196
}
 
7197
 
 
7198
/*
 
7199
 * Schedule the freefrag associated with a newblk to be released once
 
7200
 * the pointers are written and the previous block is no longer needed.
 
7201
 */
 
7202
static void
 
7203
newblk_freefrag(newblk)
 
7204
        struct newblk *newblk;
 
7205
{
 
7206
        struct freefrag *freefrag;
 
7207
 
 
7208
        if (newblk->nb_freefrag == NULL)
 
7209
                return;
 
7210
        freefrag = newblk->nb_freefrag;
 
7211
        newblk->nb_freefrag = NULL;
 
7212
        freefrag->ff_state |= COMPLETE;
 
7213
        if ((freefrag->ff_state & ALLCOMPLETE) == ALLCOMPLETE)
 
7214
                add_to_worklist(&freefrag->ff_list, 0);
 
7215
}
 
7216
 
 
7217
/*
 
7218
 * Free a newblk. Generate a new freefrag work request if appropriate.
 
7219
 * This must be called after the inode pointer and any direct block pointers
 
7220
 * are valid or fully removed via truncate or frag extension.
 
7221
 */
 
7222
static void
 
7223
free_newblk(newblk)
 
7224
        struct newblk *newblk;
 
7225
{
 
7226
        struct indirdep *indirdep;
 
7227
        struct worklist *wk;
 
7228
 
 
7229
        KASSERT(newblk->nb_jnewblk == NULL,
 
7230
            ("free_newblk; jnewblk %p still attached", newblk->nb_jnewblk));
 
7231
        mtx_assert(&lk, MA_OWNED);
 
7232
        newblk_freefrag(newblk);
 
7233
        if (newblk->nb_state & ONDEPLIST)
 
7234
                LIST_REMOVE(newblk, nb_deps);
 
7235
        if (newblk->nb_state & ONWORKLIST)
 
7236
                WORKLIST_REMOVE(&newblk->nb_list);
 
7237
        LIST_REMOVE(newblk, nb_hash);
 
7238
        if ((wk = LIST_FIRST(&newblk->nb_newdirblk)) != NULL)
 
7239
                free_newdirblk(WK_NEWDIRBLK(wk));
 
7240
        if (!LIST_EMPTY(&newblk->nb_newdirblk))
 
7241
                panic("free_newblk: extra newdirblk");
 
7242
        while ((indirdep = LIST_FIRST(&newblk->nb_indirdeps)) != NULL)
 
7243
                indirdep_complete(indirdep);
 
7244
        handle_jwork(&newblk->nb_jwork);
 
7245
        newblk->nb_list.wk_type = D_NEWBLK;
 
7246
        WORKITEM_FREE(newblk, D_NEWBLK);
2545
7247
}
2546
7248
 
2547
7249
/*
2554
7256
{
2555
7257
        struct pagedep *pagedep;
2556
7258
        struct diradd *dap;
2557
 
        int i;
 
7259
        struct worklist *wk;
2558
7260
 
2559
7261
        mtx_assert(&lk, MA_OWNED);
 
7262
        WORKLIST_REMOVE(&newdirblk->db_list);
2560
7263
        /*
2561
7264
         * If the pagedep is still linked onto the directory buffer
2562
7265
         * dependency chain, then some of the entries on the
2569
7272
         */
2570
7273
        pagedep = newdirblk->db_pagedep;
2571
7274
        pagedep->pd_state &= ~NEWBLOCK;
2572
 
        if ((pagedep->pd_state & ONWORKLIST) == 0)
 
7275
        if ((pagedep->pd_state & ONWORKLIST) == 0) {
2573
7276
                while ((dap = LIST_FIRST(&pagedep->pd_pendinghd)) != NULL)
2574
 
                        free_diradd(dap);
2575
 
        /*
2576
 
         * If no dependencies remain, the pagedep will be freed.
2577
 
         */
2578
 
        for (i = 0; i < DAHASHSZ; i++)
2579
 
                if (!LIST_EMPTY(&pagedep->pd_diraddhd[i]))
2580
 
                        break;
2581
 
        if (i == DAHASHSZ && (pagedep->pd_state & ONWORKLIST) == 0) {
2582
 
                LIST_REMOVE(pagedep, pd_hash);
2583
 
                WORKITEM_FREE(pagedep, D_PAGEDEP);
 
7277
                        free_diradd(dap, NULL);
 
7278
                /*
 
7279
                 * If no dependencies remain, the pagedep will be freed.
 
7280
                 */
 
7281
                free_pagedep(pagedep);
 
7282
        }
 
7283
        /* Should only ever be one item in the list. */
 
7284
        while ((wk = LIST_FIRST(&newdirblk->db_mkdir)) != NULL) {
 
7285
                WORKLIST_REMOVE(wk);
 
7286
                handle_written_mkdir(WK_MKDIR(wk), MKDIR_BODY);
2584
7287
        }
2585
7288
        WORKITEM_FREE(newdirblk, D_NEWDIRBLK);
2586
7289
}
2598
7301
        struct inode *ip = VTOI(pvp);
2599
7302
        struct inodedep *inodedep;
2600
7303
        struct freefile *freefile;
 
7304
        struct freeblks *freeblks;
2601
7305
 
2602
7306
        /*
2603
7307
         * This sets up the inode de-allocation dependency.
2608
7312
        freefile->fx_mode = mode;
2609
7313
        freefile->fx_oldinum = ino;
2610
7314
        freefile->fx_devvp = ip->i_devvp;
2611
 
        if ((ip->i_flag & IN_SPACECOUNTED) == 0) {
2612
 
                UFS_LOCK(ip->i_ump);
2613
 
                ip->i_fs->fs_pendinginodes += 1;
2614
 
                UFS_UNLOCK(ip->i_ump);
2615
 
        }
 
7315
        LIST_INIT(&freefile->fx_jwork);
 
7316
        UFS_LOCK(ip->i_ump);
 
7317
        ip->i_fs->fs_pendinginodes += 1;
 
7318
        UFS_UNLOCK(ip->i_ump);
2616
7319
 
2617
7320
        /*
2618
7321
         * If the inodedep does not exist, then the zero'ed inode has
2619
7322
         * been written to disk. If the allocated inode has never been
2620
7323
         * written to disk, then the on-disk inode is zero'ed. In either
2621
 
         * case we can free the file immediately.
 
7324
         * case we can free the file immediately.  If the journal was
 
7325
         * canceled before being written the inode will never make it to
 
7326
         * disk and we must send the canceled journal entrys to
 
7327
         * ffs_freefile() to be cleared in conjunction with the bitmap.
 
7328
         * Any blocks waiting on the inode to write can be safely freed
 
7329
         * here as it will never been written.
2622
7330
         */
2623
7331
        ACQUIRE_LOCK(&lk);
2624
 
        if (inodedep_lookup(pvp->v_mount, ino, 0, &inodedep) == 0 ||
2625
 
            check_inode_unwritten(inodedep)) {
 
7332
        inodedep_lookup(pvp->v_mount, ino, 0, &inodedep);
 
7333
        if (inodedep) {
 
7334
                /*
 
7335
                 * Clear out freeblks that no longer need to reference
 
7336
                 * this inode.
 
7337
                 */
 
7338
                while ((freeblks =
 
7339
                    TAILQ_FIRST(&inodedep->id_freeblklst)) != NULL) {
 
7340
                        TAILQ_REMOVE(&inodedep->id_freeblklst, freeblks,
 
7341
                            fb_next);
 
7342
                        freeblks->fb_state &= ~ONDEPLIST;
 
7343
                }
 
7344
                /*
 
7345
                 * Remove this inode from the unlinked list.
 
7346
                 */
 
7347
                if (inodedep->id_state & UNLINKED) {
 
7348
                        /*
 
7349
                         * Save the journal work to be freed with the bitmap
 
7350
                         * before we clear UNLINKED.  Otherwise it can be lost
 
7351
                         * if the inode block is written.
 
7352
                         */
 
7353
                        handle_bufwait(inodedep, &freefile->fx_jwork);
 
7354
                        clear_unlinked_inodedep(inodedep);
 
7355
                        /* Re-acquire inodedep as we've dropped lk. */
 
7356
                        inodedep_lookup(pvp->v_mount, ino, 0, &inodedep);
 
7357
                }
 
7358
        }
 
7359
        if (inodedep == NULL || check_inode_unwritten(inodedep)) {
2626
7360
                FREE_LOCK(&lk);
2627
7361
                handle_workitem_freefile(freefile);
2628
7362
                return;
2629
7363
        }
 
7364
        if ((inodedep->id_state & DEPCOMPLETE) == 0)
 
7365
                inodedep->id_state |= GOINGAWAY;
2630
7366
        WORKLIST_INSERT(&inodedep->id_inowait, &freefile->fx_list);
2631
7367
        FREE_LOCK(&lk);
2632
7368
        if (ip->i_number == ino)
2654
7390
{
2655
7391
 
2656
7392
        mtx_assert(&lk, MA_OWNED);
2657
 
        if ((inodedep->id_state & DEPCOMPLETE) != 0 ||
 
7393
 
 
7394
        if ((inodedep->id_state & (DEPCOMPLETE | UNLINKED)) != 0 ||
 
7395
            !LIST_EMPTY(&inodedep->id_dirremhd) ||
2658
7396
            !LIST_EMPTY(&inodedep->id_pendinghd) ||
2659
7397
            !LIST_EMPTY(&inodedep->id_bufwait) ||
2660
7398
            !LIST_EMPTY(&inodedep->id_inowait) ||
 
7399
            !TAILQ_EMPTY(&inodedep->id_inoreflst) ||
2661
7400
            !TAILQ_EMPTY(&inodedep->id_inoupdt) ||
2662
7401
            !TAILQ_EMPTY(&inodedep->id_newinoupdt) ||
2663
7402
            !TAILQ_EMPTY(&inodedep->id_extupdt) ||
2664
7403
            !TAILQ_EMPTY(&inodedep->id_newextupdt) ||
 
7404
            !TAILQ_EMPTY(&inodedep->id_freeblklst) ||
 
7405
            inodedep->id_mkdiradd != NULL || 
2665
7406
            inodedep->id_nlinkdelta != 0)
2666
7407
                return (0);
2667
 
 
2668
7408
        /*
2669
7409
         * Another process might be in initiate_write_inodeblock_ufs[12]
2670
7410
         * trying to allocate memory without holding "Softdep Lock".
2673
7413
            inodedep->id_savedino1 == NULL)
2674
7414
                return (0);
2675
7415
 
 
7416
        if (inodedep->id_state & ONDEPLIST)
 
7417
                LIST_REMOVE(inodedep, id_deps);
 
7418
        inodedep->id_state &= ~ONDEPLIST;
2676
7419
        inodedep->id_state |= ALLCOMPLETE;
2677
 
        LIST_REMOVE(inodedep, id_deps);
2678
 
        inodedep->id_buf = NULL;
 
7420
        inodedep->id_bmsafemap = NULL;
2679
7421
        if (inodedep->id_state & ONWORKLIST)
2680
7422
                WORKLIST_REMOVE(&inodedep->id_list);
2681
7423
        if (inodedep->id_savedino1 != NULL) {
2696
7438
{
2697
7439
 
2698
7440
        mtx_assert(&lk, MA_OWNED);
2699
 
        if ((inodedep->id_state & ONWORKLIST) != 0 ||
 
7441
        if ((inodedep->id_state & (ONWORKLIST | UNLINKED)) != 0 ||
2700
7442
            (inodedep->id_state & ALLCOMPLETE) != ALLCOMPLETE ||
 
7443
            !LIST_EMPTY(&inodedep->id_dirremhd) ||
2701
7444
            !LIST_EMPTY(&inodedep->id_pendinghd) ||
2702
7445
            !LIST_EMPTY(&inodedep->id_bufwait) ||
2703
7446
            !LIST_EMPTY(&inodedep->id_inowait) ||
 
7447
            !TAILQ_EMPTY(&inodedep->id_inoreflst) ||
2704
7448
            !TAILQ_EMPTY(&inodedep->id_inoupdt) ||
2705
7449
            !TAILQ_EMPTY(&inodedep->id_newinoupdt) ||
2706
7450
            !TAILQ_EMPTY(&inodedep->id_extupdt) ||
2707
7451
            !TAILQ_EMPTY(&inodedep->id_newextupdt) ||
2708
 
            inodedep->id_nlinkdelta != 0 || inodedep->id_savedino1 != NULL)
 
7452
            !TAILQ_EMPTY(&inodedep->id_freeblklst) ||
 
7453
            inodedep->id_mkdiradd != NULL ||
 
7454
            inodedep->id_nlinkdelta != 0 ||
 
7455
            inodedep->id_savedino1 != NULL)
2709
7456
                return (0);
 
7457
        if (inodedep->id_state & ONDEPLIST)
 
7458
                LIST_REMOVE(inodedep, id_deps);
2710
7459
        LIST_REMOVE(inodedep, id_hash);
2711
7460
        WORKITEM_FREE(inodedep, D_INODEDEP);
2712
 
        num_inodedep -= 1;
2713
7461
        return (1);
2714
7462
}
2715
7463
 
2716
7464
/*
 
7465
 * Free the block referenced by a freework structure.  The parent freeblks
 
7466
 * structure is released and completed when the final cg bitmap reaches
 
7467
 * the disk.  This routine may be freeing a jnewblk which never made it to
 
7468
 * disk in which case we do not have to wait as the operation is undone
 
7469
 * in memory immediately.
 
7470
 */
 
7471
static void
 
7472
freework_freeblock(freework)
 
7473
        struct freework *freework;
 
7474
{
 
7475
        struct freeblks *freeblks;
 
7476
        struct jnewblk *jnewblk;
 
7477
        struct ufsmount *ump;
 
7478
        struct workhead wkhd;
 
7479
        struct fs *fs;
 
7480
        int bsize;
 
7481
        int needj;
 
7482
 
 
7483
        mtx_assert(&lk, MA_OWNED);
 
7484
        /*
 
7485
         * Handle partial truncate separately.
 
7486
         */
 
7487
        if (freework->fw_indir) {
 
7488
                complete_trunc_indir(freework);
 
7489
                return;
 
7490
        }
 
7491
        freeblks = freework->fw_freeblks;
 
7492
        ump = VFSTOUFS(freeblks->fb_list.wk_mp);
 
7493
        fs = ump->um_fs;
 
7494
        needj = MOUNTEDSUJ(freeblks->fb_list.wk_mp) != 0;
 
7495
        bsize = lfragtosize(fs, freework->fw_frags);
 
7496
        LIST_INIT(&wkhd);
 
7497
        /*
 
7498
         * DEPCOMPLETE is cleared in indirblk_insert() if the block lives
 
7499
         * on the indirblk hashtable and prevents premature freeing.
 
7500
         */
 
7501
        freework->fw_state |= DEPCOMPLETE;
 
7502
        /*
 
7503
         * SUJ needs to wait for the segment referencing freed indirect
 
7504
         * blocks to expire so that we know the checker will not confuse
 
7505
         * a re-allocated indirect block with its old contents.
 
7506
         */
 
7507
        if (needj && freework->fw_lbn <= -NDADDR)
 
7508
                indirblk_insert(freework);
 
7509
        /*
 
7510
         * If we are canceling an existing jnewblk pass it to the free
 
7511
         * routine, otherwise pass the freeblk which will ultimately
 
7512
         * release the freeblks.  If we're not journaling, we can just
 
7513
         * free the freeblks immediately.
 
7514
         */
 
7515
        jnewblk = freework->fw_jnewblk;
 
7516
        if (jnewblk != NULL) {
 
7517
                cancel_jnewblk(jnewblk, &wkhd);
 
7518
                needj = 0;
 
7519
        } else if (needj) {
 
7520
                freework->fw_state |= DELAYEDFREE;
 
7521
                freeblks->fb_cgwait++;
 
7522
                WORKLIST_INSERT(&wkhd, &freework->fw_list);
 
7523
        }
 
7524
        FREE_LOCK(&lk);
 
7525
        freeblks_free(ump, freeblks, btodb(bsize));
 
7526
        CTR4(KTR_SUJ,
 
7527
            "freework_freeblock: ino %d blkno %jd lbn %jd size %ld",
 
7528
            freeblks->fb_inum, freework->fw_blkno, freework->fw_lbn, bsize);
 
7529
        ffs_blkfree(ump, fs, freeblks->fb_devvp, freework->fw_blkno, bsize,
 
7530
            freeblks->fb_inum, freeblks->fb_vtype, &wkhd);
 
7531
        ACQUIRE_LOCK(&lk);
 
7532
        /*
 
7533
         * The jnewblk will be discarded and the bits in the map never
 
7534
         * made it to disk.  We can immediately free the freeblk.
 
7535
         */
 
7536
        if (needj == 0)
 
7537
                handle_written_freework(freework);
 
7538
}
 
7539
 
 
7540
/*
 
7541
 * We enqueue freework items that need processing back on the freeblks and
 
7542
 * add the freeblks to the worklist.  This makes it easier to find all work
 
7543
 * required to flush a truncation in process_truncates().
 
7544
 */
 
7545
static void
 
7546
freework_enqueue(freework)
 
7547
        struct freework *freework;
 
7548
{
 
7549
        struct freeblks *freeblks;
 
7550
 
 
7551
        freeblks = freework->fw_freeblks;
 
7552
        if ((freework->fw_state & INPROGRESS) == 0)
 
7553
                WORKLIST_INSERT(&freeblks->fb_freeworkhd, &freework->fw_list);
 
7554
        if ((freeblks->fb_state &
 
7555
            (ONWORKLIST | INPROGRESS | ALLCOMPLETE)) == ALLCOMPLETE &&
 
7556
            LIST_EMPTY(&freeblks->fb_jblkdephd))
 
7557
                add_to_worklist(&freeblks->fb_list, WK_NODELAY);
 
7558
}
 
7559
 
 
7560
/*
 
7561
 * Start, continue, or finish the process of freeing an indirect block tree.
 
7562
 * The free operation may be paused at any point with fw_off containing the
 
7563
 * offset to restart from.  This enables us to implement some flow control
 
7564
 * for large truncates which may fan out and generate a huge number of
 
7565
 * dependencies.
 
7566
 */
 
7567
static void
 
7568
handle_workitem_indirblk(freework)
 
7569
        struct freework *freework;
 
7570
{
 
7571
        struct freeblks *freeblks;
 
7572
        struct ufsmount *ump;
 
7573
        struct fs *fs;
 
7574
 
 
7575
        freeblks = freework->fw_freeblks;
 
7576
        ump = VFSTOUFS(freeblks->fb_list.wk_mp);
 
7577
        fs = ump->um_fs;
 
7578
        if (freework->fw_state & DEPCOMPLETE) {
 
7579
                handle_written_freework(freework);
 
7580
                return;
 
7581
        }
 
7582
        if (freework->fw_off == NINDIR(fs)) {
 
7583
                freework_freeblock(freework);
 
7584
                return;
 
7585
        }
 
7586
        freework->fw_state |= INPROGRESS;
 
7587
        FREE_LOCK(&lk);
 
7588
        indir_trunc(freework, fsbtodb(fs, freework->fw_blkno),
 
7589
            freework->fw_lbn);
 
7590
        ACQUIRE_LOCK(&lk);
 
7591
}
 
7592
 
 
7593
/*
 
7594
 * Called when a freework structure attached to a cg buf is written.  The
 
7595
 * ref on either the parent or the freeblks structure is released and
 
7596
 * the freeblks is added back to the worklist if there is more work to do.
 
7597
 */
 
7598
static void
 
7599
handle_written_freework(freework)
 
7600
        struct freework *freework;
 
7601
{
 
7602
        struct freeblks *freeblks;
 
7603
        struct freework *parent;
 
7604
 
 
7605
        freeblks = freework->fw_freeblks;
 
7606
        parent = freework->fw_parent;
 
7607
        if (freework->fw_state & DELAYEDFREE)
 
7608
                freeblks->fb_cgwait--;
 
7609
        freework->fw_state |= COMPLETE;
 
7610
        if ((freework->fw_state & ALLCOMPLETE) == ALLCOMPLETE)
 
7611
                WORKITEM_FREE(freework, D_FREEWORK);
 
7612
        if (parent) {
 
7613
                if (--parent->fw_ref == 0)
 
7614
                        freework_enqueue(parent);
 
7615
                return;
 
7616
        }
 
7617
        if (--freeblks->fb_ref != 0)
 
7618
                return;
 
7619
        if ((freeblks->fb_state & (ALLCOMPLETE | ONWORKLIST | INPROGRESS)) ==
 
7620
            ALLCOMPLETE && LIST_EMPTY(&freeblks->fb_jblkdephd)) 
 
7621
                add_to_worklist(&freeblks->fb_list, WK_NODELAY);
 
7622
}
 
7623
 
 
7624
/*
2717
7625
 * This workitem routine performs the block de-allocation.
2718
7626
 * The workitem is added to the pending list after the updated
2719
7627
 * inode block has been written to disk.  As mentioned above,
2721
7629
 * to the number of blocks allocated for the file) are also
2722
7630
 * performed in this function.
2723
7631
 */
2724
 
static void
 
7632
static int
2725
7633
handle_workitem_freeblocks(freeblks, flags)
2726
7634
        struct freeblks *freeblks;
2727
7635
        int flags;
2728
7636
{
 
7637
        struct freework *freework;
 
7638
        struct newblk *newblk;
 
7639
        struct allocindir *aip;
 
7640
        struct ufsmount *ump;
 
7641
        struct worklist *wk;
 
7642
 
 
7643
        KASSERT(LIST_EMPTY(&freeblks->fb_jblkdephd),
 
7644
            ("handle_workitem_freeblocks: Journal entries not written."));
 
7645
        ump = VFSTOUFS(freeblks->fb_list.wk_mp);
 
7646
        ACQUIRE_LOCK(&lk);
 
7647
        while ((wk = LIST_FIRST(&freeblks->fb_freeworkhd)) != NULL) {
 
7648
                WORKLIST_REMOVE(wk);
 
7649
                switch (wk->wk_type) {
 
7650
                case D_DIRREM:
 
7651
                        wk->wk_state |= COMPLETE;
 
7652
                        add_to_worklist(wk, 0);
 
7653
                        continue;
 
7654
 
 
7655
                case D_ALLOCDIRECT:
 
7656
                        free_newblk(WK_NEWBLK(wk));
 
7657
                        continue;
 
7658
 
 
7659
                case D_ALLOCINDIR:
 
7660
                        aip = WK_ALLOCINDIR(wk);
 
7661
                        freework = NULL;
 
7662
                        if (aip->ai_state & DELAYEDFREE) {
 
7663
                                FREE_LOCK(&lk);
 
7664
                                freework = newfreework(ump, freeblks, NULL,
 
7665
                                    aip->ai_lbn, aip->ai_newblkno,
 
7666
                                    ump->um_fs->fs_frag, 0, 0);
 
7667
                                ACQUIRE_LOCK(&lk);
 
7668
                        }
 
7669
                        newblk = WK_NEWBLK(wk);
 
7670
                        if (newblk->nb_jnewblk) {
 
7671
                                freework->fw_jnewblk = newblk->nb_jnewblk;
 
7672
                                newblk->nb_jnewblk->jn_dep = &freework->fw_list;
 
7673
                                newblk->nb_jnewblk = NULL;
 
7674
                        }
 
7675
                        free_newblk(newblk);
 
7676
                        continue;
 
7677
 
 
7678
                case D_FREEWORK:
 
7679
                        freework = WK_FREEWORK(wk);
 
7680
                        if (freework->fw_lbn <= -NDADDR)
 
7681
                                handle_workitem_indirblk(freework);
 
7682
                        else
 
7683
                                freework_freeblock(freework);
 
7684
                        continue;
 
7685
                default:
 
7686
                        panic("handle_workitem_freeblocks: Unknown type %s",
 
7687
                            TYPENAME(wk->wk_type));
 
7688
                }
 
7689
        }
 
7690
        if (freeblks->fb_ref != 0) {
 
7691
                freeblks->fb_state &= ~INPROGRESS;
 
7692
                wake_worklist(&freeblks->fb_list);
 
7693
                freeblks = NULL;
 
7694
        }
 
7695
        FREE_LOCK(&lk);
 
7696
        if (freeblks)
 
7697
                return handle_complete_freeblocks(freeblks, flags);
 
7698
        return (0);
 
7699
}
 
7700
 
 
7701
/*
 
7702
 * Handle completion of block free via truncate.  This allows fs_pending
 
7703
 * to track the actual free block count more closely than if we only updated
 
7704
 * it at the end.  We must be careful to handle cases where the block count
 
7705
 * on free was incorrect.
 
7706
 */
 
7707
static void
 
7708
freeblks_free(ump, freeblks, blocks)
 
7709
        struct ufsmount *ump;
 
7710
        struct freeblks *freeblks;
 
7711
        int blocks;
 
7712
{
 
7713
        struct fs *fs;
 
7714
        ufs2_daddr_t remain;
 
7715
 
 
7716
        UFS_LOCK(ump);
 
7717
        remain = -freeblks->fb_chkcnt;
 
7718
        freeblks->fb_chkcnt += blocks;
 
7719
        if (remain > 0) {
 
7720
                if (remain < blocks)
 
7721
                        blocks = remain;
 
7722
                fs = ump->um_fs;
 
7723
                fs->fs_pendingblocks -= blocks;
 
7724
        }
 
7725
        UFS_UNLOCK(ump);
 
7726
}
 
7727
 
 
7728
/*
 
7729
 * Once all of the freework workitems are complete we can retire the
 
7730
 * freeblocks dependency and any journal work awaiting completion.  This
 
7731
 * can not be called until all other dependencies are stable on disk.
 
7732
 */
 
7733
static int
 
7734
handle_complete_freeblocks(freeblks, flags)
 
7735
        struct freeblks *freeblks;
 
7736
        int flags;
 
7737
{
 
7738
        struct inodedep *inodedep;
2729
7739
        struct inode *ip;
2730
7740
        struct vnode *vp;
2731
7741
        struct fs *fs;
2732
7742
        struct ufsmount *ump;
2733
 
        int i, nblocks, level, bsize;
2734
 
        ufs2_daddr_t bn, blocksreleased = 0;
2735
 
        int error, allerror = 0;
2736
 
        ufs_lbn_t baselbns[NIADDR], tmpval;
2737
 
        int fs_pendingblocks;
 
7743
        ufs2_daddr_t spare;
2738
7744
 
2739
7745
        ump = VFSTOUFS(freeblks->fb_list.wk_mp);
2740
7746
        fs = ump->um_fs;
2741
 
        fs_pendingblocks = 0;
2742
 
        tmpval = 1;
2743
 
        baselbns[0] = NDADDR;
2744
 
        for (i = 1; i < NIADDR; i++) {
2745
 
                tmpval *= NINDIR(fs);
2746
 
                baselbns[i] = baselbns[i - 1] + tmpval;
2747
 
        }
2748
 
        nblocks = btodb(fs->fs_bsize);
2749
 
        blocksreleased = 0;
2750
 
        /*
2751
 
         * Release all extended attribute blocks or frags.
2752
 
         */
2753
 
        if (freeblks->fb_oldextsize > 0) {
2754
 
                for (i = (NXADDR - 1); i >= 0; i--) {
2755
 
                        if ((bn = freeblks->fb_eblks[i]) == 0)
2756
 
                                continue;
2757
 
                        bsize = sblksize(fs, freeblks->fb_oldextsize, i);
2758
 
                        ffs_blkfree(ump, fs, freeblks->fb_devvp, bn, bsize,
2759
 
                            freeblks->fb_previousinum);
2760
 
                        blocksreleased += btodb(bsize);
2761
 
                }
2762
 
        }
2763
 
        /*
2764
 
         * Release all data blocks or frags.
2765
 
         */
2766
 
        if (freeblks->fb_oldsize > 0) {
2767
 
                /*
2768
 
                 * Indirect blocks first.
2769
 
                 */
2770
 
                for (level = (NIADDR - 1); level >= 0; level--) {
2771
 
                        if ((bn = freeblks->fb_iblks[level]) == 0)
2772
 
                                continue;
2773
 
                        if ((error = indir_trunc(freeblks, fsbtodb(fs, bn),
2774
 
                            level, baselbns[level], &blocksreleased)) != 0)
2775
 
                                allerror = error;
2776
 
                        ffs_blkfree(ump, fs, freeblks->fb_devvp, bn,
2777
 
                            fs->fs_bsize, freeblks->fb_previousinum);
2778
 
                        fs_pendingblocks += nblocks;
2779
 
                        blocksreleased += nblocks;
2780
 
                }
2781
 
                /*
2782
 
                 * All direct blocks or frags.
2783
 
                 */
2784
 
                for (i = (NDADDR - 1); i >= 0; i--) {
2785
 
                        if ((bn = freeblks->fb_dblks[i]) == 0)
2786
 
                                continue;
2787
 
                        bsize = sblksize(fs, freeblks->fb_oldsize, i);
2788
 
                        ffs_blkfree(ump, fs, freeblks->fb_devvp, bn, bsize,
2789
 
                            freeblks->fb_previousinum);
2790
 
                        fs_pendingblocks += btodb(bsize);
2791
 
                        blocksreleased += btodb(bsize);
2792
 
                }
2793
 
        }
2794
 
        UFS_LOCK(ump);
2795
 
        fs->fs_pendingblocks -= fs_pendingblocks;
2796
 
        UFS_UNLOCK(ump);
2797
 
        /*
2798
 
         * If we still have not finished background cleanup, then check
2799
 
         * to see if the block count needs to be adjusted.
2800
 
         */
2801
 
        if (freeblks->fb_chkcnt != blocksreleased &&
2802
 
            (fs->fs_flags & FS_UNCLEAN) != 0 &&
2803
 
            ffs_vgetf(freeblks->fb_list.wk_mp, freeblks->fb_previousinum,
2804
 
                (flags & LK_NOWAIT) | LK_EXCLUSIVE, &vp, FFSV_FORCEINSMQ)
2805
 
            == 0) {
 
7747
        flags = LK_EXCLUSIVE | flags;
 
7748
        spare = freeblks->fb_chkcnt;
 
7749
 
 
7750
        /*
 
7751
         * If we did not release the expected number of blocks we may have
 
7752
         * to adjust the inode block count here.  Only do so if it wasn't
 
7753
         * a truncation to zero and the modrev still matches.
 
7754
         */
 
7755
        if (spare && freeblks->fb_len != 0) {
 
7756
                if (ffs_vgetf(freeblks->fb_list.wk_mp, freeblks->fb_inum,
 
7757
                    flags, &vp, FFSV_FORCEINSMQ) != 0)
 
7758
                        return (EBUSY);
2806
7759
                ip = VTOI(vp);
2807
 
                DIP_SET(ip, i_blocks, DIP(ip, i_blocks) + \
2808
 
                    freeblks->fb_chkcnt - blocksreleased);
2809
 
                ip->i_flag |= IN_CHANGE;
 
7760
                if (DIP(ip, i_modrev) == freeblks->fb_modrev) {
 
7761
                        DIP_SET(ip, i_blocks, DIP(ip, i_blocks) - spare);
 
7762
                        ip->i_flag |= IN_CHANGE;
 
7763
                        /*
 
7764
                         * We must wait so this happens before the
 
7765
                         * journal is reclaimed.
 
7766
                         */
 
7767
                        ffs_update(vp, 1);
 
7768
                }
2810
7769
                vput(vp);
2811
7770
        }
2812
 
 
2813
 
#ifdef INVARIANTS
2814
 
        if (freeblks->fb_chkcnt != blocksreleased &&
2815
 
            ((fs->fs_flags & FS_UNCLEAN) == 0 || (flags & LK_NOWAIT) != 0))
2816
 
                printf("handle_workitem_freeblocks: block count\n");
2817
 
        if (allerror)
2818
 
                softdep_error("handle_workitem_freeblks", allerror);
2819
 
#endif /* INVARIANTS */
2820
 
 
 
7771
        if (spare < 0) {
 
7772
                UFS_LOCK(ump);
 
7773
                fs->fs_pendingblocks += spare;
 
7774
                UFS_UNLOCK(ump);
 
7775
        }
 
7776
#ifdef QUOTA
 
7777
        /* Handle spare. */
 
7778
        if (spare)
 
7779
                quotaadj(freeblks->fb_quota, ump, -spare);
 
7780
        quotarele(freeblks->fb_quota);
 
7781
#endif
2821
7782
        ACQUIRE_LOCK(&lk);
 
7783
        if (freeblks->fb_state & ONDEPLIST) {
 
7784
                inodedep_lookup(freeblks->fb_list.wk_mp, freeblks->fb_inum,
 
7785
                    0, &inodedep);
 
7786
                TAILQ_REMOVE(&inodedep->id_freeblklst, freeblks, fb_next);
 
7787
                freeblks->fb_state &= ~ONDEPLIST;
 
7788
                if (TAILQ_EMPTY(&inodedep->id_freeblklst))
 
7789
                        free_inodedep(inodedep);
 
7790
        }
 
7791
        /*
 
7792
         * All of the freeblock deps must be complete prior to this call
 
7793
         * so it's now safe to complete earlier outstanding journal entries.
 
7794
         */
 
7795
        handle_jwork(&freeblks->fb_jwork);
2822
7796
        WORKITEM_FREE(freeblks, D_FREEBLKS);
2823
 
        num_freeblkdep--;
2824
7797
        FREE_LOCK(&lk);
 
7798
        return (0);
2825
7799
}
2826
7800
 
2827
7801
/*
2828
 
 * Release blocks associated with the inode ip and stored in the indirect
 
7802
 * Release blocks associated with the freeblks and stored in the indirect
2829
7803
 * block dbn. If level is greater than SINGLE, the block is an indirect block
2830
7804
 * and recursive calls to indirtrunc must be used to cleanse other indirect
2831
7805
 * blocks.
 
7806
 *
 
7807
 * This handles partial and complete truncation of blocks.  Partial is noted
 
7808
 * with goingaway == 0.  In this case the freework is completed after the
 
7809
 * zero'd indirects are written to disk.  For full truncation the freework
 
7810
 * is completed after the block is freed.
2832
7811
 */
2833
 
static int
2834
 
indir_trunc(freeblks, dbn, level, lbn, countp)
2835
 
        struct freeblks *freeblks;
 
7812
static void
 
7813
indir_trunc(freework, dbn, lbn)
 
7814
        struct freework *freework;
2836
7815
        ufs2_daddr_t dbn;
2837
 
        int level;
2838
7816
        ufs_lbn_t lbn;
2839
 
        ufs2_daddr_t *countp;
2840
7817
{
 
7818
        struct freework *nfreework;
 
7819
        struct workhead wkhd;
 
7820
        struct freeblks *freeblks;
2841
7821
        struct buf *bp;
2842
7822
        struct fs *fs;
2843
 
        struct worklist *wk;
2844
7823
        struct indirdep *indirdep;
2845
7824
        struct ufsmount *ump;
2846
7825
        ufs1_daddr_t *bap1 = 0;
2847
 
        ufs2_daddr_t nb, *bap2 = 0;
2848
 
        ufs_lbn_t lbnadd;
 
7826
        ufs2_daddr_t nb, nnb, *bap2 = 0;
 
7827
        ufs_lbn_t lbnadd, nlbn;
2849
7828
        int i, nblocks, ufs1fmt;
2850
 
        int error, allerror = 0;
2851
 
        int fs_pendingblocks;
 
7829
        int freedblocks;
 
7830
        int goingaway;
 
7831
        int freedeps;
 
7832
        int needj;
 
7833
        int level;
 
7834
        int cnt;
2852
7835
 
 
7836
        freeblks = freework->fw_freeblks;
2853
7837
        ump = VFSTOUFS(freeblks->fb_list.wk_mp);
2854
7838
        fs = ump->um_fs;
2855
 
        fs_pendingblocks = 0;
2856
 
        lbnadd = 1;
2857
 
        for (i = level; i > 0; i--)
2858
 
                lbnadd *= NINDIR(fs);
2859
7839
        /*
2860
 
         * Get buffer of block pointers to be freed. This routine is not
2861
 
         * called until the zero'ed inode has been written, so it is safe
2862
 
         * to free blocks as they are encountered. Because the inode has
2863
 
         * been zero'ed, calls to bmap on these blocks will fail. So, we
2864
 
         * have to use the on-disk address and the block device for the
2865
 
         * filesystem to look them up. If the file was deleted before its
2866
 
         * indirect blocks were all written to disk, the routine that set
2867
 
         * us up (deallocate_dependencies) will have arranged to leave
2868
 
         * a complete copy of the indirect block in memory for our use.
2869
 
         * Otherwise we have to read the blocks in from the disk.
 
7840
         * Get buffer of block pointers to be freed.  There are three cases:
 
7841
         * 
 
7842
         * 1) Partial truncate caches the indirdep pointer in the freework
 
7843
         *    which provides us a back copy to the save bp which holds the
 
7844
         *    pointers we want to clear.  When this completes the zero
 
7845
         *    pointers are written to the real copy.
 
7846
         * 2) The indirect is being completely truncated, cancel_indirdep()
 
7847
         *    eliminated the real copy and placed the indirdep on the saved
 
7848
         *    copy.  The indirdep and buf are discarded when this completes.
 
7849
         * 3) The indirect was not in memory, we read a copy off of the disk
 
7850
         *    using the devvp and drop and invalidate the buffer when we're
 
7851
         *    done.
2870
7852
         */
2871
 
#ifdef notyet
2872
 
        bp = getblk(freeblks->fb_devvp, dbn, (int)fs->fs_bsize, 0, 0,
2873
 
            GB_NOCREAT);
2874
 
#else
2875
 
        bp = incore(&freeblks->fb_devvp->v_bufobj, dbn);
2876
 
#endif
 
7853
        goingaway = 1;
 
7854
        indirdep = NULL;
 
7855
        if (freework->fw_indir != NULL) {
 
7856
                goingaway = 0;
 
7857
                indirdep = freework->fw_indir;
 
7858
                bp = indirdep->ir_savebp;
 
7859
                if (bp == NULL || bp->b_blkno != dbn)
 
7860
                        panic("indir_trunc: Bad saved buf %p blkno %jd",
 
7861
                            bp, (intmax_t)dbn);
 
7862
        } else if ((bp = incore(&freeblks->fb_devvp->v_bufobj, dbn)) != NULL) {
 
7863
                /*
 
7864
                 * The lock prevents the buf dep list from changing and
 
7865
                 * indirects on devvp should only ever have one dependency.
 
7866
                 */
 
7867
                indirdep = WK_INDIRDEP(LIST_FIRST(&bp->b_dep));
 
7868
                if (indirdep == NULL || (indirdep->ir_state & GOINGAWAY) == 0)
 
7869
                        panic("indir_trunc: Bad indirdep %p from buf %p",
 
7870
                            indirdep, bp);
 
7871
        } else if (bread(freeblks->fb_devvp, dbn, (int)fs->fs_bsize,
 
7872
            NOCRED, &bp) != 0) {
 
7873
                brelse(bp);
 
7874
                return;
 
7875
        }
2877
7876
        ACQUIRE_LOCK(&lk);
2878
 
        if (bp != NULL && (wk = LIST_FIRST(&bp->b_dep)) != NULL) {
2879
 
                if (wk->wk_type != D_INDIRDEP ||
2880
 
                    (indirdep = WK_INDIRDEP(wk))->ir_savebp != bp ||
2881
 
                    (indirdep->ir_state & GOINGAWAY) == 0)
2882
 
                        panic("indir_trunc: lost indirdep");
2883
 
                WORKLIST_REMOVE(wk);
2884
 
                WORKITEM_FREE(indirdep, D_INDIRDEP);
2885
 
                if (!LIST_EMPTY(&bp->b_dep))
2886
 
                        panic("indir_trunc: dangling dep");
2887
 
                ump->um_numindirdeps -= 1;
2888
 
                FREE_LOCK(&lk);
2889
 
        } else {
2890
 
#ifdef notyet
2891
 
                if (bp)
2892
 
                        brelse(bp);
2893
 
#endif
2894
 
                FREE_LOCK(&lk);
2895
 
                error = bread(freeblks->fb_devvp, dbn, (int)fs->fs_bsize,
2896
 
                    NOCRED, &bp);
2897
 
                if (error) {
2898
 
                        brelse(bp);
2899
 
                        return (error);
2900
 
                }
2901
 
        }
 
7877
        /* Protects against a race with complete_trunc_indir(). */
 
7878
        freework->fw_state &= ~INPROGRESS;
2902
7879
        /*
2903
 
         * Recursively free indirect blocks.
 
7880
         * If we have an indirdep we need to enforce the truncation order
 
7881
         * and discard it when it is complete.
2904
7882
         */
 
7883
        if (indirdep) {
 
7884
                if (freework != TAILQ_FIRST(&indirdep->ir_trunc) &&
 
7885
                    !TAILQ_EMPTY(&indirdep->ir_trunc)) {
 
7886
                        /*
 
7887
                         * Add the complete truncate to the list on the
 
7888
                         * indirdep to enforce in-order processing.
 
7889
                         */
 
7890
                        if (freework->fw_indir == NULL)
 
7891
                                TAILQ_INSERT_TAIL(&indirdep->ir_trunc,
 
7892
                                    freework, fw_next);
 
7893
                        FREE_LOCK(&lk);
 
7894
                        return;
 
7895
                }
 
7896
                /*
 
7897
                 * If we're goingaway, free the indirdep.  Otherwise it will
 
7898
                 * linger until the write completes.
 
7899
                 */
 
7900
                if (goingaway) {
 
7901
                        free_indirdep(indirdep);
 
7902
                        ump->um_numindirdeps -= 1;
 
7903
                }
 
7904
        }
 
7905
        FREE_LOCK(&lk);
 
7906
        /* Initialize pointers depending on block size. */
2905
7907
        if (ump->um_fstype == UFS1) {
 
7908
                bap1 = (ufs1_daddr_t *)bp->b_data;
 
7909
                nb = bap1[freework->fw_off];
2906
7910
                ufs1fmt = 1;
2907
 
                bap1 = (ufs1_daddr_t *)bp->b_data;
2908
7911
        } else {
 
7912
                bap2 = (ufs2_daddr_t *)bp->b_data;
 
7913
                nb = bap2[freework->fw_off];
2909
7914
                ufs1fmt = 0;
2910
 
                bap2 = (ufs2_daddr_t *)bp->b_data;
2911
7915
        }
 
7916
        level = lbn_level(lbn);
 
7917
        needj = MOUNTEDSUJ(UFSTOVFS(ump)) != 0;
 
7918
        lbnadd = lbn_offset(fs, level);
2912
7919
        nblocks = btodb(fs->fs_bsize);
2913
 
        for (i = NINDIR(fs) - 1; i >= 0; i--) {
2914
 
                if (ufs1fmt)
2915
 
                        nb = bap1[i];
2916
 
                else
2917
 
                        nb = bap2[i];
 
7920
        nfreework = freework;
 
7921
        freedeps = 0;
 
7922
        cnt = 0;
 
7923
        /*
 
7924
         * Reclaim blocks.  Traverses into nested indirect levels and
 
7925
         * arranges for the current level to be freed when subordinates
 
7926
         * are free when journaling.
 
7927
         */
 
7928
        for (i = freework->fw_off; i < NINDIR(fs); i++, nb = nnb) {
 
7929
                if (i != NINDIR(fs) - 1) {
 
7930
                        if (ufs1fmt)
 
7931
                                nnb = bap1[i+1];
 
7932
                        else
 
7933
                                nnb = bap2[i+1];
 
7934
                } else
 
7935
                        nnb = 0;
2918
7936
                if (nb == 0)
2919
7937
                        continue;
 
7938
                cnt++;
2920
7939
                if (level != 0) {
2921
 
                        if ((error = indir_trunc(freeblks, fsbtodb(fs, nb),
2922
 
                             level - 1, lbn + (i * lbnadd), countp)) != 0)
2923
 
                                allerror = error;
 
7940
                        nlbn = (lbn + 1) - (i * lbnadd);
 
7941
                        if (needj != 0) {
 
7942
                                nfreework = newfreework(ump, freeblks, freework,
 
7943
                                    nlbn, nb, fs->fs_frag, 0, 0);
 
7944
                                freedeps++;
 
7945
                        }
 
7946
                        indir_trunc(nfreework, fsbtodb(fs, nb), nlbn);
 
7947
                } else {
 
7948
                        struct freedep *freedep;
 
7949
 
 
7950
                        /*
 
7951
                         * Attempt to aggregate freedep dependencies for
 
7952
                         * all blocks being released to the same CG.
 
7953
                         */
 
7954
                        LIST_INIT(&wkhd);
 
7955
                        if (needj != 0 &&
 
7956
                            (nnb == 0 || (dtog(fs, nb) != dtog(fs, nnb)))) {
 
7957
                                freedep = newfreedep(freework);
 
7958
                                WORKLIST_INSERT_UNLOCKED(&wkhd,
 
7959
                                    &freedep->fd_list);
 
7960
                                freedeps++;
 
7961
                        }
 
7962
                        CTR3(KTR_SUJ,
 
7963
                            "indir_trunc: ino %d blkno %jd size %ld",
 
7964
                            freeblks->fb_inum, nb, fs->fs_bsize);
 
7965
                        ffs_blkfree(ump, fs, freeblks->fb_devvp, nb,
 
7966
                            fs->fs_bsize, freeblks->fb_inum,
 
7967
                            freeblks->fb_vtype, &wkhd);
2924
7968
                }
2925
 
                ffs_blkfree(ump, fs, freeblks->fb_devvp, nb, fs->fs_bsize,
2926
 
                    freeblks->fb_previousinum);
2927
 
                fs_pendingblocks += nblocks;
2928
 
                *countp += nblocks;
2929
 
        }
2930
 
        UFS_LOCK(ump);
2931
 
        fs->fs_pendingblocks -= fs_pendingblocks;
2932
 
        UFS_UNLOCK(ump);
2933
 
        bp->b_flags |= B_INVAL | B_NOCACHE;
2934
 
        brelse(bp);
2935
 
        return (allerror);
 
7969
        }
 
7970
        if (goingaway) {
 
7971
                bp->b_flags |= B_INVAL | B_NOCACHE;
 
7972
                brelse(bp);
 
7973
        }
 
7974
        freedblocks = 0;
 
7975
        if (level == 0)
 
7976
                freedblocks = (nblocks * cnt);
 
7977
        if (needj == 0)
 
7978
                freedblocks += nblocks;
 
7979
        freeblks_free(ump, freeblks, freedblocks);
 
7980
        /*
 
7981
         * If we are journaling set up the ref counts and offset so this
 
7982
         * indirect can be completed when its children are free.
 
7983
         */
 
7984
        if (needj) {
 
7985
                ACQUIRE_LOCK(&lk);
 
7986
                freework->fw_off = i;
 
7987
                freework->fw_ref += freedeps;
 
7988
                freework->fw_ref -= NINDIR(fs) + 1;
 
7989
                if (level == 0)
 
7990
                        freeblks->fb_cgwait += freedeps;
 
7991
                if (freework->fw_ref == 0)
 
7992
                        freework_freeblock(freework);
 
7993
                FREE_LOCK(&lk);
 
7994
                return;
 
7995
        }
 
7996
        /*
 
7997
         * If we're not journaling we can free the indirect now.
 
7998
         */
 
7999
        dbn = dbtofsb(fs, dbn);
 
8000
        CTR3(KTR_SUJ,
 
8001
            "indir_trunc 2: ino %d blkno %jd size %ld",
 
8002
            freeblks->fb_inum, dbn, fs->fs_bsize);
 
8003
        ffs_blkfree(ump, fs, freeblks->fb_devvp, dbn, fs->fs_bsize,
 
8004
            freeblks->fb_inum, freeblks->fb_vtype, NULL);
 
8005
        /* Non SUJ softdep does single-threaded truncations. */
 
8006
        if (freework->fw_blkno == dbn) {
 
8007
                freework->fw_state |= ALLCOMPLETE;
 
8008
                ACQUIRE_LOCK(&lk);
 
8009
                handle_written_freework(freework);
 
8010
                FREE_LOCK(&lk);
 
8011
        }
 
8012
        return;
2936
8013
}
2937
8014
 
2938
8015
/*
2939
 
 * Free an allocindir.
2940
 
 * This routine must be called with splbio interrupts blocked.
 
8016
 * Cancel an allocindir when it is removed via truncation.  When bp is not
 
8017
 * NULL the indirect never appeared on disk and is scheduled to be freed
 
8018
 * independently of the indir so we can more easily track journal work.
2941
8019
 */
2942
8020
static void
2943
 
free_allocindir(aip, inodedep)
 
8021
cancel_allocindir(aip, bp, freeblks, trunc)
2944
8022
        struct allocindir *aip;
2945
 
        struct inodedep *inodedep;
 
8023
        struct buf *bp;
 
8024
        struct freeblks *freeblks;
 
8025
        int trunc;
2946
8026
{
 
8027
        struct indirdep *indirdep;
2947
8028
        struct freefrag *freefrag;
 
8029
        struct newblk *newblk;
2948
8030
 
2949
 
        mtx_assert(&lk, MA_OWNED);
2950
 
        if ((aip->ai_state & DEPCOMPLETE) == 0)
2951
 
                LIST_REMOVE(aip, ai_deps);
2952
 
        if (aip->ai_state & ONWORKLIST)
2953
 
                WORKLIST_REMOVE(&aip->ai_list);
 
8031
        newblk = (struct newblk *)aip;
2954
8032
        LIST_REMOVE(aip, ai_next);
2955
 
        if ((freefrag = aip->ai_freefrag) != NULL) {
 
8033
        /*
 
8034
         * We must eliminate the pointer in bp if it must be freed on its
 
8035
         * own due to partial truncate or pending journal work.
 
8036
         */
 
8037
        if (bp && (trunc || newblk->nb_jnewblk)) {
 
8038
                /*
 
8039
                 * Clear the pointer and mark the aip to be freed
 
8040
                 * directly if it never existed on disk.
 
8041
                 */
 
8042
                aip->ai_state |= DELAYEDFREE;
 
8043
                indirdep = aip->ai_indirdep;
 
8044
                if (indirdep->ir_state & UFS1FMT)
 
8045
                        ((ufs1_daddr_t *)bp->b_data)[aip->ai_offset] = 0;
 
8046
                else
 
8047
                        ((ufs2_daddr_t *)bp->b_data)[aip->ai_offset] = 0;
 
8048
        }
 
8049
        /*
 
8050
         * When truncating the previous pointer will be freed via
 
8051
         * savedbp.  Eliminate the freefrag which would dup free.
 
8052
         */
 
8053
        if (trunc && (freefrag = newblk->nb_freefrag) != NULL) {
 
8054
                newblk->nb_freefrag = NULL;
 
8055
                if (freefrag->ff_jdep)
 
8056
                        cancel_jfreefrag(
 
8057
                            WK_JFREEFRAG(freefrag->ff_jdep));
 
8058
                jwork_move(&freeblks->fb_jwork, &freefrag->ff_jwork);
 
8059
                WORKITEM_FREE(freefrag, D_FREEFRAG);
 
8060
        }
 
8061
        /*
 
8062
         * If the journal hasn't been written the jnewblk must be passed
 
8063
         * to the call to ffs_blkfree that reclaims the space.  We accomplish
 
8064
         * this by leaving the journal dependency on the newblk to be freed
 
8065
         * when a freework is created in handle_workitem_freeblocks().
 
8066
         */
 
8067
        cancel_newblk(newblk, NULL, &freeblks->fb_jwork);
 
8068
        WORKLIST_INSERT(&freeblks->fb_freeworkhd, &newblk->nb_list);
 
8069
}
 
8070
 
 
8071
/*
 
8072
 * Create the mkdir dependencies for . and .. in a new directory.  Link them
 
8073
 * in to a newdirblk so any subsequent additions are tracked properly.  The
 
8074
 * caller is responsible for adding the mkdir1 dependency to the journal
 
8075
 * and updating id_mkdiradd.  This function returns with lk held.
 
8076
 */
 
8077
static struct mkdir *
 
8078
setup_newdir(dap, newinum, dinum, newdirbp, mkdirp)
 
8079
        struct diradd *dap;
 
8080
        ino_t newinum;
 
8081
        ino_t dinum;
 
8082
        struct buf *newdirbp;
 
8083
        struct mkdir **mkdirp;
 
8084
{
 
8085
        struct newblk *newblk;
 
8086
        struct pagedep *pagedep;
 
8087
        struct inodedep *inodedep;
 
8088
        struct newdirblk *newdirblk = 0;
 
8089
        struct mkdir *mkdir1, *mkdir2;
 
8090
        struct worklist *wk;
 
8091
        struct jaddref *jaddref;
 
8092
        struct mount *mp;
 
8093
 
 
8094
        mp = dap->da_list.wk_mp;
 
8095
        newdirblk = malloc(sizeof(struct newdirblk), M_NEWDIRBLK,
 
8096
            M_SOFTDEP_FLAGS);
 
8097
        workitem_alloc(&newdirblk->db_list, D_NEWDIRBLK, mp);
 
8098
        LIST_INIT(&newdirblk->db_mkdir);
 
8099
        mkdir1 = malloc(sizeof(struct mkdir), M_MKDIR, M_SOFTDEP_FLAGS);
 
8100
        workitem_alloc(&mkdir1->md_list, D_MKDIR, mp);
 
8101
        mkdir1->md_state = ATTACHED | MKDIR_BODY;
 
8102
        mkdir1->md_diradd = dap;
 
8103
        mkdir1->md_jaddref = NULL;
 
8104
        mkdir2 = malloc(sizeof(struct mkdir), M_MKDIR, M_SOFTDEP_FLAGS);
 
8105
        workitem_alloc(&mkdir2->md_list, D_MKDIR, mp);
 
8106
        mkdir2->md_state = ATTACHED | MKDIR_PARENT;
 
8107
        mkdir2->md_diradd = dap;
 
8108
        mkdir2->md_jaddref = NULL;
 
8109
        if (MOUNTEDSUJ(mp) == 0) {
 
8110
                mkdir1->md_state |= DEPCOMPLETE;
 
8111
                mkdir2->md_state |= DEPCOMPLETE;
 
8112
        }
 
8113
        /*
 
8114
         * Dependency on "." and ".." being written to disk.
 
8115
         */
 
8116
        mkdir1->md_buf = newdirbp;
 
8117
        ACQUIRE_LOCK(&lk);
 
8118
        LIST_INSERT_HEAD(&mkdirlisthd, mkdir1, md_mkdirs);
 
8119
        /*
 
8120
         * We must link the pagedep, allocdirect, and newdirblk for
 
8121
         * the initial file page so the pointer to the new directory
 
8122
         * is not written until the directory contents are live and
 
8123
         * any subsequent additions are not marked live until the
 
8124
         * block is reachable via the inode.
 
8125
         */
 
8126
        if (pagedep_lookup(mp, newdirbp, newinum, 0, 0, &pagedep) == 0)
 
8127
                panic("setup_newdir: lost pagedep");
 
8128
        LIST_FOREACH(wk, &newdirbp->b_dep, wk_list)
 
8129
                if (wk->wk_type == D_ALLOCDIRECT)
 
8130
                        break;
 
8131
        if (wk == NULL)
 
8132
                panic("setup_newdir: lost allocdirect");
 
8133
        if (pagedep->pd_state & NEWBLOCK)
 
8134
                panic("setup_newdir: NEWBLOCK already set");
 
8135
        newblk = WK_NEWBLK(wk);
 
8136
        pagedep->pd_state |= NEWBLOCK;
 
8137
        pagedep->pd_newdirblk = newdirblk;
 
8138
        newdirblk->db_pagedep = pagedep;
 
8139
        WORKLIST_INSERT(&newblk->nb_newdirblk, &newdirblk->db_list);
 
8140
        WORKLIST_INSERT(&newdirblk->db_mkdir, &mkdir1->md_list);
 
8141
        /*
 
8142
         * Look up the inodedep for the parent directory so that we
 
8143
         * can link mkdir2 into the pending dotdot jaddref or
 
8144
         * the inode write if there is none.  If the inode is
 
8145
         * ALLCOMPLETE and no jaddref is present all dependencies have
 
8146
         * been satisfied and mkdir2 can be freed.
 
8147
         */
 
8148
        inodedep_lookup(mp, dinum, 0, &inodedep);
 
8149
        if (MOUNTEDSUJ(mp)) {
2956
8150
                if (inodedep == NULL)
2957
 
                        add_to_worklist(&freefrag->ff_list);
2958
 
                else
2959
 
                        WORKLIST_INSERT(&inodedep->id_bufwait,
2960
 
                            &freefrag->ff_list);
 
8151
                        panic("setup_newdir: Lost parent.");
 
8152
                jaddref = (struct jaddref *)TAILQ_LAST(&inodedep->id_inoreflst,
 
8153
                    inoreflst);
 
8154
                KASSERT(jaddref != NULL && jaddref->ja_parent == newinum &&
 
8155
                    (jaddref->ja_state & MKDIR_PARENT),
 
8156
                    ("setup_newdir: bad dotdot jaddref %p", jaddref));
 
8157
                LIST_INSERT_HEAD(&mkdirlisthd, mkdir2, md_mkdirs);
 
8158
                mkdir2->md_jaddref = jaddref;
 
8159
                jaddref->ja_mkdir = mkdir2;
 
8160
        } else if (inodedep == NULL ||
 
8161
            (inodedep->id_state & ALLCOMPLETE) == ALLCOMPLETE) {
 
8162
                dap->da_state &= ~MKDIR_PARENT;
 
8163
                WORKITEM_FREE(mkdir2, D_MKDIR);
 
8164
                mkdir2 = NULL;
 
8165
        } else {
 
8166
                LIST_INSERT_HEAD(&mkdirlisthd, mkdir2, md_mkdirs);
 
8167
                WORKLIST_INSERT(&inodedep->id_bufwait, &mkdir2->md_list);
2961
8168
        }
2962
 
        WORKITEM_FREE(aip, D_ALLOCINDIR);
 
8169
        *mkdirp = mkdir2;
 
8170
 
 
8171
        return (mkdir1);
2963
8172
}
2964
8173
 
2965
8174
/*
2998
8207
        ufs_lbn_t lbn;          /* block in directory containing new entry */
2999
8208
        struct fs *fs;
3000
8209
        struct diradd *dap;
3001
 
        struct allocdirect *adp;
 
8210
        struct newblk *newblk;
3002
8211
        struct pagedep *pagedep;
3003
8212
        struct inodedep *inodedep;
3004
8213
        struct newdirblk *newdirblk = 0;
3005
8214
        struct mkdir *mkdir1, *mkdir2;
 
8215
        struct jaddref *jaddref;
3006
8216
        struct mount *mp;
 
8217
        int isindir;
3007
8218
 
3008
8219
        /*
3009
8220
         * Whiteouts have no dependencies.
3013
8224
                        bdwrite(newdirbp);
3014
8225
                return (0);
3015
8226
        }
 
8227
        jaddref = NULL;
 
8228
        mkdir1 = mkdir2 = NULL;
3016
8229
        mp = UFSTOVFS(dp->i_ump);
3017
8230
        fs = dp->i_fs;
3018
8231
        lbn = lblkno(fs, diroffset);
3023
8236
        dap->da_offset = offset;
3024
8237
        dap->da_newinum = newinum;
3025
8238
        dap->da_state = ATTACHED;
3026
 
        if (isnewblk && lbn < NDADDR && fragoff(fs, diroffset) == 0) {
 
8239
        LIST_INIT(&dap->da_jwork);
 
8240
        isindir = bp->b_lblkno >= NDADDR;
 
8241
        if (isnewblk &&
 
8242
            (isindir ? blkoff(fs, diroffset) : fragoff(fs, diroffset)) == 0) {
3027
8243
                newdirblk = malloc(sizeof(struct newdirblk),
3028
8244
                    M_NEWDIRBLK, M_SOFTDEP_FLAGS);
3029
8245
                workitem_alloc(&newdirblk->db_list, D_NEWDIRBLK, mp);
 
8246
                LIST_INIT(&newdirblk->db_mkdir);
3030
8247
        }
 
8248
        /*
 
8249
         * If we're creating a new directory setup the dependencies and set
 
8250
         * the dap state to wait for them.  Otherwise it's COMPLETE and
 
8251
         * we can move on.
 
8252
         */
3031
8253
        if (newdirbp == NULL) {
3032
8254
                dap->da_state |= DEPCOMPLETE;
3033
8255
                ACQUIRE_LOCK(&lk);
3034
8256
        } else {
3035
8257
                dap->da_state |= MKDIR_BODY | MKDIR_PARENT;
3036
 
                mkdir1 = malloc(sizeof(struct mkdir), M_MKDIR,
3037
 
                    M_SOFTDEP_FLAGS);
3038
 
                workitem_alloc(&mkdir1->md_list, D_MKDIR, mp);
3039
 
                mkdir1->md_state = MKDIR_BODY;
3040
 
                mkdir1->md_diradd = dap;
3041
 
                mkdir2 = malloc(sizeof(struct mkdir), M_MKDIR,
3042
 
                    M_SOFTDEP_FLAGS);
3043
 
                workitem_alloc(&mkdir2->md_list, D_MKDIR, mp);
3044
 
                mkdir2->md_state = MKDIR_PARENT;
3045
 
                mkdir2->md_diradd = dap;
3046
 
                /*
3047
 
                 * Dependency on "." and ".." being written to disk.
3048
 
                 */
3049
 
                mkdir1->md_buf = newdirbp;
3050
 
                ACQUIRE_LOCK(&lk);
3051
 
                LIST_INSERT_HEAD(&mkdirlisthd, mkdir1, md_mkdirs);
3052
 
                WORKLIST_INSERT(&newdirbp->b_dep, &mkdir1->md_list);
3053
 
                FREE_LOCK(&lk);
3054
 
                bdwrite(newdirbp);
3055
 
                /*
3056
 
                 * Dependency on link count increase for parent directory
3057
 
                 */
3058
 
                ACQUIRE_LOCK(&lk);
3059
 
                if (inodedep_lookup(mp, dp->i_number, 0, &inodedep) == 0
3060
 
                    || (inodedep->id_state & ALLCOMPLETE) == ALLCOMPLETE) {
3061
 
                        dap->da_state &= ~MKDIR_PARENT;
3062
 
                        WORKITEM_FREE(mkdir2, D_MKDIR);
3063
 
                } else {
3064
 
                        LIST_INSERT_HEAD(&mkdirlisthd, mkdir2, md_mkdirs);
3065
 
                        WORKLIST_INSERT(&inodedep->id_bufwait,&mkdir2->md_list);
3066
 
                }
 
8258
                mkdir1 = setup_newdir(dap, newinum, dp->i_number, newdirbp,
 
8259
                    &mkdir2);
3067
8260
        }
3068
8261
        /*
3069
8262
         * Link into parent directory pagedep to await its being written.
3070
8263
         */
3071
 
        if (pagedep_lookup(dp, lbn, DEPALLOC, &pagedep) == 0)
3072
 
                WORKLIST_INSERT(&bp->b_dep, &pagedep->pd_list);
 
8264
        pagedep_lookup(mp, bp, dp->i_number, lbn, DEPALLOC, &pagedep);
 
8265
#ifdef DEBUG
 
8266
        if (diradd_lookup(pagedep, offset) != NULL)
 
8267
                panic("softdep_setup_directory_add: %p already at off %d\n",
 
8268
                    diradd_lookup(pagedep, offset), offset);
 
8269
#endif
3073
8270
        dap->da_pagedep = pagedep;
3074
8271
        LIST_INSERT_HEAD(&pagedep->pd_diraddhd[DIRADDHASH(offset)], dap,
3075
8272
            da_pdlist);
 
8273
        inodedep_lookup(mp, newinum, DEPALLOC | NODELAY, &inodedep);
3076
8274
        /*
3077
 
         * Link into its inodedep. Put it on the id_bufwait list if the inode
3078
 
         * is not yet written. If it is written, do the post-inode write
3079
 
         * processing to put it on the id_pendinghd list.
 
8275
         * If we're journaling, link the diradd into the jaddref so it
 
8276
         * may be completed after the journal entry is written.  Otherwise,
 
8277
         * link the diradd into its inodedep.  If the inode is not yet
 
8278
         * written place it on the bufwait list, otherwise do the post-inode
 
8279
         * write processing to put it on the id_pendinghd list.
3080
8280
         */
3081
 
        (void) inodedep_lookup(mp, newinum, DEPALLOC, &inodedep);
3082
 
        if ((inodedep->id_state & ALLCOMPLETE) == ALLCOMPLETE)
 
8281
        if (MOUNTEDSUJ(mp)) {
 
8282
                jaddref = (struct jaddref *)TAILQ_LAST(&inodedep->id_inoreflst,
 
8283
                    inoreflst);
 
8284
                KASSERT(jaddref != NULL && jaddref->ja_parent == dp->i_number,
 
8285
                    ("softdep_setup_directory_add: bad jaddref %p", jaddref));
 
8286
                jaddref->ja_diroff = diroffset;
 
8287
                jaddref->ja_diradd = dap;
 
8288
                add_to_journal(&jaddref->ja_list);
 
8289
        } else if ((inodedep->id_state & ALLCOMPLETE) == ALLCOMPLETE)
3083
8290
                diradd_inode_written(dap, inodedep);
3084
8291
        else
3085
8292
                WORKLIST_INSERT(&inodedep->id_bufwait, &dap->da_list);
3086
 
        if (isnewblk) {
3087
 
                /*
3088
 
                 * Directories growing into indirect blocks are rare
3089
 
                 * enough and the frequency of new block allocation
3090
 
                 * in those cases even more rare, that we choose not
3091
 
                 * to bother tracking them. Rather we simply force the
3092
 
                 * new directory entry to disk.
3093
 
                 */
3094
 
                if (lbn >= NDADDR) {
3095
 
                        FREE_LOCK(&lk);
3096
 
                        /*
3097
 
                         * We only have a new allocation when at the
3098
 
                         * beginning of a new block, not when we are
3099
 
                         * expanding into an existing block.
3100
 
                         */
3101
 
                        if (blkoff(fs, diroffset) == 0)
3102
 
                                return (1);
3103
 
                        return (0);
3104
 
                }
3105
 
                /*
3106
 
                 * We only have a new allocation when at the beginning
3107
 
                 * of a new fragment, not when we are expanding into an
3108
 
                 * existing fragment. Also, there is nothing to do if we
3109
 
                 * are already tracking this block.
3110
 
                 */
3111
 
                if (fragoff(fs, diroffset) != 0) {
3112
 
                        FREE_LOCK(&lk);
3113
 
                        return (0);
3114
 
                }
 
8293
        /*
 
8294
         * Add the journal entries for . and .. links now that the primary
 
8295
         * link is written.
 
8296
         */
 
8297
        if (mkdir1 != NULL && MOUNTEDSUJ(mp)) {
 
8298
                jaddref = (struct jaddref *)TAILQ_PREV(&jaddref->ja_ref,
 
8299
                    inoreflst, if_deps);
 
8300
                KASSERT(jaddref != NULL &&
 
8301
                    jaddref->ja_ino == jaddref->ja_parent &&
 
8302
                    (jaddref->ja_state & MKDIR_BODY),
 
8303
                    ("softdep_setup_directory_add: bad dot jaddref %p",
 
8304
                    jaddref));
 
8305
                mkdir1->md_jaddref = jaddref;
 
8306
                jaddref->ja_mkdir = mkdir1;
 
8307
                /*
 
8308
                 * It is important that the dotdot journal entry
 
8309
                 * is added prior to the dot entry since dot writes
 
8310
                 * both the dot and dotdot links.  These both must
 
8311
                 * be added after the primary link for the journal
 
8312
                 * to remain consistent.
 
8313
                 */
 
8314
                add_to_journal(&mkdir2->md_jaddref->ja_list);
 
8315
                add_to_journal(&jaddref->ja_list);
 
8316
        }
 
8317
        /*
 
8318
         * If we are adding a new directory remember this diradd so that if
 
8319
         * we rename it we can keep the dot and dotdot dependencies.  If
 
8320
         * we are adding a new name for an inode that has a mkdiradd we
 
8321
         * must be in rename and we have to move the dot and dotdot
 
8322
         * dependencies to this new name.  The old name is being orphaned
 
8323
         * soon.
 
8324
         */
 
8325
        if (mkdir1 != NULL) {
 
8326
                if (inodedep->id_mkdiradd != NULL)
 
8327
                        panic("softdep_setup_directory_add: Existing mkdir");
 
8328
                inodedep->id_mkdiradd = dap;
 
8329
        } else if (inodedep->id_mkdiradd)
 
8330
                merge_diradd(inodedep, dap);
 
8331
        if (newdirblk) {
 
8332
                /*
 
8333
                 * There is nothing to do if we are already tracking
 
8334
                 * this block.
 
8335
                 */
3115
8336
                if ((pagedep->pd_state & NEWBLOCK) != 0) {
3116
8337
                        WORKITEM_FREE(newdirblk, D_NEWDIRBLK);
3117
8338
                        FREE_LOCK(&lk);
3118
8339
                        return (0);
3119
8340
                }
3120
 
                /*
3121
 
                 * Find our associated allocdirect and have it track us.
3122
 
                 */
3123
 
                if (inodedep_lookup(mp, dp->i_number, 0, &inodedep) == 0)
3124
 
                        panic("softdep_setup_directory_add: lost inodedep");
3125
 
                adp = TAILQ_LAST(&inodedep->id_newinoupdt, allocdirectlst);
3126
 
                if (adp == NULL || adp->ad_lbn != lbn)
 
8341
                if (newblk_lookup(mp, dbtofsb(fs, bp->b_blkno), 0, &newblk)
 
8342
                    == 0)
3127
8343
                        panic("softdep_setup_directory_add: lost entry");
 
8344
                WORKLIST_INSERT(&newblk->nb_newdirblk, &newdirblk->db_list);
3128
8345
                pagedep->pd_state |= NEWBLOCK;
 
8346
                pagedep->pd_newdirblk = newdirblk;
3129
8347
                newdirblk->db_pagedep = pagedep;
3130
 
                WORKLIST_INSERT(&adp->ad_newdirblk, &newdirblk->db_list);
 
8348
                FREE_LOCK(&lk);
 
8349
                /*
 
8350
                 * If we extended into an indirect signal direnter to sync.
 
8351
                 */
 
8352
                if (isindir)
 
8353
                        return (1);
 
8354
                return (0);
3131
8355
        }
3132
8356
        FREE_LOCK(&lk);
3133
8357
        return (0);
3141
8365
 * occur while the move is in progress.
3142
8366
 */
3143
8367
void 
3144
 
softdep_change_directoryentry_offset(dp, base, oldloc, newloc, entrysize)
 
8368
softdep_change_directoryentry_offset(bp, dp, base, oldloc, newloc, entrysize)
 
8369
        struct buf *bp;         /* Buffer holding directory block. */
3145
8370
        struct inode *dp;       /* inode for directory */
3146
8371
        caddr_t base;           /* address of dp->i_offset */
3147
8372
        caddr_t oldloc;         /* address of old directory location */
3150
8375
{
3151
8376
        int offset, oldoffset, newoffset;
3152
8377
        struct pagedep *pagedep;
 
8378
        struct jmvref *jmvref;
3153
8379
        struct diradd *dap;
 
8380
        struct direct *de;
 
8381
        struct mount *mp;
3154
8382
        ufs_lbn_t lbn;
 
8383
        int flags;
3155
8384
 
3156
 
        ACQUIRE_LOCK(&lk);
 
8385
        mp = UFSTOVFS(dp->i_ump);
 
8386
        de = (struct direct *)oldloc;
 
8387
        jmvref = NULL;
 
8388
        flags = 0;
 
8389
        /*
 
8390
         * Moves are always journaled as it would be too complex to
 
8391
         * determine if any affected adds or removes are present in the
 
8392
         * journal.
 
8393
         */
 
8394
        if (MOUNTEDSUJ(mp)) {
 
8395
                flags = DEPALLOC;
 
8396
                jmvref = newjmvref(dp, de->d_ino,
 
8397
                    dp->i_offset + (oldloc - base),
 
8398
                    dp->i_offset + (newloc - base));
 
8399
        }
3157
8400
        lbn = lblkno(dp->i_fs, dp->i_offset);
3158
8401
        offset = blkoff(dp->i_fs, dp->i_offset);
3159
 
        if (pagedep_lookup(dp, lbn, 0, &pagedep) == 0)
3160
 
                goto done;
3161
8402
        oldoffset = offset + (oldloc - base);
3162
8403
        newoffset = offset + (newloc - base);
3163
 
 
3164
 
        LIST_FOREACH(dap, &pagedep->pd_diraddhd[DIRADDHASH(oldoffset)], da_pdlist) {
3165
 
                if (dap->da_offset != oldoffset)
3166
 
                        continue;
 
8404
        ACQUIRE_LOCK(&lk);
 
8405
        if (pagedep_lookup(mp, bp, dp->i_number, lbn, flags, &pagedep) == 0)
 
8406
                goto done;
 
8407
        dap = diradd_lookup(pagedep, oldoffset);
 
8408
        if (dap) {
3167
8409
                dap->da_offset = newoffset;
3168
 
                if (DIRADDHASH(newoffset) == DIRADDHASH(oldoffset))
3169
 
                        break;
3170
 
                LIST_REMOVE(dap, da_pdlist);
3171
 
                LIST_INSERT_HEAD(&pagedep->pd_diraddhd[DIRADDHASH(newoffset)],
3172
 
                    dap, da_pdlist);
3173
 
                break;
3174
 
        }
3175
 
        if (dap == NULL) {
3176
 
 
3177
 
                LIST_FOREACH(dap, &pagedep->pd_pendinghd, da_pdlist) {
3178
 
                        if (dap->da_offset == oldoffset) {
3179
 
                                dap->da_offset = newoffset;
3180
 
                                break;
3181
 
                        }
 
8410
                newoffset = DIRADDHASH(newoffset);
 
8411
                oldoffset = DIRADDHASH(oldoffset);
 
8412
                if ((dap->da_state & ALLCOMPLETE) != ALLCOMPLETE &&
 
8413
                    newoffset != oldoffset) {
 
8414
                        LIST_REMOVE(dap, da_pdlist);
 
8415
                        LIST_INSERT_HEAD(&pagedep->pd_diraddhd[newoffset],
 
8416
                            dap, da_pdlist);
3182
8417
                }
3183
8418
        }
3184
8419
done:
 
8420
        if (jmvref) {
 
8421
                jmvref->jm_pagedep = pagedep;
 
8422
                LIST_INSERT_HEAD(&pagedep->pd_jmvrefhd, jmvref, jm_deps);
 
8423
                add_to_journal(&jmvref->jm_list);
 
8424
        }
3185
8425
        bcopy(oldloc, newloc, entrysize);
3186
8426
        FREE_LOCK(&lk);
3187
8427
}
3188
8428
 
3189
8429
/*
 
8430
 * Move the mkdir dependencies and journal work from one diradd to another
 
8431
 * when renaming a directory.  The new name must depend on the mkdir deps
 
8432
 * completing as the old name did.  Directories can only have one valid link
 
8433
 * at a time so one must be canonical.
 
8434
 */
 
8435
static void
 
8436
merge_diradd(inodedep, newdap)
 
8437
        struct inodedep *inodedep;
 
8438
        struct diradd *newdap;
 
8439
{
 
8440
        struct diradd *olddap;
 
8441
        struct mkdir *mkdir, *nextmd;
 
8442
        short state;
 
8443
 
 
8444
        olddap = inodedep->id_mkdiradd;
 
8445
        inodedep->id_mkdiradd = newdap;
 
8446
        if ((olddap->da_state & (MKDIR_PARENT | MKDIR_BODY)) != 0) {
 
8447
                newdap->da_state &= ~DEPCOMPLETE;
 
8448
                for (mkdir = LIST_FIRST(&mkdirlisthd); mkdir; mkdir = nextmd) {
 
8449
                        nextmd = LIST_NEXT(mkdir, md_mkdirs);
 
8450
                        if (mkdir->md_diradd != olddap)
 
8451
                                continue;
 
8452
                        mkdir->md_diradd = newdap;
 
8453
                        state = mkdir->md_state & (MKDIR_PARENT | MKDIR_BODY);
 
8454
                        newdap->da_state |= state;
 
8455
                        olddap->da_state &= ~state;
 
8456
                        if ((olddap->da_state &
 
8457
                            (MKDIR_PARENT | MKDIR_BODY)) == 0)
 
8458
                                break;
 
8459
                }
 
8460
                if ((olddap->da_state & (MKDIR_PARENT | MKDIR_BODY)) != 0)
 
8461
                        panic("merge_diradd: unfound ref");
 
8462
        }
 
8463
        /*
 
8464
         * Any mkdir related journal items are not safe to be freed until
 
8465
         * the new name is stable.
 
8466
         */
 
8467
        jwork_move(&newdap->da_jwork, &olddap->da_jwork);
 
8468
        olddap->da_state |= DEPCOMPLETE;
 
8469
        complete_diradd(olddap);
 
8470
}
 
8471
 
 
8472
/*
 
8473
 * Move the diradd to the pending list when all diradd dependencies are
 
8474
 * complete.
 
8475
 */
 
8476
static void
 
8477
complete_diradd(dap)
 
8478
        struct diradd *dap;
 
8479
{
 
8480
        struct pagedep *pagedep;
 
8481
 
 
8482
        if ((dap->da_state & ALLCOMPLETE) == ALLCOMPLETE) {
 
8483
                if (dap->da_state & DIRCHG)
 
8484
                        pagedep = dap->da_previous->dm_pagedep;
 
8485
                else
 
8486
                        pagedep = dap->da_pagedep;
 
8487
                LIST_REMOVE(dap, da_pdlist);
 
8488
                LIST_INSERT_HEAD(&pagedep->pd_pendinghd, dap, da_pdlist);
 
8489
        }
 
8490
}
 
8491
 
 
8492
/*
 
8493
 * Cancel a diradd when a dirrem overlaps with it.  We must cancel the journal
 
8494
 * add entries and conditonally journal the remove.
 
8495
 */
 
8496
static void
 
8497
cancel_diradd(dap, dirrem, jremref, dotremref, dotdotremref)
 
8498
        struct diradd *dap;
 
8499
        struct dirrem *dirrem;
 
8500
        struct jremref *jremref;
 
8501
        struct jremref *dotremref;
 
8502
        struct jremref *dotdotremref;
 
8503
{
 
8504
        struct inodedep *inodedep;
 
8505
        struct jaddref *jaddref;
 
8506
        struct inoref *inoref;
 
8507
        struct mkdir *mkdir;
 
8508
 
 
8509
        /*
 
8510
         * If no remove references were allocated we're on a non-journaled
 
8511
         * filesystem and can skip the cancel step.
 
8512
         */
 
8513
        if (jremref == NULL) {
 
8514
                free_diradd(dap, NULL);
 
8515
                return;
 
8516
        }
 
8517
        /*
 
8518
         * Cancel the primary name an free it if it does not require
 
8519
         * journaling.
 
8520
         */
 
8521
        if (inodedep_lookup(dap->da_list.wk_mp, dap->da_newinum,
 
8522
            0, &inodedep) != 0) {
 
8523
                /* Abort the addref that reference this diradd.  */
 
8524
                TAILQ_FOREACH(inoref, &inodedep->id_inoreflst, if_deps) {
 
8525
                        if (inoref->if_list.wk_type != D_JADDREF)
 
8526
                                continue;
 
8527
                        jaddref = (struct jaddref *)inoref;
 
8528
                        if (jaddref->ja_diradd != dap)
 
8529
                                continue;
 
8530
                        if (cancel_jaddref(jaddref, inodedep,
 
8531
                            &dirrem->dm_jwork) == 0) {
 
8532
                                free_jremref(jremref);
 
8533
                                jremref = NULL;
 
8534
                        }
 
8535
                        break;
 
8536
                }
 
8537
        }
 
8538
        /*
 
8539
         * Cancel subordinate names and free them if they do not require
 
8540
         * journaling.
 
8541
         */
 
8542
        if ((dap->da_state & (MKDIR_PARENT | MKDIR_BODY)) != 0) {
 
8543
                LIST_FOREACH(mkdir, &mkdirlisthd, md_mkdirs) {
 
8544
                        if (mkdir->md_diradd != dap)
 
8545
                                continue;
 
8546
                        if ((jaddref = mkdir->md_jaddref) == NULL)
 
8547
                                continue;
 
8548
                        mkdir->md_jaddref = NULL;
 
8549
                        if (mkdir->md_state & MKDIR_PARENT) {
 
8550
                                if (cancel_jaddref(jaddref, NULL,
 
8551
                                    &dirrem->dm_jwork) == 0) {
 
8552
                                        free_jremref(dotdotremref);
 
8553
                                        dotdotremref = NULL;
 
8554
                                }
 
8555
                        } else {
 
8556
                                if (cancel_jaddref(jaddref, inodedep,
 
8557
                                    &dirrem->dm_jwork) == 0) {
 
8558
                                        free_jremref(dotremref);
 
8559
                                        dotremref = NULL;
 
8560
                                }
 
8561
                        }
 
8562
                }
 
8563
        }
 
8564
 
 
8565
        if (jremref)
 
8566
                journal_jremref(dirrem, jremref, inodedep);
 
8567
        if (dotremref)
 
8568
                journal_jremref(dirrem, dotremref, inodedep);
 
8569
        if (dotdotremref)
 
8570
                journal_jremref(dirrem, dotdotremref, NULL);
 
8571
        jwork_move(&dirrem->dm_jwork, &dap->da_jwork);
 
8572
        free_diradd(dap, &dirrem->dm_jwork);
 
8573
}
 
8574
 
 
8575
/*
3190
8576
 * Free a diradd dependency structure. This routine must be called
3191
8577
 * with splbio interrupts blocked.
3192
8578
 */
3193
8579
static void
3194
 
free_diradd(dap)
 
8580
free_diradd(dap, wkhd)
3195
8581
        struct diradd *dap;
 
8582
        struct workhead *wkhd;
3196
8583
{
3197
8584
        struct dirrem *dirrem;
3198
8585
        struct pagedep *pagedep;
3200
8587
        struct mkdir *mkdir, *nextmd;
3201
8588
 
3202
8589
        mtx_assert(&lk, MA_OWNED);
3203
 
        WORKLIST_REMOVE(&dap->da_list);
3204
8590
        LIST_REMOVE(dap, da_pdlist);
 
8591
        if (dap->da_state & ONWORKLIST)
 
8592
                WORKLIST_REMOVE(&dap->da_list);
3205
8593
        if ((dap->da_state & DIRCHG) == 0) {
3206
8594
                pagedep = dap->da_pagedep;
3207
8595
        } else {
3208
8596
                dirrem = dap->da_previous;
3209
8597
                pagedep = dirrem->dm_pagedep;
3210
8598
                dirrem->dm_dirinum = pagedep->pd_ino;
3211
 
                add_to_worklist(&dirrem->dm_list);
 
8599
                dirrem->dm_state |= COMPLETE;
 
8600
                if (LIST_EMPTY(&dirrem->dm_jremrefhd))
 
8601
                        add_to_worklist(&dirrem->dm_list, 0);
3212
8602
        }
3213
8603
        if (inodedep_lookup(pagedep->pd_list.wk_mp, dap->da_newinum,
3214
8604
            0, &inodedep) != 0)
3215
 
                (void) free_inodedep(inodedep);
 
8605
                if (inodedep->id_mkdiradd == dap)
 
8606
                        inodedep->id_mkdiradd = NULL;
3216
8607
        if ((dap->da_state & (MKDIR_PARENT | MKDIR_BODY)) != 0) {
3217
8608
                for (mkdir = LIST_FIRST(&mkdirlisthd); mkdir; mkdir = nextmd) {
3218
8609
                        nextmd = LIST_NEXT(mkdir, md_mkdirs);
3219
8610
                        if (mkdir->md_diradd != dap)
3220
8611
                                continue;
3221
 
                        dap->da_state &= ~mkdir->md_state;
3222
 
                        WORKLIST_REMOVE(&mkdir->md_list);
 
8612
                        dap->da_state &=
 
8613
                            ~(mkdir->md_state & (MKDIR_PARENT | MKDIR_BODY));
3223
8614
                        LIST_REMOVE(mkdir, md_mkdirs);
 
8615
                        if (mkdir->md_state & ONWORKLIST)
 
8616
                                WORKLIST_REMOVE(&mkdir->md_list);
 
8617
                        if (mkdir->md_jaddref != NULL)
 
8618
                                panic("free_diradd: Unexpected jaddref");
3224
8619
                        WORKITEM_FREE(mkdir, D_MKDIR);
 
8620
                        if ((dap->da_state & (MKDIR_PARENT | MKDIR_BODY)) == 0)
 
8621
                                break;
3225
8622
                }
3226
8623
                if ((dap->da_state & (MKDIR_PARENT | MKDIR_BODY)) != 0)
3227
8624
                        panic("free_diradd: unfound ref");
3228
8625
        }
 
8626
        if (inodedep)
 
8627
                free_inodedep(inodedep);
 
8628
        /*
 
8629
         * Free any journal segments waiting for the directory write.
 
8630
         */
 
8631
        handle_jwork(&dap->da_jwork);
3229
8632
        WORKITEM_FREE(dap, D_DIRADD);
3230
8633
}
3231
8634
 
3254
8657
        int isrmdir;            /* indicates if doing RMDIR */
3255
8658
{
3256
8659
        struct dirrem *dirrem, *prevdirrem;
 
8660
        struct inodedep *inodedep;
 
8661
        int direct;
3257
8662
 
3258
8663
        /*
3259
 
         * Allocate a new dirrem if appropriate and ACQUIRE_LOCK.
 
8664
         * Allocate a new dirrem if appropriate and ACQUIRE_LOCK.  We want
 
8665
         * newdirrem() to setup the full directory remove which requires
 
8666
         * isrmdir > 1.
3260
8667
         */
3261
8668
        dirrem = newdirrem(bp, dp, ip, isrmdir, &prevdirrem);
 
8669
        /*
 
8670
         * Add the dirrem to the inodedep's pending remove list for quick
 
8671
         * discovery later.
 
8672
         */
 
8673
        if (inodedep_lookup(UFSTOVFS(ip->i_ump), ip->i_number, 0,
 
8674
            &inodedep) == 0)
 
8675
                panic("softdep_setup_remove: Lost inodedep.");
 
8676
        KASSERT((inodedep->id_state & UNLINKED) == 0, ("inode unlinked"));
 
8677
        dirrem->dm_state |= ONDEPLIST;
 
8678
        LIST_INSERT_HEAD(&inodedep->id_dirremhd, dirrem, dm_inonext);
3262
8679
 
3263
8680
        /*
3264
8681
         * If the COMPLETE flag is clear, then there were no active
3280
8697
                        LIST_INSERT_HEAD(&dirrem->dm_pagedep->pd_dirremhd,
3281
8698
                            prevdirrem, dm_next);
3282
8699
                dirrem->dm_dirinum = dirrem->dm_pagedep->pd_ino;
 
8700
                direct = LIST_EMPTY(&dirrem->dm_jremrefhd);
3283
8701
                FREE_LOCK(&lk);
3284
 
                handle_workitem_remove(dirrem, NULL);
3285
 
        }
 
8702
                if (direct)
 
8703
                        handle_workitem_remove(dirrem, 0);
 
8704
        }
 
8705
}
 
8706
 
 
8707
/*
 
8708
 * Check for an entry matching 'offset' on both the pd_dirraddhd list and the
 
8709
 * pd_pendinghd list of a pagedep.
 
8710
 */
 
8711
static struct diradd *
 
8712
diradd_lookup(pagedep, offset)
 
8713
        struct pagedep *pagedep;
 
8714
        int offset;
 
8715
{
 
8716
        struct diradd *dap;
 
8717
 
 
8718
        LIST_FOREACH(dap, &pagedep->pd_diraddhd[DIRADDHASH(offset)], da_pdlist)
 
8719
                if (dap->da_offset == offset)
 
8720
                        return (dap);
 
8721
        LIST_FOREACH(dap, &pagedep->pd_pendinghd, da_pdlist)
 
8722
                if (dap->da_offset == offset)
 
8723
                        return (dap);
 
8724
        return (NULL);
 
8725
}
 
8726
 
 
8727
/*
 
8728
 * Search for a .. diradd dependency in a directory that is being removed.
 
8729
 * If the directory was renamed to a new parent we have a diradd rather
 
8730
 * than a mkdir for the .. entry.  We need to cancel it now before
 
8731
 * it is found in truncate().
 
8732
 */
 
8733
static struct jremref *
 
8734
cancel_diradd_dotdot(ip, dirrem, jremref)
 
8735
        struct inode *ip;
 
8736
        struct dirrem *dirrem;
 
8737
        struct jremref *jremref;
 
8738
{
 
8739
        struct pagedep *pagedep;
 
8740
        struct diradd *dap;
 
8741
        struct worklist *wk;
 
8742
 
 
8743
        if (pagedep_lookup(UFSTOVFS(ip->i_ump), NULL, ip->i_number, 0, 0,
 
8744
            &pagedep) == 0)
 
8745
                return (jremref);
 
8746
        dap = diradd_lookup(pagedep, DOTDOT_OFFSET);
 
8747
        if (dap == NULL)
 
8748
                return (jremref);
 
8749
        cancel_diradd(dap, dirrem, jremref, NULL, NULL);
 
8750
        /*
 
8751
         * Mark any journal work as belonging to the parent so it is freed
 
8752
         * with the .. reference.
 
8753
         */
 
8754
        LIST_FOREACH(wk, &dirrem->dm_jwork, wk_list)
 
8755
                wk->wk_state |= MKDIR_PARENT;
 
8756
        return (NULL);
 
8757
}
 
8758
 
 
8759
/*
 
8760
 * Cancel the MKDIR_PARENT mkdir component of a diradd when we're going to
 
8761
 * replace it with a dirrem/diradd pair as a result of re-parenting a
 
8762
 * directory.  This ensures that we don't simultaneously have a mkdir and
 
8763
 * a diradd for the same .. entry.
 
8764
 */
 
8765
static struct jremref *
 
8766
cancel_mkdir_dotdot(ip, dirrem, jremref)
 
8767
        struct inode *ip;
 
8768
        struct dirrem *dirrem;
 
8769
        struct jremref *jremref;
 
8770
{
 
8771
        struct inodedep *inodedep;
 
8772
        struct jaddref *jaddref;
 
8773
        struct mkdir *mkdir;
 
8774
        struct diradd *dap;
 
8775
 
 
8776
        if (inodedep_lookup(UFSTOVFS(ip->i_ump), ip->i_number, 0,
 
8777
            &inodedep) == 0)
 
8778
                return (jremref);
 
8779
        dap = inodedep->id_mkdiradd;
 
8780
        if (dap == NULL || (dap->da_state & MKDIR_PARENT) == 0)
 
8781
                return (jremref);
 
8782
        for (mkdir = LIST_FIRST(&mkdirlisthd); mkdir;
 
8783
            mkdir = LIST_NEXT(mkdir, md_mkdirs))
 
8784
                if (mkdir->md_diradd == dap && mkdir->md_state & MKDIR_PARENT)
 
8785
                        break;
 
8786
        if (mkdir == NULL)
 
8787
                panic("cancel_mkdir_dotdot: Unable to find mkdir\n");
 
8788
        if ((jaddref = mkdir->md_jaddref) != NULL) {
 
8789
                mkdir->md_jaddref = NULL;
 
8790
                jaddref->ja_state &= ~MKDIR_PARENT;
 
8791
                if (inodedep_lookup(UFSTOVFS(ip->i_ump), jaddref->ja_ino, 0,
 
8792
                    &inodedep) == 0)
 
8793
                        panic("cancel_mkdir_dotdot: Lost parent inodedep");
 
8794
                if (cancel_jaddref(jaddref, inodedep, &dirrem->dm_jwork)) {
 
8795
                        journal_jremref(dirrem, jremref, inodedep);
 
8796
                        jremref = NULL;
 
8797
                }
 
8798
        }
 
8799
        if (mkdir->md_state & ONWORKLIST)
 
8800
                WORKLIST_REMOVE(&mkdir->md_list);
 
8801
        mkdir->md_state |= ALLCOMPLETE;
 
8802
        complete_mkdir(mkdir);
 
8803
        return (jremref);
 
8804
}
 
8805
 
 
8806
static void
 
8807
journal_jremref(dirrem, jremref, inodedep)
 
8808
        struct dirrem *dirrem;
 
8809
        struct jremref *jremref;
 
8810
        struct inodedep *inodedep;
 
8811
{
 
8812
 
 
8813
        if (inodedep == NULL)
 
8814
                if (inodedep_lookup(jremref->jr_list.wk_mp,
 
8815
                    jremref->jr_ref.if_ino, 0, &inodedep) == 0)
 
8816
                        panic("journal_jremref: Lost inodedep");
 
8817
        LIST_INSERT_HEAD(&dirrem->dm_jremrefhd, jremref, jr_deps);
 
8818
        TAILQ_INSERT_TAIL(&inodedep->id_inoreflst, &jremref->jr_ref, if_deps);
 
8819
        add_to_journal(&jremref->jr_list);
 
8820
}
 
8821
 
 
8822
static void
 
8823
dirrem_journal(dirrem, jremref, dotremref, dotdotremref)
 
8824
        struct dirrem *dirrem;
 
8825
        struct jremref *jremref;
 
8826
        struct jremref *dotremref;
 
8827
        struct jremref *dotdotremref;
 
8828
{
 
8829
        struct inodedep *inodedep;
 
8830
 
 
8831
 
 
8832
        if (inodedep_lookup(jremref->jr_list.wk_mp, jremref->jr_ref.if_ino, 0,
 
8833
            &inodedep) == 0)
 
8834
                panic("dirrem_journal: Lost inodedep");
 
8835
        journal_jremref(dirrem, jremref, inodedep);
 
8836
        if (dotremref)
 
8837
                journal_jremref(dirrem, dotremref, inodedep);
 
8838
        if (dotdotremref)
 
8839
                journal_jremref(dirrem, dotdotremref, NULL);
3286
8840
}
3287
8841
 
3288
8842
/*
3289
8843
 * Allocate a new dirrem if appropriate and return it along with
3290
8844
 * its associated pagedep. Called without a lock, returns with lock.
3291
8845
 */
3292
 
static long num_dirrem;         /* number of dirrem allocated */
3293
8846
static struct dirrem *
3294
8847
newdirrem(bp, dp, ip, isrmdir, prevdirremp)
3295
8848
        struct buf *bp;         /* buffer containing directory block */
3303
8856
        struct diradd *dap;
3304
8857
        struct dirrem *dirrem;
3305
8858
        struct pagedep *pagedep;
 
8859
        struct jremref *jremref;
 
8860
        struct jremref *dotremref;
 
8861
        struct jremref *dotdotremref;
 
8862
        struct vnode *dvp;
3306
8863
 
3307
8864
        /*
3308
8865
         * Whiteouts have no deletion dependencies.
3309
8866
         */
3310
8867
        if (ip == NULL)
3311
8868
                panic("newdirrem: whiteout");
 
8869
        dvp = ITOV(dp);
3312
8870
        /*
3313
8871
         * If we are over our limit, try to improve the situation.
3314
8872
         * Limiting the number of dirrem structures will also limit
3315
8873
         * the number of freefile and freeblks structures.
3316
8874
         */
3317
8875
        ACQUIRE_LOCK(&lk);
3318
 
        if (!(ip->i_flags & SF_SNAPSHOT) && num_dirrem > max_softdeps / 2)
3319
 
                (void) request_cleanup(ITOV(dp)->v_mount, FLUSH_REMOVE);
3320
 
        num_dirrem += 1;
 
8876
        if (!IS_SNAPSHOT(ip) && dep_current[D_DIRREM] > max_softdeps / 2)
 
8877
                (void) request_cleanup(ITOV(dp)->v_mount, FLUSH_BLOCKS);
3321
8878
        FREE_LOCK(&lk);
3322
8879
        dirrem = malloc(sizeof(struct dirrem),
3323
8880
                M_DIRREM, M_SOFTDEP_FLAGS|M_ZERO);
3324
 
        workitem_alloc(&dirrem->dm_list, D_DIRREM, ITOV(dp)->v_mount);
 
8881
        workitem_alloc(&dirrem->dm_list, D_DIRREM, dvp->v_mount);
 
8882
        LIST_INIT(&dirrem->dm_jremrefhd);
 
8883
        LIST_INIT(&dirrem->dm_jwork);
3325
8884
        dirrem->dm_state = isrmdir ? RMDIR : 0;
3326
8885
        dirrem->dm_oldinum = ip->i_number;
3327
8886
        *prevdirremp = NULL;
3328
 
 
 
8887
        /*
 
8888
         * Allocate remove reference structures to track journal write
 
8889
         * dependencies.  We will always have one for the link and
 
8890
         * when doing directories we will always have one more for dot.
 
8891
         * When renaming a directory we skip the dotdot link change so
 
8892
         * this is not needed.
 
8893
         */
 
8894
        jremref = dotremref = dotdotremref = NULL;
 
8895
        if (DOINGSUJ(dvp)) {
 
8896
                if (isrmdir) {
 
8897
                        jremref = newjremref(dirrem, dp, ip, dp->i_offset,
 
8898
                            ip->i_effnlink + 2);
 
8899
                        dotremref = newjremref(dirrem, ip, ip, DOT_OFFSET,
 
8900
                            ip->i_effnlink + 1);
 
8901
                        dotdotremref = newjremref(dirrem, ip, dp, DOTDOT_OFFSET,
 
8902
                            dp->i_effnlink + 1);
 
8903
                        dotdotremref->jr_state |= MKDIR_PARENT;
 
8904
                } else
 
8905
                        jremref = newjremref(dirrem, dp, ip, dp->i_offset,
 
8906
                            ip->i_effnlink + 1);
 
8907
        }
3329
8908
        ACQUIRE_LOCK(&lk);
3330
8909
        lbn = lblkno(dp->i_fs, dp->i_offset);
3331
8910
        offset = blkoff(dp->i_fs, dp->i_offset);
3332
 
        if (pagedep_lookup(dp, lbn, DEPALLOC, &pagedep) == 0)
3333
 
                WORKLIST_INSERT(&bp->b_dep, &pagedep->pd_list);
 
8911
        pagedep_lookup(UFSTOVFS(dp->i_ump), bp, dp->i_number, lbn, DEPALLOC,
 
8912
            &pagedep);
3334
8913
        dirrem->dm_pagedep = pagedep;
 
8914
        dirrem->dm_offset = offset;
 
8915
        /*
 
8916
         * If we're renaming a .. link to a new directory, cancel any
 
8917
         * existing MKDIR_PARENT mkdir.  If it has already been canceled
 
8918
         * the jremref is preserved for any potential diradd in this
 
8919
         * location.  This can not coincide with a rmdir.
 
8920
         */
 
8921
        if (dp->i_offset == DOTDOT_OFFSET) {
 
8922
                if (isrmdir)
 
8923
                        panic("newdirrem: .. directory change during remove?");
 
8924
                jremref = cancel_mkdir_dotdot(dp, dirrem, jremref);
 
8925
        }
 
8926
        /*
 
8927
         * If we're removing a directory search for the .. dependency now and
 
8928
         * cancel it.  Any pending journal work will be added to the dirrem
 
8929
         * to be completed when the workitem remove completes.
 
8930
         */
 
8931
        if (isrmdir)
 
8932
                dotdotremref = cancel_diradd_dotdot(ip, dirrem, dotdotremref);
3335
8933
        /*
3336
8934
         * Check for a diradd dependency for the same directory entry.
3337
8935
         * If present, then both dependencies become obsolete and can
3338
 
         * be de-allocated. Check for an entry on both the pd_dirraddhd
3339
 
         * list and the pd_pendinghd list.
 
8936
         * be de-allocated.
3340
8937
         */
3341
 
 
3342
 
        LIST_FOREACH(dap, &pagedep->pd_diraddhd[DIRADDHASH(offset)], da_pdlist)
3343
 
                if (dap->da_offset == offset)
3344
 
                        break;
 
8938
        dap = diradd_lookup(pagedep, offset);
3345
8939
        if (dap == NULL) {
3346
 
 
3347
 
                LIST_FOREACH(dap, &pagedep->pd_pendinghd, da_pdlist)
3348
 
                        if (dap->da_offset == offset)
3349
 
                                break;
3350
 
                if (dap == NULL)
3351
 
                        return (dirrem);
 
8940
                /*
 
8941
                 * Link the jremref structures into the dirrem so they are
 
8942
                 * written prior to the pagedep.
 
8943
                 */
 
8944
                if (jremref)
 
8945
                        dirrem_journal(dirrem, jremref, dotremref,
 
8946
                            dotdotremref);
 
8947
                return (dirrem);
3352
8948
        }
3353
8949
        /*
3354
8950
         * Must be ATTACHED at this point.
3373
8969
         * Mark it COMPLETE so we can delete its inode immediately.
3374
8970
         */
3375
8971
        dirrem->dm_state |= COMPLETE;
3376
 
        free_diradd(dap);
 
8972
        cancel_diradd(dap, dirrem, jremref, dotremref, dotdotremref);
 
8973
#ifdef SUJ_DEBUG
 
8974
        if (isrmdir == 0) {
 
8975
                struct worklist *wk;
 
8976
 
 
8977
                LIST_FOREACH(wk, &dirrem->dm_jwork, wk_list)
 
8978
                        if (wk->wk_state & (MKDIR_BODY | MKDIR_PARENT))
 
8979
                                panic("bad wk %p (0x%X)\n", wk, wk->wk_state);
 
8980
        }
 
8981
#endif
 
8982
 
3377
8983
        return (dirrem);
3378
8984
}
3379
8985
 
3407
9013
        struct dirrem *dirrem, *prevdirrem;
3408
9014
        struct pagedep *pagedep;
3409
9015
        struct inodedep *inodedep;
 
9016
        struct jaddref *jaddref;
3410
9017
        struct mount *mp;
3411
9018
 
3412
9019
        offset = blkoff(dp->i_fs, dp->i_offset);
3422
9029
                dap->da_state = DIRCHG | ATTACHED | DEPCOMPLETE;
3423
9030
                dap->da_offset = offset;
3424
9031
                dap->da_newinum = newinum;
 
9032
                LIST_INIT(&dap->da_jwork);
3425
9033
        }
3426
9034
 
3427
9035
        /*
3454
9062
                            dm_next);
3455
9063
                } else {
3456
9064
                        dirrem->dm_dirinum = pagedep->pd_ino;
3457
 
                        add_to_worklist(&dirrem->dm_list);
 
9065
                        if (LIST_EMPTY(&dirrem->dm_jremrefhd))
 
9066
                                add_to_worklist(&dirrem->dm_list, 0);
3458
9067
                }
3459
9068
                FREE_LOCK(&lk);
3460
9069
                return;
3461
9070
        }
 
9071
        /*
 
9072
         * Add the dirrem to the inodedep's pending remove list for quick
 
9073
         * discovery later.  A valid nlinkdelta ensures that this lookup
 
9074
         * will not fail.
 
9075
         */
 
9076
        if (inodedep_lookup(mp, ip->i_number, 0, &inodedep) == 0)
 
9077
                panic("softdep_setup_directory_change: Lost inodedep.");
 
9078
        dirrem->dm_state |= ONDEPLIST;
 
9079
        LIST_INSERT_HEAD(&inodedep->id_dirremhd, dirrem, dm_inonext);
3462
9080
 
3463
9081
        /*
3464
9082
         * If the COMPLETE flag is clear, then there were no active
3483
9101
                        dap->da_pagedep = pagedep;
3484
9102
                }
3485
9103
                dirrem->dm_dirinum = pagedep->pd_ino;
3486
 
                add_to_worklist(&dirrem->dm_list);
 
9104
                if (LIST_EMPTY(&dirrem->dm_jremrefhd))
 
9105
                        add_to_worklist(&dirrem->dm_list, 0);
3487
9106
        }
3488
9107
        /*
3489
 
         * Link into its inodedep. Put it on the id_bufwait list if the inode
3490
 
         * is not yet written. If it is written, do the post-inode write
3491
 
         * processing to put it on the id_pendinghd list.
 
9108
         * Lookup the jaddref for this journal entry.  We must finish
 
9109
         * initializing it and make the diradd write dependent on it.
 
9110
         * If we're not journaling, put it on the id_bufwait list if the
 
9111
         * inode is not yet written. If it is written, do the post-inode
 
9112
         * write processing to put it on the id_pendinghd list.
3492
9113
         */
3493
 
        if (inodedep_lookup(mp, newinum, DEPALLOC, &inodedep) == 0 ||
3494
 
            (inodedep->id_state & ALLCOMPLETE) == ALLCOMPLETE) {
 
9114
        inodedep_lookup(mp, newinum, DEPALLOC | NODELAY, &inodedep);
 
9115
        if (MOUNTEDSUJ(mp)) {
 
9116
                jaddref = (struct jaddref *)TAILQ_LAST(&inodedep->id_inoreflst,
 
9117
                    inoreflst);
 
9118
                KASSERT(jaddref != NULL && jaddref->ja_parent == dp->i_number,
 
9119
                    ("softdep_setup_directory_change: bad jaddref %p",
 
9120
                    jaddref));
 
9121
                jaddref->ja_diroff = dp->i_offset;
 
9122
                jaddref->ja_diradd = dap;
 
9123
                LIST_INSERT_HEAD(&pagedep->pd_diraddhd[DIRADDHASH(offset)],
 
9124
                    dap, da_pdlist);
 
9125
                add_to_journal(&jaddref->ja_list);
 
9126
        } else if ((inodedep->id_state & ALLCOMPLETE) == ALLCOMPLETE) {
3495
9127
                dap->da_state |= COMPLETE;
3496
9128
                LIST_INSERT_HEAD(&pagedep->pd_pendinghd, dap, da_pdlist);
3497
9129
                WORKLIST_INSERT(&inodedep->id_pendinghd, &dap->da_list);
3500
9132
                    dap, da_pdlist);
3501
9133
                WORKLIST_INSERT(&inodedep->id_bufwait, &dap->da_list);
3502
9134
        }
 
9135
        /*
 
9136
         * If we're making a new name for a directory that has not been
 
9137
         * committed when need to move the dot and dotdot references to
 
9138
         * this new name.
 
9139
         */
 
9140
        if (inodedep->id_mkdiradd && dp->i_offset != DOTDOT_OFFSET)
 
9141
                merge_diradd(inodedep, dap);
3503
9142
        FREE_LOCK(&lk);
3504
9143
}
3505
9144
 
3514
9153
        struct inode *ip;       /* the inode with the increased link count */
3515
9154
{
3516
9155
        struct inodedep *inodedep;
 
9156
        int dflags;
3517
9157
 
3518
9158
        ACQUIRE_LOCK(&lk);
3519
 
        (void) inodedep_lookup(UFSTOVFS(ip->i_ump), ip->i_number,
3520
 
            DEPALLOC, &inodedep);
 
9159
        dflags = DEPALLOC;
 
9160
        if (IS_SNAPSHOT(ip))
 
9161
                dflags |= NODELAY;
 
9162
        inodedep_lookup(UFSTOVFS(ip->i_ump), ip->i_number, dflags, &inodedep);
3521
9163
        if (ip->i_nlink < ip->i_effnlink)
3522
9164
                panic("softdep_change_linkcnt: bad delta");
3523
9165
        inodedep->id_nlinkdelta = ip->i_nlink - ip->i_effnlink;
3525
9167
}
3526
9168
 
3527
9169
/*
3528
 
 * Called when the effective link count and the reference count
3529
 
 * on an inode drops to zero. At this point there are no names
3530
 
 * referencing the file in the filesystem and no active file
3531
 
 * references. The space associated with the file will be freed
3532
 
 * as soon as the necessary soft dependencies are cleared.
 
9170
 * Attach a sbdep dependency to the superblock buf so that we can keep
 
9171
 * track of the head of the linked list of referenced but unlinked inodes.
3533
9172
 */
3534
9173
void
3535
 
softdep_releasefile(ip)
3536
 
        struct inode *ip;       /* inode with the zero effective link count */
 
9174
softdep_setup_sbupdate(ump, fs, bp)
 
9175
        struct ufsmount *ump;
 
9176
        struct fs *fs;
 
9177
        struct buf *bp;
3537
9178
{
3538
 
        struct inodedep *inodedep;
3539
 
        struct fs *fs;
3540
 
        int extblocks;
 
9179
        struct sbdep *sbdep;
 
9180
        struct worklist *wk;
3541
9181
 
3542
 
        if (ip->i_effnlink > 0)
3543
 
                panic("softdep_releasefile: file still referenced");
3544
 
        /*
3545
 
         * We may be called several times as the on-disk link count
3546
 
         * drops to zero. We only want to account for the space once.
3547
 
         */
3548
 
        if (ip->i_flag & IN_SPACECOUNTED)
3549
 
                return;
3550
 
        /*
3551
 
         * We have to deactivate a snapshot otherwise copyonwrites may
3552
 
         * add blocks and the cleanup may remove blocks after we have
3553
 
         * tried to account for them.
3554
 
         */
3555
 
        if ((ip->i_flags & SF_SNAPSHOT) != 0)
3556
 
                ffs_snapremove(ITOV(ip));
3557
 
        /*
3558
 
         * If we are tracking an nlinkdelta, we have to also remember
3559
 
         * whether we accounted for the freed space yet.
3560
 
         */
 
9182
        if (MOUNTEDSUJ(UFSTOVFS(ump)) == 0)
 
9183
                return;
 
9184
        LIST_FOREACH(wk, &bp->b_dep, wk_list)
 
9185
                if (wk->wk_type == D_SBDEP)
 
9186
                        break;
 
9187
        if (wk != NULL)
 
9188
                return;
 
9189
        sbdep = malloc(sizeof(struct sbdep), M_SBDEP, M_SOFTDEP_FLAGS);
 
9190
        workitem_alloc(&sbdep->sb_list, D_SBDEP, UFSTOVFS(ump));
 
9191
        sbdep->sb_fs = fs;
 
9192
        sbdep->sb_ump = ump;
3561
9193
        ACQUIRE_LOCK(&lk);
3562
 
        if ((inodedep_lookup(UFSTOVFS(ip->i_ump), ip->i_number, 0, &inodedep)))
3563
 
                inodedep->id_state |= SPACECOUNTED;
 
9194
        WORKLIST_INSERT(&bp->b_dep, &sbdep->sb_list);
3564
9195
        FREE_LOCK(&lk);
3565
 
        fs = ip->i_fs;
3566
 
        extblocks = 0;
3567
 
        if (fs->fs_magic == FS_UFS2_MAGIC)
3568
 
                extblocks = btodb(fragroundup(fs, ip->i_din2->di_extsize));
3569
 
        UFS_LOCK(ip->i_ump);
3570
 
        ip->i_fs->fs_pendingblocks += DIP(ip, i_blocks) - extblocks;
3571
 
        ip->i_fs->fs_pendinginodes += 1;
3572
 
        UFS_UNLOCK(ip->i_ump);
3573
 
        ip->i_flag |= IN_SPACECOUNTED;
 
9196
}
 
9197
 
 
9198
/*
 
9199
 * Return the first unlinked inodedep which is ready to be the head of the
 
9200
 * list.  The inodedep and all those after it must have valid next pointers.
 
9201
 */
 
9202
static struct inodedep *
 
9203
first_unlinked_inodedep(ump)
 
9204
        struct ufsmount *ump;
 
9205
{
 
9206
        struct inodedep *inodedep;
 
9207
        struct inodedep *idp;
 
9208
 
 
9209
        mtx_assert(&lk, MA_OWNED);
 
9210
        for (inodedep = TAILQ_LAST(&ump->softdep_unlinked, inodedeplst);
 
9211
            inodedep; inodedep = idp) {
 
9212
                if ((inodedep->id_state & UNLINKNEXT) == 0)
 
9213
                        return (NULL);
 
9214
                idp = TAILQ_PREV(inodedep, inodedeplst, id_unlinked);
 
9215
                if (idp == NULL || (idp->id_state & UNLINKNEXT) == 0)
 
9216
                        break;
 
9217
                if ((inodedep->id_state & UNLINKPREV) == 0)
 
9218
                        break;
 
9219
        }
 
9220
        return (inodedep);
 
9221
}
 
9222
 
 
9223
/*
 
9224
 * Set the sujfree unlinked head pointer prior to writing a superblock.
 
9225
 */
 
9226
static void
 
9227
initiate_write_sbdep(sbdep)
 
9228
        struct sbdep *sbdep;
 
9229
{
 
9230
        struct inodedep *inodedep;
 
9231
        struct fs *bpfs;
 
9232
        struct fs *fs;
 
9233
 
 
9234
        bpfs = sbdep->sb_fs;
 
9235
        fs = sbdep->sb_ump->um_fs;
 
9236
        inodedep = first_unlinked_inodedep(sbdep->sb_ump);
 
9237
        if (inodedep) {
 
9238
                fs->fs_sujfree = inodedep->id_ino;
 
9239
                inodedep->id_state |= UNLINKPREV;
 
9240
        } else
 
9241
                fs->fs_sujfree = 0;
 
9242
        bpfs->fs_sujfree = fs->fs_sujfree;
 
9243
}
 
9244
 
 
9245
/*
 
9246
 * After a superblock is written determine whether it must be written again
 
9247
 * due to a changing unlinked list head.
 
9248
 */
 
9249
static int
 
9250
handle_written_sbdep(sbdep, bp)
 
9251
        struct sbdep *sbdep;
 
9252
        struct buf *bp;
 
9253
{
 
9254
        struct inodedep *inodedep;
 
9255
        struct mount *mp;
 
9256
        struct fs *fs;
 
9257
 
 
9258
        mtx_assert(&lk, MA_OWNED);
 
9259
        fs = sbdep->sb_fs;
 
9260
        mp = UFSTOVFS(sbdep->sb_ump);
 
9261
        /*
 
9262
         * If the superblock doesn't match the in-memory list start over.
 
9263
         */
 
9264
        inodedep = first_unlinked_inodedep(sbdep->sb_ump);
 
9265
        if ((inodedep && fs->fs_sujfree != inodedep->id_ino) ||
 
9266
            (inodedep == NULL && fs->fs_sujfree != 0)) {
 
9267
                bdirty(bp);
 
9268
                return (1);
 
9269
        }
 
9270
        WORKITEM_FREE(sbdep, D_SBDEP);
 
9271
        if (fs->fs_sujfree == 0)
 
9272
                return (0);
 
9273
        /*
 
9274
         * Now that we have a record of this inode in stable store allow it
 
9275
         * to be written to free up pending work.  Inodes may see a lot of
 
9276
         * write activity after they are unlinked which we must not hold up.
 
9277
         */
 
9278
        for (; inodedep != NULL; inodedep = TAILQ_NEXT(inodedep, id_unlinked)) {
 
9279
                if ((inodedep->id_state & UNLINKLINKS) != UNLINKLINKS)
 
9280
                        panic("handle_written_sbdep: Bad inodedep %p (0x%X)",
 
9281
                            inodedep, inodedep->id_state);
 
9282
                if (inodedep->id_state & UNLINKONLIST)
 
9283
                        break;
 
9284
                inodedep->id_state |= DEPCOMPLETE | UNLINKONLIST;
 
9285
        }
 
9286
 
 
9287
        return (0);
 
9288
}
 
9289
 
 
9290
/*
 
9291
 * Mark an inodedep as unlinked and insert it into the in-memory unlinked list.
 
9292
 */
 
9293
static void
 
9294
unlinked_inodedep(mp, inodedep)
 
9295
        struct mount *mp;
 
9296
        struct inodedep *inodedep;
 
9297
{
 
9298
        struct ufsmount *ump;
 
9299
 
 
9300
        mtx_assert(&lk, MA_OWNED);
 
9301
        if (MOUNTEDSUJ(mp) == 0)
 
9302
                return;
 
9303
        ump = VFSTOUFS(mp);
 
9304
        ump->um_fs->fs_fmod = 1;
 
9305
        if (inodedep->id_state & UNLINKED)
 
9306
                panic("unlinked_inodedep: %p already unlinked\n", inodedep);
 
9307
        inodedep->id_state |= UNLINKED;
 
9308
        TAILQ_INSERT_HEAD(&ump->softdep_unlinked, inodedep, id_unlinked);
 
9309
}
 
9310
 
 
9311
/*
 
9312
 * Remove an inodedep from the unlinked inodedep list.  This may require
 
9313
 * disk writes if the inode has made it that far.
 
9314
 */
 
9315
static void
 
9316
clear_unlinked_inodedep(inodedep)
 
9317
        struct inodedep *inodedep;
 
9318
{
 
9319
        struct ufsmount *ump;
 
9320
        struct inodedep *idp;
 
9321
        struct inodedep *idn;
 
9322
        struct fs *fs;
 
9323
        struct buf *bp;
 
9324
        ino_t ino;
 
9325
        ino_t nino;
 
9326
        ino_t pino;
 
9327
        int error;
 
9328
 
 
9329
        ump = VFSTOUFS(inodedep->id_list.wk_mp);
 
9330
        fs = ump->um_fs;
 
9331
        ino = inodedep->id_ino;
 
9332
        error = 0;
 
9333
        for (;;) {
 
9334
                mtx_assert(&lk, MA_OWNED);
 
9335
                KASSERT((inodedep->id_state & UNLINKED) != 0,
 
9336
                    ("clear_unlinked_inodedep: inodedep %p not unlinked",
 
9337
                    inodedep));
 
9338
                /*
 
9339
                 * If nothing has yet been written simply remove us from
 
9340
                 * the in memory list and return.  This is the most common
 
9341
                 * case where handle_workitem_remove() loses the final
 
9342
                 * reference.
 
9343
                 */
 
9344
                if ((inodedep->id_state & UNLINKLINKS) == 0)
 
9345
                        break;
 
9346
                /*
 
9347
                 * If we have a NEXT pointer and no PREV pointer we can simply
 
9348
                 * clear NEXT's PREV and remove ourselves from the list.  Be
 
9349
                 * careful not to clear PREV if the superblock points at
 
9350
                 * next as well.
 
9351
                 */
 
9352
                idn = TAILQ_NEXT(inodedep, id_unlinked);
 
9353
                if ((inodedep->id_state & UNLINKLINKS) == UNLINKNEXT) {
 
9354
                        if (idn && fs->fs_sujfree != idn->id_ino)
 
9355
                                idn->id_state &= ~UNLINKPREV;
 
9356
                        break;
 
9357
                }
 
9358
                /*
 
9359
                 * Here we have an inodedep which is actually linked into
 
9360
                 * the list.  We must remove it by forcing a write to the
 
9361
                 * link before us, whether it be the superblock or an inode.
 
9362
                 * Unfortunately the list may change while we're waiting
 
9363
                 * on the buf lock for either resource so we must loop until
 
9364
                 * we lock the right one.  If both the superblock and an
 
9365
                 * inode point to this inode we must clear the inode first
 
9366
                 * followed by the superblock.
 
9367
                 */
 
9368
                idp = TAILQ_PREV(inodedep, inodedeplst, id_unlinked);
 
9369
                pino = 0;
 
9370
                if (idp && (idp->id_state & UNLINKNEXT))
 
9371
                        pino = idp->id_ino;
 
9372
                FREE_LOCK(&lk);
 
9373
                if (pino == 0) {
 
9374
                        bp = getblk(ump->um_devvp, btodb(fs->fs_sblockloc),
 
9375
                            (int)fs->fs_sbsize, 0, 0, 0);
 
9376
                } else {
 
9377
                        error = bread(ump->um_devvp,
 
9378
                            fsbtodb(fs, ino_to_fsba(fs, pino)),
 
9379
                            (int)fs->fs_bsize, NOCRED, &bp);
 
9380
                        if (error)
 
9381
                                brelse(bp);
 
9382
                }
 
9383
                ACQUIRE_LOCK(&lk);
 
9384
                if (error)
 
9385
                        break;
 
9386
                /* If the list has changed restart the loop. */
 
9387
                idp = TAILQ_PREV(inodedep, inodedeplst, id_unlinked);
 
9388
                nino = 0;
 
9389
                if (idp && (idp->id_state & UNLINKNEXT))
 
9390
                        nino = idp->id_ino;
 
9391
                if (nino != pino ||
 
9392
                    (inodedep->id_state & UNLINKPREV) != UNLINKPREV) {
 
9393
                        FREE_LOCK(&lk);
 
9394
                        brelse(bp);
 
9395
                        ACQUIRE_LOCK(&lk);
 
9396
                        continue;
 
9397
                }
 
9398
                nino = 0;
 
9399
                idn = TAILQ_NEXT(inodedep, id_unlinked);
 
9400
                if (idn)
 
9401
                        nino = idn->id_ino;
 
9402
                /*
 
9403
                 * Remove us from the in memory list.  After this we cannot
 
9404
                 * access the inodedep.
 
9405
                 */
 
9406
                KASSERT((inodedep->id_state & UNLINKED) != 0,
 
9407
                    ("clear_unlinked_inodedep: inodedep %p not unlinked",
 
9408
                    inodedep));
 
9409
                inodedep->id_state &= ~(UNLINKED | UNLINKLINKS | UNLINKONLIST);
 
9410
                TAILQ_REMOVE(&ump->softdep_unlinked, inodedep, id_unlinked);
 
9411
                FREE_LOCK(&lk);
 
9412
                /*
 
9413
                 * The predecessor's next pointer is manually updated here
 
9414
                 * so that the NEXT flag is never cleared for an element
 
9415
                 * that is in the list.
 
9416
                 */
 
9417
                if (pino == 0) {
 
9418
                        bcopy((caddr_t)fs, bp->b_data, (u_int)fs->fs_sbsize);
 
9419
                        ffs_oldfscompat_write((struct fs *)bp->b_data, ump);
 
9420
                        softdep_setup_sbupdate(ump, (struct fs *)bp->b_data,
 
9421
                            bp);
 
9422
                } else if (fs->fs_magic == FS_UFS1_MAGIC)
 
9423
                        ((struct ufs1_dinode *)bp->b_data +
 
9424
                            ino_to_fsbo(fs, pino))->di_freelink = nino;
 
9425
                else
 
9426
                        ((struct ufs2_dinode *)bp->b_data +
 
9427
                            ino_to_fsbo(fs, pino))->di_freelink = nino;
 
9428
                /*
 
9429
                 * If the bwrite fails we have no recourse to recover.  The
 
9430
                 * filesystem is corrupted already.
 
9431
                 */
 
9432
                bwrite(bp);
 
9433
                ACQUIRE_LOCK(&lk);
 
9434
                /*
 
9435
                 * If the superblock pointer still needs to be cleared force
 
9436
                 * a write here.
 
9437
                 */
 
9438
                if (fs->fs_sujfree == ino) {
 
9439
                        FREE_LOCK(&lk);
 
9440
                        bp = getblk(ump->um_devvp, btodb(fs->fs_sblockloc),
 
9441
                            (int)fs->fs_sbsize, 0, 0, 0);
 
9442
                        bcopy((caddr_t)fs, bp->b_data, (u_int)fs->fs_sbsize);
 
9443
                        ffs_oldfscompat_write((struct fs *)bp->b_data, ump);
 
9444
                        softdep_setup_sbupdate(ump, (struct fs *)bp->b_data,
 
9445
                            bp);
 
9446
                        bwrite(bp);
 
9447
                        ACQUIRE_LOCK(&lk);
 
9448
                }
 
9449
 
 
9450
                if (fs->fs_sujfree != ino)
 
9451
                        return;
 
9452
                panic("clear_unlinked_inodedep: Failed to clear free head");
 
9453
        }
 
9454
        if (inodedep->id_ino == fs->fs_sujfree)
 
9455
                panic("clear_unlinked_inodedep: Freeing head of free list");
 
9456
        inodedep->id_state &= ~(UNLINKED | UNLINKLINKS | UNLINKONLIST);
 
9457
        TAILQ_REMOVE(&ump->softdep_unlinked, inodedep, id_unlinked);
 
9458
        return;
3574
9459
}
3575
9460
 
3576
9461
/*
3577
9462
 * This workitem decrements the inode's link count.
3578
9463
 * If the link count reaches zero, the file is removed.
3579
9464
 */
3580
 
static void 
3581
 
handle_workitem_remove(dirrem, xp)
 
9465
static int
 
9466
handle_workitem_remove(dirrem, flags)
3582
9467
        struct dirrem *dirrem;
3583
 
        struct vnode *xp;
 
9468
        int flags;
3584
9469
{
3585
 
        struct thread *td = curthread;
3586
9470
        struct inodedep *inodedep;
 
9471
        struct workhead dotdotwk;
 
9472
        struct worklist *wk;
 
9473
        struct ufsmount *ump;
 
9474
        struct mount *mp;
3587
9475
        struct vnode *vp;
3588
9476
        struct inode *ip;
3589
9477
        ino_t oldinum;
3590
 
        int error;
3591
9478
 
3592
 
        if ((vp = xp) == NULL &&
3593
 
            (error = ffs_vgetf(dirrem->dm_list.wk_mp,
3594
 
                    dirrem->dm_oldinum, LK_EXCLUSIVE, &vp, FFSV_FORCEINSMQ)) != 0) {
3595
 
                softdep_error("handle_workitem_remove: vget", error);
3596
 
                return;
3597
 
        }
 
9479
        if (dirrem->dm_state & ONWORKLIST)
 
9480
                panic("handle_workitem_remove: dirrem %p still on worklist",
 
9481
                    dirrem);
 
9482
        oldinum = dirrem->dm_oldinum;
 
9483
        mp = dirrem->dm_list.wk_mp;
 
9484
        ump = VFSTOUFS(mp);
 
9485
        flags |= LK_EXCLUSIVE;
 
9486
        if (ffs_vgetf(mp, oldinum, flags, &vp, FFSV_FORCEINSMQ) != 0)
 
9487
                return (EBUSY);
3598
9488
        ip = VTOI(vp);
3599
9489
        ACQUIRE_LOCK(&lk);
3600
 
        if ((inodedep_lookup(dirrem->dm_list.wk_mp,
3601
 
            dirrem->dm_oldinum, 0, &inodedep)) == 0)
 
9490
        if ((inodedep_lookup(mp, oldinum, 0, &inodedep)) == 0)
3602
9491
                panic("handle_workitem_remove: lost inodedep");
 
9492
        if (dirrem->dm_state & ONDEPLIST)
 
9493
                LIST_REMOVE(dirrem, dm_inonext);
 
9494
        KASSERT(LIST_EMPTY(&dirrem->dm_jremrefhd),
 
9495
            ("handle_workitem_remove:  Journal entries not written."));
 
9496
 
 
9497
        /*
 
9498
         * Move all dependencies waiting on the remove to complete
 
9499
         * from the dirrem to the inode inowait list to be completed
 
9500
         * after the inode has been updated and written to disk.  Any
 
9501
         * marked MKDIR_PARENT are saved to be completed when the .. ref
 
9502
         * is removed.
 
9503
         */
 
9504
        LIST_INIT(&dotdotwk);
 
9505
        while ((wk = LIST_FIRST(&dirrem->dm_jwork)) != NULL) {
 
9506
                WORKLIST_REMOVE(wk);
 
9507
                if (wk->wk_state & MKDIR_PARENT) {
 
9508
                        wk->wk_state &= ~MKDIR_PARENT;
 
9509
                        WORKLIST_INSERT(&dotdotwk, wk);
 
9510
                        continue;
 
9511
                }
 
9512
                WORKLIST_INSERT(&inodedep->id_inowait, wk);
 
9513
        }
 
9514
        LIST_SWAP(&dirrem->dm_jwork, &dotdotwk, worklist, wk_list);
3603
9515
        /*
3604
9516
         * Normal file deletion.
3605
9517
         */
3609
9521
                ip->i_flag |= IN_CHANGE;
3610
9522
                if (ip->i_nlink < ip->i_effnlink)
3611
9523
                        panic("handle_workitem_remove: bad file delta");
 
9524
                if (ip->i_nlink == 0) 
 
9525
                        unlinked_inodedep(mp, inodedep);
3612
9526
                inodedep->id_nlinkdelta = ip->i_nlink - ip->i_effnlink;
3613
 
                num_dirrem -= 1;
 
9527
                KASSERT(LIST_EMPTY(&dirrem->dm_jwork),
 
9528
                    ("handle_workitem_remove: worklist not empty. %s",
 
9529
                    TYPENAME(LIST_FIRST(&dirrem->dm_jwork)->wk_type)));
3614
9530
                WORKITEM_FREE(dirrem, D_DIRREM);
3615
9531
                FREE_LOCK(&lk);
3616
 
                vput(vp);
3617
 
                return;
 
9532
                goto out;
3618
9533
        }
3619
9534
        /*
3620
9535
         * Directory deletion. Decrement reference count for both the
3621
9536
         * just deleted parent directory entry and the reference for ".".
3622
 
         * Next truncate the directory to length zero. When the
3623
 
         * truncation completes, arrange to have the reference count on
3624
 
         * the parent decremented to account for the loss of "..".
 
9537
         * Arrange to have the reference count on the parent decremented
 
9538
         * to account for the loss of "..".
3625
9539
         */
3626
9540
        ip->i_nlink -= 2;
3627
9541
        DIP_SET(ip, i_nlink, ip->i_nlink);
3628
9542
        ip->i_flag |= IN_CHANGE;
3629
9543
        if (ip->i_nlink < ip->i_effnlink)
3630
9544
                panic("handle_workitem_remove: bad dir delta");
 
9545
        if (ip->i_nlink == 0)
 
9546
                unlinked_inodedep(mp, inodedep);
3631
9547
        inodedep->id_nlinkdelta = ip->i_nlink - ip->i_effnlink;
3632
 
        FREE_LOCK(&lk);
3633
 
        if ((error = ffs_truncate(vp, (off_t)0, 0, td->td_ucred, td)) != 0)
3634
 
                softdep_error("handle_workitem_remove: truncate", error);
3635
 
        ACQUIRE_LOCK(&lk);
3636
9548
        /*
3637
9549
         * Rename a directory to a new parent. Since, we are both deleting
3638
9550
         * and creating a new directory entry, the link count on the new
3639
9551
         * directory should not change. Thus we skip the followup dirrem.
3640
9552
         */
3641
9553
        if (dirrem->dm_state & DIRCHG) {
3642
 
                num_dirrem -= 1;
 
9554
                KASSERT(LIST_EMPTY(&dirrem->dm_jwork),
 
9555
                    ("handle_workitem_remove: DIRCHG and worklist not empty."));
3643
9556
                WORKITEM_FREE(dirrem, D_DIRREM);
3644
9557
                FREE_LOCK(&lk);
3645
 
                vput(vp);
3646
 
                return;
 
9558
                goto out;
3647
9559
        }
3648
 
        /*
3649
 
         * If the inodedep does not exist, then the zero'ed inode has
3650
 
         * been written to disk. If the allocated inode has never been
3651
 
         * written to disk, then the on-disk inode is zero'ed. In either
3652
 
         * case we can remove the file immediately.
3653
 
         */
3654
 
        dirrem->dm_state = 0;
3655
 
        oldinum = dirrem->dm_oldinum;
 
9560
        dirrem->dm_state = ONDEPLIST;
3656
9561
        dirrem->dm_oldinum = dirrem->dm_dirinum;
3657
 
        if (inodedep_lookup(dirrem->dm_list.wk_mp, oldinum,
3658
 
            0, &inodedep) == 0 || check_inode_unwritten(inodedep)) {
3659
 
                if (xp != NULL)
3660
 
                        add_to_worklist(&dirrem->dm_list);
 
9562
        /*
 
9563
         * Place the dirrem on the parent's diremhd list.
 
9564
         */
 
9565
        if (inodedep_lookup(mp, dirrem->dm_oldinum, 0, &inodedep) == 0)
 
9566
                panic("handle_workitem_remove: lost dir inodedep");
 
9567
        LIST_INSERT_HEAD(&inodedep->id_dirremhd, dirrem, dm_inonext);
 
9568
        /*
 
9569
         * If the allocated inode has never been written to disk, then
 
9570
         * the on-disk inode is zero'ed and we can remove the file
 
9571
         * immediately.  When journaling if the inode has been marked
 
9572
         * unlinked and not DEPCOMPLETE we know it can never be written.
 
9573
         */
 
9574
        inodedep_lookup(mp, oldinum, 0, &inodedep);
 
9575
        if (inodedep == NULL ||
 
9576
            (inodedep->id_state & (DEPCOMPLETE | UNLINKED)) == UNLINKED ||
 
9577
            check_inode_unwritten(inodedep)) {
3661
9578
                FREE_LOCK(&lk);
3662
9579
                vput(vp);
3663
 
                if (xp == NULL)
3664
 
                        handle_workitem_remove(dirrem, NULL);
3665
 
                return;
 
9580
                return handle_workitem_remove(dirrem, flags);
3666
9581
        }
3667
9582
        WORKLIST_INSERT(&inodedep->id_inowait, &dirrem->dm_list);
3668
9583
        FREE_LOCK(&lk);
3669
9584
        ip->i_flag |= IN_CHANGE;
 
9585
out:
3670
9586
        ffs_update(vp, 0);
3671
9587
        vput(vp);
 
9588
        return (0);
3672
9589
}
3673
9590
 
3674
9591
/*
3689
9606
handle_workitem_freefile(freefile)
3690
9607
        struct freefile *freefile;
3691
9608
{
 
9609
        struct workhead wkhd;
3692
9610
        struct fs *fs;
3693
9611
        struct inodedep *idp;
3694
9612
        struct ufsmount *ump;
3701
9619
        error = inodedep_lookup(UFSTOVFS(ump), freefile->fx_oldinum, 0, &idp);
3702
9620
        FREE_LOCK(&lk);
3703
9621
        if (error)
3704
 
                panic("handle_workitem_freefile: inodedep survived");
 
9622
                panic("handle_workitem_freefile: inodedep %p survived", idp);
3705
9623
#endif
3706
9624
        UFS_LOCK(ump);
3707
9625
        fs->fs_pendinginodes -= 1;
3708
9626
        UFS_UNLOCK(ump);
 
9627
        LIST_INIT(&wkhd);
 
9628
        LIST_SWAP(&freefile->fx_jwork, &wkhd, worklist, wk_list);
3709
9629
        if ((error = ffs_freefile(ump, fs, freefile->fx_devvp,
3710
 
            freefile->fx_oldinum, freefile->fx_mode)) != 0)
 
9630
            freefile->fx_oldinum, freefile->fx_mode, &wkhd)) != 0)
3711
9631
                softdep_error("handle_workitem_freefile", error);
3712
9632
        ACQUIRE_LOCK(&lk);
3713
9633
        WORKITEM_FREE(freefile, D_FREEFILE);
3757
9677
{
3758
9678
        struct worklist *wk;
3759
9679
        struct worklist marker;
3760
 
        struct indirdep *indirdep;
3761
9680
        struct inodedep *inodedep;
 
9681
        struct freeblks *freeblks;
 
9682
        struct jblkdep *jblkdep;
 
9683
        struct newblk *newblk;
3762
9684
 
3763
9685
        /*
3764
9686
         * We only care about write operations. There should never
3767
9689
        if (bp->b_iocmd != BIO_WRITE)
3768
9690
                panic("softdep_disk_io_initiation: not write");
3769
9691
 
 
9692
        if (bp->b_vflags & BV_BKGRDINPROG)
 
9693
                panic("softdep_disk_io_initiation: Writing buffer with "
 
9694
                    "background write in progress: %p", bp);
 
9695
 
3770
9696
        marker.wk_type = D_LAST + 1;    /* Not a normal workitem */
3771
9697
        PHOLD(curproc);                 /* Don't swap out kernel stack */
3772
9698
 
3792
9718
                        continue;
3793
9719
 
3794
9720
                case D_INDIRDEP:
3795
 
                        indirdep = WK_INDIRDEP(wk);
3796
 
                        if (indirdep->ir_state & GOINGAWAY)
3797
 
                                panic("disk_io_initiation: indirdep gone");
3798
 
                        /*
3799
 
                         * If there are no remaining dependencies, this
3800
 
                         * will be writing the real pointers, so the
3801
 
                         * dependency can be freed.
3802
 
                         */
3803
 
                        if (LIST_EMPTY(&indirdep->ir_deplisthd)) {
3804
 
                                struct buf *bp;
3805
 
 
3806
 
                                bp = indirdep->ir_savebp;
3807
 
                                bp->b_flags |= B_INVAL | B_NOCACHE;
3808
 
                                /* inline expand WORKLIST_REMOVE(wk); */
3809
 
                                wk->wk_state &= ~ONWORKLIST;
3810
 
                                LIST_REMOVE(wk, wk_list);
3811
 
                                WORKITEM_FREE(indirdep, D_INDIRDEP);
3812
 
                                FREE_LOCK(&lk);
3813
 
                                brelse(bp);
3814
 
                                ACQUIRE_LOCK(&lk);
3815
 
                                continue;
3816
 
                        }
3817
 
                        /*
3818
 
                         * Replace up-to-date version with safe version.
3819
 
                         */
3820
 
                        FREE_LOCK(&lk);
3821
 
                        indirdep->ir_saveddata = malloc(bp->b_bcount,
3822
 
                            M_INDIRDEP, M_SOFTDEP_FLAGS);
3823
 
                        ACQUIRE_LOCK(&lk);
3824
 
                        indirdep->ir_state &= ~ATTACHED;
3825
 
                        indirdep->ir_state |= UNDONE;
3826
 
                        bcopy(bp->b_data, indirdep->ir_saveddata, bp->b_bcount);
3827
 
                        bcopy(indirdep->ir_savebp->b_data, bp->b_data,
3828
 
                            bp->b_bcount);
 
9721
                        initiate_write_indirdep(WK_INDIRDEP(wk), bp);
3829
9722
                        continue;
3830
9723
 
3831
 
                case D_MKDIR:
3832
9724
                case D_BMSAFEMAP:
 
9725
                        initiate_write_bmsafemap(WK_BMSAFEMAP(wk), bp);
 
9726
                        continue;
 
9727
 
 
9728
                case D_JSEG:
 
9729
                        WK_JSEG(wk)->js_buf = NULL;
 
9730
                        continue;
 
9731
 
 
9732
                case D_FREEBLKS:
 
9733
                        freeblks = WK_FREEBLKS(wk);
 
9734
                        jblkdep = LIST_FIRST(&freeblks->fb_jblkdephd);
 
9735
                        /*
 
9736
                         * We have to wait for the freeblks to be journaled
 
9737
                         * before we can write an inodeblock with updated
 
9738
                         * pointers.  Be careful to arrange the marker so
 
9739
                         * we revisit the freeblks if it's not removed by
 
9740
                         * the first jwait().
 
9741
                         */
 
9742
                        if (jblkdep != NULL) {
 
9743
                                LIST_REMOVE(&marker, wk_list);
 
9744
                                LIST_INSERT_BEFORE(wk, &marker, wk_list);
 
9745
                                jwait(&jblkdep->jb_list, MNT_WAIT);
 
9746
                        }
 
9747
                        continue;
3833
9748
                case D_ALLOCDIRECT:
3834
9749
                case D_ALLOCINDIR:
 
9750
                        /*
 
9751
                         * We have to wait for the jnewblk to be journaled
 
9752
                         * before we can write to a block if the contents
 
9753
                         * may be confused with an earlier file's indirect
 
9754
                         * at recovery time.  Handle the marker as described
 
9755
                         * above.
 
9756
                         */
 
9757
                        newblk = WK_NEWBLK(wk);
 
9758
                        if (newblk->nb_jnewblk != NULL &&
 
9759
                            indirblk_lookup(newblk->nb_list.wk_mp,
 
9760
                            newblk->nb_newblkno)) {
 
9761
                                LIST_REMOVE(&marker, wk_list);
 
9762
                                LIST_INSERT_BEFORE(wk, &marker, wk_list);
 
9763
                                jwait(&newblk->nb_jnewblk->jn_list, MNT_WAIT);
 
9764
                        }
 
9765
                        continue;
 
9766
 
 
9767
                case D_SBDEP:
 
9768
                        initiate_write_sbdep(WK_SBDEP(wk));
 
9769
                        continue;
 
9770
 
 
9771
                case D_MKDIR:
 
9772
                case D_FREEWORK:
 
9773
                case D_FREEDEP:
 
9774
                case D_JSEGDEP:
3835
9775
                        continue;
3836
9776
 
3837
9777
                default:
3855
9795
        struct pagedep *pagedep;
3856
9796
        struct buf *bp;
3857
9797
{
 
9798
        struct jremref *jremref;
 
9799
        struct jmvref *jmvref;
 
9800
        struct dirrem *dirrem;
3858
9801
        struct diradd *dap;
3859
9802
        struct direct *ep;
3860
9803
        int i;
3869
9812
                return;
3870
9813
        }
3871
9814
        pagedep->pd_state |= IOSTARTED;
 
9815
        /*
 
9816
         * Wait for all journal remove dependencies to hit the disk.
 
9817
         * We can not allow any potentially conflicting directory adds
 
9818
         * to be visible before removes and rollback is too difficult.
 
9819
         * lk may be dropped and re-acquired, however we hold the buf
 
9820
         * locked so the dependency can not go away.
 
9821
         */
 
9822
        LIST_FOREACH(dirrem, &pagedep->pd_dirremhd, dm_next)
 
9823
                while ((jremref = LIST_FIRST(&dirrem->dm_jremrefhd)) != NULL)
 
9824
                        jwait(&jremref->jr_list, MNT_WAIT);
 
9825
        while ((jmvref = LIST_FIRST(&pagedep->pd_jmvrefhd)) != NULL)
 
9826
                jwait(&jmvref->jm_list, MNT_WAIT);
3872
9827
        for (i = 0; i < DAHASHSZ; i++) {
3873
9828
                LIST_FOREACH(dap, &pagedep->pd_diraddhd[i], da_pdlist) {
3874
9829
                        ep = (struct direct *)
3905
9860
        struct allocdirect *adp, *lastadp;
3906
9861
        struct ufs1_dinode *dp;
3907
9862
        struct ufs1_dinode *sip;
 
9863
        struct inoref *inoref;
3908
9864
        struct fs *fs;
3909
9865
        ufs_lbn_t i;
3910
9866
#ifdef INVARIANTS
3918
9874
        fs = inodedep->id_fs;
3919
9875
        dp = (struct ufs1_dinode *)bp->b_data +
3920
9876
            ino_to_fsbo(fs, inodedep->id_ino);
 
9877
 
 
9878
        /*
 
9879
         * If we're on the unlinked list but have not yet written our
 
9880
         * next pointer initialize it here.
 
9881
         */
 
9882
        if ((inodedep->id_state & (UNLINKED | UNLINKNEXT)) == UNLINKED) {
 
9883
                struct inodedep *inon;
 
9884
 
 
9885
                inon = TAILQ_NEXT(inodedep, id_unlinked);
 
9886
                dp->di_freelink = inon ? inon->id_ino : 0;
 
9887
        }
3921
9888
        /*
3922
9889
         * If the bitmap is not yet written, then the allocated
3923
9890
         * inode cannot be written to disk.
3933
9900
                *inodedep->id_savedino1 = *dp;
3934
9901
                bzero((caddr_t)dp, sizeof(struct ufs1_dinode));
3935
9902
                dp->di_gen = inodedep->id_savedino1->di_gen;
 
9903
                dp->di_freelink = inodedep->id_savedino1->di_freelink;
3936
9904
                return;
3937
9905
        }
3938
9906
        /*
3940
9908
         */
3941
9909
        inodedep->id_savedsize = dp->di_size;
3942
9910
        inodedep->id_savedextsize = 0;
3943
 
        if (TAILQ_EMPTY(&inodedep->id_inoupdt))
 
9911
        inodedep->id_savednlink = dp->di_nlink;
 
9912
        if (TAILQ_EMPTY(&inodedep->id_inoupdt) &&
 
9913
            TAILQ_EMPTY(&inodedep->id_inoreflst))
3944
9914
                return;
3945
9915
        /*
 
9916
         * Revert the link count to that of the first unwritten journal entry.
 
9917
         */
 
9918
        inoref = TAILQ_FIRST(&inodedep->id_inoreflst);
 
9919
        if (inoref)
 
9920
                dp->di_nlink = inoref->if_nlink;
 
9921
        /*
3946
9922
         * Set the dependencies to busy.
3947
9923
         */
3948
9924
        for (deplist = 0, adp = TAILQ_FIRST(&inodedep->id_inoupdt); adp;
3949
9925
             adp = TAILQ_NEXT(adp, ad_next)) {
3950
9926
#ifdef INVARIANTS
3951
 
                if (deplist != 0 && prevlbn >= adp->ad_lbn)
 
9927
                if (deplist != 0 && prevlbn >= adp->ad_offset)
3952
9928
                        panic("softdep_write_inodeblock: lbn order");
3953
 
                prevlbn = adp->ad_lbn;
3954
 
                if (adp->ad_lbn < NDADDR &&
3955
 
                    dp->di_db[adp->ad_lbn] != adp->ad_newblkno)
 
9929
                prevlbn = adp->ad_offset;
 
9930
                if (adp->ad_offset < NDADDR &&
 
9931
                    dp->di_db[adp->ad_offset] != adp->ad_newblkno)
3956
9932
                        panic("%s: direct pointer #%jd mismatch %d != %jd",
3957
9933
                            "softdep_write_inodeblock",
3958
 
                            (intmax_t)adp->ad_lbn,
3959
 
                            dp->di_db[adp->ad_lbn],
 
9934
                            (intmax_t)adp->ad_offset,
 
9935
                            dp->di_db[adp->ad_offset],
3960
9936
                            (intmax_t)adp->ad_newblkno);
3961
 
                if (adp->ad_lbn >= NDADDR &&
3962
 
                    dp->di_ib[adp->ad_lbn - NDADDR] != adp->ad_newblkno)
 
9937
                if (adp->ad_offset >= NDADDR &&
 
9938
                    dp->di_ib[adp->ad_offset - NDADDR] != adp->ad_newblkno)
3963
9939
                        panic("%s: indirect pointer #%jd mismatch %d != %jd",
3964
9940
                            "softdep_write_inodeblock",
3965
 
                            (intmax_t)adp->ad_lbn - NDADDR,
3966
 
                            dp->di_ib[adp->ad_lbn - NDADDR],
 
9941
                            (intmax_t)adp->ad_offset - NDADDR,
 
9942
                            dp->di_ib[adp->ad_offset - NDADDR],
3967
9943
                            (intmax_t)adp->ad_newblkno);
3968
 
                deplist |= 1 << adp->ad_lbn;
 
9944
                deplist |= 1 << adp->ad_offset;
3969
9945
                if ((adp->ad_state & ATTACHED) == 0)
3970
9946
                        panic("softdep_write_inodeblock: Unknown state 0x%x",
3971
9947
                            adp->ad_state);
3981
9957
         */
3982
9958
        for (lastadp = NULL, adp = TAILQ_FIRST(&inodedep->id_inoupdt); adp;
3983
9959
             lastadp = adp, adp = TAILQ_NEXT(adp, ad_next)) {
3984
 
                if (adp->ad_lbn >= NDADDR)
 
9960
                if (adp->ad_offset >= NDADDR)
3985
9961
                        break;
3986
 
                dp->di_db[adp->ad_lbn] = adp->ad_oldblkno;
 
9962
                dp->di_db[adp->ad_offset] = adp->ad_oldblkno;
3987
9963
                /* keep going until hitting a rollback to a frag */
3988
9964
                if (adp->ad_oldsize == 0 || adp->ad_oldsize == fs->fs_bsize)
3989
9965
                        continue;
3990
 
                dp->di_size = fs->fs_bsize * adp->ad_lbn + adp->ad_oldsize;
3991
 
                for (i = adp->ad_lbn + 1; i < NDADDR; i++) {
 
9966
                dp->di_size = fs->fs_bsize * adp->ad_offset + adp->ad_oldsize;
 
9967
                for (i = adp->ad_offset + 1; i < NDADDR; i++) {
3992
9968
#ifdef INVARIANTS
3993
9969
                        if (dp->di_db[i] != 0 && (deplist & (1 << i)) == 0)
3994
9970
                                panic("softdep_write_inodeblock: lost dep1");
4012
9988
         * we already checked for fragments in the loop above.
4013
9989
         */
4014
9990
        if (lastadp != NULL &&
4015
 
            dp->di_size <= (lastadp->ad_lbn + 1) * fs->fs_bsize) {
4016
 
                for (i = lastadp->ad_lbn; i >= 0; i--)
 
9991
            dp->di_size <= (lastadp->ad_offset + 1) * fs->fs_bsize) {
 
9992
                for (i = lastadp->ad_offset; i >= 0; i--)
4017
9993
                        if (dp->di_db[i] != 0)
4018
9994
                                break;
4019
9995
                dp->di_size = (i + 1) * fs->fs_bsize;
4030
10006
         * postpone fsck, we are stuck with this argument.
4031
10007
         */
4032
10008
        for (; adp; adp = TAILQ_NEXT(adp, ad_next))
4033
 
                dp->di_ib[adp->ad_lbn - NDADDR] = 0;
 
10009
                dp->di_ib[adp->ad_offset - NDADDR] = 0;
4034
10010
}
4035
10011
                
4036
10012
/*
4051
10027
        struct allocdirect *adp, *lastadp;
4052
10028
        struct ufs2_dinode *dp;
4053
10029
        struct ufs2_dinode *sip;
 
10030
        struct inoref *inoref;
4054
10031
        struct fs *fs;
4055
10032
        ufs_lbn_t i;
4056
10033
#ifdef INVARIANTS
4064
10041
        fs = inodedep->id_fs;
4065
10042
        dp = (struct ufs2_dinode *)bp->b_data +
4066
10043
            ino_to_fsbo(fs, inodedep->id_ino);
 
10044
 
 
10045
        /*
 
10046
         * If we're on the unlinked list but have not yet written our
 
10047
         * next pointer initialize it here.
 
10048
         */
 
10049
        if ((inodedep->id_state & (UNLINKED | UNLINKNEXT)) == UNLINKED) {
 
10050
                struct inodedep *inon;
 
10051
 
 
10052
                inon = TAILQ_NEXT(inodedep, id_unlinked);
 
10053
                dp->di_freelink = inon ? inon->id_ino : 0;
 
10054
        }
4067
10055
        /*
4068
10056
         * If the bitmap is not yet written, then the allocated
4069
10057
         * inode cannot be written to disk.
4079
10067
                *inodedep->id_savedino2 = *dp;
4080
10068
                bzero((caddr_t)dp, sizeof(struct ufs2_dinode));
4081
10069
                dp->di_gen = inodedep->id_savedino2->di_gen;
 
10070
                dp->di_freelink = inodedep->id_savedino2->di_freelink;
4082
10071
                return;
4083
10072
        }
4084
10073
        /*
4086
10075
         */
4087
10076
        inodedep->id_savedsize = dp->di_size;
4088
10077
        inodedep->id_savedextsize = dp->di_extsize;
 
10078
        inodedep->id_savednlink = dp->di_nlink;
4089
10079
        if (TAILQ_EMPTY(&inodedep->id_inoupdt) &&
4090
 
            TAILQ_EMPTY(&inodedep->id_extupdt))
 
10080
            TAILQ_EMPTY(&inodedep->id_extupdt) &&
 
10081
            TAILQ_EMPTY(&inodedep->id_inoreflst))
4091
10082
                return;
4092
10083
        /*
 
10084
         * Revert the link count to that of the first unwritten journal entry.
 
10085
         */
 
10086
        inoref = TAILQ_FIRST(&inodedep->id_inoreflst);
 
10087
        if (inoref)
 
10088
                dp->di_nlink = inoref->if_nlink;
 
10089
 
 
10090
        /*
4093
10091
         * Set the ext data dependencies to busy.
4094
10092
         */
4095
10093
        for (deplist = 0, adp = TAILQ_FIRST(&inodedep->id_extupdt); adp;
4096
10094
             adp = TAILQ_NEXT(adp, ad_next)) {
4097
10095
#ifdef INVARIANTS
4098
 
                if (deplist != 0 && prevlbn >= adp->ad_lbn)
 
10096
                if (deplist != 0 && prevlbn >= adp->ad_offset)
4099
10097
                        panic("softdep_write_inodeblock: lbn order");
4100
 
                prevlbn = adp->ad_lbn;
4101
 
                if (dp->di_extb[adp->ad_lbn] != adp->ad_newblkno)
 
10098
                prevlbn = adp->ad_offset;
 
10099
                if (dp->di_extb[adp->ad_offset] != adp->ad_newblkno)
4102
10100
                        panic("%s: direct pointer #%jd mismatch %jd != %jd",
4103
10101
                            "softdep_write_inodeblock",
4104
 
                            (intmax_t)adp->ad_lbn,
4105
 
                            (intmax_t)dp->di_extb[adp->ad_lbn],
 
10102
                            (intmax_t)adp->ad_offset,
 
10103
                            (intmax_t)dp->di_extb[adp->ad_offset],
4106
10104
                            (intmax_t)adp->ad_newblkno);
4107
 
                deplist |= 1 << adp->ad_lbn;
 
10105
                deplist |= 1 << adp->ad_offset;
4108
10106
                if ((adp->ad_state & ATTACHED) == 0)
4109
10107
                        panic("softdep_write_inodeblock: Unknown state 0x%x",
4110
10108
                            adp->ad_state);
4120
10118
         */
4121
10119
        for (lastadp = NULL, adp = TAILQ_FIRST(&inodedep->id_extupdt); adp;
4122
10120
             lastadp = adp, adp = TAILQ_NEXT(adp, ad_next)) {
4123
 
                dp->di_extb[adp->ad_lbn] = adp->ad_oldblkno;
 
10121
                dp->di_extb[adp->ad_offset] = adp->ad_oldblkno;
4124
10122
                /* keep going until hitting a rollback to a frag */
4125
10123
                if (adp->ad_oldsize == 0 || adp->ad_oldsize == fs->fs_bsize)
4126
10124
                        continue;
4127
 
                dp->di_extsize = fs->fs_bsize * adp->ad_lbn + adp->ad_oldsize;
4128
 
                for (i = adp->ad_lbn + 1; i < NXADDR; i++) {
 
10125
                dp->di_extsize = fs->fs_bsize * adp->ad_offset + adp->ad_oldsize;
 
10126
                for (i = adp->ad_offset + 1; i < NXADDR; i++) {
4129
10127
#ifdef INVARIANTS
4130
10128
                        if (dp->di_extb[i] != 0 && (deplist & (1 << i)) == 0)
4131
10129
                                panic("softdep_write_inodeblock: lost dep1");
4142
10140
         * we already checked for fragments in the loop above.
4143
10141
         */
4144
10142
        if (lastadp != NULL &&
4145
 
            dp->di_extsize <= (lastadp->ad_lbn + 1) * fs->fs_bsize) {
4146
 
                for (i = lastadp->ad_lbn; i >= 0; i--)
 
10143
            dp->di_extsize <= (lastadp->ad_offset + 1) * fs->fs_bsize) {
 
10144
                for (i = lastadp->ad_offset; i >= 0; i--)
4147
10145
                        if (dp->di_extb[i] != 0)
4148
10146
                                break;
4149
10147
                dp->di_extsize = (i + 1) * fs->fs_bsize;
4154
10152
        for (deplist = 0, adp = TAILQ_FIRST(&inodedep->id_inoupdt); adp;
4155
10153
             adp = TAILQ_NEXT(adp, ad_next)) {
4156
10154
#ifdef INVARIANTS
4157
 
                if (deplist != 0 && prevlbn >= adp->ad_lbn)
 
10155
                if (deplist != 0 && prevlbn >= adp->ad_offset)
4158
10156
                        panic("softdep_write_inodeblock: lbn order");
4159
 
                prevlbn = adp->ad_lbn;
4160
 
                if (adp->ad_lbn < NDADDR &&
4161
 
                    dp->di_db[adp->ad_lbn] != adp->ad_newblkno)
 
10157
                if ((adp->ad_state & ATTACHED) == 0)
 
10158
                        panic("inodedep %p and adp %p not attached", inodedep, adp);
 
10159
                prevlbn = adp->ad_offset;
 
10160
                if (adp->ad_offset < NDADDR &&
 
10161
                    dp->di_db[adp->ad_offset] != adp->ad_newblkno)
4162
10162
                        panic("%s: direct pointer #%jd mismatch %jd != %jd",
4163
10163
                            "softdep_write_inodeblock",
4164
 
                            (intmax_t)adp->ad_lbn,
4165
 
                            (intmax_t)dp->di_db[adp->ad_lbn],
 
10164
                            (intmax_t)adp->ad_offset,
 
10165
                            (intmax_t)dp->di_db[adp->ad_offset],
4166
10166
                            (intmax_t)adp->ad_newblkno);
4167
 
                if (adp->ad_lbn >= NDADDR &&
4168
 
                    dp->di_ib[adp->ad_lbn - NDADDR] != adp->ad_newblkno)
 
10167
                if (adp->ad_offset >= NDADDR &&
 
10168
                    dp->di_ib[adp->ad_offset - NDADDR] != adp->ad_newblkno)
4169
10169
                        panic("%s indirect pointer #%jd mismatch %jd != %jd",
4170
10170
                            "softdep_write_inodeblock:",
4171
 
                            (intmax_t)adp->ad_lbn - NDADDR,
4172
 
                            (intmax_t)dp->di_ib[adp->ad_lbn - NDADDR],
 
10171
                            (intmax_t)adp->ad_offset - NDADDR,
 
10172
                            (intmax_t)dp->di_ib[adp->ad_offset - NDADDR],
4173
10173
                            (intmax_t)adp->ad_newblkno);
4174
 
                deplist |= 1 << adp->ad_lbn;
 
10174
                deplist |= 1 << adp->ad_offset;
4175
10175
                if ((adp->ad_state & ATTACHED) == 0)
4176
10176
                        panic("softdep_write_inodeblock: Unknown state 0x%x",
4177
10177
                            adp->ad_state);
4187
10187
         */
4188
10188
        for (lastadp = NULL, adp = TAILQ_FIRST(&inodedep->id_inoupdt); adp;
4189
10189
             lastadp = adp, adp = TAILQ_NEXT(adp, ad_next)) {
4190
 
                if (adp->ad_lbn >= NDADDR)
 
10190
                if (adp->ad_offset >= NDADDR)
4191
10191
                        break;
4192
 
                dp->di_db[adp->ad_lbn] = adp->ad_oldblkno;
 
10192
                dp->di_db[adp->ad_offset] = adp->ad_oldblkno;
4193
10193
                /* keep going until hitting a rollback to a frag */
4194
10194
                if (adp->ad_oldsize == 0 || adp->ad_oldsize == fs->fs_bsize)
4195
10195
                        continue;
4196
 
                dp->di_size = fs->fs_bsize * adp->ad_lbn + adp->ad_oldsize;
4197
 
                for (i = adp->ad_lbn + 1; i < NDADDR; i++) {
 
10196
                dp->di_size = fs->fs_bsize * adp->ad_offset + adp->ad_oldsize;
 
10197
                for (i = adp->ad_offset + 1; i < NDADDR; i++) {
4198
10198
#ifdef INVARIANTS
4199
10199
                        if (dp->di_db[i] != 0 && (deplist & (1 << i)) == 0)
4200
10200
                                panic("softdep_write_inodeblock: lost dep2");
4218
10218
         * we already checked for fragments in the loop above.
4219
10219
         */
4220
10220
        if (lastadp != NULL &&
4221
 
            dp->di_size <= (lastadp->ad_lbn + 1) * fs->fs_bsize) {
4222
 
                for (i = lastadp->ad_lbn; i >= 0; i--)
 
10221
            dp->di_size <= (lastadp->ad_offset + 1) * fs->fs_bsize) {
 
10222
                for (i = lastadp->ad_offset; i >= 0; i--)
4223
10223
                        if (dp->di_db[i] != 0)
4224
10224
                                break;
4225
10225
                dp->di_size = (i + 1) * fs->fs_bsize;
4236
10236
         * postpone fsck, we are stuck with this argument.
4237
10237
         */
4238
10238
        for (; adp; adp = TAILQ_NEXT(adp, ad_next))
4239
 
                dp->di_ib[adp->ad_lbn - NDADDR] = 0;
 
10239
                dp->di_ib[adp->ad_offset - NDADDR] = 0;
 
10240
}
 
10241
 
 
10242
/*
 
10243
 * Cancel an indirdep as a result of truncation.  Release all of the
 
10244
 * children allocindirs and place their journal work on the appropriate
 
10245
 * list.
 
10246
 */
 
10247
static void
 
10248
cancel_indirdep(indirdep, bp, freeblks)
 
10249
        struct indirdep *indirdep;
 
10250
        struct buf *bp;
 
10251
        struct freeblks *freeblks;
 
10252
{
 
10253
        struct allocindir *aip;
 
10254
 
 
10255
        /*
 
10256
         * None of the indirect pointers will ever be visible,
 
10257
         * so they can simply be tossed. GOINGAWAY ensures
 
10258
         * that allocated pointers will be saved in the buffer
 
10259
         * cache until they are freed. Note that they will
 
10260
         * only be able to be found by their physical address
 
10261
         * since the inode mapping the logical address will
 
10262
         * be gone. The save buffer used for the safe copy
 
10263
         * was allocated in setup_allocindir_phase2 using
 
10264
         * the physical address so it could be used for this
 
10265
         * purpose. Hence we swap the safe copy with the real
 
10266
         * copy, allowing the safe copy to be freed and holding
 
10267
         * on to the real copy for later use in indir_trunc.
 
10268
         */
 
10269
        if (indirdep->ir_state & GOINGAWAY)
 
10270
                panic("cancel_indirdep: already gone");
 
10271
        if ((indirdep->ir_state & DEPCOMPLETE) == 0) {
 
10272
                indirdep->ir_state |= DEPCOMPLETE;
 
10273
                LIST_REMOVE(indirdep, ir_next);
 
10274
        }
 
10275
        indirdep->ir_state |= GOINGAWAY;
 
10276
        VFSTOUFS(indirdep->ir_list.wk_mp)->um_numindirdeps += 1;
 
10277
        /*
 
10278
         * Pass in bp for blocks still have journal writes
 
10279
         * pending so we can cancel them on their own.
 
10280
         */
 
10281
        while ((aip = LIST_FIRST(&indirdep->ir_deplisthd)) != 0)
 
10282
                cancel_allocindir(aip, bp, freeblks, 0);
 
10283
        while ((aip = LIST_FIRST(&indirdep->ir_donehd)) != 0)
 
10284
                cancel_allocindir(aip, NULL, freeblks, 0);
 
10285
        while ((aip = LIST_FIRST(&indirdep->ir_writehd)) != 0)
 
10286
                cancel_allocindir(aip, NULL, freeblks, 0);
 
10287
        while ((aip = LIST_FIRST(&indirdep->ir_completehd)) != 0)
 
10288
                cancel_allocindir(aip, NULL, freeblks, 0);
 
10289
        /*
 
10290
         * If there are pending partial truncations we need to keep the
 
10291
         * old block copy around until they complete.  This is because
 
10292
         * the current b_data is not a perfect superset of the available
 
10293
         * blocks.
 
10294
         */
 
10295
        if (TAILQ_EMPTY(&indirdep->ir_trunc))
 
10296
                bcopy(bp->b_data, indirdep->ir_savebp->b_data, bp->b_bcount);
 
10297
        else
 
10298
                bcopy(bp->b_data, indirdep->ir_saveddata, bp->b_bcount);
 
10299
        WORKLIST_REMOVE(&indirdep->ir_list);
 
10300
        WORKLIST_INSERT(&indirdep->ir_savebp->b_dep, &indirdep->ir_list);
 
10301
        indirdep->ir_bp = NULL;
 
10302
        indirdep->ir_freeblks = freeblks;
 
10303
}
 
10304
 
 
10305
/*
 
10306
 * Free an indirdep once it no longer has new pointers to track.
 
10307
 */
 
10308
static void
 
10309
free_indirdep(indirdep)
 
10310
        struct indirdep *indirdep;
 
10311
{
 
10312
 
 
10313
        KASSERT(TAILQ_EMPTY(&indirdep->ir_trunc),
 
10314
            ("free_indirdep: Indir trunc list not empty."));
 
10315
        KASSERT(LIST_EMPTY(&indirdep->ir_completehd),
 
10316
            ("free_indirdep: Complete head not empty."));
 
10317
        KASSERT(LIST_EMPTY(&indirdep->ir_writehd),
 
10318
            ("free_indirdep: write head not empty."));
 
10319
        KASSERT(LIST_EMPTY(&indirdep->ir_donehd),
 
10320
            ("free_indirdep: done head not empty."));
 
10321
        KASSERT(LIST_EMPTY(&indirdep->ir_deplisthd),
 
10322
            ("free_indirdep: deplist head not empty."));
 
10323
        KASSERT((indirdep->ir_state & DEPCOMPLETE),
 
10324
            ("free_indirdep: %p still on newblk list.", indirdep));
 
10325
        KASSERT(indirdep->ir_saveddata == NULL,
 
10326
            ("free_indirdep: %p still has saved data.", indirdep));
 
10327
        if (indirdep->ir_state & ONWORKLIST)
 
10328
                WORKLIST_REMOVE(&indirdep->ir_list);
 
10329
        WORKITEM_FREE(indirdep, D_INDIRDEP);
 
10330
}
 
10331
 
 
10332
/*
 
10333
 * Called before a write to an indirdep.  This routine is responsible for
 
10334
 * rolling back pointers to a safe state which includes only those
 
10335
 * allocindirs which have been completed.
 
10336
 */
 
10337
static void
 
10338
initiate_write_indirdep(indirdep, bp)
 
10339
        struct indirdep *indirdep;
 
10340
        struct buf *bp;
 
10341
{
 
10342
 
 
10343
        indirdep->ir_state |= IOSTARTED;
 
10344
        if (indirdep->ir_state & GOINGAWAY)
 
10345
                panic("disk_io_initiation: indirdep gone");
 
10346
        /*
 
10347
         * If there are no remaining dependencies, this will be writing
 
10348
         * the real pointers.
 
10349
         */
 
10350
        if (LIST_EMPTY(&indirdep->ir_deplisthd) &&
 
10351
            TAILQ_EMPTY(&indirdep->ir_trunc))
 
10352
                return;
 
10353
        /*
 
10354
         * Replace up-to-date version with safe version.
 
10355
         */
 
10356
        if (indirdep->ir_saveddata == NULL) {
 
10357
                FREE_LOCK(&lk);
 
10358
                indirdep->ir_saveddata = malloc(bp->b_bcount, M_INDIRDEP,
 
10359
                    M_SOFTDEP_FLAGS);
 
10360
                ACQUIRE_LOCK(&lk);
 
10361
        }
 
10362
        indirdep->ir_state &= ~ATTACHED;
 
10363
        indirdep->ir_state |= UNDONE;
 
10364
        bcopy(bp->b_data, indirdep->ir_saveddata, bp->b_bcount);
 
10365
        bcopy(indirdep->ir_savebp->b_data, bp->b_data,
 
10366
            bp->b_bcount);
 
10367
}
 
10368
 
 
10369
/*
 
10370
 * Called when an inode has been cleared in a cg bitmap.  This finally
 
10371
 * eliminates any canceled jaddrefs
 
10372
 */
 
10373
void
 
10374
softdep_setup_inofree(mp, bp, ino, wkhd)
 
10375
        struct mount *mp;
 
10376
        struct buf *bp;
 
10377
        ino_t ino;
 
10378
        struct workhead *wkhd;
 
10379
{
 
10380
        struct worklist *wk, *wkn;
 
10381
        struct inodedep *inodedep;
 
10382
        uint8_t *inosused;
 
10383
        struct cg *cgp;
 
10384
        struct fs *fs;
 
10385
 
 
10386
        ACQUIRE_LOCK(&lk);
 
10387
        fs = VFSTOUFS(mp)->um_fs;
 
10388
        cgp = (struct cg *)bp->b_data;
 
10389
        inosused = cg_inosused(cgp);
 
10390
        if (isset(inosused, ino % fs->fs_ipg))
 
10391
                panic("softdep_setup_inofree: inode %d not freed.", ino);
 
10392
        if (inodedep_lookup(mp, ino, 0, &inodedep))
 
10393
                panic("softdep_setup_inofree: ino %d has existing inodedep %p",
 
10394
                    ino, inodedep);
 
10395
        if (wkhd) {
 
10396
                LIST_FOREACH_SAFE(wk, wkhd, wk_list, wkn) {
 
10397
                        if (wk->wk_type != D_JADDREF)
 
10398
                                continue;
 
10399
                        WORKLIST_REMOVE(wk);
 
10400
                        /*
 
10401
                         * We can free immediately even if the jaddref
 
10402
                         * isn't attached in a background write as now
 
10403
                         * the bitmaps are reconciled.
 
10404
                         */
 
10405
                        wk->wk_state |= COMPLETE | ATTACHED;
 
10406
                        free_jaddref(WK_JADDREF(wk));
 
10407
                }
 
10408
                jwork_move(&bp->b_dep, wkhd);
 
10409
        }
 
10410
        FREE_LOCK(&lk);
 
10411
}
 
10412
 
 
10413
 
 
10414
/*
 
10415
 * Called via ffs_blkfree() after a set of frags has been cleared from a cg
 
10416
 * map.  Any dependencies waiting for the write to clear are added to the
 
10417
 * buf's list and any jnewblks that are being canceled are discarded
 
10418
 * immediately.
 
10419
 */
 
10420
void
 
10421
softdep_setup_blkfree(mp, bp, blkno, frags, wkhd)
 
10422
        struct mount *mp;
 
10423
        struct buf *bp;
 
10424
        ufs2_daddr_t blkno;
 
10425
        int frags;
 
10426
        struct workhead *wkhd;
 
10427
{
 
10428
        struct bmsafemap *bmsafemap;
 
10429
        struct jnewblk *jnewblk;
 
10430
        struct worklist *wk;
 
10431
        struct fs *fs;
 
10432
#ifdef SUJ_DEBUG
 
10433
        uint8_t *blksfree;
 
10434
        struct cg *cgp;
 
10435
        ufs2_daddr_t jstart;
 
10436
        ufs2_daddr_t jend;
 
10437
        ufs2_daddr_t end;
 
10438
        long bno;
 
10439
        int i;
 
10440
#endif
 
10441
 
 
10442
        CTR3(KTR_SUJ,
 
10443
            "softdep_setup_blkfree: blkno %jd frags %d wk head %p",
 
10444
            blkno, frags, wkhd);
 
10445
 
 
10446
        ACQUIRE_LOCK(&lk);
 
10447
        /* Lookup the bmsafemap so we track when it is dirty. */
 
10448
        fs = VFSTOUFS(mp)->um_fs;
 
10449
        bmsafemap = bmsafemap_lookup(mp, bp, dtog(fs, blkno), NULL);
 
10450
        /*
 
10451
         * Detach any jnewblks which have been canceled.  They must linger
 
10452
         * until the bitmap is cleared again by ffs_blkfree() to prevent
 
10453
         * an unjournaled allocation from hitting the disk.
 
10454
         */
 
10455
        if (wkhd) {
 
10456
                while ((wk = LIST_FIRST(wkhd)) != NULL) {
 
10457
                        CTR2(KTR_SUJ,
 
10458
                            "softdep_setup_blkfree: blkno %jd wk type %d",
 
10459
                            blkno, wk->wk_type);
 
10460
                        WORKLIST_REMOVE(wk);
 
10461
                        if (wk->wk_type != D_JNEWBLK) {
 
10462
                                WORKLIST_INSERT(&bmsafemap->sm_freehd, wk);
 
10463
                                continue;
 
10464
                        }
 
10465
                        jnewblk = WK_JNEWBLK(wk);
 
10466
                        KASSERT(jnewblk->jn_state & GOINGAWAY,
 
10467
                            ("softdep_setup_blkfree: jnewblk not canceled."));
 
10468
#ifdef SUJ_DEBUG
 
10469
                        /*
 
10470
                         * Assert that this block is free in the bitmap
 
10471
                         * before we discard the jnewblk.
 
10472
                         */
 
10473
                        cgp = (struct cg *)bp->b_data;
 
10474
                        blksfree = cg_blksfree(cgp);
 
10475
                        bno = dtogd(fs, jnewblk->jn_blkno);
 
10476
                        for (i = jnewblk->jn_oldfrags;
 
10477
                            i < jnewblk->jn_frags; i++) {
 
10478
                                if (isset(blksfree, bno + i))
 
10479
                                        continue;
 
10480
                                panic("softdep_setup_blkfree: not free");
 
10481
                        }
 
10482
#endif
 
10483
                        /*
 
10484
                         * Even if it's not attached we can free immediately
 
10485
                         * as the new bitmap is correct.
 
10486
                         */
 
10487
                        wk->wk_state |= COMPLETE | ATTACHED;
 
10488
                        free_jnewblk(jnewblk);
 
10489
                }
 
10490
        }
 
10491
 
 
10492
#ifdef SUJ_DEBUG
 
10493
        /*
 
10494
         * Assert that we are not freeing a block which has an outstanding
 
10495
         * allocation dependency.
 
10496
         */
 
10497
        fs = VFSTOUFS(mp)->um_fs;
 
10498
        bmsafemap = bmsafemap_lookup(mp, bp, dtog(fs, blkno), NULL);
 
10499
        end = blkno + frags;
 
10500
        LIST_FOREACH(jnewblk, &bmsafemap->sm_jnewblkhd, jn_deps) {
 
10501
                /*
 
10502
                 * Don't match against blocks that will be freed when the
 
10503
                 * background write is done.
 
10504
                 */
 
10505
                if ((jnewblk->jn_state & (ATTACHED | COMPLETE | DEPCOMPLETE)) ==
 
10506
                    (COMPLETE | DEPCOMPLETE))
 
10507
                        continue;
 
10508
                jstart = jnewblk->jn_blkno + jnewblk->jn_oldfrags;
 
10509
                jend = jnewblk->jn_blkno + jnewblk->jn_frags;
 
10510
                if ((blkno >= jstart && blkno < jend) ||
 
10511
                    (end > jstart && end <= jend)) {
 
10512
                        printf("state 0x%X %jd - %d %d dep %p\n",
 
10513
                            jnewblk->jn_state, jnewblk->jn_blkno,
 
10514
                            jnewblk->jn_oldfrags, jnewblk->jn_frags,
 
10515
                            jnewblk->jn_dep);
 
10516
                        panic("softdep_setup_blkfree: "
 
10517
                            "%jd-%jd(%d) overlaps with %jd-%jd",
 
10518
                            blkno, end, frags, jstart, jend);
 
10519
                }
 
10520
        }
 
10521
#endif
 
10522
        FREE_LOCK(&lk);
 
10523
}
 
10524
 
 
10525
/*
 
10526
 * Revert a block allocation when the journal record that describes it
 
10527
 * is not yet written.
 
10528
 */
 
10529
int
 
10530
jnewblk_rollback(jnewblk, fs, cgp, blksfree)
 
10531
        struct jnewblk *jnewblk;
 
10532
        struct fs *fs;
 
10533
        struct cg *cgp;
 
10534
        uint8_t *blksfree;
 
10535
{
 
10536
        ufs1_daddr_t fragno;
 
10537
        long cgbno, bbase;
 
10538
        int frags, blk;
 
10539
        int i;
 
10540
 
 
10541
        frags = 0;
 
10542
        cgbno = dtogd(fs, jnewblk->jn_blkno);
 
10543
        /*
 
10544
         * We have to test which frags need to be rolled back.  We may
 
10545
         * be operating on a stale copy when doing background writes.
 
10546
         */
 
10547
        for (i = jnewblk->jn_oldfrags; i < jnewblk->jn_frags; i++)
 
10548
                if (isclr(blksfree, cgbno + i))
 
10549
                        frags++;
 
10550
        if (frags == 0)
 
10551
                return (0);
 
10552
        /*
 
10553
         * This is mostly ffs_blkfree() sans some validation and
 
10554
         * superblock updates.
 
10555
         */
 
10556
        if (frags == fs->fs_frag) {
 
10557
                fragno = fragstoblks(fs, cgbno);
 
10558
                ffs_setblock(fs, blksfree, fragno);
 
10559
                ffs_clusteracct(fs, cgp, fragno, 1);
 
10560
                cgp->cg_cs.cs_nbfree++;
 
10561
        } else {
 
10562
                cgbno += jnewblk->jn_oldfrags;
 
10563
                bbase = cgbno - fragnum(fs, cgbno);
 
10564
                /* Decrement the old frags.  */
 
10565
                blk = blkmap(fs, blksfree, bbase);
 
10566
                ffs_fragacct(fs, blk, cgp->cg_frsum, -1);
 
10567
                /* Deallocate the fragment */
 
10568
                for (i = 0; i < frags; i++)
 
10569
                        setbit(blksfree, cgbno + i);
 
10570
                cgp->cg_cs.cs_nffree += frags;
 
10571
                /* Add back in counts associated with the new frags */
 
10572
                blk = blkmap(fs, blksfree, bbase);
 
10573
                ffs_fragacct(fs, blk, cgp->cg_frsum, 1);
 
10574
                /* If a complete block has been reassembled, account for it. */
 
10575
                fragno = fragstoblks(fs, bbase);
 
10576
                if (ffs_isblock(fs, blksfree, fragno)) {
 
10577
                        cgp->cg_cs.cs_nffree -= fs->fs_frag;
 
10578
                        ffs_clusteracct(fs, cgp, fragno, 1);
 
10579
                        cgp->cg_cs.cs_nbfree++;
 
10580
                }
 
10581
        }
 
10582
        stat_jnewblk++;
 
10583
        jnewblk->jn_state &= ~ATTACHED;
 
10584
        jnewblk->jn_state |= UNDONE;
 
10585
 
 
10586
        return (frags);
 
10587
}
 
10588
 
 
10589
static void 
 
10590
initiate_write_bmsafemap(bmsafemap, bp)
 
10591
        struct bmsafemap *bmsafemap;
 
10592
        struct buf *bp;                 /* The cg block. */
 
10593
{
 
10594
        struct jaddref *jaddref;
 
10595
        struct jnewblk *jnewblk;
 
10596
        uint8_t *inosused;
 
10597
        uint8_t *blksfree;
 
10598
        struct cg *cgp;
 
10599
        struct fs *fs;
 
10600
        ino_t ino;
 
10601
 
 
10602
        if (bmsafemap->sm_state & IOSTARTED)
 
10603
                return;
 
10604
        bmsafemap->sm_state |= IOSTARTED;
 
10605
        /*
 
10606
         * Clear any inode allocations which are pending journal writes.
 
10607
         */
 
10608
        if (LIST_FIRST(&bmsafemap->sm_jaddrefhd) != NULL) {
 
10609
                cgp = (struct cg *)bp->b_data;
 
10610
                fs = VFSTOUFS(bmsafemap->sm_list.wk_mp)->um_fs;
 
10611
                inosused = cg_inosused(cgp);
 
10612
                LIST_FOREACH(jaddref, &bmsafemap->sm_jaddrefhd, ja_bmdeps) {
 
10613
                        ino = jaddref->ja_ino % fs->fs_ipg;
 
10614
                        if (isset(inosused, ino)) {
 
10615
                                if ((jaddref->ja_mode & IFMT) == IFDIR)
 
10616
                                        cgp->cg_cs.cs_ndir--;
 
10617
                                cgp->cg_cs.cs_nifree++;
 
10618
                                clrbit(inosused, ino);
 
10619
                                jaddref->ja_state &= ~ATTACHED;
 
10620
                                jaddref->ja_state |= UNDONE;
 
10621
                                stat_jaddref++;
 
10622
                        } else
 
10623
                                panic("initiate_write_bmsafemap: inode %d "
 
10624
                                    "marked free", jaddref->ja_ino);
 
10625
                }
 
10626
        }
 
10627
        /*
 
10628
         * Clear any block allocations which are pending journal writes.
 
10629
         */
 
10630
        if (LIST_FIRST(&bmsafemap->sm_jnewblkhd) != NULL) {
 
10631
                cgp = (struct cg *)bp->b_data;
 
10632
                fs = VFSTOUFS(bmsafemap->sm_list.wk_mp)->um_fs;
 
10633
                blksfree = cg_blksfree(cgp);
 
10634
                LIST_FOREACH(jnewblk, &bmsafemap->sm_jnewblkhd, jn_deps) {
 
10635
                        if (jnewblk_rollback(jnewblk, fs, cgp, blksfree))
 
10636
                                continue;
 
10637
                        panic("initiate_write_bmsafemap: block %jd "
 
10638
                            "marked free", jnewblk->jn_blkno);
 
10639
                }
 
10640
        }
 
10641
        /*
 
10642
         * Move allocation lists to the written lists so they can be
 
10643
         * cleared once the block write is complete.
 
10644
         */
 
10645
        LIST_SWAP(&bmsafemap->sm_inodedephd, &bmsafemap->sm_inodedepwr,
 
10646
            inodedep, id_deps);
 
10647
        LIST_SWAP(&bmsafemap->sm_newblkhd, &bmsafemap->sm_newblkwr,
 
10648
            newblk, nb_deps);
 
10649
        LIST_SWAP(&bmsafemap->sm_freehd, &bmsafemap->sm_freewr, worklist,
 
10650
            wk_list);
4240
10651
}
4241
10652
 
4242
10653
/*
4246
10657
 * a request completion).  It should be called early in this
4247
10658
 * procedure, before the block is made available to other
4248
10659
 * processes or other routines are called.
 
10660
 *
4249
10661
 */
4250
10662
static void 
4251
10663
softdep_disk_write_complete(bp)
4254
10666
        struct worklist *wk;
4255
10667
        struct worklist *owk;
4256
10668
        struct workhead reattach;
4257
 
        struct newblk *newblk;
4258
 
        struct allocindir *aip;
4259
 
        struct allocdirect *adp;
4260
 
        struct indirdep *indirdep;
4261
 
        struct inodedep *inodedep;
4262
 
        struct bmsafemap *bmsafemap;
 
10669
        struct freeblks *freeblks;
 
10670
        struct buf *sbp;
4263
10671
 
4264
10672
        /*
4265
10673
         * If an error occurred while doing the write, then the data
4271
10679
        /*
4272
10680
         * This lock must not be released anywhere in this code segment.
4273
10681
         */
4274
 
        ACQUIRE_LOCK(&lk);
 
10682
        sbp = NULL;
4275
10683
        owk = NULL;
 
10684
        ACQUIRE_LOCK(&lk);
4276
10685
        while ((wk = LIST_FIRST(&bp->b_dep)) != NULL) {
4277
10686
                WORKLIST_REMOVE(wk);
 
10687
                dep_write[wk->wk_type]++;
4278
10688
                if (wk == owk)
4279
10689
                        panic("duplicate worklist: %p\n", wk);
4280
10690
                owk = wk;
4291
10701
                        continue;
4292
10702
 
4293
10703
                case D_BMSAFEMAP:
4294
 
                        bmsafemap = WK_BMSAFEMAP(wk);
4295
 
                        while ((newblk = LIST_FIRST(&bmsafemap->sm_newblkhd))) {
4296
 
                                newblk->nb_state |= DEPCOMPLETE;
4297
 
                                newblk->nb_bmsafemap = NULL;
4298
 
                                LIST_REMOVE(newblk, nb_deps);
4299
 
                        }
4300
 
                        while ((adp =
4301
 
                           LIST_FIRST(&bmsafemap->sm_allocdirecthd))) {
4302
 
                                adp->ad_state |= DEPCOMPLETE;
4303
 
                                adp->ad_buf = NULL;
4304
 
                                LIST_REMOVE(adp, ad_deps);
4305
 
                                handle_allocdirect_partdone(adp);
4306
 
                        }
4307
 
                        while ((aip =
4308
 
                            LIST_FIRST(&bmsafemap->sm_allocindirhd))) {
4309
 
                                aip->ai_state |= DEPCOMPLETE;
4310
 
                                aip->ai_buf = NULL;
4311
 
                                LIST_REMOVE(aip, ai_deps);
4312
 
                                handle_allocindir_partdone(aip);
4313
 
                        }
4314
 
                        while ((inodedep =
4315
 
                             LIST_FIRST(&bmsafemap->sm_inodedephd)) != NULL) {
4316
 
                                inodedep->id_state |= DEPCOMPLETE;
4317
 
                                LIST_REMOVE(inodedep, id_deps);
4318
 
                                inodedep->id_buf = NULL;
4319
 
                        }
4320
 
                        WORKITEM_FREE(bmsafemap, D_BMSAFEMAP);
 
10704
                        if (handle_written_bmsafemap(WK_BMSAFEMAP(wk), bp))
 
10705
                                WORKLIST_INSERT(&reattach, wk);
4321
10706
                        continue;
4322
10707
 
4323
10708
                case D_MKDIR:
4325
10710
                        continue;
4326
10711
 
4327
10712
                case D_ALLOCDIRECT:
4328
 
                        adp = WK_ALLOCDIRECT(wk);
4329
 
                        adp->ad_state |= COMPLETE;
4330
 
                        handle_allocdirect_partdone(adp);
 
10713
                        wk->wk_state |= COMPLETE;
 
10714
                        handle_allocdirect_partdone(WK_ALLOCDIRECT(wk), NULL);
4331
10715
                        continue;
4332
10716
 
4333
10717
                case D_ALLOCINDIR:
4334
 
                        aip = WK_ALLOCINDIR(wk);
4335
 
                        aip->ai_state |= COMPLETE;
4336
 
                        handle_allocindir_partdone(aip);
 
10718
                        wk->wk_state |= COMPLETE;
 
10719
                        handle_allocindir_partdone(WK_ALLOCINDIR(wk));
4337
10720
                        continue;
4338
10721
 
4339
10722
                case D_INDIRDEP:
4340
 
                        indirdep = WK_INDIRDEP(wk);
4341
 
                        if (indirdep->ir_state & GOINGAWAY)
4342
 
                                panic("disk_write_complete: indirdep gone");
4343
 
                        bcopy(indirdep->ir_saveddata, bp->b_data, bp->b_bcount);
4344
 
                        free(indirdep->ir_saveddata, M_INDIRDEP);
4345
 
                        indirdep->ir_saveddata = 0;
4346
 
                        indirdep->ir_state &= ~UNDONE;
4347
 
                        indirdep->ir_state |= ATTACHED;
4348
 
                        while ((aip = LIST_FIRST(&indirdep->ir_donehd)) != 0) {
4349
 
                                handle_allocindir_partdone(aip);
4350
 
                                if (aip == LIST_FIRST(&indirdep->ir_donehd))
4351
 
                                        panic("disk_write_complete: not gone");
4352
 
                        }
4353
 
                        WORKLIST_INSERT(&reattach, wk);
4354
 
                        if ((bp->b_flags & B_DELWRI) == 0)
4355
 
                                stat_indir_blk_ptrs++;
4356
 
                        bdirty(bp);
 
10723
                        if (handle_written_indirdep(WK_INDIRDEP(wk), bp, &sbp))
 
10724
                                WORKLIST_INSERT(&reattach, wk);
 
10725
                        continue;
 
10726
 
 
10727
                case D_FREEBLKS:
 
10728
                        wk->wk_state |= COMPLETE;
 
10729
                        freeblks = WK_FREEBLKS(wk);
 
10730
                        if ((wk->wk_state & ALLCOMPLETE) == ALLCOMPLETE &&
 
10731
                            LIST_EMPTY(&freeblks->fb_jblkdephd))
 
10732
                                add_to_worklist(wk, WK_NODELAY);
 
10733
                        continue;
 
10734
 
 
10735
                case D_FREEWORK:
 
10736
                        handle_written_freework(WK_FREEWORK(wk));
 
10737
                        break;
 
10738
 
 
10739
                case D_JSEGDEP:
 
10740
                        free_jsegdep(WK_JSEGDEP(wk));
 
10741
                        continue;
 
10742
 
 
10743
                case D_JSEG:
 
10744
                        handle_written_jseg(WK_JSEG(wk), bp);
 
10745
                        continue;
 
10746
 
 
10747
                case D_SBDEP:
 
10748
                        if (handle_written_sbdep(WK_SBDEP(wk), bp))
 
10749
                                WORKLIST_INSERT(&reattach, wk);
 
10750
                        continue;
 
10751
 
 
10752
                case D_FREEDEP:
 
10753
                        free_freedep(WK_FREEDEP(wk));
4357
10754
                        continue;
4358
10755
 
4359
10756
                default:
4370
10767
                WORKLIST_INSERT(&bp->b_dep, wk);
4371
10768
        }
4372
10769
        FREE_LOCK(&lk);
 
10770
        if (sbp)
 
10771
                brelse(sbp);
4373
10772
}
4374
10773
 
4375
10774
/*
4378
10777
 * splbio interrupts blocked.
4379
10778
 */
4380
10779
static void 
4381
 
handle_allocdirect_partdone(adp)
 
10780
handle_allocdirect_partdone(adp, wkhd)
4382
10781
        struct allocdirect *adp;        /* the completed allocdirect */
 
10782
        struct workhead *wkhd;          /* Work to do when inode is writtne. */
4383
10783
{
4384
10784
        struct allocdirectlst *listhead;
4385
10785
        struct allocdirect *listadp;
4386
10786
        struct inodedep *inodedep;
4387
 
        long bsize, delay;
 
10787
        long bsize;
4388
10788
 
4389
10789
        if ((adp->ad_state & ALLCOMPLETE) != ALLCOMPLETE)
4390
10790
                return;
4391
 
        if (adp->ad_buf != NULL)
4392
 
                panic("handle_allocdirect_partdone: dangling dep");
4393
10791
        /*
4394
10792
         * The on-disk inode cannot claim to be any larger than the last
4395
10793
         * fragment that has been written. Otherwise, the on-disk inode
4439
10837
                return;
4440
10838
        }
4441
10839
        /*
4442
 
         * If we have found the just finished dependency, then free
 
10840
         * If we have found the just finished dependency, then queue
4443
10841
         * it along with anything that follows it that is complete.
4444
 
         * If the inode still has a bitmap dependency, then it has
4445
 
         * never been written to disk, hence the on-disk inode cannot
4446
 
         * reference the old fragment so we can free it without delay.
 
10842
         * Since the pointer has not yet been written in the inode
 
10843
         * as the dependency prevents it, place the allocdirect on the
 
10844
         * bufwait list where it will be freed once the pointer is
 
10845
         * valid.
4447
10846
         */
4448
 
        delay = (inodedep->id_state & DEPCOMPLETE);
 
10847
        if (wkhd == NULL)
 
10848
                wkhd = &inodedep->id_bufwait;
4449
10849
        for (; adp; adp = listadp) {
4450
10850
                listadp = TAILQ_NEXT(adp, ad_next);
4451
10851
                if ((adp->ad_state & ALLCOMPLETE) != ALLCOMPLETE)
4452
10852
                        return;
4453
 
                free_allocdirect(listhead, adp, delay);
 
10853
                TAILQ_REMOVE(listhead, adp, ad_next);
 
10854
                WORKLIST_INSERT(wkhd, &adp->ad_block.nb_list);
4454
10855
        }
4455
10856
}
4456
10857
 
4457
10858
/*
4458
 
 * Called from within softdep_disk_write_complete above. Note that
4459
 
 * this routine is always called from interrupt level with further
4460
 
 * splbio interrupts blocked.
 
10859
 * Called from within softdep_disk_write_complete above.  This routine
 
10860
 * completes successfully written allocindirs.
4461
10861
 */
4462
10862
static void
4463
10863
handle_allocindir_partdone(aip)
4467
10867
 
4468
10868
        if ((aip->ai_state & ALLCOMPLETE) != ALLCOMPLETE)
4469
10869
                return;
4470
 
        if (aip->ai_buf != NULL)
4471
 
                panic("handle_allocindir_partdone: dangling dependency");
4472
10870
        indirdep = aip->ai_indirdep;
4473
 
        if (indirdep->ir_state & UNDONE) {
4474
 
                LIST_REMOVE(aip, ai_next);
 
10871
        LIST_REMOVE(aip, ai_next);
 
10872
        /*
 
10873
         * Don't set a pointer while the buffer is undergoing IO or while
 
10874
         * we have active truncations.
 
10875
         */
 
10876
        if (indirdep->ir_state & UNDONE || !TAILQ_EMPTY(&indirdep->ir_trunc)) {
4475
10877
                LIST_INSERT_HEAD(&indirdep->ir_donehd, aip, ai_next);
4476
10878
                return;
4477
10879
        }
4481
10883
        else
4482
10884
                ((ufs2_daddr_t *)indirdep->ir_savebp->b_data)[aip->ai_offset] =
4483
10885
                    aip->ai_newblkno;
4484
 
        LIST_REMOVE(aip, ai_next);
4485
 
        if (aip->ai_freefrag != NULL)
4486
 
                add_to_worklist(&aip->ai_freefrag->ff_list);
4487
 
        WORKITEM_FREE(aip, D_ALLOCINDIR);
4488
 
}
4489
 
 
 
10886
        /*
 
10887
         * Await the pointer write before freeing the allocindir.
 
10888
         */
 
10889
        LIST_INSERT_HEAD(&indirdep->ir_writehd, aip, ai_next);
 
10890
}
 
10891
 
 
10892
/*
 
10893
 * Release segments held on a jwork list.
 
10894
 */
 
10895
static void
 
10896
handle_jwork(wkhd)
 
10897
        struct workhead *wkhd;
 
10898
{
 
10899
        struct worklist *wk;
 
10900
 
 
10901
        while ((wk = LIST_FIRST(wkhd)) != NULL) {
 
10902
                WORKLIST_REMOVE(wk);
 
10903
                switch (wk->wk_type) {
 
10904
                case D_JSEGDEP:
 
10905
                        free_jsegdep(WK_JSEGDEP(wk));
 
10906
                        continue;
 
10907
                case D_FREEDEP:
 
10908
                        free_freedep(WK_FREEDEP(wk));
 
10909
                        continue;
 
10910
                case D_FREEFRAG:
 
10911
                        rele_jseg(WK_JSEG(WK_FREEFRAG(wk)->ff_jdep));
 
10912
                        WORKITEM_FREE(wk, D_FREEFRAG);
 
10913
                        continue;
 
10914
                case D_FREEWORK:
 
10915
                        handle_written_freework(WK_FREEWORK(wk));
 
10916
                        continue;
 
10917
                default:
 
10918
                        panic("handle_jwork: Unknown type %s\n",
 
10919
                            TYPENAME(wk->wk_type));
 
10920
                }
 
10921
        }
 
10922
}
 
10923
 
 
10924
/*
 
10925
 * Handle the bufwait list on an inode when it is safe to release items
 
10926
 * held there.  This normally happens after an inode block is written but
 
10927
 * may be delayed and handled later if there are pending journal items that
 
10928
 * are not yet safe to be released.
 
10929
 */
 
10930
static struct freefile *
 
10931
handle_bufwait(inodedep, refhd)
 
10932
        struct inodedep *inodedep;
 
10933
        struct workhead *refhd;
 
10934
{
 
10935
        struct jaddref *jaddref;
 
10936
        struct freefile *freefile;
 
10937
        struct worklist *wk;
 
10938
 
 
10939
        freefile = NULL;
 
10940
        while ((wk = LIST_FIRST(&inodedep->id_bufwait)) != NULL) {
 
10941
                WORKLIST_REMOVE(wk);
 
10942
                switch (wk->wk_type) {
 
10943
                case D_FREEFILE:
 
10944
                        /*
 
10945
                         * We defer adding freefile to the worklist
 
10946
                         * until all other additions have been made to
 
10947
                         * ensure that it will be done after all the
 
10948
                         * old blocks have been freed.
 
10949
                         */
 
10950
                        if (freefile != NULL)
 
10951
                                panic("handle_bufwait: freefile");
 
10952
                        freefile = WK_FREEFILE(wk);
 
10953
                        continue;
 
10954
 
 
10955
                case D_MKDIR:
 
10956
                        handle_written_mkdir(WK_MKDIR(wk), MKDIR_PARENT);
 
10957
                        continue;
 
10958
 
 
10959
                case D_DIRADD:
 
10960
                        diradd_inode_written(WK_DIRADD(wk), inodedep);
 
10961
                        continue;
 
10962
 
 
10963
                case D_FREEFRAG:
 
10964
                        wk->wk_state |= COMPLETE;
 
10965
                        if ((wk->wk_state & ALLCOMPLETE) == ALLCOMPLETE)
 
10966
                                add_to_worklist(wk, 0);
 
10967
                        continue;
 
10968
 
 
10969
                case D_DIRREM:
 
10970
                        wk->wk_state |= COMPLETE;
 
10971
                        add_to_worklist(wk, 0);
 
10972
                        continue;
 
10973
 
 
10974
                case D_ALLOCDIRECT:
 
10975
                case D_ALLOCINDIR:
 
10976
                        free_newblk(WK_NEWBLK(wk));
 
10977
                        continue;
 
10978
 
 
10979
                case D_JNEWBLK:
 
10980
                        wk->wk_state |= COMPLETE;
 
10981
                        free_jnewblk(WK_JNEWBLK(wk));
 
10982
                        continue;
 
10983
 
 
10984
                /*
 
10985
                 * Save freed journal segments and add references on
 
10986
                 * the supplied list which will delay their release
 
10987
                 * until the cg bitmap is cleared on disk.
 
10988
                 */
 
10989
                case D_JSEGDEP:
 
10990
                        if (refhd == NULL)
 
10991
                                free_jsegdep(WK_JSEGDEP(wk));
 
10992
                        else
 
10993
                                WORKLIST_INSERT(refhd, wk);
 
10994
                        continue;
 
10995
 
 
10996
                case D_JADDREF:
 
10997
                        jaddref = WK_JADDREF(wk);
 
10998
                        TAILQ_REMOVE(&inodedep->id_inoreflst, &jaddref->ja_ref,
 
10999
                            if_deps);
 
11000
                        /*
 
11001
                         * Transfer any jaddrefs to the list to be freed with
 
11002
                         * the bitmap if we're handling a removed file.
 
11003
                         */
 
11004
                        if (refhd == NULL) {
 
11005
                                wk->wk_state |= COMPLETE;
 
11006
                                free_jaddref(jaddref);
 
11007
                        } else
 
11008
                                WORKLIST_INSERT(refhd, wk);
 
11009
                        continue;
 
11010
 
 
11011
                default:
 
11012
                        panic("handle_bufwait: Unknown type %p(%s)",
 
11013
                            wk, TYPENAME(wk->wk_type));
 
11014
                        /* NOTREACHED */
 
11015
                }
 
11016
        }
 
11017
        return (freefile);
 
11018
}
4490
11019
/*
4491
11020
 * Called from within softdep_disk_write_complete above to restore
4492
11021
 * in-memory inode block contents to their most up-to-date state. Note
4498
11027
        struct inodedep *inodedep;
4499
11028
        struct buf *bp;         /* buffer containing the inode block */
4500
11029
{
4501
 
        struct worklist *wk, *filefree;
 
11030
        struct freefile *freefile;
4502
11031
        struct allocdirect *adp, *nextadp;
4503
11032
        struct ufs1_dinode *dp1 = NULL;
4504
11033
        struct ufs2_dinode *dp2 = NULL;
 
11034
        struct workhead wkhd;
4505
11035
        int hadchanges, fstype;
 
11036
        ino_t freelink;
4506
11037
 
 
11038
        LIST_INIT(&wkhd);
 
11039
        hadchanges = 0;
 
11040
        freefile = NULL;
4507
11041
        if ((inodedep->id_state & IOSTARTED) == 0)
4508
11042
                panic("handle_written_inodeblock: not started");
4509
11043
        inodedep->id_state &= ~IOSTARTED;
4511
11045
                fstype = UFS1;
4512
11046
                dp1 = (struct ufs1_dinode *)bp->b_data +
4513
11047
                    ino_to_fsbo(inodedep->id_fs, inodedep->id_ino);
 
11048
                freelink = dp1->di_freelink;
4514
11049
        } else {
4515
11050
                fstype = UFS2;
4516
11051
                dp2 = (struct ufs2_dinode *)bp->b_data +
4517
11052
                    ino_to_fsbo(inodedep->id_fs, inodedep->id_ino);
 
11053
                freelink = dp2->di_freelink;
 
11054
        }
 
11055
        /*
 
11056
         * Leave this inodeblock dirty until it's in the list.
 
11057
         */
 
11058
        if ((inodedep->id_state & (UNLINKED | UNLINKONLIST)) == UNLINKED) {
 
11059
                struct inodedep *inon;
 
11060
 
 
11061
                inon = TAILQ_NEXT(inodedep, id_unlinked);
 
11062
                if ((inon == NULL && freelink == 0) ||
 
11063
                    (inon && inon->id_ino == freelink)) {
 
11064
                        if (inon)
 
11065
                                inon->id_state |= UNLINKPREV;
 
11066
                        inodedep->id_state |= UNLINKNEXT;
 
11067
                }
 
11068
                hadchanges = 1;
4518
11069
        }
4519
11070
        /*
4520
11071
         * If we had to rollback the inode allocation because of
4524
11075
         * corresponding updates written to disk.
4525
11076
         */
4526
11077
        if (inodedep->id_savedino1 != NULL) {
 
11078
                hadchanges = 1;
4527
11079
                if (fstype == UFS1)
4528
11080
                        *dp1 = *inodedep->id_savedino1;
4529
11081
                else
4533
11085
                if ((bp->b_flags & B_DELWRI) == 0)
4534
11086
                        stat_inode_bitmap++;
4535
11087
                bdirty(bp);
 
11088
                /*
 
11089
                 * If the inode is clear here and GOINGAWAY it will never
 
11090
                 * be written.  Process the bufwait and clear any pending
 
11091
                 * work which may include the freefile.
 
11092
                 */
 
11093
                if (inodedep->id_state & GOINGAWAY)
 
11094
                        goto bufwait;
4536
11095
                return (1);
4537
11096
        }
4538
11097
        inodedep->id_state |= COMPLETE;
4540
11099
         * Roll forward anything that had to be rolled back before 
4541
11100
         * the inode could be updated.
4542
11101
         */
4543
 
        hadchanges = 0;
4544
11102
        for (adp = TAILQ_FIRST(&inodedep->id_inoupdt); adp; adp = nextadp) {
4545
11103
                nextadp = TAILQ_NEXT(adp, ad_next);
4546
11104
                if (adp->ad_state & ATTACHED)
4547
11105
                        panic("handle_written_inodeblock: new entry");
4548
11106
                if (fstype == UFS1) {
4549
 
                        if (adp->ad_lbn < NDADDR) {
4550
 
                                if (dp1->di_db[adp->ad_lbn]!=adp->ad_oldblkno)
 
11107
                        if (adp->ad_offset < NDADDR) {
 
11108
                                if (dp1->di_db[adp->ad_offset]!=adp->ad_oldblkno)
4551
11109
                                        panic("%s %s #%jd mismatch %d != %jd",
4552
11110
                                            "handle_written_inodeblock:",
4553
11111
                                            "direct pointer",
4554
 
                                            (intmax_t)adp->ad_lbn,
4555
 
                                            dp1->di_db[adp->ad_lbn],
 
11112
                                            (intmax_t)adp->ad_offset,
 
11113
                                            dp1->di_db[adp->ad_offset],
4556
11114
                                            (intmax_t)adp->ad_oldblkno);
4557
 
                                dp1->di_db[adp->ad_lbn] = adp->ad_newblkno;
 
11115
                                dp1->di_db[adp->ad_offset] = adp->ad_newblkno;
4558
11116
                        } else {
4559
 
                                if (dp1->di_ib[adp->ad_lbn - NDADDR] != 0)
 
11117
                                if (dp1->di_ib[adp->ad_offset - NDADDR] != 0)
4560
11118
                                        panic("%s: %s #%jd allocated as %d",
4561
11119
                                            "handle_written_inodeblock",
4562
11120
                                            "indirect pointer",
4563
 
                                            (intmax_t)adp->ad_lbn - NDADDR,
4564
 
                                            dp1->di_ib[adp->ad_lbn - NDADDR]);
4565
 
                                dp1->di_ib[adp->ad_lbn - NDADDR] =
 
11121
                                            (intmax_t)adp->ad_offset - NDADDR,
 
11122
                                            dp1->di_ib[adp->ad_offset - NDADDR]);
 
11123
                                dp1->di_ib[adp->ad_offset - NDADDR] =
4566
11124
                                    adp->ad_newblkno;
4567
11125
                        }
4568
11126
                } else {
4569
 
                        if (adp->ad_lbn < NDADDR) {
4570
 
                                if (dp2->di_db[adp->ad_lbn]!=adp->ad_oldblkno)
 
11127
                        if (adp->ad_offset < NDADDR) {
 
11128
                                if (dp2->di_db[adp->ad_offset]!=adp->ad_oldblkno)
4571
11129
                                        panic("%s: %s #%jd %s %jd != %jd",
4572
11130
                                            "handle_written_inodeblock",
4573
11131
                                            "direct pointer",
4574
 
                                            (intmax_t)adp->ad_lbn, "mismatch",
4575
 
                                            (intmax_t)dp2->di_db[adp->ad_lbn],
 
11132
                                            (intmax_t)adp->ad_offset, "mismatch",
 
11133
                                            (intmax_t)dp2->di_db[adp->ad_offset],
4576
11134
                                            (intmax_t)adp->ad_oldblkno);
4577
 
                                dp2->di_db[adp->ad_lbn] = adp->ad_newblkno;
 
11135
                                dp2->di_db[adp->ad_offset] = adp->ad_newblkno;
4578
11136
                        } else {
4579
 
                                if (dp2->di_ib[adp->ad_lbn - NDADDR] != 0)
 
11137
                                if (dp2->di_ib[adp->ad_offset - NDADDR] != 0)
4580
11138
                                        panic("%s: %s #%jd allocated as %jd",
4581
11139
                                            "handle_written_inodeblock",
4582
11140
                                            "indirect pointer",
4583
 
                                            (intmax_t)adp->ad_lbn - NDADDR,
 
11141
                                            (intmax_t)adp->ad_offset - NDADDR,
4584
11142
                                            (intmax_t)
4585
 
                                            dp2->di_ib[adp->ad_lbn - NDADDR]);
4586
 
                                dp2->di_ib[adp->ad_lbn - NDADDR] =
 
11143
                                            dp2->di_ib[adp->ad_offset - NDADDR]);
 
11144
                                dp2->di_ib[adp->ad_offset - NDADDR] =
4587
11145
                                    adp->ad_newblkno;
4588
11146
                        }
4589
11147
                }
4595
11153
                nextadp = TAILQ_NEXT(adp, ad_next);
4596
11154
                if (adp->ad_state & ATTACHED)
4597
11155
                        panic("handle_written_inodeblock: new entry");
4598
 
                if (dp2->di_extb[adp->ad_lbn] != adp->ad_oldblkno)
 
11156
                if (dp2->di_extb[adp->ad_offset] != adp->ad_oldblkno)
4599
11157
                        panic("%s: direct pointers #%jd %s %jd != %jd",
4600
11158
                            "handle_written_inodeblock",
4601
 
                            (intmax_t)adp->ad_lbn, "mismatch",
4602
 
                            (intmax_t)dp2->di_extb[adp->ad_lbn],
 
11159
                            (intmax_t)adp->ad_offset, "mismatch",
 
11160
                            (intmax_t)dp2->di_extb[adp->ad_offset],
4603
11161
                            (intmax_t)adp->ad_oldblkno);
4604
 
                dp2->di_extb[adp->ad_lbn] = adp->ad_newblkno;
 
11162
                dp2->di_extb[adp->ad_offset] = adp->ad_newblkno;
4605
11163
                adp->ad_state &= ~UNDONE;
4606
11164
                adp->ad_state |= ATTACHED;
4607
11165
                hadchanges = 1;
4613
11171
         */
4614
11172
        if (inodedep->id_savedsize == -1 || inodedep->id_savedextsize == -1)
4615
11173
                panic("handle_written_inodeblock: bad size");
 
11174
        if (inodedep->id_savednlink > LINK_MAX)
 
11175
                panic("handle_written_inodeblock: Invalid link count "
 
11176
                    "%d for inodedep %p", inodedep->id_savednlink, inodedep);
4616
11177
        if (fstype == UFS1) {
 
11178
                if (dp1->di_nlink != inodedep->id_savednlink) { 
 
11179
                        dp1->di_nlink = inodedep->id_savednlink;
 
11180
                        hadchanges = 1;
 
11181
                }
4617
11182
                if (dp1->di_size != inodedep->id_savedsize) {
4618
11183
                        dp1->di_size = inodedep->id_savedsize;
4619
11184
                        hadchanges = 1;
4620
11185
                }
4621
11186
        } else {
 
11187
                if (dp2->di_nlink != inodedep->id_savednlink) { 
 
11188
                        dp2->di_nlink = inodedep->id_savednlink;
 
11189
                        hadchanges = 1;
 
11190
                }
4622
11191
                if (dp2->di_size != inodedep->id_savedsize) {
4623
11192
                        dp2->di_size = inodedep->id_savedsize;
4624
11193
                        hadchanges = 1;
4630
11199
        }
4631
11200
        inodedep->id_savedsize = -1;
4632
11201
        inodedep->id_savedextsize = -1;
 
11202
        inodedep->id_savednlink = -1;
4633
11203
        /*
4634
11204
         * If there were any rollbacks in the inode block, then it must be
4635
11205
         * marked dirty so that its will eventually get written back in
4637
11207
         */
4638
11208
        if (hadchanges)
4639
11209
                bdirty(bp);
 
11210
bufwait:
4640
11211
        /*
4641
11212
         * Process any allocdirects that completed during the update.
4642
11213
         */
4643
11214
        if ((adp = TAILQ_FIRST(&inodedep->id_inoupdt)) != NULL)
4644
 
                handle_allocdirect_partdone(adp);
 
11215
                handle_allocdirect_partdone(adp, &wkhd);
4645
11216
        if ((adp = TAILQ_FIRST(&inodedep->id_extupdt)) != NULL)
4646
 
                handle_allocdirect_partdone(adp);
 
11217
                handle_allocdirect_partdone(adp, &wkhd);
4647
11218
        /*
4648
11219
         * Process deallocations that were held pending until the
4649
11220
         * inode had been written to disk. Freeing of the inode
4650
11221
         * is delayed until after all blocks have been freed to
4651
11222
         * avoid creation of new <vfsid, inum, lbn> triples
4652
 
         * before the old ones have been deleted.
 
11223
         * before the old ones have been deleted.  Completely
 
11224
         * unlinked inodes are not processed until the unlinked
 
11225
         * inode list is written or the last reference is removed.
4653
11226
         */
4654
 
        filefree = NULL;
4655
 
        while ((wk = LIST_FIRST(&inodedep->id_bufwait)) != NULL) {
4656
 
                WORKLIST_REMOVE(wk);
4657
 
                switch (wk->wk_type) {
4658
 
 
4659
 
                case D_FREEFILE:
4660
 
                        /*
4661
 
                         * We defer adding filefree to the worklist until
4662
 
                         * all other additions have been made to ensure
4663
 
                         * that it will be done after all the old blocks
4664
 
                         * have been freed.
4665
 
                         */
4666
 
                        if (filefree != NULL)
4667
 
                                panic("handle_written_inodeblock: filefree");
4668
 
                        filefree = wk;
4669
 
                        continue;
4670
 
 
4671
 
                case D_MKDIR:
4672
 
                        handle_written_mkdir(WK_MKDIR(wk), MKDIR_PARENT);
4673
 
                        continue;
4674
 
 
4675
 
                case D_DIRADD:
4676
 
                        diradd_inode_written(WK_DIRADD(wk), inodedep);
4677
 
                        continue;
4678
 
 
4679
 
                case D_FREEBLKS:
4680
 
                        wk->wk_state |= COMPLETE;
4681
 
                        if ((wk->wk_state  & ALLCOMPLETE) != ALLCOMPLETE)
4682
 
                                continue;
4683
 
                         /* -- fall through -- */
4684
 
                case D_FREEFRAG:
4685
 
                case D_DIRREM:
4686
 
                        add_to_worklist(wk);
4687
 
                        continue;
4688
 
 
4689
 
                case D_NEWDIRBLK:
4690
 
                        free_newdirblk(WK_NEWDIRBLK(wk));
4691
 
                        continue;
4692
 
 
4693
 
                default:
4694
 
                        panic("handle_written_inodeblock: Unknown type %s",
4695
 
                            TYPENAME(wk->wk_type));
4696
 
                        /* NOTREACHED */
 
11227
        if ((inodedep->id_state & (UNLINKED | UNLINKONLIST)) != UNLINKED) {
 
11228
                freefile = handle_bufwait(inodedep, NULL);
 
11229
                if (freefile && !LIST_EMPTY(&wkhd)) {
 
11230
                        WORKLIST_INSERT(&wkhd, &freefile->fx_list);
 
11231
                        freefile = NULL;
4697
11232
                }
4698
11233
        }
4699
 
        if (filefree != NULL) {
 
11234
        /*
 
11235
         * Move rolled forward dependency completions to the bufwait list
 
11236
         * now that those that were already written have been processed.
 
11237
         */
 
11238
        if (!LIST_EMPTY(&wkhd) && hadchanges == 0)
 
11239
                panic("handle_written_inodeblock: bufwait but no changes");
 
11240
        jwork_move(&inodedep->id_bufwait, &wkhd);
 
11241
 
 
11242
        if (freefile != NULL) {
 
11243
                /*
 
11244
                 * If the inode is goingaway it was never written.  Fake up
 
11245
                 * the state here so free_inodedep() can succeed.
 
11246
                 */
 
11247
                if (inodedep->id_state & GOINGAWAY)
 
11248
                        inodedep->id_state |= COMPLETE | DEPCOMPLETE;
4700
11249
                if (free_inodedep(inodedep) == 0)
4701
 
                        panic("handle_written_inodeblock: live inodedep");
4702
 
                add_to_worklist(filefree);
 
11250
                        panic("handle_written_inodeblock: live inodedep %p",
 
11251
                            inodedep);
 
11252
                add_to_worklist(&freefile->fx_list, 0);
4703
11253
                return (0);
4704
11254
        }
4705
11255
 
4707
11257
         * If no outstanding dependencies, free it.
4708
11258
         */
4709
11259
        if (free_inodedep(inodedep) ||
4710
 
            (TAILQ_FIRST(&inodedep->id_inoupdt) == 0 &&
4711
 
             TAILQ_FIRST(&inodedep->id_extupdt) == 0))
 
11260
            (TAILQ_FIRST(&inodedep->id_inoreflst) == 0 &&
 
11261
             TAILQ_FIRST(&inodedep->id_inoupdt) == 0 &&
 
11262
             TAILQ_FIRST(&inodedep->id_extupdt) == 0 &&
 
11263
             LIST_FIRST(&inodedep->id_bufwait) == 0))
4712
11264
                return (0);
4713
11265
        return (hadchanges);
4714
11266
}
4715
11267
 
 
11268
static int
 
11269
handle_written_indirdep(indirdep, bp, bpp)
 
11270
        struct indirdep *indirdep;
 
11271
        struct buf *bp;
 
11272
        struct buf **bpp;
 
11273
{
 
11274
        struct allocindir *aip;
 
11275
        struct buf *sbp;
 
11276
        int chgs;
 
11277
 
 
11278
        if (indirdep->ir_state & GOINGAWAY)
 
11279
                panic("handle_written_indirdep: indirdep gone");
 
11280
        if ((indirdep->ir_state & IOSTARTED) == 0)
 
11281
                panic("handle_written_indirdep: IO not started");
 
11282
        chgs = 0;
 
11283
        /*
 
11284
         * If there were rollbacks revert them here.
 
11285
         */
 
11286
        if (indirdep->ir_saveddata) {
 
11287
                bcopy(indirdep->ir_saveddata, bp->b_data, bp->b_bcount);
 
11288
                if (TAILQ_EMPTY(&indirdep->ir_trunc)) {
 
11289
                        free(indirdep->ir_saveddata, M_INDIRDEP);
 
11290
                        indirdep->ir_saveddata = NULL;
 
11291
                }
 
11292
                chgs = 1;
 
11293
        }
 
11294
        indirdep->ir_state &= ~(UNDONE | IOSTARTED);
 
11295
        indirdep->ir_state |= ATTACHED;
 
11296
        /*
 
11297
         * Move allocindirs with written pointers to the completehd if
 
11298
         * the indirdep's pointer is not yet written.  Otherwise
 
11299
         * free them here.
 
11300
         */
 
11301
        while ((aip = LIST_FIRST(&indirdep->ir_writehd)) != 0) {
 
11302
                LIST_REMOVE(aip, ai_next);
 
11303
                if ((indirdep->ir_state & DEPCOMPLETE) == 0) {
 
11304
                        LIST_INSERT_HEAD(&indirdep->ir_completehd, aip,
 
11305
                            ai_next);
 
11306
                        newblk_freefrag(&aip->ai_block);
 
11307
                        continue;
 
11308
                }
 
11309
                free_newblk(&aip->ai_block);
 
11310
        }
 
11311
        /*
 
11312
         * Move allocindirs that have finished dependency processing from
 
11313
         * the done list to the write list after updating the pointers.
 
11314
         */
 
11315
        if (TAILQ_EMPTY(&indirdep->ir_trunc)) {
 
11316
                while ((aip = LIST_FIRST(&indirdep->ir_donehd)) != 0) {
 
11317
                        handle_allocindir_partdone(aip);
 
11318
                        if (aip == LIST_FIRST(&indirdep->ir_donehd))
 
11319
                                panic("disk_write_complete: not gone");
 
11320
                        chgs = 1;
 
11321
                }
 
11322
        }
 
11323
        /*
 
11324
         * Preserve the indirdep if there were any changes or if it is not
 
11325
         * yet valid on disk.
 
11326
         */
 
11327
        if (chgs) {
 
11328
                stat_indir_blk_ptrs++;
 
11329
                bdirty(bp);
 
11330
                return (1);
 
11331
        }
 
11332
        /*
 
11333
         * If there were no changes we can discard the savedbp and detach
 
11334
         * ourselves from the buf.  We are only carrying completed pointers
 
11335
         * in this case.
 
11336
         */
 
11337
        sbp = indirdep->ir_savebp;
 
11338
        sbp->b_flags |= B_INVAL | B_NOCACHE;
 
11339
        indirdep->ir_savebp = NULL;
 
11340
        indirdep->ir_bp = NULL;
 
11341
        if (*bpp != NULL)
 
11342
                panic("handle_written_indirdep: bp already exists.");
 
11343
        *bpp = sbp;
 
11344
        /*
 
11345
         * The indirdep may not be freed until its parent points at it.
 
11346
         */
 
11347
        if (indirdep->ir_state & DEPCOMPLETE)
 
11348
                free_indirdep(indirdep);
 
11349
 
 
11350
        return (0);
 
11351
}
 
11352
 
4716
11353
/*
4717
11354
 * Process a diradd entry after its dependent inode has been written.
4718
11355
 * This routine must be called with splbio interrupts blocked.
4722
11359
        struct diradd *dap;
4723
11360
        struct inodedep *inodedep;
4724
11361
{
4725
 
        struct pagedep *pagedep;
4726
11362
 
4727
11363
        dap->da_state |= COMPLETE;
4728
 
        if ((dap->da_state & ALLCOMPLETE) == ALLCOMPLETE) {
4729
 
                if (dap->da_state & DIRCHG)
4730
 
                        pagedep = dap->da_previous->dm_pagedep;
4731
 
                else
4732
 
                        pagedep = dap->da_pagedep;
4733
 
                LIST_REMOVE(dap, da_pdlist);
4734
 
                LIST_INSERT_HEAD(&pagedep->pd_pendinghd, dap, da_pdlist);
4735
 
        }
 
11364
        complete_diradd(dap);
4736
11365
        WORKLIST_INSERT(&inodedep->id_pendinghd, &dap->da_list);
4737
11366
}
4738
11367
 
4739
11368
/*
 
11369
 * Returns true if the bmsafemap will have rollbacks when written.  Must
 
11370
 * only be called with lk and the buf lock on the cg held.
 
11371
 */
 
11372
static int
 
11373
bmsafemap_backgroundwrite(bmsafemap, bp)
 
11374
        struct bmsafemap *bmsafemap;
 
11375
        struct buf *bp;
 
11376
{
 
11377
        int dirty;
 
11378
 
 
11379
        dirty = !LIST_EMPTY(&bmsafemap->sm_jaddrefhd) | 
 
11380
            !LIST_EMPTY(&bmsafemap->sm_jnewblkhd);
 
11381
        /*
 
11382
         * If we're initiating a background write we need to process the
 
11383
         * rollbacks as they exist now, not as they exist when IO starts.
 
11384
         * No other consumers will look at the contents of the shadowed
 
11385
         * buf so this is safe to do here.
 
11386
         */
 
11387
        if (bp->b_xflags & BX_BKGRDMARKER)
 
11388
                initiate_write_bmsafemap(bmsafemap, bp);
 
11389
 
 
11390
        return (dirty);
 
11391
}
 
11392
 
 
11393
/*
 
11394
 * Re-apply an allocation when a cg write is complete.
 
11395
 */
 
11396
static int
 
11397
jnewblk_rollforward(jnewblk, fs, cgp, blksfree)
 
11398
        struct jnewblk *jnewblk;
 
11399
        struct fs *fs;
 
11400
        struct cg *cgp;
 
11401
        uint8_t *blksfree;
 
11402
{
 
11403
        ufs1_daddr_t fragno;
 
11404
        ufs2_daddr_t blkno;
 
11405
        long cgbno, bbase;
 
11406
        int frags, blk;
 
11407
        int i;
 
11408
 
 
11409
        frags = 0;
 
11410
        cgbno = dtogd(fs, jnewblk->jn_blkno);
 
11411
        for (i = jnewblk->jn_oldfrags; i < jnewblk->jn_frags; i++) {
 
11412
                if (isclr(blksfree, cgbno + i))
 
11413
                        panic("jnewblk_rollforward: re-allocated fragment");
 
11414
                frags++;
 
11415
        }
 
11416
        if (frags == fs->fs_frag) {
 
11417
                blkno = fragstoblks(fs, cgbno);
 
11418
                ffs_clrblock(fs, blksfree, (long)blkno);
 
11419
                ffs_clusteracct(fs, cgp, blkno, -1);
 
11420
                cgp->cg_cs.cs_nbfree--;
 
11421
        } else {
 
11422
                bbase = cgbno - fragnum(fs, cgbno);
 
11423
                cgbno += jnewblk->jn_oldfrags;
 
11424
                /* If a complete block had been reassembled, account for it. */
 
11425
                fragno = fragstoblks(fs, bbase);
 
11426
                if (ffs_isblock(fs, blksfree, fragno)) {
 
11427
                        cgp->cg_cs.cs_nffree += fs->fs_frag;
 
11428
                        ffs_clusteracct(fs, cgp, fragno, -1);
 
11429
                        cgp->cg_cs.cs_nbfree--;
 
11430
                }
 
11431
                /* Decrement the old frags.  */
 
11432
                blk = blkmap(fs, blksfree, bbase);
 
11433
                ffs_fragacct(fs, blk, cgp->cg_frsum, -1);
 
11434
                /* Allocate the fragment */
 
11435
                for (i = 0; i < frags; i++)
 
11436
                        clrbit(blksfree, cgbno + i);
 
11437
                cgp->cg_cs.cs_nffree -= frags;
 
11438
                /* Add back in counts associated with the new frags */
 
11439
                blk = blkmap(fs, blksfree, bbase);
 
11440
                ffs_fragacct(fs, blk, cgp->cg_frsum, 1);
 
11441
        }
 
11442
        return (frags);
 
11443
}
 
11444
 
 
11445
/*
 
11446
 * Complete a write to a bmsafemap structure.  Roll forward any bitmap
 
11447
 * changes if it's not a background write.  Set all written dependencies 
 
11448
 * to DEPCOMPLETE and free the structure if possible.
 
11449
 */
 
11450
static int
 
11451
handle_written_bmsafemap(bmsafemap, bp)
 
11452
        struct bmsafemap *bmsafemap;
 
11453
        struct buf *bp;
 
11454
{
 
11455
        struct newblk *newblk;
 
11456
        struct inodedep *inodedep;
 
11457
        struct jaddref *jaddref, *jatmp;
 
11458
        struct jnewblk *jnewblk, *jntmp;
 
11459
        struct ufsmount *ump;
 
11460
        uint8_t *inosused;
 
11461
        uint8_t *blksfree;
 
11462
        struct cg *cgp;
 
11463
        struct fs *fs;
 
11464
        ino_t ino;
 
11465
        int chgs;
 
11466
 
 
11467
        if ((bmsafemap->sm_state & IOSTARTED) == 0)
 
11468
                panic("initiate_write_bmsafemap: Not started\n");
 
11469
        ump = VFSTOUFS(bmsafemap->sm_list.wk_mp);
 
11470
        chgs = 0;
 
11471
        bmsafemap->sm_state &= ~IOSTARTED;
 
11472
        /*
 
11473
         * Release journal work that was waiting on the write.
 
11474
         */
 
11475
        handle_jwork(&bmsafemap->sm_freewr);
 
11476
 
 
11477
        /*
 
11478
         * Restore unwritten inode allocation pending jaddref writes.
 
11479
         */
 
11480
        if (!LIST_EMPTY(&bmsafemap->sm_jaddrefhd)) {
 
11481
                cgp = (struct cg *)bp->b_data;
 
11482
                fs = VFSTOUFS(bmsafemap->sm_list.wk_mp)->um_fs;
 
11483
                inosused = cg_inosused(cgp);
 
11484
                LIST_FOREACH_SAFE(jaddref, &bmsafemap->sm_jaddrefhd,
 
11485
                    ja_bmdeps, jatmp) {
 
11486
                        if ((jaddref->ja_state & UNDONE) == 0)
 
11487
                                continue;
 
11488
                        ino = jaddref->ja_ino % fs->fs_ipg;
 
11489
                        if (isset(inosused, ino))
 
11490
                                panic("handle_written_bmsafemap: "
 
11491
                                    "re-allocated inode");
 
11492
                        if ((bp->b_xflags & BX_BKGRDMARKER) == 0) {
 
11493
                                if ((jaddref->ja_mode & IFMT) == IFDIR)
 
11494
                                        cgp->cg_cs.cs_ndir++;
 
11495
                                cgp->cg_cs.cs_nifree--;
 
11496
                                setbit(inosused, ino);
 
11497
                                chgs = 1;
 
11498
                        }
 
11499
                        jaddref->ja_state &= ~UNDONE;
 
11500
                        jaddref->ja_state |= ATTACHED;
 
11501
                        free_jaddref(jaddref);
 
11502
                }
 
11503
        }
 
11504
        /*
 
11505
         * Restore any block allocations which are pending journal writes.
 
11506
         */
 
11507
        if (LIST_FIRST(&bmsafemap->sm_jnewblkhd) != NULL) {
 
11508
                cgp = (struct cg *)bp->b_data;
 
11509
                fs = VFSTOUFS(bmsafemap->sm_list.wk_mp)->um_fs;
 
11510
                blksfree = cg_blksfree(cgp);
 
11511
                LIST_FOREACH_SAFE(jnewblk, &bmsafemap->sm_jnewblkhd, jn_deps,
 
11512
                    jntmp) {
 
11513
                        if ((jnewblk->jn_state & UNDONE) == 0)
 
11514
                                continue;
 
11515
                        if ((bp->b_xflags & BX_BKGRDMARKER) == 0 &&
 
11516
                            jnewblk_rollforward(jnewblk, fs, cgp, blksfree))
 
11517
                                chgs = 1;
 
11518
                        jnewblk->jn_state &= ~(UNDONE | NEWBLOCK);
 
11519
                        jnewblk->jn_state |= ATTACHED;
 
11520
                        free_jnewblk(jnewblk);
 
11521
                }
 
11522
        }
 
11523
        while ((newblk = LIST_FIRST(&bmsafemap->sm_newblkwr))) {
 
11524
                newblk->nb_state |= DEPCOMPLETE;
 
11525
                newblk->nb_state &= ~ONDEPLIST;
 
11526
                newblk->nb_bmsafemap = NULL;
 
11527
                LIST_REMOVE(newblk, nb_deps);
 
11528
                if (newblk->nb_list.wk_type == D_ALLOCDIRECT)
 
11529
                        handle_allocdirect_partdone(
 
11530
                            WK_ALLOCDIRECT(&newblk->nb_list), NULL);
 
11531
                else if (newblk->nb_list.wk_type == D_ALLOCINDIR)
 
11532
                        handle_allocindir_partdone(
 
11533
                            WK_ALLOCINDIR(&newblk->nb_list));
 
11534
                else if (newblk->nb_list.wk_type != D_NEWBLK)
 
11535
                        panic("handle_written_bmsafemap: Unexpected type: %s",
 
11536
                            TYPENAME(newblk->nb_list.wk_type));
 
11537
        }
 
11538
        while ((inodedep = LIST_FIRST(&bmsafemap->sm_inodedepwr)) != NULL) {
 
11539
                inodedep->id_state |= DEPCOMPLETE;
 
11540
                inodedep->id_state &= ~ONDEPLIST;
 
11541
                LIST_REMOVE(inodedep, id_deps);
 
11542
                inodedep->id_bmsafemap = NULL;
 
11543
        }
 
11544
        LIST_REMOVE(bmsafemap, sm_next);
 
11545
        if (chgs == 0 && LIST_EMPTY(&bmsafemap->sm_jaddrefhd) &&
 
11546
            LIST_EMPTY(&bmsafemap->sm_jnewblkhd) &&
 
11547
            LIST_EMPTY(&bmsafemap->sm_newblkhd) &&
 
11548
            LIST_EMPTY(&bmsafemap->sm_inodedephd) &&
 
11549
            LIST_EMPTY(&bmsafemap->sm_freehd)) {
 
11550
                LIST_REMOVE(bmsafemap, sm_hash);
 
11551
                WORKITEM_FREE(bmsafemap, D_BMSAFEMAP);
 
11552
                return (0);
 
11553
        }
 
11554
        LIST_INSERT_HEAD(&ump->softdep_dirtycg, bmsafemap, sm_next);
 
11555
        bdirty(bp);
 
11556
        return (1);
 
11557
}
 
11558
 
 
11559
/*
 
11560
 * Try to free a mkdir dependency.
 
11561
 */
 
11562
static void
 
11563
complete_mkdir(mkdir)
 
11564
        struct mkdir *mkdir;
 
11565
{
 
11566
        struct diradd *dap;
 
11567
 
 
11568
        if ((mkdir->md_state & ALLCOMPLETE) != ALLCOMPLETE)
 
11569
                return;
 
11570
        LIST_REMOVE(mkdir, md_mkdirs);
 
11571
        dap = mkdir->md_diradd;
 
11572
        dap->da_state &= ~(mkdir->md_state & (MKDIR_PARENT | MKDIR_BODY));
 
11573
        if ((dap->da_state & (MKDIR_PARENT | MKDIR_BODY)) == 0) {
 
11574
                dap->da_state |= DEPCOMPLETE;
 
11575
                complete_diradd(dap);
 
11576
        }
 
11577
        WORKITEM_FREE(mkdir, D_MKDIR);
 
11578
}
 
11579
 
 
11580
/*
4740
11581
 * Handle the completion of a mkdir dependency.
4741
11582
 */
4742
11583
static void
4744
11585
        struct mkdir *mkdir;
4745
11586
        int type;
4746
11587
{
4747
 
        struct diradd *dap;
4748
 
        struct pagedep *pagedep;
4749
11588
 
4750
 
        if (mkdir->md_state != type)
 
11589
        if ((mkdir->md_state & (MKDIR_PARENT | MKDIR_BODY)) != type)
4751
11590
                panic("handle_written_mkdir: bad type");
4752
 
        dap = mkdir->md_diradd;
4753
 
        dap->da_state &= ~type;
4754
 
        if ((dap->da_state & (MKDIR_PARENT | MKDIR_BODY)) == 0)
4755
 
                dap->da_state |= DEPCOMPLETE;
4756
 
        if ((dap->da_state & ALLCOMPLETE) == ALLCOMPLETE) {
4757
 
                if (dap->da_state & DIRCHG)
4758
 
                        pagedep = dap->da_previous->dm_pagedep;
4759
 
                else
4760
 
                        pagedep = dap->da_pagedep;
4761
 
                LIST_REMOVE(dap, da_pdlist);
4762
 
                LIST_INSERT_HEAD(&pagedep->pd_pendinghd, dap, da_pdlist);
4763
 
        }
4764
 
        LIST_REMOVE(mkdir, md_mkdirs);
4765
 
        WORKITEM_FREE(mkdir, D_MKDIR);
 
11591
        mkdir->md_state |= COMPLETE;
 
11592
        complete_mkdir(mkdir);
 
11593
}
 
11594
 
 
11595
static int
 
11596
free_pagedep(pagedep)
 
11597
        struct pagedep *pagedep;
 
11598
{
 
11599
        int i;
 
11600
 
 
11601
        if (pagedep->pd_state & NEWBLOCK)
 
11602
                return (0);
 
11603
        if (!LIST_EMPTY(&pagedep->pd_dirremhd))
 
11604
                return (0);
 
11605
        for (i = 0; i < DAHASHSZ; i++)
 
11606
                if (!LIST_EMPTY(&pagedep->pd_diraddhd[i]))
 
11607
                        return (0);
 
11608
        if (!LIST_EMPTY(&pagedep->pd_pendinghd))
 
11609
                return (0);
 
11610
        if (!LIST_EMPTY(&pagedep->pd_jmvrefhd))
 
11611
                return (0);
 
11612
        if (pagedep->pd_state & ONWORKLIST)
 
11613
                WORKLIST_REMOVE(&pagedep->pd_list);
 
11614
        LIST_REMOVE(pagedep, pd_hash);
 
11615
        WORKITEM_FREE(pagedep, D_PAGEDEP);
 
11616
 
 
11617
        return (1);
4766
11618
}
4767
11619
 
4768
11620
/*
4790
11642
         */
4791
11643
        while ((dirrem = LIST_FIRST(&pagedep->pd_dirremhd)) != NULL) {
4792
11644
                LIST_REMOVE(dirrem, dm_next);
 
11645
                dirrem->dm_state |= COMPLETE;
4793
11646
                dirrem->dm_dirinum = pagedep->pd_ino;
4794
 
                add_to_worklist(&dirrem->dm_list);
 
11647
                KASSERT(LIST_EMPTY(&dirrem->dm_jremrefhd),
 
11648
                    ("handle_written_filepage: Journal entries not written."));
 
11649
                add_to_worklist(&dirrem->dm_list, 0);
4795
11650
        }
4796
11651
        /*
4797
11652
         * Free any directory additions that have been committed.
4800
11655
         */
4801
11656
        if ((pagedep->pd_state & NEWBLOCK) == 0)
4802
11657
                while ((dap = LIST_FIRST(&pagedep->pd_pendinghd)) != NULL)
4803
 
                        free_diradd(dap);
 
11658
                        free_diradd(dap, NULL);
4804
11659
        /*
4805
11660
         * Uncommitted directory entries must be restored.
4806
11661
         */
4845
11700
         * Otherwise it will remain to track any new entries on
4846
11701
         * the page in case they are fsync'ed.
4847
11702
         */
4848
 
        if ((pagedep->pd_state & NEWBLOCK) == 0) {
4849
 
                LIST_REMOVE(pagedep, pd_hash);
4850
 
                WORKITEM_FREE(pagedep, D_PAGEDEP);
4851
 
        }
 
11703
        free_pagedep(pagedep);
4852
11704
        return (0);
4853
11705
}
4854
11706
 
4880
11732
         */
4881
11733
        ip->i_effnlink = ip->i_nlink;
4882
11734
        ACQUIRE_LOCK(&lk);
4883
 
        if (inodedep_lookup(UFSTOVFS(ip->i_ump),
4884
 
            ip->i_number, 0, &inodedep) == 0) {
 
11735
        if (inodedep_lookup(UFSTOVFS(ip->i_ump), ip->i_number, 0,
 
11736
            &inodedep) == 0) {
4885
11737
                FREE_LOCK(&lk);
4886
11738
                return;
4887
11739
        }
4888
11740
        ip->i_effnlink -= inodedep->id_nlinkdelta;
4889
 
        if (inodedep->id_state & SPACECOUNTED)
4890
 
                ip->i_flag |= IN_SPACECOUNTED;
4891
11741
        FREE_LOCK(&lk);
4892
11742
}
4893
11743
 
4908
11758
        int waitfor;            /* nonzero => update must be allowed */
4909
11759
{
4910
11760
        struct inodedep *inodedep;
 
11761
        struct inoref *inoref;
4911
11762
        struct worklist *wk;
4912
11763
        struct mount *mp;
4913
11764
        struct buf *ibp;
 
11765
        struct fs *fs;
4914
11766
        int error;
4915
11767
 
 
11768
        mp = UFSTOVFS(ip->i_ump);
 
11769
        fs = ip->i_fs;
 
11770
        /*
 
11771
         * Preserve the freelink that is on disk.  clear_unlinked_inodedep()
 
11772
         * does not have access to the in-core ip so must write directly into
 
11773
         * the inode block buffer when setting freelink.
 
11774
         */
 
11775
        if (fs->fs_magic == FS_UFS1_MAGIC)
 
11776
                DIP_SET(ip, i_freelink, ((struct ufs1_dinode *)bp->b_data +
 
11777
                    ino_to_fsbo(fs, ip->i_number))->di_freelink);
 
11778
        else
 
11779
                DIP_SET(ip, i_freelink, ((struct ufs2_dinode *)bp->b_data +
 
11780
                    ino_to_fsbo(fs, ip->i_number))->di_freelink);
4916
11781
        /*
4917
11782
         * If the effective link count is not equal to the actual link
4918
11783
         * count, then we must track the difference in an inodedep while
4920
11785
         * if there is no existing inodedep, then there are no dependencies
4921
11786
         * to track.
4922
11787
         */
4923
 
        mp = UFSTOVFS(ip->i_ump);
4924
11788
        ACQUIRE_LOCK(&lk);
 
11789
again:
4925
11790
        if (inodedep_lookup(mp, ip->i_number, 0, &inodedep) == 0) {
4926
11791
                FREE_LOCK(&lk);
4927
11792
                if (ip->i_effnlink != ip->i_nlink)
4931
11796
        if (inodedep->id_nlinkdelta != ip->i_nlink - ip->i_effnlink)
4932
11797
                panic("softdep_update_inodeblock: bad delta");
4933
11798
        /*
 
11799
         * If we're flushing all dependencies we must also move any waiting
 
11800
         * for journal writes onto the bufwait list prior to I/O.
 
11801
         */
 
11802
        if (waitfor) {
 
11803
                TAILQ_FOREACH(inoref, &inodedep->id_inoreflst, if_deps) {
 
11804
                        if ((inoref->if_state & (DEPCOMPLETE | GOINGAWAY))
 
11805
                            == DEPCOMPLETE) {
 
11806
                                jwait(&inoref->if_list, MNT_WAIT);
 
11807
                                goto again;
 
11808
                        }
 
11809
                }
 
11810
        }
 
11811
        /*
4934
11812
         * Changes have been initiated. Anything depending on these
4935
11813
         * changes cannot occur until this inode has been written.
4936
11814
         */
4945
11823
         */
4946
11824
        merge_inode_lists(&inodedep->id_newinoupdt, &inodedep->id_inoupdt);
4947
11825
        if (!TAILQ_EMPTY(&inodedep->id_inoupdt))
4948
 
                handle_allocdirect_partdone(TAILQ_FIRST(&inodedep->id_inoupdt));
 
11826
                handle_allocdirect_partdone(TAILQ_FIRST(&inodedep->id_inoupdt),
 
11827
                    NULL);
4949
11828
        merge_inode_lists(&inodedep->id_newextupdt, &inodedep->id_extupdt);
4950
11829
        if (!TAILQ_EMPTY(&inodedep->id_extupdt))
4951
 
                handle_allocdirect_partdone(TAILQ_FIRST(&inodedep->id_extupdt));
 
11830
                handle_allocdirect_partdone(TAILQ_FIRST(&inodedep->id_extupdt),
 
11831
                    NULL);
4952
11832
        /*
4953
11833
         * Now that the inode has been pushed into the buffer, the
4954
11834
         * operations dependent on the inode being written to disk
4971
11851
                return;
4972
11852
        }
4973
11853
retry:
4974
 
        if ((inodedep->id_state & DEPCOMPLETE) != 0) {
 
11854
        if ((inodedep->id_state & (DEPCOMPLETE | GOINGAWAY)) != 0) {
4975
11855
                FREE_LOCK(&lk);
4976
11856
                return;
4977
11857
        }
4978
 
        ibp = inodedep->id_buf;
 
11858
        ibp = inodedep->id_bmsafemap->sm_buf;
4979
11859
        ibp = getdirtybuf(ibp, &lk, MNT_WAIT);
4980
11860
        if (ibp == NULL) {
4981
11861
                /*
5007
11887
 
5008
11888
        newadp = TAILQ_FIRST(newlisthead);
5009
11889
        for (listadp = TAILQ_FIRST(oldlisthead); listadp && newadp;) {
5010
 
                if (listadp->ad_lbn < newadp->ad_lbn) {
 
11890
                if (listadp->ad_offset < newadp->ad_offset) {
5011
11891
                        listadp = TAILQ_NEXT(listadp, ad_next);
5012
11892
                        continue;
5013
11893
                }
5014
11894
                TAILQ_REMOVE(newlisthead, newadp, ad_next);
5015
11895
                TAILQ_INSERT_BEFORE(listadp, newadp, ad_next);
5016
 
                if (listadp->ad_lbn == newadp->ad_lbn) {
 
11896
                if (listadp->ad_offset == newadp->ad_offset) {
5017
11897
                        allocdirect_merge(oldlisthead, newadp,
5018
11898
                            listadp);
5019
11899
                        listadp = newadp;
5036
11916
{
5037
11917
        struct inodedep *inodedep;
5038
11918
        struct pagedep *pagedep;
 
11919
        struct inoref *inoref;
5039
11920
        struct worklist *wk;
5040
11921
        struct diradd *dap;
5041
11922
        struct mount *mp;
5052
11933
        fs = ip->i_fs;
5053
11934
        mp = vp->v_mount;
5054
11935
        ACQUIRE_LOCK(&lk);
 
11936
restart:
5055
11937
        if (inodedep_lookup(mp, ip->i_number, 0, &inodedep) == 0) {
5056
11938
                FREE_LOCK(&lk);
5057
11939
                return (0);
5058
11940
        }
 
11941
        TAILQ_FOREACH(inoref, &inodedep->id_inoreflst, if_deps) {
 
11942
                if ((inoref->if_state & (DEPCOMPLETE | GOINGAWAY))
 
11943
                    == DEPCOMPLETE) {
 
11944
                        jwait(&inoref->if_list, MNT_WAIT);
 
11945
                        goto restart;
 
11946
                }
 
11947
        }
5059
11948
        if (!LIST_EMPTY(&inodedep->id_inowait) ||
5060
 
            !LIST_EMPTY(&inodedep->id_bufwait) ||
5061
11949
            !TAILQ_EMPTY(&inodedep->id_extupdt) ||
5062
11950
            !TAILQ_EMPTY(&inodedep->id_newextupdt) ||
5063
11951
            !TAILQ_EMPTY(&inodedep->id_inoupdt) ||
5064
11952
            !TAILQ_EMPTY(&inodedep->id_newinoupdt))
5065
 
                panic("softdep_fsync: pending ops");
 
11953
                panic("softdep_fsync: pending ops %p", inodedep);
5066
11954
        for (error = 0, flushparent = 0; ; ) {
5067
11955
                if ((wk = LIST_FIRST(&inodedep->id_pendinghd)) == NULL)
5068
11956
                        break;
5165
12053
                                        pagedep_new_block = pagedep->pd_state & NEWBLOCK;
5166
12054
                                        FREE_LOCK(&lk);
5167
12055
                                        locked = 0;
5168
 
                                        if (pagedep_new_block &&
5169
 
                                            (error = ffs_syncvnode(pvp, MNT_WAIT))) {
 
12056
                                        if (pagedep_new_block && (error =
 
12057
                                            ffs_syncvnode(pvp, MNT_WAIT, 0))) {
5170
12058
                                                vput(pvp);
5171
12059
                                                return (error);
5172
12060
                                        }
5199
12087
 * Flush all the dirty bitmaps associated with the block device
5200
12088
 * before flushing the rest of the dirty blocks so as to reduce
5201
12089
 * the number of dependencies that will have to be rolled back.
 
12090
 *
 
12091
 * XXX Unused?
5202
12092
 */
5203
12093
void
5204
12094
softdep_fsync_mountdev(vp)
5245
12135
}
5246
12136
 
5247
12137
/*
 
12138
 * Sync all cylinder groups that were dirty at the time this function is
 
12139
 * called.  Newly dirtied cgs will be inserted before the sentinel.  This
 
12140
 * is used to flush freedep activity that may be holding up writes to a
 
12141
 * indirect block.
 
12142
 */
 
12143
static int
 
12144
sync_cgs(mp, waitfor)
 
12145
        struct mount *mp;
 
12146
        int waitfor;
 
12147
{
 
12148
        struct bmsafemap *bmsafemap;
 
12149
        struct bmsafemap *sentinel;
 
12150
        struct ufsmount *ump;
 
12151
        struct buf *bp;
 
12152
        int error;
 
12153
 
 
12154
        sentinel = malloc(sizeof(*sentinel), M_BMSAFEMAP, M_ZERO | M_WAITOK);
 
12155
        sentinel->sm_cg = -1;
 
12156
        ump = VFSTOUFS(mp);
 
12157
        error = 0;
 
12158
        ACQUIRE_LOCK(&lk);
 
12159
        LIST_INSERT_HEAD(&ump->softdep_dirtycg, sentinel, sm_next);
 
12160
        for (bmsafemap = LIST_NEXT(sentinel, sm_next); bmsafemap != NULL;
 
12161
            bmsafemap = LIST_NEXT(sentinel, sm_next)) {
 
12162
                /* Skip sentinels and cgs with no work to release. */
 
12163
                if (bmsafemap->sm_cg == -1 ||
 
12164
                    (LIST_EMPTY(&bmsafemap->sm_freehd) &&
 
12165
                    LIST_EMPTY(&bmsafemap->sm_freewr))) {
 
12166
                        LIST_REMOVE(sentinel, sm_next);
 
12167
                        LIST_INSERT_AFTER(bmsafemap, sentinel, sm_next);
 
12168
                        continue;
 
12169
                }
 
12170
                /*
 
12171
                 * If we don't get the lock and we're waiting try again, if
 
12172
                 * not move on to the next buf and try to sync it.
 
12173
                 */
 
12174
                bp = getdirtybuf(bmsafemap->sm_buf, &lk, waitfor);
 
12175
                if (bp == NULL && waitfor == MNT_WAIT)
 
12176
                        continue;
 
12177
                LIST_REMOVE(sentinel, sm_next);
 
12178
                LIST_INSERT_AFTER(bmsafemap, sentinel, sm_next);
 
12179
                if (bp == NULL)
 
12180
                        continue;
 
12181
                FREE_LOCK(&lk);
 
12182
                if (waitfor == MNT_NOWAIT)
 
12183
                        bawrite(bp);
 
12184
                else
 
12185
                        error = bwrite(bp);
 
12186
                ACQUIRE_LOCK(&lk);
 
12187
                if (error)
 
12188
                        break;
 
12189
        }
 
12190
        LIST_REMOVE(sentinel, sm_next);
 
12191
        FREE_LOCK(&lk);
 
12192
        free(sentinel, M_BMSAFEMAP);
 
12193
        return (error);
 
12194
}
 
12195
 
 
12196
/*
5248
12197
 * This routine is called when we are trying to synchronously flush a
5249
12198
 * file. This routine must eliminate any filesystem metadata dependencies
5250
 
 * so that the syncing routine can succeed by pushing the dirty blocks
5251
 
 * associated with the file. If any I/O errors occur, they are returned.
 
12199
 * so that the syncing routine can succeed.
5252
12200
 */
5253
12201
int
5254
12202
softdep_sync_metadata(struct vnode *vp)
5255
12203
{
 
12204
        int error;
 
12205
 
 
12206
        /*
 
12207
         * Ensure that any direct block dependencies have been cleared,
 
12208
         * truncations are started, and inode references are journaled.
 
12209
         */
 
12210
        ACQUIRE_LOCK(&lk);
 
12211
        /*
 
12212
         * Write all journal records to prevent rollbacks on devvp.
 
12213
         */
 
12214
        if (vp->v_type == VCHR)
 
12215
                softdep_flushjournal(vp->v_mount);
 
12216
        error = flush_inodedep_deps(vp, vp->v_mount, VTOI(vp)->i_number);
 
12217
        /*
 
12218
         * Ensure that all truncates are written so we won't find deps on
 
12219
         * indirect blocks.
 
12220
         */
 
12221
        process_truncates(vp);
 
12222
        FREE_LOCK(&lk);
 
12223
 
 
12224
        return (error);
 
12225
}
 
12226
 
 
12227
/*
 
12228
 * This routine is called when we are attempting to sync a buf with
 
12229
 * dependencies.  If waitfor is MNT_NOWAIT it attempts to schedule any
 
12230
 * other IO it can but returns EBUSY if the buffer is not yet able to
 
12231
 * be written.  Dependencies which will not cause rollbacks will always
 
12232
 * return 0.
 
12233
 */
 
12234
int
 
12235
softdep_sync_buf(struct vnode *vp, struct buf *bp, int waitfor)
 
12236
{
 
12237
        struct indirdep *indirdep;
5256
12238
        struct pagedep *pagedep;
5257
 
        struct allocdirect *adp;
5258
12239
        struct allocindir *aip;
5259
 
        struct buf *bp, *nbp;
 
12240
        struct newblk *newblk;
 
12241
        struct buf *nbp;
5260
12242
        struct worklist *wk;
5261
 
        struct bufobj *bo;
5262
 
        int i, error, waitfor;
5263
 
 
5264
 
        if (!DOINGSOFTDEP(vp))
5265
 
                return (0);
5266
 
        /*
5267
 
         * Ensure that any direct block dependencies have been cleared.
5268
 
         */
5269
 
        ACQUIRE_LOCK(&lk);
5270
 
        if ((error = flush_inodedep_deps(vp->v_mount, VTOI(vp)->i_number))) {
5271
 
                FREE_LOCK(&lk);
5272
 
                return (error);
5273
 
        }
5274
 
        FREE_LOCK(&lk);
5275
 
        /*
5276
 
         * For most files, the only metadata dependencies are the
5277
 
         * cylinder group maps that allocate their inode or blocks.
5278
 
         * The block allocation dependencies can be found by traversing
5279
 
         * the dependency lists for any buffers that remain on their
5280
 
         * dirty buffer list. The inode allocation dependency will
5281
 
         * be resolved when the inode is updated with MNT_WAIT.
5282
 
         * This work is done in two passes. The first pass grabs most
5283
 
         * of the buffers and begins asynchronously writing them. The
5284
 
         * only way to wait for these asynchronous writes is to sleep
5285
 
         * on the filesystem vnode which may stay busy for a long time
5286
 
         * if the filesystem is active. So, instead, we make a second
5287
 
         * pass over the dependencies blocking on each write. In the
5288
 
         * usual case we will be blocking against a write that we
5289
 
         * initiated, so when it is done the dependency will have been
5290
 
         * resolved. Thus the second pass is expected to end quickly.
5291
 
         */
5292
 
        waitfor = MNT_NOWAIT;
5293
 
        bo = &vp->v_bufobj;
5294
 
 
5295
 
top:
5296
 
        /*
5297
 
         * We must wait for any I/O in progress to finish so that
5298
 
         * all potential buffers on the dirty list will be visible.
5299
 
         */
5300
 
        BO_LOCK(bo);
5301
 
        drain_output(vp);
5302
 
        while ((bp = TAILQ_FIRST(&bo->bo_dirty.bv_hd)) != NULL) {
5303
 
                bp = getdirtybuf(bp, BO_MTX(bo), MNT_WAIT);
5304
 
                if (bp)
5305
 
                        break;
5306
 
        }
5307
 
        BO_UNLOCK(bo);
5308
 
        if (bp == NULL)
5309
 
                return (0);
5310
 
loop:
5311
 
        /* While syncing snapshots, we must allow recursive lookups */
5312
 
        BUF_AREC(bp);
 
12243
        int i, error;
 
12244
 
 
12245
        /*
 
12246
         * For VCHR we just don't want to force flush any dependencies that
 
12247
         * will cause rollbacks.
 
12248
         */
 
12249
        if (vp->v_type == VCHR) {
 
12250
                if (waitfor == MNT_NOWAIT && softdep_count_dependencies(bp, 0))
 
12251
                        return (EBUSY);
 
12252
                return (0);
 
12253
        }
5313
12254
        ACQUIRE_LOCK(&lk);
5314
12255
        /*
5315
12256
         * As we hold the buffer locked, none of its dependencies
5316
12257
         * will disappear.
5317
12258
         */
 
12259
        error = 0;
 
12260
top:
5318
12261
        LIST_FOREACH(wk, &bp->b_dep, wk_list) {
5319
12262
                switch (wk->wk_type) {
5320
12263
 
5321
12264
                case D_ALLOCDIRECT:
5322
 
                        adp = WK_ALLOCDIRECT(wk);
5323
 
                        if (adp->ad_state & DEPCOMPLETE)
5324
 
                                continue;
5325
 
                        nbp = adp->ad_buf;
5326
 
                        nbp = getdirtybuf(nbp, &lk, waitfor);
5327
 
                        if (nbp == NULL)
5328
 
                                continue;
5329
 
                        FREE_LOCK(&lk);
5330
 
                        if (waitfor == MNT_NOWAIT) {
5331
 
                                bawrite(nbp);
5332
 
                        } else if ((error = bwrite(nbp)) != 0) {
5333
 
                                break;
5334
 
                        }
5335
 
                        ACQUIRE_LOCK(&lk);
5336
 
                        continue;
5337
 
 
5338
12265
                case D_ALLOCINDIR:
5339
 
                        aip = WK_ALLOCINDIR(wk);
5340
 
                        if (aip->ai_state & DEPCOMPLETE)
 
12266
                        newblk = WK_NEWBLK(wk);
 
12267
                        if (newblk->nb_jnewblk != NULL) {
 
12268
                                if (waitfor == MNT_NOWAIT) {
 
12269
                                        error = EBUSY;
 
12270
                                        goto out_unlock;
 
12271
                                }
 
12272
                                jwait(&newblk->nb_jnewblk->jn_list, waitfor);
 
12273
                                goto top;
 
12274
                        }
 
12275
                        if (newblk->nb_state & DEPCOMPLETE ||
 
12276
                            waitfor == MNT_NOWAIT)
5341
12277
                                continue;
5342
 
                        nbp = aip->ai_buf;
 
12278
                        nbp = newblk->nb_bmsafemap->sm_buf;
5343
12279
                        nbp = getdirtybuf(nbp, &lk, waitfor);
5344
12280
                        if (nbp == NULL)
5345
 
                                continue;
 
12281
                                goto top;
5346
12282
                        FREE_LOCK(&lk);
5347
 
                        if (waitfor == MNT_NOWAIT) {
5348
 
                                bawrite(nbp);
5349
 
                        } else if ((error = bwrite(nbp)) != 0) {
5350
 
                                break;
5351
 
                        }
 
12283
                        if ((error = bwrite(nbp)) != 0)
 
12284
                                goto out;
5352
12285
                        ACQUIRE_LOCK(&lk);
5353
12286
                        continue;
5354
12287
 
5355
12288
                case D_INDIRDEP:
 
12289
                        indirdep = WK_INDIRDEP(wk);
 
12290
                        if (waitfor == MNT_NOWAIT) {
 
12291
                                if (!TAILQ_EMPTY(&indirdep->ir_trunc) ||
 
12292
                                    !LIST_EMPTY(&indirdep->ir_deplisthd)) {
 
12293
                                        error = EBUSY;
 
12294
                                        goto out_unlock;
 
12295
                                }
 
12296
                        }
 
12297
                        if (!TAILQ_EMPTY(&indirdep->ir_trunc))
 
12298
                                panic("softdep_sync_buf: truncation pending.");
5356
12299
                restart:
5357
 
 
5358
 
                        LIST_FOREACH(aip, &WK_INDIRDEP(wk)->ir_deplisthd, ai_next) {
5359
 
                                if (aip->ai_state & DEPCOMPLETE)
 
12300
                        LIST_FOREACH(aip, &indirdep->ir_deplisthd, ai_next) {
 
12301
                                newblk = (struct newblk *)aip;
 
12302
                                if (newblk->nb_jnewblk != NULL) {
 
12303
                                        jwait(&newblk->nb_jnewblk->jn_list,
 
12304
                                            waitfor);
 
12305
                                        goto restart;
 
12306
                                }
 
12307
                                if (newblk->nb_state & DEPCOMPLETE)
5360
12308
                                        continue;
5361
 
                                nbp = aip->ai_buf;
5362
 
                                nbp = getdirtybuf(nbp, &lk, MNT_WAIT);
 
12309
                                nbp = newblk->nb_bmsafemap->sm_buf;
 
12310
                                nbp = getdirtybuf(nbp, &lk, waitfor);
5363
12311
                                if (nbp == NULL)
5364
12312
                                        goto restart;
5365
12313
                                FREE_LOCK(&lk);
5366
 
                                if ((error = bwrite(nbp)) != 0) {
5367
 
                                        goto loop_end;
5368
 
                                }
 
12314
                                if ((error = bwrite(nbp)) != 0)
 
12315
                                        goto out;
5369
12316
                                ACQUIRE_LOCK(&lk);
5370
12317
                                goto restart;
5371
12318
                        }
5372
12319
                        continue;
5373
12320
 
5374
 
                case D_INODEDEP:
5375
 
                        if ((error = flush_inodedep_deps(wk->wk_mp,
5376
 
                            WK_INODEDEP(wk)->id_ino)) != 0) {
5377
 
                                FREE_LOCK(&lk);
5378
 
                                break;
5379
 
                        }
5380
 
                        continue;
5381
 
 
5382
12321
                case D_PAGEDEP:
5383
12322
                        /*
 
12323
                         * Only flush directory entries in synchronous passes.
 
12324
                         */
 
12325
                        if (waitfor != MNT_WAIT) {
 
12326
                                error = EBUSY;
 
12327
                                goto out_unlock;
 
12328
                        }
 
12329
                        /*
 
12330
                         * While syncing snapshots, we must allow recursive
 
12331
                         * lookups.
 
12332
                         */
 
12333
                        BUF_AREC(bp);
 
12334
                        /*
5384
12335
                         * We are trying to sync a directory that may
5385
12336
                         * have dependencies on both its own metadata
5386
12337
                         * and/or dependencies on the inodes of any
5391
12342
                        for (i = 0; i < DAHASHSZ; i++) {
5392
12343
                                if (LIST_FIRST(&pagedep->pd_diraddhd[i]) == 0)
5393
12344
                                        continue;
5394
 
                                if ((error =
5395
 
                                    flush_pagedep_deps(vp, wk->wk_mp,
5396
 
                                                &pagedep->pd_diraddhd[i]))) {
5397
 
                                        FREE_LOCK(&lk);
5398
 
                                        goto loop_end;
 
12345
                                if ((error = flush_pagedep_deps(vp, wk->wk_mp,
 
12346
                                    &pagedep->pd_diraddhd[i]))) {
 
12347
                                        BUF_NOREC(bp);
 
12348
                                        goto out_unlock;
5399
12349
                                }
5400
12350
                        }
5401
 
                        continue;
5402
 
 
5403
 
                case D_MKDIR:
5404
 
                        /*
5405
 
                         * This case should never happen if the vnode has
5406
 
                         * been properly sync'ed. However, if this function
5407
 
                         * is used at a place where the vnode has not yet
5408
 
                         * been sync'ed, this dependency can show up. So,
5409
 
                         * rather than panic, just flush it.
5410
 
                         */
5411
 
                        nbp = WK_MKDIR(wk)->md_buf;
5412
 
                        nbp = getdirtybuf(nbp, &lk, waitfor);
5413
 
                        if (nbp == NULL)
5414
 
                                continue;
5415
 
                        FREE_LOCK(&lk);
5416
 
                        if (waitfor == MNT_NOWAIT) {
5417
 
                                bawrite(nbp);
5418
 
                        } else if ((error = bwrite(nbp)) != 0) {
5419
 
                                break;
5420
 
                        }
5421
 
                        ACQUIRE_LOCK(&lk);
5422
 
                        continue;
5423
 
 
5424
 
                case D_BMSAFEMAP:
5425
 
                        /*
5426
 
                         * This case should never happen if the vnode has
5427
 
                         * been properly sync'ed. However, if this function
5428
 
                         * is used at a place where the vnode has not yet
5429
 
                         * been sync'ed, this dependency can show up. So,
5430
 
                         * rather than panic, just flush it.
5431
 
                         */
5432
 
                        nbp = WK_BMSAFEMAP(wk)->sm_buf;
5433
 
                        nbp = getdirtybuf(nbp, &lk, waitfor);
5434
 
                        if (nbp == NULL)
5435
 
                                continue;
5436
 
                        FREE_LOCK(&lk);
5437
 
                        if (waitfor == MNT_NOWAIT) {
5438
 
                                bawrite(nbp);
5439
 
                        } else if ((error = bwrite(nbp)) != 0) {
5440
 
                                break;
5441
 
                        }
5442
 
                        ACQUIRE_LOCK(&lk);
 
12351
                        BUF_NOREC(bp);
 
12352
                        continue;
 
12353
 
 
12354
                case D_FREEWORK:
 
12355
                case D_FREEDEP:
 
12356
                case D_JSEGDEP:
 
12357
                case D_JNEWBLK:
5443
12358
                        continue;
5444
12359
 
5445
12360
                default:
5446
 
                        panic("softdep_sync_metadata: Unknown type %s",
 
12361
                        panic("softdep_sync_buf: Unknown type %s",
5447
12362
                            TYPENAME(wk->wk_type));
5448
12363
                        /* NOTREACHED */
5449
12364
                }
5450
 
        loop_end:
5451
 
                /* We reach here only in error and unlocked */
5452
 
                if (error == 0)
5453
 
                        panic("softdep_sync_metadata: zero error");
5454
 
                BUF_NOREC(bp);
5455
 
                bawrite(bp);
5456
 
                return (error);
5457
12365
        }
 
12366
out_unlock:
5458
12367
        FREE_LOCK(&lk);
5459
 
        BO_LOCK(bo);
5460
 
        while ((nbp = TAILQ_NEXT(bp, b_bobufs)) != NULL) {
5461
 
                nbp = getdirtybuf(nbp, BO_MTX(bo), MNT_WAIT);
5462
 
                if (nbp)
5463
 
                        break;
5464
 
        }
5465
 
        BO_UNLOCK(bo);
5466
 
        BUF_NOREC(bp);
5467
 
        bawrite(bp);
5468
 
        if (nbp != NULL) {
5469
 
                bp = nbp;
5470
 
                goto loop;
5471
 
        }
5472
 
        /*
5473
 
         * The brief unlock is to allow any pent up dependency
5474
 
         * processing to be done. Then proceed with the second pass.
5475
 
         */
5476
 
        if (waitfor == MNT_NOWAIT) {
5477
 
                waitfor = MNT_WAIT;
5478
 
                goto top;
5479
 
        }
5480
 
 
5481
 
        /*
5482
 
         * If we have managed to get rid of all the dirty buffers,
5483
 
         * then we are done. For certain directories and block
5484
 
         * devices, we may need to do further work.
5485
 
         *
5486
 
         * We must wait for any I/O in progress to finish so that
5487
 
         * all potential buffers on the dirty list will be visible.
5488
 
         */
5489
 
        BO_LOCK(bo);
5490
 
        drain_output(vp);
5491
 
        BO_UNLOCK(bo);
5492
 
        return (0);
 
12368
out:
 
12369
        return (error);
5493
12370
}
5494
12371
 
5495
12372
/*
5497
12374
 * Called with splbio blocked.
5498
12375
 */
5499
12376
static int
5500
 
flush_inodedep_deps(mp, ino)
 
12377
flush_inodedep_deps(vp, mp, ino)
 
12378
        struct vnode *vp;
5501
12379
        struct mount *mp;
5502
12380
        ino_t ino;
5503
12381
{
5504
12382
        struct inodedep *inodedep;
 
12383
        struct inoref *inoref;
5505
12384
        int error, waitfor;
5506
12385
 
5507
12386
        /*
5522
12401
                        return (error);
5523
12402
                FREE_LOCK(&lk);
5524
12403
                ACQUIRE_LOCK(&lk);
 
12404
restart:
5525
12405
                if (inodedep_lookup(mp, ino, 0, &inodedep) == 0)
5526
12406
                        return (0);
 
12407
                TAILQ_FOREACH(inoref, &inodedep->id_inoreflst, if_deps) {
 
12408
                        if ((inoref->if_state & (DEPCOMPLETE | GOINGAWAY))
 
12409
                            == DEPCOMPLETE) {
 
12410
                                jwait(&inoref->if_list, MNT_WAIT);
 
12411
                                goto restart;
 
12412
                        }
 
12413
                }
5527
12414
                if (flush_deplist(&inodedep->id_inoupdt, waitfor, &error) ||
5528
12415
                    flush_deplist(&inodedep->id_newinoupdt, waitfor, &error) ||
5529
12416
                    flush_deplist(&inodedep->id_extupdt, waitfor, &error) ||
5555
12442
        int *errorp;
5556
12443
{
5557
12444
        struct allocdirect *adp;
 
12445
        struct newblk *newblk;
5558
12446
        struct buf *bp;
5559
12447
 
5560
12448
        mtx_assert(&lk, MA_OWNED);
5561
12449
        TAILQ_FOREACH(adp, listhead, ad_next) {
5562
 
                if (adp->ad_state & DEPCOMPLETE)
 
12450
                newblk = (struct newblk *)adp;
 
12451
                if (newblk->nb_jnewblk != NULL) {
 
12452
                        jwait(&newblk->nb_jnewblk->jn_list, MNT_WAIT);
 
12453
                        return (1);
 
12454
                }
 
12455
                if (newblk->nb_state & DEPCOMPLETE)
5563
12456
                        continue;
5564
 
                bp = adp->ad_buf;
 
12457
                bp = newblk->nb_bmsafemap->sm_buf;
5565
12458
                bp = getdirtybuf(bp, &lk, waitfor);
5566
12459
                if (bp == NULL) {
5567
12460
                        if (waitfor == MNT_NOWAIT)
5569
12462
                        return (1);
5570
12463
                }
5571
12464
                FREE_LOCK(&lk);
5572
 
                if (waitfor == MNT_NOWAIT) {
 
12465
                if (waitfor == MNT_NOWAIT)
5573
12466
                        bawrite(bp);
5574
 
                } else if ((*errorp = bwrite(bp)) != 0) {
5575
 
                        ACQUIRE_LOCK(&lk);
5576
 
                        return (1);
5577
 
                }
 
12467
                else 
 
12468
                        *errorp = bwrite(bp);
5578
12469
                ACQUIRE_LOCK(&lk);
5579
12470
                return (1);
5580
12471
        }
5582
12473
}
5583
12474
 
5584
12475
/*
 
12476
 * Flush dependencies associated with an allocdirect block.
 
12477
 */
 
12478
static int
 
12479
flush_newblk_dep(vp, mp, lbn)
 
12480
        struct vnode *vp;
 
12481
        struct mount *mp;
 
12482
        ufs_lbn_t lbn;
 
12483
{
 
12484
        struct newblk *newblk;
 
12485
        struct bufobj *bo;
 
12486
        struct inode *ip;
 
12487
        struct buf *bp;
 
12488
        ufs2_daddr_t blkno;
 
12489
        int error;
 
12490
 
 
12491
        error = 0;
 
12492
        bo = &vp->v_bufobj;
 
12493
        ip = VTOI(vp);
 
12494
        blkno = DIP(ip, i_db[lbn]);
 
12495
        if (blkno == 0)
 
12496
                panic("flush_newblk_dep: Missing block");
 
12497
        ACQUIRE_LOCK(&lk);
 
12498
        /*
 
12499
         * Loop until all dependencies related to this block are satisfied.
 
12500
         * We must be careful to restart after each sleep in case a write
 
12501
         * completes some part of this process for us.
 
12502
         */
 
12503
        for (;;) {
 
12504
                if (newblk_lookup(mp, blkno, 0, &newblk) == 0) {
 
12505
                        FREE_LOCK(&lk);
 
12506
                        break;
 
12507
                }
 
12508
                if (newblk->nb_list.wk_type != D_ALLOCDIRECT)
 
12509
                        panic("flush_newblk_deps: Bad newblk %p", newblk);
 
12510
                /*
 
12511
                 * Flush the journal.
 
12512
                 */
 
12513
                if (newblk->nb_jnewblk != NULL) {
 
12514
                        jwait(&newblk->nb_jnewblk->jn_list, MNT_WAIT);
 
12515
                        continue;
 
12516
                }
 
12517
                /*
 
12518
                 * Write the bitmap dependency.
 
12519
                 */
 
12520
                if ((newblk->nb_state & DEPCOMPLETE) == 0) {
 
12521
                        bp = newblk->nb_bmsafemap->sm_buf;
 
12522
                        bp = getdirtybuf(bp, &lk, MNT_WAIT);
 
12523
                        if (bp == NULL)
 
12524
                                continue;
 
12525
                        FREE_LOCK(&lk);
 
12526
                        error = bwrite(bp);
 
12527
                        if (error)
 
12528
                                break;
 
12529
                        ACQUIRE_LOCK(&lk);
 
12530
                        continue;
 
12531
                }
 
12532
                /*
 
12533
                 * Write the buffer.
 
12534
                 */
 
12535
                FREE_LOCK(&lk);
 
12536
                BO_LOCK(bo);
 
12537
                bp = gbincore(bo, lbn);
 
12538
                if (bp != NULL) {
 
12539
                        error = BUF_LOCK(bp, LK_EXCLUSIVE | LK_SLEEPFAIL |
 
12540
                            LK_INTERLOCK, BO_MTX(bo));
 
12541
                        if (error == ENOLCK) {
 
12542
                                ACQUIRE_LOCK(&lk);
 
12543
                                continue; /* Slept, retry */
 
12544
                        }
 
12545
                        if (error != 0)
 
12546
                                break;  /* Failed */
 
12547
                        if (bp->b_flags & B_DELWRI) {
 
12548
                                bremfree(bp);
 
12549
                                error = bwrite(bp);
 
12550
                                if (error)
 
12551
                                        break;
 
12552
                        } else
 
12553
                                BUF_UNLOCK(bp);
 
12554
                } else
 
12555
                        BO_UNLOCK(bo);
 
12556
                /*
 
12557
                 * We have to wait for the direct pointers to
 
12558
                 * point at the newdirblk before the dependency
 
12559
                 * will go away.
 
12560
                 */
 
12561
                error = ffs_update(vp, 1);
 
12562
                if (error)
 
12563
                        break;
 
12564
                ACQUIRE_LOCK(&lk);
 
12565
        }
 
12566
        return (error);
 
12567
}
 
12568
 
 
12569
/*
5585
12570
 * Eliminate a pagedep dependency by flushing out all its diradd dependencies.
5586
12571
 * Called with splbio blocked.
5587
12572
 */
5592
12577
        struct diraddhd *diraddhdp;
5593
12578
{
5594
12579
        struct inodedep *inodedep;
 
12580
        struct inoref *inoref;
5595
12581
        struct ufsmount *ump;
5596
12582
        struct diradd *dap;
5597
12583
        struct vnode *vp;
5598
 
        struct bufobj *bo;
5599
12584
        int error = 0;
5600
12585
        struct buf *bp;
5601
12586
        ino_t inum;
5602
 
        struct worklist *wk;
5603
12587
 
5604
12588
        ump = VFSTOUFS(mp);
 
12589
restart:
5605
12590
        while ((dap = LIST_FIRST(diraddhdp)) != NULL) {
5606
12591
                /*
5607
12592
                 * Flush ourselves if this directory entry
5623
12608
                /*
5624
12609
                 * A newly allocated directory must have its "." and
5625
12610
                 * ".." entries written out before its name can be
5626
 
                 * committed in its parent. We do not want or need
5627
 
                 * the full semantics of a synchronous ffs_syncvnode as
5628
 
                 * that may end up here again, once for each directory
5629
 
                 * level in the filesystem. Instead, we push the blocks
5630
 
                 * and wait for them to clear. We have to fsync twice
5631
 
                 * because the first call may choose to defer blocks
5632
 
                 * that still have dependencies, but deferral will
5633
 
                 * happen at most once.
 
12611
                 * committed in its parent. 
5634
12612
                 */
5635
12613
                inum = dap->da_newinum;
 
12614
                if (inodedep_lookup(UFSTOVFS(ump), inum, 0, &inodedep) == 0)
 
12615
                        panic("flush_pagedep_deps: lost inode1");
 
12616
                /*
 
12617
                 * Wait for any pending journal adds to complete so we don't
 
12618
                 * cause rollbacks while syncing.
 
12619
                 */
 
12620
                TAILQ_FOREACH(inoref, &inodedep->id_inoreflst, if_deps) {
 
12621
                        if ((inoref->if_state & (DEPCOMPLETE | GOINGAWAY))
 
12622
                            == DEPCOMPLETE) {
 
12623
                                jwait(&inoref->if_list, MNT_WAIT);
 
12624
                                goto restart;
 
12625
                        }
 
12626
                }
5636
12627
                if (dap->da_state & MKDIR_BODY) {
5637
12628
                        FREE_LOCK(&lk);
5638
12629
                        if ((error = ffs_vgetf(mp, inum, LK_EXCLUSIVE, &vp,
5639
12630
                            FFSV_FORCEINSMQ)))
5640
12631
                                break;
5641
 
                        if ((error=ffs_syncvnode(vp, MNT_NOWAIT)) ||
5642
 
                            (error=ffs_syncvnode(vp, MNT_NOWAIT))) {
5643
 
                                vput(vp);
5644
 
                                break;
5645
 
                        }
5646
 
                        bo = &vp->v_bufobj;
5647
 
                        BO_LOCK(bo);
5648
 
                        drain_output(vp);
 
12632
                        error = flush_newblk_dep(vp, mp, 0);
5649
12633
                        /*
5650
 
                         * If first block is still dirty with a D_MKDIR
5651
 
                         * dependency then it needs to be written now.
 
12634
                         * If we still have the dependency we might need to
 
12635
                         * update the vnode to sync the new link count to
 
12636
                         * disk.
5652
12637
                         */
5653
 
                        for (;;) {
5654
 
                                error = 0;
5655
 
                                bp = gbincore(bo, 0);
5656
 
                                if (bp == NULL)
5657
 
                                        break;  /* First block not present */
5658
 
                                error = BUF_LOCK(bp,
5659
 
                                                 LK_EXCLUSIVE |
5660
 
                                                 LK_SLEEPFAIL |
5661
 
                                                 LK_INTERLOCK,
5662
 
                                                 BO_MTX(bo));
5663
 
                                BO_LOCK(bo);
5664
 
                                if (error == ENOLCK)
5665
 
                                        continue;       /* Slept, retry */
5666
 
                                if (error != 0)
5667
 
                                        break;          /* Failed */
5668
 
                                if ((bp->b_flags & B_DELWRI) == 0) {
5669
 
                                        BUF_UNLOCK(bp);
5670
 
                                        break;  /* Buffer not dirty */
5671
 
                                }
5672
 
                                for (wk = LIST_FIRST(&bp->b_dep);
5673
 
                                     wk != NULL;
5674
 
                                     wk = LIST_NEXT(wk, wk_list))
5675
 
                                        if (wk->wk_type == D_MKDIR)
5676
 
                                                break;
5677
 
                                if (wk == NULL)
5678
 
                                        BUF_UNLOCK(bp); /* Dependency gone */
5679
 
                                else {
5680
 
                                        /*
5681
 
                                         * D_MKDIR dependency remains,
5682
 
                                         * must write buffer to stable
5683
 
                                         * storage.
5684
 
                                         */
5685
 
                                        BO_UNLOCK(bo);
5686
 
                                        bremfree(bp);
5687
 
                                        error = bwrite(bp);
5688
 
                                        BO_LOCK(bo);
5689
 
                                }
5690
 
                                break;
5691
 
                        }
5692
 
                        BO_UNLOCK(bo);
 
12638
                        if (error == 0 && dap == LIST_FIRST(diraddhdp))
 
12639
                                error = ffs_update(vp, 1);
5693
12640
                        vput(vp);
5694
12641
                        if (error != 0)
5695
 
                                break;  /* Flushing of first block failed */
 
12642
                                break;
5696
12643
                        ACQUIRE_LOCK(&lk);
5697
12644
                        /*
5698
12645
                         * If that cleared dependencies, go on to next.
5699
12646
                         */
5700
12647
                        if (dap != LIST_FIRST(diraddhdp))
5701
12648
                                continue;
5702
 
                        if (dap->da_state & MKDIR_BODY)
5703
 
                                panic("flush_pagedep_deps: MKDIR_BODY");
 
12649
                        if (dap->da_state & MKDIR_BODY) {
 
12650
                                inodedep_lookup(UFSTOVFS(ump), inum, 0,
 
12651
                                    &inodedep);
 
12652
                                panic("flush_pagedep_deps: MKDIR_BODY "
 
12653
                                    "inodedep %p dap %p vp %p",
 
12654
                                    inodedep, dap, vp);
 
12655
                        }
5704
12656
                }
5705
12657
                /*
5706
12658
                 * Flush the inode on which the directory entry depends.
5719
12671
                 * If the inode still has bitmap dependencies,
5720
12672
                 * push them to disk.
5721
12673
                 */
5722
 
                if ((inodedep->id_state & DEPCOMPLETE) == 0) {
5723
 
                        bp = inodedep->id_buf;
 
12674
                if ((inodedep->id_state & (DEPCOMPLETE | GOINGAWAY)) == 0) {
 
12675
                        bp = inodedep->id_bmsafemap->sm_buf;
5724
12676
                        bp = getdirtybuf(bp, &lk, MNT_WAIT);
5725
12677
                        if (bp == NULL)
5726
12678
                                goto retry;
5733
12685
                }
5734
12686
                /*
5735
12687
                 * If the inode is still sitting in a buffer waiting
5736
 
                 * to be written, push it to disk.
 
12688
                 * to be written or waiting for the link count to be
 
12689
                 * adjusted update it here to flush it to disk.
5737
12690
                 */
5738
 
                FREE_LOCK(&lk);
5739
 
                if ((error = bread(ump->um_devvp,
5740
 
                    fsbtodb(ump->um_fs, ino_to_fsba(ump->um_fs, inum)),
5741
 
                    (int)ump->um_fs->fs_bsize, NOCRED, &bp)) != 0) {
5742
 
                        brelse(bp);
5743
 
                        break;
 
12691
                if (dap == LIST_FIRST(diraddhdp)) {
 
12692
                        FREE_LOCK(&lk);
 
12693
                        if ((error = ffs_vgetf(mp, inum, LK_EXCLUSIVE, &vp,
 
12694
                            FFSV_FORCEINSMQ)))
 
12695
                                break;
 
12696
                        error = ffs_update(vp, 1);
 
12697
                        vput(vp);
 
12698
                        if (error)
 
12699
                                break;
 
12700
                        ACQUIRE_LOCK(&lk);
5744
12701
                }
5745
 
                if ((error = bwrite(bp)) != 0)
5746
 
                        break;
5747
 
                ACQUIRE_LOCK(&lk);
5748
12702
                /*
5749
12703
                 * If we have failed to get rid of all the dependencies
5750
12704
                 * then something is seriously wrong.
5751
12705
                 */
5752
 
                if (dap == LIST_FIRST(diraddhdp))
5753
 
                        panic("flush_pagedep_deps: flush failed");
 
12706
                if (dap == LIST_FIRST(diraddhdp)) {
 
12707
                        inodedep_lookup(UFSTOVFS(ump), inum, 0, &inodedep);
 
12708
                        panic("flush_pagedep_deps: failed to flush " 
 
12709
                            "inodedep %p ino %d dap %p", inodedep, inum, dap);
 
12710
                }
5754
12711
        }
5755
12712
        if (error)
5756
12713
                ACQUIRE_LOCK(&lk);
5768
12725
softdep_slowdown(vp)
5769
12726
        struct vnode *vp;
5770
12727
{
 
12728
        struct ufsmount *ump;
 
12729
        int jlow;
5771
12730
        int max_softdeps_hard;
5772
12731
 
5773
12732
        ACQUIRE_LOCK(&lk);
 
12733
        jlow = 0;
 
12734
        /*
 
12735
         * Check for journal space if needed.
 
12736
         */
 
12737
        if (DOINGSUJ(vp)) {
 
12738
                ump = VFSTOUFS(vp->v_mount);
 
12739
                if (journal_space(ump, 0) == 0)
 
12740
                        jlow = 1;
 
12741
        }
5774
12742
        max_softdeps_hard = max_softdeps * 11 / 10;
5775
 
        if (num_dirrem < max_softdeps_hard / 2 &&
5776
 
            num_inodedep < max_softdeps_hard &&
 
12743
        if (dep_current[D_DIRREM] < max_softdeps_hard / 2 &&
 
12744
            dep_current[D_INODEDEP] < max_softdeps_hard &&
5777
12745
            VFSTOUFS(vp->v_mount)->um_numindirdeps < maxindirdeps &&
5778
 
            num_freeblkdep < max_softdeps_hard) {
 
12746
            dep_current[D_FREEBLKS] < max_softdeps_hard && jlow == 0) {
5779
12747
                FREE_LOCK(&lk);
5780
12748
                return (0);
5781
12749
        }
5782
 
        if (VFSTOUFS(vp->v_mount)->um_numindirdeps >= maxindirdeps)
 
12750
        if (VFSTOUFS(vp->v_mount)->um_numindirdeps >= maxindirdeps || jlow)
5783
12751
                softdep_speedup();
5784
12752
        stat_sync_limit_hit += 1;
5785
12753
        FREE_LOCK(&lk);
 
12754
        if (DOINGSUJ(vp))
 
12755
                return (0);
5786
12756
        return (1);
5787
12757
}
5788
12758
 
5789
12759
/*
5790
12760
 * Called by the allocation routines when they are about to fail
5791
 
 * in the hope that we can free up some disk space.
 
12761
 * in the hope that we can free up the requested resource (inodes
 
12762
 * or disk space).
5792
12763
 * 
5793
12764
 * First check to see if the work list has anything on it. If it has,
5794
 
 * clean up entries until we successfully free some space. Because this
5795
 
 * process holds inodes locked, we cannot handle any remove requests
5796
 
 * that might block on a locked inode as that could lead to deadlock.
5797
 
 * If the worklist yields no free space, encourage the syncer daemon
5798
 
 * to help us. In no event will we try for longer than tickdelay seconds.
 
12765
 * clean up entries until we successfully free the requested resource.
 
12766
 * Because this process holds inodes locked, we cannot handle any remove
 
12767
 * requests that might block on a locked inode as that could lead to
 
12768
 * deadlock. If the worklist yields none of the requested resource,
 
12769
 * start syncing out vnodes to free up the needed space.
5799
12770
 */
5800
12771
int
5801
 
softdep_request_cleanup(fs, vp)
 
12772
softdep_request_cleanup(fs, vp, cred, resource)
5802
12773
        struct fs *fs;
5803
12774
        struct vnode *vp;
 
12775
        struct ucred *cred;
 
12776
        int resource;
5804
12777
{
5805
12778
        struct ufsmount *ump;
 
12779
        struct mount *mp;
 
12780
        struct vnode *lvp, *mvp;
5806
12781
        long starttime;
5807
12782
        ufs2_daddr_t needed;
5808
12783
        int error;
5809
12784
 
5810
 
        ump = VTOI(vp)->i_ump;
 
12785
        /*
 
12786
         * If we are being called because of a process doing a
 
12787
         * copy-on-write, then it is not safe to process any
 
12788
         * worklist items as we will recurse into the copyonwrite
 
12789
         * routine.  This will result in an incoherent snapshot.
 
12790
         * If the vnode that we hold is a snapshot, we must avoid
 
12791
         * handling other resources that could cause deadlock.
 
12792
         */
 
12793
        if ((curthread->td_pflags & TDP_COWINPROGRESS) || IS_SNAPSHOT(VTOI(vp)))
 
12794
                return (0);
 
12795
 
 
12796
        if (resource == FLUSH_BLOCKS_WAIT)
 
12797
                stat_cleanup_blkrequests += 1;
 
12798
        else
 
12799
                stat_cleanup_inorequests += 1;
 
12800
 
 
12801
        mp = vp->v_mount;
 
12802
        ump = VFSTOUFS(mp);
5811
12803
        mtx_assert(UFS_MTX(ump), MA_OWNED);
5812
 
        needed = fs->fs_cstotal.cs_nbfree + fs->fs_contigsumsize;
5813
 
        starttime = time_second + tickdelay;
5814
 
        /*
5815
 
         * If we are being called because of a process doing a
5816
 
         * copy-on-write, then it is not safe to update the vnode
5817
 
         * as we may recurse into the copy-on-write routine.
5818
 
         */
5819
 
        if (!(curthread->td_pflags & TDP_COWINPROGRESS)) {
5820
 
                UFS_UNLOCK(ump);
5821
 
                error = ffs_update(vp, 1);
5822
 
                UFS_LOCK(ump);
5823
 
                if (error != 0)
5824
 
                        return (0);
5825
 
        }
5826
 
        while (fs->fs_pendingblocks > 0 && fs->fs_cstotal.cs_nbfree <= needed) {
5827
 
                if (time_second > starttime)
5828
 
                        return (0);
5829
 
                UFS_UNLOCK(ump);
 
12804
        UFS_UNLOCK(ump);
 
12805
        error = ffs_update(vp, 1);
 
12806
        if (error != 0) {
 
12807
                UFS_LOCK(ump);
 
12808
                return (0);
 
12809
        }
 
12810
        /*
 
12811
         * If we are in need of resources, consider pausing for
 
12812
         * tickdelay to give ourselves some breathing room.
 
12813
         */
 
12814
        ACQUIRE_LOCK(&lk);
 
12815
        process_removes(vp);
 
12816
        process_truncates(vp);
 
12817
        request_cleanup(UFSTOVFS(ump), resource);
 
12818
        FREE_LOCK(&lk);
 
12819
        /*
 
12820
         * Now clean up at least as many resources as we will need.
 
12821
         *
 
12822
         * When requested to clean up inodes, the number that are needed
 
12823
         * is set by the number of simultaneous writers (mnt_writeopcount)
 
12824
         * plus a bit of slop (2) in case some more writers show up while
 
12825
         * we are cleaning.
 
12826
         *
 
12827
         * When requested to free up space, the amount of space that
 
12828
         * we need is enough blocks to allocate a full-sized segment
 
12829
         * (fs_contigsumsize). The number of such segments that will
 
12830
         * be needed is set by the number of simultaneous writers
 
12831
         * (mnt_writeopcount) plus a bit of slop (2) in case some more
 
12832
         * writers show up while we are cleaning.
 
12833
         *
 
12834
         * Additionally, if we are unpriviledged and allocating space,
 
12835
         * we need to ensure that we clean up enough blocks to get the
 
12836
         * needed number of blocks over the threshhold of the minimum
 
12837
         * number of blocks required to be kept free by the filesystem
 
12838
         * (fs_minfree).
 
12839
         */
 
12840
        if (resource == FLUSH_INODES_WAIT) {
 
12841
                needed = vp->v_mount->mnt_writeopcount + 2;
 
12842
        } else if (resource == FLUSH_BLOCKS_WAIT) {
 
12843
                needed = (vp->v_mount->mnt_writeopcount + 2) *
 
12844
                    fs->fs_contigsumsize;
 
12845
                if (priv_check_cred(cred, PRIV_VFS_BLOCKRESERVE, 0))
 
12846
                        needed += fragstoblks(fs,
 
12847
                            roundup((fs->fs_dsize * fs->fs_minfree / 100) -
 
12848
                            fs->fs_cstotal.cs_nffree, fs->fs_frag));
 
12849
        } else {
 
12850
                UFS_LOCK(ump);
 
12851
                printf("softdep_request_cleanup: Unknown resource type %d\n",
 
12852
                    resource);
 
12853
                return (0);
 
12854
        }
 
12855
        starttime = time_second;
 
12856
retry:
 
12857
        if ((resource == FLUSH_BLOCKS_WAIT && ump->softdep_on_worklist > 0 &&
 
12858
            fs->fs_cstotal.cs_nbfree <= needed) ||
 
12859
            (resource == FLUSH_INODES_WAIT && fs->fs_pendinginodes > 0 &&
 
12860
            fs->fs_cstotal.cs_nifree <= needed)) {
5830
12861
                ACQUIRE_LOCK(&lk);
5831
12862
                if (ump->softdep_on_worklist > 0 &&
5832
 
                    process_worklist_item(UFSTOVFS(ump), LK_NOWAIT) != -1) {
 
12863
                    process_worklist_item(UFSTOVFS(ump),
 
12864
                    ump->softdep_on_worklist, LK_NOWAIT) != 0)
5833
12865
                        stat_worklist_push += 1;
5834
 
                        FREE_LOCK(&lk);
5835
 
                        UFS_LOCK(ump);
5836
 
                        continue;
5837
 
                }
5838
 
                request_cleanup(UFSTOVFS(ump), FLUSH_REMOVE_WAIT);
5839
12866
                FREE_LOCK(&lk);
5840
 
                UFS_LOCK(ump);
5841
 
        }
 
12867
        }
 
12868
        /*
 
12869
         * If we still need resources and there are no more worklist
 
12870
         * entries to process to obtain them, we have to start flushing
 
12871
         * the dirty vnodes to force the release of additional requests
 
12872
         * to the worklist that we can then process to reap addition
 
12873
         * resources. We walk the vnodes associated with the mount point
 
12874
         * until we get the needed worklist requests that we can reap.
 
12875
         */
 
12876
        if ((resource == FLUSH_BLOCKS_WAIT && 
 
12877
             fs->fs_cstotal.cs_nbfree <= needed) ||
 
12878
            (resource == FLUSH_INODES_WAIT && fs->fs_pendinginodes > 0 &&
 
12879
             fs->fs_cstotal.cs_nifree <= needed)) {
 
12880
                MNT_VNODE_FOREACH_ALL(lvp, mp, mvp) {
 
12881
                        if (TAILQ_FIRST(&lvp->v_bufobj.bo_dirty.bv_hd) == 0) {
 
12882
                                VI_UNLOCK(lvp);
 
12883
                                continue;
 
12884
                        }
 
12885
                        if (vget(lvp, LK_EXCLUSIVE | LK_INTERLOCK | LK_NOWAIT,
 
12886
                            curthread))
 
12887
                                continue;
 
12888
                        if (lvp->v_vflag & VV_NOSYNC) { /* unlinked */
 
12889
                                vput(lvp);
 
12890
                                continue;
 
12891
                        }
 
12892
                        (void) ffs_syncvnode(lvp, MNT_NOWAIT, 0);
 
12893
                        vput(lvp);
 
12894
                }
 
12895
                lvp = ump->um_devvp;
 
12896
                if (vn_lock(lvp, LK_EXCLUSIVE | LK_NOWAIT) == 0) {
 
12897
                        VOP_FSYNC(lvp, MNT_NOWAIT, curthread);
 
12898
                        VOP_UNLOCK(lvp, 0);
 
12899
                }
 
12900
                if (ump->softdep_on_worklist > 0) {
 
12901
                        stat_cleanup_retries += 1;
 
12902
                        goto retry;
 
12903
                }
 
12904
                stat_cleanup_failures += 1;
 
12905
        }
 
12906
        if (time_second - starttime > stat_cleanup_high_delay)
 
12907
                stat_cleanup_high_delay = time_second - starttime;
 
12908
        UFS_LOCK(ump);
5842
12909
        return (1);
5843
12910
}
5844
12911
 
5872
12939
         */
5873
12940
        if (ump->softdep_on_worklist > max_softdeps / 10) {
5874
12941
                td->td_pflags |= TDP_SOFTDEP;
5875
 
                process_worklist_item(mp, LK_NOWAIT);
5876
 
                process_worklist_item(mp, LK_NOWAIT);
 
12942
                process_worklist_item(mp, 2, LK_NOWAIT);
5877
12943
                td->td_pflags &= ~TDP_SOFTDEP;
5878
12944
                stat_worklist_push += 2;
5879
12945
                return(1);
5882
12948
         * Next, we attempt to speed up the syncer process. If that
5883
12949
         * is successful, then we allow the process to continue.
5884
12950
         */
5885
 
        if (softdep_speedup() && resource != FLUSH_REMOVE_WAIT)
 
12951
        if (softdep_speedup() &&
 
12952
            resource != FLUSH_BLOCKS_WAIT &&
 
12953
            resource != FLUSH_INODES_WAIT)
5886
12954
                return(0);
5887
12955
        /*
5888
12956
         * If we are resource constrained on inode dependencies, try
5897
12965
        switch (resource) {
5898
12966
 
5899
12967
        case FLUSH_INODES:
 
12968
        case FLUSH_INODES_WAIT:
5900
12969
                stat_ino_limit_push += 1;
5901
12970
                req_clear_inodedeps += 1;
5902
12971
                stat_countp = &stat_ino_limit_hit;
5903
12972
                break;
5904
12973
 
5905
 
        case FLUSH_REMOVE:
5906
 
        case FLUSH_REMOVE_WAIT:
 
12974
        case FLUSH_BLOCKS:
 
12975
        case FLUSH_BLOCKS_WAIT:
5907
12976
                stat_blk_limit_push += 1;
5908
12977
                req_clear_remove += 1;
5909
12978
                stat_countp = &stat_blk_limit_hit;
5965
13034
 
5966
13035
        mtx_assert(&lk, MA_OWNED);
5967
13036
 
5968
 
        for (cnt = 0; cnt < pagedep_hash; cnt++) {
 
13037
        for (cnt = 0; cnt <= pagedep_hash; cnt++) {
5969
13038
                pagedephd = &pagedep_hashtbl[next++];
5970
 
                if (next >= pagedep_hash)
 
13039
                if (next > pagedep_hash)
5971
13040
                        next = 0;
5972
13041
                LIST_FOREACH(pagedep, pagedephd, pd_hash) {
5973
13042
                        if (LIST_EMPTY(&pagedep->pd_dirremhd))
5991
13060
                                softdep_error("clear_remove: vget", error);
5992
13061
                                goto finish_write;
5993
13062
                        }
5994
 
                        if ((error = ffs_syncvnode(vp, MNT_NOWAIT)))
 
13063
                        if ((error = ffs_syncvnode(vp, MNT_NOWAIT, 0)))
5995
13064
                                softdep_error("clear_remove: fsync", error);
5996
13065
                        bo = &vp->v_bufobj;
5997
13066
                        BO_LOCK(bo);
6029
13098
         * We will then gather up all the inodes in its block 
6030
13099
         * that have dependencies and flush them out.
6031
13100
         */
6032
 
        for (cnt = 0; cnt < inodedep_hash; cnt++) {
 
13101
        for (cnt = 0; cnt <= inodedep_hash; cnt++) {
6033
13102
                inodedephd = &inodedep_hashtbl[next++];
6034
 
                if (next >= inodedep_hash)
 
13103
                if (next > inodedep_hash)
6035
13104
                        next = 0;
6036
13105
                if ((inodedep = LIST_FIRST(inodedephd)) != NULL)
6037
13106
                        break;
6074
13143
                }
6075
13144
                vfs_unbusy(mp);
6076
13145
                if (ino == lastino) {
6077
 
                        if ((error = ffs_syncvnode(vp, MNT_WAIT)))
 
13146
                        if ((error = ffs_syncvnode(vp, MNT_WAIT, 0)))
6078
13147
                                softdep_error("clear_inodedeps: fsync1", error);
6079
13148
                } else {
6080
 
                        if ((error = ffs_syncvnode(vp, MNT_NOWAIT)))
 
13149
                        if ((error = ffs_syncvnode(vp, MNT_NOWAIT, 0)))
6081
13150
                                softdep_error("clear_inodedeps: fsync2", error);
6082
13151
                        BO_LOCK(&vp->v_bufobj);
6083
13152
                        drain_output(vp);
6089
13158
        }
6090
13159
}
6091
13160
 
 
13161
void
 
13162
softdep_buf_append(bp, wkhd)
 
13163
        struct buf *bp;
 
13164
        struct workhead *wkhd;
 
13165
{
 
13166
        struct worklist *wk;
 
13167
 
 
13168
        ACQUIRE_LOCK(&lk);
 
13169
        while ((wk = LIST_FIRST(wkhd)) != NULL) {
 
13170
                WORKLIST_REMOVE(wk);
 
13171
                WORKLIST_INSERT(&bp->b_dep, wk);
 
13172
        }
 
13173
        FREE_LOCK(&lk);
 
13174
 
 
13175
}
 
13176
 
 
13177
void
 
13178
softdep_inode_append(ip, cred, wkhd)
 
13179
        struct inode *ip;
 
13180
        struct ucred *cred;
 
13181
        struct workhead *wkhd;
 
13182
{
 
13183
        struct buf *bp;
 
13184
        struct fs *fs;
 
13185
        int error;
 
13186
 
 
13187
        fs = ip->i_fs;
 
13188
        error = bread(ip->i_devvp, fsbtodb(fs, ino_to_fsba(fs, ip->i_number)),
 
13189
            (int)fs->fs_bsize, cred, &bp);
 
13190
        if (error) {
 
13191
                bqrelse(bp);
 
13192
                softdep_freework(wkhd);
 
13193
                return;
 
13194
        }
 
13195
        softdep_buf_append(bp, wkhd);
 
13196
        bqrelse(bp);
 
13197
}
 
13198
 
 
13199
void
 
13200
softdep_freework(wkhd)
 
13201
        struct workhead *wkhd;
 
13202
{
 
13203
 
 
13204
        ACQUIRE_LOCK(&lk);
 
13205
        handle_jwork(wkhd);
 
13206
        FREE_LOCK(&lk);
 
13207
}
 
13208
 
6092
13209
/*
6093
13210
 * Function to determine if the buffer has outstanding dependencies
6094
13211
 * that will cause a roll-back if the buffer is written. If wantcount
6100
13217
        int wantcount;
6101
13218
{
6102
13219
        struct worklist *wk;
 
13220
        struct bmsafemap *bmsafemap;
 
13221
        struct freework *freework;
6103
13222
        struct inodedep *inodedep;
6104
13223
        struct indirdep *indirdep;
 
13224
        struct freeblks *freeblks;
6105
13225
        struct allocindir *aip;
6106
13226
        struct pagedep *pagedep;
 
13227
        struct dirrem *dirrem;
 
13228
        struct newblk *newblk;
 
13229
        struct mkdir *mkdir;
6107
13230
        struct diradd *dap;
6108
13231
        int i, retval;
6109
13232
 
6132
13255
                                if (!wantcount)
6133
13256
                                        goto out;
6134
13257
                        }
 
13258
                        if (TAILQ_FIRST(&inodedep->id_inoreflst)) {
 
13259
                                /* Add reference dependency. */
 
13260
                                retval += 1;
 
13261
                                if (!wantcount)
 
13262
                                        goto out;
 
13263
                        }
6135
13264
                        continue;
6136
13265
 
6137
13266
                case D_INDIRDEP:
6138
13267
                        indirdep = WK_INDIRDEP(wk);
6139
13268
 
 
13269
                        TAILQ_FOREACH(freework, &indirdep->ir_trunc, fw_next) {
 
13270
                                /* indirect truncation dependency */
 
13271
                                retval += 1;
 
13272
                                if (!wantcount)
 
13273
                                        goto out;
 
13274
                        }
 
13275
 
6140
13276
                        LIST_FOREACH(aip, &indirdep->ir_deplisthd, ai_next) {
6141
13277
                                /* indirect block pointer dependency */
6142
13278
                                retval += 1;
6147
13283
 
6148
13284
                case D_PAGEDEP:
6149
13285
                        pagedep = WK_PAGEDEP(wk);
 
13286
                        LIST_FOREACH(dirrem, &pagedep->pd_dirremhd, dm_next) {
 
13287
                                if (LIST_FIRST(&dirrem->dm_jremrefhd)) {
 
13288
                                        /* Journal remove ref dependency. */
 
13289
                                        retval += 1;
 
13290
                                        if (!wantcount)
 
13291
                                                goto out;
 
13292
                                }
 
13293
                        }
6150
13294
                        for (i = 0; i < DAHASHSZ; i++) {
6151
13295
 
6152
13296
                                LIST_FOREACH(dap, &pagedep->pd_diraddhd[i], da_pdlist) {
6159
13303
                        continue;
6160
13304
 
6161
13305
                case D_BMSAFEMAP:
 
13306
                        bmsafemap = WK_BMSAFEMAP(wk);
 
13307
                        if (LIST_FIRST(&bmsafemap->sm_jaddrefhd)) {
 
13308
                                /* Add reference dependency. */
 
13309
                                retval += 1;
 
13310
                                if (!wantcount)
 
13311
                                        goto out;
 
13312
                        }
 
13313
                        if (LIST_FIRST(&bmsafemap->sm_jnewblkhd)) {
 
13314
                                /* Allocate block dependency. */
 
13315
                                retval += 1;
 
13316
                                if (!wantcount)
 
13317
                                        goto out;
 
13318
                        }
 
13319
                        continue;
 
13320
 
 
13321
                case D_FREEBLKS:
 
13322
                        freeblks = WK_FREEBLKS(wk);
 
13323
                        if (LIST_FIRST(&freeblks->fb_jblkdephd)) {
 
13324
                                /* Freeblk journal dependency. */
 
13325
                                retval += 1;
 
13326
                                if (!wantcount)
 
13327
                                        goto out;
 
13328
                        }
 
13329
                        continue;
 
13330
 
6162
13331
                case D_ALLOCDIRECT:
6163
13332
                case D_ALLOCINDIR:
 
13333
                        newblk = WK_NEWBLK(wk);
 
13334
                        if (newblk->nb_jnewblk) {
 
13335
                                /* Journal allocate dependency. */
 
13336
                                retval += 1;
 
13337
                                if (!wantcount)
 
13338
                                        goto out;
 
13339
                        }
 
13340
                        continue;
 
13341
 
6164
13342
                case D_MKDIR:
 
13343
                        mkdir = WK_MKDIR(wk);
 
13344
                        if (mkdir->md_jaddref) {
 
13345
                                /* Journal reference dependency. */
 
13346
                                retval += 1;
 
13347
                                if (!wantcount)
 
13348
                                        goto out;
 
13349
                        }
 
13350
                        continue;
 
13351
 
 
13352
                case D_FREEWORK:
 
13353
                case D_FREEDEP:
 
13354
                case D_JSEGDEP:
 
13355
                case D_JSEG:
 
13356
                case D_SBDEP:
6165
13357
                        /* never a dependency on these blocks */
6166
13358
                        continue;
6167
13359
 
6168
13360
                default:
6169
 
                        panic("softdep_check_for_rollback: Unexpected type %s",
 
13361
                        panic("softdep_count_dependencies: Unexpected type %s",
6170
13362
                            TYPENAME(wk->wk_type));
6171
13363
                        /* NOTREACHED */
6172
13364
                }
6382
13574
 
6383
13575
#ifdef DDB
6384
13576
 
 
13577
static void
 
13578
inodedep_print(struct inodedep *inodedep, int verbose)
 
13579
{
 
13580
        db_printf("%p fs %p st %x ino %jd inoblk %jd delta %d nlink %d"
 
13581
            " saveino %p\n",
 
13582
            inodedep, inodedep->id_fs, inodedep->id_state,
 
13583
            (intmax_t)inodedep->id_ino,
 
13584
            (intmax_t)fsbtodb(inodedep->id_fs,
 
13585
            ino_to_fsba(inodedep->id_fs, inodedep->id_ino)),
 
13586
            inodedep->id_nlinkdelta, inodedep->id_savednlink,
 
13587
            inodedep->id_savedino1);
 
13588
 
 
13589
        if (verbose == 0)
 
13590
                return;
 
13591
 
 
13592
        db_printf("\tpendinghd %p, bufwait %p, inowait %p, inoreflst %p, "
 
13593
            "mkdiradd %p\n",
 
13594
            LIST_FIRST(&inodedep->id_pendinghd),
 
13595
            LIST_FIRST(&inodedep->id_bufwait),
 
13596
            LIST_FIRST(&inodedep->id_inowait),
 
13597
            TAILQ_FIRST(&inodedep->id_inoreflst),
 
13598
            inodedep->id_mkdiradd);
 
13599
        db_printf("\tinoupdt %p, newinoupdt %p, extupdt %p, newextupdt %p\n",
 
13600
            TAILQ_FIRST(&inodedep->id_inoupdt),
 
13601
            TAILQ_FIRST(&inodedep->id_newinoupdt),
 
13602
            TAILQ_FIRST(&inodedep->id_extupdt),
 
13603
            TAILQ_FIRST(&inodedep->id_newextupdt));
 
13604
}
 
13605
 
 
13606
DB_SHOW_COMMAND(inodedep, db_show_inodedep)
 
13607
{
 
13608
 
 
13609
        if (have_addr == 0) {
 
13610
                db_printf("Address required\n");
 
13611
                return;
 
13612
        }
 
13613
        inodedep_print((struct inodedep*)addr, 1);
 
13614
}
 
13615
 
6385
13616
DB_SHOW_COMMAND(inodedeps, db_show_inodedeps)
6386
13617
{
6387
13618
        struct inodedep_hashhead *inodedephd;
6395
13626
                LIST_FOREACH(inodedep, inodedephd, id_hash) {
6396
13627
                        if (fs != NULL && fs != inodedep->id_fs)
6397
13628
                                continue;
6398
 
                        db_printf("%p fs %p st %x ino %jd inoblk %jd\n",
6399
 
                            inodedep, inodedep->id_fs, inodedep->id_state,
6400
 
                            (intmax_t)inodedep->id_ino,
6401
 
                            (intmax_t)fsbtodb(inodedep->id_fs,
6402
 
                            ino_to_fsba(inodedep->id_fs, inodedep->id_ino)));
 
13629
                        inodedep_print(inodedep, 0);
6403
13630
                }
6404
13631
        }
6405
13632
}
6406
13633
 
 
13634
DB_SHOW_COMMAND(worklist, db_show_worklist)
 
13635
{
 
13636
        struct worklist *wk;
 
13637
 
 
13638
        if (have_addr == 0) {
 
13639
                db_printf("Address required\n");
 
13640
                return;
 
13641
        }
 
13642
        wk = (struct worklist *)addr;
 
13643
        printf("worklist: %p type %s state 0x%X\n",
 
13644
            wk, TYPENAME(wk->wk_type), wk->wk_state);
 
13645
}
 
13646
 
 
13647
DB_SHOW_COMMAND(workhead, db_show_workhead)
 
13648
{
 
13649
        struct workhead *wkhd;
 
13650
        struct worklist *wk;
 
13651
        int i;
 
13652
 
 
13653
        if (have_addr == 0) {
 
13654
                db_printf("Address required\n");
 
13655
                return;
 
13656
        }
 
13657
        wkhd = (struct workhead *)addr;
 
13658
        wk = LIST_FIRST(wkhd);
 
13659
        for (i = 0; i < 100 && wk != NULL; i++, wk = LIST_NEXT(wk, wk_list))
 
13660
                db_printf("worklist: %p type %s state 0x%X",
 
13661
                    wk, TYPENAME(wk->wk_type), wk->wk_state);
 
13662
        if (i == 100)
 
13663
                db_printf("workhead overflow");
 
13664
        printf("\n");
 
13665
}
 
13666
 
 
13667
 
 
13668
DB_SHOW_COMMAND(mkdirs, db_show_mkdirs)
 
13669
{
 
13670
        struct jaddref *jaddref;
 
13671
        struct diradd *diradd;
 
13672
        struct mkdir *mkdir;
 
13673
 
 
13674
        LIST_FOREACH(mkdir, &mkdirlisthd, md_mkdirs) {
 
13675
                diradd = mkdir->md_diradd;
 
13676
                db_printf("mkdir: %p state 0x%X dap %p state 0x%X",
 
13677
                    mkdir, mkdir->md_state, diradd, diradd->da_state);
 
13678
                if ((jaddref = mkdir->md_jaddref) != NULL)
 
13679
                        db_printf(" jaddref %p jaddref state 0x%X",
 
13680
                            jaddref, jaddref->ja_state);
 
13681
                db_printf("\n");
 
13682
        }
 
13683
}
 
13684
 
6407
13685
#endif /* DDB */
6408
13686
 
6409
13687
#endif /* SOFTUPDATES */