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: if((ip->i_mode&ILARG) == 0) { 6428: 6429: /* small file algorithm */ 6430: 6431: if((bn & ~7) != 0) { 6432: 6433: /* convert small to large */ 6434: 6435: if ((bp = alloc(d)) == NULL) 6436: return(NULL); 6437: bap = bp->b_addr; 6438: for(i=0; i<8; i++) { 6439: *bap++ = ip->i_addr[i]; 6440: ip->i_addr[i] = 0; 6441: } 6442: ip->i_addr[0] = bp->b_blkno; 6443: bdwrite(bp); 6444: ip->i_mode =| ILARG; 6445: goto large; 6446: } 6447: nb = ip->i_addr[bn]; 6448: if(nb == 0 && (bp = alloc(d)) != NULL) { 6449: bdwrite(bp); 6450: nb = bp->b_blkno; 6451: ip->i_addr[bn] = nb; 6452: ip->i_flag =| IUPD; 6453: } 6454: rablock = 0; 6455: if (bn<7) 6456: rablock = ip->i_addr[bn+1]; 6457: return(nb); 6458: } 6459: 6460: /* large file algorithm */ 6461: 6462: large: 6463: i = bn>>8; 6464: if(bn & 0174000) 6465: i = 7; 6466: if((nb=ip->i_addr[i]) == 0) { 6467: ip->i_flag =| IUPD; 6468: if ((bp = alloc(d)) == NULL) 6469: return(NULL); 6470: ip->i_addr[i] = bp->b_blkno; 6471: } else 6472: bp = bread(d, nb); 6473: bap = bp->b_addr; 6474: 6475: /* "huge" fetch of double indirect block */ 6476: 6477: if(i == 7) { 6478: i = ((bn>>8) & 0377) - 7; 6479: if((nb=bap[i]) == 0) { 6480: if((nbp = alloc(d)) == NULL) { 6481: brelse(bp); 6482: return(NULL); 6483: } 6484: bap[i] = nbp->b_blkno; 6485: bdwrite(bp); 6486: } else { 6487: brelse(bp); 6488: nbp = bread(d, nb); 6489: } 6490: bp = nbp; 6491: bap = bp->b_addr; 6492: } 6493: 6494: /* normal indirect fetch */ 6495: 6496: i = bn & 0377; 6497: if((nb=bap[i]) == 0 && (nbp = alloc(d)) != NULL) { 6498: nb = nbp->b_blkno; 6499: bap[i] = nb; 6500: bdwrite(nbp); 6501: bdwrite(bp); 6502: } else 6503: brelse(bp); 6504: rablock = 0; 6505: if(i < 255) 6506: rablock = bap[i+1]; 6507: return(nb); 6508: } 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: /* --------------------------- */