Large files
static uint
bmap(struct inode *ip, uint bn)
{
uint addr, *a;
struct buf *bp;
if(bn < NDIRECT){
if((addr = ip->addrs[bn]) == 0)
ip->addrs[bn] = addr = balloc(ip->dev);
return addr;
}
bn -= NDIRECT;
//mycode
//第一个非直接块
if(bn < NINDIRECT){
// Load indirect block, allocating if necessary.
if((addr = ip->addrs[NDIRECT]) == 0)
ip->addrs[NDIRECT] = addr = balloc(ip->dev);
bp = bread(ip->dev, addr);
a = (uint*)bp->data;
if((addr = a[bn]) == 0){
a[bn] = addr = balloc(ip->dev);
log_write(bp);
}
brelse(bp);
return addr;
}
//第二个非直接块
bn -= NINDIRECT;
if(bn < NNINDIRECT){
// Load indirect block, allocating if necessary.
if((addr = ip->addrs[NDIRECT + 1]) == 0)
ip->addrs[NDIRECT + 1] = addr = balloc(ip->dev);
bp = bread(ip->dev, addr);
a = (uint*)bp->data;
int index = bn / (BSIZE / sizeof(uint));
if((addr = a[index]) == 0){
a[index] = addr = balloc(ip->dev);
log_write(bp);
}
brelse(bp);
bp = bread(ip->dev, addr);
a = (uint*)bp->data;
index = bn % (BSIZE / sizeof(uint));
if((addr = a[index]) == 0){
a[index] = addr = balloc(ip->dev);
log_write(bp);
}
brelse(bp);
return addr;
}
panic("bmap: out of range");
}
void
itrunc(struct inode *ip)
{
int i, j, k;
struct buf *bp, *bp2;
uint *a, *a2;
for(i = 0; i < NDIRECT; i++){
if(ip->addrs[i]){
bfree(ip->dev, ip->addrs[i]);
ip->addrs[i] = 0;
}
}
//第一个非直接块
if(ip->addrs[NDIRECT]){
bp = bread(ip->dev, ip->addrs[NDIRECT]);
a = (uint*)bp->data;
for(j = 0; j < NINDIRECT; j++){
if(a[j])
bfree(ip->dev, a[j]);
}
brelse(bp);
bfree(ip->dev, ip->addrs[NDIRECT]);
ip->addrs[NDIRECT] = 0;
}
//第二个非直接块
if(ip->addrs[NDIRECT + 1]){
bp = bread(ip->dev, ip->addrs[NDIRECT + 1]);
a = (uint*)bp->data;
for(j = 0; j < NINDIRECT; j++){
if(a[j]) {
bp2 = bread(ip->dev, a[j]);
a2 = (uint*)bp2->data;
for(k = 0; k < NINDIRECT; k++){
if(a2[k])
bfree(ip->dev, a2[k]);
}
brelse(bp2);
bfree(ip->dev, a[j]);
}
}
brelse(bp);
bfree(ip->dev, ip->addrs[NDIRECT]);
ip->addrs[NDIRECT] = 0;
}
ip->size = 0;
iupdate(ip);
}
Symbolic links
uint
sys_symlink() {
char target[MAXPATH], path[MAXPATH];
if(argstr(0, target, MAXPATH) < 0 || argstr(1, path, MAXPATH) < 0)
return -1;
struct inode* ip;
begin_op();
ip = create(path, T_SYMLINK, 0, 0);
if(ip == 0){
end_op();
return -1;
}
if((writei(ip, 0, (uint64)target, 0, MAXPATH)) == 0){
iunlockput(ip);
end_op();
return -1;
}
iunlockput(ip); //createilock,在这里释放
end_op();
return 0;
}
if(!(omode & O_NOFOLLOW)){
int count = 0;
struct inode* nextip;
while(count < 10 && ip->type == T_SYMLINK){
count++;
if((readi(ip, 0, (uint64)path, 0, MAXPATH)) == 0){
iunlockput(ip);
end_op();
return -1;
}
if((nextip = namei(path)) == 0){
iunlockput(ip);
end_op();
return -1;
}
iunlockput(ip);
ip = nextip;
ilock(ip);
}
if(count >= 10){ //注意计数
iunlockput(ip);
end_op();
return -1;
}
}