* Removed fs_get_file_map(); for a file system that only has contiguous files,

there is no need for the file map service.
* Added and implemented fs_read_pages() - this should fix bug #1633; the file
  system had not been ported to the new file cache API yet.
* Cleanup.


git-svn-id: file:///srv/svn/repos/haiku/haiku/trunk@22970 a95241bf-73f2-0310-859d-f6bbb57e9c96
This commit is contained in:
Axel Dörfler
2007-11-21 12:41:58 +00:00
parent ffea746866
commit ff99132e67
@@ -93,30 +93,15 @@ fs_free_identify_partition_cookie(partition_data *partition, void *_cookie)
} }
// #pragma mark - FS hooks
static status_t static status_t
fs_mount(dev_t mountID, const char *device, uint32 flags, fs_mount(dev_t mountID, const char *device, uint32 flags,
const char *args, void **_data, ino_t *_rootID) const char *args, void **_volume, ino_t *_rootID)
{ {
/*
Kernel passes in nspace_id, (representing a disk or partition?)
and a string representing the device (eg, "/dev/scsi/disk/030/raw)
Flags will be used for things like specifying read-only mounting.
parms is parameters passed in as switches from the mount command,
and len is the length of the otions. data is a pointer to a
driver-specific struct that should be allocated in this routine.
It will then be passed back in by the kernel to a number of the other
fs driver functions. vnid should also be passed back to the kernel,
representing the vnode id of the root vnode.
*/
status_t result = EINVAL;
// return EINVAL if it's not a device compatible with the driver.
bool allowJoliet = true; bool allowJoliet = true;
nspace *vol; nspace *volume;
(void)flags;
/* Create semaphore if it's not already created. When do we need to
use semaphores? */
// Check for a 'nojoliet' parm // Check for a 'nojoliet' parm
// all we check for is the existance of 'nojoliet' in the parms. // all we check for is the existance of 'nojoliet' in the parms.
@@ -139,25 +124,19 @@ fs_mount(dev_t mountID, const char *device, uint32 flags,
} }
// Try and mount volume as an ISO volume. // Try and mount volume as an ISO volume.
result = ISOMount(device, O_RDONLY, &vol, allowJoliet); status_t result = ISOMount(device, O_RDONLY, &volume, allowJoliet);
if (result == B_OK) {
// If it is ISO …
if (result == B_NO_ERROR) {
//ino_t rootID = vol->rootDirRec.startLBN[FS_DATA_FORMAT];
//*vnid = rootID;
*_rootID = ISO_ROOTNODE_ID; *_rootID = ISO_ROOTNODE_ID;
*_data = (void*)vol; *_volume = volume;
vol->id = mountID; volume->id = mountID;
// You MUST do this. Create the vnode for the root. result = publish_vnode(mountID, *_rootID, &volume->rootDirRec);
result = publish_vnode(mountID, *_rootID, (void*)&(vol->rootDirRec)); if (result != B_OK) {
if (result != B_NO_ERROR) { block_cache_delete(volume->fBlockCache, false);
block_cache_delete(vol->fBlockCache, false); free(volume);
free(vol); result = B_ERROR;
result = EINVAL; }
} else
result = B_NO_ERROR;
} }
return result; return result;
} }
@@ -188,51 +167,30 @@ fs_unmount(void *_ns)
static status_t static status_t
fs_read_fs_stat(void *_ns, struct fs_info *fss) fs_read_fs_stat(void *_ns, struct fs_info *fss)
{ {
// Fill in fs_info struct for device.
nspace *ns = (nspace *)_ns; nspace *ns = (nspace *)_ns;
int i; int i;
TRACE(("fs_read_fs_stat - ENTER\n"));
// Fill in device id.
//fss->dev = ns->fd;
// Root vnode ID
//fss->root = ISO_ROOTNODE_ID;
// File system flags.
fss->flags = B_FS_IS_PERSISTENT | B_FS_IS_READONLY; fss->flags = B_FS_IS_PERSISTENT | B_FS_IS_READONLY;
// FS block size.
fss->block_size = ns->logicalBlkSize[FS_DATA_FORMAT]; fss->block_size = ns->logicalBlkSize[FS_DATA_FORMAT];
// IO size - specifies buffer size for file copying
fss->io_size = 65536; fss->io_size = 65536;
// Total blocks?
fss->total_blocks = ns->volSpaceSize[FS_DATA_FORMAT]; fss->total_blocks = ns->volSpaceSize[FS_DATA_FORMAT];
// Free blocks = 0, read only
fss->free_blocks = 0; fss->free_blocks = 0;
// Device name.
strncpy(fss->device_name, ns->devicePath, sizeof(fss->device_name)); strncpy(fss->device_name, ns->devicePath, sizeof(fss->device_name));
strncpy(fss->volume_name, ns->volIDString, sizeof(fss->volume_name)); strncpy(fss->volume_name, ns->volIDString, sizeof(fss->volume_name));
for (i = strlen(fss->volume_name)-1; i >=0 ; i--) for (i = strlen(fss->volume_name) - 1; i >=0 ; i--) {
if (fss->volume_name[i] != ' ') if (fss->volume_name[i] != ' ')
break; break;
}
if (i < 0) if (i < 0)
strcpy(fss->volume_name, "UNKNOWN"); strcpy(fss->volume_name, "UNKNOWN");
else else
fss->volume_name[i + 1] = 0; fss->volume_name[i + 1] = 0;
// File system name
strcpy(fss->fsh_name, "iso9660"); strcpy(fss->fsh_name, "iso9660");
return B_OK;
TRACE(("fs_read_fs_stat - EXIT\n"));
return 0;
} }
@@ -246,23 +204,12 @@ fs_get_vnode_name(void *ns, void *_node, char *buffer, size_t bufferSize)
} }
/* fs_walk - the walk function just "walks" through a directory looking for
the specified file. When you find it, call get_vnode on its vnid to init
it for the kernel.
*/
static status_t static status_t
fs_walk(void *_ns, void *base, const char *file, ino_t *_vnodeID, int *_type) fs_walk(void *_ns, void *base, const char *file, ino_t *_vnodeID, int *_type)
{ {
/* Starting at the base, find file in the subdir, and return path
string and vnode id of file. */
nspace *ns = (nspace *)_ns; nspace *ns = (nspace *)_ns;
vnode *baseNode = (vnode*)base; vnode *baseNode = (vnode*)base;
uint32 dataLen = baseNode->dataLen[FS_DATA_FORMAT];
vnode *newNode = NULL; vnode *newNode = NULL;
status_t result = ENOENT;
bool done = FALSE;
uint32 totalRead = 0;
off_t block = baseNode->startLBN[FS_DATA_FORMAT];
TRACE(("fs_walk - looking for %s in dir file of length %d\n", file, TRACE(("fs_walk - looking for %s in dir file of length %d\n", file,
baseNode->dataLen[FS_DATA_FORMAT])); baseNode->dataLen[FS_DATA_FORMAT]));
@@ -272,27 +219,26 @@ fs_walk(void *_ns, void *base, const char *file, ino_t *_vnodeID, int *_type)
TRACE(("fs_walk - found \".\" file.\n")); TRACE(("fs_walk - found \".\" file.\n"));
*_vnodeID = baseNode->id; *_vnodeID = baseNode->id;
*_type = S_IFDIR; *_type = S_IFDIR;
if (get_vnode(ns->id, *_vnodeID, (void **)&newNode) != 0) return get_vnode(ns->id, *_vnodeID, (void **)&newNode);
result = EINVAL;
else
result = B_NO_ERROR;
} else if (strcmp(file, "..") == 0) { } else if (strcmp(file, "..") == 0) {
// parent directory // parent directory
TRACE(("fs_walk - found \"..\" file.\n")); TRACE(("fs_walk - found \"..\" file.\n"));
*_vnodeID = baseNode->parID; *_vnodeID = baseNode->parID;
*_type = S_IFDIR; *_type = S_IFDIR;
if (get_vnode(ns->id, *_vnodeID, (void **)&newNode) != 0) return get_vnode(ns->id, *_vnodeID, (void **)&newNode);
result = EINVAL; }
else
result = B_NO_ERROR;
} else {
// look up file in the directory // look up file in the directory
char *blockData; uint32 dataLength = baseNode->dataLen[FS_DATA_FORMAT];
status_t result = ENOENT;
uint32 totalRead = 0;
off_t block = baseNode->startLBN[FS_DATA_FORMAT];
bool done = false;
while ((totalRead < dataLen) && !done) { while (totalRead < dataLength && !done) {
off_t cachedBlock = block; off_t cachedBlock = block;
char *blockData = (char *)block_cache_get_etc(ns->fBlockCache, block, 0,
blockData = (char *)block_cache_get_etc(ns->fBlockCache, block, 0, ns->logicalBlkSize[FS_DATA_FORMAT]); ns->logicalBlkSize[FS_DATA_FORMAT]);
if (blockData != NULL) { if (blockData != NULL) {
int bytesRead = 0; int bytesRead = 0;
off_t blockBytesRead = 0; off_t blockBytesRead = 0;
@@ -308,39 +254,33 @@ fs_walk(void *_ns, void *base, const char *file, ino_t *_vnodeID, int *_type)
node.fileIDString = NULL; node.fileIDString = NULL;
node.attr.slName = NULL; node.attr.slName = NULL;
while (blockBytesRead < 2*ns->logicalBlkSize[FS_DATA_FORMAT] while (blockBytesRead < 2 * ns->logicalBlkSize[FS_DATA_FORMAT]
&& totalRead + blockBytesRead < dataLen && totalRead + blockBytesRead < dataLength
&& blockData[0] != 0 && blockData[0] != 0
&& !done) && !done) {
{ initResult = InitNode(&node, blockData, &bytesRead,
initResult = InitNode(&node, blockData, &bytesRead, ns->joliet_level); ns->joliet_level);
TRACE(("fs_walk - InitNode returned %s, filename %s, %d bytes read\n", strerror(initResult), node.fileIDString, bytesRead)); TRACE(("fs_walk - InitNode returned %s, filename %s, %d bytes read\n", strerror(initResult), node.fileIDString, bytesRead));
if (initResult == B_NO_ERROR) { if (initResult == B_OK) {
if (strlen(node.fileIDString) == strlen(file) if (!strcmp(node.fileIDString, file)) {
&& !strncmp(node.fileIDString, file, strlen(file)))
{
TRACE(("fs_walk - success, found vnode at block %Ld, pos %Ld\n", block, blockBytesRead)); TRACE(("fs_walk - success, found vnode at block %Ld, pos %Ld\n", block, blockBytesRead));
*_vnodeID = (block << 30) + (blockBytesRead & 0xFFFFFFFF); *_vnodeID = (block << 30)
+ (blockBytesRead & 0xffffffff);
TRACE(("fs_walk - New vnode id is %Ld\n", *_vnodeID)); TRACE(("fs_walk - New vnode id is %Ld\n", *_vnodeID));
if (get_vnode(ns->id, *_vnodeID, (void **)&newNode) != 0) result = get_vnode(ns->id, *_vnodeID,
result = EINVAL; (void **)&newNode);
else { if (result == B_OK) {
newNode->parID = baseNode->id; newNode->parID = baseNode->id;
done = TRUE; done = true;
result = B_NO_ERROR;
} }
} else { } else {
if (node.fileIDString != NULL) {
free(node.fileIDString); free(node.fileIDString);
node.fileIDString = NULL; node.fileIDString = NULL;
}
if (node.attr.slName != NULL) {
free(node.attr.slName); free(node.attr.slName);
node.attr.slName = NULL; node.attr.slName = NULL;
} }
}
} else { } else {
result = initResult; result = initResult;
if (bytesRead == 0) if (bytesRead == 0)
@@ -365,61 +305,54 @@ fs_walk(void *_ns, void *base, const char *file, ino_t *_vnodeID, int *_type)
if (newNode) if (newNode)
*_type = newNode->attr.stat[FS_DATA_FORMAT].st_mode; *_type = newNode->attr.stat[FS_DATA_FORMAT].st_mode;
} TRACE(("fs_walk - EXIT, result is %s, vnid is %Lu\n",
TRACE(("fs_walk - EXIT, result is %s, vnid is %Lu\n", strerror(result), *_vnodeID)); strerror(result), *_vnodeID));
return result; return result;
} }
static status_t static status_t
fs_read_vnode(void *_ns, ino_t vnid, void **node, bool reenter) fs_read_vnode(void *_ns, ino_t vnodeID, void **_node, bool reenter)
{ {
uint32 block, pos;
nspace *ns = (nspace*)_ns; nspace *ns = (nspace*)_ns;
status_t result = B_NO_ERROR;
vnode *newNode = (vnode*)calloc(sizeof(vnode), 1); vnode *newNode = (vnode*)calloc(sizeof(vnode), 1);
if (newNode == NULL)
return B_NO_MEMORY;
(void)reenter; uint32 pos = vnodeID & 0x3fffffff;
uint32 block = vnodeID >> 30;
pos = (vnid & 0x3FFFFFFF); TRACE(("fs_read_vnode - block = %ld, pos = %ld, raw = %Lu node 0x%x\n",
block = (vnid >> 30); block, pos, vnodeID, newNode));
TRACE(("fs_read_vnode - ENTER, block = %ld, pos = %ld, raw = %Lu node 0x%x\n", if (pos > ns->logicalBlkSize[FS_DATA_FORMAT])
block, pos, vnid, newNode)); return B_BAD_VALUE;
if (newNode != NULL) { char *data = (char *)block_cache_get_etc(ns->fBlockCache,
if (vnid == ISO_ROOTNODE_ID) { block, 0, ns->logicalBlkSize[FS_DATA_FORMAT]);
TRACE(("fs_read_vnode - root node requested.\n")); if (data == NULL) {
memcpy(newNode, &(ns->rootDirRec), sizeof(vnode)); free(newNode);
*node = (void*)newNode; return B_IO_ERROR;
} else { }
char *blockData = (char *)block_cache_get_etc(ns->fBlockCache, block, 0, ns->logicalBlkSize[FS_DATA_FORMAT]);
if (pos > ns->logicalBlkSize[FS_DATA_FORMAT]) { status_t result = InitNode(newNode, data + pos, NULL, ns->joliet_level);
if (blockData != NULL)
block_cache_put(ns->fBlockCache, block); block_cache_put(ns->fBlockCache, block);
result = EINVAL; if (result < B_OK) {
} else if (blockData != NULL) { free(newNode);
result = InitNode(newNode, blockData + pos, NULL, ns->joliet_level); return result;
block_cache_put(ns->fBlockCache, block);
newNode->id = vnid;
TRACE(("fs_read_vnode - init result is %s\n", strerror(result)));
*node = (void *)newNode;
TRACE(("fs_read_vnode - new file %s, size %ld\n", newNode->fileIDString, newNode->dataLen[FS_DATA_FORMAT]));
} }
}
} else
result = ENOMEM;
if (result == B_OK && !(newNode->flags & ISO_ISDIR)) { newNode->id = vnodeID;
newNode->cache = file_cache_create(ns->id, vnid, *_node = (void *)newNode;
if ((newNode->flags & ISO_ISDIR) == 0) {
newNode->cache = file_cache_create(ns->id, vnodeID,
newNode->dataLen[FS_DATA_FORMAT]); newNode->dataLen[FS_DATA_FORMAT]);
} }
TRACE(("fs_read_vnode - EXIT, result is %s\n", strerror(result))); return B_OK;
return result;
} }
@@ -453,97 +386,33 @@ fs_release_vnode(void *ns, void *_node, bool reenter)
static status_t static status_t
fs_get_file_map(fs_volume _fs, fs_vnode _node, off_t pos, size_t reqLen, fs_read_pages(fs_volume _fs, fs_vnode _node, fs_cookie _cookie, off_t pos,
struct file_io_vec *vecs, size_t *_count) const iovec *vecs, size_t count, size_t *_numBytes, bool reenter)
{ {
nspace *ns = (nspace *)_fs; // global stuff nspace *ns = (nspace *)_fs;
vnode *node = (vnode *)_node; // The read file vnode. vnode *node = (vnode *)_node;
uint16 blockSize = ns->logicalBlkSize[FS_DATA_FORMAT];
uint32 startBlock = node->startLBN[FS_DATA_FORMAT] + (pos / blockSize);
off_t blockPos = pos % blockSize;
off_t numBlocks = 0;
uint32 dataLen = node->dataLen[FS_DATA_FORMAT];
size_t endLen = 0;
size_t startLen = 0;
size_t index = 0, max = *_count;
TRACE(("fs_get_file_map - ENTER (0x%x)\n", node)); uint32 fileSize = node->dataLen[FS_DATA_FORMAT];
size_t bytesLeft = *_numBytes;
// Allow an open to work on a dir, but no reads if (pos >= fileSize) {
if (node->flags & ISO_ISDIR) *_numBytes = 0;
return EISDIR;
if (pos < 0)
pos = 0;
*_count = 0;
// If passed-in requested length is bigger than file size, change it to
// file size.
if (reqLen + pos > dataLen)
reqLen = dataLen - pos;
// Compute the length of the partial start-block read, if any.
if (reqLen + blockPos <= blockSize)
startLen = reqLen;
else if (blockPos > 0)
startLen = blockSize - blockPos;
if (blockPos == 0 && reqLen >= blockSize) {
TRACE(("Setting startLen to 0\n"));
startLen = 0;
}
// Compute the length of the partial end-block read, if any.
if (reqLen + blockPos > blockSize)
endLen = (reqLen + blockPos) % blockSize;
// Compute the number of middle blocks to read.
numBlocks = ((reqLen - endLen - startLen) / blockSize);
if (pos >= dataLen) {
// If pos >= file length, return
return B_OK; return B_OK;
} }
if (pos + bytesLeft > fileSize) {
// Read in the first, potentially partial, block. bytesLeft = fileSize - pos;
if (startLen > 0) { *_numBytes = bytesLeft;
vecs[index].offset = startBlock * blockSize + blockPos;
vecs[index].length = startLen;
startBlock++;
index++;
if (index >= max) {
// we're out of file_io_vecs; let's bail out
*_count = index;
return B_BUFFER_OVERFLOW;
}
} }
// Read in the middle blocks. file_io_vec fileVec;
if (numBlocks > 0) { fileVec.offset = pos + node->startLBN[FS_DATA_FORMAT]
for (int32 i = startBlock; i < startBlock + numBlocks; i++) { * ns->logicalBlkSize[FS_DATA_FORMAT];
vecs[index].offset = i * blockSize; fileVec.length = bytesLeft;
vecs[index].length = blockSize;
index++;
if (index >= max) {
// we're out of file_io_vecs; let's bail out
*_count = index;
return B_BUFFER_OVERFLOW;
}
}
}
// Read in the last partial block. uint32 vecIndex = 0;
if (endLen > 0) { size_t vecOffset = 0;
off_t endBlock = startBlock + numBlocks; return read_file_io_vec_pages(ns->fd, &fileVec, 1, vecs, count,
vecs[index].offset = endBlock * blockSize; &vecIndex, &vecOffset, &bytesLeft);
vecs[index].length = endLen;
index++;
}
*_count = index;
TRACE(("fs_get_file_map - EXIT\n"));
return B_OK;
} }
@@ -595,129 +464,25 @@ fs_open(void *_ns, void *_node, int omode, void **cookie)
static status_t static status_t
fs_read(void *_ns, void *_node, void *cookie, off_t pos, void *buf, size_t *len) fs_read(void *_ns, void *_node, void *cookie, off_t pos, void *buffer,
size_t *_length)
{ {
#if 0 vnode *node = (vnode *)_node;
nspace *ns = (nspace *)_ns; // global stuff
vnode *node = (vnode *)_node; // The read file vnode.
uint16 blockSize = ns->logicalBlkSize[FS_DATA_FORMAT];
uint32 startBlock = node->startLBN[FS_DATA_FORMAT] + (pos / blockSize);
off_t blockPos = pos % blockSize;
off_t numBlocks = 0;
uint32 dataLen = node->dataLen[FS_DATA_FORMAT];
status_t result = B_NO_ERROR;
size_t endLen = 0;
size_t reqLen = *len;
size_t startLen = 0;
(void)cookie;
// Allow an open to work on a dir, but no reads
if (node->flags & ISO_ISDIR) if (node->flags & ISO_ISDIR)
return EISDIR; return EISDIR;
if (pos < 0) uint32 fileSize = node->dataLen[FS_DATA_FORMAT];
pos = 0;
*len = 0;
// If passed-in requested length is bigger than file size, change it to
// file size.
if (reqLen + pos > dataLen)
reqLen = dataLen - pos;
// Compute the length of the partial start-block read, if any.
if (reqLen + blockPos <= blockSize)
startLen = reqLen;
else if (blockPos > 0)
startLen = blockSize - blockPos;
if (blockPos == 0 && reqLen >= blockSize) {
TRACE(("Setting startLen to 0, even block read\n"));
startLen = 0;
}
// Compute the length of the partial end-block read, if any.
if (reqLen + blockPos > blockSize)
endLen = (reqLen + blockPos) % blockSize;
// Compute the number of middle blocks to read.
numBlocks = ((reqLen - endLen - startLen) / blockSize);
//dprintf("fs_read - ENTER, pos is %Ld, len is %lu\n", pos, reqLen);
//dprintf("fs_read - filename is %s\n", node->fileIDString);
//dprintf("fs_read - total file length is %lu\n", dataLen);
//dprintf("fs_read - start block of file is %lu\n", node->startLBN[FS_DATA_FORMAT]);
//dprintf("fs_read - block pos is %Lu\n", blockPos);
//dprintf("fs_read - read block will be %lu\n", startBlock);
//dprintf("fs_read - startLen is %lu\n", startLen);
//dprintf("fs_read - endLen is %lu\n", endLen);
//dprintf("fs_read - num blocks to read is %Ld\n", numBlocks);
if (pos >= dataLen) {
// If pos >= file length, return length of 0.
*len = 0;
return B_OK;
}
// Read in the first, potentially partial, block.
if (startLen > 0) {
off_t cachedBlock = startBlock;
char *blockData = (char *)block_cache_get_etc(ns->fBlockCache, startBlock, 0, blockSize);
if (blockData != NULL) {
//dprintf("fs_read - copying first block, len is %d.\n", startLen);
memcpy(buf, blockData+blockPos, startLen);
*len += startLen;
block_cache_put(ns->fBlockCache, cachedBlock);
startBlock++;
} else
result = EIO;
}
// Read in the middle blocks.
if (numBlocks > 0 && result == B_NO_ERROR) {
TRACE(("fs_read - getting middle blocks\n"));
char *endBuf = ((char *)buf) + startLen;
for (int32 i=startBlock; i<startBlock+numBlocks; i++) {
char *blockData = (char *)block_cache_get_etc(ns->fBlockCache, i, 0, blockSize);
memcpy(endBuf, blockData, blockSize);
*len += blockSize;
endBuf += blockSize;
block_cache_put(ns->fBlockCache, i);
}
}
// Read in the last partial block.
if (result == B_NO_ERROR && endLen > 0) {
off_t endBlock = startBlock + numBlocks;
char *endBlockData = (char*)block_cache_get_etc(ns->fBlockCache, endBlock, 0, blockSize);
if (endBlockData != NULL) {
char *endBuf = ((char *)buf) + (reqLen - endLen);
memcpy(endBuf, endBlockData, endLen);
block_cache_put(ns->fBlockCache, endBlock);
*len += endLen;
} else
result = EIO;
}
TRACE(("fs_read - EXIT, result is %s\n", strerror(result)));
return result;
#else
vnode *node = (vnode *)_node; // The read file vnode.
uint32 dataLen = node->dataLen[FS_DATA_FORMAT];
// set/check boundaries for pos/length // set/check boundaries for pos/length
if (pos < 0) { if (pos < 0)
return B_BAD_VALUE; return B_BAD_VALUE;
} if (pos >= fileSize) {
if (pos >= dataLen) { *_length = 0;
// If pos >= file length, return length of 0.
*len = 0;
return B_OK; return B_OK;
} }
return file_cache_read(node->cache, NULL, pos, buf, len);
#endif return file_cache_read(node->cache, NULL, pos, buffer, _length);
} }
@@ -728,11 +493,10 @@ fs_close(void *ns, void *node, void *cookie)
(void)node; (void)node;
(void)cookie; (void)cookie;
//dprintf("fs_close - ENTER\n");
//dprintf("fs_close - EXIT\n");
return B_OK; return B_OK;
} }
static status_t static status_t
fs_free_cookie(void *ns, void *node, void *cookie) fs_free_cookie(void *ns, void *node, void *cookie)
{ {
@@ -740,14 +504,10 @@ fs_free_cookie(void *ns, void *node, void *cookie)
(void)node; (void)node;
(void)cookie; (void)cookie;
// We don't allocate file cookies, so we do nothing here.
//dprintf("fs_free_cookie - ENTER\n");
//if (cookie != NULL) free (cookie);
//dprintf("fs_free_cookie - EXIT\n");
return B_OK; return B_OK;
} }
// fs_access - checks permissions for access.
static status_t static status_t
fs_access(void *ns, void *node, int mode) fs_access(void *ns, void *node, int mode)
{ {
@@ -755,23 +515,18 @@ fs_access(void *ns, void *node, int mode)
(void)node; (void)node;
(void)mode; (void)mode;
// ns - global, fs-specific struct for device
// node - node to check permissions for
// mode - requested permissions on node.
//dprintf("fs_access - ENTER\n");
//dprintf("fs_access - EXIT\n");
return B_OK; return B_OK;
} }
static status_t static status_t
fs_read_link(void *_ns, void *_node, char *buffer, size_t *_bufferSize) fs_read_link(void */*_volume*/, void *_node, char *buffer, size_t *_bufferSize)
{ {
vnode *node = (vnode *)_node; vnode *node = (vnode *)_node;
status_t result = EINVAL;
(void)_ns; if (!S_ISLNK(node->attr.stat[FS_DATA_FORMAT].st_mode))
return B_BAD_VALUE;
if (S_ISLNK(node->attr.stat[FS_DATA_FORMAT].st_mode)) {
size_t length = strlen(node->attr.slName); size_t length = strlen(node->attr.slName);
if (length > *_bufferSize) if (length > *_bufferSize)
memcpy(buffer, node->attr.slName, *_bufferSize); memcpy(buffer, node->attr.slName, *_bufferSize);
@@ -780,10 +535,7 @@ fs_read_link(void *_ns, void *_node, char *buffer, size_t *_bufferSize)
*_bufferSize = length; *_bufferSize = length;
} }
result = B_NO_ERROR; return B_OK;
}
return result;
} }
@@ -791,28 +543,24 @@ static status_t
fs_open_dir(void *_ns, void *_node, void **cookie) fs_open_dir(void *_ns, void *_node, void **cookie)
{ {
vnode *node = (vnode *)_node; vnode *node = (vnode *)_node;
status_t result = B_NO_ERROR;
dircookie *dirCookie = (dircookie *)malloc(sizeof(dircookie));
(void)_ns; TRACE(("fs_open_dir - node is 0x%x\n", _node));
TRACE(("fs_open_dir - ENTER, node is 0x%x\n", _node));
if (!(node->flags & ISO_ISDIR)) if (!(node->flags & ISO_ISDIR))
result = EMFILE; return B_NOT_A_DIRECTORY;
dircookie *dirCookie = (dircookie *)malloc(sizeof(dircookie));
if (dirCookie == NULL)
return B_NO_MEMORY;
if (dirCookie != NULL) {
dirCookie->startBlock = node->startLBN[FS_DATA_FORMAT]; dirCookie->startBlock = node->startLBN[FS_DATA_FORMAT];
dirCookie->block = node->startLBN[FS_DATA_FORMAT]; dirCookie->block = node->startLBN[FS_DATA_FORMAT];
dirCookie->totalSize = node->dataLen[FS_DATA_FORMAT]; dirCookie->totalSize = node->dataLen[FS_DATA_FORMAT];
dirCookie->pos = 0; dirCookie->pos = 0;
dirCookie->id = node->id; dirCookie->id = node->id;
*cookie = (void *)dirCookie; *cookie = (void *)dirCookie;
} else
result = ENOMEM;
TRACE(("fs_open_dir - EXIT\n")); return B_OK;
return result;
} }
@@ -820,18 +568,15 @@ static status_t
fs_read_dir(void *_ns, void *_node, void *_cookie, struct dirent *buffer, fs_read_dir(void *_ns, void *_node, void *_cookie, struct dirent *buffer,
size_t bufferSize, uint32 *num) size_t bufferSize, uint32 *num)
{ {
status_t result = B_NO_ERROR;
nspace *ns = (nspace *)_ns; nspace *ns = (nspace *)_ns;
dircookie *dirCookie = (dircookie *)_cookie; dircookie *dirCookie = (dircookie *)_cookie;
(void)_node;
TRACE(("fs_read_dir - ENTER\n")); TRACE(("fs_read_dir - ENTER\n"));
result = ISOReadDirEnt(ns, dirCookie, buffer, bufferSize); status_t result = ISOReadDirEnt(ns, dirCookie, buffer, bufferSize);
// If we succeeded, return 1, the number of dirents we read. // If we succeeded, return 1, the number of dirents we read.
if (result == B_NO_ERROR) if (result == B_OK)
*num = 1; *num = 1;
else else
*num = 0; *num = 0;
@@ -840,7 +585,7 @@ fs_read_dir(void *_ns, void *_node, void *_cookie, struct dirent *buffer,
// a zero in *num. // a zero in *num.
if (result == ENOENT) if (result == ENOENT)
result = B_NO_ERROR; result = B_OK;
TRACE(("fs_read_dir - EXIT, result is %s\n", strerror(result))); TRACE(("fs_read_dir - EXIT, result is %s\n", strerror(result)));
return result; return result;
@@ -850,35 +595,17 @@ fs_read_dir(void *_ns, void *_node, void *_cookie, struct dirent *buffer,
static status_t static status_t
fs_rewind_dir(void *ns, void *node, void* _cookie) fs_rewind_dir(void *ns, void *node, void* _cookie)
{ {
status_t result = EINVAL;
dircookie *cookie = (dircookie*)_cookie; dircookie *cookie = (dircookie*)_cookie;
(void)ns;
(void)node;
//dprintf("fs_rewind_dir - ENTER\n");
if (cookie != NULL) {
cookie->block = cookie->startBlock; cookie->block = cookie->startBlock;
cookie->pos = 0; cookie->pos = 0;
result = B_NO_ERROR; return B_OK;
}
//dprintf("fs_rewind_dir - EXIT, result is %s\n", strerror(result));
return result;
} }
static status_t static status_t
fs_close_dir(void *ns, void *node, void *cookie) fs_close_dir(void *ns, void *node, void *cookie)
{ {
(void)ns;
(void)node;
(void)cookie;
// ns - global, fs-specific struct for device
// node - directory to close
// cookie - current cookie for directory.
//dprintf("fs_close_dir - ENTER\n");
//dprintf("fs_close_dir - EXIT\n");
return B_OK; return B_OK;
} }
@@ -886,20 +613,11 @@ fs_close_dir(void *ns, void *node, void *cookie)
static status_t static status_t
fs_free_dir_cookie(void *ns, void *node, void *cookie) fs_free_dir_cookie(void *ns, void *node, void *cookie)
{ {
(void)ns;
(void)node;
// ns - global, fs-specific struct for device
// node - directory related to cookie
// cookie - current cookie for directory, to free.
//dprintf("fs_free_dir_cookie - ENTER\n");
if (cookie != NULL)
free(cookie); free(cookie);
//dprintf("fs_free_dir_cookie - EXIT\n");
return B_OK; return B_OK;
} }
// #pragma mark - // #pragma mark -
@@ -908,7 +626,6 @@ iso_std_ops(int32 op, ...)
{ {
switch (op) { switch (op) {
case B_MODULE_INIT: case B_MODULE_INIT:
return B_OK;
case B_MODULE_UNINIT: case B_MODULE_UNINIT:
return B_OK; return B_OK;
default: default:
@@ -944,43 +661,43 @@ static file_system_module_info sISO660FileSystem = {
&fs_get_vnode_name, &fs_get_vnode_name,
&fs_read_vnode, &fs_read_vnode,
&fs_release_vnode, &fs_release_vnode,
NULL, // &fs_remove_vnode() NULL, // fs_remove_vnode()
/* VM file access */ /* VM file access */
NULL, // &fs_can_page NULL, // fs_can_page
NULL, // &fs_read_pages &fs_read_pages,
NULL, // &fs_write_pages NULL, // fs_write_pages
&fs_get_file_map, NULL, // fs_get_file_map
NULL, // &fs_ioctl NULL, // fs_ioctl
NULL, // &fs_set_flags NULL, // fs_set_flags
NULL, // &fs_select NULL, // fs_select
NULL, // &fs_deselect NULL, // fs_deselect
NULL, // &fs_fsync NULL, // fs_fsync
&fs_read_link, &fs_read_link,
NULL, // &fs_create_symlink, NULL, // fs_create_symlink
NULL, // &fs_link, NULL, // fs_link,
NULL, // &fs_unlink NULL, // fs_unlink
NULL, // &fs_rename NULL, // fs_rename
&fs_access, &fs_access,
&fs_read_stat, &fs_read_stat,
NULL, // &fs_write_stat NULL, // fs_write_stat
/* file operations */ /* file operations */
NULL, // &fs_create NULL, // fs_create
&fs_open, &fs_open,
&fs_close, &fs_close,
&fs_free_cookie, &fs_free_cookie,
&fs_read, &fs_read,
NULL, // &fs_write NULL, // fs_write
/* directory operations */ /* directory operations */
NULL, // &fs_create_dir NULL, // fs_create_dir
NULL, // &fs_remove_dir NULL, // fs_remove_dir
&fs_open_dir, &fs_open_dir,
&fs_close_dir, &fs_close_dir,
&fs_free_dir_cookie, &fs_free_dir_cookie,
@@ -988,42 +705,42 @@ static file_system_module_info sISO660FileSystem = {
&fs_rewind_dir, &fs_rewind_dir,
/* attribute directory operations */ /* attribute directory operations */
NULL, // &fs_open_attr_dir NULL, // fs_open_attr_dir
NULL, // &fs_close_attr_dir NULL, // fs_close_attr_dir
NULL, // &fs_free_attr_dir_cookie NULL, // fs_free_attr_dir_cookie
NULL, // &fs_read_attr_dir NULL, // fs_read_attr_dir
NULL, // &fs_rewind_attr_dir NULL, // fs_rewind_attr_dir
/* attribute operations */ /* attribute operations */
NULL, // &fs_create_attr NULL, // fs_create_attr
NULL, // &fs_open_attr NULL, // fs_open_attr
NULL, // &fs_close_attr NULL, // fs_close_attr
NULL, // &fs_free_attr_cookie NULL, // fs_free_attr_cookie
NULL, // &fs_read_attr NULL, // fs_read_attr
NULL, // &fs_write_attr NULL, // fs_write_attr
NULL, // &fs_read_attr_stat NULL, // fs_read_attr_stat
NULL, // &fs_write_attr_stat NULL, // fs_write_attr_stat
NULL, // &fs_rename_attr NULL, // fs_rename_attr
NULL, // &fs_remove_attr NULL, // fs_remove_attr
/* index directory & index operations */ /* index directory & index operations */
NULL, // &fs_open_index_dir NULL, // fs_open_index_dir
NULL, // &fs_close_index_dir NULL, // fs_close_index_dir
NULL, // &fs_free_index_dir_cookie NULL, // fs_free_index_dir_cookie
NULL, // &fs_read_index_dir NULL, // fs_read_index_dir
NULL, // &fs_rewind_index_dir NULL, // fs_rewind_index_dir
NULL, // &fs_create_index NULL, // fs_create_index
NULL, // &fs_remove_index NULL, // fs_remove_index
NULL, // &fs_stat_index NULL, // fs_stat_index
/* query operations */ /* query operations */
NULL, // &fs_open_query NULL, // fs_open_query
NULL, // &fs_close_query NULL, // fs_close_query
NULL, // &fs_free_query_cookie NULL, // fs_free_query_cookie
NULL, // &fs_read_query NULL, // fs_read_query
NULL, // &fs_rewind_query NULL, // fs_rewind_query
}; };
module_info *modules[] = { module_info *modules[] = {