#include <linux/seq_file.h>
#include <linux/vfs.h>
#include <linux/mempool.h>
+#include <linux/delay.h>
#include "cifsfs.h"
#include "cifspdu.h"
#define DECLARE_GLOBALS_HERE
{
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 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",
};
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,
#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 */
};
#endif /* CONFIG_CIFS_EXPERIMENTAL */
};
struct file_operations cifs_file_nobrl_ops = {
- .read = cifs_read_wrapper,
- .write = cifs_write_wrapper,
- .open = cifs_open,
- .release = cifs_close,
- .fsync = cifs_fsync,
- .flush = cifs_flush,
- .mmap = cifs_file_mmap,
- .sendfile = generic_file_sendfile,
+ .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,
+ .ioctl = cifs_ioctl,
#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,
+ .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 */
+ /* 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,
+ .ioctl = cifs_ioctl,
#endif /* CONFIG_CIFS_POSIX */
#ifdef CONFIG_CIFS_EXPERIMENTAL
- .dir_notify = cifs_dir_notify,
+ .dir_notify = cifs_dir_notify,
#endif /* CONFIG_CIFS_EXPERIMENTAL */
};
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) {
}
} 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));
static int cifs_dnotify_thread(void * dummyarg)
{
+ struct list_head *tmp;
+ struct cifsSesInfo *ses;
+
daemonize("cifsdnotifyd");
allow_signal(SIGTERM);
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);
}