|
|
1.1 root 1: /*
1.1.1.2 root 2: * linux/fs/minix/symlink.c
1.1 root 3: *
1.1.1.3 root 4: * Copyright (C) 1991, 1992 Linus Torvalds
1.1.1.2 root 5: *
6: * minix symlink handling code
1.1 root 7: */
8:
9: #include <asm/segment.h>
10:
1.1.1.3 root 11: #include <linux/errno.h>
1.1 root 12: #include <linux/sched.h>
13: #include <linux/fs.h>
14: #include <linux/minix_fs.h>
1.1.1.2 root 15: #include <linux/stat.h>
1.1 root 16:
17: static int minix_readlink(struct inode *, char *, int);
1.1.1.4 ! root 18: static int minix_follow_link(struct inode *, struct inode *, int, int, struct inode **);
1.1 root 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:
1.1.1.4 ! root 40: static int minix_follow_link(struct inode * dir, struct inode * inode,
! 41: int flag, int mode, struct inode ** res_inode)
1.1 root 42: {
1.1.1.4 ! root 43: int error;
1.1 root 44: unsigned short fs;
45: struct buffer_head * bh;
46:
1.1.1.4 ! root 47: *res_inode = NULL;
1.1 root 48: if (!dir) {
49: dir = current->root;
50: dir->i_count++;
51: }
52: if (!inode) {
53: iput(dir);
1.1.1.4 ! root 54: return -ENOENT;
1.1 root 55: }
56: if (!S_ISLNK(inode->i_mode)) {
57: iput(dir);
1.1.1.4 ! root 58: *res_inode = inode;
! 59: return 0;
1.1 root 60: }
1.1.1.4 ! root 61: if (current->link_count > 5) {
! 62: iput(inode);
1.1 root 63: iput(dir);
1.1.1.4 ! root 64: return -ELOOP;
! 65: }
! 66: if (!(bh = minix_bread(inode, 0, 0))) {
1.1 root 67: iput(inode);
1.1.1.4 ! root 68: iput(dir);
! 69: return -EIO;
1.1 root 70: }
71: iput(inode);
1.1.1.4 ! root 72: __asm__("mov %%fs,%0":"=r" (fs));
1.1 root 73: __asm__("mov %0,%%fs"::"r" ((unsigned short) 0x10));
74: current->link_count++;
1.1.1.4 ! root 75: error = open_namei(bh->b_data,flag,mode,res_inode,dir);
1.1 root 76: current->link_count--;
77: __asm__("mov %0,%%fs"::"r" (fs));
78: brelse(bh);
1.1.1.4 ! root 79: return error;
1.1 root 80: }
81:
82: static int minix_readlink(struct inode * inode, char * buffer, int buflen)
83: {
84: struct buffer_head * bh;
85: int i;
86: char c;
87:
88: if (!S_ISLNK(inode->i_mode)) {
89: iput(inode);
90: return -EINVAL;
91: }
92: if (buflen > 1023)
93: buflen = 1023;
1.1.1.4 ! root 94: bh = minix_bread(inode, 0, 0);
1.1 root 95: iput(inode);
96: if (!bh)
97: return 0;
98: i = 0;
99: while (i<buflen && (c = bh->b_data[i])) {
100: i++;
101: put_fs_byte(c,buffer++);
102: }
103: brelse(bh);
104: return i;
105: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.