ARCH_OPT := -D__ARCH_IA32
O := -O2
-W := -Wall -Wextra -Wno-unknown-pragmas
+W := -Wall -Wextra -Wno-unknown-pragmas \
+ -Wno-unused-function \
+ -Wno-unused-but-set-variable \
+ -Wno-unused-parameter \
+ -Wno-unused-variable\
+ -Werror=incompatible-pointer-types
+
CFLAGS := -std=gnu99 -ffreestanding $(O) $(W) $(ARCH_OPT)
LDFLAGS := -ffreestanding $(O) -nostdlib -lgcc
\ No newline at end of file
size_t entry_n = (rsdt->header.length - sizeof(acpi_sdthdr_t)) >> 2;
for (size_t i = 0; i < entry_n; i++) {
- acpi_sdthdr_t* sdthdr = ((acpi_apic_t**)&(rsdt->entry))[i];
+ acpi_sdthdr_t* sdthdr =
+ (acpi_sdthdr_t*)((acpi_apic_t**)&(rsdt->entry))[i];
switch (sdthdr->signature) {
case ACPI_MADT_SIG:
madt_parse((acpi_madt_t*)sdthdr, ctx);
// Cosidering only one IOAPIC present (max 24 pins)
// FIXME: use hash table instead
- toc->madt.irq_exception = (acpi_intso_t*)vcalloc(24, sizeof(acpi_intso_t*));
+ toc->madt.irq_exception =
+ (acpi_intso_t**)vcalloc(24, sizeof(acpi_intso_t*));
size_t so_idx = 0;
while (ics_start < ics_end) {
static struct ahci_hba hba;
void
-__ahci_hba_isr(isr_param param);
+__ahci_hba_isr(const isr_param* param);
int
ahci_init_device(struct hba_port* port);
"SATA III (6.0Gbps)" };
void
-__ahci_hba_isr(isr_param param)
+__ahci_hba_isr(const isr_param* param)
{
// TODO: clear the interrupt status
// TODO: I/O-operation scheduler should be here
}
int
-ahci_identify_device(struct hba_port* port)
+ahci_identify_device(struct hba_device* device)
{
// 用于重新识别设备(比如在热插拔的情况下)
- vfree(port->device);
- return ahci_init_device(port);
+ vfree(device);
+ return ahci_init_device(device->port);
}
void
#include <lunaix/mm/vmm.h>
#include <lunaix/spike.h>
+void
+sata_read_error(struct hba_port* port)
+{
+ uint32_t tfd = port->regs[HBA_RPxTFD];
+ port->device->last_error = (tfd >> 8) & 0xff;
+ port->device->last_status = tfd & 0xff;
+}
+
int
__sata_buffer_io(struct hba_device* dev,
uint64_t lba,
header->options |= HBA_CMDH_WRITE * (write == 1);
uint16_t count = ICEIL(size, port->device->block_size);
- struct sata_reg_fis* fis = table->command_fis;
+ struct sata_reg_fis* fis = (struct sata_reg_fis*)table->command_fis;
if ((port->device->flags & HBA_DEV_FEXTLBA)) {
// 如果该设备支持48位LBA寻址
{
return __sata_buffer_io(dev, lba, buffer, size, 1);
}
-
-void
-sata_read_error(struct hba_port* port)
-{
- uint32_t tfd = port->regs[HBA_RPxTFD];
- port->device->last_error = (tfd >> 8) & 0xff;
- port->device->last_status = tfd & 0xff;
-}
\ No newline at end of file
device->block_size = SCSI_FLIP(*(parameter + 2));
}
-void
+int
__scsi_buffer_io(struct hba_device* dev,
uint64_t lba,
void* buffer,
uint32_t count = ICEIL(size, port->device->block_size);
- struct sata_reg_fis* fis = table->command_fis;
+ struct sata_reg_fis* fis = (struct sata_reg_fis*)table->command_fis;
void* cdb = table->atapi_cmd;
sata_create_fis(fis, ATA_PACKET, (size << 8), 0);
fis->feature = 1 | ((!write) << 2);
return 0;
}
-void
+int
scsi_read_buffer(struct hba_device* dev,
uint64_t lba,
void* buffer,
uint32_t size)
{
- __scsi_buffer_io(dev, lba, buffer, size, 0);
+ return __scsi_buffer_io(dev, lba, buffer, size, 0);
}
-void
+int
scsi_write_buffer(struct hba_device* dev,
uint64_t lba,
void* buffer,
uint32_t size)
{
- __scsi_buffer_io(dev, lba, buffer, size, 1);
+ return __scsi_buffer_io(dev, lba, buffer, size, 1);
}
\ No newline at end of file
dev_info->flags |= HBA_DEV_FEXTLBA;
}
- ahci_parsestr(&dev_info->serial_num, data + IDDEV_OFFSERIALNUM, 10);
- ahci_parsestr(&dev_info->model, data + IDDEV_OFFMODELNUM, 20);
+ ahci_parsestr(dev_info->serial_num, data + IDDEV_OFFSERIALNUM, 10);
+ ahci_parsestr(dev_info->model, data + IDDEV_OFFMODELNUM, 20);
}
void
PCI_INTR_IRQ(pos->intr_info),
PCI_INTR_PIN(pos->intr_info));
#ifdef PCI_PRINT_BAR_LISTING
- pci_reg_t bar;
+ uint32_t bar;
for (size_t i = 1; i <= 6; i++) {
size_t size = pci_bar_sizing(pos, &bar, i);
if (!bar)
unsigned int ss;
} __attribute__((packed)) isr_param;
-typedef void (*int_subscriber)(isr_param*);
+typedef void (*int_subscriber)(const isr_param*);
#pragma region ISR_DECLARATION
uint64_t lba,
uint32_t alloc_size);
-void
+int
scsi_read_buffer(struct hba_device* dev,
uint64_t lba,
void* buffer,
uint32_t size);
-void
+int
scsi_write_buffer(struct hba_device* dev,
uint64_t lba,
void* buffer,
// PCI Configuration Space (C-Space) r/w:
// Refer to "PCI Local Bus Specification, Rev.3, Section 3.2.2.3.2"
-inline pci_reg_t
+static inline pci_reg_t
pci_read_cspace(uint32_t base, int offset)
{
io_outl(PCI_CONFIG_ADDR, base | (offset & ~0x3));
return io_inl(PCI_CONFIG_DATA);
}
-inline void
+static inline void
pci_write_cspace(uint32_t base, int offset, pci_reg_t data)
{
io_outl(PCI_CONFIG_ADDR, base | (offset & ~0x3));
#define HASH_SIZE_BITS 32
uint32_t
-strhash_32(unsigned char* str, uint32_t truncate_to);
+strhash_32(char* str, uint32_t truncate_to);
/**
* @brief Simple generic hash function
#define USTACK_END (0x9fffffff - USTACK_SIZE + 1)
#define UMMAP_AREA 0x4D000000
-#define SYS_TIMER_FREQUENCY_HZ 2048
-
#ifndef __ASM__
#include <stddef.h>
// From Linux kernel v2.6.0 <kernel.h:194>
char name_val[DEVICE_NAME_SIZE];
void* underlay;
void* fs_node;
- int (*read)(struct device* dev,
- void* buf,
- unsigned int offset,
- unsigned int len);
- int (*write)(struct device* dev,
- void* buf,
- unsigned int offset,
- unsigned int len);
+ int (*read)(struct device* dev, void* buf, size_t offset, size_t len);
+ int (*write)(struct device* dev, void* buf, size_t offset, size_t len);
};
void
static inline void
llist_append(struct llist_header* head, struct llist_header* elem)
{
- __llist_add(elem, head, head->next);
+ __llist_add(elem, head->prev, head);
}
static inline void
llist_prepend(struct llist_header* head, struct llist_header* elem)
{
- __llist_add(elem, head->prev, head);
+ __llist_add(elem, head, head->next);
}
static inline void
--- /dev/null
+#ifndef __LUNAIX_LRU_H
+#define __LUNAIX_LRU_H
+
+#include <lunaix/ds/llist.h>
+
+struct lru_zone
+{
+ struct llist_header lead_node;
+ struct llist_header zones;
+};
+
+struct lru_node
+{
+ struct llist_header lru_nodes;
+};
+
+struct lru_zone*
+lru_new_zone();
+
+void
+lru_use_one(struct lru_zone* zone, struct lru_node* node);
+
+struct lru_node*
+lru_evict_one(struct lru_zone* zone);
+
+void
+lru_remove(struct lru_node* node);
+
+#endif /* __LUNAIX_LRU_H */
#include <lunaix/ds/hashtable.h>
#include <lunaix/ds/hstr.h>
#include <lunaix/ds/llist.h>
+#include <lunaix/ds/lru.h>
#include <lunaix/status.h>
#define VFS_NAME_MAXLEN 128
#define FSTYPE_ROFS 0x1
#define VFS_VALID_CHAR(chr) \
- ('A' <= (chr) && (chr) <= 'Z' || 'a' <= (chr) && (chr) <= 'z' || \
- '0' <= (chr) && (chr) <= '9' || (chr) == '.' || (chr) == '_' || \
+ (('A' <= (chr) && (chr) <= 'Z') || ('a' <= (chr) && (chr) <= 'z') || \
+ ('0' <= (chr) && (chr) <= '9') || (chr) == '.' || (chr) == '_' || \
(chr) == '-')
extern struct hstr vfs_ddot;
extern struct hstr vfs_dot;
struct v_dnode;
+struct v_inode;
+struct v_superblock;
+struct v_file;
+struct v_fd;
struct pcache;
struct filesystem
struct v_file_ops
{
- int (*write)(struct v_file* file, void* buffer, size_t len, size_t fpos);
- int (*read)(struct v_file* file, void* buffer, size_t len, size_t fpos);
- int (*readdir)(struct v_file* file, struct dir_context* dctx);
- int (*seek)(struct v_file* file, size_t offset);
- int (*rename)(struct v_file* file, char* new_name);
+ int (*write)(struct v_inode* inode, void* buffer, size_t len, size_t fpos);
+ int (*read)(struct v_inode* inode, void* buffer, size_t len, size_t fpos);
+ int (*readdir)(struct v_inode* inode, struct dir_context* dctx);
+ int (*seek)(struct v_inode* inode, size_t offset);
+ int (*rename)(struct v_inode* inode, char* new_name);
int (*close)(struct v_file* file);
- int (*sync)(struct v_file* file);
+ int (*sync)(struct v_inode* inode);
};
struct v_file
struct llist_header* f_list;
uint32_t f_pos;
uint32_t ref_count;
- void* data; // 允许底层FS绑定他的一些专有数据
struct v_file_ops ops;
};
{
struct llist_header pg_list;
struct llist_header dirty_list;
+ struct lru_node lru;
void* pg;
uint32_t flags;
uint32_t fpos;
struct pcache
{
+ struct v_inode* master;
struct btrie tree;
struct llist_header pages;
struct llist_header dirty;
struct pcache_pg** page);
int
-pcache_write(struct v_file* file, void* data, uint32_t len, uint32_t fpos);
+pcache_write(struct v_inode* inode, void* data, uint32_t len, uint32_t fpos);
int
-pcache_read(struct v_file* file, void* data, uint32_t len, uint32_t fpos);
+pcache_read(struct v_inode* inode, void* data, uint32_t len, uint32_t fpos);
void
pcache_release(struct pcache* pcache);
int
-pcache_commit(struct v_file* file, struct pcache_pg* page);
+pcache_commit(struct v_inode* inode, struct pcache_pg* page);
void
-pcache_invalidate(struct v_file* file, struct pcache_pg* page);
+pcache_commit_all(struct v_inode* inode);
void
-pcache_commit_all(struct v_file* file);
+pcache_invalidate(struct pcache* pcache, struct pcache_pg* page);
#endif /* __LUNAIX_VFS_H */
struct llist_header siblings;
struct
{
- int (*write)(struct v_file* file,
+ int (*write)(struct v_inode* inode,
void* buffer,
size_t len,
size_t fpos);
- int (*read)(struct v_file* file, void* buffer, size_t len, size_t fpos);
+ int (*read)(struct v_inode* inode,
+ void* buffer,
+ size_t len,
+ size_t fpos);
} ops;
};
#define ELOOP -22
#define ENODEV -23
#define ERANGE -24
+#define ENOMEM LXOUTOFMEM
#endif /* __LUNAIX_CODE_H */
}
int
-__block_read(struct device* dev,
- void* buf,
- unsigned int offset,
- unsigned int len)
+__block_read(struct device* dev, void* buf, size_t offset, size_t len)
{
int errno;
struct block_dev* bdev = (struct block_dev*)dev->underlay;
}
int
-__block_write(struct device* dev,
- void* buf,
- unsigned int offset,
- unsigned int len)
+__block_write(struct device* dev, void* buf, size_t offset, size_t len)
{
int errno;
struct block_dev* bdev = (struct block_dev*)dev->underlay;
static struct twifs_node* dev_root;
int
-__dev_read(struct v_file* file, void* buffer, size_t len, size_t fpos);
+__dev_read(struct v_inode* inode, void* buffer, size_t len, size_t fpos);
int
-__dev_write(struct v_file* file, void* buffer, size_t len, size_t fpos);
+__dev_write(struct v_inode* inode, void* buffer, size_t len, size_t fpos);
void
device_init()
}
int
-__dev_read(struct v_file* file, void* buffer, size_t len, size_t fpos)
+__dev_read(struct v_inode* inode, void* buffer, size_t len, size_t fpos)
{
- struct twifs_node* dev_node = (struct twifs_node*)file->inode->data;
+ struct twifs_node* dev_node = (struct twifs_node*)inode->data;
struct device* dev = (struct device*)dev_node->data;
if (!dev->read) {
}
int
-__dev_write(struct v_file* file, void* buffer, size_t len, size_t fpos)
+__dev_write(struct v_inode* inode, void* buffer, size_t len, size_t fpos)
{
- struct twifs_node* dev_node = (struct twifs_node*)file->inode->data;
+ struct twifs_node* dev_node = (struct twifs_node*)inode->data;
struct device* dev = (struct device*)dev_node->data;
if (!dev->write) {
}
void
-__btrie_remove(struct btrie_node* node)
+__btrie_rm_recursive(struct btrie_node* node)
{
struct btrie_node* parent = node->parent;
+
if (parent) {
llist_delete(&node->siblings);
llist_delete(&node->nodes);
vfree(node);
- if (llist_empty(&parent->children)) {
- __btrie_remove(parent);
+ if (llist_empty(&parent->children) && !parent->data) {
+ __btrie_rm_recursive(parent);
}
}
}
return 0;
}
void* data = node->data;
- __btrie_remove(node);
+ if (!llist_empty(&node->children)) {
+ node->data = NULL;
+ } else {
+ __btrie_rm_recursive(node);
+ }
return data;
}
--- /dev/null
+#include <lunaix/ds/lru.h>
+#include <lunaix/mm/valloc.h>
+
+struct llist_header zone_lead = { .next = &zone_lead, .prev = &zone_lead };
+
+struct lru_zone*
+lru_new_zone()
+{
+ struct lru_zone* zone = valloc(sizeof(struct lru_zone));
+ if (!zone) {
+ return NULL;
+ }
+
+ llist_init_head(&zone->lead_node);
+ llist_append(&zone_lead, &zone->zones);
+
+ return zone;
+}
+
+void
+lru_use_one(struct lru_zone* zone, struct lru_node* node)
+{
+ if (node->lru_nodes.next && node->lru_nodes.prev) {
+ llist_delete(&node->lru_nodes);
+ }
+
+ llist_prepend(&zone->lead_node, &node->lru_nodes);
+}
+
+struct lru_node*
+lru_evict_one(struct lru_zone* zone)
+{
+ struct llist_header* tail = zone->lead_node.prev;
+ if (tail == &zone->lead_node) {
+ return;
+ }
+
+ llist_delete(tail);
+
+ return container_of(tail, struct lru_node, lru_nodes);
+}
+
+void
+lru_remove(struct lru_node* node)
+{
+ if (node->lru_nodes.next && node->lru_nodes.prev) {
+ llist_delete(&node->lru_nodes);
+ }
+}
\ No newline at end of file
#define PCACHE_DIRTY 0x1
+static struct lru_zone* pcache_zone;
+
void
pcache_init(struct pcache* pcache)
{
btrie_init(&pcache->tree, PG_SIZE_BITS);
llist_init_head(&pcache->dirty);
llist_init_head(&pcache->pages);
+ pcache_zone = lru_new_zone();
}
void
pcache_release_page(struct pcache* pcache, struct pcache_pg* page)
{
- pmm_free_page(KERNEL_PID, page->pg);
- vmm_del_mapping(PD_REFERENCED, page->pg);
+ vfree(page->pg);
llist_delete(&page->pg_list);
pcache->n_pages--;
}
+void
+pcache_evict(struct pcache* pcache)
+{
+ struct pcache_pg* page =
+ container_of(lru_evict_one(pcache_zone), struct pcache_pg, lru);
+
+ if (!page)
+ return;
+
+ pcache_invalidate(pcache, page);
+}
+
struct pcache_pg*
pcache_new_page(struct pcache* pcache, uint32_t index)
{
- void* pg = pmm_alloc_page(KERNEL_PID, 0);
- void* pg_v = vmm_vmap(pg, PG_SIZE, PG_PREM_URW);
struct pcache_pg* ppg = vzalloc(sizeof(struct pcache_pg));
- ppg->pg = pg_v;
+ void* pg = valloc(PG_SIZE);
+
+ if (!ppg || !pg) {
+ pcache_evict(pcache);
+ if (!ppg && !(ppg = vzalloc(sizeof(struct pcache_pg)))) {
+ return NULL;
+ }
+
+ if (!pg && !(pg = valloc(PG_SIZE))) {
+ return NULL;
+ }
+ }
+
+ ppg->pg = pg;
llist_append(&pcache->pages, &ppg->pg_list);
btrie_set(&pcache->tree, index, ppg);
struct pcache_pg* pg = btrie_get(&pcache->tree, index);
int is_new = 0;
*offset = index & ((1 << pcache->tree.truncated) - 1);
- if (!pg) {
- pg = pcache_new_page(pcache, index);
+ if (!pg && (pg = pcache_new_page(pcache, index))) {
pg->fpos = index - *offset;
pcache->n_pages++;
is_new = 1;
}
+ if (pg)
+ lru_use_one(pcache_zone, &pg->lru);
*page = pg;
return is_new;
}
int
-pcache_write(struct v_file* file, void* data, uint32_t len, uint32_t fpos)
+pcache_write(struct v_inode* inode, void* data, uint32_t len, uint32_t fpos)
{
uint32_t pg_off, buf_off = 0;
- struct pcache* pcache = file->inode->pg_cache;
+ struct pcache* pcache = inode->pg_cache;
struct pcache_pg* pg;
while (buf_off < len) {
pcache_get_page(pcache, fpos, &pg_off, &pg);
+ if (!pg) {
+ return ENOMEM;
+ }
+
uint32_t wr_bytes = MIN(PG_SIZE - pg_off, len - buf_off);
memcpy(pg->pg + pg_off, (data + buf_off), wr_bytes);
}
int
-pcache_read(struct v_file* file, void* data, uint32_t len, uint32_t fpos)
+pcache_read(struct v_inode* inode, void* data, uint32_t len, uint32_t fpos)
{
uint32_t pg_off, buf_off = 0, new_pg = 0;
int errno = 0;
- struct pcache* pcache = file->inode->pg_cache;
+ struct pcache* pcache = inode->pg_cache;
struct pcache_pg* pg;
- struct v_inode* inode = file->inode;
while (buf_off < len) {
if (pcache_get_page(pcache, fpos, &pg_off, &pg)) {
+
+ if (!pg) {
+ return ENOMEM;
+ }
+
// Filling up the page
- errno = inode->default_fops.read(file, pg->pg, PG_SIZE, pg->fpos);
+ errno = inode->default_fops.read(inode, pg->pg, PG_SIZE, pg->fpos);
if (errno >= 0 && errno < PG_SIZE) {
// EOF
len = buf_off + errno;
struct pcache_pg *pos, *n;
llist_for_each(pos, n, &pcache->pages, pg_list)
{
+ lru_remove(&pos->lru);
vfree(pos);
}
}
int
-pcache_commit(struct v_file* file, struct pcache_pg* page)
+pcache_commit(struct v_inode* inode, struct pcache_pg* page)
{
if (!(page->flags & PCACHE_DIRTY)) {
return;
}
- struct v_inode* inode = file->inode;
- int errno = inode->default_fops.write(file, page->pg, PG_SIZE, page->fpos);
+ int errno = inode->default_fops.write(inode, page->pg, PG_SIZE, page->fpos);
if (!errno) {
page->flags &= ~PCACHE_DIRTY;
llist_delete(&page->dirty_list);
- file->inode->pg_cache->n_dirty--;
+ inode->pg_cache->n_dirty--;
}
return errno;
}
void
-pcache_commit_all(struct v_file* file)
+pcache_commit_all(struct v_inode* inode)
{
- struct pcache* cache = file->inode->pg_cache;
+ struct pcache* cache = inode->pg_cache;
struct pcache_pg *pos, *n;
+
llist_for_each(pos, n, &cache->dirty, dirty_list)
{
- pcache_commit(file, pos);
+ pcache_commit(inode, pos);
}
}
void
-pcache_invalidate(struct v_file* file, struct pcache_pg* page)
+pcache_invalidate(struct pcache* pcache, struct pcache_pg* page)
{
- pcache_commit(file, page);
- pcache_release_page(&file->inode->pg_cache, page);
+ pcache_commit(pcache->master, page);
+ pcache_release_page(pcache, page);
}
\ No newline at end of file
__twifs_create_inode(struct twifs_node* twi_node);
int
-__twifs_iterate_dir(struct v_file* file, struct dir_context* dctx);
+__twifs_iterate_dir(struct v_inode* inode, struct dir_context* dctx);
int
__twifs_mount(struct v_superblock* vsb, struct v_dnode* mount_point);
__twifs_rmstuff(struct v_inode* inode);
int
-__twifs_fwrite(struct v_file* file, void* buffer, size_t len, size_t fpos);
+__twifs_fwrite(struct v_inode* inode, void* buffer, size_t len, size_t fpos);
int
-__twifs_fread(struct v_file* file, void* buffer, size_t len, size_t fpos);
+__twifs_fread(struct v_inode* inode, void* buffer, size_t len, size_t fpos);
void
twifs_init()
}
int
-__twifs_fwrite(struct v_file* file, void* buffer, size_t len, size_t fpos)
+__twifs_fwrite(struct v_inode* inode, void* buffer, size_t len, size_t fpos)
{
- struct twifs_node* twi_node = (struct twifs_node*)file->inode->data;
+ struct twifs_node* twi_node = (struct twifs_node*)inode->data;
if (!twi_node || !twi_node->ops.write) {
return ENOTSUP;
}
- return twi_node->ops.write(file, buffer, len, fpos);
+ return twi_node->ops.write(inode, buffer, len, fpos);
}
int
-__twifs_fread(struct v_file* file, void* buffer, size_t len, size_t fpos)
+__twifs_fread(struct v_inode* inode, void* buffer, size_t len, size_t fpos)
{
- struct twifs_node* twi_node = (struct twifs_node*)file->inode->data;
+ struct twifs_node* twi_node = (struct twifs_node*)inode->data;
if (!twi_node || !twi_node->ops.read) {
return ENOTSUP;
}
- return twi_node->ops.read(file, buffer, len, fpos);
+ return twi_node->ops.read(inode, buffer, len, fpos);
}
struct twifs_node*
}
int
-__twifs_iterate_dir(struct v_file* file, struct dir_context* dctx)
+__twifs_iterate_dir(struct v_inode* inode, struct dir_context* dctx)
{
- struct twifs_node* twi_node = (struct twifs_node*)(file->inode->data);
+ struct twifs_node* twi_node = (struct twifs_node*)(inode->data);
int counter = 0;
struct twifs_node *pos, *n;
int options)
{
struct v_dnode* interim;
- char* pathname = path;
+ const char* pathname = path;
int errno = __vfs_walk(start, path, &interim, component, options);
int counter = 0;
if ((inode->itype & VFS_IFFILE) && !inode->pg_cache) {
struct pcache* pcache = vzalloc(sizeof(struct pcache));
pcache_init(pcache);
+ pcache->master = inode;
inode->pg_cache = pcache;
}
if (!file->ops.close || !(errno = file->ops.close(file))) {
file->dnode->ref_count--;
file->inode->open_count--;
- pcache_commit_all(file);
+ pcache_commit_all(file->inode);
cake_release(file_pile, file);
}
return errno;
vfs_fsync(struct v_file* file)
{
int errno = ENOTSUP;
- pcache_commit_all(file);
+ pcache_commit_all(file->inode);
if (file->ops.sync) {
- errno = file->ops.sync(file);
- }
- if (!errno && file->inode->ops.sync) {
- return file->inode->ops.sync(file->inode);
+ errno = file->ops.sync(file->inode);
}
return errno;
}
__vfs_readdir_callback(&dctx, vfs_ddot.value, vfs_ddot.len, 0);
} else {
dctx.index -= 2;
- if ((errno = fd_s->file->ops.readdir(fd_s->file, &dctx))) {
+ if ((errno = fd_s->file->ops.readdir(fd_s->file->inode, &dctx))) {
goto done;
}
}
}
__SYSCALL_INTERRUPTIBLE(
- { errno = file->ops.read(file, buf, count, file->f_pos); })
+ { errno = file->ops.read(file->inode, buf, count, file->f_pos); })
if (errno > 0) {
file->f_pos += errno;
}
__SYSCALL_INTERRUPTIBLE(
- { errno = file->ops.write(file, buf, count, file->f_pos); })
+ { errno = file->ops.write(file->inode, buf, count, file->f_pos); })
if (errno > 0) {
file->f_pos += errno;
fpos = offset;
break;
}
- if (!file->ops.seek || !(errno = file->ops.seek(file, fpos))) {
+ if (!file->ops.seek || !(errno = file->ops.seek(file->inode, fpos))) {
file->f_pos = fpos;
}
int
vfs_readlink(struct v_dnode* dnode, char* buf, size_t size)
{
- char* link;
+ const char* link;
if (dnode->inode->ops.read_symlink) {
int errno = dnode->inode->ops.read_symlink(dnode->inode, &link);
strncpy(buf, link, size);
}
newfd_s = __current->fdtable->fds[newfd];
- if (newfd_s && (errno = vfs_close(newfd_s))) {
+ if (newfd_s && (errno = vfs_close(newfd_s->file))) {
goto done;
}
__alloc_cake(unsigned int cake_pg)
{
uintptr_t pa = pmm_alloc_cpage(KERNEL_PID, cake_pg, 0);
+ if (!pa) {
+ return NULL;
+ }
return vmm_vmap(pa, cake_pg * PG_SIZE, PG_PREM_RW);
}
{
struct cake_s* cake = __alloc_cake(pile->pg_per_cake);
+ if (!cake) {
+ return NULL;
+ }
+
int max_piece = pile->pieces_per_cake;
cake->first_piece = (void*)((uintptr_t)cake + pile->offset);
cake->next_free = 0;
- piece_index_t* free_list = &cake->free_list;
+ piece_index_t* free_list = cake->free_list;
for (size_t i = 0; i < max_piece - 1; i++) {
free_list[i] = i + 1;
}
unsigned int pg_per_cake,
int options)
{
+ if (!pile) {
+ return;
+ }
+
unsigned int offset = sizeof(long);
// 默认每块儿蛋糕对齐到地址总线宽度
pile->offset = ROUNDUP(sizeof(struct cake_s) + free_list_size, offset);
pile->pieces_per_cake -= ICEIL((pile->offset - free_list_size), piece_size);
- strncpy(&pile->pile_name, name, PILE_NAME_MAXLEN);
+ strncpy(pile->pile_name, name, PILE_NAME_MAXLEN);
llist_init_head(&pile->free);
llist_init_head(&pile->full);
pos = list_entry(pile->free.next, typeof(*pos), cakes);
}
+ if (!pos)
+ return NULL;
+
piece_index_t found_index = pos->next_free;
pos->next_free = pos->free_list[found_index];
pos->used_pieces++;
pos->used_pieces--;
pile->alloced_pieces--;
- llist_delete(pos);
+ llist_delete(&pos->cakes);
if (!pos->used_pieces) {
llist_append(&pile->free, &pos->cakes);
} else {
{
for (size_t i = 0; i < CLASS_LEN(piles_names); i++) {
int size = 1 << (i + 3);
- piles[i] = cake_new_pile(&piles_names[i], size, size > 1024 ? 8 : 1, 0);
+ piles[i] = cake_new_pile(piles_names[i], size, size > 1024 ? 8 : 1, 0);
}
// DMA 内存保证128字节对齐
for (size_t i = 0; i < CLASS_LEN(piles_names_dma); i++) {
int size = 1 << (i + 7);
piles_dma[i] = cake_new_pile(
- &piles_names_dma[i], size, size > 1024 ? 4 : 1, PILE_CACHELINE);
+ piles_names_dma[i], size, size > 1024 ? 4 : 1, PILE_CACHELINE);
}
}
void*
valloc(unsigned int size)
{
- return __valloc(size, &piles, CLASS_LEN(piles_names), 3);
+ return __valloc(size, piles, CLASS_LEN(piles_names), 3);
}
void*
vzalloc(unsigned int size)
{
- void* ptr = __valloc(size, &piles, CLASS_LEN(piles_names), 3);
+ void* ptr = __valloc(size, piles, CLASS_LEN(piles_names), 3);
memset(ptr, 0, size);
return ptr;
}
return 0;
}
- void* ptr = __valloc(alloc_size, &piles, CLASS_LEN(piles_names), 3);
+ void* ptr = __valloc(alloc_size, piles, CLASS_LEN(piles_names), 3);
memset(ptr, 0, alloc_size);
return ptr;
}
void
vfree(void* ptr)
{
- __vfree(ptr, &piles, CLASS_LEN(piles_names));
+ __vfree(ptr, piles, CLASS_LEN(piles_names));
}
void*
valloc_dma(unsigned int size)
{
- return __valloc(size, &piles_dma, CLASS_LEN(piles_names_dma), 7);
+ return __valloc(size, piles_dma, CLASS_LEN(piles_names_dma), 7);
}
void*
vzalloc_dma(unsigned int size)
{
- void* ptr = __valloc(size, &piles_dma, CLASS_LEN(piles_names_dma), 7);
+ void* ptr = __valloc(size, piles_dma, CLASS_LEN(piles_names_dma), 7);
memset(ptr, 0, size);
return ptr;
}
void
vfree_dma(void* ptr)
{
- __vfree(ptr, &piles_dma, CLASS_LEN(piles_names_dma));
+ __vfree(ptr, piles_dma, CLASS_LEN(piles_names_dma));
}
\ No newline at end of file
proc->pgid = proc->pid;
proc->fdtable = vzalloc(sizeof(struct v_fdtable));
- llist_init_head(&proc->mm.regions);
+ llist_init_head(&proc->mm.regions.head);
llist_init_head(&proc->children);
llist_init_head(&proc->grp_member);
llist_init_head(&proc->sleep.sleepers);
LOG_MODULE("SYSCALL")
extern void
-syscall_hndlr(isr_param* param);
+syscall_hndlr(const isr_param* param);
void
syscall_install()
assert_msg(timer_ctx, "Fail to initialize timer contex");
timer_ctx->active_timers = (struct lx_timer*)cake_grab(timer_pile);
- llist_init_head(timer_ctx->active_timers);
+ llist_init_head(&timer_ctx->active_timers->link);
}
void
timer->payload = payload;
timer->flags = flags;
- llist_append(timer_ctx->active_timers, &timer->link);
+ llist_append(&timer_ctx->active_timers->link, &timer->link);
return timer;
}
* @return unsigned int
*/
uint32_t
-strhash_32(unsigned char* str, uint32_t truncate_to)
+strhash_32(char* str, uint32_t truncate_to)
{
if (!str)
return 0;
clean:
@rm -rf $(BUILD_DIR) || exit 1
- @sleep 2
+ @sleep 1
run: $(BUILD_DIR)/$(OS_ISO)
@qemu-system-i386 -cdrom $(BUILD_DIR)/$(OS_ISO) $(QEMU_OPTIONS)