Linux-2.6.12-rc2

Initial git repository build. I'm not bothering with the full history,
even though we have it. We can create a separate "historical" git
archive of that later if we want to, and in the meantime it's about
3.2GB when imported into git - space that would just make the early
git days unnecessarily complicated, when we don't have a lot of good
infrastructure for it.

Let it rip!
diff --git a/fs/udf/symlink.c b/fs/udf/symlink.c
new file mode 100644
index 0000000..43f3051
--- /dev/null
+++ b/fs/udf/symlink.c
@@ -0,0 +1,123 @@
+/*
+ * symlink.c
+ *
+ * PURPOSE
+ *	Symlink handling routines for the OSTA-UDF(tm) filesystem.
+ *
+ * CONTACTS
+ *	E-mail regarding any portion of the Linux UDF file system should be
+ *	directed to the development team mailing list (run by majordomo):
+ *		linux_udf@hpesjro.fc.hp.com
+ *
+ * COPYRIGHT
+ *	This file is distributed under the terms of the GNU General Public
+ *	License (GPL). Copies of the GPL can be obtained from:
+ *		ftp://prep.ai.mit.edu/pub/gnu/GPL
+ *	Each contributing author retains all rights to their own work.
+ *
+ *  (C) 1998-2001 Ben Fennema
+ *  (C) 1999 Stelias Computing Inc 
+ *
+ * HISTORY
+ *
+ *  04/16/99 blf  Created.
+ *
+ */
+
+#include "udfdecl.h"
+#include <asm/uaccess.h>
+#include <linux/errno.h>
+#include <linux/fs.h>
+#include <linux/udf_fs.h>
+#include <linux/time.h>
+#include <linux/mm.h>
+#include <linux/stat.h>
+#include <linux/slab.h>
+#include <linux/pagemap.h>
+#include <linux/smp_lock.h>
+#include <linux/buffer_head.h>
+#include "udf_i.h"
+
+static void udf_pc_to_char(struct super_block *sb, char *from, int fromlen, char *to)
+{
+	struct pathComponent *pc;
+	int elen = 0;
+	char *p = to;
+
+	while (elen < fromlen)
+	{
+		pc = (struct pathComponent *)(from + elen);
+		switch (pc->componentType)
+		{
+			case 1:
+				if (pc->lengthComponentIdent == 0)
+				{
+					p = to;
+					*p++ = '/';
+				}
+				break;
+			case 3:
+				memcpy(p, "../", 3);
+				p += 3;
+				break;
+			case 4:
+				memcpy(p, "./", 2);
+				p += 2;
+				/* that would be . - just ignore */
+				break;
+			case 5:
+				p += udf_get_filename(sb, pc->componentIdent, p, pc->lengthComponentIdent);
+				*p++ = '/';
+				break;
+		}
+		elen += sizeof(struct pathComponent) + pc->lengthComponentIdent;
+	}
+	if (p > to+1)
+		p[-1] = '\0';
+	else
+		p[0] = '\0';
+}
+
+static int udf_symlink_filler(struct file *file, struct page *page)
+{
+	struct inode *inode = page->mapping->host;
+	struct buffer_head *bh = NULL;
+	char *symlink;
+	int err = -EIO;
+	char *p = kmap(page);
+
+	lock_kernel();
+	if (UDF_I_ALLOCTYPE(inode) == ICBTAG_FLAG_AD_IN_ICB)
+		symlink = UDF_I_DATA(inode) + UDF_I_LENEATTR(inode);
+	else
+	{
+		bh = sb_bread(inode->i_sb, udf_block_map(inode, 0));
+
+		if (!bh)
+			goto out;
+
+		symlink = bh->b_data;
+	}
+
+	udf_pc_to_char(inode->i_sb, symlink, inode->i_size, p);
+	udf_release_data(bh);
+
+	unlock_kernel();
+	SetPageUptodate(page);
+	kunmap(page);
+	unlock_page(page);
+	return 0;
+out:
+	unlock_kernel();
+	SetPageError(page);
+	kunmap(page);
+	unlock_page(page);
+	return err;
+}
+
+/*
+ * symlinks can't do much...
+ */
+struct address_space_operations udf_symlink_aops = {
+	.readpage		= udf_symlink_filler,
+};