2005-04-17 02:20:36 +04:00
/*
* fs / cifs / cifsfs . c
*
2008-05-17 07:12:45 +04:00
* Copyright ( C ) International Business Machines Corp . , 2002 , 2008
2005-04-17 02:20:36 +04:00
* Author ( s ) : Steve French ( sfrench @ us . ibm . com )
*
* Common Internet FileSystem ( CIFS ) client
*
* This library is free software ; you can redistribute it and / or modify
* it under the terms of the GNU Lesser General Public License as published
* by the Free Software Foundation ; either version 2.1 of the License , or
* ( at your option ) any later version .
*
* This library is distributed in the hope that it will be useful ,
* but WITHOUT ANY WARRANTY ; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE . See
* the GNU Lesser General Public License for more details .
*
* You should have received a copy of the GNU Lesser General Public License
* along with this library ; if not , write to the Free Software
* Foundation , Inc . , 59 Temple Place , Suite 330 , Boston , MA 02111 - 1307 USA
*/
/* Note that BB means BUGBUG (ie something to fix eventually) */
# include <linux/module.h>
# include <linux/fs.h>
# include <linux/mount.h>
# include <linux/slab.h>
# include <linux/init.h>
# include <linux/list.h>
# include <linux/seq_file.h>
# include <linux/vfs.h>
# include <linux/mempool.h>
2005-11-30 07:55:11 +03:00
# include <linux/delay.h>
2006-04-22 02:52:25 +04:00
# include <linux/kthread.h>
2006-12-07 07:34:23 +03:00
# include <linux/freezer.h>
2010-09-02 04:06:02 +04:00
# include <net/ipv6.h>
2005-04-17 02:20:36 +04:00
# include "cifsfs.h"
# include "cifspdu.h"
# define DECLARE_GLOBALS_HERE
# include "cifsglob.h"
# include "cifsproto.h"
# include "cifs_debug.h"
# include "cifs_fs_sb.h"
# include <linux/mm.h>
2007-11-03 08:02:24 +03:00
# include <linux/key-type.h>
2007-11-03 08:11:06 +03:00
# include "cifs_spnego.h"
2010-07-05 16:41:50 +04:00
# include "fscache.h"
2005-04-17 02:20:36 +04:00
# define CIFS_MAGIC_NUMBER 0xFF534D42 /* the first four bytes of SMB PDUs */
int cifsFYI = 0 ;
int cifsERROR = 1 ;
int traceSMB = 0 ;
unsigned int oplockEnabled = 1 ;
unsigned int experimEnabled = 0 ;
unsigned int linuxExtEnabled = 1 ;
unsigned int lookupCacheEnabled = 1 ;
unsigned int multiuser_mount = 0 ;
2010-04-24 15:57:45 +04:00
unsigned int global_secflags = CIFSSEC_DEF ;
2006-06-01 02:40:51 +04:00
/* unsigned int ntlmv2_support = 0; */
2005-04-17 02:20:36 +04:00
unsigned int sign_CIFS_PDUs = 1 ;
2007-02-12 11:55:41 +03:00
static const struct super_operations cifs_super_ops ;
2005-04-17 02:20:36 +04:00
unsigned int CIFSMaxBufSize = CIFS_MAX_MSGSIZE ;
module_param ( CIFSMaxBufSize , int , 0 ) ;
2007-07-17 21:34:02 +04:00
MODULE_PARM_DESC ( CIFSMaxBufSize , " Network buffer size (not including header). "
" Default: 16384 Range: 8192 to 130048 " ) ;
2005-04-17 02:20:36 +04:00
unsigned int cifs_min_rcv = CIFS_MIN_RCV_POOL ;
module_param ( cifs_min_rcv , int , 0 ) ;
2007-07-17 21:34:02 +04:00
MODULE_PARM_DESC ( cifs_min_rcv , " Network buffers in pool. Default: 4 Range: "
" 1 to 64 " ) ;
2005-04-17 02:20:36 +04:00
unsigned int cifs_min_small = 30 ;
module_param ( cifs_min_small , int , 0 ) ;
2007-07-17 21:34:02 +04:00
MODULE_PARM_DESC ( cifs_min_small , " Small network buffers in pool. Default: 30 "
" Range: 2 to 256 " ) ;
2005-04-17 02:20:36 +04:00
unsigned int cifs_max_pending = CIFS_MAX_REQ ;
module_param ( cifs_max_pending , int , 0 ) ;
2007-07-17 21:34:02 +04:00
MODULE_PARM_DESC ( cifs_max_pending , " Simultaneous requests to server. "
" Default: 50 Range: 2 to 256 " ) ;
2005-04-17 02:20:36 +04:00
extern mempool_t * cifs_sm_req_poolp ;
extern mempool_t * cifs_req_poolp ;
extern mempool_t * cifs_mid_poolp ;
2010-10-11 23:07:19 +04:00
void
cifs_sb_active ( struct super_block * sb )
{
struct cifs_sb_info * server = CIFS_SB ( sb ) ;
if ( atomic_inc_return ( & server - > active ) = = 1 )
atomic_inc ( & sb - > s_active ) ;
}
void
cifs_sb_deactive ( struct super_block * sb )
{
struct cifs_sb_info * server = CIFS_SB ( sb ) ;
if ( atomic_dec_and_test ( & server - > active ) )
deactivate_super ( sb ) ;
}
2005-04-17 02:20:36 +04:00
static int
cifs_read_super ( struct super_block * sb , void * data ,
const char * devname , int silent )
{
struct inode * inode ;
struct cifs_sb_info * cifs_sb ;
int rc = 0 ;
2007-07-13 04:33:32 +04:00
2007-02-17 07:30:54 +03:00
/* BB should we make this contingent on mount parm? */
sb - > s_flags | = MS_NODIRATIME | MS_NOATIME ;
2007-07-07 23:25:05 +04:00
sb - > s_fs_info = kzalloc ( sizeof ( struct cifs_sb_info ) , GFP_KERNEL ) ;
2005-04-17 02:20:36 +04:00
cifs_sb = CIFS_SB ( sb ) ;
2007-05-01 00:13:06 +04:00
if ( cifs_sb = = NULL )
2005-04-17 02:20:36 +04:00
return - ENOMEM ;
2010-10-08 20:20:12 +04:00
spin_lock_init ( & cifs_sb - > tlink_tree_lock ) ;
2010-10-28 19:16:44 +04:00
cifs_sb - > tlink_tree = RB_ROOT ;
2010-10-08 20:20:12 +04:00
2010-04-22 14:09:48 +04:00
rc = bdi_setup_and_register ( & cifs_sb - > bdi , " cifs " , BDI_CAP_MAP_COPY ) ;
if ( rc ) {
kfree ( cifs_sb ) ;
return rc ;
}
2008-01-11 04:49:48 +03:00
# ifdef CONFIG_CIFS_DFS_UPCALL
/* copy mount params to sb for use in submounts */
/* BB: should we move this after the mount so we
* do not have to do the copy on failed mounts ?
* BB : May be it is better to do simple copy before
* complex operation ( mount ) , and in case of fail
* just exit instead of doing mount and attempting
* undo it if this copy fails ? */
2008-06-11 01:37:02 +04:00
if ( data ) {
int len = strlen ( data ) ;
cifs_sb - > mountdata = kzalloc ( len + 1 , GFP_KERNEL ) ;
if ( cifs_sb - > mountdata = = NULL ) {
2010-04-22 14:09:48 +04:00
bdi_destroy ( & cifs_sb - > bdi ) ;
2008-06-11 01:37:02 +04:00
kfree ( sb - > s_fs_info ) ;
sb - > s_fs_info = NULL ;
return - ENOMEM ;
}
strncpy ( cifs_sb - > mountdata , data , len + 1 ) ;
cifs_sb - > mountdata [ len ] = ' \0 ' ;
2008-01-11 04:49:48 +03:00
}
# endif
2005-04-17 02:20:36 +04:00
rc = cifs_mount ( sb , cifs_sb , data , devname ) ;
if ( rc ) {
if ( ! silent )
2010-04-21 07:50:45 +04:00
cERROR ( 1 , " cifs_mount failed w/return code = %d " , rc ) ;
2005-04-17 02:20:36 +04:00
goto out_mount_failed ;
}
sb - > s_magic = CIFS_MAGIC_NUMBER ;
sb - > s_op = & cifs_super_ops ;
2010-04-22 14:09:48 +04:00
sb - > s_bdi = & cifs_sb - > bdi ;
2005-04-17 02:20:36 +04:00
sb - > s_blocksize = CIFS_MAX_MSGSIZE ;
sb - > s_blocksize_bits = 14 ; /* default 2**14 = CIFS_MAX_MSGSIZE */
2009-05-27 17:37:34 +04:00
inode = cifs_root_iget ( sb , ROOT_I ) ;
2005-04-17 02:20:36 +04:00
2008-02-07 11:15:33 +03:00
if ( IS_ERR ( inode ) ) {
rc = PTR_ERR ( inode ) ;
inode = NULL ;
2005-04-17 02:20:36 +04:00
goto out_no_root ;
}
sb - > s_root = d_alloc_root ( inode ) ;
if ( ! sb - > s_root ) {
rc = - ENOMEM ;
goto out_no_root ;
}
2007-07-13 04:33:32 +04:00
2007-07-11 22:30:34 +04:00
# ifdef CONFIG_CIFS_EXPERIMENTAL
if ( cifs_sb - > mnt_cifs_flags & CIFS_MOUNT_SERVER_INUM ) {
2010-04-21 07:50:45 +04:00
cFYI ( 1 , " export ops supported " ) ;
2007-07-11 22:30:34 +04:00
sb - > s_export_op = & cifs_export_ops ;
}
# endif /* EXPERIMENTAL */
2005-04-17 02:20:36 +04:00
return 0 ;
out_no_root :
2010-04-21 07:50:45 +04:00
cERROR ( 1 , " cifs_read_super: get root inode failed " ) ;
2005-04-17 02:20:36 +04:00
if ( inode )
iput ( inode ) ;
2008-08-12 02:31:40 +04:00
2008-08-12 02:28:53 +04:00
cifs_umount ( sb , cifs_sb ) ;
2005-04-17 02:20:36 +04:00
out_mount_failed :
2007-05-01 00:13:06 +04:00
if ( cifs_sb ) {
2008-01-11 04:49:48 +03:00
# ifdef CONFIG_CIFS_DFS_UPCALL
if ( cifs_sb - > mountdata ) {
kfree ( cifs_sb - > mountdata ) ;
cifs_sb - > mountdata = NULL ;
}
# endif
2009-08-17 01:05:08 +04:00
unload_nls ( cifs_sb - > local_nls ) ;
2010-04-22 14:09:48 +04:00
bdi_destroy ( & cifs_sb - > bdi ) ;
2005-04-17 02:20:36 +04:00
kfree ( cifs_sb ) ;
}
return rc ;
}
static void
cifs_put_super ( struct super_block * sb )
{
int rc = 0 ;
struct cifs_sb_info * cifs_sb ;
2010-04-21 07:50:45 +04:00
cFYI ( 1 , " In cifs_put_super " ) ;
2005-04-17 02:20:36 +04:00
cifs_sb = CIFS_SB ( sb ) ;
2007-05-01 00:13:06 +04:00
if ( cifs_sb = = NULL ) {
2010-04-21 07:50:45 +04:00
cFYI ( 1 , " Empty cifs superblock info passed to unmount " ) ;
2005-04-17 02:20:36 +04:00
return ;
}
push BKL down into ->put_super
Move BKL into ->put_super from the only caller. A couple of
filesystems had trivial enough ->put_super (only kfree and NULLing of
s_fs_info + stuff in there) to not get any locking: coda, cramfs, efs,
hugetlbfs, omfs, qnx4, shmem, all others got the full treatment. Most
of them probably don't need it, but I'd rather sort that out individually.
Preferably after all the other BKL pushdowns in that area.
[AV: original used to move lock_super() down as well; these changes are
removed since we don't do lock_super() at all in generic_shutdown_super()
now]
[AV: fuse, btrfs and xfs are known to need no damn BKL, exempt]
Signed-off-by: Christoph Hellwig <hch@lst.de>
Signed-off-by: Al Viro <viro@zeniv.linux.org.uk>
2009-05-05 17:40:36 +04:00
2007-07-07 23:25:05 +04:00
rc = cifs_umount ( sb , cifs_sb ) ;
2008-02-08 02:25:02 +03:00
if ( rc )
2010-04-21 07:50:45 +04:00
cERROR ( 1 , " cifs_umount failed with return code %d " , rc ) ;
2008-01-11 04:49:48 +03:00
# ifdef CONFIG_CIFS_DFS_UPCALL
if ( cifs_sb - > mountdata ) {
kfree ( cifs_sb - > mountdata ) ;
cifs_sb - > mountdata = NULL ;
}
# endif
2005-04-17 02:20:36 +04:00
unload_nls ( cifs_sb - > local_nls ) ;
2010-04-22 14:09:48 +04:00
bdi_destroy ( & cifs_sb - > bdi ) ;
2005-04-17 02:20:36 +04:00
kfree ( cifs_sb ) ;
}
static int
2006-06-23 13:02:58 +04:00
cifs_statfs ( struct dentry * dentry , struct kstatfs * buf )
2005-04-17 02:20:36 +04:00
{
2006-06-23 13:02:58 +04:00
struct super_block * sb = dentry - > d_sb ;
2008-04-28 08:04:34 +04:00
struct cifs_sb_info * cifs_sb = CIFS_SB ( sb ) ;
2010-09-21 03:01:35 +04:00
struct cifsTconInfo * tcon = cifs_sb_master_tcon ( cifs_sb ) ;
2005-04-29 09:41:07 +04:00
int rc = - EOPNOTSUPP ;
2008-04-28 08:04:34 +04:00
int xid ;
2005-04-17 02:20:36 +04:00
xid = GetXid ( ) ;
buf - > f_type = CIFS_MAGIC_NUMBER ;
2008-04-28 08:04:34 +04:00
/*
* PATH_MAX may be too long - it would presumably be total path ,
* but note that some servers ( includinng Samba 3 ) have a shorter
* maximum path .
*
* Instead could get the real value via SMB_QUERY_FS_ATTRIBUTE_INFO .
*/
buf - > f_namelen = PATH_MAX ;
2005-04-17 02:20:36 +04:00
buf - > f_files = 0 ; /* undefined */
buf - > f_ffree = 0 ; /* unlimited */
2008-04-28 08:04:34 +04:00
/*
* We could add a second check for a QFS Unix capability bit
*/
if ( ( tcon - > ses - > capabilities & CAP_UNIX ) & &
( CIFS_POSIX_EXTENSIONS & le64_to_cpu ( tcon - > fsUnixInfo . Capability ) ) )
rc = CIFSSMBQFSPosixInfo ( xid , tcon , buf ) ;
/*
* Only need to call the old QFSInfo if failed on newer one ,
* e . g . by OS / 2.
* */
if ( rc & & ( tcon - > ses - > capabilities & CAP_NT_SMBS ) )
rc = CIFSSMBQFSInfo ( xid , tcon , buf ) ;
/*
* Some old Windows servers also do not support level 103 , retry with
* older level one if old server failed the previous call or we
* bypassed it because we detected that this was an older LANMAN sess
*/
2007-05-01 00:13:06 +04:00
if ( rc )
2008-04-28 08:04:34 +04:00
rc = SMBOldQFSInfo ( xid , tcon , buf ) ;
2005-04-17 02:20:36 +04:00
FreeXid ( xid ) ;
2008-04-28 08:04:34 +04:00
return 0 ;
2005-04-17 02:20:36 +04:00
}
2008-07-16 05:03:57 +04:00
static int cifs_permission ( struct inode * inode , int mask )
2005-04-17 02:20:36 +04:00
{
struct cifs_sb_info * cifs_sb ;
cifs_sb = CIFS_SB ( inode - > i_sb ) ;
2008-07-31 15:41:58 +04:00
if ( cifs_sb - > mnt_cifs_flags & CIFS_MOUNT_NO_PERM ) {
if ( ( mask & MAY_EXEC ) & & ! execute_ok ( inode ) )
return - EACCES ;
else
return 0 ;
} else /* file mode might have been restricted at mount time
2007-07-13 04:33:32 +04:00
on the client ( above and beyond ACL on servers ) for
2005-04-17 02:20:36 +04:00
servers which do not support setting and viewing mode bits ,
2007-07-13 04:33:32 +04:00
so allowing client to check permissions is useful */
2005-04-17 02:20:36 +04:00
return generic_permission ( inode , mask , NULL ) ;
}
2006-12-07 07:33:20 +03:00
static struct kmem_cache * cifs_inode_cachep ;
static struct kmem_cache * cifs_req_cachep ;
static struct kmem_cache * cifs_mid_cachep ;
static struct kmem_cache * cifs_sm_req_cachep ;
2005-04-17 02:20:36 +04:00
mempool_t * cifs_sm_req_poolp ;
mempool_t * cifs_req_poolp ;
mempool_t * cifs_mid_poolp ;
static struct inode *
cifs_alloc_inode ( struct super_block * sb )
{
struct cifsInodeInfo * cifs_inode ;
2006-12-07 07:33:17 +03:00
cifs_inode = kmem_cache_alloc ( cifs_inode_cachep , GFP_KERNEL ) ;
2005-04-17 02:20:36 +04:00
if ( ! cifs_inode )
return NULL ;
cifs_inode - > cifsAttrs = 0x20 ; /* default */
cifs_inode - > time = 0 ;
/* Until the file is open and we have gotten oplock
info back from the server , can not assume caching of
file data or metadata */
2010-11-03 10:58:57 +03:00
cifs_set_oplock_level ( cifs_inode , 0 ) ;
2008-10-18 05:03:20 +04:00
cifs_inode - > delete_pending = false ;
2010-02-12 15:44:16 +03:00
cifs_inode - > invalid_mapping = false ;
2005-04-17 02:20:36 +04:00
cifs_inode - > vfs_inode . i_blkbits = 14 ; /* 2**14 = CIFS_MAX_MSGSIZE */
2009-04-03 21:44:00 +04:00
cifs_inode - > server_eof = 0 ;
2007-07-13 04:33:32 +04:00
2007-02-17 07:30:54 +03:00
/* Can not set i_flags here - they get immediately overwritten
to zero by the VFS */
/* cifs_inode->vfs_inode.i_flags = S_NOATIME | S_NOCMTIME;*/
2005-04-17 02:20:36 +04:00
INIT_LIST_HEAD ( & cifs_inode - > openFileList ) ;
return & cifs_inode - > vfs_inode ;
}
static void
cifs_destroy_inode ( struct inode * inode )
{
kmem_cache_free ( cifs_inode_cachep , CIFS_I ( inode ) ) ;
}
2010-07-05 16:42:45 +04:00
static void
2010-06-07 22:34:48 +04:00
cifs_evict_inode ( struct inode * inode )
2010-07-05 16:42:45 +04:00
{
2010-06-07 22:34:48 +04:00
truncate_inode_pages ( & inode - > i_data , 0 ) ;
end_writeback ( inode ) ;
2010-07-05 16:42:45 +04:00
cifs_fscache_release_inode_cookie ( inode ) ;
}
2009-06-11 18:27:32 +04:00
static void
cifs_show_address ( struct seq_file * s , struct TCP_Server_Info * server )
{
seq_printf ( s , " ,addr= " ) ;
switch ( server - > addr . sockAddr . sin_family ) {
case AF_INET :
seq_printf ( s , " %pI4 " , & server - > addr . sockAddr . sin_addr . s_addr ) ;
break ;
case AF_INET6 :
seq_printf ( s , " %pI6 " ,
& server - > addr . sockAddr6 . sin6_addr . s6_addr ) ;
if ( server - > addr . sockAddr6 . sin6_scope_id )
seq_printf ( s , " %%%u " ,
server - > addr . sockAddr6 . sin6_scope_id ) ;
break ;
default :
seq_printf ( s , " (unknown) " ) ;
}
}
2005-04-17 02:20:36 +04:00
/*
* cifs_show_options ( ) is for displaying mount options in / proc / mounts .
* Not all settable options are displayed but most of the important
* ones are .
*/
static int
cifs_show_options ( struct seq_file * s , struct vfsmount * m )
{
2009-08-28 18:11:10 +04:00
struct cifs_sb_info * cifs_sb = CIFS_SB ( m - > mnt_sb ) ;
2010-09-21 03:01:35 +04:00
struct cifsTconInfo * tcon = cifs_sb_master_tcon ( cifs_sb ) ;
2010-09-02 04:06:02 +04:00
struct sockaddr * srcaddr ;
srcaddr = ( struct sockaddr * ) & tcon - > ses - > server - > srcaddr ;
2009-06-11 18:27:28 +04:00
2009-08-28 18:11:10 +04:00
seq_printf ( s , " ,unc=%s " , tcon - > treeName ) ;
2010-09-30 03:51:12 +04:00
if ( cifs_sb - > mnt_cifs_flags & CIFS_MOUNT_MULTIUSER )
seq_printf ( s , " ,multiuser " ) ;
else if ( tcon - > ses - > userName )
2009-06-11 18:27:28 +04:00
seq_printf ( s , " ,username=%s " , tcon - > ses - > userName ) ;
2010-09-30 03:51:12 +04:00
2009-06-11 18:27:28 +04:00
if ( tcon - > ses - > domainName )
seq_printf ( s , " ,domain=%s " , tcon - > ses - > domainName ) ;
2010-09-02 04:06:02 +04:00
if ( srcaddr - > sa_family ! = AF_UNSPEC ) {
struct sockaddr_in * saddr4 ;
struct sockaddr_in6 * saddr6 ;
saddr4 = ( struct sockaddr_in * ) srcaddr ;
saddr6 = ( struct sockaddr_in6 * ) srcaddr ;
if ( srcaddr - > sa_family = = AF_INET6 )
seq_printf ( s , " ,srcaddr=%pI6c " ,
& saddr6 - > sin6_addr ) ;
else if ( srcaddr - > sa_family = = AF_INET )
seq_printf ( s , " ,srcaddr=%pI4 " ,
& saddr4 - > sin_addr . s_addr ) ;
else
seq_printf ( s , " ,srcaddr=BAD-AF:%i " ,
( int ) ( srcaddr - > sa_family ) ) ;
}
2009-06-11 18:27:28 +04:00
seq_printf ( s , " ,uid=%d " , cifs_sb - > mnt_uid ) ;
2009-06-11 18:27:29 +04:00
if ( cifs_sb - > mnt_cifs_flags & CIFS_MOUNT_OVERR_UID )
seq_printf ( s , " ,forceuid " ) ;
2009-08-03 20:45:10 +04:00
else
seq_printf ( s , " ,noforceuid " ) ;
2009-06-11 18:27:29 +04:00
2009-06-11 18:27:28 +04:00
seq_printf ( s , " ,gid=%d " , cifs_sb - > mnt_gid ) ;
2009-06-11 18:27:29 +04:00
if ( cifs_sb - > mnt_cifs_flags & CIFS_MOUNT_OVERR_GID )
seq_printf ( s , " ,forcegid " ) ;
2009-08-03 20:45:10 +04:00
else
seq_printf ( s , " ,noforcegid " ) ;
2009-06-11 18:27:28 +04:00
2009-06-11 18:27:32 +04:00
cifs_show_address ( s , tcon - > ses - > server ) ;
2005-04-17 02:20:36 +04:00
2009-06-11 18:27:28 +04:00
if ( ! tcon - > unix_ext )
seq_printf ( s , " ,file_mode=0%o,dir_mode=0%o " ,
2008-05-17 07:12:45 +04:00
cifs_sb - > mnt_file_mode ,
cifs_sb - > mnt_dir_mode ) ;
2009-06-11 18:27:28 +04:00
if ( tcon - > seal )
seq_printf ( s , " ,seal " ) ;
if ( tcon - > nocase )
seq_printf ( s , " ,nocase " ) ;
if ( tcon - > retry )
seq_printf ( s , " ,hard " ) ;
if ( cifs_sb - > prepath )
seq_printf ( s , " ,prepath=%s " , cifs_sb - > prepath ) ;
if ( cifs_sb - > mnt_cifs_flags & CIFS_MOUNT_POSIX_PATHS )
seq_printf ( s , " ,posixpaths " ) ;
if ( cifs_sb - > mnt_cifs_flags & CIFS_MOUNT_SET_UID )
seq_printf ( s , " ,setuids " ) ;
if ( cifs_sb - > mnt_cifs_flags & CIFS_MOUNT_SERVER_INUM )
seq_printf ( s , " ,serverino " ) ;
if ( cifs_sb - > mnt_cifs_flags & CIFS_MOUNT_DIRECT_IO )
seq_printf ( s , " ,directio " ) ;
if ( cifs_sb - > mnt_cifs_flags & CIFS_MOUNT_NO_XATTR )
seq_printf ( s , " ,nouser_xattr " ) ;
if ( cifs_sb - > mnt_cifs_flags & CIFS_MOUNT_MAP_SPECIAL_CHR )
seq_printf ( s , " ,mapchars " ) ;
if ( cifs_sb - > mnt_cifs_flags & CIFS_MOUNT_UNX_EMUL )
seq_printf ( s , " ,sfu " ) ;
if ( cifs_sb - > mnt_cifs_flags & CIFS_MOUNT_NO_BRL )
seq_printf ( s , " ,nobrl " ) ;
if ( cifs_sb - > mnt_cifs_flags & CIFS_MOUNT_CIFS_ACL )
seq_printf ( s , " ,cifsacl " ) ;
if ( cifs_sb - > mnt_cifs_flags & CIFS_MOUNT_DYNPERM )
seq_printf ( s , " ,dynperm " ) ;
if ( m - > mnt_sb - > s_flags & MS_POSIXACL )
seq_printf ( s , " ,acl " ) ;
2010-07-30 16:56:00 +04:00
if ( cifs_sb - > mnt_cifs_flags & CIFS_MOUNT_MF_SYMLINKS )
seq_printf ( s , " ,mfsymlinks " ) ;
2010-11-24 15:19:07 +03:00
if ( cifs_sb - > mnt_cifs_flags & CIFS_MOUNT_FSCACHE )
seq_printf ( s , " ,fsc " ) ;
2009-06-11 18:27:28 +04:00
seq_printf ( s , " ,rsize=%d " , cifs_sb - > rsize ) ;
seq_printf ( s , " ,wsize=%d " , cifs_sb - > wsize ) ;
2010-12-01 12:12:28 +03:00
/* convert actimeo and display it in seconds */
seq_printf ( s , " ,actimeo=%lu " , cifs_sb - > actimeo / HZ ) ;
2009-06-11 18:27:28 +04:00
2005-04-17 02:20:36 +04:00
return 0 ;
}
2008-04-24 15:21:56 +04:00
static void cifs_umount_begin ( struct super_block * sb )
2005-10-10 21:34:22 +04:00
{
2008-04-24 15:21:56 +04:00
struct cifs_sb_info * cifs_sb = CIFS_SB ( sb ) ;
2007-07-13 04:33:32 +04:00
struct cifsTconInfo * tcon ;
2005-10-10 21:34:22 +04:00
2007-05-01 00:13:06 +04:00
if ( cifs_sb = = NULL )
2005-10-11 01:28:38 +04:00
return ;
2010-09-21 03:01:35 +04:00
tcon = cifs_sb_master_tcon ( cifs_sb ) ;
2008-11-15 19:12:47 +03:00
2010-10-18 21:59:37 +04:00
spin_lock ( & cifs_tcp_ses_lock ) ;
2009-06-26 07:25:49 +04:00
if ( ( tcon - > tc_count > 1 ) | | ( tcon - > tidStatus = = CifsExiting ) ) {
/* we have other mounts to same share or we have
already tried to force umount this and woken up
all waiting network requests , nothing to do */
2010-10-18 21:59:37 +04:00
spin_unlock ( & cifs_tcp_ses_lock ) ;
2009-06-26 07:25:49 +04:00
return ;
} else if ( tcon - > tc_count = = 1 )
2005-10-11 01:06:37 +04:00
tcon - > tidStatus = CifsExiting ;
2010-10-18 21:59:37 +04:00
spin_unlock ( & cifs_tcp_ses_lock ) ;
2005-10-11 01:06:37 +04:00
2006-07-15 02:37:11 +04:00
/* cancel_brl_requests(tcon); */ /* BB mark all brl mids as exiting */
2005-11-10 02:21:09 +03:00
/* cancel_notify_requests(tcon); */
2007-07-13 04:33:32 +04:00
if ( tcon - > ses & & tcon - > ses - > server ) {
2010-04-21 07:50:45 +04:00
cFYI ( 1 , " wake up tasks now - umount begin not complete " ) ;
2005-10-11 01:28:38 +04:00
wake_up_all ( & tcon - > ses - > server - > request_q ) ;
2005-11-30 07:55:11 +03:00
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 ) ;
2005-10-11 01:06:37 +04:00
}
2005-10-10 21:34:22 +04:00
return ;
}
2006-09-29 01:34:06 +04:00
# ifdef CONFIG_CIFS_STATS2
static int cifs_show_stats ( struct seq_file * s , struct vfsmount * mnt )
{
/* BB FIXME */
return 0 ;
}
# endif
2005-04-17 02:20:36 +04:00
static int cifs_remount ( struct super_block * sb , int * flags , char * data )
{
* flags | = MS_NODIRATIME ;
return 0 ;
}
2010-06-07 21:43:19 +04:00
static int cifs_drop_inode ( struct inode * inode )
2010-06-01 22:47:40 +04:00
{
struct cifs_sb_info * cifs_sb = CIFS_SB ( inode - > i_sb ) ;
2010-06-07 21:43:19 +04:00
/* no serverino => unconditional eviction */
return ! ( cifs_sb - > mnt_cifs_flags & CIFS_MOUNT_SERVER_INUM ) | |
generic_drop_inode ( inode ) ;
2010-06-01 22:47:40 +04:00
}
2007-02-12 11:55:41 +03:00
static const struct super_operations cifs_super_ops = {
2005-04-17 02:20:36 +04:00
. put_super = cifs_put_super ,
. statfs = cifs_statfs ,
. alloc_inode = cifs_alloc_inode ,
. destroy_inode = cifs_destroy_inode ,
2010-06-01 22:47:40 +04:00
. drop_inode = cifs_drop_inode ,
2010-06-07 22:34:48 +04:00
. evict_inode = cifs_evict_inode ,
2010-06-01 22:47:40 +04:00
/* .delete_inode = cifs_delete_inode, */ /* Do not need above
function unless later we add lazy close of inodes or unless the
2007-07-13 04:33:32 +04:00
kernel forgets to call us with the same number of releases ( closes )
as opens */
2005-04-17 02:20:36 +04:00
. show_options = cifs_show_options ,
2005-11-10 02:21:09 +03:00
. umount_begin = cifs_umount_begin ,
2005-04-17 02:20:36 +04:00
. remount_fs = cifs_remount ,
2006-09-29 01:34:06 +04:00
# ifdef CONFIG_CIFS_STATS2
2006-09-30 05:08:55 +04:00
. show_stats = cifs_show_stats ,
2006-09-29 01:34:06 +04:00
# endif
2005-04-17 02:20:36 +04:00
} ;
2010-07-26 12:52:33 +04:00
static struct dentry *
cifs_do_mount ( struct file_system_type * fs_type ,
int flags , const char * dev_name , void * data )
2005-04-17 02:20:36 +04:00
{
int rc ;
2010-08-16 00:51:10 +04:00
struct super_block * sb ;
sb = sget ( fs_type , NULL , set_anon_super , NULL ) ;
2005-04-17 02:20:36 +04:00
2010-04-21 07:50:45 +04:00
cFYI ( 1 , " Devname: %s flags: %d " , dev_name , flags ) ;
2005-04-17 02:20:36 +04:00
2010-02-24 15:25:29 +03:00
if ( IS_ERR ( sb ) )
2010-07-26 12:52:33 +04:00
return ERR_CAST ( sb ) ;
2005-04-17 02:20:36 +04:00
sb - > s_flags = flags ;
[PATCH] vfs: MS_VERBOSE should be MS_SILENT
The meaning of MS_VERBOSE is backwards; if the bit is set, it really means,
"don't be verbose". This is confusing and counter-intuitive.
In addition, there is also no way to set the MS_VERBOSE flag in the
mount(8) program in util-linux, but interesting, it does define options
which would do the right thing if MS_SILENT were defined, which
unfortunately we do not:
#ifdef MS_SILENT
{ "quiet", 0, 0, MS_SILENT }, /* be quiet */
{ "loud", 0, 1, MS_SILENT }, /* print out messages. */
#endif
So the obvious fix is to deprecate the use of MS_VERBOSE and replace it
with MS_SILENT.
Signed-off-by: "Theodore Ts'o" <tytso@mit.edu>
Signed-off-by: Andrew Morton <akpm@osdl.org>
Signed-off-by: Linus Torvalds <torvalds@osdl.org>
2006-03-24 14:15:10 +03:00
rc = cifs_read_super ( sb , data , dev_name , flags & MS_SILENT ? 1 : 0 ) ;
2005-04-17 02:20:36 +04:00
if ( rc ) {
2009-05-06 09:34:22 +04:00
deactivate_locked_super ( sb ) ;
2010-07-26 12:52:33 +04:00
return ERR_PTR ( rc ) ;
2005-04-17 02:20:36 +04:00
}
sb - > s_flags | = MS_ACTIVE ;
2010-07-26 12:52:33 +04:00
return dget ( sb - > s_root ) ;
2005-04-17 02:20:36 +04:00
}
2006-10-01 10:28:46 +04:00
static ssize_t cifs_file_aio_write ( struct kiocb * iocb , const struct iovec * iov ,
unsigned long nr_segs , loff_t pos )
2005-04-17 02:20:36 +04:00
{
2006-12-08 13:36:48 +03:00
struct inode * inode = iocb - > ki_filp - > f_path . dentry - > d_inode ;
2005-04-17 02:20:36 +04:00
ssize_t written ;
2006-10-01 10:28:46 +04:00
written = generic_file_aio_write ( iocb , iov , nr_segs , pos ) ;
2005-11-18 04:03:00 +03:00
if ( ! CIFS_I ( inode ) - > clientCanCacheAll )
filemap_fdatawrite ( inode - > i_mapping ) ;
2005-04-17 02:20:36 +04:00
return written ;
}
2006-01-13 01:41:28 +03:00
static loff_t cifs_llseek ( struct file * file , loff_t offset , int origin )
{
/* origin == SEEK_END => we must revalidate the cached file length */
2006-09-24 02:11:07 +04:00
if ( origin = = SEEK_END ) {
2007-02-01 07:27:59 +03:00
int retval ;
/* some applications poll for the file length in this strange
way so we must seek to end on non - oplocked files by
setting the revalidate time to zero */
2007-04-02 22:47:20 +04:00
CIFS_I ( file - > f_path . dentry - > d_inode ) - > time = 0 ;
2007-02-01 07:27:59 +03:00
2010-02-12 15:44:18 +03:00
retval = cifs_revalidate_file ( file ) ;
2006-01-13 01:41:28 +03:00
if ( retval < 0 )
return ( loff_t ) retval ;
}
2008-06-27 13:05:24 +04:00
return generic_file_llseek_unlocked ( file , offset , origin ) ;
2006-01-13 01:41:28 +03:00
}
2008-10-23 08:42:37 +04:00
static int cifs_setlease ( struct file * file , long arg , struct file_lock * * lease )
{
2010-09-18 17:09:31 +04:00
/* note that this is called by vfs setlease with lock_flocks held
to protect * lease from going away */
2008-10-23 08:42:37 +04:00
struct inode * inode = file - > f_path . dentry - > d_inode ;
2010-09-21 03:01:31 +04:00
struct cifsFileInfo * cfile = file - > private_data ;
2008-10-23 08:42:37 +04:00
if ( ! ( S_ISREG ( inode - > i_mode ) ) )
return - EINVAL ;
/* check if file is oplocked */
if ( ( ( arg = = F_RDLCK ) & &
( CIFS_I ( inode ) - > clientCanCacheRead ) ) | |
( ( arg = = F_WRLCK ) & &
( CIFS_I ( inode ) - > clientCanCacheAll ) ) )
return generic_setlease ( file , arg , lease ) ;
2010-09-30 03:51:11 +04:00
else if ( tlink_tcon ( cfile - > tlink ) - > local_lease & &
! CIFS_I ( inode ) - > clientCanCacheRead )
2008-10-23 08:42:37 +04:00
/* If the server claims to support oplock on this
file , then we still need to check oplock even
if the local_lease mount option is set , but there
are servers which do not support oplock for which
this mount option may be useful if the user
knows that the file won ' t be changed on the server
by anyone else */
return generic_setlease ( file , arg , lease ) ;
2010-10-31 15:35:10 +03:00
else
2008-10-23 08:42:37 +04:00
return - EAGAIN ;
}
2008-01-11 04:49:48 +03:00
struct file_system_type cifs_fs_type = {
2005-04-17 02:20:36 +04:00
. owner = THIS_MODULE ,
. name = " cifs " ,
2010-07-26 12:52:33 +04:00
. mount = cifs_do_mount ,
2005-04-17 02:20:36 +04:00
. kill_sb = kill_anon_super ,
/* .fs_flags */
} ;
2007-02-12 11:55:38 +03:00
const struct inode_operations cifs_dir_inode_ops = {
2005-04-17 02:20:36 +04:00
. create = cifs_create ,
. lookup = cifs_lookup ,
. getattr = cifs_getattr ,
. unlink = cifs_unlink ,
. link = cifs_hardlink ,
. mkdir = cifs_mkdir ,
. rmdir = cifs_rmdir ,
. rename = cifs_rename ,
. permission = cifs_permission ,
/* revalidate:cifs_revalidate, */
. setattr = cifs_setattr ,
. symlink = cifs_symlink ,
. mknod = cifs_mknod ,
# ifdef CONFIG_CIFS_XATTR
. setxattr = cifs_setxattr ,
. getxattr = cifs_getxattr ,
. listxattr = cifs_listxattr ,
. removexattr = cifs_removexattr ,
# endif
} ;
2007-02-12 11:55:38 +03:00
const struct inode_operations cifs_file_inode_ops = {
2005-04-17 02:20:36 +04:00
/* revalidate:cifs_revalidate, */
. setattr = cifs_setattr ,
. getattr = cifs_getattr , /* do we need this anymore? */
. rename = cifs_rename ,
. permission = cifs_permission ,
# ifdef CONFIG_CIFS_XATTR
. setxattr = cifs_setxattr ,
. getxattr = cifs_getxattr ,
. listxattr = cifs_listxattr ,
. removexattr = cifs_removexattr ,
2007-07-13 04:33:32 +04:00
# endif
2005-04-17 02:20:36 +04:00
} ;
2007-02-12 11:55:38 +03:00
const struct inode_operations cifs_symlink_inode_ops = {
2007-07-13 04:33:32 +04:00
. readlink = generic_readlink ,
2005-04-17 02:20:36 +04:00
. follow_link = cifs_follow_link ,
. put_link = cifs_put_link ,
. permission = cifs_permission ,
/* BB add the following two eventually */
/* revalidate: cifs_revalidate,
setattr : cifs_notify_change , */ /* BB do we need notify change */
# ifdef CONFIG_CIFS_XATTR
. setxattr = cifs_setxattr ,
. getxattr = cifs_getxattr ,
. listxattr = cifs_listxattr ,
. removexattr = cifs_removexattr ,
2007-07-13 04:33:32 +04:00
# endif
2005-04-17 02:20:36 +04:00
} ;
2006-03-28 13:56:42 +04:00
const struct file_operations cifs_file_ops = {
2005-11-18 04:03:00 +03:00
. read = do_sync_read ,
. write = do_sync_write ,
. aio_read = generic_file_aio_read ,
. aio_write = cifs_file_aio_write ,
2005-04-17 02:20:36 +04:00
. open = cifs_open ,
. release = cifs_close ,
. lock = cifs_lock ,
. fsync = cifs_fsync ,
. flush = cifs_flush ,
. mmap = cifs_file_mmap ,
2007-06-01 13:49:19 +04:00
. splice_read = generic_file_splice_read ,
2006-01-13 01:41:28 +03:00
. llseek = cifs_llseek ,
2005-04-29 09:41:04 +04:00
# ifdef CONFIG_CIFS_POSIX
2008-05-15 09:51:55 +04:00
. unlocked_ioctl = cifs_ioctl ,
2005-04-29 09:41:04 +04:00
# endif /* CONFIG_CIFS_POSIX */
2008-10-23 08:42:37 +04:00
. setlease = cifs_setlease ,
2005-04-17 02:20:36 +04:00
} ;
2006-03-28 13:56:42 +04:00
const struct file_operations cifs_file_direct_ops = {
2009-12-07 08:44:46 +03:00
/* no aio, no readv -
2005-04-17 02:20:36 +04:00
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 ,
2009-12-07 08:44:46 +03:00
. mmap = cifs_file_mmap ,
2007-06-01 13:49:19 +04:00
. splice_read = generic_file_splice_read ,
2005-04-29 09:41:04 +04:00
# ifdef CONFIG_CIFS_POSIX
2008-05-15 09:51:55 +04:00
. unlocked_ioctl = cifs_ioctl ,
2005-04-29 09:41:04 +04:00
# endif /* CONFIG_CIFS_POSIX */
2006-01-13 01:41:28 +03:00
. llseek = cifs_llseek ,
2008-10-23 08:42:37 +04:00
. setlease = cifs_setlease ,
2005-04-17 02:20:36 +04:00
} ;
2006-03-28 13:56:42 +04:00
const struct file_operations cifs_file_nobrl_ops = {
2005-11-18 04:03:00 +03:00
. read = do_sync_read ,
. write = do_sync_write ,
. 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 ,
2007-06-01 13:49:19 +04:00
. splice_read = generic_file_splice_read ,
2006-01-13 01:41:28 +03:00
. llseek = cifs_llseek ,
2005-11-11 22:41:00 +03:00
# ifdef CONFIG_CIFS_POSIX
2008-05-15 09:51:55 +04:00
. unlocked_ioctl = cifs_ioctl ,
2005-11-11 22:41:00 +03:00
# endif /* CONFIG_CIFS_POSIX */
2008-10-23 08:42:37 +04:00
. setlease = cifs_setlease ,
2005-11-11 22:41:00 +03:00
} ;
2006-03-28 13:56:42 +04:00
const struct file_operations cifs_file_direct_nobrl_ops = {
2007-07-13 04:33:32 +04:00
/* no mmap, no aio, no readv -
2005-11-18 04:03:00 +03:00
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 ,
2010-03-27 05:00:49 +03:00
. mmap = cifs_file_mmap ,
2007-06-01 13:49:19 +04:00
. splice_read = generic_file_splice_read ,
2005-11-11 22:41:00 +03:00
# ifdef CONFIG_CIFS_POSIX
2008-05-15 09:51:55 +04:00
. unlocked_ioctl = cifs_ioctl ,
2005-11-11 22:41:00 +03:00
# endif /* CONFIG_CIFS_POSIX */
2006-01-13 01:41:28 +03:00
. llseek = cifs_llseek ,
2008-10-23 08:42:37 +04:00
. setlease = cifs_setlease ,
2005-11-11 22:41:00 +03:00
} ;
2005-04-17 02:20:36 +04:00
2006-03-28 13:56:42 +04:00
const struct file_operations cifs_dir_ops = {
2005-04-17 02:20:36 +04:00
. readdir = cifs_readdir ,
. release = cifs_closedir ,
. read = generic_read_dir ,
2008-05-15 09:51:55 +04:00
. unlocked_ioctl = cifs_ioctl ,
2008-09-03 23:53:01 +04:00
. llseek = generic_file_llseek ,
2005-04-17 02:20:36 +04:00
} ;
static void
2008-07-26 06:45:34 +04:00
cifs_init_once ( void * inode )
2005-04-17 02:20:36 +04:00
{
struct cifsInodeInfo * cifsi = inode ;
2007-05-17 09:10:57 +04:00
inode_init_once ( & cifsi - > vfs_inode ) ;
INIT_LIST_HEAD ( & cifsi - > lockList ) ;
2005-04-17 02:20:36 +04:00
}
static int
cifs_init_inodecache ( void )
{
cifs_inode_cachep = kmem_cache_create ( " cifs_inode_cache " ,
2007-08-31 02:09:15 +04:00
sizeof ( struct cifsInodeInfo ) ,
2006-03-24 14:16:06 +03:00
0 , ( SLAB_RECLAIM_ACCOUNT |
SLAB_MEM_SPREAD ) ,
2007-07-20 05:11:58 +04:00
cifs_init_once ) ;
2005-04-17 02:20:36 +04:00
if ( cifs_inode_cachep = = NULL )
return - ENOMEM ;
return 0 ;
}
static void
cifs_destroy_inodecache ( void )
{
2006-09-27 12:49:40 +04:00
kmem_cache_destroy ( cifs_inode_cachep ) ;
2005-04-17 02:20:36 +04:00
}
static int
cifs_init_request_bufs ( void )
{
2007-05-01 00:13:06 +04:00
if ( CIFSMaxBufSize < 8192 ) {
2005-04-17 02:20:36 +04:00
/* Buffer size can not be smaller than 2 * PATH_MAX since maximum
Unicode path name has to fit in any SMB / CIFS path based frames */
CIFSMaxBufSize = 8192 ;
} else if ( CIFSMaxBufSize > 1024 * 127 ) {
CIFSMaxBufSize = 1024 * 127 ;
} else {
CIFSMaxBufSize & = 0x1FE00 ; /* Round size to even 512 byte mult*/
}
2010-04-21 07:50:45 +04:00
/* cERROR(1, "CIFSMaxBufSize %d 0x%x",CIFSMaxBufSize,CIFSMaxBufSize); */
2005-04-17 02:20:36 +04:00
cifs_req_cachep = kmem_cache_create ( " cifs_request " ,
CIFSMaxBufSize +
MAX_CIFS_HDR_SIZE , 0 ,
2007-07-20 05:11:58 +04:00
SLAB_HWCACHE_ALIGN , NULL ) ;
2005-04-17 02:20:36 +04:00
if ( cifs_req_cachep = = NULL )
return - ENOMEM ;
2007-05-01 00:13:06 +04:00
if ( cifs_min_rcv < 1 )
2005-04-17 02:20:36 +04:00
cifs_min_rcv = 1 ;
else if ( cifs_min_rcv > 64 ) {
cifs_min_rcv = 64 ;
2010-04-21 07:50:45 +04:00
cERROR ( 1 , " cifs_min_rcv set to maximum (64) " ) ;
2005-04-17 02:20:36 +04:00
}
2006-03-26 13:37:50 +04:00
cifs_req_poolp = mempool_create_slab_pool ( cifs_min_rcv ,
cifs_req_cachep ) ;
2005-04-17 02:20:36 +04:00
2007-05-01 00:13:06 +04:00
if ( cifs_req_poolp = = NULL ) {
2005-04-17 02:20:36 +04:00
kmem_cache_destroy ( cifs_req_cachep ) ;
return - ENOMEM ;
}
2005-12-13 07:53:18 +03:00
/* MAX_CIFS_SMALL_BUFFER_SIZE bytes is enough for most SMB responses and
2005-04-17 02:20:36 +04:00
almost all handle based requests ( but not write response , nor is it
sufficient for path based requests ) . A smaller size would have
2007-07-13 04:33:32 +04:00
been more efficient ( compacting multiple slab items on one 4 k page )
2005-04-17 02:20:36 +04:00
for the case in which debug was on , but this larger size allows
more SMBs to use small buffer alloc and is still much more
2007-07-07 03:13:06 +04:00
efficient to alloc 1 per page off the slab compared to 17 K ( 5 page )
2005-04-17 02:20:36 +04:00
alloc of large cifs buffers even when page debugging is on */
cifs_sm_req_cachep = kmem_cache_create ( " cifs_small_rq " ,
2007-07-07 03:13:06 +04:00
MAX_CIFS_SMALL_BUFFER_SIZE , 0 , SLAB_HWCACHE_ALIGN ,
2007-07-20 05:11:58 +04:00
NULL ) ;
2005-04-17 02:20:36 +04:00
if ( cifs_sm_req_cachep = = NULL ) {
mempool_destroy ( cifs_req_poolp ) ;
kmem_cache_destroy ( cifs_req_cachep ) ;
2007-07-07 03:13:06 +04:00
return - ENOMEM ;
2005-04-17 02:20:36 +04:00
}
2007-05-01 00:13:06 +04:00
if ( cifs_min_small < 2 )
2005-04-17 02:20:36 +04:00
cifs_min_small = 2 ;
else if ( cifs_min_small > 256 ) {
cifs_min_small = 256 ;
2010-04-21 07:50:45 +04:00
cFYI ( 1 , " cifs_min_small set to maximum (256) " ) ;
2005-04-17 02:20:36 +04:00
}
2006-03-26 13:37:50 +04:00
cifs_sm_req_poolp = mempool_create_slab_pool ( cifs_min_small ,
cifs_sm_req_cachep ) ;
2005-04-17 02:20:36 +04:00
2007-05-01 00:13:06 +04:00
if ( cifs_sm_req_poolp = = NULL ) {
2005-04-17 02:20:36 +04:00
mempool_destroy ( cifs_req_poolp ) ;
kmem_cache_destroy ( cifs_req_cachep ) ;
kmem_cache_destroy ( cifs_sm_req_cachep ) ;
return - ENOMEM ;
}
return 0 ;
}
static void
cifs_destroy_request_bufs ( void )
{
mempool_destroy ( cifs_req_poolp ) ;
2006-09-27 12:49:40 +04:00
kmem_cache_destroy ( cifs_req_cachep ) ;
2005-04-17 02:20:36 +04:00
mempool_destroy ( cifs_sm_req_poolp ) ;
2006-09-27 12:49:40 +04:00
kmem_cache_destroy ( cifs_sm_req_cachep ) ;
2005-04-17 02:20:36 +04:00
}
static int
cifs_init_mids ( void )
{
cifs_mid_cachep = kmem_cache_create ( " cifs_mpx_ids " ,
2007-08-31 02:09:15 +04:00
sizeof ( struct mid_q_entry ) , 0 ,
SLAB_HWCACHE_ALIGN , NULL ) ;
2005-04-17 02:20:36 +04:00
if ( cifs_mid_cachep = = NULL )
return - ENOMEM ;
2006-03-26 13:37:50 +04:00
/* 3 is a reasonable minimum number of simultaneous operations */
cifs_mid_poolp = mempool_create_slab_pool ( 3 , cifs_mid_cachep ) ;
2007-05-01 00:13:06 +04:00
if ( cifs_mid_poolp = = NULL ) {
2005-04-17 02:20:36 +04:00
kmem_cache_destroy ( cifs_mid_cachep ) ;
return - ENOMEM ;
}
return 0 ;
}
static void
cifs_destroy_mids ( void )
{
mempool_destroy ( cifs_mid_poolp ) ;
2006-09-27 12:49:40 +04:00
kmem_cache_destroy ( cifs_mid_cachep ) ;
2005-04-17 02:20:36 +04:00
}
static int __init
init_cifs ( void )
{
int rc = 0 ;
cifs_proc_init ( ) ;
2008-11-14 21:44:38 +03:00
INIT_LIST_HEAD ( & cifs_tcp_ses_list ) ;
2005-10-11 06:52:13 +04:00
# ifdef CONFIG_CIFS_EXPERIMENTAL
INIT_LIST_HEAD ( & GlobalDnotifyReqList ) ;
INIT_LIST_HEAD ( & GlobalDnotifyRsp_Q ) ;
2007-07-07 03:13:06 +04:00
# endif
2005-04-17 02:20:36 +04:00
/*
* Initialize Global counters
*/
atomic_set ( & sesInfoAllocCount , 0 ) ;
atomic_set ( & tconInfoAllocCount , 0 ) ;
2007-07-07 03:13:06 +04:00
atomic_set ( & tcpSesAllocCount , 0 ) ;
2005-04-17 02:20:36 +04:00
atomic_set ( & tcpSesReconnectCount , 0 ) ;
atomic_set ( & tconInfoReconnectCount , 0 ) ;
atomic_set ( & bufAllocCount , 0 ) ;
2005-12-04 00:58:57 +03:00
atomic_set ( & smBufAllocCount , 0 ) ;
# ifdef CONFIG_CIFS_STATS2
atomic_set ( & totBufAllocCount , 0 ) ;
atomic_set ( & totSmBufAllocCount , 0 ) ;
# endif /* CONFIG_CIFS_STATS2 */
2005-04-17 02:20:36 +04:00
atomic_set ( & midCount , 0 ) ;
GlobalCurrentXid = 0 ;
GlobalTotalActiveXid = 0 ;
GlobalMaxActiveXid = 0 ;
2010-10-18 21:59:37 +04:00
spin_lock_init ( & cifs_tcp_ses_lock ) ;
2010-10-15 23:34:03 +04:00
spin_lock_init ( & cifs_file_list_lock ) ;
2005-04-17 02:20:36 +04:00
spin_lock_init ( & GlobalMid_Lock ) ;
2007-05-01 00:13:06 +04:00
if ( cifs_max_pending < 2 ) {
2005-04-17 02:20:36 +04:00
cifs_max_pending = 2 ;
2010-04-21 07:50:45 +04:00
cFYI ( 1 , " cifs_max_pending set to min of 2 " ) ;
2007-05-01 00:13:06 +04:00
} else if ( cifs_max_pending > 256 ) {
2005-04-17 02:20:36 +04:00
cifs_max_pending = 256 ;
2010-04-21 07:50:45 +04:00
cFYI ( 1 , " cifs_max_pending set to max of 256 " ) ;
2005-04-17 02:20:36 +04:00
}
2010-07-05 16:41:50 +04:00
rc = cifs_fscache_register ( ) ;
if ( rc )
2010-09-22 23:15:36 +04:00
goto out_clean_proc ;
2010-07-05 16:41:50 +04:00
2005-04-17 02:20:36 +04:00
rc = cifs_init_inodecache ( ) ;
2006-04-22 02:52:25 +04:00
if ( rc )
2010-09-22 23:15:36 +04:00
goto out_unreg_fscache ;
2006-04-22 02:52:25 +04:00
rc = cifs_init_mids ( ) ;
if ( rc )
goto out_destroy_inodecache ;
rc = cifs_init_request_bufs ( ) ;
if ( rc )
goto out_destroy_mids ;
rc = register_filesystem ( & cifs_fs_type ) ;
if ( rc )
goto out_destroy_request_bufs ;
2007-11-03 08:02:24 +03:00
# ifdef CONFIG_CIFS_UPCALL
rc = register_key_type ( & cifs_spnego_key_type ) ;
if ( rc )
goto out_unregister_filesystem ;
2008-01-09 19:21:36 +03:00
# endif
2006-04-22 02:52:25 +04:00
return 0 ;
2007-11-03 08:02:24 +03:00
# ifdef CONFIG_CIFS_UPCALL
2010-09-22 23:15:36 +04:00
out_unregister_filesystem :
2006-04-22 02:52:25 +04:00
unregister_filesystem ( & cifs_fs_type ) ;
2010-08-07 23:54:46 +04:00
# endif
2010-09-22 23:15:36 +04:00
out_destroy_request_bufs :
2006-04-22 02:52:25 +04:00
cifs_destroy_request_bufs ( ) ;
2010-09-22 23:15:36 +04:00
out_destroy_mids :
2006-04-22 02:52:25 +04:00
cifs_destroy_mids ( ) ;
2010-09-22 23:15:36 +04:00
out_destroy_inodecache :
2006-04-22 02:52:25 +04:00
cifs_destroy_inodecache ( ) ;
2010-09-22 23:15:36 +04:00
out_unreg_fscache :
2010-07-05 16:41:50 +04:00
cifs_fscache_unregister ( ) ;
2010-09-22 23:15:36 +04:00
out_clean_proc :
cifs_proc_clean ( ) ;
2005-04-17 02:20:36 +04:00
return rc ;
}
static void __exit
exit_cifs ( void )
{
2010-04-21 07:50:45 +04:00
cFYI ( DBG2 , " exit_cifs " ) ;
2005-04-17 02:20:36 +04:00
cifs_proc_clean ( ) ;
2010-07-05 16:41:50 +04:00
cifs_fscache_unregister ( ) ;
2008-01-09 19:21:36 +03:00
# ifdef CONFIG_CIFS_DFS_UPCALL
2008-04-24 12:56:07 +04:00
cifs_dfs_release_automount_timer ( ) ;
2008-01-09 19:21:36 +03:00
# endif
2007-11-03 08:02:24 +03:00
# ifdef CONFIG_CIFS_UPCALL
unregister_key_type ( & cifs_spnego_key_type ) ;
2005-04-17 02:20:36 +04:00
# endif
unregister_filesystem ( & cifs_fs_type ) ;
cifs_destroy_inodecache ( ) ;
cifs_destroy_mids ( ) ;
cifs_destroy_request_bufs ( ) ;
}
MODULE_AUTHOR ( " Steve French <sfrench@us.ibm.com> " ) ;
2007-07-07 03:13:06 +04:00
MODULE_LICENSE ( " GPL " ) ; /* combination of LGPL + GPL source behaves as GPL */
2005-04-17 02:20:36 +04:00
MODULE_DESCRIPTION
2007-07-17 21:34:02 +04:00
( " VFS to access servers complying with the SNIA CIFS Specification "
" e.g. Samba and Windows " ) ;
2005-04-17 02:20:36 +04:00
MODULE_VERSION ( CIFS_VERSION ) ;
module_init ( init_cifs )
module_exit ( exit_cifs )