Annotation of linux/fs/minix/file.c, revision 1.1

1.1     ! root        1: /*
        !             2:  * linux/fs/minix/file.c
        !             3:  *
        !             4:  * minix regular file handling primitives
        !             5:  */
        !             6: 
        !             7: #include <errno.h>
        !             8: #include <fcntl.h>
        !             9: 
        !            10: #include <sys/dirent.h>
        !            11: #include <sys/stat.h>
        !            12: 
        !            13: #include <asm/segment.h>
        !            14: #include <asm/system.h>
        !            15: 
        !            16: #include <linux/sched.h>
        !            17: #include <linux/minix_fs.h>
        !            18: #include <linux/kernel.h>
        !            19: 
        !            20: #define        NBUF    16
        !            21: 
        !            22: #define MIN(a,b) (((a)<(b))?(a):(b))
        !            23: #define MAX(a,b) (((a)>(b))?(a):(b))
        !            24: 
        !            25: #include <linux/fs.h>
        !            26: #include <linux/minix_fs.h>
        !            27: 
        !            28: int minix_file_read(struct inode *, struct file *, char *, int);
        !            29: static int minix_file_write(struct inode *, struct file *, char *, int);
        !            30: 
        !            31: /*
        !            32:  * We have mostly NULL's here: the current defaults are ok for
        !            33:  * the minix filesystem.
        !            34:  */
        !            35: static struct file_operations minix_file_operations = {
        !            36:        NULL,                   /* lseek - default */
        !            37:        minix_file_read,        /* read */
        !            38:        minix_file_write,       /* write */
        !            39:        NULL,                   /* readdir - bad */
        !            40:        NULL,                   /* select - default */
        !            41:        NULL,                   /* ioctl - default */
        !            42:        NULL,                   /* no special open is needed */
        !            43:        NULL                    /* release */
        !            44: };
        !            45: 
        !            46: struct inode_operations minix_file_inode_operations = {
        !            47:        &minix_file_operations, /* default file operations */
        !            48:        NULL,                   /* create */
        !            49:        NULL,                   /* lookup */
        !            50:        NULL,                   /* link */
        !            51:        NULL,                   /* unlink */
        !            52:        NULL,                   /* symlink */
        !            53:        NULL,                   /* mkdir */
        !            54:        NULL,                   /* rmdir */
        !            55:        NULL,                   /* mknod */
        !            56:        NULL,                   /* rename */
        !            57:        NULL,                   /* readlink */
        !            58:        NULL,                   /* follow_link */
        !            59:        minix_bmap,             /* bmap */
        !            60:        minix_truncate          /* truncate */
        !            61: };
        !            62: 
        !            63: static inline void wait_on_buffer(struct buffer_head * bh)
        !            64: {
        !            65:        cli();
        !            66:        while (bh->b_lock)
        !            67:                sleep_on(&bh->b_wait);
        !            68:        sti();
        !            69: }
        !            70: 
        !            71: /*
        !            72:  * minix_file_read() is also needed by the directory read-routine,
        !            73:  * so it's not static. NOTE! reading directories directly is a bad idea,
        !            74:  * but has to be supported for now for compatability reasons with older
        !            75:  * versions.
        !            76:  */
        !            77: int minix_file_read(struct inode * inode, struct file * filp, char * buf, int count)
        !            78: {
        !            79:        int read,left,chars,nr;
        !            80:        int block, blocks, offset;
        !            81:        struct buffer_head ** bhb, ** bhe;
        !            82:        struct buffer_head * buflist[NBUF];
        !            83: 
        !            84:        if (!inode) {
        !            85:                printk("minix_file_read: inode = NULL\n");
        !            86:                return -EINVAL;
        !            87:        }
        !            88:        if (!(S_ISREG(inode->i_mode) || S_ISDIR(inode->i_mode))) {
        !            89:                printk("minix_file_read: mode = %07o\n",inode->i_mode);
        !            90:                return -EINVAL;
        !            91:        }
        !            92:        if (filp->f_pos > inode->i_size)
        !            93:                left = 0;
        !            94:        else
        !            95:                left = inode->i_size - filp->f_pos;
        !            96:        if (left > count)
        !            97:                left = count;
        !            98:        if (left <= 0)
        !            99:                return 0;
        !           100:        read = 0;
        !           101:        block = filp->f_pos >> BLOCK_SIZE_BITS;
        !           102:        offset = filp->f_pos & (BLOCK_SIZE-1);
        !           103:        blocks = (left + offset + BLOCK_SIZE - 1) / BLOCK_SIZE;
        !           104:        bhb = bhe = buflist;
        !           105:        do {
        !           106:                if (blocks) {
        !           107:                        --blocks;
        !           108:                        if (nr = minix_bmap(inode,block++)) {
        !           109:                                *bhb = getblk(inode->i_dev,nr);
        !           110:                                if (!(*bhb)->b_uptodate)
        !           111:                                        ll_rw_block(READ,*bhb);
        !           112:                        } else
        !           113:                                *bhb = NULL;
        !           114: 
        !           115:                        if (++bhb == &buflist[NBUF])
        !           116:                                bhb = buflist;
        !           117: 
        !           118:                        if (bhb != bhe)
        !           119:                                continue;
        !           120:                }
        !           121:                if (*bhe) {
        !           122:                        wait_on_buffer(*bhe);
        !           123:                        if (!(*bhe)->b_uptodate) {
        !           124:                                do {
        !           125:                                        brelse(*bhe);
        !           126:                                        if (++bhe == &buflist[NBUF])
        !           127:                                                bhe = buflist;
        !           128:                                } while (bhe != bhb);
        !           129:                                break;
        !           130:                        }
        !           131:                }
        !           132: 
        !           133:                if (left < BLOCK_SIZE - offset)
        !           134:                        chars = left;
        !           135:                else
        !           136:                        chars = BLOCK_SIZE - offset;
        !           137:                filp->f_pos += chars;
        !           138:                left -= chars;
        !           139:                read += chars;
        !           140:                if (*bhe) {
        !           141:                        memcpy_tofs(buf,offset+(*bhe)->b_data,chars);
        !           142:                        brelse(*bhe);
        !           143:                        buf += chars;
        !           144:                } else {
        !           145:                        while (chars-->0)
        !           146:                                put_fs_byte(0,buf++);
        !           147:                }
        !           148:                offset = 0;
        !           149:                if (++bhe == &buflist[NBUF])
        !           150:                        bhe = buflist;
        !           151:        } while (left > 0);
        !           152:        if (!read)
        !           153:                return -EIO;
        !           154:        inode->i_atime = CURRENT_TIME;
        !           155:        inode->i_dirt = 1;
        !           156:        return read;
        !           157: }
        !           158: 
        !           159: static int minix_file_write(struct inode * inode, struct file * filp, char * buf, int count)
        !           160: {
        !           161:        off_t pos;
        !           162:        int written,block,c;
        !           163:        struct buffer_head * bh;
        !           164:        char * p;
        !           165: 
        !           166:        if (!inode) {
        !           167:                printk("minix_file_write: inode = NULL\n");
        !           168:                return -EINVAL;
        !           169:        }
        !           170:        if (!S_ISREG(inode->i_mode)) {
        !           171:                printk("minix_file_write: mode = %07o\n",inode->i_mode);
        !           172:                return -EINVAL;
        !           173:        }
        !           174: /*
        !           175:  * ok, append may not work when many processes are writing at the same time
        !           176:  * but so what. That way leads to madness anyway.
        !           177:  */
        !           178:        if (filp->f_flags & O_APPEND)
        !           179:                pos = inode->i_size;
        !           180:        else
        !           181:                pos = filp->f_pos;
        !           182:        written = 0;
        !           183:        while (written<count) {
        !           184:                if (!(block = minix_create_block(inode,pos/BLOCK_SIZE))) {
        !           185:                        if (!written)
        !           186:                                written = -ENOSPC;
        !           187:                        break;
        !           188:                }
        !           189:                c = BLOCK_SIZE - (pos % BLOCK_SIZE);
        !           190:                if (c > count-written)
        !           191:                        c = count-written;
        !           192:                if (c == BLOCK_SIZE)
        !           193:                        bh = getblk(inode->i_dev, block);
        !           194:                else
        !           195:                        bh = bread(inode->i_dev,block);
        !           196:                if (!bh) {
        !           197:                        if (!written)
        !           198:                                written = -EIO;
        !           199:                        break;
        !           200:                }
        !           201:                p = (pos % BLOCK_SIZE) + bh->b_data;
        !           202:                pos += c;
        !           203:                if (pos > inode->i_size) {
        !           204:                        inode->i_size = pos;
        !           205:                        inode->i_dirt = 1;
        !           206:                }
        !           207:                written += c;
        !           208:                memcpy_fromfs(p,buf,c);
        !           209:                buf += c;
        !           210:                bh->b_uptodate = 1;
        !           211:                bh->b_dirt = 1;
        !           212:                brelse(bh);
        !           213:        }
        !           214:        inode->i_mtime = CURRENT_TIME;
        !           215:        if (!(filp->f_flags & O_APPEND)) {
        !           216:                filp->f_pos = pos;
        !           217:                inode->i_ctime = CURRENT_TIME;
        !           218:        }
        !           219:        inode->i_dirt = 1;
        !           220:        return written;
        !           221: }

unix.superglobalmegacorp.com

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