Implemented optional 'statfs' for visible df(1) lufs filesystems entry.
authorshort <>
Thu, 28 Aug 2003 21:22:52 +0000 (21:22 +0000)
committershort <>
Thu, 28 Aug 2003 21:22:52 +0000 (21:22 +0000)
include/lufs/proto.h
kernel/Linux/2.4/inode.c
kernel/Linux/2.5/inode.c
lufsd/filesystem.c
lufsd/filesystem.h
lufsd/fsctl.c

index 3938430..287548b 100644 (file)
@@ -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];
index ce8e165..f7d3ad3 100644 (file)
@@ -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)
index ee4f13f..9ef652a 100644 (file)
@@ -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)
index 3836f17..261cc1c 100644 (file)
@@ -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...");
index ba8d02c..f8a5199 100644 (file)
@@ -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{
index 5f9b832..4660aa2 100644 (file)
@@ -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;