Beispiel #1
0
func TestAllocateMultiple(t *testing.T) {
	tmp, err := ioutil.TempFile("", "bazil-test-inodes-")
	if err != nil {
		t.Fatal(err)
	}
	defer func() {
		tmp.Close()
		os.Remove(tmp.Name())
	}()

	db, err := bolt.Open(tmp.Name(), 0666)
	if err != nil {
		t.Fatal(err)
	}
	defer db.Close()

	var inodeBucketName = []byte("inodetest")
	db.Update(func(tx *bolt.Tx) error {
		_, err := tx.CreateBucketIfNotExists(inodeBucketName)
		return err
	})

	const firstInode = 1024
	for i := uint64(firstInode); i < firstInode+100; i += 2 {
		var gotOne, gotTwo uint64
		f := func(tx *bolt.Tx) error {
			bucket := tx.Bucket(inodeBucketName)
			if bucket == nil {
				return fmt.Errorf("inode bucket missing in test: %q", inodeBucketName)
			}
			var err error
			gotOne, err = inodes.Allocate(bucket)
			if err != nil {
				return err
			}
			gotTwo, err = inodes.Allocate(bucket)
			return err
		}
		if err := db.Update(f); err != nil {
			t.Error(err)
		}
		if g, e := gotOne, i; g != e {
			t.Errorf("wrong inode allocated: %d != %d", g, e)
		}
		if g, e := gotTwo, i+1; g != e {
			t.Errorf("wrong inode allocated: %d != %d", g, e)
		}
	}
}
Beispiel #2
0
func (d *dir) Mkdir(req *fuse.MkdirRequest, intr fs.Intr) (fs.Node, fuse.Error) {
	d.mu.Lock()
	defer d.mu.Unlock()

	// TODO handle req.Mode

	var child node
	err := d.fs.db.Update(func(tx *bolt.Tx) error {
		bucket := d.fs.bucket(tx).Bucket(bucketInode)
		if bucket == nil {
			return errors.New("inode bucket is missing")
		}
		inode, err := inodes.Allocate(bucket)
		if err != nil {
			return err
		}
		child = &dir{
			inode:  inode,
			name:   req.Name,
			parent: d,
			fs:     d.fs,
			active: make(map[string]node),
		}
		d.active[req.Name] = child
		return d.saveInternal(tx, req.Name, child)
		// TODO clean up active on error
	})
	if err != nil {
		if err == inodes.OutOfInodes {
			return nil, fuse.Errno(syscall.ENOSPC)
		}
		return nil, err
	}
	return child, nil
}
Beispiel #3
0
func (d *dir) Create(req *fuse.CreateRequest, resp *fuse.CreateResponse, intr fs.Intr) (fs.Node, fs.Handle, fuse.Error) {
	d.mu.Lock()
	defer d.mu.Unlock()

	// TODO check for duplicate name

	switch req.Mode & os.ModeType {
	case 0:
		var child node
		err := d.fs.db.Update(func(tx *bolt.Tx) error {
			bucket := d.fs.bucket(tx).Bucket(bucketInode)
			if bucket == nil {
				return errors.New("inode bucket is missing")
			}
			inode, err := inodes.Allocate(bucket)
			if err != nil {
				return err
			}

			manifest := blobs.EmptyManifest("file")
			blob, err := blobs.Open(d.fs.chunkStore, manifest)
			if err != nil {
				return fmt.Errorf("blob open problem: %v", err)
			}
			child = &file{
				inode:  inode,
				name:   req.Name,
				parent: d,
				blob:   blob,
			}
			d.active[req.Name] = child

			return d.saveInternal(tx, req.Name, child)
			// TODO clean up active on error
		})
		if err != nil {
			return nil, nil, err
		}
		return child, child, nil
	default:
		return nil, nil, fuse.EPERM
	}
}