Skip to content

Commit 0906d7f

Browse files
aschmahmannStebalien
authored andcommitted
fix (pinning): pin ls traverses all indirect pins. pin ls pin type precedence change - a direct/recursive pin is now labeled as such even if also indirectly pinned.
1 parent 59834fd commit 0906d7f

File tree

5 files changed

+136
-114
lines changed

5 files changed

+136
-114
lines changed

core/commands/pin.go

Lines changed: 24 additions & 68 deletions
Original file line numberDiff line numberDiff line change
@@ -11,13 +11,15 @@ import (
1111
core "github.com/ipfs/go-ipfs/core"
1212
cmdenv "github.com/ipfs/go-ipfs/core/commands/cmdenv"
1313
e "github.com/ipfs/go-ipfs/core/commands/e"
14+
coreapi "github.com/ipfs/go-ipfs/core/coreapi"
1415
pin "github.com/ipfs/go-ipfs/pin"
1516

1617
bserv "github.com/ipfs/go-blockservice"
1718
cid "github.com/ipfs/go-cid"
1819
cidenc "github.com/ipfs/go-cidutil/cidenc"
1920
cmds "github.com/ipfs/go-ipfs-cmds"
2021
offline "github.com/ipfs/go-ipfs-exchange-offline"
22+
ipld "github.com/ipfs/go-ipld-format"
2123
dag "github.com/ipfs/go-merkledag"
2224
verifcid "github.com/ipfs/go-verifcid"
2325
coreiface "github.com/ipfs/interface-go-ipfs-core"
@@ -352,7 +354,7 @@ Example:
352354
if len(req.Arguments) > 0 {
353355
err = pinLsKeys(req, typeStr, n, api, emit)
354356
} else {
355-
err = pinLsAll(req, typeStr, n, emit)
357+
err = pinLsAll(req, typeStr, n.Pinning, n.DAG, emit)
356358
}
357359
if err != nil {
358360
return err
@@ -475,84 +477,38 @@ func pinLsKeys(req *cmds.Request, typeStr string, n *core.IpfsNode, api coreifac
475477
return nil
476478
}
477479

478-
func pinLsAll(req *cmds.Request, typeStr string, n *core.IpfsNode, emit func(value interface{}) error) error {
480+
func pinLsAll(req *cmds.Request, typeStr string, pinning pin.Pinner, dag ipld.DAGService, emit func(value interface{}) error) error {
481+
pinCh, errCh := coreapi.PinLsAll(req.Context, typeStr, pinning, dag)
482+
479483
enc, err := cmdenv.GetCidEncoder(req)
480484
if err != nil {
481485
return err
482486
}
483487

484-
keys := cid.NewSet()
485-
486-
AddToResultKeys := func(keyList []cid.Cid, typeStr string) error {
487-
for _, c := range keyList {
488-
if keys.Visit(c) {
489-
err := emit(&PinLsOutputWrapper{
490-
PinLsObject: PinLsObject{
491-
Type: typeStr,
492-
Cid: enc.Encode(c),
493-
},
494-
})
495-
if err != nil {
496-
return err
497-
}
488+
ctx := req.Context
489+
loop:
490+
for {
491+
select {
492+
case p, ok := <-pinCh:
493+
if !ok {
494+
break loop
498495
}
499-
}
500-
return nil
501-
}
502-
503-
if typeStr == "direct" || typeStr == "all" {
504-
dkeys, err := n.Pinning.DirectKeys(req.Context)
505-
if err != nil {
506-
return err
507-
}
508-
err = AddToResultKeys(dkeys, "direct")
509-
if err != nil {
510-
return err
511-
}
512-
}
513-
if typeStr == "recursive" || typeStr == "all" {
514-
rkeys, err := n.Pinning.RecursiveKeys(req.Context)
515-
if err != nil {
516-
return err
517-
}
518-
err = AddToResultKeys(rkeys, "recursive")
519-
if err != nil {
520-
return err
521-
}
522-
}
523-
if typeStr == "indirect" || typeStr == "all" {
524-
rkeys, err := n.Pinning.RecursiveKeys(req.Context)
525-
if err != nil {
526-
return err
527-
}
528-
for _, k := range rkeys {
529-
var visitErr error
530-
err := dag.Walk(req.Context, dag.GetLinksWithDAG(n.DAG), k, func(c cid.Cid) bool {
531-
r := keys.Visit(c)
532-
if r {
533-
err := emit(&PinLsOutputWrapper{
534-
PinLsObject: PinLsObject{
535-
Type: "indirect",
536-
Cid: enc.Encode(c),
537-
},
538-
})
539-
if err != nil {
540-
visitErr = err
541-
}
542-
}
543-
return r
544-
}, dag.SkipRoot(), dag.Concurrent())
545-
546-
if visitErr != nil {
547-
return visitErr
548-
}
549-
if err != nil {
496+
if err := emit(&PinLsOutputWrapper{
497+
PinLsObject: PinLsObject{
498+
Type: p.Type(),
499+
Cid: enc.Encode(p.Path().Cid()),
500+
},
501+
}); err != nil {
550502
return err
551503
}
504+
505+
case <-ctx.Done():
506+
return ctx.Err()
552507
}
553508
}
554509

555-
return nil
510+
err = <-errCh
511+
return err
556512
}
557513

558514
const (

core/coreapi/pin.go

Lines changed: 108 additions & 42 deletions
Original file line numberDiff line numberDiff line change
@@ -3,14 +3,15 @@ package coreapi
33
import (
44
"context"
55
"fmt"
6-
76
bserv "github.com/ipfs/go-blockservice"
8-
cid "github.com/ipfs/go-cid"
7+
"github.com/ipfs/go-cid"
98
offline "github.com/ipfs/go-ipfs-exchange-offline"
10-
merkledag "github.com/ipfs/go-merkledag"
9+
"github.com/ipfs/go-ipfs/pin"
10+
ipld "github.com/ipfs/go-ipld-format"
11+
"github.com/ipfs/go-merkledag"
1112
coreiface "github.com/ipfs/interface-go-ipfs-core"
1213
caopts "github.com/ipfs/interface-go-ipfs-core/options"
13-
path "github.com/ipfs/interface-go-ipfs-core/path"
14+
"github.com/ipfs/interface-go-ipfs-core/path"
1415
)
1516

1617
type PinAPI CoreAPI
@@ -194,57 +195,122 @@ func (p *pinInfo) Type() string {
194195
}
195196

196197
func (api *PinAPI) pinLsAll(typeStr string, ctx context.Context) ([]coreiface.Pin, error) {
198+
pinCh, errCh := PinLsAll(ctx, typeStr, api.pinning, api.dag)
199+
200+
var pins []coreiface.Pin
201+
loop:
202+
for {
203+
select {
204+
case p, ok := <-pinCh:
205+
if !ok {
206+
break loop
207+
}
208+
pins = append(pins, p)
209+
case <-ctx.Done():
210+
return nil, ctx.Err()
211+
}
212+
}
213+
err := <-errCh
214+
if err != nil {
215+
return nil, err
216+
}
217+
218+
return pins, nil
219+
}
197220

198-
keys := make(map[cid.Cid]*pinInfo)
221+
// PinLsAll is an internal function for returning a list of pins
222+
func PinLsAll(ctx context.Context, typeStr string, pin pin.Pinner, dag ipld.DAGService) (chan coreiface.Pin, chan error) {
223+
ch := make(chan coreiface.Pin, 32)
224+
errCh := make(chan error, 1)
199225

200-
AddToResultKeys := func(keyList []cid.Cid, typeStr string) {
226+
keys := cid.NewSet()
227+
AddToResultKeys := func(keyList []cid.Cid, typeStr string) error {
201228
for _, c := range keyList {
202-
keys[c] = &pinInfo{
203-
pinType: typeStr,
204-
path: path.IpldPath(c),
229+
if keys.Visit(c) {
230+
select {
231+
case ch <- &pinInfo{
232+
pinType: typeStr,
233+
path: path.IpldPath(c),
234+
}:
235+
case <-ctx.Done():
236+
return ctx.Err()
237+
}
205238
}
206239
}
240+
return nil
207241
}
208242

209-
if typeStr == "direct" || typeStr == "all" {
210-
dkeys, err := api.pinning.DirectKeys(ctx)
211-
if err != nil {
212-
return nil, err
213-
}
214-
AddToResultKeys(dkeys, "direct")
215-
}
216-
if typeStr == "indirect" || typeStr == "all" {
217-
set := cid.NewSet()
218-
rkeys, err := api.pinning.RecursiveKeys(ctx)
219-
if err != nil {
220-
return nil, err
221-
}
222-
for _, k := range rkeys {
223-
err := merkledag.Walk(
224-
ctx, merkledag.GetLinksWithDAG(api.dag), k,
225-
set.Visit,
226-
merkledag.SkipRoot(), merkledag.Concurrent(),
227-
)
243+
go func() {
244+
defer close(ch)
245+
defer close(errCh)
246+
if typeStr == "direct" || typeStr == "all" {
247+
dkeys, err := pin.DirectKeys(ctx)
228248
if err != nil {
229-
return nil, err
249+
errCh <- err
250+
return
251+
}
252+
if err := AddToResultKeys(dkeys, "direct"); err != nil {
253+
errCh <- err
254+
return
230255
}
231256
}
232-
AddToResultKeys(set.Keys(), "indirect")
233-
}
234-
if typeStr == "recursive" || typeStr == "all" {
235-
rkeys, err := api.pinning.RecursiveKeys(ctx)
236-
if err != nil {
237-
return nil, err
257+
if typeStr == "recursive" || typeStr == "all" {
258+
rkeys, err := pin.RecursiveKeys(ctx)
259+
if err != nil {
260+
errCh <- err
261+
return
262+
}
263+
if err := AddToResultKeys(rkeys, "recursive"); err != nil {
264+
errCh <- err
265+
return
266+
}
238267
}
239-
AddToResultKeys(rkeys, "recursive")
240-
}
268+
if typeStr == "indirect" || typeStr == "all" {
269+
rkeys, err := pin.RecursiveKeys(ctx)
270+
if err != nil {
271+
errCh <- err
272+
return
273+
}
241274

242-
out := make([]coreiface.Pin, 0, len(keys))
243-
for _, v := range keys {
244-
out = append(out, v)
245-
}
275+
// If we're only listing indirect pins, we need to
276+
// explicitly mark direct/recursive pins so we don't
277+
// send them.
278+
if typeStr == "indirect" {
279+
dkeys, err := pin.DirectKeys(ctx)
280+
if err != nil {
281+
errCh <- err
282+
return
283+
}
284+
285+
for _, k := range dkeys {
286+
keys.Add(k)
287+
}
288+
for _, k := range rkeys {
289+
keys.Add(k)
290+
}
291+
}
246292

247-
return out, nil
293+
indirectKeys := cid.NewSet()
294+
for _, k := range rkeys {
295+
err := merkledag.Walk(ctx, merkledag.GetLinksWithDAG(dag), k, func(c cid.Cid) bool {
296+
r := indirectKeys.Visit(c)
297+
if r {
298+
if err := AddToResultKeys([]cid.Cid{c}, "indirect"); err != nil {
299+
return false
300+
}
301+
}
302+
return r
303+
}, merkledag.SkipRoot(), merkledag.Concurrent())
304+
305+
if err != nil {
306+
errCh <- err
307+
return
308+
}
309+
}
310+
}
311+
}()
312+
313+
return ch, errCh
248314
}
249315

250316
func (api *PinAPI) core() coreiface.CoreAPI {

core/coreapi/unixfs.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -32,7 +32,7 @@ type UnixfsAPI CoreAPI
3232
var nilNode *core.IpfsNode
3333
var once sync.Once
3434

35-
func getOrCreateNilNode() (*core.IpfsNode,error) {
35+
func getOrCreateNilNode() (*core.IpfsNode, error) {
3636
once.Do(func() {
3737
if nilNode != nil {
3838
return

go.mod

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -51,7 +51,7 @@ require (
5151
github.com/ipfs/go-path v0.0.7
5252
github.com/ipfs/go-unixfs v0.2.1
5353
github.com/ipfs/go-verifcid v0.0.1
54-
github.com/ipfs/interface-go-ipfs-core v0.2.3
54+
github.com/ipfs/interface-go-ipfs-core v0.2.5
5555
github.com/jbenet/go-is-domain v1.0.3
5656
github.com/jbenet/go-random v0.0.0-20190219211222-123a90aedc0c
5757
github.com/jbenet/go-temp-err-catcher v0.0.0-20150120210811-aac704a3f4f2

go.sum

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -259,8 +259,8 @@ github.com/ipfs/go-unixfs v0.2.1 h1:g51t9ODICFZ3F51FPivm8dE7NzYcdAQNUL9wGP5AYa0=
259259
github.com/ipfs/go-unixfs v0.2.1/go.mod h1:IwAAgul1UQIcNZzKPYZWOCijryFBeCV79cNubPzol+k=
260260
github.com/ipfs/go-verifcid v0.0.1 h1:m2HI7zIuR5TFyQ1b79Da5N9dnnCP1vcu2QqawmWlK2E=
261261
github.com/ipfs/go-verifcid v0.0.1/go.mod h1:5Hrva5KBeIog4A+UpqlaIU+DEstipcJYQQZc0g37pY0=
262-
github.com/ipfs/interface-go-ipfs-core v0.2.3 h1:E6uQ+1fJjkxJWlL9lAE72a5FWeyeeNL3GitLy8+jq3Y=
263-
github.com/ipfs/interface-go-ipfs-core v0.2.3/go.mod h1:Tihp8zxGpUeE3Tokr94L6zWZZdkRQvG5TL6i9MuNE+s=
262+
github.com/ipfs/interface-go-ipfs-core v0.2.5 h1:/rspOe8RbIxwtssEXHB+X9JXhOBDCQt8x50d2kFPXL8=
263+
github.com/ipfs/interface-go-ipfs-core v0.2.5/go.mod h1:Tihp8zxGpUeE3Tokr94L6zWZZdkRQvG5TL6i9MuNE+s=
264264
github.com/jackpal/gateway v1.0.4/go.mod h1:lTpwd4ACLXmpyiCTRtfiNyVnUmqT9RivzCDQetPfnjA=
265265
github.com/jackpal/gateway v1.0.5 h1:qzXWUJfuMdlLMtt0a3Dgt+xkWQiA5itDEITVJtuSwMc=
266266
github.com/jackpal/gateway v1.0.5/go.mod h1:lTpwd4ACLXmpyiCTRtfiNyVnUmqT9RivzCDQetPfnjA=

0 commit comments

Comments
 (0)