2 * linux/fs/ext2/symlink.c
4 * Copyright (C) 1992, 1993, 1994 Remy Card (card@masi.ibp.fr)
5 * Laboratoire MASI - Institut Blaise Pascal
6 * Universite Pierre et Marie Curie (Paris VI)
10 * linux/fs/minix/symlink.c
12 * Copyright (C) 1991, 1992 Linus Torvalds
14 * ext2 symlink handling code
17 #include <asm/segment.h>
19 #include <linux/errno.h>
21 #include <linux/ext2_fs.h>
22 #include <linux/sched.h>
23 #include <linux/stat.h>
25 static int ext2_readlink (struct inode
*, char *, int);
26 static int ext2_follow_link (struct inode
*, struct inode
*, int, int,
30 * symlinks can't do much...
32 struct inode_operations ext2_symlink_inode_operations
= {
33 NULL
, /* no file-operations */
43 ext2_readlink
, /* readlink */
44 ext2_follow_link
, /* follow_link */
50 static int ext2_follow_link(struct inode
* dir
, struct inode
* inode
,
51 int flag
, int mode
, struct inode
** res_inode
)
54 struct buffer_head
* bh
= NULL
;
66 if (!S_ISLNK(inode
->i_mode
)) {
71 if (current
->link_count
> 5) {
76 if (inode
->i_blocks
) {
77 if (!(bh
= ext2_bread (inode
, 0, 0, &error
))) {
84 link
= (char *) inode
->u
.ext2_i
.i_data
;
85 current
->link_count
++;
86 error
= open_namei (link
, flag
, mode
, res_inode
, dir
);
87 current
->link_count
--;
94 static int ext2_readlink (struct inode
* inode
, char * buffer
, int buflen
)
96 struct buffer_head
* bh
= NULL
;
101 if (!S_ISLNK(inode
->i_mode
)) {
105 if (buflen
> inode
->i_sb
->s_blocksize
- 1)
106 buflen
= inode
->i_sb
->s_blocksize
- 1;
107 if (inode
->i_blocks
) {
108 bh
= ext2_bread (inode
, 0, 0, &err
);
116 link
= (char *) inode
->u
.ext2_i
.i_data
;
118 while (i
< buflen
&& (c
= link
[i
])) {
120 put_fs_byte (c
, buffer
++);