root/fs/smbfs/file.c

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

DEFINITIONS

This source file includes following definitions.
  1. smb_fsync
  2. smb_make_open
  3. smb_file_read
  4. smb_file_write

   1 /*
   2  *  file.c
   3  *
   4  *  Copyright (C) 1995 by Paal-Kr. Engstad and Volker Lendecke
   5  *
   6  */
   7 
   8 #include <linux/module.h>
   9 
  10 #include <asm/segment.h>
  11 #include <asm/system.h>
  12 
  13 #include <linux/sched.h>
  14 #include <linux/kernel.h>
  15 #include <linux/errno.h>
  16 #include <linux/fcntl.h>
  17 #include <linux/stat.h>
  18 #include <linux/mm.h>
  19 #include <linux/smb_fs.h>
  20 #include <linux/malloc.h>
  21 
  22 static int 
  23 smb_fsync(struct inode *inode, struct file *file)
     /* [previous][next][first][last][top][bottom][index][help] */
  24 {
  25         return 0;
  26 }
  27 
  28 int
  29 smb_make_open(struct inode *i, int right)
     /* [previous][next][first][last][top][bottom][index][help] */
  30 {
  31         struct smb_dirent *dirent;
  32         int open_result;
  33 
  34         if (i == NULL) {
  35                 printk("smb_make_open: got NULL inode\n");
  36                 return -EINVAL;
  37         }
  38 
  39         dirent = &(SMB_INOP(i)->finfo);
  40 
  41         DDPRINTK("smb_make_open: dirent->opened = %d\n", dirent->opened);
  42 
  43         if ((dirent->opened) == 0) {
  44                 /* tries max. rights */
  45                 open_result = smb_proc_open(SMB_SERVER(i),
  46                                             dirent->path, dirent->len,
  47                                             dirent);
  48                 if (open_result) 
  49                         return open_result;
  50 
  51                 dirent->opened = 1;
  52         }
  53 
  54         if (   ((right == O_RDONLY) && (   (dirent->access == O_RDONLY)
  55                                         || (dirent->access == O_RDWR)))
  56             || ((right == O_WRONLY) && (   (dirent->access == O_WRONLY)
  57                                         || (dirent->access == O_RDWR)))
  58             || ((right == O_RDWR)   && (dirent->access == O_RDWR)))
  59                 return 0;
  60 
  61         return -EACCES;
  62 }
  63 
  64 static int 
  65 smb_file_read(struct inode *inode, struct file *file, char *buf, int count)
     /* [previous][next][first][last][top][bottom][index][help] */
  66 {
  67         int result, bufsize, to_read, already_read;
  68         off_t pos;
  69         int errno;
  70 
  71         DPRINTK("smb_file_read: enter %s\n", SMB_FINFO(inode)->path);
  72         
  73         if (!inode) {
  74                 DPRINTK("smb_file_read: inode = NULL\n");
  75                 return -EINVAL;
  76         }
  77 
  78         if (!S_ISREG(inode->i_mode)) {
  79                 DPRINTK("smb_file_read: read from non-file, mode %07o\n",
  80                         inode->i_mode);
  81                 return -EINVAL;
  82         }
  83 
  84         if ((errno = smb_make_open(inode, O_RDONLY)) != 0)
  85                 return errno;
  86         
  87         pos = file->f_pos;
  88 
  89         if (pos + count > inode->i_size)
  90                 count = inode->i_size - pos;
  91 
  92         if (count <= 0)
  93                 return 0;
  94         bufsize = SMB_SERVER(inode)->max_xmit - SMB_HEADER_LEN - 5 * 2 - 5;
  95 
  96         already_read = 0;
  97 
  98         /* First read in as much as possible for each bufsize. */
  99         while (already_read < count) {
 100 
 101                 result = 0;
 102                 to_read = 0;
 103                 
 104                 if ((SMB_SERVER(inode)->blkmode & 1) != 0) {
 105                         to_read = min(65535, count - already_read);
 106                         DPRINTK("smb_file_read: Raw %d bytes\n", to_read);
 107                         result = smb_proc_read_raw(SMB_SERVER(inode),
 108                                                    SMB_FINFO(inode),
 109                                                    pos, to_read, buf);
 110                         DPRINTK("smb_file_read: returned %d\n", result);
 111                 }
 112 
 113                 if (result <= 0) {
 114                         to_read = min(bufsize, count - already_read);
 115                         result = smb_proc_read(SMB_SERVER(inode),
 116                                                SMB_FINFO(inode),
 117                                                pos, to_read, buf, 1);
 118                 }
 119 
 120                 if (result < 0)
 121                         return result;
 122                 pos += result;
 123                 buf += result;
 124                 already_read += result;
 125 
 126                 if (result < to_read) {
 127                         break;
 128                 }
 129         }
 130 
 131         file->f_pos = pos;
 132 
 133         if (!IS_RDONLY(inode)) inode->i_atime = CURRENT_TIME;
 134         inode->i_dirt = 1;
 135 
 136         DPRINTK("smb_file_read: exit %s\n", SMB_FINFO(inode)->path);
 137 
 138         return already_read;
 139 }
 140 
 141 static int 
 142 smb_file_write(struct inode *inode, struct file *file, const char *buf, int count)
     /* [previous][next][first][last][top][bottom][index][help] */
 143 {
 144         int result, bufsize, to_write, already_written;
 145         off_t pos;
 146         int errno;
 147                           
 148         if (!inode) {
 149                 DPRINTK("smb_file_write: inode = NULL\n");
 150                 return -EINVAL;
 151         }
 152 
 153         if (!S_ISREG(inode->i_mode)) {
 154                 DPRINTK("smb_file_write: write to non-file, mode %07o\n",
 155                        inode->i_mode);
 156                 return -EINVAL;
 157         }
 158 
 159         DPRINTK("smb_file_write: enter %s\n", SMB_FINFO(inode)->path);
 160 
 161         if (count <= 0)
 162                 return 0;
 163 
 164         if ((errno = smb_make_open(inode, O_RDWR)) != 0)
 165                 return errno;
 166         
 167         pos = file->f_pos;
 168 
 169         if (file->f_flags & O_APPEND)
 170                 pos = inode->i_size;
 171 
 172         bufsize = SMB_SERVER(inode)->max_xmit - SMB_HEADER_LEN - 5 * 2 - 5;
 173 
 174         already_written = 0;
 175 
 176         DPRINTK("smb_write_file: blkmode = %d, blkmode & 2 = %d\n",
 177                 SMB_SERVER(inode)->blkmode,
 178                 SMB_SERVER(inode)->blkmode & 2);
 179         
 180         while (already_written < count) {
 181 
 182                 result = 0;
 183                 to_write = 0;
 184 
 185                 if ((SMB_SERVER(inode)->blkmode & 2) != 0) {
 186                         to_write = min(65535, count - already_written);
 187                         DPRINTK("smb_file_write: Raw %d bytes\n", to_write);
 188                         result = smb_proc_write_raw(SMB_SERVER(inode),
 189                                                     SMB_FINFO(inode), 
 190                                                     pos, to_write, buf);
 191                         DPRINTK("smb_file_write: returned %d\n", result);
 192                 }
 193 
 194                 if (result <= 0) {
 195                         to_write = min(bufsize, count - already_written);
 196                         result = smb_proc_write(SMB_SERVER(inode),
 197                                                 SMB_FINFO(inode), 
 198                                                 pos, to_write, buf);
 199                 }
 200 
 201                 if (result < 0)
 202                         return result;
 203 
 204                 pos += result;
 205                 buf += result;
 206                 already_written += result;
 207 
 208                 if (result < to_write) {
 209                         break;
 210                 }
 211         }
 212 
 213         inode->i_mtime = inode->i_ctime = CURRENT_TIME;
 214         inode->i_dirt = 1;
 215 
 216         file->f_pos = pos;
 217 
 218         if (pos > inode->i_size) {
 219                 inode->i_size = pos;
 220         }
 221 
 222         DPRINTK("smb_file_write: exit %s\n", SMB_FINFO(inode)->path);
 223 
 224         return already_written;
 225 }
 226 
 227 static struct file_operations smb_file_operations = {
 228         NULL,                   /* lseek - default */
 229         smb_file_read,          /* read */
 230         smb_file_write,         /* write */
 231         NULL,                   /* readdir - bad */
 232         NULL,                   /* select - default */
 233         smb_ioctl,              /* ioctl */
 234         smb_mmap,               /* mmap */
 235         NULL,                   /* open */
 236         NULL,                   /* release */
 237         smb_fsync,              /* fsync */
 238 };
 239 
 240 struct inode_operations smb_file_inode_operations = {
 241         &smb_file_operations,   /* default file operations */
 242         NULL,                   /* create */
 243         NULL,                   /* lookup */
 244         NULL,                   /* link */
 245         NULL,                   /* unlink */
 246         NULL,                   /* symlink */
 247         NULL,                   /* mkdir */
 248         NULL,                   /* rmdir */
 249         NULL,                   /* mknod */
 250         NULL,                   /* rename */
 251         NULL,                   /* readlink */
 252         NULL,                   /* follow_link */
 253         NULL,                   /* bmap */
 254         NULL                    /* truncate */
 255 };
 256 
 257 /*
 258  * Overrides for Emacs so that we follow Linus's tabbing style.
 259  * Emacs will notice this stuff at the end of the file and automatically
 260  * adjust the settings for this buffer only.  This must remain at the end
 261  * of the file.
 262  * ---------------------------------------------------------------------------
 263  * Local variables:
 264  * c-indent-level: 8
 265  * c-brace-imaginary-offset: 0
 266  * c-brace-offset: -8
 267  * c-argdecl-indent: 8
 268  * c-label-offset: -8
 269  * c-continued-statement-offset: 8
 270  * c-continued-brace-offset: 0
 271  * End:
 272  */

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