1 /* $NetBSD: inode.c,v 1.61 2008/10/09 16:56:23 christos Exp $ */
4 * Copyright (c) 1980, 1986, 1993
5 * The Regents of the University of California. All rights reserved.
7 * Redistribution and use in source and binary forms, with or without
8 * modification, are permitted provided that the following conditions
10 * 1. Redistributions of source code must retain the above copyright
11 * notice, this list of conditions and the following disclaimer.
12 * 2. Redistributions in binary form must reproduce the above copyright
13 * notice, this list of conditions and the following disclaimer in the
14 * documentation and/or other materials provided with the distribution.
15 * 3. Neither the name of the University nor the names of its contributors
16 * may be used to endorse or promote products derived from this software
17 * without specific prior written permission.
19 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
20 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
21 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
22 * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
23 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
24 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
25 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
26 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
27 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
28 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
32 #include <sys/cdefs.h>
35 static char sccsid
[] = "@(#)inode.c 8.8 (Berkeley) 4/28/95";
37 __RCSID("$NetBSD: inode.c,v 1.61 2008/10/09 16:56:23 christos Exp $");
41 #include <sys/param.h>
44 #include <ufs/ufs/dinode.h>
45 #include <ufs/ufs/dir.h>
46 #include <ufs/ffs/fs.h>
47 #include <ufs/ffs/ffs_extern.h>
48 #include <ufs/ufs/ufs_bswap.h>
63 static ino_t startinum
;
65 static int iblock(struct inodesc
*, long, u_int64_t
);
66 static void swap_dinode1(union dinode
*, int);
67 static void swap_dinode2(union dinode
*, int);
70 ckinode(union dinode
*dp
, struct inodesc
*idesc
)
78 char pathbuf
[MAXPATHLEN
+ 1];
80 if (idesc
->id_fix
!= IGNORE
)
81 idesc
->id_fix
= DONTKNOW
;
82 idesc
->id_entryno
= 0;
83 idesc
->id_filesize
= iswap64(DIP(dp
, size
));
84 mode
= iswap16(DIP(dp
, mode
)) & IFMT
;
85 if (mode
== IFBLK
|| mode
== IFCHR
|| (mode
== IFLNK
&&
86 (idesc
->id_filesize
< sblock
->fs_maxsymlinklen
||
87 (isappleufs
&& (idesc
->id_filesize
< APPLEUFS_MAXSYMLINKLEN
)) ||
88 (sblock
->fs_maxsymlinklen
== 0 && DIP(dp
, blocks
) == 0))))
94 ndb
= howmany(iswap64(DIP(&dino
, size
)), sblock
->fs_bsize
);
95 for (i
= 0; i
< NDADDR
; i
++) {
97 (offset
= blkoff(sblock
, iswap64(DIP(&dino
, size
)))) != 0)
99 numfrags(sblock
, fragroundup(sblock
, offset
));
101 idesc
->id_numfrags
= sblock
->fs_frag
;
102 if (DIP(&dino
, db
[i
]) == 0) {
103 if (idesc
->id_type
== DATA
&& ndb
>= 0) {
104 /* An empty block in a directory XXX */
106 getpathname(pathbuf
, sizeof(pathbuf
),
107 idesc
->id_number
, idesc
->id_number
);
108 pfatal("DIRECTORY %s: CONTAINS EMPTY BLOCKS",
110 if (reply("ADJUST LENGTH") == 1) {
111 dp
= ginode(idesc
->id_number
);
112 DIP_SET(dp
, size
, iswap64(i
*
115 "YOU MUST RERUN FSCK AFTERWARDS\n");
123 idesc
->id_blkno
= iswap64(dino
.dp2
.di_db
[i
]);
125 idesc
->id_blkno
= iswap32(dino
.dp1
.di_db
[i
]);
126 if (idesc
->id_type
!= DATA
)
127 ret
= (*idesc
->id_func
)(idesc
);
129 ret
= dirscan(idesc
);
133 idesc
->id_numfrags
= sblock
->fs_frag
;
134 remsize
= iswap64(DIP(&dino
, size
)) - sblock
->fs_bsize
* NDADDR
;
135 sizepb
= sblock
->fs_bsize
;
136 for (i
= 0; i
< NIADDR
; i
++) {
137 if (DIP(&dino
, ib
[i
])) {
139 idesc
->id_blkno
= iswap64(dino
.dp2
.di_ib
[i
]);
141 idesc
->id_blkno
= iswap32(dino
.dp1
.di_ib
[i
]);
142 ret
= iblock(idesc
, i
+ 1, remsize
);
146 if (idesc
->id_type
== DATA
&& remsize
> 0) {
147 /* An empty block in a directory XXX */
149 getpathname(pathbuf
, sizeof(pathbuf
),
150 idesc
->id_number
, idesc
->id_number
);
151 pfatal("DIRECTORY %s: CONTAINS EMPTY BLOCKS",
153 if (reply("ADJUST LENGTH") == 1) {
154 dp
= ginode(idesc
->id_number
);
156 iswap64(iswap64(DIP(dp
, size
))
160 "YOU MUST RERUN FSCK AFTERWARDS\n");
167 sizepb
*= NINDIR(sblock
);
174 iblock(struct inodesc
*idesc
, long ilevel
, u_int64_t isize
)
177 int i
, n
, (*func
) (struct inodesc
*), nif
;
180 char pathbuf
[MAXPATHLEN
+ 1];
183 if (idesc
->id_type
!= DATA
) {
184 func
= idesc
->id_func
;
185 if (((n
= (*func
)(idesc
)) & KEEPON
) == 0)
189 if (chkrange(idesc
->id_blkno
, idesc
->id_numfrags
))
191 bp
= getdatablk(idesc
->id_blkno
, sblock
->fs_bsize
);
193 for (sizepb
= sblock
->fs_bsize
, i
= 0; i
< ilevel
; i
++)
194 sizepb
*= NINDIR(sblock
);
195 if (howmany(isize
, sizepb
) > (size_t)NINDIR(sblock
))
196 nif
= NINDIR(sblock
);
198 nif
= howmany(isize
, sizepb
);
199 if (do_blkswap
) { /* swap byte order of the whole blk */
201 for (i
= 0; i
< nif
; i
++)
202 bp
->b_un
.b_indir2
[i
] =
203 bswap64(bp
->b_un
.b_indir2
[i
]);
205 for (i
= 0; i
< nif
; i
++)
206 bp
->b_un
.b_indir1
[i
] =
207 bswap32(bp
->b_un
.b_indir1
[i
]);
210 flush(fswritefd
, bp
);
212 if (idesc
->id_func
== pass1check
&& nif
< NINDIR(sblock
)) {
213 for (i
= nif
; i
< NINDIR(sblock
); i
++) {
214 if (IBLK(bp
, i
) == 0)
216 (void)snprintf(buf
, sizeof(buf
),
217 "PARTIALLY TRUNCATED INODE I=%llu",
218 (unsigned long long)idesc
->id_number
);
219 if (dofix(idesc
, buf
)) {
225 flush(fswritefd
, bp
);
227 for (i
= 0; i
< nif
; i
++) {
230 idesc
->id_blkno
= iswap64(bp
->b_un
.b_indir2
[i
]);
232 idesc
->id_blkno
= iswap32(bp
->b_un
.b_indir1
[i
]);
236 n
= iblock(idesc
, ilevel
, isize
);
238 bp
->b_flags
&= ~B_INUSE
;
242 if (idesc
->id_type
== DATA
&& isize
> 0) {
243 /* An empty block in a directory XXX */
245 getpathname(pathbuf
, sizeof(pathbuf
),
246 idesc
->id_number
, idesc
->id_number
);
247 pfatal("DIRECTORY %s: CONTAINS EMPTY BLOCKS",
249 if (reply("ADJUST LENGTH") == 1) {
250 dp
= ginode(idesc
->id_number
);
252 iswap64(iswap64(DIP(dp
, size
))
256 "YOU MUST RERUN FSCK AFTERWARDS\n");
259 bp
->b_flags
&= ~B_INUSE
;
266 bp
->b_flags
&= ~B_INUSE
;
271 * Check that a block in a legal block number.
272 * Return 0 if in range, 1 if out of range.
275 chkrange(daddr_t blk
, int cnt
)
279 if (cnt
<= 0 || blk
<= 0 || blk
> maxfsblock
||
280 cnt
- 1 > maxfsblock
- blk
)
282 if (cnt
> sblock
->fs_frag
||
283 fragnum(sblock
, blk
) + cnt
> sblock
->fs_frag
) {
285 printf("bad size: blk %lld, offset %d, size %d\n",
286 (long long)blk
, (int)fragnum(sblock
, blk
), cnt
);
288 c
= dtog(sblock
, blk
);
289 if (blk
< cgdmin(sblock
, c
)) {
290 if ((blk
+ cnt
) > cgsblock(sblock
, c
)) {
292 printf("blk %lld < cgdmin %lld;",
294 (long long)cgdmin(sblock
, c
));
295 printf(" blk + cnt %lld > cgsbase %lld\n",
296 (long long)(blk
+ cnt
),
297 (long long)cgsblock(sblock
, c
));
302 if ((blk
+ cnt
) > cgbase(sblock
, c
+1)) {
304 printf("blk %lld >= cgdmin %lld;",
306 (long long)cgdmin(sblock
, c
));
307 printf(" blk + cnt %lld > sblock->fs_fpg %d\n",
308 (long long)(blk
+cnt
), sblock
->fs_fpg
);
317 * General purpose interface for reading inodes.
320 ginode(ino_t inumber
)
325 if (inumber
< ROOTINO
|| inumber
> maxino
)
326 errexit("bad inode number %llu to ginode",
327 (unsigned long long)inumber
);
328 if (startinum
== 0 ||
329 inumber
< startinum
|| inumber
>= startinum
+ INOPB(sblock
)) {
330 iblk
= ino_to_fsba(sblock
, inumber
);
332 pbp
->b_flags
&= ~B_INUSE
;
333 pbp
= getdatablk(iblk
, sblock
->fs_bsize
);
334 startinum
= (inumber
/ INOPB(sblock
)) * INOPB(sblock
);
337 blkoff
= (inumber
% INOPB(sblock
)) * DINODE2_SIZE
;
338 return ((union dinode
*)((caddr_t
)pbp
->b_un
.b_buf
+ blkoff
));
340 blkoff
= (inumber
% INOPB(sblock
)) * DINODE1_SIZE
;
341 return ((union dinode
*)((caddr_t
)pbp
->b_un
.b_buf
+ blkoff
));
345 swap_dinode1(union dinode
*dp
, int n
)
348 struct ufs1_dinode
*dp1
;
349 int32_t maxsymlinklen
= sblock
->fs_maxsymlinklen
;
351 maxsymlinklen
= APPLEUFS_MAXSYMLINKLEN
;
353 dp1
= (struct ufs1_dinode
*)&dp
->dp1
;
354 for (i
= 0; i
< n
; i
++, dp1
++) {
355 ffs_dinode1_swap(dp1
, dp1
);
356 if (((iswap16(dp1
->di_mode
) & IFMT
) != IFLNK
) ||
358 (maxsymlinklen
< 0) ||
359 (iswap64(dp1
->di_size
) > (uint64_t)maxsymlinklen
)) {
360 for (j
= 0; j
< (NDADDR
+ NIADDR
); j
++)
361 dp1
->di_db
[j
] = bswap32(dp1
->di_db
[j
]);
367 swap_dinode2(union dinode
*dp
, int n
)
370 struct ufs2_dinode
*dp2
;
372 dp2
= (struct ufs2_dinode
*)&dp
->dp2
;
373 for (i
= 0; i
< n
; i
++, dp2
++) {
374 ffs_dinode2_swap(dp2
, dp2
);
375 if ((iswap16(dp2
->di_mode
) & IFMT
) != IFLNK
) {
376 for (j
= 0; j
< (NDADDR
+ NIADDR
+ NXADDR
); j
++)
377 dp2
->di_extb
[j
] = bswap64(dp2
->di_extb
[j
]);
383 * Special purpose version of ginode used to optimize first pass
384 * over all the inodes in numerical order.
386 ino_t nextino
, lastinum
, lastvalidinum
;
387 long readcnt
, readpercg
, fullcnt
, inobufsize
, partialcnt
, partialsize
;
388 union dinode
*inodebuf
;
391 getnextinode(ino_t inumber
)
395 static union dinode
*dp
;
398 if (inumber
!= nextino
++ || inumber
> lastvalidinum
)
399 errexit("bad inode number %llu to nextinode",
400 (unsigned long long)inumber
);
402 if (inumber
>= lastinum
) {
404 dblk
= fsbtodb(sblock
, ino_to_fsba(sblock
, lastinum
));
405 if (readcnt
% readpercg
== 0) {
407 lastinum
+= partialcnt
;
412 (void)bread(fsreadfd
, (caddr_t
)inodebuf
, dblk
, size
);
415 swap_dinode2(inodebuf
, lastinum
- inumber
);
417 swap_dinode1(inodebuf
, lastinum
- inumber
);
418 bwrite(fswritefd
, (char *)inodebuf
, dblk
, size
);
420 dp
= (union dinode
*)inodebuf
;
423 dp
= (union dinode
*)
424 ((char *)dp
+ (is_ufs2
? DINODE2_SIZE
: DINODE1_SIZE
));
429 setinodebuf(ino_t inum
)
432 if (inum
% sblock
->fs_ipg
!= 0)
433 errexit("bad inode number %llu to setinodebuf",
434 (unsigned long long)inum
);
436 lastvalidinum
= inum
+ sblock
->fs_ipg
- 1;
441 if (inodebuf
!= NULL
)
443 inobufsize
= blkroundup(sblock
, INOBUFSIZE
);
444 fullcnt
= inobufsize
/ (is_ufs2
? DINODE2_SIZE
: DINODE1_SIZE
);
445 readpercg
= sblock
->fs_ipg
/ fullcnt
;
446 partialcnt
= sblock
->fs_ipg
% fullcnt
;
447 partialsize
= partialcnt
* (is_ufs2
? DINODE2_SIZE
: DINODE1_SIZE
);
448 if (partialcnt
!= 0) {
451 partialcnt
= fullcnt
;
452 partialsize
= inobufsize
;
454 if (inodebuf
== NULL
&&
455 (inodebuf
= malloc((unsigned)inobufsize
)) == NULL
)
456 errexit("Cannot allocate space for inode buffer");
463 if (inodebuf
!= NULL
)
464 free((char *)inodebuf
);
469 * Routines to maintain information about directory inodes.
470 * This is built during the first pass and used during the
471 * second and third passes.
473 * Enter inodes into the cache.
476 cacheino(union dinode
*dp
, ino_t inumber
)
479 struct inoinfo
**inpp
, **ninpsort
;
480 unsigned int i
, blks
, extra
;
483 size
= iswap64(DIP(dp
, size
));
484 blks
= howmany(size
, sblock
->fs_bsize
);
486 blks
= NDADDR
+ NIADDR
;
488 extra
= (blks
- 1) * sizeof (int64_t);
491 inp
= malloc(sizeof(*inp
) + extra
);
494 inpp
= &inphead
[inumber
% dirhash
];
495 inp
->i_nexthash
= *inpp
;
497 inp
->i_child
= inp
->i_sibling
= 0;
498 if (inumber
== ROOTINO
)
499 inp
->i_parent
= ROOTINO
;
501 inp
->i_parent
= (ino_t
)0;
502 inp
->i_dotdot
= (ino_t
)0;
503 inp
->i_number
= inumber
;
505 inp
->i_numblks
= blks
;
506 for (i
= 0; i
< (blks
< NDADDR
? blks
: NDADDR
); i
++)
507 inp
->i_blks
[i
] = DIP(dp
, db
[i
]);
509 for (i
= 0; i
< NIADDR
; i
++)
510 inp
->i_blks
[NDADDR
+ i
] = DIP(dp
, ib
[i
]);
511 if (inplast
== listmax
) {
512 ninpsort
= (struct inoinfo
**)realloc((char *)inpsort
,
513 (unsigned)(listmax
+ 100) * sizeof(struct inoinfo
*));
515 errexit("cannot increase directory list");
519 inpsort
[inplast
++] = inp
;
523 * Look up an inode cache structure.
526 getinoinfo(ino_t inumber
)
530 for (inp
= inphead
[inumber
% dirhash
]; inp
; inp
= inp
->i_nexthash
) {
531 if (inp
->i_number
!= inumber
)
535 errexit("cannot find inode %llu", (unsigned long long)inumber
);
536 return ((struct inoinfo
*)0);
540 * Clean up all the inode cache structure.
545 struct inoinfo
**inpp
;
549 for (inpp
= &inpsort
[inplast
- 1]; inpp
>= inpsort
; inpp
--)
550 free((char *)(*inpp
));
551 free((char *)inphead
);
552 free((char *)inpsort
);
553 inphead
= inpsort
= NULL
;
564 clri(struct inodesc
*idesc
, const char *type
, int flag
)
568 dp
= ginode(idesc
->id_number
);
571 (iswap16(DIP(dp
, mode
)) & IFMT
) == IFDIR
? "DIR" : "FILE");
572 pinode(idesc
->id_number
);
574 if (preen
|| reply("CLEAR") == 1) {
576 printf(" (CLEARED)\n");
578 (void)ckinode(dp
, idesc
);
580 inoinfo(idesc
->id_number
)->ino_state
= USTATE
;
587 findname(struct inodesc
*idesc
)
589 struct direct
*dirp
= idesc
->id_dirp
;
593 if (iswap32(dirp
->d_ino
) != idesc
->id_parent
|| idesc
->id_entryno
< 2) {
597 if ((len
= dirp
->d_namlen
+ 1) > MAXPATHLEN
) {
598 /* XXX: We don't fix but we ignore */
601 /* this is namebuf from utilities.c */
602 buf
= __UNCONST(idesc
->id_name
);
603 (void)memcpy(buf
, dirp
->d_name
, (size_t)dirp
->d_namlen
+ 1);
608 findino(struct inodesc
*idesc
)
610 struct direct
*dirp
= idesc
->id_dirp
;
612 if (dirp
->d_ino
== 0)
614 if (strcmp(dirp
->d_name
, idesc
->id_name
) == 0 &&
615 iswap32(dirp
->d_ino
) >= ROOTINO
&& iswap32(dirp
->d_ino
) <= maxino
) {
616 idesc
->id_parent
= iswap32(dirp
->d_ino
);
623 clearentry(struct inodesc
*idesc
)
625 struct direct
*dirp
= idesc
->id_dirp
;
627 if (dirp
->d_ino
!= idesc
->id_parent
|| idesc
->id_entryno
< 2) {
632 return (STOP
|FOUND
|ALTERED
);
643 printf(" I=%llu ", (unsigned long long)ino
);
644 if (ino
< ROOTINO
|| ino
> maxino
)
649 if (Uflag
&& (pw
= getpwuid((int)iswap32(DIP(dp
, uid
)))) != 0)
650 printf("%s ", pw
->pw_name
);
653 printf("%u ", (unsigned)iswap32(DIP(dp
, uid
)));
654 printf("MODE=%o\n", iswap16(DIP(dp
, mode
)));
656 printf("%s: ", cdevname());
657 printf("SIZE=%llu ", (unsigned long long)iswap64(DIP(dp
, size
)));
658 t
= iswap32(DIP(dp
, mtime
));
660 printf("MTIME=%12.12s %4.4s ", &p
[4], &p
[20]);
664 blkerror(ino_t ino
, const char *type
, daddr_t blk
)
666 struct inostat
*info
;
668 pfatal("%lld %s I=%llu", (long long)blk
, type
, (unsigned long long)ino
);
671 switch (info
->ino_state
) {
674 info
->ino_state
= FCLEAR
;
678 info
->ino_state
= DCLEAR
;
686 errexit("BAD STATE %d TO BLKERR", info
->ino_state
);
692 * allocate an unused inode
695 allocino(ino_t request
, int type
)
699 struct ufs1_dinode
*dp1
;
700 struct ufs2_dinode
*dp2
;
702 struct cg
*cgp
= cgrp
;
704 struct inostat
*info
= NULL
;
708 else if (inoinfo(request
)->ino_state
!= USTATE
)
710 for (ino
= request
; ino
< maxino
; ino
++) {
712 if (info
->ino_state
== USTATE
)
717 cg
= ino_to_cg(sblock
, ino
);
718 /* If necessary, extend the inoinfo array. grow exponentially */
719 if ((ino
% sblock
->fs_ipg
) >= (uint64_t)inostathead
[cg
].il_numalloced
) {
720 unsigned long newalloced
, i
;
721 newalloced
= MIN(sblock
->fs_ipg
,
722 MAX(2 * inostathead
[cg
].il_numalloced
, 10));
723 info
= calloc(newalloced
, sizeof(struct inostat
));
725 pwarn("cannot alloc %lu bytes to extend inoinfo\n",
726 sizeof(struct inostat
) * newalloced
);
729 memmove(info
, inostathead
[cg
].il_stat
,
730 inostathead
[cg
].il_numalloced
* sizeof(*info
));
731 for (i
= inostathead
[cg
].il_numalloced
; i
< newalloced
; i
++) {
732 info
[i
].ino_state
= USTATE
;
734 if (inostathead
[cg
].il_numalloced
)
735 free(inostathead
[cg
].il_stat
);
736 inostathead
[cg
].il_stat
= info
;
737 inostathead
[cg
].il_numalloced
= newalloced
;
740 getblk(&cgblk
, cgtod(sblock
, cg
), sblock
->fs_cgsize
);
741 memcpy(cgp
, cgblk
.b_un
.b_cg
, sblock
->fs_cgsize
);
742 if ((doswap
&& !needswap
) || (!doswap
&& needswap
))
743 ffs_cg_swap(cgblk
.b_un
.b_cg
, cgp
, sblock
);
744 if (!cg_chkmagic(cgp
, 0))
745 pfatal("CG %d: ALLOCINO: BAD MAGIC NUMBER\n", cg
);
748 setbit(cg_inosused(cgp
, 0), ino
% sblock
->fs_ipg
);
749 cgp
->cg_cs
.cs_nifree
--;
750 switch (type
& IFMT
) {
752 info
->ino_state
= DSTATE
;
753 cgp
->cg_cs
.cs_ndir
++;
757 info
->ino_state
= FSTATE
;
766 dp2
->di_db
[0] = iswap64(allocblk(1));
767 if (dp2
->di_db
[0] == 0) {
768 info
->ino_state
= USTATE
;
771 dp2
->di_mode
= iswap16(type
);
774 dp2
->di_atime
= iswap64(t
);
775 dp2
->di_mtime
= dp2
->di_ctime
= dp2
->di_atime
;
776 dp2
->di_size
= iswap64(sblock
->fs_fsize
);
777 dp2
->di_blocks
= iswap64(btodb(sblock
->fs_fsize
));
780 dp1
->di_db
[0] = iswap32(allocblk(1));
781 if (dp1
->di_db
[0] == 0) {
782 info
->ino_state
= USTATE
;
785 dp1
->di_mode
= iswap16(type
);
788 dp1
->di_atime
= iswap32(t
);
789 dp1
->di_mtime
= dp1
->di_ctime
= dp1
->di_atime
;
790 dp1
->di_size
= iswap64(sblock
->fs_fsize
);
791 dp1
->di_blocks
= iswap32(btodb(sblock
->fs_fsize
));
796 info
->ino_type
= IFTODT(type
);
801 * deallocate an inode
806 struct inodesc idesc
;
809 memset(&idesc
, 0, sizeof(struct inodesc
));
810 idesc
.id_type
= ADDR
;
811 idesc
.id_func
= pass4check
;
812 idesc
.id_number
= ino
;
814 (void)ckinode(dp
, &idesc
);
817 inoinfo(ino
)->ino_state
= USTATE
;