This source file includes following definitions.
- xiafs_file_read
 
- xiafs_file_write
 
   1 
   2 
   3 
   4 
   5 
   6 
   7 
   8 
   9 
  10 
  11 
  12 #include <asm/segment.h>
  13 #include <asm/system.h>
  14 
  15 #include <linux/sched.h>
  16 #include <linux/fs.h>
  17 #include <linux/xia_fs.h>
  18 #include <linux/kernel.h>
  19 #include <linux/errno.h>
  20 #include <linux/fcntl.h>
  21 #include <linux/stat.h>
  22 #include <linux/locks.h>
  23 
  24 #include "xiafs_mac.h"
  25 
  26 #define NBUF    32
  27 
  28 #define MIN(a,b) (((a)<(b))?(a):(b))
  29 #define MAX(a,b) (((a)>(b))?(a):(b))
  30 
  31 static int xiafs_file_read(struct inode *, struct file *, char *, int);
  32 static int xiafs_file_write(struct inode *, struct file *, char *, int);
  33 
  34 
  35 
  36 
  37 
  38 static struct file_operations xiafs_file_operations = {
  39     NULL,                       
  40     xiafs_file_read,            
  41     xiafs_file_write,           
  42     NULL,                       
  43     NULL,                       
  44     NULL,                       
  45     generic_mmap,               
  46     NULL,                       
  47     NULL,                       
  48     xiafs_sync_file             
  49 };
  50 
  51 struct inode_operations xiafs_file_inode_operations = {
  52     &xiafs_file_operations,     
  53     NULL,                       
  54     NULL,                       
  55     NULL,                       
  56     NULL,                       
  57     NULL,                       
  58     NULL,                       
  59     NULL,                       
  60     NULL,                       
  61     NULL,                       
  62     NULL,                       
  63     NULL,                       
  64     xiafs_bmap,                 
  65     xiafs_truncate,             
  66     NULL                        
  67 };
  68 
  69 static int 
  70 xiafs_file_read(struct inode * inode, struct file * filp, char * buf, int count)
     
  71 {
  72     int read, left, chars;
  73     int zone_nr, zones, f_zones, offset;
  74     int bhrequest, uptodate;
  75     struct buffer_head ** bhb, ** bhe;
  76     struct buffer_head * bhreq[NBUF];
  77     struct buffer_head * buflist[NBUF];
  78 
  79     if (!inode) {
  80         printk("XIA-FS: inode = NULL (%s %d)\n", WHERE_ERR);
  81         return -EINVAL;
  82     }
  83     if (!S_ISREG(inode->i_mode)) {
  84         printk("XIA-FS: mode != regular (%s %d)\n", WHERE_ERR);
  85         return -EINVAL;
  86     }
  87     offset = filp->f_pos;
  88     left = inode->i_size - offset;
  89     if (left > count)
  90         left = count;
  91     if (left <= 0)
  92         return 0;
  93     read = 0;
  94     zone_nr = offset >> XIAFS_ZSIZE_BITS(inode->i_sb);
  95     offset &= XIAFS_ZSIZE(inode->i_sb) -1 ;
  96     f_zones =(inode->i_size+XIAFS_ZSIZE(inode->i_sb)-1)>>XIAFS_ZSIZE_BITS(inode->i_sb);
  97     zones = (left+offset+XIAFS_ZSIZE(inode->i_sb)-1) >> XIAFS_ZSIZE_BITS(inode->i_sb);
  98     bhb = bhe = buflist;
  99     if (filp->f_reada) {
 100         if(zones < read_ahead[MAJOR(inode->i_dev)] >> (1+XIAFS_ZSHIFT(inode->i_sb)))
 101           zones = read_ahead[MAJOR(inode->i_dev)] >> (1+XIAFS_ZSHIFT(inode->i_sb));
 102         if (zone_nr + zones > f_zones)
 103             zones = f_zones - zone_nr;
 104     }
 105 
 106     
 107 
 108 
 109 
 110 
 111 
 112 
 113 
 114 
 115 
 116     do {
 117         bhrequest = 0;
 118         uptodate = 1;
 119         while (zones--) {
 120             *bhb = xiafs_getblk(inode, zone_nr++, 0);
 121             if (*bhb && !(*bhb)->b_uptodate) {
 122                 uptodate = 0;
 123                 bhreq[bhrequest++] = *bhb;
 124             }
 125 
 126             if (++bhb == &buflist[NBUF])
 127                 bhb = buflist;
 128             
 129             
 130 
 131             if (uptodate)
 132                 break;
 133             if (bhb == bhe)
 134                 break;
 135         }
 136 
 137         
 138         if (bhrequest)
 139             ll_rw_block(READ, bhrequest, bhreq);
 140 
 141         do { 
 142             if (*bhe) {
 143                 wait_on_buffer(*bhe);
 144                 if (!(*bhe)->b_uptodate) {      
 145                     brelse(*bhe);
 146                     if (++bhe == &buflist[NBUF])
 147                       bhe = buflist;
 148                     left = 0;
 149                     break;
 150                 }
 151             }
 152             if (left < XIAFS_ZSIZE(inode->i_sb) - offset)
 153                 chars = left;
 154             else
 155                 chars = XIAFS_ZSIZE(inode->i_sb) - offset;
 156             filp->f_pos += chars;
 157             left -= chars;
 158             read += chars;
 159             if (*bhe) {
 160                 memcpy_tofs(buf,offset+(*bhe)->b_data,chars);
 161                 brelse(*bhe);
 162                 buf += chars;
 163             } else {
 164                 while (chars-->0)
 165                     put_fs_byte(0,buf++);
 166             }
 167             offset = 0;
 168             if (++bhe == &buflist[NBUF])
 169                 bhe = buflist;
 170         } while (left > 0 && bhe != bhb && (!*bhe || !(*bhe)->b_lock));
 171     } while (left > 0);
 172 
 173 
 174     while (bhe != bhb) {
 175         brelse(*bhe);
 176         if (++bhe == &buflist[NBUF])
 177             bhe = buflist;
 178     };
 179     if (!read)
 180         return -EIO;
 181     filp->f_reada = 1;
 182     if (!IS_RDONLY (inode)) {
 183         inode->i_atime = CURRENT_TIME;
 184         inode->i_dirt = 1;
 185     }
 186     return read;
 187 }
 188 
 189 static int 
 190 xiafs_file_write(struct inode * inode, struct file * filp, char * buf, int count)
     
 191 {
 192     off_t pos;
 193     int written, c;
 194     struct buffer_head * bh;
 195     char * cp;
 196 
 197     if (!inode) {
 198         printk("XIA-FS: inode = NULL (%s %d)\n", WHERE_ERR);
 199         return -EINVAL;
 200     }
 201     if (!S_ISREG(inode->i_mode)) {
 202         printk("XIA-FS: mode != regular (%s %d)\n", WHERE_ERR);
 203         return -EINVAL;
 204     }
 205 
 206 
 207 
 208 
 209     if (filp->f_flags & O_APPEND)
 210         pos = inode->i_size;
 211     else
 212         pos = filp->f_pos;
 213     written = 0;
 214     while (written < count) {
 215         bh = xiafs_getblk(inode, pos >> XIAFS_ZSIZE_BITS(inode->i_sb), 1);
 216         if (!bh) {
 217             if (!written)
 218                 written = -ENOSPC;
 219             break;
 220         }
 221         c = XIAFS_ZSIZE(inode->i_sb) - (pos & (XIAFS_ZSIZE(inode->i_sb) - 1));
 222         if (c > count-written)
 223             c = count-written;
 224         if (c != XIAFS_ZSIZE(inode->i_sb) && !bh->b_uptodate) {
 225             ll_rw_block(READ, 1, &bh);
 226             wait_on_buffer(bh);
 227             if (!bh->b_uptodate) {
 228                 brelse(bh);
 229                 if (!written)
 230                     written = -EIO;
 231                 break;
 232             }
 233         }
 234         cp = (pos & (XIAFS_ZSIZE(inode->i_sb)-1)) + bh->b_data;
 235         pos += c;
 236         if (pos > inode->i_size) {
 237             inode->i_size = pos;
 238             inode->i_dirt = 1;
 239         }
 240         written += c;
 241         memcpy_fromfs(cp,buf,c);
 242         buf += c;
 243         bh->b_uptodate = 1;
 244         mark_buffer_dirty(bh, 0);
 245         brelse(bh);
 246     }
 247     inode->i_mtime = inode->i_ctime = CURRENT_TIME;
 248     filp->f_pos = pos;
 249     inode->i_dirt = 1;
 250 
 251     return written;
 252 }