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
11 #include <linux/errno.h>
12 #include <linux/sched.h>
13 #include <linux/malloc.h>
15 #include <linux/stat.h>
16 #include <linux/affs_fs.h>
17 #include <linux/amigaffs.h>
18 #include <asm/uaccess.h>
20 #define MIN(a,b) (((a) < (b)) ? (a) : (b))
22 static int affs_readlink(struct dentry
*, char *, int);
23 static struct dentry
*affs_follow_link(struct dentry
*dentry
, struct dentry
*base
, unsigned int);
25 struct inode_operations affs_symlink_inode_operations
= {
26 NULL
, /* no file-operations */
36 affs_readlink
, /* readlink */
37 affs_follow_link
, /* follow_link */
43 NULL
, /* permission */
49 affs_readlink(struct dentry
*dentry
, char *buffer
, int buflen
)
51 struct inode
*inode
= dentry
->d_inode
;
52 struct buffer_head
*bh
;
53 struct slink_front
*lf
;
59 pr_debug("AFFS: readlink(ino=%lu,buflen=%d)\n",inode
->i_ino
,buflen
);
61 bh
= affs_bread(inode
->i_dev
,inode
->i_ino
,AFFS_I2BSIZE(inode
));
63 affs_warning(inode
->i_sb
,"follow_link","Unable to read i-node block %lu\n",
67 lf
= (struct slink_front
*)bh
->b_data
;
71 pf
= inode
->i_sb
->u
.affs_sb
.s_prefix
? inode
->i_sb
->u
.affs_sb
.s_prefix
: "/";
73 if (strchr(lf
->symname
,':')) { /* Handle assign or volume name */
74 while (i
< buflen
&& (c
= pf
[i
])) {
78 while (i
< buflen
&& (c
= lf
->symname
[j
]) != ':') {
83 put_user('/',buffer
++);
88 while (i
< buflen
&& (c
= lf
->symname
[j
])) {
89 if (c
== '/' && lc
== '/' && (i
+ 3 < buflen
)) { /* parent dir */
90 put_user('.',buffer
++);
91 put_user('.',buffer
++);
102 static struct dentry
*
103 affs_follow_link(struct dentry
*dentry
, struct dentry
*base
, unsigned int follow
)
105 struct inode
*inode
= dentry
->d_inode
;
106 struct buffer_head
*bh
;
107 struct slink_front
*lf
;
114 pr_debug("AFFS: follow_link(ino=%lu)\n",inode
->i_ino
);
116 if (!(buffer
= kmalloc(1024,GFP_KERNEL
))) {
118 return ERR_PTR(-ENOSPC
);
120 bh
= affs_bread(inode
->i_dev
,inode
->i_ino
,AFFS_I2BSIZE(inode
));
122 affs_warning(inode
->i_sb
,"follow_link","Unable to read i-node block %lu\n",
126 return ERR_PTR(-EIO
);
130 lf
= (struct slink_front
*)bh
->b_data
;
132 pf
= inode
->i_sb
->u
.affs_sb
.s_prefix
? inode
->i_sb
->u
.affs_sb
.s_prefix
: "/";
134 if (strchr(lf
->symname
,':')) { /* Handle assign or volume name */
135 while (i
< 1023 && (c
= pf
[i
]))
137 while (i
< 1023 && lf
->symname
[j
] != ':')
138 buffer
[i
++] = lf
->symname
[j
++];
144 while (i
< 1023 && (c
= lf
->symname
[j
])) {
145 if (c
== '/' && lc
== '/' && i
< 1020) { /* parent dir */
155 base
= lookup_dentry(buffer
,base
,follow
);