|
|
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.