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

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