⛏️ index : haiku.git

/*
 * Copyright 2020 Suhel Mehta, mehtasuhel@gmail.com
 * Copyright 2008-2010, Axel DΓΆrfler, axeld@pinc-software.de.
 * All rights reserved. Distributed under the terms of the MIT License.
 */

#ifndef INODE_H
#define INODE_H

#include "ufs2.h"
#include "Volume.h"

#define	UFS2_ROOT	((ino_t)2)


struct timeval32
{
	int tv_sec, tv_usec;
};


struct ufs2_inode {
	u_int16_t	fileMode;
	int16_t		linkCount;
	int32_t		userId;
	int32_t		groupId;
	int32_t		inodeBlockSize;
	int64_t		size;
	int64_t		inodeBlocks;
	struct		timeval32	accessTime;
	struct		timeval32	modifiedTime;
	struct		timeval32	changeTime;
	struct		timeval32	createTime;
	/* time in nano seconds */
	int32_t		nsModifiedTime;
	int32_t		nsAccessTime;
	int32_t		nsChangeTime;
	int32_t		nsCreateTime;
	int32_t		generationNumber;
	int32_t		kernelFlags;
	int32_t		statusFlags;
	int32_t		extendedAttSize; /* Extended attribute size */
	/* 2 Direct extended attribute block pointers */
	int64_t		extendedBklPtr1;
	int64_t		extendedBklPtr2;

	union {
		struct {
			int64_t		directBlockPointer[12];
			int64_t		indirectBlockPointer;
			int64_t		doubleIndriectBlockPointer;
			int64_t		tripleIndriectBlockPointer;
		};
		char	symlinkpath[120];
	};
	/* Unused but need to figure out what are they */
	int64_t		unused1;
	int64_t		unused2;
	int64_t		unused3;


	static void _DecodeTime(struct timespec& timespec, timeval32 time)
	{
		timespec.tv_sec = time.tv_sec;
		timespec.tv_nsec = time.tv_usec * 1000;
	}
	void GetAccessTime(struct timespec& timespec) const
		{ _DecodeTime(timespec, accessTime); }
	void GetChangeTime(struct timespec& timespec) const
		{ _DecodeTime(timespec, changeTime); }
	void GetModificationTime(struct timespec& timespec) const
		{ _DecodeTime(timespec, modifiedTime); }
	void GetCreationTime(struct timespec& timespec) const
		{ _DecodeTime(timespec, createTime); }
};

class Inode {
	public:
						Inode(Volume* volume, ino_t id);
						Inode(Volume* volume, ino_t id,
							const ufs2_inode& item);
						~Inode();

			status_t	InitCheck();

			ino_t		ID() const { return fID; }
//
			rw_lock*	Lock() { return& fLock; }
//
//			status_t	UpdateNodeFromDisk();

			bool		IsDirectory() const
							{ return S_ISDIR(Mode()); }
			bool		IsFile() const
							{ return S_ISREG(Mode()); }
			bool		IsSymLink() const
							{ return S_ISLNK(Mode()); }
//			status_t	CheckPermissions(int accessMode) const;

			mode_t		Mode() const { return fNode.fileMode; }
			off_t		Size() const { return fNode.size; }
			uid_t		UserID() const { return fNode.userId; }
			gid_t		GroupID() const { return fNode.groupId; }
			int16_t		LinkCount() const { return fNode.linkCount; }
			uint64_t	NumBlocks() const
							{ return fNode.inodeBlocks * (fNode.inodeBlockSize >> 9); }
			void		GetChangeTime(struct timespec& timespec) const
							{ fNode.GetChangeTime(timespec); }
			void		GetModificationTime(struct timespec& timespec) const
							{ fNode.GetModificationTime(timespec); }
			void		GetCreationTime(struct timespec& timespec) const
							{ fNode.GetCreationTime(timespec); }
			void		GetAccessTime(struct timespec& timespec) const
							{ fNode.GetAccessTime(timespec); }
			status_t	CheckPermissions(int accessMode) const;

			Volume*		GetVolume() const { return fVolume; }

			ino_t		Parent();

			off_t   	FindBlock(off_t block_number, off_t block_offset);
			status_t	ReadAt(off_t pos, uint8* buffer, size_t* length);
			status_t	ReadLink(char* buffer, size_t *_bufferSize);
//			status_t	FillGapWithZeros(off_t start, off_t end);

			void*		FileCache() const { return fCache; }
			void*		Map() const { return fMap; }

//			status_t	FindParent(ino_t* id);
	//static	Inode*		Create(Transaction& transaction, ino_t id, Inode* parent, int32 mode, uint64 size = 0, uint64 flags = 0);
private:
						Inode(Volume* volume);
						Inode(const Inode&);
						Inode& operator=(const Inode&);
			int64_t		GetBlockPointer(int ptrNumber) {
						return fNode.directBlockPointer[ptrNumber]; }

			int64_t 	GetIndirectBlockPointer() {
						return fNode.indirectBlockPointer; }

			int64_t 	GetDoubleIndirectBlockPtr() {
						return fNode.doubleIndriectBlockPointer; }

			int64_t 	GetTripleIndirectBlockPtr() {
						return fNode.tripleIndriectBlockPointer; }

//			uint64		_NumBlocks();
private:

			rw_lock		fLock;
			::Volume*	fVolume;
			ino_t		fID;
			void*		fCache;
			void*		fMap;
			status_t	fInitStatus;
			ufs2_inode	fNode;
};

#endif	// INODE_H