提交 ef921d5f 创建 作者: Silas Boyd-Wickizer's avatar Silas Boyd-Wickizer

Merge branch 'old-types' into scale-amd64

...@@ -69,6 +69,7 @@ struct inode : public referenced, public rcu_freed ...@@ -69,6 +69,7 @@ struct inode : public referenced, public rcu_freed
short minor; short minor;
u32 size; u32 size;
std::atomic<u32> addrs[NDIRECT+1]; std::atomic<u32> addrs[NDIRECT+1];
std::atomic<volatile u32*> iaddrs;
private: private:
inode(); inode();
......
...@@ -45,6 +45,8 @@ ...@@ -45,6 +45,8 @@
static void itrunc(struct inode*); static void itrunc(struct inode*);
static inode* the_root; static inode* the_root;
#define IADDRSSZ (sizeof(u32)*NINDIRECT)
// Read the super block. // Read the super block.
static void static void
readsb(int dev, struct superblock *sb) readsb(int dev, struct superblock *sb)
...@@ -240,6 +242,14 @@ iupdate(struct inode *ip) ...@@ -240,6 +242,14 @@ iupdate(struct inode *ip)
memmove(dip->addrs, ip->addrs, sizeof(ip->addrs)); memmove(dip->addrs, ip->addrs, sizeof(ip->addrs));
bwrite(bp); bwrite(bp);
brelse(bp, 1); brelse(bp, 1);
if (ip->addrs[NDIRECT] != 0) {
assert(ip->iaddrs.load() != nullptr);
bp = bread(ip->dev, ip->addrs[NDIRECT], 1);
memmove(bp->data, (void*)ip->iaddrs.load(), IADDRSSZ);
bwrite(bp);
brelse(bp, 1);
}
} }
// Find the inode with number inum on device dev // Find the inode with number inum on device dev
...@@ -253,7 +263,8 @@ inode::inode() ...@@ -253,7 +263,8 @@ inode::inode()
: rcu_freed("inode"), : rcu_freed("inode"),
flags(0), readbusy(0) flags(0), readbusy(0)
{ {
dir = 0; dir.store(nullptr);
iaddrs.store(nullptr);
} }
inode::~inode() inode::~inode()
...@@ -265,6 +276,10 @@ inode::~inode() ...@@ -265,6 +276,10 @@ inode::~inode()
gc_delayed(d); gc_delayed(d);
assert(cmpxch(&dir, d, (decltype(d)) 0)); assert(cmpxch(&dir, d, (decltype(d)) 0));
} }
if (iaddrs.load() != nullptr) {
kmfree((void*)iaddrs.load(), IADDRSSZ);
iaddrs.store(nullptr);
}
destroylock(&lock); destroylock(&lock);
destroycondvar(&cv); destroycondvar(&cv);
...@@ -512,8 +527,8 @@ iunlockput(struct inode *ip) ...@@ -512,8 +527,8 @@ iunlockput(struct inode *ip)
static u32 static u32
bmap(struct inode *ip, u32 bn) bmap(struct inode *ip, u32 bn)
{ {
u32 addr, *a;
struct buf *bp; struct buf *bp;
u32 addr;
if(bn < NDIRECT){ if(bn < NDIRECT){
retry0: retry0:
...@@ -528,9 +543,11 @@ bmap(struct inode *ip, u32 bn) ...@@ -528,9 +543,11 @@ bmap(struct inode *ip, u32 bn)
} }
bn -= NDIRECT; bn -= NDIRECT;
if(bn < NINDIRECT){ if (bn >= NINDIRECT)
// Load indirect block, allocating if necessary. panic("bmap: out of range");
retry1:
retry1:
if (ip->iaddrs == nullptr) {
if((addr = ip->addrs[NDIRECT]) == 0) { if((addr = ip->addrs[NDIRECT]) == 0) {
addr = balloc(ip->dev); addr = balloc(ip->dev);
if (!cmpxch(&ip->addrs[NDIRECT], (u32)0, addr)) { if (!cmpxch(&ip->addrs[NDIRECT], (u32)0, addr)) {
...@@ -539,26 +556,27 @@ bmap(struct inode *ip, u32 bn) ...@@ -539,26 +556,27 @@ bmap(struct inode *ip, u32 bn)
} }
} }
int writerflag = 0; volatile u32* iaddrs = (u32*)kmalloc(IADDRSSZ, "iaddrs");
bp = bread(ip->dev, addr, writerflag); bp = bread(ip->dev, addr, 0);
a = (u32*)bp->data; memmove((void*)iaddrs, bp->data, IADDRSSZ);
if((addr = a[bn]) == 0){ brelse(bp, 0);
brelse(bp, writerflag); if (!cmpxch(&ip->iaddrs, (volatile u32*)nullptr, iaddrs)) {
bfree(ip->dev, addr);
writerflag = 1; kmfree((void*)iaddrs, IADDRSSZ);
bp = bread(ip->dev, addr, writerflag); goto retry1;
a = (u32*)bp->data; }
addr = a[bn]; }
if (addr == 0) {
a[bn] = addr = balloc(ip->dev); retry2:
bwrite(bp); if ((addr = ip->iaddrs[bn]) == 0) {
} addr = balloc(ip->dev);
if (!__sync_bool_compare_and_swap(&ip->iaddrs[bn], (u32)0, addr)) {
bfree(ip->dev, addr);
goto retry2;
} }
brelse(bp, writerflag);
return addr;
} }
panic("bmap: out of range"); return addr;
} }
// Truncate inode (discard contents). // Truncate inode (discard contents).
......
您添加了 0 到此讨论。请谨慎行事。
请先完成此评论的编辑!
注册 或者 后发表评论