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:
+81
-31
@@ -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;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user