Annotation of dmsdos/src/dblspace_fileops.c-2.3.99, revision 1.1

1.1     ! root        1: /*
        !             2: dblspace_fileops.c-2.1.80
        !             3: 
        !             4: DMSDOS CVF-FAT module: file operation routines (for kernel>=2.1.80).
        !             5: 
        !             6: ******************************************************************************
        !             7: DMSDOS (compressed MSDOS filesystem support) for Linux
        !             8: written 1995-1998 by Frank Gockel and Pavel Pisa
        !             9: 
        !            10:     (C) Copyright 1995-1998 by Frank Gockel
        !            11:     (C) Copyright 1996-1998 by Pavel Pisa
        !            12: 
        !            13: Some code of dmsdos has been copied from the msdos filesystem
        !            14: so there are the following additional copyrights:
        !            15: 
        !            16:     (C) Copyright 1992,1993 by Werner Almesberger (msdos filesystem)
        !            17:     (C) Copyright 1994,1995 by Jacques Gelinas (mmap code)
        !            18:     (C) Copyright 1992-1995 by Linus Torvalds
        !            19: 
        !            20: DMSDOS was inspired by the THS filesystem (a simple doublespace
        !            21: DS-0-2 compressed read-only filesystem) written 1994 by Thomas Scheuermann.
        !            22: 
        !            23: The DMSDOS code is distributed under the Gnu General Public Licence.
        !            24: See file COPYING for details.
        !            25: ******************************************************************************
        !            26: 
        !            27: */
        !            28: 
        !            29: #include <linux/sched.h>
        !            30: #include <linux/ctype.h>
        !            31: #include <linux/major.h>
        !            32: #include <linux/blkdev.h>
        !            33: #include <linux/fs.h>
        !            34: #include <linux/stat.h>
        !            35: #include <linux/locks.h>
        !            36: #include <asm/segment.h>
        !            37: #include <linux/mm.h>
        !            38: #include <linux/malloc.h>
        !            39: #include <linux/string.h>
        !            40: #include <linux/msdos_fs.h>
        !            41: #include <linux/errno.h>
        !            42: #include <linux/kernel.h>
        !            43: #include <linux/shm.h>
        !            44: #include <linux/mman.h>
        !            45: #include <asm/system.h>
        !            46: #include "dmsdos.h"
        !            47: 
        !            48: extern unsigned long dmsdos_speedup;
        !            49: 
        !            50: #define MIN(x,y) (   ( (x)<(y) ) ? (x) : (y)   )
        !            51: 
        !            52: void do_cluster_reada(struct super_block*sb,int clusternr)
        !            53: { /* read one cluster ahead without waiting for the data */
        !            54:   int nextclust;
        !            55: 
        !            56:   nextclust=dbl_fat_nextcluster(sb,clusternr,NULL);
        !            57:   if(nextclust>0)
        !            58:   { /* no need to read-ahead if it is in cache */
        !            59:     /* for a simple search for existence we needn't lock the cache */
        !            60:     if(find_in_ccache(sb,nextclust,NULL,NULL)==NULL)
        !            61:                           dmsdos_read_cluster(sb,NULL,nextclust);
        !            62:   }
        !            63: }
        !            64: 
        !            65: int dblspace_file_read(
        !            66:         struct file *filp,
        !            67:         char *buf,
        !            68:         size_t count,
        !            69:         loff_t *ppos)
        !            70: {      
        !            71:         int clusternr;
        !            72:         /*unsigned char*clusterd;*/
        !            73:         int offset;
        !            74:         int bytes_read;
        !            75:         int membytes;
        !            76:         int membytes_bits;
        !            77:         int ret;
        !            78:         char * b;
        !            79:         int toread;
        !            80:         Cluster_head*ch;
        !            81:         struct inode *inode;
        !            82:         struct super_block*sb;
        !            83:         Dblsb*dblsb;
        !            84: 
        !            85:         LOG_FS("DMSDOS: file_read start...\n");
        !            86: 
        !            87:         inode = filp->f_dentry->d_inode;
        !            88:         LOG_FS("DMSDOS: file_read: got inode\n");
        !            89:         sb=inode->i_sb;
        !            90:         LOG_FS("DMSDOS: file_read: got sb\n");
        !            91:         dblsb=MSDOS_SB(sb)->private_data;
        !            92:         LOG_FS("DMSDOS: file_read: got dblsb\n");
        !            93:         
        !            94:        if (!inode) {
        !            95:                printk(KERN_ERR "DMSDOS: file_read: inode = NULL, rejected.\n");
        !            96:                return -EINVAL;
        !            97:        }
        !            98:        /* S_ISLNK allows for UMSDOS. Should never happen for normal MSDOS */
        !            99:        if (!S_ISREG(inode->i_mode) && !S_ISLNK(inode->i_mode)) {
        !           100:                printk(KERN_ERR "DMSDOS: file_read: mode = %07o, rejected.\n",inode->i_mode);
        !           101:                return -EINVAL;
        !           102:        }
        !           103: 
        !           104:         LOG_FS("DMSDOS: file_read init complete...\n");
        !           105: 
        !           106:         if(count<=0)return 0;
        !           107:         
        !           108:         if(*ppos>=inode->i_size)return 0;
        !           109:         
        !           110:         if(*ppos+count>inode->i_size)count=inode->i_size-*ppos;
        !           111:         
        !           112:         ret=verify_area(VERIFY_WRITE, buf, count);
        !           113:         if(ret<0)return ret;
        !           114:         ret=0;
        !           115: 
        !           116:         membytes=SECTOR_SIZE*dblsb->s_sectperclust;
        !           117:         membytes_bits=SECTOR_BITS+dblsb->s_spc_bits;
        !           118:         
        !           119:         /* calculate clusternr for cluster to read */
        !           120:         offset=*ppos&(membytes-1);
        !           121:         LOG_CLUST("DMSDOS: file_read: get_cluster...\n");
        !           122:         clusternr=get_cluster(inode,*ppos>>membytes_bits);
        !           123:         if(clusternr<=0)
        !           124:         {  printk(KERN_ERR "DMSDOS: file_readx: FAT mismatches file size for ino=%ld\n",
        !           125:                    inode->i_ino);
        !           126:            return 0;        
        !           127:         }
        !           128:         
        !           129:         bytes_read=0;
        !           130:         b=buf;
        !           131:         
        !           132:         do
        !           133:         {  LOG_CLUST("DMSDOS: file_read: calling ch_read...\n");
        !           134:            ch=ch_read(sb,clusternr,0);
        !           135:            LOG_CLUST("DMSDOS: file_read: after ch_read\n");
        !           136:            ret=(ch==NULL)?-EIO:0;
        !           137:            if(ret>=0)
        !           138:            { if(count>READA_THRESHOLD&&(dmsdos_speedup&SP_USE_READ_AHEAD)!=0)
        !           139:                              do_cluster_reada(inode->i_sb,clusternr);
        !           140:              toread=(membytes-offset>count) ? count : membytes-offset;
        !           141:              /*printk("DMSDOS file_readx: memcpy_tofs(0x%08x,0x%08x,0x%08x)\n",
        !           142:                      b,clusterd+offset,toread);*/
        !           143:              memcpy_tofs(b,ch->c_data+offset,toread);
        !           144:              bytes_read+=toread;
        !           145:              *ppos+=toread;
        !           146:              count-=toread;
        !           147:              ch_free(ch);
        !           148:              if(count>0)
        !           149:              { b+=toread;
        !           150:                offset=0;
        !           151:                LOG_CLUST("DMSDOS: file_read: get_cluster...\n");
        !           152:                clusternr=get_cluster(inode,*ppos>>membytes_bits);
        !           153:                if(*ppos&(membytes-1))
        !           154:                  panic("DMSDOS: read_file bug: f_pos not cluster-aligned");
        !           155:                if(clusternr<=0)
        !           156:                { ret=-EIO;
        !           157:                  printk(KERN_ERR "DMSDOS: file_readx: FAT mismatches file size for ino=%ld\n",
        !           158:                          inode->i_ino);
        !           159:                }
        !           160:              }
        !           161:            }
        !           162:         }
        !           163:         while(count>0&&ret>=0);
        !           164:         
        !           165:         return (bytes_read==0&&ret<0)?ret:bytes_read;        
        !           166: }
        !           167: 
        !           168: int dblspace_file_write(
        !           169:         struct file *filp,
        !           170:         const char *buf,
        !           171:         size_t count,
        !           172:         loff_t *ppos)
        !           173: {
        !           174:         int cluster;
        !           175:         int ret=0;
        !           176:         unsigned int offset;
        !           177:         const unsigned char *b;
        !           178:         int canwrite;
        !           179:         int written;
        !           180:         int clustersize;
        !           181:         int clustersize_bits;
        !           182:         int uc;
        !           183:         Cluster_head*ch;
        !           184:         struct inode *inode = filp->f_dentry->d_inode;
        !           185:         struct super_block*sb=inode->i_sb;
        !           186:         Dblsb*dblsb=MSDOS_SB(sb)->private_data;
        !           187:         
        !           188:        if (!inode) {
        !           189:                printk(KERN_ERR "dmsdos_file_write: inode = NULL\n");
        !           190:                return -EINVAL;
        !           191:        }
        !           192:        /* S_ISLNK allows for UMSDOS. Should never happen for normal MSDOS */
        !           193:        if (!S_ISREG(inode->i_mode) && !S_ISLNK(inode->i_mode)) {
        !           194:                printk(KERN_ERR "dmsdos_file_write: mode = %07o\n",inode->i_mode);
        !           195:                return -EINVAL;
        !           196:        }
        !           197: /*
        !           198:  * ok, append may not work when many processes are writing at the same time
        !           199:  * but so what. That way leads to madness anyway.
        !           200:  */
        !           201:         if(sb->s_flags&MS_RDONLY)
        !           202:         { printk(KERN_ERR "DMSDOS: file_write: READ-ONLY filesystem\n");
        !           203:           return -EROFS;
        !           204:         }
        !           205:         
        !           206:         if(dblsb->s_comp==READ_ONLY)return -EPERM;
        !           207:  
        !           208:        if (filp->f_flags & O_APPEND) *ppos = inode->i_size;
        !           209:        if (count <= 0) return 0;
        !           210: 
        !           211:         ret=verify_area(VERIFY_READ, buf, count);
        !           212:         if(ret<0)return ret;
        !           213:         ret=0;
        !           214:        
        !           215:        clustersize=dblsb->s_sectperclust*SECTOR_SIZE;
        !           216:        clustersize_bits=dblsb->s_spc_bits+SECTOR_BITS;
        !           217:        
        !           218:        uc=0;
        !           219:         /* no longer working in 2.3.99...
        !           220:        if(dmsdos_speedup&SP_NO_EMD_COMPR)
        !           221:          uc=(MSDOS_I(inode)->i_binary>1)?1:0; / uncompressed forced /
        !           222:        */ 
        !           223: 
        !           224:        offset=*ppos&(clustersize-1);
        !           225:        do
        !           226:        { cluster=get_cluster(inode,*ppos>>clustersize_bits);
        !           227:          if(cluster>0)break;
        !           228:           if(dblsb->s_full==2)
        !           229:           { printk(KERN_ERR "DMSDOS: write_file: CVF full (full flag set)\n");
        !           230:             return -ENOSPC;
        !           231:           }
        !           232:           if(dblsb->s_free_sectors<MIN_FREE_SECTORS)
        !           233:           { printk(KERN_ERR "DMSDOS: write_file: CVF full (free sector count too low)\n");
        !           234:             return -ENOSPC;
        !           235:           }
        !           236:          if(fat_add_cluster(inode)<0)
        !           237:          { printk(KERN_ERR "DMSDOS: write_file: fat_add_cluster failed\n");
        !           238:            return -ENOSPC;
        !           239:          }
        !           240:        }
        !           241:        while(cluster<=0);
        !           242:        
        !           243:        LOG_CLUST("DMSDOS: file_write: beginning with cluster %d\n",
        !           244:               cluster);
        !           245: 
        !           246:         b=buf;
        !           247:         written=0;
        !           248:         
        !           249:         while(count>0)
        !           250:         {
        !           251:          if(offset>0||count<clustersize)
        !           252:          { /* cluster must be read because it will only partially overwritten */
        !           253:            LOG_CLUST("DMSDOS: write_file: reading cluster %d...\n",cluster);
        !           254:            ch=ch_read(sb,cluster,C_KEEP_LOCK);
        !           255:            if(ch==NULL)
        !           256:            { printk(KERN_ERR "DMSDOS: write_file: read_cluster failed!\n");
        !           257:              ret=-EIO;
        !           258:              break;                          
        !           259:            }
        !           260:             /*lock_ch(ch); we call with KEEP_LOCK above */
        !           261:           }
        !           262:           else 
        !           263:           { /* cluster will be fully overwritten, don't read it */
        !           264:             ch=ch_read(sb,cluster,C_KEEP_LOCK|C_NO_READ);
        !           265:             if(ch==NULL)
        !           266:             { printk(KERN_ERR "DMSDOS: write_file: ch_noread failed!\n");
        !           267:               ret=-EIO;
        !           268:               break;
        !           269:             }
        !           270:             /*lock_ch(ch); we call with KEEP_LOCK above */
        !           271:             ch->c_length= (count+offset<clustersize) ?
        !           272:                                                   count+offset : clustersize;
        !           273:          }
        !           274:          canwrite=MIN(clustersize-offset,count);
        !           275:          memcpy_fromfs(&(ch->c_data[offset]),b,canwrite);
        !           276:                     
        !           277:          /* did cluster grow ? */
        !           278:          if(canwrite+offset>ch->c_length)
        !           279:          { /*printk(KERN_ERR "DMSDOS: write_file: write beyond logical cluster end, appending.\n");
        !           280:            */
        !           281:            ch->c_length=canwrite+offset;
        !           282:          }
        !           283:          if(ch->c_length>clustersize)
        !           284:          { printk(KERN_ERR "DMSDOS: write_file: length>clustersize ??? bug !!!\n");
        !           285:            ch->c_length=clustersize; 
        !           286:          }
        !           287: 
        !           288:          /*unlock_ch(ch); no not here*/ 
        !           289: 
        !           290:          LOG_CLUST("DMSDOS: write_file: writing cluster %d...\n",cluster);
        !           291: 
        !           292:           /* ch_dirty_locked unlocks the cluster */
        !           293:          if(ch_dirty_locked(ch,0,uc)<0)
        !           294:          { printk(KERN_ERR "DMSDOS: write_file: ch_dirty failed!\n");
        !           295:            ch_free(ch);
        !           296:            ch=NULL;
        !           297:            ret=-EIO;
        !           298:            break;
        !           299:          }
        !           300:          ch_free(ch);
        !           301:          ch=NULL;
        !           302:                                                         
        !           303:          offset=0;
        !           304:          b+=canwrite;
        !           305:          *ppos+=canwrite;
        !           306:          written+=canwrite;
        !           307:          count-=canwrite;
        !           308:          
        !           309:          if(count==0)break; /* braucht keinen neuen cluster mehr*/
        !           310:          
        !           311:          /* next cluster ? */
        !           312:          cluster=get_cluster(inode,*ppos>>clustersize_bits);
        !           313:          if(cluster<=0)
        !           314:          { LOG_CLUST("DMSDOS: write_file: write_loop: allocating new cluster\n");
        !           315:             if(dblsb->s_full==2)
        !           316:             { printk(KERN_ERR "DMSDOS: write_file: CVF full (full flag set)\n");
        !           317:               ret=-ENOSPC;
        !           318:               break;
        !           319:             }
        !           320:             if(dblsb->s_free_sectors<MIN_FREE_SECTORS)
        !           321:             { printk(KERN_ERR "DMSDOS: write_file: CVF full (free sector count too low)\n");
        !           322:               ret=-ENOSPC;
        !           323:               break;
        !           324:             }
        !           325:            if(fat_add_cluster(inode)<0)
        !           326:            { printk(KERN_ERR "DMSDOS: write_file: fat_add_cluster failed\n");
        !           327:              ret=-ENOSPC;
        !           328:              break;
        !           329:            }
        !           330:            cluster=get_cluster(inode,*ppos>>clustersize_bits);
        !           331:            if(cluster<=0)
        !           332:            { printk(KERN_ERR "DMSDOS: write_file: something's wrong, cannot happen\n");
        !           333:              ret=-EIO;
        !           334:              break;
        !           335:            }
        !           336:          }
        !           337:        }
        !           338:        
        !           339:        if(*ppos>inode->i_size)
        !           340:        { inode->i_size=*ppos;
        !           341:          /*inode->i_dirt=1; .... HMMM .... */
        !           342:           mark_inode_dirty(inode);
        !           343:        }
        !           344:        
        !           345:        return (written==0)?ret:written;                
        !           346: }
        !           347: 
        !           348: 
        !           349: /* Grmpf.... partially untested code. Don't know an application that does
        !           350:    writable mmaps, but it would be needed for testing this piece of code */
        !           351:    
        !           352: /* idea: kernel does buffer reads with bmap calculated buffers - impossible
        !           353:          for dmsdos. (see kernel mmap code).
        !           354:          kernel emulates writable mmap by calling file_write when no buffers
        !           355:          are present - should work for dmsdos.
        !           356:          so we do file_read-emulated readable mmaps here though the
        !           357:          generic_mmap function is used.
        !           358: */
        !           359: 
        !           360: #ifdef DMSDOS_USE_READPAGE   
        !           361: 
        !           362: #ifdef __FOR_KERNEL_2_3_99
        !           363: #error kernels >= 2.3.99 need mmap interface
        !           364: #endif
        !           365: 
        !           366: int read_the_page(unsigned long address, unsigned long pos,
        !           367:                    struct inode*inode)
        !           368: {
        !           369:        unsigned int clear;
        !           370:        long gap;       /* distance from eof to pos */
        !           371:        
        !           372:        LOG_FS("DMSDOS: read_the_page\n");
        !           373: 
        !           374:        address &= PAGE_MASK;
        !           375: 
        !           376:        clear = 0;
        !           377:        gap = inode->i_size - pos;
        !           378:        if (gap <= 0){
        !           379:                /* mmaping beyond end of file */
        !           380:                clear = PAGE_SIZE;
        !           381:        }else{
        !           382:                int cur_read;
        !           383:                int need_read;
        !           384:                struct file filp;
        !           385:                if (gap < PAGE_SIZE){
        !           386:                        clear = PAGE_SIZE - gap;
        !           387:                }
        !           388:                filp.f_reada = 0;
        !           389:                filp.f_pos = pos;
        !           390:                need_read = PAGE_SIZE - clear;
        !           391:                {       mm_segment_t cur_fs = get_fs();
        !           392:                         filp.f_dentry=kmalloc(sizeof(struct dentry),GFP_KERNEL);
        !           393:                         if(filp.f_dentry==NULL)
        !           394:                         { printk(KERN_ERR "DMSDOS: read_the_page: no memory!\n");
        !           395:                           return -1;
        !           396:                         }
        !           397:                         filp.f_dentry->d_inode=inode;
        !           398:                        
        !           399:                        set_fs (KERNEL_DS);
        !           400:                         LOG_FS("DMSDOS: read_the_page: calling file_read...\n");  
        !           401:                        cur_read = dblspace_file_read (&filp,
        !           402:                                                       (char*)address,
        !           403:                                                       need_read,
        !           404:                                                        &(filp.f_pos));
        !           405:                        set_fs (cur_fs);
        !           406:                         kfree(filp.f_dentry);
        !           407:                }
        !           408:                if (cur_read != need_read){
        !           409:                        printk ("DMSDOS: Error while reading an mmap file %d <> %d\n"
        !           410:                                ,cur_read,need_read);
        !           411:                        return -1;
        !           412:                }
        !           413:        }
        !           414:        if (clear > 0){
        !           415:                memset ((char*)address+PAGE_SIZE-clear,0,clear);
        !           416:        }
        !           417:        return 0;
        !           418: }
        !           419: 
        !           420: #ifdef READPAGE_DENTRY
        !           421: int dblspace_readpage(struct dentry*dentry, struct page *page)
        !           422: {  unsigned long   address;
        !           423:    int             error = -1;
        !           424:    struct inode*inode=dentry->d_inode;
        !           425: #else
        !           426: int dblspace_readpage(struct inode *inode, struct page *page)
        !           427: {  unsigned long   address;
        !           428:    int             error = -1;
        !           429: #endif                
        !           430:    LOG_FS("DMSDOS: readpage %08lx\n", page_address(page));
        !           431:    
        !           432:    address = page_address(page);
        !           433:    atomic_inc(&page->count);
        !           434:    set_bit(PG_locked, &page->flags);
        !           435:                    
        !           436:    /* now read the data */
        !           437:    error=read_the_page(address,page->offset,inode);
        !           438: 
        !           439:    LOG_FS("DMSDOS: readpage: read_the_page returned %d\n",error);
        !           440: 
        !           441:    if(error==0)set_bit(PG_uptodate, &page->flags);
        !           442:                    
        !           443:    clear_bit(PG_locked, &page->flags);
        !           444:    wake_up(&page->wait);
        !           445:                                                                                        
        !           446:    free_page(address);
        !           447:    return error;
        !           448: }
        !           449: 
        !           450: #else /* from: ifdef DMSDOS_USE_READPAGE */
        !           451: 
        !           452: /* this is supposed to be obsolete stuff for older kernels... */
        !           453: 
        !           454: /* we reactivate it for 2.3.99 kernel */
        !           455: 
        !           456: /*
        !           457:  * Fill in the supplied page for mmap
        !           458:  */
        !           459: struct page* dblspace_file_mmap_nopage(
        !           460:        struct vm_area_struct * area,
        !           461:        unsigned long address,
        !           462:        int write_access)
        !           463: {
        !           464:        struct inode * inode = area->vm_file->f_dentry->d_inode;
        !           465:        struct page* page;
        !           466:        unsigned int clear;
        !           467:        int pos;
        !           468:        long gap;       /* distance from eof to pos */
        !           469:        
        !           470:        LOG_FS("DMSDOS: file_mmap_nopage\n");
        !           471:         /*page = __get_free_page(GFP_KERNEL);*/
        !           472:         page=alloc_pages(GFP_KERNEL,0);
        !           473:         if (!page)return NULL;
        !           474:         LOG_FS("DMSDOS: file_mmap_nopage: got page\n");
        !           475:                                 
        !           476:        address &= PAGE_MASK;
        !           477:        pos = address - area->vm_start + area->vm_pgoff*PAGE_SIZE;
        !           478: 
        !           479:        clear = 0;
        !           480:        gap = inode->i_size - pos;
        !           481:        if (gap <= 0){
        !           482:                /* mmaping beyond end of file */
        !           483:                clear = PAGE_SIZE;
        !           484:        }else{
        !           485:                int cur_read;
        !           486:                int need_read;
        !           487:                struct file filp;
        !           488:                if (gap < PAGE_SIZE){
        !           489:                        clear = PAGE_SIZE - gap;
        !           490:                }
        !           491:                filp.f_reada = 0;
        !           492:                filp.f_pos = pos;
        !           493:                need_read = PAGE_SIZE - clear;
        !           494:                {       mm_segment_t cur_fs = get_fs();
        !           495:                         filp.f_dentry=kmalloc(sizeof(struct dentry),GFP_KERNEL);
        !           496:                         if(filp.f_dentry==NULL)
        !           497:                         { printk(KERN_ERR "DMSDOS: file_mmap_nopage: no memory!\n");
        !           498:                           return NULL;
        !           499:                         }
        !           500:                         filp.f_dentry->d_inode=inode;
        !           501:                        
        !           502:                         set_fs (KERNEL_DS);
        !           503:                         LOG_FS("DMSDOS: file_mmap_nopage: calling file_read...\n");
        !           504:                        cur_read = dblspace_file_read(&filp,
        !           505:                                         (char*)page_address(page),
        !           506:                                        need_read,&filp.f_pos);
        !           507:                         LOG_FS("DMSDOS: file_mmap_nopage: file_read returned\n");
        !           508:                        set_fs (cur_fs);
        !           509:                         kfree(filp.f_dentry);
        !           510:                }
        !           511:                if (cur_read != need_read){
        !           512:                        printk ("DMSDOS: Error while reading an mmap file %d <> %d\n"
        !           513:                                ,cur_read,need_read);
        !           514:                }
        !           515:        }
        !           516:        if (clear > 0){
        !           517:                memset ((char*)page+PAGE_SIZE-clear,0,clear);
        !           518:        }
        !           519:         LOG_FS("DMSDOS: file_mmap_nopage: end\n");
        !           520:        return page;
        !           521: }
        !           522: 
        !           523: struct vm_operations_struct dblspace_file_mmap = {
        !           524:        NULL,                   /* open */
        !           525:        NULL,                   /* close */
        !           526:        NULL,                   /* unmap */
        !           527:        NULL,                   /* protect */
        !           528:        NULL,                   /* sync */
        !           529:        dblspace_file_mmap_nopage,      /* nopage */
        !           530:        NULL,                   /* wppage */
        !           531:        NULL,                   /* swapout */
        !           532: };
        !           533: 
        !           534: /*
        !           535:  * This is used for a general mmap of a dmsdos file
        !           536:  * Returns 0 if ok, or a negative error code if not.
        !           537:  */
        !           538: int dblspace_mmap(struct file*file,struct vm_area_struct*vma)
        !           539: {       struct inode *inode = file->f_dentry->d_inode;
        !           540:        LOG_FS("DMSDOS: mmap ino=%ld\n",inode->i_ino);
        !           541:        if (vma->vm_flags & VM_SHARED)  /* only PAGE_COW or read-only supported now */
        !           542:                return -EINVAL;
        !           543:        /*
        !           544:         if (vma->vm_offset & (inode->i_sb->s_blocksize - 1))
        !           545:                return -EINVAL;
        !           546:         */
        !           547:        if (!inode->i_sb || !S_ISREG(inode->i_mode))
        !           548:                return -EACCES;
        !           549:        if (!IS_RDONLY(inode)) {
        !           550:                inode->i_atime = CURRENT_TIME;
        !           551:                /*inode->i_dirt = 1;*/
        !           552:                 mark_inode_dirty(inode);
        !           553:        }
        !           554: 
        !           555:         vma->vm_file = file;
        !           556:        vma->vm_ops = &dblspace_file_mmap;
        !           557:        return 0;
        !           558: }
        !           559: 
        !           560: #endif /* from: else / ifdef DMSDOS_USE_READPAGE */
        !           561: 

unix.superglobalmegacorp.com

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