#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
};
+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];
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)
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)
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){
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...");
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{
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;