Commit 810d5a02 authored by Steve French's avatar Steve French Committed by Steve French

add direct mount options to optionally bypass the page cache on reads and writes

parent f85d7dfa
......@@ -115,11 +115,20 @@ cifs client, and that EA support is present in later versions of Samba (e.g.
3.0.6 and later (also EA support works in all versions of Windows, at least to
shares on NTFS filesystems). Extended Attribute (xattr) support is an optional
feature of most Linux filesystems which may require enabling via
make menuconfig
make menuconfig.
The CIFS client can get and set POSIX ACLs (getfacl, setfacl) to Samba servers
version 3.10 and later. Setting POSIX ACLs requires enabling both XATTR and
then POSIX support in the CIFS configuration options when building the cifs
module.
Some administrators may want to change Samba's smb.conf "map archive" and
"create mask" parameters from the default. Creating special devices (mknod)
remotely may require specifying a mkdev function to Samba if you are not using
"create mask" parameters from the default. Unless the create mask is changed
newly created files can end up with an unnecessarily restrictive default mode,
which may not be what you want, although if the CIFS Unix extensions are
enabled on the server and client, subsequent setattr calls (e.g. chmod) can
fix the mode. Note that creating special devices (mknod) remotely
may require specifying a mkdev function to Samba if you are not using
Samba 3.0.6 or later. For more information on these see the manual pages
("man smb.conf") on the Samba server system. Note that the cifs vfs,
unlike the smbfs vfs, does not read the smb.conf on the client system
......@@ -324,6 +333,23 @@ A partial list of the supported mount options follows:
the client) set the uid and gid is the default. This
parameter has no effect if the CIFS Unix Extensions are not
negotiated.
netbiosname When mounting to servers via port 139, specifies the RFC1001
source name to use to represent the client netbios machine
name when doing the RFC1001 netbios session initialize.
direct Do not do inode data caching on files opened on this mount.
This precludes mmaping files on this mount. In some cases
with fast networks and little or no caching benefits on the
client (e.g. when the application is doing large sequential
reads bigger than page size without rereading the same data)
this can provide better performance than the default
behavior which caches reads (reaadahead) and writes
(writebehind) through the local Linux client pagecache
if oplock (caching token) is granted and held. Note that
direct allows write operations larger than page size
to be sent to the server.
acl Allow setfacl and getfacl to manage posix ACLs if server
supports them. (default)
noacl Do not allow setfacl and getfacl calls on this mount
The mount.cifs mount helper also accepts a few mount options before -o
including:
......@@ -402,7 +428,7 @@ require enabling an ifdef (e.g. by adding "#define CIFS_FCNTL" in cifsglob.h)
CONFIG_CIFS_FCNTL (fcntl needed for support of directory change
notification and perhaps later for file leases)
Per share (per client mount) statistics are available in /proc/fs/cifs/DebugData
Per share (per client mount) statistics are available in /proc/fs/cifs/Stats
if the kernel was configured with cifs statistics enabled. The statistics
represent the number of successful (ie non-zero return code from the server)
SMB responses to some of the more common commands (open, delete, mkdir etc.).
......
/*
* fs/cifs/cifs_fs_sb.h
*
* Copyright (c) International Business Machines Corp., 2002
* Copyright (c) International Business Machines Corp., 2002,2004
* Author(s): Steve French (sfrench@us.ibm.com)
*
* This library is free software; you can redistribute it and/or modify
......@@ -21,6 +21,7 @@
#define CIFS_MOUNT_NO_PERM 1 /* do not do client vfs_perm check */
#define CIFS_MOUNT_SET_UID 2 /* set current->euid in create etc. */
#define CIFS_MOUNT_SERVER_INUM 4 /* inode numbers from uniqueid from server */
#define CIFS_MOUNT_DIRECT_IO 8 /* do not write nor read through page cache */
struct cifs_sb_info {
struct cifsTconInfo *tcon; /* primary mount */
......
......@@ -435,6 +435,20 @@ cifs_read_wrapper(struct file * file, char __user *read_data, size_t read_size,
return -EIO;
cFYI(1,("In read_wrapper size %zd at %lld",read_size,*poffset));
#ifdef 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_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 {
......@@ -467,7 +481,18 @@ cifs_write_wrapper(struct file * file, const char __user *write_data,
cFYI(1,("In write_wrapper size %zd at %lld",write_size,*poffset));
#ifdef 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_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) {
......
......@@ -71,6 +71,7 @@ struct smb_vol {
unsigned noperm:1;
unsigned no_psx_acl:1; /* set if posix acl support should be disabled */
unsigned server_ino:1; /* use inode numbers from server ie UniqueId */
unsigned direct_io:1;
unsigned int rsize;
unsigned int wsize;
unsigned int sockopt;
......@@ -792,6 +793,10 @@ cifs_parse_mount_options(char *options, const char *devname,struct smb_vol *vol)
vol->no_psx_acl = 0;
} else if (strnicmp(data, "noacl",5) == 0) {
vol->no_psx_acl = 1;
} else if (strnicmp(data, "direct",6) == 0) {
vol->direct_io = 1;
} else if (strnicmp(data, "forcedirectio",13) == 0) {
vol->direct_io = 1;
} else if (strnicmp(data, "noac", 4) == 0) {
printk(KERN_WARNING "CIFS: Mount option noac not supported. Instead set /proc/fs/cifs/LookupCacheEnabled to 0\n");
} else
......@@ -1407,6 +1412,10 @@ cifs_mount(struct super_block *sb, struct cifs_sb_info *cifs_sb,
cifs_sb->mnt_cifs_flags |= CIFS_MOUNT_SET_UID;
if(volume_info.server_ino)
cifs_sb->mnt_cifs_flags |= CIFS_MOUNT_SERVER_INUM;
if(volume_info.direct_io) {
cFYI(1,("mounting share using direct i/o"));
cifs_sb->mnt_cifs_flags |= CIFS_MOUNT_DIRECT_IO;
}
tcon =
find_unc(sin_server.sin_addr.s_addr, volume_info.UNC,
......
......@@ -1067,6 +1067,17 @@ int cifs_file_mmap(struct file * file, struct vm_area_struct * vma)
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) {
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment