ChangeSet 1.2197, 2005/03/25 14:12:19-06:00, [EMAIL PROTECTED](none)
[CIFS] add generic readv/writev and aio support.
Suggested by Christoph Hellwig
Signed-off-by: Steve French ([EMAIL PROTECTED])
CHANGES | 3 ++-
cifsfs.c | 54 ++++++++++++++++++++++--------------------------------
cifsfs.h | 1 +
file.c | 11 -----------
inode.c | 47 +++++++++++++++++++++++++++--------------------
readdir.c | 14 +++++++++++---
6 files changed, 63 insertions(+), 67 deletions(-)
diff -Nru a/fs/cifs/CHANGES b/fs/cifs/CHANGES
--- a/fs/cifs/CHANGES 2005-03-30 12:09:52 -08:00
+++ b/fs/cifs/CHANGES 2005-03-30 12:09:52 -08:00
@@ -4,7 +4,8 @@
transact response for an SMB request and search entry split across two frames.
Fix updates of DOS attributes and time fields so that files on NT4 servers
do not get marked delete on close. Display sizes of cifs buffer pools in
-cifs stats.
+cifs stats. Fix oops in unmount when cifsd thread being killed by
+shutdown. Add generic readv/writev and aio support.
Version 1.30
------------
diff -Nru a/fs/cifs/cifsfs.c b/fs/cifs/cifsfs.c
--- a/fs/cifs/cifsfs.c 2005-03-30 12:09:52 -08:00
+++ b/fs/cifs/cifsfs.c 2005-03-30 12:09:52 -08:00
@@ -445,28 +445,13 @@
cifs_read_wrapper(struct file * file, char __user *read_data, size_t read_size,
loff_t * poffset)
{
- if(file == NULL)
- return -EIO;
- else if(file->f_dentry == NULL)
+ 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));
-#ifdef CONFIG_CIFS_EXPERIMENTAL
- /* check whether we can cache writes locally */
- if(file->f_dentry->d_sb) {
- struct cifs_sb_info *cifs_sb;
- cifs_sb = CIFS_SB(file->f_dentry->d_sb);
- if(cifs_sb != NULL) {
- if(cifs_sb->mnt_cifs_flags & CIFS_MOUNT_DIRECT_IO)
- return cifs_user_read(file,read_data,
- read_size,poffset);
- }
- }
-#endif /* CIFS_EXPERIMENTAL */
-
if(CIFS_I(file->f_dentry->d_inode)->clientCanCacheRead) {
return generic_file_read(file,read_data,read_size,poffset);
} else {
@@ -490,28 +475,13 @@
{
ssize_t written;
- if(file == NULL)
- return -EIO;
- else if(file->f_dentry == NULL)
+ 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));
-#ifdef CONFIG_CIFS_EXPERIMENTAL /* BB fixme - fix user char * to kernel
char * mapping here BB */
- /* check whether we can cache writes locally */
- if(file->f_dentry->d_sb) {
- struct cifs_sb_info *cifs_sb;
- cifs_sb = CIFS_SB(file->f_dentry->d_sb);
- if(cifs_sb != NULL) {
- if(cifs_sb->mnt_cifs_flags & CIFS_MOUNT_DIRECT_IO) {
- return cifs_user_write(file,write_data,
- write_size,poffset);
- }
- }
- }
-#endif /* CIFS_EXPERIMENTAL */
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) {
@@ -591,6 +561,26 @@
.flush = cifs_flush,
.mmap = cifs_file_mmap,
.sendfile = generic_file_sendfile,
+#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 */
+};
+
+struct file_operations cifs_file_direct_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,
+ .lock = cifs_lock,
+ .fsync = cifs_fsync,
+ .flush = cifs_flush,
+ .sendfile = generic_file_sendfile, /* BB removeme BB */
#ifdef CONFIG_CIFS_EXPERIMENTAL
.dir_notify = cifs_dir_notify,
#endif /* CONFIG_CIFS_EXPERIMENTAL */
diff -Nru a/fs/cifs/cifsfs.h b/fs/cifs/cifsfs.h
--- a/fs/cifs/cifsfs.h 2005-03-30 12:09:52 -08:00
+++ b/fs/cifs/cifsfs.h 2005-03-30 12:09:52 -08:00
@@ -62,6 +62,7 @@
/* Functions related to files and directories */
extern struct file_operations cifs_file_ops;
+extern struct file_operations cifs_file_direct_ops; /* if directio mount */
extern int cifs_open(struct inode *inode, struct file *file);
extern int cifs_close(struct inode *inode, struct file *file);
extern int cifs_closedir(struct inode *inode, struct file *file);
diff -Nru a/fs/cifs/file.c b/fs/cifs/file.c
--- a/fs/cifs/file.c 2005-03-30 12:09:52 -08:00
+++ b/fs/cifs/file.c 2005-03-30 12:09:52 -08:00
@@ -1314,17 +1314,6 @@
struct dentry *dentry = file->f_dentry;
int rc, xid;
-#ifdef CIFS_EXPERIMENTAL /* BB fixme reenable when cifs_read_wrapper fixed */
- if (dentry->d_sb) {
- struct cifs_sb_info *cifs_sb;
- cifs_sb = CIFS_SB(sb);
- if (cifs_sb != NULL) {
- if (cifs_sb->mnt_cifs_flags & CIFS_MOUNT_DIRECT_IO)
- return -ENODEV
- }
- }
-#endif /* CIFS_EXPERIMENTAL */
-
xid = GetXid();
rc = cifs_revalidate(dentry);
if (rc) {
diff -Nru a/fs/cifs/inode.c b/fs/cifs/inode.c
--- a/fs/cifs/inode.c 2005-03-30 12:09:52 -08:00
+++ b/fs/cifs/inode.c 2005-03-30 12:09:52 -08:00
@@ -99,7 +99,8 @@
cFYI(1, (" Old time %ld ", cifsInfo->time));
cifsInfo->time = jiffies;
cFYI(1, (" New time %ld ", cifsInfo->time));
- atomic_set(&cifsInfo->inUse,1); /* ok to set on every refresh
of inode */
+ /* this is ok to set on every inode revalidate */
+ atomic_set(&cifsInfo->inUse,1);
inode->i_atime =
cifs_NTtimeToUnix(le64_to_cpu(findData.LastAccessTime));
@@ -137,17 +138,17 @@
client is writing to it due to potential races */
i_size_write(inode, end_of_file);
-/* blksize needs to be multiple of two. So safer to default to blksize
- and blkbits set in superblock so 2**blkbits and blksize will match */
-/* inode->i_blksize =
- (pTcon->ses->server->maxBuf - MAX_CIFS_HDR_SIZE) &
0xFFFFFE00;*/
-
- /* This seems incredibly stupid but it turns out that
- i_blocks is not related to (i_size / i_blksize), instead a
- size of 512 is required to be used for calculating num blocks */
-
-/* inode->i_blocks =
+ /* blksize needs to be multiple of two. So safer to default to
+ blksize and blkbits set in superblock so 2**blkbits and blksize
+ will match rather than setting to:
+ (pTcon->ses->server->maxBuf - MAX_CIFS_HDR_SIZE) & 0xFFFFFE00;*/
+
+ /* This seems incredibly stupid but it turns out that i_blocks
+ is not related to (i_size / i_blksize), instead 512 byte size
+ is required for calculating num blocks */
+
+ /* inode->i_blocks =
(inode->i_blksize - 1 + num_of_bytes) >>
inode->i_blkbits;*/
/* 512 bytes (2**9) is the fake blocksize that must be used */
@@ -156,14 +157,17 @@
}
if (num_of_bytes < end_of_file)
- cFYI(1, ("Server inconsistency Error: it says
allocation size less than end of file "));
+ cFYI(1, ("allocation size less than end of file "));
cFYI(1,
("Size %ld and blocks %ld ",
(unsigned long) inode->i_size, inode->i_blocks));
if (S_ISREG(inode->i_mode)) {
cFYI(1, (" File inode "));
inode->i_op = &cifs_file_inode_ops;
- inode->i_fop = &cifs_file_ops;
+ if(cifs_sb->mnt_cifs_flags & CIFS_MOUNT_DIRECT_IO)
+ inode->i_fop = &cifs_file_direct_ops;
+ else
+ inode->i_fop = &cifs_file_ops;
inode->i_data.a_ops = &cifs_addr_ops;
} else if (S_ISDIR(inode->i_mode)) {
cFYI(1, (" Directory inode"));
@@ -198,7 +202,7 @@
if((pfindData == NULL) && (*pinode != NULL)) {
if(CIFS_I(*pinode)->clientCanCacheRead) {
- cFYI(1,("No need to revalidate inode sizes on cached
file "));
+ cFYI(1,("No need to revalidate cached inode sizes"));
return rc;
}
}
@@ -259,7 +263,7 @@
Are there Windows server or network appliances
for which IndexNumber field is not guaranteed unique? */
- /* if(cifs_sb->mnt_cifs_flags & CIFS_MOUNT_SERVER_INUM)
{
+ /* if(cifs_sb->mnt_cifs_flags & CIFS_MOUNT_SERVER_INUM){
(*pinode)->i_ino =
(unsigned long)pfindData->IndexNumber;
} */ /*NB: ino incremented to unique num in new_inode*/
@@ -273,10 +277,10 @@
cifsInfo->time = jiffies;
cFYI(1, (" New time %ld ", cifsInfo->time));
-/* blksize needs to be multiple of two. So safer to default to blksize
- and blkbits set in superblock so 2**blkbits and blksize will match */
-/* inode->i_blksize =
- (pTcon->ses->server->maxBuf - MAX_CIFS_HDR_SIZE) &
0xFFFFFE00;*/
+ /* blksize needs to be multiple of two. So safer to default to
+ blksize and blkbits set in superblock so 2**blkbits and blksize
+ will match rather than setting to:
+ (pTcon->ses->server->maxBuf - MAX_CIFS_HDR_SIZE) & 0xFFFFFE00;*/
/* Linux can not store file creation time unfortunately so we
ignore it */
inode->i_atime =
@@ -334,7 +338,10 @@
if (S_ISREG(inode->i_mode)) {
cFYI(1, (" File inode "));
inode->i_op = &cifs_file_inode_ops;
- inode->i_fop = &cifs_file_ops;
+ if(cifs_sb->mnt_cifs_flags & CIFS_MOUNT_DIRECT_IO)
+ inode->i_fop = &cifs_file_direct_ops;
+ else
+ inode->i_fop = &cifs_file_ops;
inode->i_data.a_ops = &cifs_addr_ops;
} else if (S_ISDIR(inode->i_mode)) {
cFYI(1, (" Directory inode "));
diff -Nru a/fs/cifs/readdir.c b/fs/cifs/readdir.c
--- a/fs/cifs/readdir.c 2005-03-30 12:09:52 -08:00
+++ b/fs/cifs/readdir.c 2005-03-30 12:09:52 -08:00
@@ -169,7 +169,7 @@
}
if (allocation_size < end_of_file)
- cFYI(1, ("Possible sparse file: allocation size less than end
of file "));
+ cFYI(1, ("May be sparse file, allocation less than file size"));
cFYI(1,
("File Size %ld and blocks %ld and blocksize %ld",
(unsigned long)tmp_inode->i_size, tmp_inode->i_blocks,
@@ -177,7 +177,10 @@
if (S_ISREG(tmp_inode->i_mode)) {
cFYI(1, (" File inode "));
tmp_inode->i_op = &cifs_file_inode_ops;
- tmp_inode->i_fop = &cifs_file_ops;
+ if(cifs_sb->mnt_cifs_flags & CIFS_MOUNT_DIRECT_IO)
+ tmp_inode->i_fop = &cifs_file_direct_ops;
+ else
+ tmp_inode->i_fop = &cifs_file_ops;
tmp_inode->i_data.a_ops = &cifs_addr_ops;
} else if (S_ISDIR(tmp_inode->i_mode)) {
cFYI(1, (" Directory inode"));
@@ -197,6 +200,8 @@
FILE_UNIX_INFO *pfindData, int *pobject_type)
{
struct cifsInodeInfo *cifsInfo = CIFS_I(tmp_inode);
+ struct cifs_sb_info *cifs_sb = CIFS_SB(tmp_inode->i_sb);
+
__u32 type = le32_to_cpu(pfindData->Type);
__u64 num_of_bytes = le64_to_cpu(pfindData->NumOfBytes);
__u64 end_of_file = le64_to_cpu(pfindData->EndOfFile);
@@ -255,7 +260,10 @@
if (S_ISREG(tmp_inode->i_mode)) {
cFYI(1, ("File inode"));
tmp_inode->i_op = &cifs_file_inode_ops;
- tmp_inode->i_fop = &cifs_file_ops;
+ if(cifs_sb->mnt_cifs_flags & CIFS_MOUNT_DIRECT_IO)
+ tmp_inode->i_fop = &cifs_file_direct_ops;
+ else
+ tmp_inode->i_fop = &cifs_file_ops;
tmp_inode->i_data.a_ops = &cifs_addr_ops;
} else if (S_ISDIR(tmp_inode->i_mode)) {
cFYI(1, ("Directory inode"));
-
To unsubscribe from this list: send the line "unsubscribe bk-commits-head" in
the body of a message to [EMAIL PROTECTED]
More majordomo info at http://vger.kernel.org/majordomo-info.html