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

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: }

unix.superglobalmegacorp.com

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