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