X-Git-Url: https://git.openpandora.org/cgi-bin/gitweb.cgi?a=blobdiff_plain;f=fs%2Fcifs%2Fcifsfs.c;h=e10213b7541e4ec6685daa2c91ffe6a8aaf2c1c4;hb=1b1dcc1b57a49136f118a0f16367256ff9994a69;hp=877095a1192ad8e13b7bffe6e041ab578346ec46;hpb=d40d9d29c020f8466c96f8e3ad4b7c014ff1085d;p=pandora-kernel.git diff --git a/fs/cifs/cifsfs.c b/fs/cifs/cifsfs.c index 877095a1192a..e10213b7541e 100644 --- a/fs/cifs/cifsfs.c +++ b/fs/cifs/cifsfs.c @@ -32,6 +32,7 @@ #include #include #include +#include #include "cifsfs.h" #include "cifspdu.h" #define DECLARE_GLOBALS_HERE @@ -405,6 +406,7 @@ static struct quotactl_ops cifs_quotactl_ops = { }; #endif +#ifdef CONFIG_CIFS_EXPERIMENTAL static void cifs_umount_begin(struct super_block * sblock) { struct cifs_sb_info *cifs_sb; @@ -422,16 +424,23 @@ static void cifs_umount_begin(struct super_block * sblock) tcon->tidStatus = CifsExiting; up(&tcon->tconSem); + /* cancel_brl_requests(tcon); */ + /* cancel_notify_requests(tcon); */ if(tcon->ses && tcon->ses->server) { - cERROR(1,("wake up tasks now - umount begin not complete")); + cFYI(1,("wake up tasks now - umount begin not complete")); wake_up_all(&tcon->ses->server->request_q); + wake_up_all(&tcon->ses->server->response_q); + msleep(1); /* yield */ + /* we have to kick the requests once more */ + wake_up_all(&tcon->ses->server->response_q); + msleep(1); } /* BB FIXME - finish add checks for tidStatus BB */ return; } - +#endif static int cifs_remount(struct super_block *sb, int *flags, char *data) { @@ -450,7 +459,9 @@ struct super_operations cifs_super_ops = { unless later we add lazy close of inodes or unless the kernel forgets to call us with the same number of releases (closes) as opens */ .show_options = cifs_show_options, -/* .umount_begin = cifs_umount_begin, */ /* BB finish in the future */ +#ifdef CONFIG_CIFS_EXPERIMENTAL + .umount_begin = cifs_umount_begin, +#endif .remount_fs = cifs_remount, }; @@ -478,57 +489,30 @@ cifs_get_sb(struct file_system_type *fs_type, return sb; } -static ssize_t -cifs_read_wrapper(struct file * file, char __user *read_data, size_t read_size, - loff_t * poffset) +static ssize_t cifs_file_writev(struct file *file, const struct iovec *iov, + unsigned long nr_segs, loff_t *ppos) { - if(file->f_dentry == NULL) - return -EIO; - else if(file->f_dentry->d_inode == NULL) - return -EIO; - - cFYI(1,("In read_wrapper size %zd at %lld",read_size,*poffset)); + struct inode *inode = file->f_dentry->d_inode; + ssize_t written; - if(CIFS_I(file->f_dentry->d_inode)->clientCanCacheRead) { - return generic_file_read(file,read_data,read_size,poffset); - } else { - /* BB do we need to lock inode from here until after invalidate? */ -/* if(file->f_dentry->d_inode->i_mapping) { - filemap_fdatawrite(file->f_dentry->d_inode->i_mapping); - filemap_fdatawait(file->f_dentry->d_inode->i_mapping); - }*/ -/* cifs_revalidate(file->f_dentry);*/ /* BB fixme */ - - /* BB we should make timer configurable - perhaps - by simply calling cifs_revalidate here */ - /* invalidate_remote_inode(file->f_dentry->d_inode);*/ - return generic_file_read(file,read_data,read_size,poffset); - } + written = generic_file_writev(file, iov, nr_segs, ppos); + if (!CIFS_I(inode)->clientCanCacheAll) + filemap_fdatawrite(inode->i_mapping); + return written; } -static ssize_t -cifs_write_wrapper(struct file * file, const char __user *write_data, - size_t write_size, loff_t * poffset) +static ssize_t cifs_file_aio_write(struct kiocb *iocb, const char __user *buf, + size_t count, loff_t pos) { + struct inode *inode = iocb->ki_filp->f_dentry->d_inode; ssize_t written; - if(file->f_dentry == NULL) - return -EIO; - else if(file->f_dentry->d_inode == NULL) - return -EIO; - - cFYI(1,("In write_wrapper size %zd at %lld",write_size,*poffset)); - - written = generic_file_write(file,write_data,write_size,poffset); - if(!CIFS_I(file->f_dentry->d_inode)->clientCanCacheAll) { - if(file->f_dentry->d_inode->i_mapping) { - filemap_fdatawrite(file->f_dentry->d_inode->i_mapping); - } - } + written = generic_file_aio_write(iocb, buf, count, pos); + if (!CIFS_I(inode)->clientCanCacheAll) + filemap_fdatawrite(inode->i_mapping); return written; } - static struct file_system_type cifs_fs_type = { .owner = THIS_MODULE, .name = "cifs", @@ -589,8 +573,12 @@ struct inode_operations cifs_symlink_inode_ops = { }; struct file_operations cifs_file_ops = { - .read = cifs_read_wrapper, - .write = cifs_write_wrapper, + .read = do_sync_read, + .write = do_sync_write, + .readv = generic_file_readv, + .writev = cifs_file_writev, + .aio_read = generic_file_aio_read, + .aio_write = cifs_file_aio_write, .open = cifs_open, .release = cifs_close, .lock = cifs_lock, @@ -603,10 +591,6 @@ struct file_operations cifs_file_ops = { #endif /* CONFIG_CIFS_POSIX */ #ifdef CONFIG_CIFS_EXPERIMENTAL - .readv = generic_file_readv, - .writev = generic_file_writev, - .aio_read = generic_file_aio_read, - .aio_write = generic_file_aio_write, .dir_notify = cifs_dir_notify, #endif /* CONFIG_CIFS_EXPERIMENTAL */ }; @@ -626,6 +610,46 @@ struct file_operations cifs_file_direct_ops = { .ioctl = cifs_ioctl, #endif /* CONFIG_CIFS_POSIX */ +#ifdef CONFIG_CIFS_EXPERIMENTAL + .dir_notify = cifs_dir_notify, +#endif /* CONFIG_CIFS_EXPERIMENTAL */ +}; +struct file_operations cifs_file_nobrl_ops = { + .read = do_sync_read, + .write = do_sync_write, + .readv = generic_file_readv, + .writev = cifs_file_writev, + .aio_read = generic_file_aio_read, + .aio_write = cifs_file_aio_write, + .open = cifs_open, + .release = cifs_close, + .fsync = cifs_fsync, + .flush = cifs_flush, + .mmap = cifs_file_mmap, + .sendfile = generic_file_sendfile, +#ifdef CONFIG_CIFS_POSIX + .ioctl = cifs_ioctl, +#endif /* CONFIG_CIFS_POSIX */ + +#ifdef CONFIG_CIFS_EXPERIMENTAL + .dir_notify = cifs_dir_notify, +#endif /* CONFIG_CIFS_EXPERIMENTAL */ +}; + +struct file_operations cifs_file_direct_nobrl_ops = { + /* no mmap, no aio, no readv - + BB reevaluate whether they can be done with directio, no cache */ + .read = cifs_user_read, + .write = cifs_user_write, + .open = cifs_open, + .release = cifs_close, + .fsync = cifs_fsync, + .flush = cifs_flush, + .sendfile = generic_file_sendfile, /* BB removeme BB */ +#ifdef CONFIG_CIFS_POSIX + .ioctl = cifs_ioctl, +#endif /* CONFIG_CIFS_POSIX */ + #ifdef CONFIG_CIFS_EXPERIMENTAL .dir_notify = cifs_dir_notify, #endif /* CONFIG_CIFS_EXPERIMENTAL */ @@ -836,9 +860,9 @@ static int cifs_oplock_thread(void * dummyarg) DeleteOplockQEntry(oplock_item); /* can not grab inode sem here since it would deadlock when oplock received on delete - since vfs_unlink holds the i_sem across + since vfs_unlink holds the i_mutex across the call */ - /* down(&inode->i_sem);*/ + /* mutex_lock(&inode->i_mutex);*/ if (S_ISREG(inode->i_mode)) { rc = filemap_fdatawrite(inode->i_mapping); if(CIFS_I(inode)->clientCanCacheRead == 0) { @@ -847,7 +871,7 @@ static int cifs_oplock_thread(void * dummyarg) } } else rc = 0; - /* up(&inode->i_sem);*/ + /* mutex_unlock(&inode->i_mutex);*/ if (rc) CIFS_I(inode)->write_behind_rc = rc; cFYI(1,("Oplock flush inode %p rc %d",inode,rc)); @@ -877,6 +901,9 @@ static int cifs_oplock_thread(void * dummyarg) static int cifs_dnotify_thread(void * dummyarg) { + struct list_head *tmp; + struct cifsSesInfo *ses; + daemonize("cifsdnotifyd"); allow_signal(SIGTERM); @@ -885,7 +912,19 @@ static int cifs_dnotify_thread(void * dummyarg) if(try_to_freeze()) continue; set_current_state(TASK_INTERRUPTIBLE); - schedule_timeout(39*HZ); + schedule_timeout(15*HZ); + read_lock(&GlobalSMBSeslock); + /* check if any stuck requests that need + to be woken up and wakeq so the + thread can wake up and error out */ + list_for_each(tmp, &GlobalSMBSessionList) { + ses = list_entry(tmp, struct cifsSesInfo, + cifsSessionList); + if(ses && ses->server && + atomic_read(&ses->server->inFlight)) + wake_up_all(&ses->server->response_q); + } + read_unlock(&GlobalSMBSeslock); } while(!signal_pending(current)); complete_and_exit (&cifs_dnotify_exited, 0); }