From: short <> Date: Thu, 28 Aug 2003 21:22:52 +0000 (+0000) Subject: Implemented optional 'statfs' for visible df(1) lufs filesystems entry. X-Git-Tag: lufs_0_9_6_captive1~13 X-Git-Url: http://git.jankratochvil.net/?p=lufs.git;a=commitdiff_plain;h=d3e58bd4e9541009e1fd374a57b6210e3b7d440d Implemented optional 'statfs' for visible df(1) lufs filesystems entry. --- diff --git a/include/lufs/proto.h b/include/lufs/proto.h index 3938430..287548b 100644 --- a/include/lufs/proto.h +++ b/include/lufs/proto.h @@ -45,8 +45,9 @@ #define PTYPE_READLINK 0x0F #define PTYPE_LINK 0x10 #define PTYPE_SYMLINK 0x11 +#define PTYPE_STATFS 0x12 -#define PTYPE_MAX 0x11 +#define PTYPE_MAX 0x12 #define PTYPE_ERROR 0x100 @@ -77,6 +78,15 @@ struct lufs_fattr{ }; +struct lufs_sbattr{ /* struct statfs64 */ + unsigned long long sb_bytes; + unsigned long long sb_bytes_free; + unsigned long long sb_bytes_available; + unsigned long long sb_files; + unsigned long long sb_ffree; +}; + + struct lufs_req_readdir{ unsigned short offset; char dirname[0]; diff --git a/kernel/Linux/2.4/inode.c b/kernel/Linux/2.4/inode.c index ce8e165..f7d3ad3 100644 --- a/kernel/Linux/2.4/inode.c +++ b/kernel/Linux/2.4/inode.c @@ -377,17 +377,43 @@ struct inode* lu_iget(struct super_block *sb, struct lufs_fattr *fattr) static int lu_statfs(struct super_block *sb, struct statfs *attr) { + int res; + struct iovec riov; + struct server_slot *slot; + struct lufs_sbattr sbattr; + TRACE("in\n"); + if((slot = lu_getslot(GET_INFO(sb))) == NULL) + return -ERESTARTSYS; + + riov.iov_base = &sbattr; + riov.iov_len = sizeof(sbattr); + + if((res = lu_execute(GET_INFO(sb), slot, PTYPE_STATFS, NULL, 0, &riov, 1)) < 0) + goto out; + + if(PIS_ERROR(res)){ + WARN("statfs failed\n"); + res = PERROR(res); + goto out; + } + attr->f_type = LU_MAGIC; attr->f_bsize = LU_BLOCKSIZE; - attr->f_blocks = 0; - attr->f_namelen = LU_MAXPATHLEN; - attr->f_files = -1; - attr->f_bavail = -1; + attr->f_blocks = sbattr.sb_bytes / LU_BLOCKSIZE; + attr->f_bfree = sbattr.sb_bytes_free / LU_BLOCKSIZE; + attr->f_bavail = sbattr.sb_bytes_available / LU_BLOCKSIZE; + attr->f_files = sbattr.sb_files; + attr->f_ffree = sbattr.sb_ffree; + attr->f_namelen = 0xFF; + + res = 0; + out: TRACE("out\n"); - return 0; + lu_putslot(slot); + return res; } static void lu_put_super(struct super_block *sb) diff --git a/kernel/Linux/2.5/inode.c b/kernel/Linux/2.5/inode.c index ee4f13f..9ef652a 100644 --- a/kernel/Linux/2.5/inode.c +++ b/kernel/Linux/2.5/inode.c @@ -385,17 +385,43 @@ struct inode* lu_iget(struct super_block *sb, struct lufs_fattr *fattr) static int lu_statfs(struct super_block *sb, struct statfs *attr) { + int res; + struct iovec riov; + struct server_slot *slot; + struct lufs_sbattr sbattr; + TRACE("in\n"); + if((slot = lu_getslot(GET_INFO(sb))) == NULL) + return -ERESTARTSYS; + + riov.iov_base = &sbattr; + riov.iov_len = sizeof(sbattr); + + if((res = lu_execute(GET_INFO(sb), slot, PTYPE_STATFS, NULL, 0, &riov, 1)) < 0) + goto out; + + if(PIS_ERROR(res)){ + WARN("statfs failed\n"); + res = PERROR(res); + goto out; + } + attr->f_type = LU_MAGIC; attr->f_bsize = LU_BLOCKSIZE; - attr->f_blocks = 0; - attr->f_namelen = LU_MAXPATHLEN; - attr->f_files = -1; - attr->f_bavail = -1; + attr->f_blocks = sbattr.sb_bytes / LU_BLOCKSIZE; + attr->f_bfree = sbattr.sb_bytes_free / LU_BLOCKSIZE; + attr->f_bavail = sbattr.sb_bytes_available / LU_BLOCKSIZE; + attr->f_files = sbattr.sb_files; + attr->f_ffree = sbattr.sb_ffree; + attr->f_namelen = 0xFF; + + res = 0; + out: TRACE("out\n"); - return 0; + lu_putslot(slot); + return res; } static void lu_put_super(struct super_block *sb) diff --git a/lufsd/filesystem.c b/lufsd/filesystem.c index 3836f17..261cc1c 100644 --- a/lufsd/filesystem.c +++ b/lufsd/filesystem.c @@ -392,6 +392,28 @@ generic_setattr(struct file_system *fs, struct message *msg){ return lu_makemsg(&fs->fs_msg, PTYPE_OK, NULL, 0); } +static struct message* +generic_statfs(struct file_system *fs, struct message *msg){ + struct lufs_sbattr *sbattr = (void *)fs->fs_buf; + + TRACE("statfs"); + + sbattr->sb_bytes=0; + sbattr->sb_bytes_free=0; + sbattr->sb_bytes_available=0; /* FIXME: Why -1 by original lufs? */ + sbattr->sb_files=0; /* FIXME: Why -1 by original lufs? */ + sbattr->sb_ffree=0; /* FIXME: Why -1 by original lufs? */ + if(fs->fs_ops->statfs){ + if(fs->fs_ops->statfs(fs->fs_context, sbattr) < 0){ + TRACE("statfs failed!"); + return NULL; + } + } + + /* lu_makemsg() does not copy its 'data' - use persistent 'fs->fs_buf'! */ + return lu_makemsg(&fs->fs_msg, PTYPE_OK, (void *)sbattr, sizeof(*sbattr)); +} + void handle_fs(struct file_system *fs, int sock, pid_t pid){ @@ -416,6 +438,7 @@ handle_fs(struct file_system *fs, int sock, pid_t pid){ handlers[15] = generic_readlink; // PTYPE_READLINK handlers[16] = generic_link; // PTYPE_LINK handlers[17] = generic_symlink; // PTYPE_SYMLINK + handlers[18] = generic_statfs; // PTYPE_STATFS if(!fs->fs_mounted){ TRACE("connecting the slot..."); diff --git a/lufsd/filesystem.h b/lufsd/filesystem.h index ba8d02c..f8a5199 100644 --- a/lufsd/filesystem.h +++ b/lufsd/filesystem.h @@ -43,6 +43,7 @@ struct fs_operations{ int (*link)(void*, char*, char*); int (*symlink)(void*, char*, char*); int (*setattr)(void*, char*, struct lufs_fattr*); + int (*statfs)(void*, struct lufs_sbattr*); }; struct file_system{ diff --git a/lufsd/fsctl.c b/lufsd/fsctl.c index 5f9b832..4660aa2 100644 --- a/lufsd/fsctl.c +++ b/lufsd/fsctl.c @@ -326,6 +326,10 @@ get_filesystem(struct fs_ctl *ctl, char *fs){ if(!(fops->setattr = (int(*)(void*, char*, struct lufs_fattr*))dlsym(dlhandle, buf))) ERROR(dlerror()); + sprintf(buf, "%s_statfs", fs); + /* 'statfs' is optional as it is new for lufs-0.9.6-captive. */ + fops->statfs = (int(*)(void*, struct lufs_sbattr*))dlsym(dlhandle, buf); + TRACE("file system loaded"); ctl->dlhandle = dlhandle;