root/fs/smbfs/file.c

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

DEFINITIONS

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

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