00001
00011 #include "file.h"
00012 #include "storage.h"
00013 #include "mountdata.h"
00014
00015
00016 #include <linux/list.h>
00017 #include <linux/rwsem.h>
00018 #include <linux/fs.h>
00019 #include <asm/uaccess.h>
00020
00021
00022
00029 int mumufs_file_open( struct inode * inode, struct file * file )
00030 {
00031 int RetVal = generic_file_open( inode, file );
00032 if ( RetVal != 0 )
00033 {
00034 return RetVal;
00035 }
00036
00037
00038
00039
00040
00041 file->private_data = 0;
00042 return 0;
00043 }
00044
00045
00055 int mumufs_file_release( struct inode * inode, struct file * file )
00056 {
00057 struct mumufs_storage * storage = (struct mumufs_storage *)(inode->i_private);
00058
00059 if ( storage == NULL )
00060 {
00061
00062 #ifdef DEBUG
00063 printk( "MUMU: mumufs_storage is not available for a file when it is closed.\n" );
00064 #endif
00065 return 0;
00066 }
00067
00068 return 0;
00069 }
00070
00071
00082 ssize_t mumufs_file_read( struct file * file, char * buffer, size_t size, loff_t * offset )
00083 {
00084 struct inode * node = file->f_dentry->d_inode;
00085 struct mumufs_storage * storage = (struct mumufs_storage *)(node->i_private);
00086
00087 #ifdef DEBUG
00088 mount_data->last_op = MUMU_READ;
00089 mount_data->last_bytes = size;
00090 mount_data->last_offset = *offset;
00091 #endif
00092
00093 #ifdef DEBUG
00094 if ( storage == NULL )
00095 {
00096
00097 return -EINVAL;
00098 }
00099 #endif
00100
00101
00102 if ( *offset != 0 ) return -EINVAL;
00103
00104 Loop:
00105 down_read( & storage->buffer_lock );
00106
00107 if ( size < storage->buffer_size )
00108 {
00109
00110 up_read( & storage->buffer_lock );
00111 return -EINVAL;
00112 }
00113
00114 if ( (storage->buffer_version != 0) &&
00115 (file->private_data != storage->buffer_version) )
00116 {
00117 int bytes_copied = storage->buffer_size;
00118
00119 if ( copy_to_user( buffer, storage->buffer, bytes_copied ) != 0 )
00120 {
00121 bytes_copied = -EINVAL;
00122 }
00123 else
00124 {
00125
00126 file->private_data = storage->buffer_version;
00127 node->i_atime = CURRENT_TIME;
00128 }
00129
00130 up_read( & storage->buffer_lock );
00131 return bytes_copied;
00132 }
00133
00134
00135
00136
00137
00138
00139 if ( file->f_flags & O_NONBLOCK )
00140 {
00141 up_read( & storage->buffer_lock );
00142 return -EAGAIN;
00143 }
00144
00145
00146
00147 up_read( & storage->buffer_lock );
00148 if ( wait_event_interruptible( storage->blocked_readers,
00149 (storage->buffer_version != file->private_data) ) != 0 )
00150 {
00151 return -ERESTARTSYS;
00152 }
00153 goto Loop;
00154 }
00155
00156
00157
00166 ssize_t mumufs_file_write( struct file * file, const char * buffer, size_t size, loff_t * offset )
00167 {
00168 struct inode * node = file->f_dentry->d_inode;
00169 struct mumufs_storage * storage = (struct mumufs_storage *)(node->i_private);
00170 struct mumu_mount_data * mount_data = (struct mumu_mount_data *)(file->f_dentry->d_sb->s_fs_info);
00171 unsigned char * kernel_buffer = NULL;
00172
00173 #ifdef DEBUG
00174 mount_data->last_op = MUMU_WRITE;
00175 mount_data->last_bytes = size;
00176 mount_data->last_offset = *offset;
00177 #endif
00178
00179 #ifdef DEBUG
00180 if ( storage == NULL )
00181 {
00182
00183 return -EINVAL;
00184 }
00185 #endif
00186
00187
00188 if ( *offset != 0 ) return -EINVAL;
00189 if ( size > mount_data->max_block_size ) return -EINVAL;
00190
00191
00192 kernel_buffer = kmalloc( size, GFP_KERNEL );
00193 if ( kernel_buffer == NULL ) return -ENOSPC;
00194 if ( copy_from_user( kernel_buffer, buffer, size ) != 0 )
00195 {
00196 kfree( kernel_buffer );
00197 return -EFAULT;
00198 }
00199
00200 down_write( & storage->buffer_lock );
00201
00202 if ( storage->buffer != NULL )
00203 {
00204 kfree( storage->buffer );
00205 }
00206 storage->buffer = kernel_buffer;
00207 storage->buffer_size = size;
00208
00209
00210 if ( ++(storage->buffer_version) == 0 )
00211 {
00212 ++(storage->buffer_version);
00213 }
00214
00215 node->i_size = size;
00216 node->i_mtime = CURRENT_TIME;
00217 node->i_blocks = 1;
00218 node->i_bytes = size;
00219
00220 up_write( & storage->buffer_lock );
00221
00222
00223 wake_up_interruptible( & storage->blocked_readers );
00224 return size;
00225 }
00226
00227
00228
00235 unsigned int mumufs_file_poll( struct file * file, struct poll_table_struct * poll_table )
00236 {
00237 unsigned int mask = POLLOUT | POLLWRNORM;
00238 struct inode * node = file->f_dentry->d_inode;
00239 struct mumufs_storage * storage = (struct mumufs_storage *)(node->i_private);
00240
00241 #ifdef DEBUG
00242 if ( storage == NULL )
00243 {
00244 return POLLERR;
00245 }
00246 #endif
00247
00248
00249 poll_wait( file, & storage->blocked_readers, poll_table );
00250
00251 down_read( & storage->buffer_lock );
00252 if ( (storage->buffer_version != 0) &&
00253 (file->private_data != storage->buffer_version) )
00254 {
00255 mask |= POLLIN | POLLRDNORM;
00256 }
00257 up_read( & storage->buffer_lock );
00258
00259 return mask;
00260 }
00261