Import 2.3.32
[davej-history.git] / fs / affs / symlink.c
blob6aad1c2222f1effe4531269d48ecec66ca5b3ca3
1 /*
2 * linux/fs/affs/symlink.c
4 * 1995 Hans-Joachim Widmaier - Modified for affs.
6 * Copyright (C) 1991, 1992 Linus Torvalds
8 * affs symlink handling code
9 */
11 #include <linux/errno.h>
12 #include <linux/fs.h>
13 #include <linux/stat.h>
14 #include <linux/affs_fs.h>
15 #include <linux/amigaffs.h>
16 #include <linux/pagemap.h>
18 static int affs_symlink_readpage(struct dentry *dentry, struct page *page)
20 struct buffer_head *bh;
21 struct inode *inode = dentry->d_inode;
22 char *link = (char*)kmap(page);
23 struct slink_front *lf;
24 int err;
25 int i, j;
26 char c;
27 char lc;
28 char *pf;
30 pr_debug("AFFS: follow_link(ino=%lu)\n",inode->i_ino);
32 err = -EIO;
33 bh = affs_bread(inode->i_dev,inode->i_ino,AFFS_I2BSIZE(inode));
34 if (!bh)
35 goto fail;
36 i = 0;
37 j = 0;
38 lf = (struct slink_front *)bh->b_data;
39 lc = 0;
40 pf = inode->i_sb->u.affs_sb.s_prefix ? inode->i_sb->u.affs_sb.s_prefix : "/";
42 if (strchr(lf->symname,':')) { /* Handle assign or volume name */
43 while (i < 1023 && (c = pf[i]))
44 link[i++] = c;
45 while (i < 1023 && lf->symname[j] != ':')
46 link[i++] = lf->symname[j++];
47 if (i < 1023)
48 link[i++] = '/';
49 j++;
50 lc = '/';
52 while (i < 1023 && (c = lf->symname[j])) {
53 if (c == '/' && lc == '/' && i < 1020) { /* parent dir */
54 link[i++] = '.';
55 link[i++] = '.';
57 link[i++] = c;
58 lc = c;
59 j++;
61 link[i] = '\0';
62 affs_brelse(bh);
63 SetPageUptodate(page);
64 kunmap(page);
65 UnlockPage(page);
66 return 0;
67 fail:
68 SetPageError(page);
69 kunmap(page);
70 UnlockPage(page);
71 return err;
74 struct inode_operations affs_symlink_inode_operations = {
75 readlink: page_readlink,
76 follow_link: page_follow_link,
77 readpage: affs_symlink_readpage,