backport of https://github.com/majestrate/XD/commit/4ce9d0ac14a84fcc8a419b46b996de984b1fce79 diff --git a/src/xd/lib/fs/std.go b/src/xd/lib/fs/std.go index 2e2c9f8..76615b2 100644 --- a/src/xd/lib/fs/std.go +++ b/src/xd/lib/fs/std.go @@ -39,7 +39,7 @@ func (f stdFs) OpenFileReadOnly(fname string) (ReadFile, error) { } func (f stdFs) OpenFileWriteOnly(fname string) (WriteFile, error) { - return os.OpenFile(fname, os.O_CREATE|os.O_WRONLY, 0600) + return os.OpenFile(fname, os.O_WRONLY|os.O_CREATE, 0755) } func (f stdFs) RemoveAll(fname string) error { diff --git a/src/xd/lib/mktorrent/mktorrent.go b/src/xd/lib/mktorrent/mktorrent.go index b6a58f7..a7dcaca 100644 --- a/src/xd/lib/mktorrent/mktorrent.go +++ b/src/xd/lib/mktorrent/mktorrent.go @@ -26,10 +26,12 @@ func mkTorrentSingle(f fs.Driver, fpath string, pieceLength uint32) (*metainfo.T err = nil d := sha1.Sum(buff[0:n]) info.Pieces = append(info.Pieces, d[:]...) + info.Length += uint64(n) break } else if err == nil { d := sha1.Sum(buff) info.Pieces = append(info.Pieces, d[:]...) + info.Length += uint64(n) } else { return nil, err } diff --git a/src/xd/lib/storage/fs.go b/src/xd/lib/storage/fs.go index fbe8e91..cd6c630 100644 --- a/src/xd/lib/storage/fs.go +++ b/src/xd/lib/storage/fs.go @@ -100,7 +100,7 @@ func (t *fsTorrent) Allocate() (err error) { return } -func (t fsTorrent) openfileRead(i metainfo.FileInfo) (f fs.ReadFile, err error) { +func (t *fsTorrent) openfileRead(i metainfo.FileInfo) (f fs.ReadFile, err error) { var fname string if t.meta.IsSingleFile() { fname = t.FilePath() @@ -111,7 +111,7 @@ func (t fsTorrent) openfileRead(i metainfo.FileInfo) (f fs.ReadFile, err error) return } -func (t fsTorrent) openfileWrite(i metainfo.FileInfo) (f fs.WriteFile, err error) { +func (t *fsTorrent) openfileWrite(i metainfo.FileInfo) (f fs.WriteFile, err error) { var fname string if t.meta.IsSingleFile() { fname = t.FilePath() @@ -122,7 +122,7 @@ func (t fsTorrent) openfileWrite(i metainfo.FileInfo) (f fs.WriteFile, err error return } -func (t fsTorrent) readFileAt(fi metainfo.FileInfo, b []byte, off int64) (n int, err error) { +func (t *fsTorrent) readFileAt(fi metainfo.FileInfo, b []byte, off int64) (n int, err error) { // from github.com/anacrolix/torrent var f fs.ReadFile @@ -149,6 +149,7 @@ func (t fsTorrent) readFileAt(fi metainfo.FileInfo, b []byte, off int64) (n int, } func (t *fsTorrent) ReadAt(b []byte, off int64) (n int, err error) { + l := len(b) files := t.meta.Info.GetFiles() // from github.com/anacrolix/torrent for _, fi := range files { @@ -158,6 +159,7 @@ func (t *fsTorrent) ReadAt(b []byte, off int64) (n int, err error) { n += n1 off += int64(n1) b = b[n1:] + if len(b) == 0 { // Got what we need. return @@ -299,9 +301,8 @@ func (t *fsTorrent) GetPiece(r common.PieceRequest, pc *common.PieceData) (err e t.access.Lock() sz := t.meta.Info.PieceLength offset := int64(r.Begin) + (int64(sz) * int64(r.Index)) - if pc.Data == nil || uint32(len(pc.Data)) != r.Length { - pc.Data = make([]byte, r.Length) - } + pc.Data = make([]byte, r.Length) + log.Debugf("get piece %d offset=%d len=%d", r.Index, r.Begin, r.Length) if t.st.pooledIO() { iop := readIOP{ offset: offset, @@ -324,20 +325,17 @@ func (t *fsTorrent) GetPiece(r common.PieceRequest, pc *common.PieceData) (err e } func (t *fsTorrent) VerifyPiece(idx uint32) (err error) { - var pc common.PieceData - err = t.verifyPiece(idx, &pc) - return -} - -func (t *fsTorrent) verifyPiece(idx uint32, pc *common.PieceData) (err error) { l := t.meta.LengthOfPiece(idx) r := common.PieceRequest{ Index: idx, Length: l, } - err = t.GetPiece(r, pc) + var pc common.PieceData + pc.Data = make([]byte, l) + pc.Index = idx + err = t.GetPiece(r, &pc) if err == nil { - if t.meta.Info.CheckPiece(pc) { + if t.meta.Info.CheckPiece(&pc) { t.bf.Set(pc.Index) } else { t.bf.Unset(pc.Index) @@ -352,18 +350,15 @@ func (t *fsTorrent) VerifyAll() (err error) { err = ErrNoMetaInfo return } - var pc common.PieceData t.bfmtx.Lock() t.checking = true log.Infof("checking local data for %s", t.Name()) t.ensureBitfield() info := t.MetaInfo().Info sz := info.NumPieces() - pc.Data = make([]byte, info.PieceLength) idx := uint32(0) for idx < sz { - t := t - err = t.verifyPiece(uint32(idx), &pc) + err = t.VerifyPiece(uint32(idx)) if err == common.ErrInvalidPiece { err = nil } else if err != nil { diff --git a/src/xd/lib/storage/storage_test.go b/src/xd/lib/storage/storage_test.go index 1f57421..12339c3 100644 --- a/src/xd/lib/storage/storage_test.go +++ b/src/xd/lib/storage/storage_test.go @@ -6,6 +6,7 @@ import ( "testing" "xd/lib/common" "xd/lib/fs" + "xd/lib/log" "xd/lib/metainfo" "xd/lib/mktorrent" ) @@ -26,6 +27,8 @@ func createRandomTorrent(testFname string) (*metainfo.TorrentFile, error) { func TestStorage(t *testing.T) { + log.SetLevel("debug") + st := &FsStorage{ MetaDir: "storage", DataDir: "data", @@ -61,24 +64,30 @@ func TestStorage(t *testing.T) { } var pc common.PieceData err = torrent.GetPiece(common.PieceRequest{ - Index: 0, + Index: 1, Begin: 0, Length: 16384, }, &pc) if err != nil { + t.Log(err.Error()) t.Fail() return } + log.Infof("put chunk: idx=%d offset=%d", pc.Index, pc.Begin) + err = torrent.PutChunk(&pc) if err != nil { + t.Log(err.Error()) t.Fail() return } - err = torrent.VerifyPiece(0) + log.Infof("verify piece 1") + err = torrent.VerifyPiece(1) if err != nil { + t.Log(err.Error()) t.Fail() return }