Now has a basic understanding of uid/gid/mode values and maintains it -

permissions are not tested, though.
Removed the STREAM_TYPE_ constants.
Now maintains a modification and creation time for all nodes.
Implemented rootfs_write_stat() completely. rootfs_read_stat() now fills
in all required values.


git-svn-id: file:///srv/svn/repos/haiku/trunk/current@8959 a95241bf-73f2-0310-859d-f6bbb57e9c96
This commit is contained in:
Axel Dörfler 2004-09-14 23:42:14 +00:00
parent f8cbad7b3e
commit a837c705f5

View File

@ -28,13 +28,9 @@
# define TRACE(x)
#endif
typedef enum {
STREAM_TYPE_DIR = S_IFDIR,
STREAM_TYPE_SYMLINK = S_IFLNK,
} stream_type;
struct rootfs_stream {
stream_type type;
mode_t type;
struct stream_dir {
struct rootfs_vnode *dir_head;
struct rootfs_cookie *jar_head;
@ -47,8 +43,12 @@ struct rootfs_stream {
struct rootfs_vnode {
struct rootfs_vnode *all_next;
vnode_id id;
char *name;
vnode_id id;
char *name;
time_t modification_time;
time_t creation_time;
uid_t uid;
gid_t gid;
struct rootfs_vnode *parent;
struct rootfs_vnode *dir_next;
struct rootfs_stream stream;
@ -109,7 +109,7 @@ rootfs_vnode_compare_func(void *_v, const void *_key)
static struct rootfs_vnode *
rootfs_create_vnode(struct rootfs *fs, const char *name, int type)
rootfs_create_vnode(struct rootfs *fs, struct rootfs_vnode *parent, const char *name, int type)
{
struct rootfs_vnode *vnode;
@ -127,6 +127,10 @@ rootfs_create_vnode(struct rootfs *fs, const char *name, int type)
vnode->id = fs->next_vnode_id++;
vnode->stream.type = type;
vnode->creation_time = vnode->modification_time = time(NULL);
vnode->uid = geteuid();
vnode->gid = parent ? parent->gid : getegid();
// inherit group from parent if possible
return vnode;
}
@ -215,7 +219,9 @@ rootfs_insert_in_dir(struct rootfs_vnode *dir, struct rootfs_vnode *v)
{
v->dir_next = dir->stream.dir.dir_head;
dir->stream.dir.dir_head = v;
return 0;
dir->modification_time = time(NULL);
return B_OK;
}
@ -235,10 +241,12 @@ rootfs_remove_from_dir(struct rootfs_vnode *dir, struct rootfs_vnode *findit)
else
dir->stream.dir.dir_head = v->dir_next;
v->dir_next = NULL;
return 0;
dir->modification_time = time(NULL);
return B_OK;
}
}
return -1;
return B_ENTRY_NOT_FOUND;
}
@ -260,9 +268,9 @@ rootfs_remove(struct rootfs *fs, struct rootfs_vnode *dir, const char *name, boo
vnode = rootfs_find_in_dir(dir, name);
if (!vnode)
status = B_ENTRY_NOT_FOUND;
else if (isDirectory && vnode->stream.type != STREAM_TYPE_DIR)
else if (isDirectory && !S_ISDIR(vnode->stream.type))
status = B_NOT_A_DIRECTORY;
else if (!isDirectory && vnode->stream.type == STREAM_TYPE_DIR)
else if (!isDirectory && S_ISDIR(vnode->stream.type))
status = B_IS_A_DIRECTORY;
else if (isDirectory && !rootfs_is_dir_empty(vnode))
status = B_DIRECTORY_NOT_EMPTY;
@ -314,7 +322,7 @@ rootfs_mount(mount_id id, const char *device, void *args, fs_volume *_fs, vnode_
}
// create the root vnode
vnode = rootfs_create_vnode(fs, ".", STREAM_TYPE_DIR);
vnode = rootfs_create_vnode(fs, NULL, ".", S_IFDIR | 0777);
if (vnode == NULL) {
err = B_NO_MEMORY;
goto err3;
@ -385,7 +393,7 @@ rootfs_lookup(fs_volume _fs, fs_vnode _dir, const char *name, vnode_id *_id, int
status_t status;
TRACE(("rootfs_lookup: entry dir %p, name '%s'\n", dir, name));
if (dir->stream.type != STREAM_TYPE_DIR)
if (!S_ISDIR(dir->stream.type))
return B_NOT_A_DIRECTORY;
mutex_lock(&fs->lock);
@ -556,7 +564,7 @@ rootfs_write(fs_volume fs, fs_vnode v, fs_cookie cookie, off_t pos, const void *
static status_t
rootfs_create_dir(fs_volume _fs, fs_vnode _dir, const char *name, int perms, vnode_id *_newID)
rootfs_create_dir(fs_volume _fs, fs_vnode _dir, const char *name, int mode, vnode_id *_newID)
{
struct rootfs *fs = _fs;
struct rootfs_vnode *dir = _dir;
@ -575,7 +583,7 @@ rootfs_create_dir(fs_volume _fs, fs_vnode _dir, const char *name, int perms, vno
}
TRACE(("rootfs_create: creating new vnode\n"));
vnode = rootfs_create_vnode(fs, name, STREAM_TYPE_DIR);
vnode = rootfs_create_vnode(fs, dir, name, S_IFDIR | (mode & S_IUMSK));
if (vnode == NULL) {
status = B_NO_MEMORY;
goto err;
@ -621,7 +629,7 @@ rootfs_open_dir(fs_volume _fs, fs_vnode _v, fs_cookie *_cookie)
TRACE(("rootfs_open: vnode %p\n", vnode));
if (vnode->stream.type != STREAM_TYPE_DIR)
if (!S_ISDIR(vnode->stream.type))
return B_BAD_VALUE;
cookie = malloc(sizeof(struct rootfs_cookie));
@ -764,7 +772,7 @@ rootfs_read_link(fs_volume _fs, fs_vnode _link, char *buffer, size_t bufferSize)
{
struct rootfs_vnode *link = _link;
if (link->stream.type != STREAM_TYPE_SYMLINK)
if (!S_ISLNK(link->stream.type))
return B_BAD_VALUE;
if (bufferSize < link->stream.symlink.length)
@ -794,7 +802,7 @@ rootfs_symlink(fs_volume _fs, fs_vnode _dir, const char *name, const char *path,
}
TRACE(("rootfs_create: creating new symlink\n"));
vnode = rootfs_create_vnode(fs, name, STREAM_TYPE_SYMLINK);
vnode = rootfs_create_vnode(fs, dir, name, S_IFLNK | (mode & S_IUMSK));
if (vnode == NULL) {
status = B_NO_MEMORY;
goto err;
@ -914,28 +922,55 @@ rootfs_read_stat(fs_volume _fs, fs_vnode _v, struct stat *stat)
struct rootfs *fs = _fs;
struct rootfs_vnode *vnode = _v;
TRACE(("rootfs_rstat: vnode %p (0x%Lx), stat %p\n", vnode, vnode->id, stat));
TRACE(("rootfs_read_stat: vnode %p (0x%Lx), stat %p\n", vnode, vnode->id, stat));
// stream exists, but we know to return size 0, since we can only hold directories
stat->st_dev = fs->id;
stat->st_ino = vnode->id;
stat->st_size = 0;
stat->st_mode = vnode->stream.type | DEFFILEMODE;
stat->st_mode = vnode->stream.type;
stat->st_nlink = 1;
stat->st_blksize = 65536;
stat->st_uid = vnode->uid;
stat->st_gid = vnode->gid;
stat->st_atime = time(NULL);
stat->st_mtime = stat->st_ctime = vnode->creation_time;
stat->st_crtime = vnode->creation_time;
return 0;
}
static status_t
rootfs_write_stat(fs_volume _fs, fs_vnode _v, const struct stat *stat, uint32 statMask)
rootfs_write_stat(fs_volume _fs, fs_vnode _vnode, const struct stat *stat, uint32 statMask)
{
#ifdef TRACE_ROOTFS
struct rootfs_vnode *v = _v;
struct rootfs *fs = _fs;
struct rootfs_vnode *vnode = _vnode;
TRACE(("rootfs_wstat: vnode %p (0x%Lx), stat %p\n", v, v->id, stat));
#endif
// cannot change anything
return EINVAL;
TRACE(("rootfs_write_stat: vnode %p (0x%Lx), stat %p\n", vnode, vnode->id, stat));
// we cannot change the size of anything
if (statMask & FS_WRITE_STAT_SIZE)
return B_BAD_VALUE;
if (statMask & FS_WRITE_STAT_MODE)
vnode->stream.type = (vnode->stream.type & ~S_IUMSK) | (stat->st_mode & S_IUMSK);
if (statMask & FS_WRITE_STAT_UID)
vnode->uid = stat->st_uid;
if (statMask & FS_WRITE_STAT_GID)
vnode->gid = stat->st_gid;
if (statMask & FS_WRITE_STAT_MTIME)
vnode->modification_time = stat->st_mtime;
if (statMask & FS_WRITE_STAT_CRTIME)
vnode->creation_time = stat->st_crtime;
notify_listener(B_STAT_CHANGED, fs->id, 0, 0, vnode->id, NULL);
return B_OK;
}