Hi, Symlinks can´t be correctly created by ELKS. If a prebuilt filesystem with symlinks is mounted under ELKS, it is recognized by command ls, but programs cannot follow the link. The attached patch fixes both problems. In addition, also fixes the function strlen_fromfs(), which always returned zero. I also took the opportunity to rewrite some functions in fs/inode.c and fs/minix/inode.c to make them clearer and reduce code size. Code size was reduced by 128 bytes and data increased by 32 bytes. Greetings, Juan
diff -Nur elks.orig/arch/i86/mm/user.c elks/arch/i86/mm/user.c --- elks.orig/arch/i86/mm/user.c 2014-11-16 08:20:56.000000000 -0600 +++ elks/arch/i86/mm/user.c 2014-11-25 15:14:13.000000000 -0600 @@ -10,7 +10,6 @@ int verfy_area(void *p, size_t len) { - register char *ptr = p; register __ptask currentp = current; /* @@ -22,7 +21,7 @@ /* * User process boundaries */ - if ((__pptr)(ptr + len) > currentp->t_endseg) + if ((__pptr)((char *)p + len) > currentp->t_endseg) return -EFAULT; return 0; @@ -131,7 +130,7 @@ pop di pop bp ret -#endasm +#endasm #endif #if 0 @@ -168,7 +167,7 @@ cld xor al,al ! search for NULL byte mov cx,#-1 - rep + repne scasb sub di,[bp+.strlen_fromfs.saddr] ! calc len +1 dec di diff -Nur elks.orig/fs/inode.c elks/fs/inode.c --- elks.orig/fs/inode.c 2014-11-16 08:20:56.000000000 -0600 +++ elks/fs/inode.c 2014-11-25 19:15:51.000000000 -0600 @@ -415,9 +415,7 @@ #ifdef BLOAT_FS inode->i_version = ++event; #endif - inode->i_sem = 0; inode->i_ino = ++ino; - inode->i_dev = 0; nr_free_inodes--; if (nr_free_inodes < 0) { printk("VFS: get_empty_inode: bad free inode count.\n"); @@ -462,30 +460,26 @@ ino_t inr /*,int crossmntp */ ) { register struct inode *inode; - struct inode *empty = NULL; debug3("iget called(%x, %d, %d)\n", sb, inr, 0 /* crossmntp */ ); if (!sb) panic("VFS: iget with sb==NULL"); + repeat: - inode = first_inode; do { - if (inode->i_dev == sb->s_dev && inode->i_ino == inr) { - goto found_it; - } - } while((inode = inode->i_prev) != first_inode); - - if (!empty) { + inode = first_inode; + do { + if (inode->i_dev == sb->s_dev && inode->i_ino == inr) + goto found_it; + } while((inode = inode->i_prev) != first_inode); debug("iget: getting an empty inode...\n"); - empty = get_empty_inode(); - debug1("iget: got one... (%x)!\n", empty); - goto repeat; - } - inode = empty; + } while(!(inode = get_empty_inode())); + debug1("iget: got one... (%x)!\n", empty); + inode->i_sb = sb; inode->i_dev = sb->s_dev; - inode->i_ino = inr; inode->i_flags = ((unsigned short int) sb->s_flags); + inode->i_ino = inr; put_last_free(inode); debug("iget: Reading inode\n"); read_inode(inode); @@ -509,8 +503,6 @@ inode = tmp; wait_on_inode(inode); } - if (empty) - iput(empty); return_it: return inode; diff -Nur elks.orig/fs/minix/inode.c elks/fs/minix/inode.c --- elks.orig/fs/minix/inode.c 2014-11-16 08:20:56.000000000 -0600 +++ elks/fs/minix/inode.c 2014-11-25 15:56:48.000000000 -0600 @@ -26,6 +26,7 @@ static void minix_commit_super(register struct super_block *); static void minix_read_inode(register struct inode *); static struct buffer_head *minix_update_inode(register struct inode *); +extern struct inode_operations pipe_inode_operations; /* Function definitions */ @@ -293,7 +294,7 @@ #endif -/* Adapted from Linux 0.12's inode.c. _bmap() is a big function, I know +/* Adapted from Linux 0.12's inode.c. _bmap() is a big function, I know Rewritten 2001 by Alan Cox based on newer kernel code + my own plans */ @@ -400,20 +401,22 @@ void minix_set_ops(struct inode *inode) { - if (S_ISREG(inode->i_mode)) - inode->i_op = &minix_file_inode_operations; - else if (S_ISDIR(inode->i_mode)) - inode->i_op = &minix_dir_inode_operations; - else if (S_ISLNK(inode->i_mode)) - inode->i_op = &minix_symlink_inode_operations; - else if (S_ISCHR(inode->i_mode)) - inode->i_op = &chrdev_inode_operations; - else if (S_ISBLK(inode->i_mode)) - inode->i_op = &blkdev_inode_operations; -#ifdef NOT_YET - else if (S_ISFIFO(inode->i_mode)) - init_fifo(inode); -#endif + static unsigned char tabc[] = { + 0, 1, 2, 0, 3, 0, 4, 0, + 5, 0, 6, 0, 7, 0, 0, 0, + }; + static struct inode_operations *inop[] = { + NULL, /* Invalid */ + &pipe_inode_operations, /* FIFO (init_fifo(inode);) */ + &chrdev_inode_operations, + &minix_dir_inode_operations, + &blkdev_inode_operations, + &minix_file_inode_operations, + &minix_symlink_inode_operations, + NULL, /* Socket */ + }; + + inode->i_op = inop[(int)tabc[(inode->i_mode & S_IFMT) >> 12]]; } /* diff -Nur elks.orig/fs/minix/namei.c elks/fs/minix/namei.c --- elks.orig/fs/minix/namei.c 2014-11-16 08:20:56.000000000 -0600 +++ elks/fs/minix/namei.c 2014-11-25 15:48:47.000000000 -0600 @@ -598,11 +598,10 @@ int minix_symlink(struct inode *dir, char *name, size_t len, char *symname) { struct minix_dir_entry *de; - register struct inode *inode = NULL; - struct buffer_head *bh = NULL; - register struct buffer_head *name_block = NULL; + register struct inode *inode; + struct buffer_head *bh; + register struct buffer_head *name_block; int i; - char c; if (!(inode = minix_new_inode(dir))) { iput(dir); @@ -619,13 +618,13 @@ return -ENOSPC; } map_buffer(name_block); - i = 0; - while (i < 1023 && (c = *(symname++))) - name_block->b_data[i++] = c; + if((i = strlen_fromfs(symname)) > 1023) + i = 1023; + memcpy_fromfs(name_block->b_data, symname, i); name_block->b_data[i] = 0; + inode->i_size = (__u32) i; mark_buffer_dirty(name_block, 1); unmap_brelse(name_block); - inode->i_size = (__u32) i; inode->i_dirt = 1; bh = minix_find_entry(dir, name, len, &de); map_buffer(bh); diff -Nur elks.orig/fs/minix/symlink.c elks/fs/minix/symlink.c --- elks.orig/fs/minix/symlink.c 2014-11-16 08:20:56.000000000 -0600 +++ elks/fs/minix/symlink.c 2014-11-25 15:24:08.000000000 -0600 @@ -29,6 +29,7 @@ int error; struct buffer_head *bh; static int link_count = 0; + __u16 ds, *pds; *res_inode = NULL; if (!dir) { @@ -57,7 +58,11 @@ iput(inode); /* current-> */ link_count++; map_buffer(bh); + pds = ¤t->t_regs.ds; + ds = *pds; + *pds = get_ds(); error = open_namei(bh->b_data, flag, mode, res_inode, dir); + *pds = ds; /* current-> */ link_count--; unmap_brelse(bh); return error; @@ -67,7 +72,7 @@ char *buffer, int buflen) { register struct buffer_head *bh; - char c; + size_t len; { register struct inode *inodep = inode; @@ -75,8 +80,6 @@ iput(inodep); return -EINVAL; } - if (buflen > 1023) - buflen = 1023; bh = minix_bread(inodep, 0, 0); iput(inodep); } @@ -85,15 +88,13 @@ return 0; map_buffer(bh); - { - register char *pi = 0; - while (((int)pi) < buflen && (c = bh->b_data[(int)pi])) { - pi++; - put_user_char(c,buffer++); - } - unmap_brelse(bh); - return (int)pi; - } + if((len = strlen(bh->b_data) + 1) > buflen) + len = buflen; + if (len > 1023) + len = 1023; + memcpy_tofs(buffer, bh->b_data, len); + unmap_brelse(bh); + return len; } /*