1 // SPDX-License-Identifier: GPL-2.0-or-later 1 // SPDX-License-Identifier: GPL-2.0-or-later 2 /* 2 /* 3 * Copyright (C) International Business Mach 3 * Copyright (C) International Business Machines Corp., 2000-2004 4 */ 4 */ 5 5 6 #include <linux/fs.h> 6 #include <linux/fs.h> 7 #include <linux/quotaops.h> 7 #include <linux/quotaops.h> 8 #include "jfs_incore.h" 8 #include "jfs_incore.h" 9 #include "jfs_inode.h" 9 #include "jfs_inode.h" 10 #include "jfs_superblock.h" 10 #include "jfs_superblock.h" 11 #include "jfs_dmap.h" 11 #include "jfs_dmap.h" 12 #include "jfs_extent.h" 12 #include "jfs_extent.h" 13 #include "jfs_debug.h" 13 #include "jfs_debug.h" 14 14 15 /* 15 /* 16 * forward references 16 * forward references 17 */ 17 */ 18 static int extBalloc(struct inode *, s64, s64 18 static int extBalloc(struct inode *, s64, s64 *, s64 *); 19 static s64 extRoundDown(s64 nb); 19 static s64 extRoundDown(s64 nb); 20 20 21 #define DPD(a) (printk("(a): %d\n",(a 21 #define DPD(a) (printk("(a): %d\n",(a))) 22 #define DPC(a) (printk("(a): %c\n",(a 22 #define DPC(a) (printk("(a): %c\n",(a))) 23 #define DPL1(a) 23 #define DPL1(a) \ 24 { 24 { \ 25 if ((a) >> 32) 25 if ((a) >> 32) \ 26 printk("(a): %x%08x ",(a)); 26 printk("(a): %x%08x ",(a)); \ 27 else 27 else \ 28 printk("(a): %x ",(a) << 32); 28 printk("(a): %x ",(a) << 32); \ 29 } 29 } 30 #define DPL(a) 30 #define DPL(a) \ 31 { 31 { \ 32 if ((a) >> 32) 32 if ((a) >> 32) \ 33 printk("(a): %x%08x\n",(a)); 33 printk("(a): %x%08x\n",(a)); \ 34 else 34 else \ 35 printk("(a): %x\n",(a) << 32); 35 printk("(a): %x\n",(a) << 32); \ 36 } 36 } 37 37 38 #define DPD1(a) (printk("(a): %d ",(a 38 #define DPD1(a) (printk("(a): %d ",(a))) 39 #define DPX(a) (printk("(a): %08x\n", 39 #define DPX(a) (printk("(a): %08x\n",(a))) 40 #define DPX1(a) (printk("(a): %08x ", 40 #define DPX1(a) (printk("(a): %08x ",(a))) 41 #define DPS(a) (printk("%s\n",(a))) 41 #define DPS(a) (printk("%s\n",(a))) 42 #define DPE(a) (printk("\nENTERING: % 42 #define DPE(a) (printk("\nENTERING: %s\n",(a))) 43 #define DPE1(a) (printk("\nENTERING: % 43 #define DPE1(a) (printk("\nENTERING: %s",(a))) 44 #define DPS1(a) (printk(" %s ",(a))) 44 #define DPS1(a) (printk(" %s ",(a))) 45 45 46 46 47 /* 47 /* 48 * NAME: extAlloc() 48 * NAME: extAlloc() 49 * 49 * 50 * FUNCTION: allocate an extent for a speci 50 * FUNCTION: allocate an extent for a specified page range within a 51 * file. 51 * file. 52 * 52 * 53 * PARAMETERS: 53 * PARAMETERS: 54 * ip - the inode of the file. 54 * ip - the inode of the file. 55 * xlen - requested extent length. 55 * xlen - requested extent length. 56 * pno - the starting page number wit 56 * pno - the starting page number with the file. 57 * xp - pointer to an xad. on entry 57 * xp - pointer to an xad. on entry, xad describes an 58 * extent that is used as an al 58 * extent that is used as an allocation hint if the 59 * xaddr of the xad is non-zero 59 * xaddr of the xad is non-zero. on successful exit, 60 * the xad describes the newly 60 * the xad describes the newly allocated extent. 61 * abnr - bool indicating whether the 61 * abnr - bool indicating whether the newly allocated extent 62 * should be marked as allocate 62 * should be marked as allocated but not recorded. 63 * 63 * 64 * RETURN VALUES: 64 * RETURN VALUES: 65 * 0 - success 65 * 0 - success 66 * -EIO - i/o error. 66 * -EIO - i/o error. 67 * -ENOSPC - insufficient disk resources. 67 * -ENOSPC - insufficient disk resources. 68 */ 68 */ 69 int 69 int 70 extAlloc(struct inode *ip, s64 xlen, s64 pno, 70 extAlloc(struct inode *ip, s64 xlen, s64 pno, xad_t * xp, bool abnr) 71 { 71 { 72 struct jfs_sb_info *sbi = JFS_SBI(ip-> 72 struct jfs_sb_info *sbi = JFS_SBI(ip->i_sb); 73 s64 nxlen, nxaddr, xoff, hint, xaddr = 73 s64 nxlen, nxaddr, xoff, hint, xaddr = 0; 74 int rc; 74 int rc; 75 int xflag; 75 int xflag; 76 76 77 /* This blocks if we are low on resour 77 /* This blocks if we are low on resources */ 78 txBeginAnon(ip->i_sb); 78 txBeginAnon(ip->i_sb); 79 79 80 /* Avoid race with jfs_commit_inode() 80 /* Avoid race with jfs_commit_inode() */ 81 mutex_lock(&JFS_IP(ip)->commit_mutex); 81 mutex_lock(&JFS_IP(ip)->commit_mutex); 82 82 83 /* validate extent length */ 83 /* validate extent length */ 84 if (xlen > MAXXLEN) 84 if (xlen > MAXXLEN) 85 xlen = MAXXLEN; 85 xlen = MAXXLEN; 86 86 87 /* get the page's starting extent offs 87 /* get the page's starting extent offset */ 88 xoff = pno << sbi->l2nbperpage; 88 xoff = pno << sbi->l2nbperpage; 89 89 90 /* check if an allocation hint was pro 90 /* check if an allocation hint was provided */ 91 if ((hint = addressXAD(xp))) { 91 if ((hint = addressXAD(xp))) { 92 /* get the size of the extent 92 /* get the size of the extent described by the hint */ 93 nxlen = lengthXAD(xp); 93 nxlen = lengthXAD(xp); 94 94 95 /* check if the hint is for th 95 /* check if the hint is for the portion of the file 96 * immediately previous to the 96 * immediately previous to the current allocation 97 * request and if hint extent 97 * request and if hint extent has the same abnr 98 * value as the current reques 98 * value as the current request. if so, we can 99 * extend the hint extent to i 99 * extend the hint extent to include the current 100 * extent if we can allocate t 100 * extent if we can allocate the blocks immediately 101 * following the hint extent. 101 * following the hint extent. 102 */ 102 */ 103 if (offsetXAD(xp) + nxlen == x 103 if (offsetXAD(xp) + nxlen == xoff && 104 abnr == ((xp->flag & XAD_N 104 abnr == ((xp->flag & XAD_NOTRECORDED) ? true : false)) 105 xaddr = hint + nxlen; 105 xaddr = hint + nxlen; 106 106 107 /* adjust the hint to the last 107 /* adjust the hint to the last block of the extent */ 108 hint += (nxlen - 1); 108 hint += (nxlen - 1); 109 } 109 } 110 110 111 /* allocate the disk blocks for the ex 111 /* allocate the disk blocks for the extent. initially, extBalloc() 112 * will try to allocate disk blocks fo 112 * will try to allocate disk blocks for the requested size (xlen). 113 * if this fails (xlen contiguous free 113 * if this fails (xlen contiguous free blocks not available), it'll 114 * try to allocate a smaller number of 114 * try to allocate a smaller number of blocks (producing a smaller 115 * extent), with this smaller number o 115 * extent), with this smaller number of blocks consisting of the 116 * requested number of blocks rounded 116 * requested number of blocks rounded down to the next smaller 117 * power of 2 number (i.e. 16 -> 8). 117 * power of 2 number (i.e. 16 -> 8). it'll continue to round down 118 * and retry the allocation until the 118 * and retry the allocation until the number of blocks to allocate 119 * is smaller than the number of block 119 * is smaller than the number of blocks per page. 120 */ 120 */ 121 nxlen = xlen; 121 nxlen = xlen; 122 if ((rc = extBalloc(ip, hint ? hint : 122 if ((rc = extBalloc(ip, hint ? hint : INOHINT(ip), &nxlen, &nxaddr))) { 123 mutex_unlock(&JFS_IP(ip)->comm 123 mutex_unlock(&JFS_IP(ip)->commit_mutex); 124 return (rc); 124 return (rc); 125 } 125 } 126 126 127 /* Allocate blocks to quota. */ 127 /* Allocate blocks to quota. */ 128 rc = dquot_alloc_block(ip, nxlen); 128 rc = dquot_alloc_block(ip, nxlen); 129 if (rc) { 129 if (rc) { 130 dbFree(ip, nxaddr, (s64) nxlen 130 dbFree(ip, nxaddr, (s64) nxlen); 131 mutex_unlock(&JFS_IP(ip)->comm 131 mutex_unlock(&JFS_IP(ip)->commit_mutex); 132 return rc; 132 return rc; 133 } 133 } 134 134 135 /* determine the value of the extent f 135 /* determine the value of the extent flag */ 136 xflag = abnr ? XAD_NOTRECORDED : 0; 136 xflag = abnr ? XAD_NOTRECORDED : 0; 137 137 138 /* if we can extend the hint extent to 138 /* if we can extend the hint extent to cover the current request, 139 * extend it. otherwise, insert a new 139 * extend it. otherwise, insert a new extent to 140 * cover the current request. 140 * cover the current request. 141 */ 141 */ 142 if (xaddr && xaddr == nxaddr) 142 if (xaddr && xaddr == nxaddr) 143 rc = xtExtend(0, ip, xoff, (in 143 rc = xtExtend(0, ip, xoff, (int) nxlen, 0); 144 else 144 else 145 rc = xtInsert(0, ip, xflag, xo 145 rc = xtInsert(0, ip, xflag, xoff, (int) nxlen, &nxaddr, 0); 146 146 147 /* if the extend or insert failed, 147 /* if the extend or insert failed, 148 * free the newly allocated blocks and 148 * free the newly allocated blocks and return the error. 149 */ 149 */ 150 if (rc) { 150 if (rc) { 151 dbFree(ip, nxaddr, nxlen); 151 dbFree(ip, nxaddr, nxlen); 152 dquot_free_block(ip, nxlen); 152 dquot_free_block(ip, nxlen); 153 mutex_unlock(&JFS_IP(ip)->comm 153 mutex_unlock(&JFS_IP(ip)->commit_mutex); 154 return (rc); 154 return (rc); 155 } 155 } 156 156 157 /* set the results of the extent alloc 157 /* set the results of the extent allocation */ 158 XADaddress(xp, nxaddr); 158 XADaddress(xp, nxaddr); 159 XADlength(xp, nxlen); 159 XADlength(xp, nxlen); 160 XADoffset(xp, xoff); 160 XADoffset(xp, xoff); 161 xp->flag = xflag; 161 xp->flag = xflag; 162 162 163 mark_inode_dirty(ip); 163 mark_inode_dirty(ip); 164 164 165 mutex_unlock(&JFS_IP(ip)->commit_mutex 165 mutex_unlock(&JFS_IP(ip)->commit_mutex); 166 /* 166 /* 167 * COMMIT_SyncList flags an anonymous 167 * COMMIT_SyncList flags an anonymous tlock on page that is on 168 * sync list. 168 * sync list. 169 * We need to commit the inode to get 169 * We need to commit the inode to get the page written to the disk. 170 */ 170 */ 171 if (test_and_clear_cflag(COMMIT_Syncli 171 if (test_and_clear_cflag(COMMIT_Synclist,ip)) 172 jfs_commit_inode(ip, 0); 172 jfs_commit_inode(ip, 0); 173 173 174 return (0); 174 return (0); 175 } 175 } 176 176 177 /* 177 /* 178 * NAME: extHint() 178 * NAME: extHint() 179 * 179 * 180 * FUNCTION: produce an extent allocation h 180 * FUNCTION: produce an extent allocation hint for a file offset. 181 * 181 * 182 * PARAMETERS: 182 * PARAMETERS: 183 * ip - the inode of the file. 183 * ip - the inode of the file. 184 * offset - file offset for which the hi 184 * offset - file offset for which the hint is needed. 185 * xp - pointer to the xad that is t 185 * xp - pointer to the xad that is to be filled in with 186 * the hint. 186 * the hint. 187 * 187 * 188 * RETURN VALUES: 188 * RETURN VALUES: 189 * 0 - success 189 * 0 - success 190 * -EIO - i/o error. 190 * -EIO - i/o error. 191 */ 191 */ 192 int extHint(struct inode *ip, s64 offset, xad_ 192 int extHint(struct inode *ip, s64 offset, xad_t * xp) 193 { 193 { 194 struct super_block *sb = ip->i_sb; 194 struct super_block *sb = ip->i_sb; 195 int nbperpage = JFS_SBI(sb)->nbperpage 195 int nbperpage = JFS_SBI(sb)->nbperpage; 196 s64 prev; 196 s64 prev; 197 int rc = 0; 197 int rc = 0; 198 s64 xaddr; 198 s64 xaddr; 199 int xlen; 199 int xlen; 200 int xflag; 200 int xflag; 201 201 202 /* init the hint as "no hint provided" 202 /* init the hint as "no hint provided" */ 203 XADaddress(xp, 0); 203 XADaddress(xp, 0); 204 204 205 /* determine the starting extent offse 205 /* determine the starting extent offset of the page previous 206 * to the page containing the offset. 206 * to the page containing the offset. 207 */ 207 */ 208 prev = ((offset & ~POFFSET) >> JFS_SBI 208 prev = ((offset & ~POFFSET) >> JFS_SBI(sb)->l2bsize) - nbperpage; 209 209 210 /* if the offset is in the first page 210 /* if the offset is in the first page of the file, no hint provided. 211 */ 211 */ 212 if (prev < 0) 212 if (prev < 0) 213 goto out; 213 goto out; 214 214 215 rc = xtLookup(ip, prev, nbperpage, &xf 215 rc = xtLookup(ip, prev, nbperpage, &xflag, &xaddr, &xlen, 0); 216 216 217 if ((rc == 0) && xlen) { 217 if ((rc == 0) && xlen) { 218 if (xlen != nbperpage) { 218 if (xlen != nbperpage) { 219 jfs_error(ip->i_sb, "c 219 jfs_error(ip->i_sb, "corrupt xtree\n"); 220 rc = -EIO; 220 rc = -EIO; 221 } 221 } 222 XADaddress(xp, xaddr); 222 XADaddress(xp, xaddr); 223 XADlength(xp, xlen); 223 XADlength(xp, xlen); 224 XADoffset(xp, prev); 224 XADoffset(xp, prev); 225 /* 225 /* 226 * only preserve the abnr flag 226 * only preserve the abnr flag within the xad flags 227 * of the returned hint. 227 * of the returned hint. 228 */ 228 */ 229 xp->flag = xflag & XAD_NOTREC 229 xp->flag = xflag & XAD_NOTRECORDED; 230 } else 230 } else 231 rc = 0; 231 rc = 0; 232 232 233 out: 233 out: 234 return (rc); 234 return (rc); 235 } 235 } 236 236 237 237 238 /* 238 /* 239 * NAME: extRecord() 239 * NAME: extRecord() 240 * 240 * 241 * FUNCTION: change a page with a file from 241 * FUNCTION: change a page with a file from not recorded to recorded. 242 * 242 * 243 * PARAMETERS: 243 * PARAMETERS: 244 * ip - inode of the file. 244 * ip - inode of the file. 245 * cp - cbuf of the file page. 245 * cp - cbuf of the file page. 246 * 246 * 247 * RETURN VALUES: 247 * RETURN VALUES: 248 * 0 - success 248 * 0 - success 249 * -EIO - i/o error. 249 * -EIO - i/o error. 250 * -ENOSPC - insufficient disk resources. 250 * -ENOSPC - insufficient disk resources. 251 */ 251 */ 252 int extRecord(struct inode *ip, xad_t * xp) 252 int extRecord(struct inode *ip, xad_t * xp) 253 { 253 { 254 int rc; 254 int rc; 255 255 256 txBeginAnon(ip->i_sb); 256 txBeginAnon(ip->i_sb); 257 257 258 mutex_lock(&JFS_IP(ip)->commit_mutex); 258 mutex_lock(&JFS_IP(ip)->commit_mutex); 259 259 260 /* update the extent */ 260 /* update the extent */ 261 rc = xtUpdate(0, ip, xp); 261 rc = xtUpdate(0, ip, xp); 262 262 263 mutex_unlock(&JFS_IP(ip)->commit_mutex 263 mutex_unlock(&JFS_IP(ip)->commit_mutex); 264 return rc; 264 return rc; 265 } 265 } 266 266 267 /* 267 /* 268 * NAME: extBalloc() 268 * NAME: extBalloc() 269 * 269 * 270 * FUNCTION: allocate disk blocks to form a 270 * FUNCTION: allocate disk blocks to form an extent. 271 * 271 * 272 * initially, we will try to allo 272 * initially, we will try to allocate disk blocks for the 273 * requested size (nblocks). if 273 * requested size (nblocks). if this fails (nblocks 274 * contiguous free blocks not ava 274 * contiguous free blocks not available), we'll try to allocate 275 * a smaller number of blocks (pr 275 * a smaller number of blocks (producing a smaller extent), with 276 * this smaller number of blocks 276 * this smaller number of blocks consisting of the requested 277 * number of blocks rounded down 277 * number of blocks rounded down to the next smaller power of 2 278 * number (i.e. 16 -> 8). we'll 278 * number (i.e. 16 -> 8). we'll continue to round down and 279 * retry the allocation until the 279 * retry the allocation until the number of blocks to allocate 280 * is smaller than the number of 280 * is smaller than the number of blocks per page. 281 * 281 * 282 * PARAMETERS: 282 * PARAMETERS: 283 * ip - the inode of the file. 283 * ip - the inode of the file. 284 * hint - disk block number to be use 284 * hint - disk block number to be used as an allocation hint. 285 * *nblocks - pointer to an s64 value. o 285 * *nblocks - pointer to an s64 value. on entry, this value specifies 286 * the desired number of block 286 * the desired number of block to be allocated. on successful 287 * exit, this value is set to 287 * exit, this value is set to the number of blocks actually 288 * allocated. 288 * allocated. 289 * blkno - pointer to a block address 289 * blkno - pointer to a block address that is filled in on successful 290 * return with the starting bl 290 * return with the starting block number of the newly 291 * allocated block range. 291 * allocated block range. 292 * 292 * 293 * RETURN VALUES: 293 * RETURN VALUES: 294 * 0 - success 294 * 0 - success 295 * -EIO - i/o error. 295 * -EIO - i/o error. 296 * -ENOSPC - insufficient disk resources. 296 * -ENOSPC - insufficient disk resources. 297 */ 297 */ 298 static int 298 static int 299 extBalloc(struct inode *ip, s64 hint, s64 * nb 299 extBalloc(struct inode *ip, s64 hint, s64 * nblocks, s64 * blkno) 300 { 300 { 301 struct jfs_inode_info *ji = JFS_IP(ip) 301 struct jfs_inode_info *ji = JFS_IP(ip); 302 struct jfs_sb_info *sbi = JFS_SBI(ip-> 302 struct jfs_sb_info *sbi = JFS_SBI(ip->i_sb); 303 s64 nb, nblks, daddr, max; 303 s64 nb, nblks, daddr, max; 304 int rc, nbperpage = sbi->nbperpage; 304 int rc, nbperpage = sbi->nbperpage; 305 struct bmap *bmp = sbi->bmap; 305 struct bmap *bmp = sbi->bmap; 306 int ag; 306 int ag; 307 307 308 /* get the number of blocks to initial 308 /* get the number of blocks to initially attempt to allocate. 309 * we'll first try the number of block 309 * we'll first try the number of blocks requested unless this 310 * number is greater than the maximum 310 * number is greater than the maximum number of contiguous free 311 * blocks in the map. in that case, we 311 * blocks in the map. in that case, we'll start off with the 312 * maximum free. 312 * maximum free. 313 */ 313 */ 314 314 315 /* give up if no space left */ 315 /* give up if no space left */ 316 if (bmp->db_maxfreebud == -1) 316 if (bmp->db_maxfreebud == -1) 317 return -ENOSPC; 317 return -ENOSPC; 318 318 319 max = (s64) 1 << bmp->db_maxfreebud; 319 max = (s64) 1 << bmp->db_maxfreebud; 320 if (*nblocks >= max && *nblocks > nbpe 320 if (*nblocks >= max && *nblocks > nbperpage) 321 nb = nblks = (max > nbperpage) 321 nb = nblks = (max > nbperpage) ? max : nbperpage; 322 else 322 else 323 nb = nblks = *nblocks; 323 nb = nblks = *nblocks; 324 324 325 /* try to allocate blocks */ 325 /* try to allocate blocks */ 326 while ((rc = dbAlloc(ip, hint, nb, &da 326 while ((rc = dbAlloc(ip, hint, nb, &daddr)) != 0) { 327 /* if something other than an 327 /* if something other than an out of space error, 328 * stop and return this error. 328 * stop and return this error. 329 */ 329 */ 330 if (rc != -ENOSPC) 330 if (rc != -ENOSPC) 331 return (rc); 331 return (rc); 332 332 333 /* decrease the allocation req 333 /* decrease the allocation request size */ 334 nb = min(nblks, extRoundDown(n 334 nb = min(nblks, extRoundDown(nb)); 335 335 336 /* give up if we cannot cover 336 /* give up if we cannot cover a page */ 337 if (nb < nbperpage) 337 if (nb < nbperpage) 338 return (rc); 338 return (rc); 339 } 339 } 340 340 341 *nblocks = nb; 341 *nblocks = nb; 342 *blkno = daddr; 342 *blkno = daddr; 343 343 344 if (S_ISREG(ip->i_mode) && (ji->filese 344 if (S_ISREG(ip->i_mode) && (ji->fileset == FILESYSTEM_I)) { 345 ag = BLKTOAG(daddr, sbi); 345 ag = BLKTOAG(daddr, sbi); 346 spin_lock_irq(&ji->ag_lock); 346 spin_lock_irq(&ji->ag_lock); 347 if (ji->active_ag == -1) { 347 if (ji->active_ag == -1) { 348 atomic_inc(&bmp->db_ac 348 atomic_inc(&bmp->db_active[ag]); 349 ji->active_ag = ag; 349 ji->active_ag = ag; 350 } else if (ji->active_ag != ag 350 } else if (ji->active_ag != ag) { 351 atomic_dec(&bmp->db_ac 351 atomic_dec(&bmp->db_active[ji->active_ag]); 352 atomic_inc(&bmp->db_ac 352 atomic_inc(&bmp->db_active[ag]); 353 ji->active_ag = ag; 353 ji->active_ag = ag; 354 } 354 } 355 spin_unlock_irq(&ji->ag_lock); 355 spin_unlock_irq(&ji->ag_lock); 356 } 356 } 357 357 358 return (0); 358 return (0); 359 } 359 } 360 360 361 /* 361 /* 362 * NAME: extRoundDown() 362 * NAME: extRoundDown() 363 * 363 * 364 * FUNCTION: round down a specified number 364 * FUNCTION: round down a specified number of blocks to the next 365 * smallest power of 2 number. 365 * smallest power of 2 number. 366 * 366 * 367 * PARAMETERS: 367 * PARAMETERS: 368 * nb - the inode of the file. 368 * nb - the inode of the file. 369 * 369 * 370 * RETURN VALUES: 370 * RETURN VALUES: 371 * next smallest power of 2 number. 371 * next smallest power of 2 number. 372 */ 372 */ 373 static s64 extRoundDown(s64 nb) 373 static s64 extRoundDown(s64 nb) 374 { 374 { 375 int i; 375 int i; 376 u64 m, k; 376 u64 m, k; 377 377 378 for (i = 0, m = (u64) 1 << 63; i < 64; 378 for (i = 0, m = (u64) 1 << 63; i < 64; i++, m >>= 1) { 379 if (m & nb) 379 if (m & nb) 380 break; 380 break; 381 } 381 } 382 382 383 i = 63 - i; 383 i = 63 - i; 384 k = (u64) 1 << i; 384 k = (u64) 1 << i; 385 k = ((k - 1) & nb) ? k : k >> 1; 385 k = ((k - 1) & nb) ? k : k >> 1; 386 386 387 return (k); 387 return (k); 388 } 388 } 389 389
Linux® is a registered trademark of Linus Torvalds in the United States and other countries.
TOMOYO® is a registered trademark of NTT DATA CORPORATION.