Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

disk method support error #3

Open
wants to merge 1 commit into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion addr/addr.go
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
package addr

import (
"github.com/tchajed/goose/machine/disk"
"github.com/mit-pdos/go-journal/disk"

"github.com/mit-pdos/go-journal/common"
)
Expand Down
13 changes: 8 additions & 5 deletions buf/buf.go
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@
package buf

import (
"github.com/tchajed/goose/machine/disk"
"github.com/mit-pdos/go-journal/disk"
"github.com/tchajed/marshal"

"github.com/mit-pdos/go-journal/addr"
Expand Down Expand Up @@ -93,14 +93,17 @@ func (buf *Buf) SetDirty() {
buf.dirty = true
}

func (buf *Buf) WriteDirect(d disk.Disk) {
func (buf *Buf) WriteDirect(d disk.Disk) error {
buf.SetDirty()
if buf.Sz == disk.BlockSize {
d.Write(uint64(buf.Addr.Blkno), buf.Data)
return d.Write(uint64(buf.Addr.Blkno), buf.Data)
} else {
blk := d.Read(uint64(buf.Addr.Blkno))
blk, err := d.Read(uint64(buf.Addr.Blkno))
if err != nil {
return err
}
buf.Install(blk)
d.Write(uint64(buf.Addr.Blkno), blk)
return d.Write(uint64(buf.Addr.Blkno), blk)
}
}

Expand Down
2 changes: 1 addition & 1 deletion buf/buf_test.go
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
package buf

import (
"github.com/tchajed/goose/machine/disk"
"github.com/mit-pdos/go-journal/disk"

"testing"

Expand Down
2 changes: 1 addition & 1 deletion common/common.go
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
package common

import (
"github.com/tchajed/goose/machine/disk"
"github.com/mit-pdos/go-journal/disk"
)

const (
Expand Down
36 changes: 36 additions & 0 deletions disk/disk.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
package disk

// Block is a 4096-byte buffer
type Block = []byte

const BlockSize uint64 = 4096 //128 // 32 // 4096

// Disk provides access to a logical block-based disk
type Disk interface {
// Read reads a disk block by address
//
// Expects a < Size().
Read(a uint64) (Block, error)

// ReadTo reads the disk block at a and stores the result in b
//
// Expects a < Size().
ReadTo(a uint64, b Block) error

// Write updates a disk block by address
//
// Expects a < Size().
Write(a uint64, v Block) error

// Size reports how big the disk is, in blocks
Size() (uint64, error)

// Barrier ensures data is persisted.
//
// When it returns, all outstanding writes are guaranteed to be durably on
// disk
Barrier() error

// Close releases any resources used by the disk and makes it unusable.
Close() error
}
147 changes: 147 additions & 0 deletions disk/disk_impl.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,147 @@
package disk

import (
"fmt"
"sync"

"golang.org/x/sys/unix"
)

var _ Disk = (*fileDisk)(nil)

type fileDisk struct {
fd int
numBlocks uint64
}

func NewFileDisk(path string, numBlocks uint64) (fileDisk, error) {
fd, err := unix.Open(path, unix.O_RDWR|unix.O_CREAT, 0666)
if err != nil {
return fileDisk{}, err
}
var stat unix.Stat_t
err = unix.Fstat(fd, &stat)
if err != nil {
return fileDisk{}, err
}
if (stat.Mode&unix.S_IFREG) != 0 && uint64(stat.Size) != numBlocks {
err = unix.Ftruncate(fd, int64(numBlocks*BlockSize))
if err != nil {
return fileDisk{}, err
}
}
return fileDisk{fd, numBlocks}, nil
}

// var _ Disk = FileDisk{}

func (d fileDisk) ReadTo(a uint64, buf Block) error {
if uint64(len(buf)) != BlockSize {
panic("buffer is not block-sized")
}
if a >= d.numBlocks {
panic(fmt.Errorf("out-of-bounds read at %v", a))
}
_, err := unix.Pread(d.fd, buf, int64(a*BlockSize))
if err != nil {
panic("read failed: " + err.Error())
}
fmt.Printf("read: %v-%v\n", a, buf)
return nil
}

func (d fileDisk) Read(a uint64) (Block, error) {
buf := make([]byte, BlockSize)
err := d.ReadTo(a, buf)
return buf, err
}

func (d fileDisk) Write(a uint64, v Block) error {
if uint64(len(v)) != BlockSize {
panic(fmt.Errorf("v is not block sized (%d bytes)", len(v)))
}
if a >= d.numBlocks {
panic(fmt.Errorf("out-of-bounds write at %v", a))
}
_, err := unix.Pwrite(d.fd, v, int64(a*BlockSize))
if err != nil {
panic("write failed: " + err.Error())
}
fmt.Printf("write: %v-%v\n", a, v)
return nil
}

func (d fileDisk) Size() (uint64, error) {
return d.numBlocks, nil
}

func (d fileDisk) Barrier() error {
// NOTE: on macOS, this flushes to the drive but doesn't actually issue a
// disk barrier; see https://golang.org/src/internal/poll/fd_fsync_darwin.go
// for more details. The correct replacement is to issue a fcntl syscall with
// cmd F_FULLFSYNC.
err := unix.Fsync(d.fd)
if err != nil {
panic("file sync failed: " + err.Error())
}
fmt.Printf("barrier\n")
return nil
}

func (d fileDisk) Close() error {
err := unix.Close(d.fd)
if err != nil {
panic(err)
}
return nil
}

var _ Disk = (*memDisk)(nil)

type memDisk struct {
l *sync.RWMutex
blocks [][BlockSize]byte
}

func NewMemDisk(numBlocks uint64) memDisk {
blocks := make([][BlockSize]byte, numBlocks)
return memDisk{l: new(sync.RWMutex), blocks: blocks}
}

func (d memDisk) ReadTo(a uint64, buf Block) error {
d.l.RLock()
defer d.l.RUnlock()
if a >= uint64(len(d.blocks)) {
panic(fmt.Errorf("out-of-bounds read at %v", a))
}
copy(buf, d.blocks[a][:])
return nil
}

func (d memDisk) Read(a uint64) (Block, error) {
buf := make(Block, BlockSize)
d.ReadTo(a, buf)
return buf, nil
}

func (d memDisk) Write(a uint64, v Block) error {
if uint64(len(v)) != BlockSize {
panic(fmt.Errorf("v is not block-sized (%d bytes)", len(v)))
}
d.l.Lock()
defer d.l.Unlock()
if a >= uint64(len(d.blocks)) {
panic(fmt.Errorf("out-of-bounds write at %v", a))
}
copy(d.blocks[a][:], v)
return nil
}

func (d memDisk) Size() (uint64, error) {
// this never changes so we assume it's safe to run lock-free
return uint64(len(d.blocks)), nil
}

func (d memDisk) Barrier() error { return nil }

func (d memDisk) Close() error { return nil }
2 changes: 1 addition & 1 deletion go.mod
Original file line number Diff line number Diff line change
Expand Up @@ -6,5 +6,5 @@ require (
github.com/stretchr/testify v1.8.4
github.com/tchajed/goose v0.5.3
github.com/tchajed/marshal v0.4.3
golang.org/x/sys v0.16.0 // indirect
golang.org/x/sys v0.6.0
)
9 changes: 1 addition & 8 deletions go.sum
Original file line number Diff line number Diff line change
Expand Up @@ -38,7 +38,6 @@ github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+
github.com/stretchr/objx v0.4.0/go.mod h1:YvHI0jy2hoMjB+UWwv71VJQ9isScKT/TqJzVSSt89Yw=
github.com/stretchr/objx v0.5.0/go.mod h1:Yh+to48EsGEfYuaHDzXPcE3xhTkx73EhmCGUpEOglKo=
github.com/stretchr/testify v1.4.0/go.mod h1:j7eGeouHqKxXV5pUuKE4zz7dFj8WfuZ+81PSLYec5m4=
github.com/stretchr/testify v1.6.1 h1:hDPOHmpOpP40lSULcqw7IrRb/u7w6RpDC9399XyoNd0=
github.com/stretchr/testify v1.6.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg=
github.com/stretchr/testify v1.7.0/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg=
github.com/stretchr/testify v1.7.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg=
Expand All @@ -48,15 +47,13 @@ github.com/stretchr/testify v1.8.4/go.mod h1:sz/lmYIOXD/1dqDmKjjqLyZ2RngseejIcXl
github.com/tchajed/goose v0.0.0-20191114201541-ebbf1d75c8ca/go.mod h1:2c33VcNcIHG8vQhprFmBlZxpC62+TfmnGjB+jVaKhXo=
github.com/tchajed/goose v0.0.0-20200128225509-92a5cfe01fc4/go.mod h1:rhep/Jc/mYPoMIYG8dPtnc71UHAPHNYRx1qvpB245Ss=
github.com/tchajed/goose v0.2.0/go.mod h1:Y2zBxxd3wa0lrYRDyebxZgbgV4LLsPUtsBiLe1wnS9c=
github.com/tchajed/goose v0.3.1 h1:pofh2XDZR5lt+WYgKBZbHwyD2QPgea/37gRbLa2AecI=
github.com/tchajed/goose v0.3.1/go.mod h1:s6D4ibH0SaPtDcp0krx05XkZLlqipgRyRH8X6JP+hcc=
github.com/tchajed/goose v0.4.4/go.mod h1:w5NCIqICRsj0OJfTuft7HO2H51u629Qn0d+wxZsu6Eo=
github.com/tchajed/goose v0.5.3 h1:+Ag8wwWfsQZfsTSW953HfDvJmzQ6YopLsfnTNzcd/ZE=
github.com/tchajed/goose v0.5.3/go.mod h1:ISQLiMmllwxTyKhi5wn/PKE3CeseL6Jnvv3CCWOHvVE=
github.com/tchajed/mailboat v0.0.0-20191026015926-338a5b81ac1d/go.mod h1:dmgNTEH0kreeKMWd+ntzsrp7ie2LWHGMe7VxP6d1Aew=
github.com/tchajed/mailboat v0.2.0/go.mod h1:aKa/T1YCMVZFM2xbXnMNyp9r4k0pPni4+sJ8GoY51Hw=
github.com/tchajed/marshal v0.0.0-20200707011626-0d2aa09818a9/go.mod h1:TPo3bTYJkH87/4rXlxe0bpVWLnN+b5kjJnoXHLBfdaA=
github.com/tchajed/marshal v0.2.0 h1:6syf2SG3//AE891aHhj6BS+fv3OCMxFM322x05ot3QE=
github.com/tchajed/marshal v0.2.0/go.mod h1:jq2B5uP+QvY51sZB57Td/OsareaZEzm3HVuvVKhC22I=
github.com/tchajed/marshal v0.4.3 h1:dnLvl3JDzWMAj2xyCSWxiOr5PcZlu++KdPdl1/Ts51g=
github.com/tchajed/marshal v0.4.3/go.mod h1:tdiYzC42jUHdvBWrJYa7LytEbHEV2zA+nI3TLLb/nvU=
Expand Down Expand Up @@ -99,18 +96,15 @@ golang.org/x/sys v0.0.0-20210423082822-04245dca01da/go.mod h1:h1NjWce9XRLGQEsW7w
golang.org/x/sys v0.0.0-20210510120138-977fb7262007/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.0.0-20210615035016-665e8c7367d1/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.0.0-20210630005230-0f9fa26af87c/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.0.0-20210823070655-63515b42dcdf h1:2ucpDCmfkl8Bd/FsLtiD653Wf96cW37s+iGx93zsu4k=
golang.org/x/sys v0.0.0-20210823070655-63515b42dcdf/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.0.0-20210927094055-39ccf1dd6fa6/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.0.0-20211019181941-9d821ace8654/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.0.0-20220319134239-a9b59b0215f8/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.0.0-20220520151302-bc2c85ada10a/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.0.0-20220722155257-8c9f86f7a55f/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.0.0-20220811171246-fbc7d0a398ab/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.5.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.6.0 h1:MVltZSvRTcU2ljQOhs94SXPftV6DCNnZViHeQps87pQ=
golang.org/x/sys v0.6.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.16.0 h1:xWw16ngr6ZMtmxDyKyIgsE93KNKz5HKmMa3b8ALHidU=
golang.org/x/sys v0.16.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA=
golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo=
golang.org/x/term v0.0.0-20210927222741-03fcf44c2211/go.mod h1:jbD1KX2456YbFQfuXm/mYQcufACuNUgVhRMnK/tPxf8=
golang.org/x/term v0.5.0/go.mod h1:jMB1sMXY+tzblOD4FWmEbocvup2/aLOaQEp7JmGp78k=
Expand Down Expand Up @@ -139,7 +133,6 @@ gopkg.in/yaml.v2 v2.2.2/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
gopkg.in/yaml.v2 v2.2.5/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
gopkg.in/yaml.v2 v2.2.8/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
gopkg.in/yaml.v3 v3.0.0-20200615113413-eeeca48fe776 h1:tQIYjPdBoyREyB9XMu+nnTclpTYkz2zFM+lzLJFO4gQ=
gopkg.in/yaml.v3 v3.0.0-20200615113413-eeeca48fe776/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA=
gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
23 changes: 14 additions & 9 deletions jrnl/jrnl.go
Original file line number Diff line number Diff line change
Expand Up @@ -35,16 +35,18 @@ package jrnl
import (
"github.com/mit-pdos/go-journal/addr"
"github.com/mit-pdos/go-journal/buf"
"github.com/mit-pdos/go-journal/disk"
"github.com/mit-pdos/go-journal/obj"
"github.com/mit-pdos/go-journal/util"
"github.com/mit-pdos/go-journal/wal"
)

// LogBlocks is the maximum number of blocks that can be written in one
// operation
const LogBlocks uint64 = 511
const LogBlocks uint64 = wal.LOGSZ //3

// LogBytes is the maximum size of an operation, in bytes
const LogBytes uint64 = 4096 * 511
const LogBytes uint64 = disk.BlockSize * LogBlocks

// Op is an in-progress journal operation.
//
Expand All @@ -66,14 +68,17 @@ func Begin(log *obj.Log) *Op {
return trans
}

func (op *Op) ReadBuf(addr addr.Addr, sz uint64) *buf.Buf {
func (op *Op) ReadBuf(addr addr.Addr, sz uint64) (*buf.Buf, error) {
b := op.bufs.Lookup(addr)
if b == nil {
buf := op.log.Load(addr, sz)
buf, err := op.log.Load(addr, sz)
if err != nil {
return nil, err
}
op.bufs.Insert(buf)
return op.bufs.Lookup(addr)
return op.bufs.Lookup(addr), nil
}
return b
return b, nil
}

// OverWrite writes an object to addr
Expand Down Expand Up @@ -111,8 +116,8 @@ func (op *Op) NDirty() uint64 {
//
// wait=false is an asynchronous commit, which can be made durable later with
// Flush.
func (op *Op) CommitWait(wait bool) bool {
func (op *Op) CommitWait(wait bool) error {
util.DPrintf(3, "Commit %p w %v\n", op, wait)
ok := op.log.CommitWait(op.bufs.DirtyBufs(), wait)
return ok
err := op.log.CommitWait(op.bufs.DirtyBufs(), wait)
return err
}
Loading