linux-8086.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
From: Juan Perez-Sanchez <lithoxs@gmail.com>
To: linux-8086 <linux-8086@vger.kernel.org>
Subject: [PATCH] Symlinks fixed
Date: Tue, 25 Nov 2014 18:44:10 -0600	[thread overview]
Message-ID: <CAD6VGua3LoGn__46TRcjZoV1PUbGxQW4XdU7x5ZgEdrnBNqOdg@mail.gmail.com> (raw)

[-- Attachment #1: Type: text/plain, Size: 542 bytes --]

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

[-- Attachment #2: elks-2f.patch --]
[-- Type: text/x-patch, Size: 6900 bytes --]

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

                 reply	other threads:[~2014-11-26  0:44 UTC|newest]

Thread overview: [no followups] expand[flat|nested]  mbox.gz  Atom feed

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=CAD6VGua3LoGn__46TRcjZoV1PUbGxQW4XdU7x5ZgEdrnBNqOdg@mail.gmail.com \
    --to=lithoxs@gmail.com \
    --cc=linux-8086@vger.kernel.org \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).