github.com/olivere/camlistore@v0.0.0-20140121221811-1b7ac2da0199/pkg/fs/debug.go (about)

     1  // +build linux darwin
     2  
     3  /*
     4  Copyright 2013 Google Inc.
     5  
     6  Licensed under the Apache License, Version 2.0 (the "License");
     7  you may not use this file except in compliance with the License.
     8  You may obtain a copy of the License at
     9  
    10       http://www.apache.org/licenses/LICENSE-2.0
    11  
    12  Unless required by applicable law or agreed to in writing, software
    13  distributed under the License is distributed on an "AS IS" BASIS,
    14  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
    15  See the License for the specific language governing permissions and
    16  limitations under the License.
    17  */
    18  
    19  package fs
    20  
    21  import (
    22  	"bytes"
    23  	"fmt"
    24  	"os"
    25  	"strconv"
    26  
    27  	"camlistore.org/pkg/types"
    28  
    29  	"camlistore.org/third_party/code.google.com/p/rsc/fuse"
    30  )
    31  
    32  // If TrackStats is true, statistics are kept on operations.
    33  var TrackStats bool
    34  
    35  func init() {
    36  	TrackStats, _ = strconv.ParseBool(os.Getenv("CAMLI_TRACK_FS_STATS"))
    37  }
    38  
    39  var (
    40  	mutFileOpen      = newStat("mutfile-open")
    41  	mutFileOpenError = newStat("mutfile-open-error")
    42  	mutFileOpenRO    = newStat("mutfile-open-ro")
    43  	mutFileOpenRW    = newStat("mutfile-open-rw")
    44  	roFileOpen       = newStat("rofile-open")
    45  	roFileOpenError  = newStat("rofile-open-error")
    46  )
    47  
    48  var statByName = map[string]*stat{}
    49  
    50  func newStat(name string) *stat {
    51  	if statByName[name] != nil {
    52  		panic("duplicate registraton of " + name)
    53  	}
    54  	s := &stat{name: name}
    55  	statByName[name] = s
    56  	return s
    57  }
    58  
    59  // A stat is a wrapper around an atomic int64, as is a fuse.Node
    60  // exporting that data as a decimal.
    61  type stat struct {
    62  	n    types.AtomicInt64
    63  	name string
    64  }
    65  
    66  func (s *stat) Incr() {
    67  	if TrackStats {
    68  		s.n.Add(1)
    69  	}
    70  }
    71  
    72  func (s *stat) content() []byte {
    73  	var buf bytes.Buffer
    74  	fmt.Fprintf(&buf, "%d", s.n.Get())
    75  	buf.WriteByte('\n')
    76  	return buf.Bytes()
    77  }
    78  
    79  func (s *stat) Attr() fuse.Attr {
    80  	return fuse.Attr{
    81  		Mode:   0400,
    82  		Uid:    uint32(os.Getuid()),
    83  		Gid:    uint32(os.Getgid()),
    84  		Size:   uint64(len(s.content())),
    85  		Mtime:  serverStart,
    86  		Ctime:  serverStart,
    87  		Crtime: serverStart,
    88  	}
    89  }
    90  
    91  func (s *stat) Read(req *fuse.ReadRequest, res *fuse.ReadResponse, intr fuse.Intr) fuse.Error {
    92  	c := s.content()
    93  	if req.Offset > int64(len(c)) {
    94  		return nil
    95  	}
    96  	c = c[req.Offset:]
    97  	size := req.Size
    98  	if size > len(c) {
    99  		size = len(c)
   100  	}
   101  	res.Data = make([]byte, size)
   102  	copy(res.Data, c)
   103  	return nil
   104  }
   105  
   106  // A statsDir FUSE directory node is returned by root.go, by opening
   107  // ".camli_fs_stats" in the root directory.
   108  type statsDir struct{}
   109  
   110  func (statsDir) Attr() fuse.Attr {
   111  	return fuse.Attr{
   112  		Mode: os.ModeDir | 0700,
   113  		Uid:  uint32(os.Getuid()),
   114  		Gid:  uint32(os.Getgid()),
   115  	}
   116  }
   117  
   118  func (statsDir) ReadDir(intr fuse.Intr) (ents []fuse.Dirent, err fuse.Error) {
   119  	for k := range statByName {
   120  		ents = append(ents, fuse.Dirent{Name: k})
   121  	}
   122  	return
   123  }
   124  
   125  func (statsDir) Lookup(req *fuse.LookupRequest, res *fuse.LookupResponse, intr fuse.Intr) (fuse.Node, fuse.Error) {
   126  	name := req.Name
   127  	s, ok := statByName[name]
   128  	if !ok {
   129  		return nil, fuse.ENOENT
   130  	}
   131  	return s, nil
   132  }