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