|
|
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: char datum;
81: int need_cluster;
82: Cluster_head*ch;
83: struct inode *inode;
84: struct super_block*sb;
85: Dblsb*dblsb;
86:
87: LOG_FS("DMSDOS: file_read start...\n");
88:
89: inode = filp->f_dentry->d_inode;
90: LOG_FS("DMSDOS: file_read: got inode\n");
91: sb=inode->i_sb;
92: LOG_FS("DMSDOS: file_read: got sb\n");
93: dblsb=MSDOS_SB(sb)->private_data;
94: LOG_FS("DMSDOS: file_read: got dblsb\n");
95:
96: if (!inode) {
97: printk(KERN_ERR "DMSDOS: file_read: inode = NULL, rejected.\n");
98: return -EINVAL;
99: }
100: /* S_ISLNK allows for UMSDOS. Should never happen for normal MSDOS */
101: if (!S_ISREG(inode->i_mode) && !S_ISLNK(inode->i_mode)) {
102: printk(KERN_ERR "DMSDOS: file_read: mode = %07o, rejected.\n",inode->i_mode);
103: return -EINVAL;
104: }
105:
106: LOG_FS("DMSDOS: file_read init complete...\n");
107:
108: if(count<=0)return 0;
109:
110: if(*ppos>=inode->i_size)return 0;
111:
112: if(*ppos+count>inode->i_size)count=inode->i_size-*ppos;
113:
114: ret=verify_area(VERIFY_WRITE, buf, count);
115: if(ret<0)return ret;
116: ret=0;
117:
118: membytes=SECTOR_SIZE*dblsb->s_sectperclust;
119: membytes_bits=SECTOR_BITS+dblsb->s_spc_bits;
120:
121: /* calculate clusternr for cluster to read */
122: offset=*ppos&(membytes-1);
123: LOG_CLUST("DMSDOS: file_read: get_cluster...\n");
124: clusternr=get_cluster(inode,*ppos>>membytes_bits);
125: if(clusternr<=0)
126: { printk(KERN_ERR "DMSDOS: file_readx: FAT mismatches file size for ino=%ld\n",
127: inode->i_ino);
128: return 0;
129: }
130:
131: bytes_read=0;
132: b=buf;
133:
134: if(MSDOS_I(inode)->i_binary==0)goto text_read;
135:
136: do
137: { LOG_CLUST("DMSDOS: file_read: calling ch_read...\n");
138: ch=ch_read(sb,clusternr,0);
139: LOG_CLUST("DMSDOS: file_read: after ch_read\n");
140: ret=(ch==NULL)?-EIO:0;
141: if(ret>=0)
142: { if(count>READA_THRESHOLD&&(dmsdos_speedup&SP_USE_READ_AHEAD)!=0)
143: do_cluster_reada(inode->i_sb,clusternr);
144: toread=(membytes-offset>count) ? count : membytes-offset;
145: /*printk("DMSDOS file_readx: memcpy_tofs(0x%08x,0x%08x,0x%08x)\n",
146: b,clusterd+offset,toread);*/
147: memcpy_tofs(b,ch->c_data+offset,toread);
148: bytes_read+=toread;
149: *ppos+=toread;
150: count-=toread;
151: ch_free(ch);
152: if(count>0)
153: { b+=toread;
154: offset=0;
155: LOG_CLUST("DMSDOS: file_read: get_cluster...\n");
156: clusternr=get_cluster(inode,*ppos>>membytes_bits);
157: if(*ppos&(membytes-1))
158: panic("DMSDOS: read_file bug: f_pos not cluster-aligned");
159: if(clusternr<=0)
160: { ret=-EIO;
161: printk(KERN_ERR "DMSDOS: file_readx: FAT mismatches file size for ino=%ld\n",
162: inode->i_ino);
163: }
164: }
165: }
166: }
167: while(count>0&&ret>=0);
168:
169: return (bytes_read==0&&ret<0)?ret:bytes_read;
170:
171: text_read:
172: /* ok, let's do it byte for byte..... */
173: bytes_read=0;
174: need_cluster=1;
175: ch=NULL;
176: while(count>0&&inode->i_size>*ppos)
177: { if(need_cluster)
178: { clusternr=get_cluster(inode,*ppos>>membytes_bits);
179: if(clusternr<=0)
180: { printk(KERN_ERR "DMSDOS: get_cluster failed (FAT problem ?)\n");
181: return -EIO;
182: }
183: ch=ch_read(sb,clusternr,0);
184: if(ch==NULL)return -EIO;
185: if(count>READA_THRESHOLD&&(dmsdos_speedup&SP_USE_READ_AHEAD)!=0)
186: do_cluster_reada(inode->i_sb,clusternr);
187: clusternr=dbl_fat_nextcluster(sb,clusternr,NULL);
188: need_cluster=0;
189: }
190:
191: datum=ch->c_data[offset++];
192:
193: ++(*ppos);
194: if(datum!=13)
195: { /*put_fs_byte(datum,&(buf[bytes_read]));*/
196: memcpy_tofs(&(buf[bytes_read]),&datum,1);
197: ++bytes_read;
198: --count;
199: }
200: if(offset==membytes)
201: { need_cluster=1;
202: ch_free(ch);
203: ch=NULL;
204: offset=0;
205: }
206: }
207:
208: if(ch)ch_free(ch);
209: return bytes_read;
210: }
211:
212: int dblspace_file_write(
213: struct file *filp,
214: const char *buf,
215: size_t count,
216: loff_t *ppos)
217: {
218: int cluster;
219: int ret=0;
220: unsigned int offset;
221: const unsigned char *b;
222: int canwrite;
223: int written;
224: int clustersize;
225: int clustersize_bits;
226: int uc;
227: int cr;
228: char datum;
229: int need_cluster;
230: Cluster_head*ch;
231: struct inode *inode = filp->f_dentry->d_inode;
232: struct super_block*sb=inode->i_sb;
233: Dblsb*dblsb=MSDOS_SB(sb)->private_data;
234:
235: if (!inode) {
236: printk(KERN_ERR "dmsdos_file_write: inode = NULL\n");
237: return -EINVAL;
238: }
239: /* S_ISLNK allows for UMSDOS. Should never happen for normal MSDOS */
240: if (!S_ISREG(inode->i_mode) && !S_ISLNK(inode->i_mode)) {
241: printk(KERN_ERR "dmsdos_file_write: mode = %07o\n",inode->i_mode);
242: return -EINVAL;
243: }
244: /*
245: * ok, append may not work when many processes are writing at the same time
246: * but so what. That way leads to madness anyway.
247: */
248: if(sb->s_flags&MS_RDONLY)
249: { printk(KERN_ERR "DMSDOS: file_write: READ-ONLY filesystem\n");
250: return -EROFS;
251: }
252:
253: if(dblsb->s_comp==READ_ONLY)return -EPERM;
254:
255: if (filp->f_flags & O_APPEND) *ppos = inode->i_size;
256: if (count <= 0) return 0;
257:
258: ret=verify_area(VERIFY_READ, buf, count);
259: if(ret<0)return ret;
260: ret=0;
261:
262: clustersize=dblsb->s_sectperclust*SECTOR_SIZE;
263: clustersize_bits=dblsb->s_spc_bits+SECTOR_BITS;
264:
265: uc=0;
266: if(dmsdos_speedup&SP_NO_EMD_COMPR)
267: uc=(MSDOS_I(inode)->i_binary>1)?1:0; /* uncompressed forced */
268:
269: offset=*ppos&(clustersize-1);
270: do
271: { cluster=get_cluster(inode,*ppos>>clustersize_bits);
272: if(cluster>0)break;
273: if(dblsb->s_full==2)
274: { printk(KERN_ERR "DMSDOS: write_file: CVF full (full flag set)\n");
275: return -ENOSPC;
276: }
277: if(dblsb->s_free_sectors<MIN_FREE_SECTORS)
278: { printk(KERN_ERR "DMSDOS: write_file: CVF full (free sector count too low)\n");
279: return -ENOSPC;
280: }
281: if(fat_add_cluster(inode)<0)
282: { printk(KERN_ERR "DMSDOS: write_file: fat_add_cluster failed\n");
283: return -ENOSPC;
284: }
285: }
286: while(cluster<=0);
287:
288: LOG_CLUST("DMSDOS: file_write: beginning with cluster %d\n",
289: cluster);
290:
291: b=buf;
292: written=0;
293:
294: if(MSDOS_I(inode)->i_binary==0)goto text_write;
295:
296: while(count>0)
297: {
298: if(offset>0||count<clustersize)
299: { /* cluster must be read because it will only partially overwritten */
300: LOG_CLUST("DMSDOS: write_file: reading cluster %d...\n",cluster);
301: ch=ch_read(sb,cluster,C_KEEP_LOCK);
302: if(ch==NULL)
303: { printk(KERN_ERR "DMSDOS: write_file: read_cluster failed!\n");
304: ret=-EIO;
305: break;
306: }
307: /*lock_ch(ch); we call with KEEP_LOCK above */
308: }
309: else
310: { /* cluster will be fully overwritten, don't read it */
311: ch=ch_read(sb,cluster,C_KEEP_LOCK|C_NO_READ);
312: if(ch==NULL)
313: { printk(KERN_ERR "DMSDOS: write_file: ch_noread failed!\n");
314: ret=-EIO;
315: break;
316: }
317: /*lock_ch(ch); we call with KEEP_LOCK above */
318: ch->c_length= (count+offset<clustersize) ?
319: count+offset : clustersize;
320: }
321: canwrite=MIN(clustersize-offset,count);
322: memcpy_fromfs(&(ch->c_data[offset]),b,canwrite);
323:
324: /* did cluster grow ? */
325: if(canwrite+offset>ch->c_length)
326: { /*printk(KERN_ERR "DMSDOS: write_file: write beyond logical cluster end, appending.\n");
327: */
328: ch->c_length=canwrite+offset;
329: }
330: if(ch->c_length>clustersize)
331: { printk(KERN_ERR "DMSDOS: write_file: length>clustersize ??? bug !!!\n");
332: ch->c_length=clustersize;
333: }
334:
335: /*unlock_ch(ch); no not here*/
336:
337: LOG_CLUST("DMSDOS: write_file: writing cluster %d...\n",cluster);
338:
339: /* ch_dirty_locked unlocks the cluster */
340: if(ch_dirty_locked(ch,0,uc)<0)
341: { printk(KERN_ERR "DMSDOS: write_file: ch_dirty failed!\n");
342: ch_free(ch);
343: ch=NULL;
344: ret=-EIO;
345: break;
346: }
347: ch_free(ch);
348: ch=NULL;
349:
350: offset=0;
351: b+=canwrite;
352: *ppos+=canwrite;
353: written+=canwrite;
354: count-=canwrite;
355:
356: if(count==0)break; /* braucht keinen neuen cluster mehr*/
357:
358: /* next cluster ? */
359: cluster=get_cluster(inode,*ppos>>clustersize_bits);
360: if(cluster<=0)
361: { LOG_CLUST("DMSDOS: write_file: write_loop: allocating new cluster\n");
362: if(dblsb->s_full==2)
363: { printk(KERN_ERR "DMSDOS: write_file: CVF full (full flag set)\n");
364: ret=-ENOSPC;
365: break;
366: }
367: if(dblsb->s_free_sectors<MIN_FREE_SECTORS)
368: { printk(KERN_ERR "DMSDOS: write_file: CVF full (free sector count too low)\n");
369: ret=-ENOSPC;
370: break;
371: }
372: if(fat_add_cluster(inode)<0)
373: { printk(KERN_ERR "DMSDOS: write_file: fat_add_cluster failed\n");
374: ret=-ENOSPC;
375: break;
376: }
377: cluster=get_cluster(inode,*ppos>>clustersize_bits);
378: if(cluster<=0)
379: { printk(KERN_ERR "DMSDOS: write_file: something's wrong, cannot happen\n");
380: ret=-EIO;
381: break;
382: }
383: }
384: }
385:
386: if(*ppos>inode->i_size)
387: { inode->i_size=*ppos;
388: /*inode->i_dirt=1; .... HMMM .... */
389: mark_inode_dirty(inode);
390: }
391:
392: return (written==0)?ret:written;
393:
394: text_write:
395: written=0;
396: need_cluster=1;
397: cr=0;
398: ch=NULL;
399: while(count>0||cr==1)
400: { if(need_cluster)
401: { LOG_CLUST("DMSDOS: text_write: need_cluster=%d\n",
402: cluster);
403: /* we cannot simply calculate here...
404: so we never know and must always read the cluster */
405: ch=ch_read(sb,cluster,C_KEEP_LOCK);
406: if(ch==NULL)
407: { printk(KERN_ERR "DMSDOS: write_file: read_cluster failed!\n");
408: ret=-EIO;
409: break;
410: }
411: /*lock_ch(ch); we call with KEEP_LOCK above */
412: need_cluster=0;
413: }
414:
415: if(cr==1)
416: { datum=10;
417: cr=0;
418: }
419: else
420: { /*datum=get_fs_byte(&(buf[written]));*/
421: memcpy_fromfs(&datum,&(buf[written]),1);
422: ++written;
423: if(datum==10)
424: { datum=13;
425: cr=1;
426: }
427: --count;
428: }
429:
430: ch->c_data[offset++]=datum;
431:
432: ++(*ppos);
433: if(offset>ch->c_length)ch->c_length=offset;
434:
435: if(offset==clustersize)
436: { /* cluster is full and must be written back */
437: /*unlock_ch(ch);*/
438: /* ch_dirty_locked unlocks the cluster *after* write */
439: if(ch_dirty_locked(ch,0,uc)<0)
440: { printk(KERN_ERR "DMSDOS: write_file: ch_dirty failed!\n");
441: ch_free(ch);
442: ch=NULL;
443: ret=-EIO;
444: break;
445: }
446: ch_free(ch);
447: ch=NULL;
448:
449: /*check whether end reached */
450: if(count==0&&cr==0)
451: { offset=0; /* tells that there's no rest */
452: break;
453: }
454: /* check whether a new cluster is needed */
455: cluster=get_cluster(inode,*ppos>>clustersize_bits);
456: if(cluster<=0)
457: {
458: if(dblsb->s_full==2)
459: { printk(KERN_ERR "DMSDOS: write_file: CVF full (full flag set)\n");
460: ret=-ENOSPC;
461: break;
462: }
463: if(dblsb->s_free_sectors<MIN_FREE_SECTORS)
464: { printk(KERN_ERR "DMSDOS: write_file: CVF full (free sector count too low)\n");
465: ret=-ENOSPC;
466: break;
467: }
468: if(fat_add_cluster(inode)<0)
469: { printk(KERN_ERR "DMSDOS: write_file: fat_add_cluster failed\n");
470: ret=-ENOSPC;
471: break;
472: }
473: cluster=get_cluster(inode,*ppos>>clustersize_bits);
474: if(cluster<=0)
475: { printk(KERN_ERR "DMSDOS: write_file: something wrong, cannot happen\n");
476: ret=-EIO;
477: break;
478: }
479: ch=ch_read(sb,cluster,C_KEEP_LOCK|C_NO_READ);
480: if(ch==NULL)
481: { printk(KERN_ERR "DMSDOS: write_file: ch_noread failed\n");
482: ret=-EIO;
483: break;
484: }
485: /*lock_ch(ch); we called with KEEP_LOCK above */
486: ch->c_length=SECTOR_SIZE;
487: }
488: else need_cluster=1;
489: offset=0;
490: }
491: }
492:
493: /* check whether there's a rest to be written */
494: if(offset)
495: { /*unlock_ch(ch);*/
496: /* ch_dirty_locked unlocks the cluster *after* write */
497: if(ch_dirty_locked(ch,0,uc)<0)
498: { printk(KERN_ERR "DMSDOS: write_file: ch_dirty failed!\n");
499: if(ret==0)ret=-EIO;
500: }
501: }
502:
503: if(ch)ch_free(ch);
504:
505: if(*ppos>inode->i_size)
506: { inode->i_size=*ppos;
507: /*inode->i_dirt=1; .... HMMM .... */
508: mark_inode_dirty(inode);
509: }
510:
511: return (written==0)?ret:written;
512: }
513:
514:
515: /* Grmpf.... partially untested code. Don't know an application that does
516: writable mmaps, but it would be needed for testing this piece of code */
517:
518: /* idea: kernel does buffer reads with bmap calculated buffers - impossible
519: for dmsdos. (see kernel mmap code).
520: kernel emulates writable mmap by calling file_write when no buffers
521: are present - should work for dmsdos.
522: so we do file_read-emulated readable mmaps here though the
523: generic_mmap function is used.
524: */
525:
526: #ifdef DMSDOS_USE_READPAGE
527: int read_the_page(unsigned long address, unsigned long pos,
528: struct inode*inode)
529: {
530: unsigned int clear;
531: long gap; /* distance from eof to pos */
532:
533: LOG_FS("DMSDOS: read_the_page\n");
534:
535: address &= PAGE_MASK;
536:
537: clear = 0;
538: gap = inode->i_size - pos;
539: if (gap <= 0){
540: /* mmaping beyond end of file */
541: clear = PAGE_SIZE;
542: }else{
543: int cur_read;
544: int need_read;
545: struct file filp;
546: if (gap < PAGE_SIZE){
547: clear = PAGE_SIZE - gap;
548: }
549: filp.f_reada = 0;
550: filp.f_pos = pos;
551: need_read = PAGE_SIZE - clear;
552: { mm_segment_t cur_fs = get_fs();
553: filp.f_dentry=kmalloc(sizeof(struct dentry),GFP_KERNEL);
554: if(filp.f_dentry==NULL)
555: { printk(KERN_ERR "DMSDOS: read_the_page: no memory!\n");
556: return -1;
557: }
558: filp.f_dentry->d_inode=inode;
559:
560: set_fs (KERNEL_DS);
561: LOG_FS("DMSDOS: read_the_page: calling file_read...\n");
562: cur_read = dblspace_file_read (&filp,
563: (char*)address,
564: need_read,
565: &(filp.f_pos));
566: set_fs (cur_fs);
567: kfree(filp.f_dentry);
568: }
569: if (cur_read != need_read){
570: printk ("DMSDOS: Error while reading an mmap file %d <> %d\n"
571: ,cur_read,need_read);
572: return -1;
573: }
574: }
575: if (clear > 0){
576: memset ((char*)address+PAGE_SIZE-clear,0,clear);
577: }
578: return 0;
579: }
580:
581: #ifdef READPAGE_DENTRY
582: int dblspace_readpage(struct dentry*dentry, struct page *page)
583: { unsigned long address;
584: int error = -1;
585: struct inode*inode=dentry->d_inode;
586: #else
587: int dblspace_readpage(struct inode *inode, struct page *page)
588: { unsigned long address;
589: int error = -1;
590: #endif
591: LOG_FS("DMSDOS: readpage %08lx\n", page_address(page));
592:
593: address = page_address(page);
594: atomic_inc(&page->count);
595: set_bit(PG_locked, &page->flags);
596:
597: /* now read the data */
598: error=read_the_page(address,page->offset,inode);
599:
600: LOG_FS("DMSDOS: readpage: read_the_page returned %d\n",error);
601:
602: if(error==0)set_bit(PG_uptodate, &page->flags);
603:
604: clear_bit(PG_locked, &page->flags);
605: wake_up(&page->wait);
606:
607: free_page(address);
608: return error;
609: }
610:
611: #else /* from: ifdef DMSDOS_USE_READPAGE */
612:
613: /* this is supposed to be obsolete stuff for older kernels... */
614:
615: #if LINUX_VERSION_CODE >= LVC(2,1,90)
616: #error kernel >=2.1.90 requires readpage interface, rerun dmsdos configuration
617: #endif
618:
619: /*
620: * Fill in the supplied page for mmap
621: */
622: static unsigned long dblspace_file_mmap_nopage(
623: struct vm_area_struct * area,
624: unsigned long address,
625: int error_code)
626: {
627: struct inode * inode = area->vm_dentry->d_inode;
628: unsigned long page;
629: unsigned int clear;
630: int pos;
631: long gap; /* distance from eof to pos */
632:
633: LOG_FS("DMSDOS: file_mmap_nopage\n");
634: page = __get_free_page(GFP_KERNEL);
635: if (!page)return page;
636: LOG_FS("DMSDOS: file_mmap_nopage: got page\n");
637:
638: address &= PAGE_MASK;
639: pos = address - area->vm_start + area->vm_offset;
640:
641: clear = 0;
642: gap = inode->i_size - pos;
643: if (gap <= 0){
644: /* mmaping beyond end of file */
645: clear = PAGE_SIZE;
646: }else{
647: int cur_read;
648: int need_read;
649: struct file filp;
650: if (gap < PAGE_SIZE){
651: clear = PAGE_SIZE - gap;
652: }
653: filp.f_reada = 0;
654: filp.f_pos = pos;
655: need_read = PAGE_SIZE - clear;
656: { mm_segment_t cur_fs = get_fs();
657: filp.f_dentry=kmalloc(sizeof(struct dentry),GFP_KERNEL);
658: if(filp.f_dentry==NULL)
659: { printk(KERN_ERR "DMSDOS: file_mmap_nopage: no memory!\n");
660: return -1;
661: }
662: filp.f_dentry->d_inode=inode;
663:
664: set_fs (KERNEL_DS);
665: LOG_FS("DMSDOS: file_mmap_nopage: calling file_read...\n");
666: cur_read = dblspace_file_read (&filp,(char*)page,
667: need_read,&filp.f_pos);
668: LOG_FS("DMSDOS: file_mmap_nopage: file_read returned\n");
669: set_fs (cur_fs);
670: kfree(filp.f_dentry);
671: }
672: if (cur_read != need_read){
673: printk ("DMSDOS: Error while reading an mmap file %d <> %d\n"
674: ,cur_read,need_read);
675: }
676: }
677: if (clear > 0){
678: memset ((char*)page+PAGE_SIZE-clear,0,clear);
679: }
680: LOG_FS("DMSDOS: file_mmap_nopage: end\n");
681: return page;
682: }
683:
684: struct vm_operations_struct dblspace_file_mmap = {
685: NULL, /* open */
686: NULL, /* close */
687: NULL, /* unmap */
688: NULL, /* protect */
689: NULL, /* sync */
690: NULL, /* advise */
691: dblspace_file_mmap_nopage, /* nopage */
692: NULL, /* wppage */
693: NULL, /* swapout */
694: NULL, /* swapin */
695: };
696:
697: /*
698: * This is used for a general mmap of a dmsdos file
699: * Returns 0 if ok, or a negative error code if not.
700: */
701: int dblspace_mmap(struct file*file,struct vm_area_struct*vma)
702: { struct inode *inode = file->f_dentry->d_inode;
703: LOG_FS("DMSDOS: mmap ino=%ld\n",inode->i_ino);
704: if (vma->vm_flags & VM_SHARED) /* only PAGE_COW or read-only supported now */
705: return -EINVAL;
706: if (vma->vm_offset & (inode->i_sb->s_blocksize - 1))
707: return -EINVAL;
708: if (!inode->i_sb || !S_ISREG(inode->i_mode))
709: return -EACCES;
710: if (!IS_RDONLY(inode)) {
711: inode->i_atime = CURRENT_TIME;
712: /*inode->i_dirt = 1;*/
713: mark_inode_dirty(inode);
714: }
715:
716: vma->vm_dentry = dget(file->f_dentry);
717: vma->vm_ops = &dblspace_file_mmap;
718: return 0;
719: }
720:
721: #endif /* from: else / ifdef DMSDOS_USE_READPAGE */
722:
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.