|
|
1.1 root 1: /*
2: * linux/fs/ext/symlink.c
3: *
4: * (C) 1992 Remy Card ([email protected])
5: *
6: * from
7: *
8: * linux/fs/minix/symlink.c
9: *
10: * (C) 1991 Linus Torvalds
11: *
12: * ext symlink handling code
13: */
14:
15: #include <errno.h>
16:
17: #include <asm/segment.h>
18:
19: #include <linux/sched.h>
20: #include <linux/fs.h>
21: #include <linux/ext_fs.h>
22: #include <linux/stat.h>
23:
24: static int ext_readlink(struct inode *, char *, int);
25: static struct inode * ext_follow_link(struct inode *, struct inode *);
26:
27: /*
28: * symlinks can't do much...
29: */
30: struct inode_operations ext_symlink_inode_operations = {
31: NULL, /* no file-operations */
32: NULL, /* create */
33: NULL, /* lookup */
34: NULL, /* link */
35: NULL, /* unlink */
36: NULL, /* symlink */
37: NULL, /* mkdir */
38: NULL, /* rmdir */
39: NULL, /* mknod */
40: NULL, /* rename */
41: ext_readlink, /* readlink */
42: ext_follow_link, /* follow_link */
43: NULL, /* bmap */
44: NULL /* truncate */
45: };
46:
47: static struct inode * ext_follow_link(struct inode * dir, struct inode * inode)
48: {
49: unsigned short fs;
50: struct buffer_head * bh;
51:
52: if (!dir) {
53: dir = current->root;
54: dir->i_count++;
55: }
56: if (!inode) {
57: iput(dir);
58: return NULL;
59: }
60: if (!S_ISLNK(inode->i_mode)) {
61: iput(dir);
62: return inode;
63: }
64: __asm__("mov %%fs,%0":"=r" (fs));
65: if ((current->link_count > 5) || !inode->i_data[0] ||
66: !(bh = bread(inode->i_dev, inode->i_data[0]))) {
67: iput(dir);
68: iput(inode);
69: return NULL;
70: }
71: iput(inode);
72: __asm__("mov %0,%%fs"::"r" ((unsigned short) 0x10));
73: current->link_count++;
74: inode = _namei(bh->b_data,dir,1);
75: current->link_count--;
76: __asm__("mov %0,%%fs"::"r" (fs));
77: brelse(bh);
78: return inode;
79: }
80:
81: static int ext_readlink(struct inode * inode, char * buffer, int buflen)
82: {
83: struct buffer_head * bh;
84: int i;
85: char c;
86:
87: if (!S_ISLNK(inode->i_mode)) {
88: iput(inode);
89: return -EINVAL;
90: }
91: if (buflen > 1023)
92: buflen = 1023;
93: if (inode->i_data[0])
94: bh = bread(inode->i_dev, inode->i_data[0]);
95: else
96: bh = NULL;
97: iput(inode);
98: if (!bh)
99: return 0;
100: i = 0;
101: while (i<buflen && (c = bh->b_data[i])) {
102: i++;
103: put_fs_byte(c,buffer++);
104: }
105: brelse(bh);
106: return i;
107: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.