Example #1
0
func fillEntryOut(out *raw.EntryOut, i *maggiefs.Inode) {
	// fill out
	out.NodeId = i.Inodeid
	out.Generation = i.Generation
	out.EntryValid = uint64(0)
	out.AttrValid = uint64(0)
	out.EntryValidNsec = uint32(100)
	out.AttrValidNsec = uint32(100)
	//Inode
	out.Ino = i.Inodeid
	out.Size = i.Length
	out.Blocks = numBlocks(i.Length, maggiefs.PAGESIZE)
	out.Atime = uint64(0)       // always 0 for atime
	out.Mtime = uint64(i.Mtime) // Mtime is user modifiable and is the last time data changed
	out.Ctime = uint64(i.Ctime) // Ctime is tracked by the FS and changes when attrs or data change
	out.Atimensec = uint32(0)
	out.Mtimensec = uint32(0)
	out.Ctimensec = uint32(0)
	out.Mode = i.FullMode()
	out.Nlink = i.Nlink
	out.Uid = i.Uid
	out.Gid = i.Gid
	out.Rdev = uint32(0) // regular file, not block dvice
	out.Blksize = maggiefs.PAGESIZE
}
Example #2
0
// seta an inode
func (nd *NameData) SetInode(i *maggiefs.Inode) (err error) {
	nd.inodeStripeLock[i.Inodeid%STRIPE_SIZE].Lock()
	defer nd.inodeStripeLock[i.Inodeid%STRIPE_SIZE].Unlock()
	key := make([]byte, 8)
	binary.LittleEndian.PutUint64(key, i.Inodeid)
	// do the write and send OK
	binsize := i.BinSize()
	b := make([]byte, binsize)
	i.ToBytes(b)

	err = nd.inodb.Put(WriteOpts, key, b)
	return err
}
Example #3
0
// adds an inode persistent store, setting its inode ID to the generated ID, and returning
// the generated id and error
func (nd *NameData) AddInode(i *maggiefs.Inode) (uint64, error) {
	newNodeId, err := nd.GetIncrCounter(COUNTER_INODE, 1)
	if err != nil {
		return 0, err
	}
	i.Inodeid = newNodeId
	err = nd.SetInode(i)
	return i.Inodeid, err
}
Example #4
0
func (m *MaggieFuse) Mkdir(out *raw.EntryOut, header *raw.InHeader, input *raw.MkdirIn, name string) (code fuse.Status) {

	// make new child
	currTime := time.Now().Unix()
	i := maggiefs.Inode{
		0, // id 0 to start, we get id when inserting
		0,
		maggiefs.FTYPE_DIR,
		0,
		07777 & input.Mode,
		currTime,
		currTime,
		0,
		header.Uid,
		header.Gid,
		"",
		make([]maggiefs.Block, 0, 0),
		make(map[string]maggiefs.Dentry),
		make(map[string][]byte),
	}

	// save
	id, err := m.names.AddInode(&i)
	if err != nil {
		return fuse.EROFS
	}
	i.Inodeid = id
	// link parent
	err = m.names.Link(header.NodeId, id, name, false)
	if err != nil {
		// garbage collector will clean up our 0 reference node
		if err == maggiefs.E_EXISTS {
			return fuse.Status(syscall.EEXIST)
		}
		if err == maggiefs.E_NOTDIR {
			return fuse.ENOTDIR
		}
		return fuse.EROFS
	}
	// send entry back to child
	fillEntryOut(out, &i)
	return fuse.OK
}
Example #5
0
func (m *MaggieFuse) Mknod(out *raw.EntryOut, header *raw.InHeader, input *raw.MknodIn, name string) (code fuse.Status) {

	//build node
	currTime := time.Now().Unix()
	i := maggiefs.Inode{
		0, // id 0 to start
		0, // gen 0
		maggiefs.FTYPE_REG,
		0,
		input.Mode & 07777,
		currTime,
		currTime,
		1,
		header.Uid,
		header.Gid,
		"",
		make([]maggiefs.Block, 0, 0),
		make(map[string]maggiefs.Dentry),
		make(map[string][]byte),
	}

	// save new node
	id, err := m.names.AddInode(&i)
	if err != nil {
		return fuse.EROFS
	}
	i.Inodeid = id

	// link parent
	err = m.names.Link(header.NodeId, i.Inodeid, name, false)
	if err != nil {
		if err == maggiefs.E_EXISTS {
			return fuse.Status(syscall.EEXIST)
		} else {
			return fuse.EROFS
		}
	}
	// output
	fillEntryOut(out, &i)
	return fuse.OK

}
Example #6
0
// acquires lease, then adds the blocks to the namenode,
// patching up the referenced inode to match
func (w *InodeWriter) addBlocksForFileWrite(inode *maggiefs.Inode, off uint64, length uint32) error {
	//	fmt.Printf("Adding/extending blocks for write at off %d length %d\n", off, length)
	newEndPos := off + uint64(length)
	if newEndPos > inode.Length {
		// if we have a last block and it's less than max length,
		// extend last block to max block length first
		//		fmt.Printf("Adding/extending blocks for file write to inode %+v\n", inode)
		if inode.Blocks != nil && len(inode.Blocks) > 0 {
			idx := int(len(inode.Blocks) - 1)
			lastBlock := inode.Blocks[idx]
			if lastBlock.Length() < BLOCKLENGTH {
				extendLength := BLOCKLENGTH - lastBlock.Length()
				if lastBlock.EndPos+extendLength > off+uint64(length) {
					// only extend as much as we need to
					extendLength = off + uint64(length) - lastBlock.EndPos
				}
				lastBlock.EndPos = lastBlock.EndPos + extendLength
				inode.Blocks[idx] = lastBlock
				inode.Length += extendLength
			}
		}
		// and add new blocks as necessary
		for newEndPos > inode.Length {
			//			fmt.Printf("New end pos %d still greater than inode length %d\n", newEndPos, inode.Length)
			newBlockLength := newEndPos - inode.Length
			if newBlockLength > BLOCKLENGTH {
				newBlockLength = BLOCKLENGTH
			}
			newBlock, err := w.names.AddBlock(inode.Inodeid, uint32(newBlockLength))
			if err != nil {
				return err
			}
			inode.Blocks = append(inode.Blocks, newBlock)
			inode.Length += newBlockLength
		}
	}
	inode.Mtime = time.Now().Unix()
	err := w.names.SetInode(inode)
	return err
}
Example #7
0
func (m *MaggieFuse) Symlink(out *raw.EntryOut, header *raw.InHeader, pointedTo string, linkName string) (code fuse.Status) {
	// new inode type symlink
	currTime := time.Now().Unix()
	i := maggiefs.Inode{
		0, // id 0 to start, we get id when inserting
		0,
		maggiefs.FTYPE_LNK,
		0,
		0777,
		currTime,
		currTime,
		0,
		header.Uid,
		header.Gid,
		pointedTo,
		make([]maggiefs.Block, 0, 0),
		make(map[string]maggiefs.Dentry),
		make(map[string][]byte),
	}
	// save
	id, err := m.names.AddInode(&i)
	if err != nil {
		return fuse.EROFS
	}
	i.Inodeid = id
	// link parent
	err = m.names.Link(header.NodeId, i.Inodeid, linkName, false)
	if err != nil {
		if err == maggiefs.E_EXISTS {
			return fuse.Status(syscall.EEXIST)
		} else if err == maggiefs.E_NOTDIR {
			return fuse.ENOTDIR
		}
		return fuse.EROFS
	}
	// send entry back to child
	fillEntryOut(out, &i)
	return fuse.OK
}
Example #8
0
func fillAttrOut(out *raw.AttrOut, i *maggiefs.Inode) {
	// raw.Attr
	out.Ino = i.Inodeid
	out.Size = i.Length
	out.Blocks = numBlocks(i.Length, maggiefs.PAGESIZE)
	out.Atime = uint64(0)       // always 0 for atime
	out.Mtime = uint64(i.Mtime) // Mtime is user modifiable and is the last time data changed
	out.Ctime = uint64(i.Ctime) // Ctime is tracked by the FS and changes when attrs or data change
	out.Atimensec = uint32(0)
	out.Mtimensec = uint32(0)
	out.Ctimensec = uint32(0)
	out.Mode = i.FullMode()
	out.Nlink = i.Nlink
	out.Uid = i.Uid
	out.Gid = i.Gid
	out.Rdev = uint32(0) // regular file, not block dvice
	out.Blksize = maggiefs.PAGESIZE
	// raw.AttrOut
	out.AttrValid = uint64(0)
	out.AttrValidNsec = uint32(100)
	fmt.Printf("Filled attrOut %v with inode %v\n", out, i)
}