Patch by Jens Arm with cleanup by myself:

Implemented the statfs operation which helps to get
information like used and free blocks on the volume.


git-svn-id: file:///srv/svn/repos/haiku/haiku/trunk@31716 a95241bf-73f2-0310-859d-f6bbb57e9c96
This commit is contained in:
Stephan Aßmus
2009-07-23 13:47:29 +00:00
parent d0ed3c5f45
commit 130e0a69f8
+81 -31
View File
@@ -125,15 +125,12 @@ fromFsshStatToStat(struct fssh_stat* f_stbuf, struct stat* stbuf)
stbuf->st_ctime = f_stbuf->fssh_st_ctime; stbuf->st_ctime = f_stbuf->fssh_st_ctime;
} }
#define _ERR(x) (-1*fssh_to_host_error(x)) #define _ERR(x) (-1 * fssh_to_host_error(x))
// pragma mark - FUSE functions // pragma mark - FUSE functions
//extern "C" {
int int
fuse_getattr(const char* path, struct stat* stbuf) fuse_getattr(const char* path, struct stat* stbuf)
{ {
@@ -347,56 +344,109 @@ fuse_destroy(void* priv_data)
} }
//} // extern "C" { static fssh_dev_t
get_volume_id()
{
struct fssh_stat st;
fssh_status_t error = _kern_read_stat(-1, kMountPoint, false, &st,
sizeof(st));
if (error != FSSH_B_OK) {
fprintf(stderr, "get_volume_id(): Failed to stat() mount point: %s\n",
fssh_strerror(error));
return error;
}
return st.fssh_st_dev;
}
struct fuse_operations fuse_cmds; static int
fuse_statfs(const char *path __attribute__((unused)),
struct statvfs *sfs)
{
PRINTD("##statfs\n");
fssh_dev_t volumeID = get_volume_id();
if (volumeID < 0)
return _ERR(volumeID);
fssh_fs_info info;
fssh_status_t status = _kern_read_fs_info(volumeID, &info);
if (status != FSSH_B_OK)
return _ERR(status);
sfs->f_bsize = sfs->f_frsize = info.block_size;
sfs->f_blocks = info.total_blocks;
sfs->f_bavail = sfs->f_bfree = info.free_blocks;
return 0;
}
struct fuse_operations gFUSEOperations;
static void static void
initialiseFuseOps(struct fuse_operations* fuse_cmds) initialiseFuseOps(struct fuse_operations* fuseOps)
{ {
fuse_cmds->getattr = fuse_getattr; fuseOps->getattr = fuse_getattr;
fuse_cmds->access = fuse_access; fuseOps->access = fuse_access;
fuse_cmds->readlink = fuse_readlink; fuseOps->readlink = fuse_readlink;
fuse_cmds->readdir = fuse_readdir; fuseOps->readdir = fuse_readdir;
fuse_cmds->mknod = fuse_mknod; fuseOps->mknod = fuse_mknod;
fuse_cmds->mkdir = fuse_mkdir; fuseOps->mkdir = fuse_mkdir;
fuse_cmds->symlink = fuse_symlink; fuseOps->symlink = fuse_symlink;
fuse_cmds->unlink = fuse_unlink; fuseOps->unlink = fuse_unlink;
fuse_cmds->rmdir = fuse_rmdir; fuseOps->rmdir = fuse_rmdir;
fuse_cmds->rename = fuse_rename; fuseOps->rename = fuse_rename;
fuse_cmds->link = fuse_link; fuseOps->link = fuse_link;
fuse_cmds->chmod = fuse_chmod; fuseOps->chmod = fuse_chmod;
fuse_cmds->chown = fuse_chown; fuseOps->chown = fuse_chown;
fuse_cmds->truncate = NULL; fuseOps->truncate = NULL;
fuse_cmds->utimens = NULL; fuseOps->utimens = NULL;
fuse_cmds->open = fuse_open; fuseOps->open = fuse_open;
fuse_cmds->read = fuse_read; fuseOps->read = fuse_read;
fuse_cmds->write = fuse_write; fuseOps->write = fuse_write;
fuse_cmds->statfs = NULL; fuseOps->statfs = fuse_statfs;
fuse_cmds->release = NULL; fuseOps->release = NULL;
fuse_cmds->fsync = NULL; fuseOps->fsync = NULL;
fuse_cmds->destroy = fuse_destroy; fuseOps->destroy = fuse_destroy;
} }
static int static int
fssh_fuse_session(const char* device, const char* mntPoint, const char* fsName) fssh_fuse_session(const char* device, const char* mntPoint, const char* fsName)
{ {
// Mount the volume in the root FS.
fssh_dev_t fsDev = _kern_mount(kMountPoint, device, fsName, 0, NULL, 0); fssh_dev_t fsDev = _kern_mount(kMountPoint, device, fsName, 0, NULL, 0);
if (fsDev < 0) { if (fsDev < 0) {
fprintf(stderr, "Error: Mounting FS failed: %s\n", fprintf(stderr, "Error: Mounting FS failed: %s\n",
fssh_strerror(fsDev)); fssh_strerror(fsDev));
return 1; return 1;
} }
// Run the fuse_main() loop.
const char* argv[5]; const char* argv[5];
argv[0] = (const char*)"bfs_shell"; argv[0] = (const char*)"bfs_shell";
argv[1] = mntPoint; argv[1] = mntPoint;
argv[2] = (const char*)"-d"; argv[2] = (const char*)"-d";
argv[3] = (const char*)"-s"; argv[3] = (const char*)"-s";
initialiseFuseOps(&fuse_cmds);
return fuse_main(4, (char**)argv, &fuse_cmds, NULL); initialiseFuseOps(&gFUSEOperations);
int ret = fuse_main(4, (char**)argv, &gFUSEOperations, NULL);
// Unmount the volume again.
_kern_setcwd(-1, "/");
// Avoid a "busy" vnode.
fssh_status_t error = _kern_unmount(kMountPoint, 0);
if (error != FSSH_B_OK) {
fprintf(stderr, "Error: Unmounting FS failed: %s\n",
fssh_strerror(error));
return 1;
}
return ret;
} }