anchor.diff:          {_, NewQ} ->
               erlang:monitor(process, Pid),
               {noreply, S#state{putq = NewQ}}
  -    end;
  -
  -handle_call({get_tag_timestamp, TagName}, _From, S) ->
  +    end.
  +
  +do_get_tag_timestamp(TagName, S) ->
       case gb_trees:lookup(TagName, S#state.tags) of
           none ->
  -            {reply, notfound, S};
  +            notfound;
           {value, {_Time, _VolName} = TagNfo} ->
  -            {reply, {ok, TagNfo}, S}
  -    end;
  -
  -handle_call({get_tag_data, TagName, TagNfo}, From, S) ->
  -    spawn(fun() ->
  -        read_tag(TagName, S#state.nodename, S#state.root, TagNfo, From)
  -    end),
  -    {noreply, S};
  -
  -handle_call({put_tag_data, {Tag, Data}}, _From, S) ->
  +            {ok, TagNfo}
  +    end.
  +
  +do_get_tag_data(Tag, VolName, From, S) ->
  +    {ok, TagDir, _Url} = ddfs_util:hashdir(Tag,
  +                                           disco:host(node()),
  +                                           "tag",
  +                                           S#state.root,
  +                                           VolName),
  +    TagPath = filename:join(TagDir, binary_to_list(Tag)),
  +    case prim_file:read_file(TagPath) of
  +        {ok, Binary} ->
  +            gen_server:reply(From, {ok, Binary});
  +        {error, Reason} ->
  +            error_logger:warning_report({"Read failed", TagPath, Reason}),
  +            gen_server:reply(From, {error, read_failed})
  +    end.
  +
  +do_put_tag_data(Tag, Data, S) ->
       {_Space, VolName} = choose_vol(S#state.vols),
       {ok, Local, _} = ddfs_util:hashdir(Tag,
                                          S#state.nodename,
  
positive.code:         {_, NewQ} ->
              erlang:monitor(process, Pid),
              {noreply, S#state{getq = NewQ}}
      end;
  
  handle_call(get_diskspace, _From, #state{vols = Vols} = S) ->
      {reply, lists:foldl(fun ({{Free, Used}, _VolName}, {TotalFree, TotalUsed}) ->
                                  {TotalFree + Free, TotalUsed + Used}
                          end, {0, 0}, Vols), S};
  
  handle_call({put_blob, BlobName}, {Pid, _Ref} = From, #state{putq = Q} = S) ->
      Reply = fun() ->
                      {_Space, VolName} = choose_vol(S#state.vols),
                      {ok, Local, Url} = ddfs_util:hashdir(list_to_binary(BlobName),
  
negative.code:     Dst = filename:join(Local,  TagL),
      case ddfs_util:safe_rename(Src, Dst) of
          ok ->
              {{ok, Url},
               S#state{tags = gb_trees:enter(TagName,
                                             {Time, VolName},
                                             S#state.tags)}};
          {error, _} = E ->
              {E, S}
      end.
  
  -spec init_vols(nonempty_string(), [nonempty_string(),...]) ->
  