Skip to content

Commit

Permalink
Reduce redundant stat calls when statting by resource ID (#2208)
Browse files Browse the repository at this point in the history
  • Loading branch information
ishank011 committed Oct 28, 2021
1 parent 9203c5b commit 4157eed
Show file tree
Hide file tree
Showing 3 changed files with 67 additions and 35 deletions.
3 changes: 3 additions & 0 deletions changelog/unreleased/reduce-redundant-stat-calls.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
Enhancement: Reduce redundant stat calls when statting by resource ID

https://github.com/cs3org/reva/pull/2208
66 changes: 43 additions & 23 deletions internal/grpc/services/gateway/storageprovider.go
Original file line number Diff line number Diff line change
Expand Up @@ -1345,16 +1345,28 @@ func (s *svc) statAcrossProviders(ctx context.Context, req *provider.StatRequest
}

func (s *svc) Stat(ctx context.Context, req *provider.StatRequest) (*provider.StatResponse, error) {

if utils.IsRelativeReference(req.Ref) {
return s.stat(ctx, req)
}

p, st := s.getPath(ctx, req.Ref, req.ArbitraryMetadataKeys...)
if st.Code != rpc.Code_CODE_OK {
return &provider.StatResponse{
Status: st,
}, nil
p := ""
var res *provider.StatResponse
var err error
if utils.IsAbsolutePathReference(req.Ref) {
p = req.Ref.Path
} else {
// Reference by just resource ID
// Stat it and store for future use
res, err = s.stat(ctx, req)
if err != nil {
return &provider.StatResponse{
Status: status.NewInternal(ctx, err, "gateway: error stating ref:"+req.Ref.String()),
}, nil
}
if res != nil && res.Status.Code != rpc.Code_CODE_OK {
return res, nil
}
p = res.Info.Path
}

if path.Clean(p) == s.getHome(ctx) {
Expand All @@ -1366,33 +1378,41 @@ func (s *svc) Stat(ctx context.Context, req *provider.StatRequest) (*provider.St
}

if !s.inSharedFolder(ctx, p) {
if res != nil {
return res, nil
}
return s.stat(ctx, req)
}

// we need to provide the info of the target, not the reference.
if s.isShareName(ctx, p) {
statRes, err := s.stat(ctx, req)
if err != nil {
return &provider.StatResponse{
Status: status.NewInternal(ctx, err, "gateway: error stating ref:"+req.Ref.String()),
}, nil
}
// If we haven't returned an error by now and res is nil, it means that
// req is an absolute path based ref, so we didn't stat it previously.
// So stat it now
if res == nil {
res, err = s.stat(ctx, req)
if err != nil {
return &provider.StatResponse{
Status: status.NewInternal(ctx, err, "gateway: error stating ref:"+req.Ref.String()),
}, nil
}

if statRes.Status.Code != rpc.Code_CODE_OK {
return &provider.StatResponse{
Status: statRes.Status,
}, nil
if res.Status.Code != rpc.Code_CODE_OK {
return &provider.StatResponse{
Status: res.Status,
}, nil
}
}

ri, protocol, err := s.checkRef(ctx, statRes.Info)
ri, protocol, err := s.checkRef(ctx, res.Info)
if err != nil {
return &provider.StatResponse{
Status: status.NewStatusFromErrType(ctx, "error resolving reference "+statRes.Info.Target, err),
Status: status.NewStatusFromErrType(ctx, "error resolving reference "+res.Info.Target, err),
}, nil
}

if protocol == "webdav" {
ri, err = s.webdavRefStat(ctx, statRes.Info.Target)
ri, err = s.webdavRefStat(ctx, res.Info.Target)
if err != nil {
return &provider.StatResponse{
Status: status.NewInternal(ctx, err, "gateway: error resolving webdav reference: "+p),
Expand All @@ -1404,10 +1424,10 @@ func (s *svc) Stat(ctx context.Context, req *provider.StatRequest) (*provider.St
// information. For example, if requests comes to: /home/MyShares/photos and photos
// is reference to /user/peter/Holidays/photos, we need to still return to the user
// /home/MyShares/photos
orgPath := statRes.Info.Path
statRes.Info = ri
statRes.Info.Path = orgPath
return statRes, nil
orgPath := res.Info.Path
res.Info = ri
res.Info.Path = orgPath
return res, nil

}

Expand Down
33 changes: 21 additions & 12 deletions pkg/storage/utils/eosfs/eosfs.go
Original file line number Diff line number Diff line change
Expand Up @@ -772,11 +772,30 @@ func (fs *eosfs) GetMD(ctx context.Context, ref *provider.Reference, mdKeys []st
log := appctx.GetLogger(ctx)
log.Info().Msg("eosfs: get md for ref:" + ref.String())

p, err := fs.resolve(ctx, ref)
u, err := getUser(ctx)
if err != nil {
return nil, errors.Wrap(err, "eosfs: error resolving reference")
return nil, err
}
auth, err := fs.getUserAuth(ctx, u, "")
if err != nil {
return nil, err
}

if ref.ResourceId != nil {
fid, err := strconv.ParseUint(ref.ResourceId.OpaqueId, 10, 64)
if err != nil {
return nil, fmt.Errorf("error converting string to int for eos fileid: %s", ref.ResourceId.OpaqueId)
}

eosFileInfo, err := fs.c.GetFileInfoByInode(ctx, auth, fid)
if err != nil {
return nil, err
}
return fs.convertToResourceInfo(ctx, eosFileInfo)
}

p := ref.Path

// if path is home we need to add in the response any shadow folder in the shadow homedirectory.
if fs.conf.EnableHome {
if fs.isShareFolder(ctx, p) {
Expand All @@ -785,16 +804,6 @@ func (fs *eosfs) GetMD(ctx context.Context, ref *provider.Reference, mdKeys []st
}

fn := fs.wrap(ctx, p)

u, err := getUser(ctx)
if err != nil {
return nil, err
}
auth, err := fs.getUserAuth(ctx, u, fn)
if err != nil {
return nil, err
}

eosFileInfo, err := fs.c.GetFileInfoByPath(ctx, auth, fn)
if err != nil {
return nil, err
Expand Down

0 comments on commit 4157eed

Please sign in to comment.