[PATCH] Symlinks fixed

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



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 = &current->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;
 }
 
 /*

[Index of Archives]     [Kernel]     [Linux ia64]     [DCCP]     [Linux for ARM]     [Yosemite News]     [Linux SCSI]     [Linux Hams]

  Powered by Linux