patch-2.1.112 linux/fs/ufs/symlink.c

Next file: linux/fs/ufs/truncate.c
Previous file: linux/fs/ufs/swab.h
Back to the patch index
Back to the overall index

diff -u --recursive --new-file v2.1.111/linux/fs/ufs/symlink.c linux/fs/ufs/symlink.c
@@ -0,0 +1,138 @@
+/*
+ *  linux/ufs/ufs/symlink.c
+ *
+ * Copyright (C) 1998
+ * Daniel Pirkl <[email protected]>
+ * Charles University, Faculty of Mathematics and Physics
+ *
+ *  from
+ *
+ *  linux/fs/ext2/symlink.c
+ *
+ * Copyright (C) 1992, 1993, 1994, 1995
+ * Remy Card ([email protected])
+ * Laboratoire MASI - Institut Blaise Pascal
+ * Universite Pierre et Marie Curie (Paris VI)
+ *
+ *  from
+ *
+ *  linux/fs/minix/symlink.c
+ *
+ *  Copyright (C) 1991, 1992  Linus Torvalds
+ *
+ *  ext2 symlink handling code
+ */
+
+#include <asm/uaccess.h>
+
+#include <linux/errno.h>
+#include <linux/fs.h>
+#include <linux/ext2_fs.h>
+#include <linux/sched.h>
+#include <linux/mm.h>
+#include <linux/stat.h>
+
+
+#undef UFS_SYMLINK_DEBUG
+
+#ifdef UFS_SYMLINK_DEBUG
+#define UFSD(x) printk("(%s, %d), %s:", __FILE__, __LINE__, __FUNCTION__); printk x;
+#else
+#define UFSD(x)
+#endif
+
+
+static struct dentry * ufs_follow_link(struct dentry * dentry,
+	struct dentry * base)
+{
+	struct inode * inode;
+	struct buffer_head * bh;
+	int error;
+	char * link;
+
+	UFSD(("ENTER\n"))
+
+	inode = dentry->d_inode;
+	bh = NULL;
+	/* slow symlink */	    
+	if (inode->i_blocks) {
+		if (!(bh = ufs_bread (inode, 0, 0, &error))) {
+			dput(base);
+			return ERR_PTR(-EIO);
+		}
+		link = bh->b_data;
+	}
+	/* fast symlink */
+	else {
+		link = (char *) inode->u.ufs_i.i_u1.i_symlink;
+	}
+	UPDATE_ATIME(inode);
+	base = lookup_dentry(link, base, 1);
+	if (bh)
+		brelse(bh);
+	UFSD(("EXIT\n"))
+	return base;
+}
+
+static int ufs_readlink (struct dentry * dentry, char * buffer, int buflen)
+{
+	struct super_block * sb;
+	struct inode * inode;
+	struct buffer_head * bh;
+	char * link;
+	int i;
+
+	UFSD(("ENTER\n"))
+
+	inode = dentry->d_inode;
+	sb = inode->i_sb;
+	bh = NULL;
+	if (buflen > sb->s_blocksize - 1)
+		buflen = sb->s_blocksize - 1;
+	/* slow symlink */
+	if (inode->i_blocks) {
+		int err;
+		bh = ufs_bread (inode, 0, 0, &err);
+		if (!bh) {
+			if(err < 0) /* indicate type of error */
+				return err;
+			return 0;
+		}
+		link = bh->b_data;
+	}
+	/* fast symlink */
+	else {
+		link = (char *) inode->u.ufs_i.i_u1.i_symlink;
+	}
+	i = 0;
+	while (i < buflen && link[i])
+		i++;
+	if (copy_to_user(buffer, link, i))
+		i = -EFAULT;
+ 	UPDATE_ATIME(inode);
+	if (bh)
+		brelse (bh);
+	UFSD(("ENTER\n"))
+	return i;
+}
+
+struct inode_operations ufs_symlink_inode_operations = {
+	NULL,			/* no file-operations */
+	NULL,			/* create */
+	NULL,			/* lookup */
+	NULL,			/* link */
+	NULL,			/* unlink */
+	NULL,			/* symlink */
+	NULL,			/* mkdir */
+	NULL,			/* rmdir */
+	NULL,			/* mknod */
+	NULL,			/* rename */
+	ufs_readlink,		/* readlink */
+	ufs_follow_link,	/* follow_link */
+	NULL,			/* readpage */
+	NULL,			/* writepage */
+	NULL,			/* bmap */
+	NULL,			/* truncate */
+	NULL,			/* permission */
+	NULL			/* smap */
+};

FUNET's LINUX-ADM group, [email protected]
TCL-scripts by Sam Shen, [email protected]