anchor.diff:  
   -spec do_put_tag_commit(tagname(), [{node(), volume_name()}], #state{}) ->
                          {{'ok', url()} | {'error', _}, #state{}}.
  -do_put_tag_commit(Tag, TagVol, S) ->
  +do_put_tag_commit(Tag, TagVol, #state{nodename = NodeName,
  +                                      root = Root,
  +                                      tags = Tags} = S) ->
       {_, VolName} = lists:keyfind(node(), 1, TagVol),
       {ok, Local, Url} = ddfs_util:hashdir(Tag,
  -                                         S#state.nodename,
  +                                         NodeName,
                                            "tag",
  -                                         S#state.root,
  +                                         Root,
                                            VolName),
       {TagName, Time} = ddfs_util:unpack_objname(Tag),
   
  
positive.code: -spec do_put_tag_data(tagname(), binary(), #state{}) -> put_tag_data_result().
  do_put_tag_data(_Tag, _Data, #state{vols = []}) ->
      {error, no_volumes};
  do_put_tag_data(Tag, Data, S) ->
      {_Space, VolName} = choose_vol(S#state.vols),
      {ok, Local, _} = ddfs_util:hashdir(Tag,
                                         S#state.nodename,
                                         "tag",
                                         S#state.root,
                                         VolName),
      case ddfs_util:ensure_dir(Local) of
          ok ->
  
negative.code: 
  -type tag_ts() :: not_found | {ok, {erlang:timestamp(), volume_name()}}.
  -spec do_get_tag_timestamp(tagname(), #state{}) -> tag_ts().
  do_get_tag_timestamp(TagName, #state{tags = Tags}) ->
      case gb_trees:lookup(TagName, Tags) of
          none ->
              notfound;
          {value, {_Time, _VolName} = TagNfo} ->
  