Пример #1
0
// reiserfs_open
static status_t
reiserfs_open(fs_volume *fs, fs_vnode *_node, int openMode, void **cookie)
{
//	FUNCTION_START();
	Volume *volume = (Volume*)fs->private_volume;
	VNode *node = (VNode*)_node->private_node;
FUNCTION(("node: (%Ld: %lu, %lu)\n", node->GetID(), node->GetDirID(),
		  node->GetObjectID()));
	status_t error = B_OK;
	// check the open mode
	if ((openMode & O_RWMASK) == O_WRONLY || (openMode & O_RWMASK) == O_RDWR
		|| (openMode & (O_TRUNC | O_CREAT))) {
		error = B_READ_ONLY_DEVICE;
	}
	// create a StreamReader
	if (error == B_OK) {
		StreamReader *reader = new(nothrow) StreamReader(volume->GetTree(),
			node->GetDirID(), node->GetObjectID());
		if (reader) {
			error = reader->Suspend();
			if (error == B_OK)
				*cookie = reader;
			else
				delete reader;
		} else
			error = B_NO_MEMORY;
	}
	RETURN_ERROR(error);
}
Пример #2
0
// reiserfs_read
static status_t
reiserfs_read(fs_volume *fs, fs_vnode *_node, void *cookie, off_t pos,
	void *buffer, size_t *bufferSize)
{
	TOUCH(fs);
//	FUNCTION_START();
//	Volume *volume = (Volume*)fs->private_volume;
	VNode *node = (VNode*)_node->private_node;
	FUNCTION(("((%Ld: %lu, %lu), %Ld, %p, %lu)\n", node->GetID(),
			  node->GetDirID(), node->GetObjectID(), pos, buffer,
			  *bufferSize));
	status_t error = B_OK;
	// don't read anything but files
	if (!node->IsFile()) {
		if (node->IsDir())
			error = B_IS_A_DIRECTORY;
		else
			error = B_BAD_VALUE;
	}

	// read
	StreamReader *reader = (StreamReader*)cookie;
	if (error == B_OK) {
		error = reader->Resume();
		if (error == B_OK) {
			error = reader->ReadAt(pos, buffer, *bufferSize, bufferSize);
			reader->Suspend();
		}
	}
	RETURN_ERROR(error);
}
Пример #3
0
// reiserfs_close_dir
static status_t
reiserfs_close_dir(fs_volume *fs, fs_vnode *_node, void *cookie)
{
	TOUCH(fs); TOUCH(cookie);
//	FUNCTION_START();
	VNode *node = (VNode*)_node->private_node;
FUNCTION(("node: (%Ld: %lu, %lu)\n", node->GetID(), node->GetDirID(),
		  node->GetObjectID()));
	TOUCH(node);
	return B_OK;
}
Пример #4
0
// reiserfs_lookup
static status_t
reiserfs_lookup(fs_volume* fs, fs_vnode* _dir, const char *entryName,
	ino_t *vnid)
{
//	FUNCTION_START();
	Volume *volume = (Volume*)fs->private_volume;
	VNode *dir = (VNode*)_dir->private_node;
FUNCTION(("dir: (%Ld: %lu, %lu), entry: `%s'\n", dir->GetID(), dir->GetDirID(),
		  dir->GetObjectID(), entryName));
	status_t error = B_OK;
	VNode *entryNode = NULL;

	// check for non-directories
	if (!dir->IsDir()) {
		error = B_ENTRY_NOT_FOUND;

	// special entries: "." and ".."
	} else if (!strcmp(entryName, ".")) {
		*vnid = dir->GetID();
		if (volume->GetVNode(*vnid, &entryNode) != B_OK)
			error = B_BAD_VALUE;
	} else if (!strcmp(entryName, "..")) {
		*vnid = dir->GetParentID();
		if (volume->GetVNode(*vnid, &entryNode) != B_OK)
			error = B_BAD_VALUE;

	// ordinary entries
	} else {
		// find the entry
		VNode foundNode;
		error = volume->FindDirEntry(dir, entryName, &foundNode, true);

		// hide non-file/dir/symlink entries, if the user desires that, and
		// those entries explicitly set to hidden
		if (error == B_OK
			&& ((foundNode.IsEsoteric() && volume->GetHideEsoteric())
				|| volume->IsNegativeEntry(foundNode.GetID()))) {
			error = B_ENTRY_NOT_FOUND;
		}
		if (error == B_OK) {
			*vnid = foundNode.GetID();
			error = volume->GetVNode(*vnid, &entryNode);
		}
	}

	// add to the entry cache
	if (error == B_OK) {
		entry_cache_add(volume->GetID(), dir->GetID(), entryName,
			*vnid);
	}

	RETURN_ERROR(error);
}
Пример #5
0
// reiserfs_free_dir_cookie
static status_t
reiserfs_free_dir_cookie(fs_volume *fs, fs_vnode *_node, void *cookie)
{
	TOUCH(fs);
//	FUNCTION_START();
	VNode *node = (VNode*)_node->private_node;
FUNCTION(("node: (%Ld: %lu, %lu)\n", node->GetID(), node->GetDirID(),
		  node->GetObjectID()));
	TOUCH(node);
	DirectoryCookie *iterator = (DirectoryCookie*)cookie;
	delete iterator;
	return B_OK;
}
Пример #6
0
// reiserfs_free_cookie
static status_t
reiserfs_free_cookie(fs_volume *fs, fs_vnode *_node, void *cookie)
{
	TOUCH(fs);
//	FUNCTION_START();
	VNode *node = (VNode*)_node->private_node;
FUNCTION(("node: (%Ld: %lu, %lu)\n", node->GetID(), node->GetDirID(),
		  node->GetObjectID()));
	TOUCH(node);
	StreamReader *reader = (StreamReader*)cookie;
	delete reader;
	return B_OK;
}
Пример #7
0
// reiserfs_rewind_dir
static status_t
reiserfs_rewind_dir(fs_volume *fs, fs_vnode *_node, void *cookie)
{
	TOUCH(fs);
//	FUNCTION_START();
	VNode *node = (VNode*)_node->private_node;
FUNCTION(("node: (%Ld: %lu, %lu)\n", node->GetID(), node->GetDirID(),
		  node->GetObjectID()));
	TOUCH(node);
	DirectoryCookie *iterator = (DirectoryCookie*)cookie;
	status_t error = iterator->Rewind();	// no need to Resume()
	if (error == B_OK)
		error = iterator->Suspend();
	RETURN_ERROR(error);
}
Пример #8
0
// reiserfs_open_dir
static status_t
reiserfs_open_dir(fs_volume *fs, fs_vnode *_node, void **cookie)
{
//	FUNCTION_START();
	Volume *volume = (Volume*)fs->private_volume;
	VNode *node = (VNode*)_node->private_node;
FUNCTION(("node: (%Ld: %lu, %lu)\n", node->GetID(), node->GetDirID(),
		  node->GetObjectID()));
	status_t error = (node->IsDir() ? B_OK : B_NOT_A_DIRECTORY);
	if (error == B_OK) {
		DirectoryCookie *iterator = new(nothrow) DirectoryCookie(
			volume->GetTree(), node->GetDirID(), node->GetObjectID());
		if (iterator) {
			error = iterator->Suspend();
			if (error == B_OK)
				*cookie = iterator;
			else
				delete iterator;
		} else
			error = B_NO_MEMORY;
	}
	FUNCTION_END();
	RETURN_ERROR(error);
}
Пример #9
0
// reiserfs_read_symlink
static status_t
reiserfs_read_symlink(fs_volume *fs, fs_vnode *_node, char *buffer,
	size_t *bufferSize)
{
//	FUNCTION_START();
	Volume *volume = (Volume*)fs->private_volume;
	VNode *node = (VNode*)_node->private_node;
FUNCTION(("node: (%Ld: %lu, %lu)\n", node->GetID(), node->GetDirID(),
		  node->GetObjectID()));
	status_t error = B_OK;
	// read symlinks only
	if (!node->IsSymlink())
		error = B_BAD_VALUE;
	// read
	if (error == B_OK)
		error = volume->ReadLink(node, buffer, *bufferSize, bufferSize);
	RETURN_ERROR(error);
}
Пример #10
0
// reiserfs_access
static status_t
reiserfs_access(fs_volume *fs, fs_vnode *_node, int mode)
{
	TOUCH(fs);
//	FUNCTION_START();
//	Volume *volume = (Volume*)fs->private_volume;
	VNode *node = (VNode*)_node->private_node;
FUNCTION(("node: (%Ld: %lu, %lu)\n", node->GetID(), node->GetDirID(),
		  node->GetObjectID()));
	// write access requested?
	if (mode & W_OK)
		return B_READ_ONLY_DEVICE;
	// get node permissions
	StatData *statData = node->GetStatData();
	int userPermissions = (statData->GetMode() & S_IRWXU) >> 6;
	int groupPermissions = (statData->GetMode() & S_IRWXG) >> 3;
	int otherPermissions = statData->GetMode() & S_IRWXO;
	// get the permissions for this uid/gid
	int permissions = 0;
	uid_t uid = geteuid();
	// user is root
	if (uid == 0) {
		// root has always read/write permission, but at least one of the
		// X bits must be set for execute permission
		permissions = userPermissions | groupPermissions | otherPermissions
			| S_IROTH | S_IWOTH;
	// user is node owner
	} else if (uid == statData->GetUID())
		permissions = userPermissions;
	// user is in owning group
	else if (is_user_in_group(statData->GetGID()))
		permissions = groupPermissions;
	// user is one of the others
	else
		permissions = otherPermissions;
	// do the check
	if (mode & ~permissions)
		return B_NOT_ALLOWED;
	return B_OK;
}
Пример #11
0
// reiserfs_read_stat
static status_t
reiserfs_read_stat(fs_volume *fs, fs_vnode *_node, struct stat *st)
{
//	FUNCTION_START();
	Volume *volume = (Volume*)fs->private_volume;
	VNode *node = (VNode*)_node->private_node;
FUNCTION(("node: (%Ld: %lu, %lu)\n", node->GetID(), node->GetDirID(),
		  node->GetObjectID()));
	status_t error = B_OK;
	StatData *statData = node->GetStatData();
	st->st_dev = volume->GetID();
	st->st_ino = node->GetID();
	st->st_mode = statData->GetMode();
	st->st_nlink = statData->GetNLink();
	st->st_uid = statData->GetUID();
	st->st_gid = statData->GetGID();
	st->st_size = statData->GetSize();
	st->st_blksize = kOptimalIOSize;
	st->st_atime = statData->GetATime();
	st->st_mtime = st->st_ctime = statData->GetMTime();
	st->st_crtime = statData->GetCTime();
	RETURN_ERROR(error);
}
Пример #12
0
// reiserfs_read_dir
static status_t
reiserfs_read_dir(fs_volume *fs, fs_vnode *_node, void *cookie,
	struct dirent *buffer, size_t bufferSize, uint32 *count)
{
//	FUNCTION_START();
	Volume *volume = (Volume*)fs->private_volume;
	VNode *node = (VNode*)_node->private_node;
FUNCTION(("node: (%Ld: %lu, %lu)\n", node->GetID(), node->GetDirID(),
		  node->GetObjectID()));
	DirectoryCookie *iterator = (DirectoryCookie*)cookie;
	status_t error = iterator->Resume();
	if (error == B_OK) {
		// read one entry
		DirItem item;
		int32 index = 0;
		DirEntry *entry = NULL;
		bool done = false;
		while (error == B_OK && !done
			   && (error = iterator->GetNext(&item, &index, &entry)) == B_OK) {
			uint32 dirID = entry->GetDirID();
			uint32 objectID = entry->GetObjectID();
			// skip hidden entries and entries the user specified to be hidden
			if (entry->IsHidden() || volume->IsNegativeEntry(dirID, objectID))
				continue;
			// skip entry, if we can't get the stat data, or it is neither a
			// file, a dir nor a symlink and the user desired to hide those.
			StatData statData;
			StatItem statItem;
			if (volume->GetTree()->FindStatItem(dirID, objectID, &statItem)
					!= B_OK
				|| statItem.GetStatData(&statData) != B_OK
				|| (statData.IsEsoteric() && volume->GetHideEsoteric())) {
				continue;
			}
			if (error == B_OK) {
				// get the name
				size_t nameLen = 0;
				const char *name = item.EntryNameAt(index, &nameLen);
				if (!name || nameLen == 0)	// bad data: skip it gracefully
					continue;
				// fill in the entry name -- checks whether the
				// entry fits into the buffer
				error = set_dirent_name(buffer, bufferSize, name,
										nameLen);
				if (error == B_OK) {
					// fill in the other data
					buffer->d_dev = volume->GetID();
					buffer->d_ino = VNode::GetIDFor(dirID, objectID);
					*count = 1;
PRINT(("Successfully read entry: dir: (%Ld: %ld, %ld), name: `%s', "
	   "id: (%Ld, %ld, %ld), reclen: %hu\n", node->GetID(), node->GetDirID(),
	   node->GetObjectID(), buffer->d_name, buffer->d_ino, dirID, objectID,
	   buffer->d_reclen));
					if (!strcmp("..", buffer->d_name))
						iterator->SetEncounteredDotDot(true);
					done = true;
				}
	 		}
 		}
 		if (error == B_ENTRY_NOT_FOUND) {
 			if (iterator->EncounteredDotDot()) {
	 			error = B_OK;
				*count = 0;
			} else {
				// this is necessary for the root directory
				// it usually has no ".." entry, so we simulate one
				// get the name
				const char *name = "..";
				size_t nameLen = strlen(name);
				// fill in the entry name -- checks whether the
				// entry fits into the buffer
				error = set_dirent_name(buffer, bufferSize, name,
										nameLen);
				if (error == B_OK) {
					// fill in the other data
					buffer->d_dev = volume->GetID();
					buffer->d_ino = node->GetID();
	// < That's not correct!
					*count = 1;
PRINT(("faking `..' entry: dir: (%Ld: %ld, %ld), name: `%s', "
	   "id: (%Ld, %ld, %ld), reclen: %hu\n", node->GetID(), node->GetDirID(),
	   node->GetObjectID(), buffer->d_name, buffer->d_ino, node->GetDirID(),
	   node->GetObjectID(), buffer->d_reclen));
					iterator->SetEncounteredDotDot(true);
				}
			}
 		}
 		iterator->Suspend();
	}
PRINT(("returning %ld entries\n", *count));
	RETURN_ERROR(error);
}