diff --git a/include/minix/ipc.h b/include/minix/ipc.h index 7fc034651..0c64dcad5 100644 --- a/include/minix/ipc.h +++ b/include/minix/ipc.h @@ -291,6 +291,20 @@ typedef struct { } mess_vfs_fs_rename; _ASSERT_MSG_SIZE(mess_vfs_fs_rename); +typedef struct { + ino_t inode; + + size_t path_len; + size_t mem_size; + cp_grant_id_t grant_path; + cp_grant_id_t grant_target; + uid_t uid; + gid_t gid; + + uint8_t data[24]; +} mess_vfs_fs_slink; +_ASSERT_MSG_SIZE(mess_vfs_fs_slink); + typedef struct { ino_t inode; time_t actime; @@ -384,6 +398,7 @@ typedef struct { mess_vfs_fs_readsuper m_vfs_fs_readsuper; mess_fs_vfs_readsuper m_fs_vfs_readsuper; mess_vfs_fs_rename m_vfs_fs_rename; + mess_vfs_fs_slink m_vfs_fs_slink; mess_vfs_fs_utime m_vfs_fs_utime; mess_vfs_utimens m_vfs_utimens; mess_vm_vfs_mmap m_vm_vfs_mmap; diff --git a/lib/libpuffs/open.c b/lib/libpuffs/open.c index 02c5a18d8..5406fe838 100644 --- a/lib/libpuffs/open.c +++ b/lib/libpuffs/open.c @@ -293,32 +293,32 @@ int fs_slink(void) struct vattr va; int len; - caller_uid = (uid_t) fs_m_in.REQ_UID; - caller_gid = (gid_t) fs_m_in.REQ_GID; + caller_uid = fs_m_in.m_vfs_fs_slink.uid; + caller_gid = fs_m_in.m_vfs_fs_slink.gid; /* Copy the link name's last component */ - len = fs_m_in.REQ_PATH_LEN; + len = fs_m_in.m_vfs_fs_slink.path_len; pcn.pcn_namelen = len - 1; if (pcn.pcn_namelen > NAME_MAX) return(ENAMETOOLONG); - if (fs_m_in.REQ_MEM_SIZE >= PATH_MAX) + if (fs_m_in.m_vfs_fs_slink.mem_size >= PATH_MAX) return(ENAMETOOLONG); - r = sys_safecopyfrom(VFS_PROC_NR, (cp_grant_id_t) fs_m_in.REQ_GRANT, + r = sys_safecopyfrom(VFS_PROC_NR, fs_m_in.m_vfs_fs_slink.grant_path, (vir_bytes) 0, (vir_bytes) pcn.pcn_name, (size_t) len); if (r != OK) return(r); NUL(pcn.pcn_name, len, sizeof(pcn.pcn_name)); /* Copy the target path (note that it's not null terminated) */ - r = sys_safecopyfrom(VFS_PROC_NR, (cp_grant_id_t) fs_m_in.REQ_GRANT3, + r = sys_safecopyfrom(VFS_PROC_NR, fs_m_in.m_vfs_fs_slink.grant_target, (vir_bytes) 0, (vir_bytes) target, - (size_t) fs_m_in.REQ_MEM_SIZE); + fs_m_in.m_vfs_fs_slink.mem_size); if (r != OK) return(r); - target[fs_m_in.REQ_MEM_SIZE] = '\0'; + target[fs_m_in.m_vfs_fs_slink.mem_size] = '\0'; - if (strlen(target) != (size_t) fs_m_in.REQ_MEM_SIZE) { + if (strlen(target) != (size_t) fs_m_in.m_vfs_fs_slink.mem_size) { /* This can happen if the user provides a buffer * with a \0 in it. This can cause a lot of trouble * when the symlink is used later. We could just use @@ -330,7 +330,7 @@ int fs_slink(void) return(ENAMETOOLONG); } - if ((pn_dir = puffs_pn_nodewalk(global_pu, 0, &fs_m_in.REQ_INODE_NR)) == NULL) + if ((pn_dir = puffs_pn_nodewalk(global_pu, 0, &fs_m_in.m_vfs_fs_slink.inode)) == NULL) return(EINVAL); memset(&pni, 0, sizeof(pni)); @@ -338,7 +338,7 @@ int fs_slink(void) memset(&va, 0, sizeof(va)); va.va_type = VLNK; - va.va_mode = (mode_t) (I_SYMBOLIC_LINK | RWX_MODES); + va.va_mode = (I_SYMBOLIC_LINK | RWX_MODES); va.va_uid = caller_uid; va.va_gid = caller_gid; va.va_atime = va.va_mtime = va.va_ctime = clock_timespec(); diff --git a/servers/ext2/open.c b/servers/ext2/open.c index 9e48894a6..a8a74f7b0 100644 --- a/servers/ext2/open.c +++ b/servers/ext2/open.c @@ -195,21 +195,21 @@ int fs_slink() char* link_target_buf = NULL; /* either sip->i_block or bp->b_data */ struct buf *bp = NULL; /* disk buffer for link */ - caller_uid = (uid_t) fs_m_in.REQ_UID; - caller_gid = (gid_t) fs_m_in.REQ_GID; + caller_uid = fs_m_in.m_vfs_fs_slink.uid; + caller_gid = fs_m_in.m_vfs_fs_slink.gid; /* Copy the link name's last component */ - len = fs_m_in.REQ_PATH_LEN; + len = fs_m_in.m_vfs_fs_slink.path_len; if (len > NAME_MAX || len > EXT2_NAME_MAX) return(ENAMETOOLONG); - r = sys_safecopyfrom(VFS_PROC_NR, (cp_grant_id_t) fs_m_in.REQ_GRANT, + r = sys_safecopyfrom(VFS_PROC_NR, fs_m_in.m_vfs_fs_slink.grant_path, (vir_bytes) 0, (vir_bytes) string, (size_t) len); if (r != OK) return(r); NUL(string, len, sizeof(string)); /* Temporarily open the dir. */ - if( (ldirp = get_inode(fs_dev, (pino_t) fs_m_in.REQ_INODE_NR)) == NULL) + if( (ldirp = get_inode(fs_dev, fs_m_in.m_vfs_fs_slink.inode)) == NULL) return(EINVAL); /* Create the inode for the symlink. */ @@ -220,21 +220,21 @@ int fs_slink() * Otherwise allocate a disk block for the contents of the symlink and * copy contents of symlink (the name pointed to) into first disk block. */ if( (r = err_code) == OK) { - if ( (fs_m_in.REQ_MEM_SIZE + 1) > sip->i_sp->s_block_size) { + if ( (fs_m_in.m_vfs_fs_slink.mem_size + 1) > sip->i_sp->s_block_size) { r = ENAMETOOLONG; - } else if ((fs_m_in.REQ_MEM_SIZE + 1) <= MAX_FAST_SYMLINK_LENGTH) { + } else if ((fs_m_in.m_vfs_fs_slink.mem_size + 1) <= MAX_FAST_SYMLINK_LENGTH) { r = sys_safecopyfrom(VFS_PROC_NR, - (cp_grant_id_t) fs_m_in.REQ_GRANT3, + fs_m_in.m_vfs_fs_slink.grant_target, (vir_bytes) 0, (vir_bytes) sip->i_block, - (vir_bytes) fs_m_in.REQ_MEM_SIZE); + (vir_bytes) fs_m_in.m_vfs_fs_slink.mem_size); sip->i_dirt = IN_DIRTY; link_target_buf = (char*) sip->i_block; } else { if ((bp = new_block(sip, (off_t) 0)) != NULL) { sys_safecopyfrom(VFS_PROC_NR, - (cp_grant_id_t) fs_m_in.REQ_GRANT3, + fs_m_in.m_vfs_fs_slink.grant_target, (vir_bytes) 0, (vir_bytes) b_data(bp), - (vir_bytes) fs_m_in.REQ_MEM_SIZE); + (vir_bytes) fs_m_in.m_vfs_fs_slink.mem_size); lmfs_markdirty(bp); link_target_buf = b_data(bp); } else { @@ -243,9 +243,9 @@ int fs_slink() } if (r == OK) { assert(link_target_buf); - link_target_buf[fs_m_in.REQ_MEM_SIZE] = '\0'; + link_target_buf[fs_m_in.m_vfs_fs_slink.mem_size] = '\0'; sip->i_size = (off_t) strlen(link_target_buf); - if (sip->i_size != fs_m_in.REQ_MEM_SIZE) { + if (sip->i_size != fs_m_in.m_vfs_fs_slink.mem_size) { /* This can happen if the user provides a buffer * with a \0 in it. This can cause a lot of trouble * when the symlink is used later. We could just use diff --git a/servers/mfs/open.c b/servers/mfs/open.c index 56b6f3069..d41eef0db 100644 --- a/servers/mfs/open.c +++ b/servers/mfs/open.c @@ -178,18 +178,18 @@ int fs_slink() char string[MFS_NAME_MAX]; /* last component of the new dir's path name */ struct buf *bp; /* disk buffer for link */ - caller_uid = (uid_t) fs_m_in.REQ_UID; - caller_gid = (gid_t) fs_m_in.REQ_GID; + caller_uid = fs_m_in.m_vfs_fs_slink.uid; + caller_gid = fs_m_in.m_vfs_fs_slink.gid; /* Copy the link name's last component */ - len = min( (unsigned) fs_m_in.REQ_PATH_LEN, sizeof(string)); - r = sys_safecopyfrom(VFS_PROC_NR, (cp_grant_id_t) fs_m_in.REQ_GRANT, + len = min( (unsigned) fs_m_in.m_vfs_fs_slink.path_len, sizeof(string)); + r = sys_safecopyfrom(VFS_PROC_NR, fs_m_in.m_vfs_fs_slink.grant_path, (vir_bytes) 0, (vir_bytes) string, (size_t) len); if (r != OK) return(r); NUL(string, len, sizeof(string)); /* Temporarily open the dir. */ - if( (ldirp = get_inode(fs_dev, (pino_t) fs_m_in.REQ_INODE_NR)) == NULL) + if( (ldirp = get_inode(fs_dev, fs_m_in.m_vfs_fs_slink.inode)) == NULL) return(EINVAL); /* Create the inode for the symlink. */ @@ -199,7 +199,7 @@ int fs_slink() /* Allocate a disk block for the contents of the symlink. * Copy contents of symlink (the name pointed to) into first disk block. */ if( (r = err_code) == OK) { - size_t namelen = (size_t) fs_m_in.REQ_MEM_SIZE; + size_t namelen = fs_m_in.m_vfs_fs_slink.mem_size; bp = new_block(sip, (off_t) 0); if (bp == NULL) r = err_code; @@ -208,7 +208,7 @@ int fs_slink() r = ENAMETOOLONG; } else { r = sys_safecopyfrom(VFS_PROC_NR, - (cp_grant_id_t) fs_m_in.REQ_GRANT3, + fs_m_in.m_vfs_fs_slink.grant_target, (vir_bytes) 0, (vir_bytes) b_data(bp), namelen); b_data(bp)[namelen] = '\0'; @@ -217,7 +217,7 @@ int fs_slink() if(bp != NULL && r == OK) { sip->i_size = (off_t) strlen(b_data(bp)); - if(sip->i_size != fs_m_in.REQ_MEM_SIZE) { + if(sip->i_size != fs_m_in.m_vfs_fs_slink.mem_size) { /* This can happen if the user provides a buffer * with a \0 in it. This can cause a lot of trouble * when the symlink is used later. We could just use diff --git a/servers/vfs/request.c b/servers/vfs/request.c index ad3777d8d..b31f5f085 100644 --- a/servers/vfs/request.c +++ b/servers/vfs/request.c @@ -1025,13 +1025,13 @@ static int req_slink_actual( /* Fill in request message */ m.m_type = REQ_SLINK; - m.REQ_INODE_NR = (pino_t) inode_nr; - m.REQ_UID = (puid_t) uid; - m.REQ_GID = (pgid_t) gid; - m.REQ_GRANT = gid_name; - m.REQ_PATH_LEN = len; - m.REQ_GRANT3 = gid_buf; - m.REQ_MEM_SIZE = path_length; + m.m_vfs_fs_slink.inode = inode_nr; + m.m_vfs_fs_slink.uid = uid; + m.m_vfs_fs_slink.gid = gid; + m.m_vfs_fs_slink.grant_path = gid_name; + m.m_vfs_fs_slink.path_len = len; + m.m_vfs_fs_slink.grant_target = gid_buf; + m.m_vfs_fs_slink.mem_size = path_length; /* Send/rec request */ r = fs_sendrec(fs_e, &m);