static int dev_null_poll(fs_node_t* node, int events);
static int dev_always_ready_poll(fs_node_t* node, int events);
-static const struct file_operations devfs_dir_ops = {
- .finddir = devfs_finddir_impl,
+static const struct file_operations devfs_dir_ops = {0};
+
+static const struct inode_operations devfs_dir_iops = {
+ .lookup = devfs_finddir_impl,
.readdir = devfs_readdir_impl,
};
g_dev_root.vfs.inode = 1;
g_dev_root.vfs.length = 0;
g_dev_root.vfs.f_ops = &devfs_dir_ops;
+ g_dev_root.vfs.i_ops = &devfs_dir_iops;
memset(&g_dev_null, 0, sizeof(g_dev_null));
strcpy(g_dev_null.name, "null");
static const struct file_operations overlay_dir_ops = {
.read = overlay_read_impl,
- .finddir = overlay_finddir_impl,
+};
+
+static const struct inode_operations overlay_dir_iops = {
+ .lookup = overlay_finddir_impl,
.readdir = overlay_readdir_impl,
};
if (c->vfs.flags == FS_DIRECTORY) {
c->vfs.f_ops = &overlay_dir_ops;
+ c->vfs.i_ops = &overlay_dir_iops;
} else {
c->vfs.f_ops = &overlay_file_ops;
}
// Prefer upper layer readdir; fall back to lower.
fs_node_t* src = dir->upper ? dir->upper : dir->lower;
if (!src) return 0;
+ if (src->i_ops && src->i_ops->readdir)
+ return src->i_ops->readdir(src, inout_index, buf, buf_len);
if (src->f_ops && src->f_ops->readdir)
return src->f_ops->readdir(src, inout_index, buf, buf_len);
return 0;
fs_node_t* upper_child = NULL;
fs_node_t* lower_child = NULL;
- if (dir->upper && dir->upper->f_ops && dir->upper->f_ops->finddir)
- upper_child = dir->upper->f_ops->finddir(dir->upper, name);
- if (dir->lower && dir->lower->f_ops && dir->lower->f_ops->finddir)
- lower_child = dir->lower->f_ops->finddir(dir->lower, name);
+ if (dir->upper) {
+ if (dir->upper->i_ops && dir->upper->i_ops->lookup)
+ upper_child = dir->upper->i_ops->lookup(dir->upper, name);
+ else if (dir->upper->f_ops && dir->upper->f_ops->finddir)
+ upper_child = dir->upper->f_ops->finddir(dir->upper, name);
+ }
+ if (dir->lower) {
+ if (dir->lower->i_ops && dir->lower->i_ops->lookup)
+ lower_child = dir->lower->i_ops->lookup(dir->lower, name);
+ else if (dir->lower->f_ops && dir->lower->f_ops->finddir)
+ lower_child = dir->lower->f_ops->finddir(dir->lower, name);
+ }
if (!upper_child && !lower_child) return 0;
return overlay_wrap_child(dir, name, lower_child, upper_child);
root->vfs.inode = upper_root->inode;
root->vfs.length = 0;
root->vfs.f_ops = &overlay_dir_ops;
+ root->vfs.i_ops = &overlay_dir_iops;
root->path[0] = 0;
return 0;
}
-static const struct file_operations persistfs_root_fops = {
- .finddir = persist_root_finddir,
+static const struct file_operations persistfs_root_fops = {0};
+
+static const struct inode_operations persistfs_root_iops = {
+ .lookup = persist_root_finddir,
};
static const struct file_operations persistfs_counter_fops = {
g_root.inode = 1;
g_root.length = 0;
g_root.f_ops = &persistfs_root_fops;
+ g_root.i_ops = &persistfs_root_iops;
memset(&g_counter, 0, sizeof(g_counter));
strcpy(g_counter.name, "counter");
/* --- per-PID directory --- */
-/* Forward declarations for file_operations tables used in dynamic node creation */
+/* Forward declarations for file_operations / inode_operations tables */
static const struct file_operations procfs_pid_dir_fops;
+static const struct inode_operations procfs_pid_dir_iops;
static const struct file_operations procfs_pid_status_fops;
static const struct file_operations procfs_pid_maps_fops;
g_pid_dir[slot].flags = FS_DIRECTORY;
g_pid_dir[slot].inode = pid;
g_pid_dir[slot].f_ops = &procfs_pid_dir_fops;
+ g_pid_dir[slot].i_ops = &procfs_pid_dir_iops;
return &g_pid_dir[slot];
}
/* --- file_operations tables --- */
-static const struct file_operations procfs_root_fops = {
- .finddir = proc_root_finddir,
+static const struct file_operations procfs_root_fops = {0};
+
+static const struct inode_operations procfs_root_iops = {
+ .lookup = proc_root_finddir,
.readdir = proc_root_readdir,
};
-static const struct file_operations procfs_self_fops = {
- .finddir = proc_self_finddir,
+static const struct file_operations procfs_self_fops = {0};
+
+static const struct inode_operations procfs_self_iops = {
+ .lookup = proc_self_finddir,
.readdir = proc_self_readdir,
};
.read = proc_cmdline_read,
};
-static const struct file_operations procfs_pid_dir_fops = {
- .finddir = proc_pid_finddir,
+static const struct file_operations procfs_pid_dir_fops = {0};
+
+static const struct inode_operations procfs_pid_dir_iops = {
+ .lookup = proc_pid_finddir,
.readdir = proc_pid_readdir,
};
strcpy(g_proc_root.name, "proc");
g_proc_root.flags = FS_DIRECTORY;
g_proc_root.f_ops = &procfs_root_fops;
+ g_proc_root.i_ops = &procfs_root_iops;
memset(&g_proc_self, 0, sizeof(g_proc_self));
strcpy(g_proc_self.name, "self");
g_proc_self.flags = FS_DIRECTORY;
g_proc_self.f_ops = &procfs_self_fops;
+ g_proc_self.i_ops = &procfs_self_iops;
memset(&g_proc_self_status, 0, sizeof(g_proc_self_status));
strcpy(g_proc_self_status.name, "status");
.write = tmpfs_write_impl,
};
-static const struct file_operations tmpfs_dir_ops = {
- .finddir = tmpfs_finddir_impl,
+static const struct file_operations tmpfs_dir_ops = {0};
+
+static const struct inode_operations tmpfs_dir_iops = {
+ .lookup = tmpfs_finddir_impl,
.readdir = tmpfs_readdir_impl,
};
struct tmpfs_node* nd = tmpfs_node_alloc(name, FS_DIRECTORY);
if (!nd) return NULL;
nd->vfs.f_ops = &tmpfs_dir_ops;
+ nd->vfs.i_ops = &tmpfs_dir_iops;
tmpfs_child_add(dir, nd);
return nd;
}
if (!root) return NULL;
root->vfs.f_ops = &tmpfs_dir_ops;
+ root->vfs.i_ops = &tmpfs_dir_iops;
return &root->vfs;
}