/* subr_xxx.c 4.8 81/08/31 */
* Bmap defines the structure of file system storage
* by returning the physical block number on a device given the
* inode and the logical block number in a file.
* When convenient, it also leaves the physical
* block number of the next block of the file in rablock
register struct inode
*ip
;
* blocks 0..NADDR-4 are direct blocks
if(rwflg
==B_READ
|| (bp
= alloc(dev
))==NULL
)
nb
= dbtofsb(bp
->b_blkno
);
if ((ip
->i_mode
&IFMT
) == IFDIR
)
* Write directory blocks synchronously
* so they never appear with garbage in
rablock
= ip
->i_un
.i_addr
[i
+1];
* addresses NADDR-3, NADDR-2, and NADDR-1
* have single, double, triple indirect blocks.
* the first step is to determine
* how many levels of indirection.
* fetch the first indirect block
nb
= ip
->i_un
.i_addr
[NADDR
-j
];
if(rwflg
==B_READ
|| (bp
= alloc(dev
))==NULL
)
nb
= dbtofsb(bp
->b_blkno
);
* Write synchronously so that indirect blocks
* never point at garbage.
ip
->i_un
.i_addr
[NADDR
-j
] = nb
;
* fetch through the indirect blocks
if(bp
->b_flags
& B_ERROR
) {
if(rwflg
==B_READ
|| (nbp
= alloc(dev
))==NULL
) {
nb
= dbtofsb(nbp
->b_blkno
);
if (j
< 3 || (ip
->i_mode
&IFMT
) == IFDIR
)
* Write synchronously so indirect blocks
* never point at garbage and blocks
* in directories never contain garbage.
* Pass back c to the user at his location u_base;
* update u_base, u_count, and u_offset. Return -1
* on the last character of the user's read.
* u_base is in the user address space unless u_segflg is set.
if((id
= u
.u_segflg
) == 1)
if(id
?suibyte(u
.u_base
, c
):subyte(u
.u_base
, c
) < 0) {
return(u
.u_count
== 0? -1: 0);
* Pick up and return the next character from the user's
* write call at location u_base;
* update u_base, u_count, and u_offset. Return -1
* when u_count is exhausted. u_base is in the user's
* address space unless u_segflg is set.
if((id
= u
.u_segflg
) == 1)
if((c
= id
==0?fubyte(u
.u_base
):fuibyte(u
.u_base
)) < 0) {
* Routine which sets a user error; placed in
* illegal entries in the bdevsw and cdevsw tables.
* Null routine; placed in insignificant entries
* in the bdevsw and cdevsw tables.
for (p
= &proc
[pidhash
[PIDHASH(pid
)]]; p
!= &proc
[0]; p
= &proc
[p
->p_idhash
])
return ((struct proc
*)0);