subr.c

6400 # 6401 #include "../param.h" 6402 #include "../conf.h" 6403 #include "../inode.h" 6404 #include "../user.h" 6405 #include "../buf.h" 6406 #include "../systm.h" 6407 6408 /* Bmap defines the structure of file system storage 6409 * by returning the physical block number on a device given the 6410 * inode and the logical block number in a file. 6411 * When convenient, it also leaves the physical 6412 * block number of the next block of the file in rablock 6413 * for use in read-ahead. 6414 */ 6415 bmap(ip, bn) 6416 struct inode *ip; 6417 int bn; 6418 { 6419 register *bp, *bap, nb; 6420 int *nbp, d, i; 6421 6422 d = ip->i_dev; 6423 if(bn & ~077777) { 6424 u.u_error = EFBIG; 6425 return(0); 6426 } 6427 6428 if((ip->i_mode&ILARG) == 0) { 6429 6430 /* small file algorithm */ 6431 6432 if((bn & ~7) != 0) { 6433 6434 /* convert small to large */ 6435 6436 if ((bp = alloc(d)) == NULL) 6437 return(NULL); 6438 bap = bp->b_addr; 6439 for(i=0; i<8; i++) { 6440 *bap++ = ip->i_addr[i]; 6441 ip->i_addr[i] = 0; 6442 } 6443 ip->i_addr[0] = bp->b_blkno; 6444 bdwrite(bp); 6445 ip->i_mode =| ILARG; 6446 goto large; 6447 } 6448 nb = ip->i_addr[bn]; 6449 if(nb == 0 && (bp = alloc(d)) != NULL) { 6450 bdwrite(bp); 6451 nb = bp->b_blkno; 6452 ip->i_addr[bn] = nb; 6453 ip->i_flag =| IUPD; 6454 } 6455 rablock = 0; 6456 if (bn<7) 6457 rablock = ip->i_addr[bn+1]; 6458 return(nb); 6459 } 6460 6461 /* large file algorithm */ 6462 6463 large: 6464 i = bn>>8; 6465 if(bn & 0174000) 6466 i = 7; 6467 if((nb=ip->i_addr[i]) == 0) { 6468 ip->i_flag =| IUPD; 6469 if ((bp = alloc(d)) == NULL) 6470 return(NULL); 6471 ip->i_addr[i] = bp->b_blkno; 6472 } else 6473 bp = bread(d, nb); 6474 bap = bp->b_addr; 6475 6476 /* "huge" fetch of double indirect block */ 6477 6478 if(i == 7) { 6479 i = ((bn>>8) & 0377) - 7; 6480 if((nb=bap[i]) == 0) { 6481 if((nbp = alloc(d)) == NULL) { 6482 brelse(bp); 6483 return(NULL); 6484 } 6485 bap[i] = nbp->b_blkno; 6486 bdwrite(bp); 6487 } else { 6488 brelse(bp); 6489 nbp = bread(d, nb); 6490 } 6491 bp = nbp; 6492 bap = bp->b_addr; 6493 } 6494 6495 /* normal indirect fetch */ 6496 6497 i = bn & 0377; 6498 if((nb=bap[i]) == 0 && (nbp = alloc(d)) != NULL) { 6499 nb = nbp->b_blkno; 6500 bap[i] = nb; 6501 bdwrite(nbp); 6502 bdwrite(bp); 6503 } else 6504 brelse(bp); 6505 rablock = 0; 6506 if(i < 255) 6507 rablock = bap[i+1]; 6508 return(nb); 6509 } 6510 /* ------------------------ */ 6511 6512 /* Pass back c to the user at his location u_base; 6513 * update u_base, u_count, and u_offset. Return -1 6514 * on the last character of the user's read. 6515 * u_base is in the user address space unless u_segflg is set. 6516 */ 6517 passc(c) 6518 char c; 6519 { 6520 6521 if(u.u_segflg) 6522 *u.u_base = c; else 6523 if(subyte(u.u_base, c) < 0) { 6524 u.u_error = EFAULT; 6525 return(-1); 6526 } 6527 u.u_count--; 6528 if(++u.u_offset[1] == 0) 6529 u.u_offset[0]++; 6530 u.u_base++; 6531 return(u.u_count == 0? -1: 0); 6532 } 6533 /* ------------------------ */ 6534 6535 /* 6536 * Pick up and return the next character from the user's 6537 * write call at location u_base; 6538 * update u_base, u_count, and u_offset. Return -1 6539 * when u_count is exhausted. u_base is in the user's 6540 * address space unless u_segflg is set. 6541 */ 6542 cpass() 6543 { 6544 register c; 6545 6546 if(u.u_count == 0) 6547 return(-1); 6548 if(u.u_segflg) 6549 c = *u.u_base; else 6550 if((c=fubyte(u.u_base)) < 0) { 6551 u.u_error = EFAULT; 6552 return(-1); 6553 } 6554 u.u_count--; 6555 if(++u.u_offset[1] == 0) 6556 u.u_offset[0]++; 6557 u.u_base++; 6558 return(c&0377); 6559 } 6560 /* ------------------------ */ 6561 6562 /* 6563 * Routine which sets a user error; placed in 6564 * illegal entries in the bdevsw and cdevsw tables. 6565 */ 6566 nodev() 6567 { 6568 6569 u.u_error = ENODEV; 6570 } 6571 /* ------------------------ */ 6572 6573 /* 6574 * Null routine; placed in insignificant entries 6575 * in the bdevsw and cdevsw tables. 6576 */ 6577 nulldev() 6578 { 6579 } 6580 /* ------------------------ */ 6581 6582 /* 6583 * copy count words from from to to. 6584 */ 6585 bcopy(from, to, count) 6586 int *from, *to; 6587 { 6588 register *a, *b, c; 6589 6590 a = from; 6591 b = to; 6592 c = count; 6593 do 6594 *b++ = *a++; 6595 while(--c); 6596 } 6597 /* ------------------------ */ 6598 6599