Add primary cache management feature to libminixfs as mfs and ext2 currently do separately, remove cache code from mfs and ext2, and make them use the libminixfs interface. This makes all fields of the buf struct private to libminixfs and FS clients aren't supposed to access them at all. Only the opaque 'void *data' field (the FS block contents, used to be called bp) is to be accessed by the FS client. The main purpose is to implement the interface to the 2ndary vm cache just once, get rid of some code duplication, and add a little abstraction to reduce the code inertia of the whole caching business. Some minor sanity checking and prohibition done by mfs in this code as removed from the generic primary cache code as a result: - checking all inodes are not in use when allocating/resizing the cache - checking readonly filesystems aren't written to - checking the superblock isn't written to on mounted filesystems The minixfslib code relies on fs_blockstats() in the client filesystem to return some FS usage information.
150 lines
4.2 KiB
C
150 lines
4.2 KiB
C
#include "inc.h"
|
|
#include <assert.h>
|
|
#include <sys/stat.h>
|
|
#include <sys/statfs.h>
|
|
#include <sys/statvfs.h>
|
|
#include <minix/com.h>
|
|
#include <string.h>
|
|
#include <time.h>
|
|
|
|
#include <minix/vfsif.h>
|
|
|
|
|
|
/*===========================================================================*
|
|
* stat_dir_record *
|
|
*===========================================================================*/
|
|
static int stat_dir_record(
|
|
register struct dir_record *dir, /* pointer to dir record to stat */
|
|
int pipe_pos, /* position in a pipe, supplied by fstat() */
|
|
endpoint_t who_e, /* Caller endpoint */
|
|
cp_grant_id_t gid /* grant for the stat buf */
|
|
)
|
|
{
|
|
/* This function returns all the info about a particular inode. It's missing
|
|
* the recording date because of a bug in the standard functions stdtime.
|
|
* Once the bug is fixed the function can be called inside this function to
|
|
* return the date. */
|
|
|
|
/* Common code for stat and fstat system calls. */
|
|
struct stat statbuf;
|
|
int r;
|
|
struct tm ltime;
|
|
time_t time1;
|
|
u32_t blocks;
|
|
|
|
blocks = v_pri.volume_space_size_l;
|
|
/* The unit of blocks should be 512 */
|
|
assert(v_pri.logical_block_size_l >= 512);
|
|
blocks = blocks * (v_pri.logical_block_size_l >> 9);
|
|
|
|
memset(&statbuf, 0, sizeof(struct stat));
|
|
|
|
statbuf.st_dev = fs_dev; /* the device of the file */
|
|
statbuf.st_ino = ID_DIR_RECORD(dir); /* the id of the dir record */
|
|
statbuf.st_mode = dir->d_mode; /* flags of the file */
|
|
statbuf.st_nlink = dir->d_count; /* times this file is used */
|
|
statbuf.st_uid = 0; /* user root */
|
|
statbuf.st_gid = 0; /* group operator */
|
|
statbuf.st_rdev = NO_DEV;
|
|
statbuf.st_size = dir->d_file_size; /* size of the file */
|
|
statbuf.st_blksize = v_pri.logical_block_size_l;
|
|
statbuf.st_blocks = blocks;
|
|
|
|
ltime.tm_year = dir->rec_date[0];
|
|
ltime.tm_mon = dir->rec_date[1] - 1;
|
|
ltime.tm_mday = dir->rec_date[2];
|
|
ltime.tm_hour = dir->rec_date[3];
|
|
ltime.tm_min = dir->rec_date[4];
|
|
ltime.tm_sec = dir->rec_date[5];
|
|
ltime.tm_isdst = 0;
|
|
|
|
if (dir->rec_date[6] != 0)
|
|
ltime.tm_hour += dir->rec_date[6] / 4;
|
|
|
|
time1 = mktime(<ime);
|
|
|
|
statbuf.st_atime = time1;
|
|
statbuf.st_mtime = time1;
|
|
statbuf.st_ctime = time1;
|
|
|
|
/* Copy the struct to user space. */
|
|
r = sys_safecopyto(who_e, gid, 0, (vir_bytes) &statbuf,
|
|
(phys_bytes) sizeof(statbuf));
|
|
|
|
return(r);
|
|
}
|
|
|
|
|
|
/*===========================================================================*
|
|
* fs_stat *
|
|
*===========================================================================*/
|
|
int fs_stat()
|
|
{
|
|
register int r; /* return value */
|
|
struct dir_record *dir;
|
|
r = EINVAL;
|
|
|
|
if ((dir = get_dir_record(fs_m_in.REQ_INODE_NR)) != NULL) {
|
|
r = stat_dir_record(dir, 0, fs_m_in.m_source, fs_m_in.REQ_GRANT);
|
|
release_dir_record(dir);
|
|
}
|
|
|
|
return(r);
|
|
}
|
|
|
|
|
|
/*===========================================================================*
|
|
* fs_fstatfs *
|
|
*===========================================================================*/
|
|
int fs_fstatfs()
|
|
{
|
|
struct statfs st;
|
|
int r;
|
|
|
|
st.f_bsize = v_pri.logical_block_size_l;
|
|
|
|
/* Copy the struct to user space. */
|
|
r = sys_safecopyto(fs_m_in.m_source, fs_m_in.REQ_GRANT, 0,
|
|
(vir_bytes) &st, (phys_bytes) sizeof(st));
|
|
|
|
return(r);
|
|
}
|
|
|
|
|
|
/*===========================================================================*
|
|
* fs_statvfs *
|
|
*===========================================================================*/
|
|
int fs_statvfs()
|
|
{
|
|
struct statvfs st;
|
|
int r;
|
|
|
|
|
|
st.f_bsize = v_pri.logical_block_size_l;
|
|
st.f_frsize = st.f_bsize;
|
|
st.f_blocks = v_pri.volume_space_size_l;
|
|
st.f_bfree = 0;
|
|
st.f_bavail = 0;
|
|
st.f_files = 0;
|
|
st.f_ffree = 0;
|
|
st.f_favail = 0;
|
|
st.f_fsid = fs_dev;
|
|
st.f_flag = ST_RDONLY;
|
|
st.f_namemax = NAME_MAX;
|
|
|
|
/* Copy the struct to user space. */
|
|
r = sys_safecopyto(fs_m_in.m_source, fs_m_in.REQ_GRANT, 0, (vir_bytes) &st,
|
|
(phys_bytes) sizeof(st));
|
|
|
|
return(r);
|
|
}
|
|
|
|
/*===========================================================================*
|
|
* blockstats *
|
|
*===========================================================================*/
|
|
void fs_blockstats(u32_t *blocks, u32_t *free, u32_t *used)
|
|
{
|
|
*used = *blocks = v_pri.volume_space_size_l;
|
|
*free = 0;
|
|
}
|
|
|