root/fs/ncpfs/file.c

/* [previous][next][first][last][top][bottom][index][help] */

DEFINITIONS

This source file includes following definitions.
  1. min
  2. ncp_fsync
  3. ncp_make_open
  4. ncp_file_read
  5. ncp_file_write

   1 /*
   2  *  file.c
   3  *
   4  *  Copyright (C) 1995 by Paal-Kr. Engstad and Volker Lendecke
   5  *
   6  */
   7 
   8 #include <asm/segment.h>
   9 #include <asm/system.h>
  10 
  11 #include <linux/sched.h>
  12 #include <linux/kernel.h>
  13 #include <linux/errno.h>
  14 #include <linux/fcntl.h>
  15 #include <linux/stat.h>
  16 #include <linux/mm.h>
  17 #include <linux/ncp_fs.h>
  18 #include "ncplib_kernel.h"
  19 #include <linux/malloc.h>
  20 
  21 static inline int min(int a, int b)
     /* [previous][next][first][last][top][bottom][index][help] */
  22 {
  23         return a<b ? a : b;
  24 }
  25 
  26 static int 
  27 ncp_fsync(struct inode *inode, struct file *file)
     /* [previous][next][first][last][top][bottom][index][help] */
  28 {
  29         return 0;
  30 }
  31 
  32 int
  33 ncp_make_open(struct inode *i, int right)
     /* [previous][next][first][last][top][bottom][index][help] */
  34 {
  35         struct nw_file_info *finfo;
  36 
  37         if (i == NULL)
  38         {
  39                 printk("ncp_make_open: got NULL inode\n");
  40                 return -EINVAL;
  41         }
  42 
  43         finfo = NCP_FINFO(i);
  44 
  45         DPRINTK("ncp_make_open: dirent->opened = %d\n", finfo->opened);
  46 
  47         if (finfo->opened == 0)
  48         {
  49                 /* tries max. rights */
  50                 if (ncp_open_create_file_or_subdir(NCP_SERVER(i),
  51                                                    NULL, NULL,
  52                                                    OC_MODE_OPEN, 0,
  53                                                    AR_READ | AR_WRITE,
  54                                                    finfo) == 0)
  55                 {
  56                         finfo->access = O_RDWR;
  57                 }
  58                 else if (ncp_open_create_file_or_subdir(NCP_SERVER(i),
  59                                                         NULL, NULL,
  60                                                         OC_MODE_OPEN, 0,
  61                                                         AR_READ,
  62                                                         finfo) == 0)
  63                 {
  64                         finfo->access = O_RDONLY;
  65                 }
  66                 else
  67                 {
  68                         return -EACCES;
  69                 }
  70         }
  71 
  72         if (   ((right == O_RDONLY) && (   (finfo->access == O_RDONLY)
  73                                         || (finfo->access == O_RDWR)))
  74             || ((right == O_WRONLY) && (   (finfo->access == O_WRONLY)
  75                                         || (finfo->access == O_RDWR)))
  76             || ((right == O_RDWR)   && (finfo->access == O_RDWR)))
  77                 return 0;
  78 
  79         return -EACCES;
  80 }
  81 
  82 static int 
  83 ncp_file_read(struct inode *inode, struct file *file, char *buf, int count)
     /* [previous][next][first][last][top][bottom][index][help] */
  84 {
  85         int bufsize, to_read, already_read;
  86         off_t pos;
  87         int errno;
  88 
  89         DPRINTK("ncp_file_read: enter %s\n", NCP_ISTRUCT(inode)->entryName);
  90         
  91         if (inode == NULL)
  92         {
  93                 DPRINTK("ncp_file_read: inode = NULL\n");
  94                 return -EINVAL;
  95         }
  96 
  97         if (!S_ISREG(inode->i_mode))
  98         {
  99                 DPRINTK("ncp_file_read: read from non-file, mode %07o\n",
 100                         inode->i_mode);
 101                 return -EINVAL;
 102         }
 103 
 104         pos = file->f_pos;
 105 
 106         if (pos + count > inode->i_size)
 107         {
 108                 count = inode->i_size - pos;
 109         }
 110 
 111         if (count <= 0)
 112         {
 113                 return 0;
 114         }
 115 
 116         if ((errno = ncp_make_open(inode, O_RDONLY)) != 0)
 117         {
 118                 return errno;
 119         }
 120         
 121         bufsize = NCP_SERVER(inode)->buffer_size;
 122 
 123         already_read = 0;
 124 
 125         /* First read in as much as possible for each bufsize. */
 126         while (already_read < count)
 127         {
 128                 int read_this_time;
 129 
 130                 if ((pos % bufsize) != 0)
 131                 {
 132                         to_read = bufsize - (pos % bufsize);
 133                 }
 134                 else
 135                 {
 136                         to_read = bufsize;
 137                 }
 138 
 139                 to_read = min(to_read, count - already_read);
 140 
 141                 if (ncp_read(NCP_SERVER(inode), NCP_FINFO(inode)->file_handle,
 142                              pos, to_read, buf, &read_this_time) != 0)
 143                 {
 144                         return -EIO; /* This is not exact, i know.. */
 145                 }
 146 
 147                 pos += read_this_time;
 148                 buf += read_this_time;
 149                 already_read += read_this_time;
 150 
 151                 if (read_this_time < to_read)
 152                 {
 153                         break;
 154                 }
 155         }
 156 
 157         file->f_pos = pos;
 158 
 159         if (!IS_RDONLY(inode)) inode->i_atime = CURRENT_TIME;
 160         inode->i_dirt = 1;
 161 
 162         DPRINTK("ncp_file_read: exit %s\n", NCP_ISTRUCT(inode)->entryName);
 163 
 164         return already_read;
 165 }
 166 
 167 static int 
 168 ncp_file_write(struct inode *inode, struct file *file, const char *buf,
     /* [previous][next][first][last][top][bottom][index][help] */
 169                int count)
 170 {
 171         int bufsize, to_write, already_written;
 172         off_t pos;
 173         int errno;
 174                           
 175         if (inode == NULL)
 176         {
 177                 DPRINTK("ncp_file_write: inode = NULL\n");
 178                 return -EINVAL;
 179         }
 180 
 181         if (!S_ISREG(inode->i_mode))
 182         {
 183                 DPRINTK("ncp_file_write: write to non-file, mode %07o\n",
 184                        inode->i_mode);
 185                 return -EINVAL;
 186         }
 187 
 188         DPRINTK("ncp_file_write: enter %s\n", NCP_ISTRUCT(inode)->entryName);
 189 
 190         if (count <= 0)
 191         {
 192                 return 0;
 193         }
 194 
 195         if ((errno = ncp_make_open(inode, O_RDWR)) != 0)
 196         {
 197                 return errno;
 198         }
 199         
 200         pos = file->f_pos;
 201 
 202         if (file->f_flags & O_APPEND)
 203         {
 204                 pos = inode->i_size;
 205         }
 206 
 207         bufsize = NCP_SERVER(inode)->buffer_size;
 208 
 209         already_written = 0;
 210 
 211         while (already_written < count)
 212         {
 213                 int written_this_time;
 214 
 215                 if ((pos % bufsize) != 0)
 216                 {
 217                         to_write = bufsize - (pos % bufsize);
 218                 }
 219                 else
 220                 {
 221                         to_write = bufsize;
 222                 }
 223 
 224                 to_write = min(to_write, count - already_written);
 225                 if (ncp_write(NCP_SERVER(inode), NCP_FINFO(inode)->file_handle,
 226                               pos, to_write, buf, &written_this_time) != 0)
 227                 {
 228                         return -EIO;
 229                 }
 230 
 231                 pos += written_this_time;
 232                 buf += written_this_time;
 233                 already_written += written_this_time;
 234 
 235                 if (written_this_time < to_write)
 236                 {
 237                         break;
 238                 }
 239         }
 240 
 241         inode->i_mtime = inode->i_ctime = CURRENT_TIME;
 242         inode->i_dirt = 1;
 243 
 244         file->f_pos = pos;
 245 
 246         if (pos > inode->i_size)
 247         {
 248                 inode->i_size = pos;
 249         }
 250 
 251         DPRINTK("ncp_file_write: exit %s\n", NCP_ISTRUCT(inode)->entryName);
 252 
 253         return already_written;
 254 }
 255 
 256 static struct file_operations ncp_file_operations = {
 257         NULL,                   /* lseek - default */
 258         ncp_file_read,          /* read */
 259         ncp_file_write,         /* write */
 260         NULL,                   /* readdir - bad */
 261         NULL,                   /* select - default */
 262         ncp_ioctl,              /* ioctl */
 263         ncp_mmap,               /* mmap */
 264         NULL,                   /* open */
 265         NULL,                   /* release */
 266         ncp_fsync,              /* fsync */
 267 };
 268 
 269 struct inode_operations ncp_file_inode_operations = {
 270         &ncp_file_operations,   /* default file operations */
 271         NULL,                   /* create */
 272         NULL,                   /* lookup */
 273         NULL,                   /* link */
 274         NULL,                   /* unlink */
 275         NULL,                   /* symlink */
 276         NULL,                   /* mkdir */
 277         NULL,                   /* rmdir */
 278         NULL,                   /* mknod */
 279         NULL,                   /* rename */
 280         NULL,                   /* readlink */
 281         NULL,                   /* follow_link */
 282         NULL,                   /* bmap */
 283         NULL                    /* truncate */
 284 };

/* [previous][next][first][last][top][bottom][index][help] */