Annotation of linux/fs/ext/symlink.c, revision 1.1.1.2

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);
                     24: static struct inode * ext_follow_link(struct inode *, struct inode *);
                     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: 
                     46: static struct inode * ext_follow_link(struct inode * dir, struct inode * inode)
                     47: {
                     48:        unsigned short fs;
                     49:        struct buffer_head * bh;
                     50: 
                     51:        if (!dir) {
                     52:                dir = current->root;
                     53:                dir->i_count++;
                     54:        }
                     55:        if (!inode) {
                     56:                iput(dir);
                     57:                return NULL;
                     58:        }
                     59:        if (!S_ISLNK(inode->i_mode)) {
                     60:                iput(dir);
                     61:                return inode;
                     62:        }
                     63:        __asm__("mov %%fs,%0":"=r" (fs));
                     64:        if ((current->link_count > 5) || !inode->i_data[0] ||
1.1.1.2 ! root       65:           !(bh = bread(inode->i_dev, inode->i_data[0], BLOCK_SIZE))) {
1.1       root       66:                iput(dir);
                     67:                iput(inode);
                     68:                return NULL;
                     69:        }
                     70:        iput(inode);
                     71:        __asm__("mov %0,%%fs"::"r" ((unsigned short) 0x10));
                     72:        current->link_count++;
                     73:        inode = _namei(bh->b_data,dir,1);
                     74:        current->link_count--;
                     75:        __asm__("mov %0,%%fs"::"r" (fs));
                     76:        brelse(bh);
                     77:        return inode;
                     78: }
                     79: 
                     80: static int ext_readlink(struct inode * inode, char * buffer, int buflen)
                     81: {
                     82:        struct buffer_head * bh;
                     83:        int i;
                     84:        char c;
                     85: 
                     86:        if (!S_ISLNK(inode->i_mode)) {
                     87:                iput(inode);
                     88:                return -EINVAL;
                     89:        }
                     90:        if (buflen > 1023)
                     91:                buflen = 1023;
                     92:        if (inode->i_data[0])
1.1.1.2 ! root       93:                bh = bread(inode->i_dev, inode->i_data[0], BLOCK_SIZE);
1.1       root       94:        else
                     95:                bh = NULL;
                     96:        iput(inode);
                     97:        if (!bh)
                     98:                return 0;
                     99:        i = 0;
                    100:        while (i<buflen && (c = bh->b_data[i])) {
                    101:                i++;
                    102:                put_fs_byte(c,buffer++);
                    103:        }
                    104:        brelse(bh);
                    105:        return i;
                    106: }

unix.superglobalmegacorp.com

This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.