2015-07-17 17:38:15 +03:00
/*
* ( C ) 2001 Clemson University and The University of Chicago
*
* See COPYING in top - level directory .
*/
# include "protocol.h"
2015-12-04 20:56:14 +03:00
# include "orangefs-kernel.h"
# include "orangefs-bufmap.h"
2015-07-17 17:38:15 +03:00
# include <linux/parser.h>
2015-11-24 23:12:14 +03:00
/* a cache for orangefs-inode objects (i.e. orangefs inode private data) */
static struct kmem_cache * orangefs_inode_cache ;
2015-07-17 17:38:15 +03:00
2015-11-24 23:12:14 +03:00
/* list for storing orangefs specific superblocks in use */
LIST_HEAD ( orangefs_superblocks ) ;
2015-07-17 17:38:15 +03:00
2015-11-24 23:12:14 +03:00
DEFINE_SPINLOCK ( orangefs_superblocks_lock ) ;
2015-07-17 17:38:15 +03:00
enum {
Opt_intr ,
Opt_acl ,
Opt_local_lock ,
Opt_err
} ;
static const match_table_t tokens = {
{ Opt_acl , " acl " } ,
{ Opt_intr , " intr " } ,
{ Opt_local_lock , " local_lock " } ,
{ Opt_err , NULL }
} ;
static int parse_mount_options ( struct super_block * sb , char * options ,
int silent )
{
2015-11-24 23:12:14 +03:00
struct orangefs_sb_info_s * orangefs_sb = ORANGEFS_SB ( sb ) ;
2015-07-17 17:38:15 +03:00
substring_t args [ MAX_OPT_ARGS ] ;
char * p ;
/*
* Force any potential flags that might be set from the mount
* to zero , ie , initialize to unset .
*/
sb - > s_flags & = ~ MS_POSIXACL ;
2015-11-24 23:12:14 +03:00
orangefs_sb - > flags & = ~ ORANGEFS_OPT_INTR ;
orangefs_sb - > flags & = ~ ORANGEFS_OPT_LOCAL_LOCK ;
2015-07-17 17:38:15 +03:00
while ( ( p = strsep ( & options , " , " ) ) ! = NULL ) {
int token ;
if ( ! * p )
continue ;
token = match_token ( p , tokens , args ) ;
switch ( token ) {
case Opt_acl :
sb - > s_flags | = MS_POSIXACL ;
break ;
case Opt_intr :
2015-11-24 23:12:14 +03:00
orangefs_sb - > flags | = ORANGEFS_OPT_INTR ;
2015-07-17 17:38:15 +03:00
break ;
case Opt_local_lock :
2015-11-24 23:12:14 +03:00
orangefs_sb - > flags | = ORANGEFS_OPT_LOCAL_LOCK ;
2015-07-17 17:38:15 +03:00
break ;
default :
goto fail ;
}
}
return 0 ;
fail :
if ( ! silent )
gossip_err ( " Error: mount option [%s] is not supported. \n " , p ) ;
return - EINVAL ;
}
2015-11-24 23:12:14 +03:00
static void orangefs_inode_cache_ctor ( void * req )
2015-07-17 17:38:15 +03:00
{
2015-11-24 23:12:14 +03:00
struct orangefs_inode_s * orangefs_inode = req ;
2015-07-17 17:38:15 +03:00
2015-11-24 23:12:14 +03:00
inode_init_once ( & orangefs_inode - > vfs_inode ) ;
init_rwsem ( & orangefs_inode - > xattr_sem ) ;
2015-07-17 17:38:15 +03:00
2015-11-24 23:12:14 +03:00
orangefs_inode - > vfs_inode . i_version = 1 ;
2015-07-17 17:38:15 +03:00
}
2015-11-24 23:12:14 +03:00
static struct inode * orangefs_alloc_inode ( struct super_block * sb )
2015-07-17 17:38:15 +03:00
{
2015-11-24 23:12:14 +03:00
struct orangefs_inode_s * orangefs_inode ;
2015-07-17 17:38:15 +03:00
2016-02-04 21:48:16 +03:00
orangefs_inode = kmem_cache_alloc ( orangefs_inode_cache , GFP_KERNEL ) ;
2015-11-24 23:12:14 +03:00
if ( orangefs_inode = = NULL ) {
gossip_err ( " Failed to allocate orangefs_inode \n " ) ;
2015-07-17 17:38:15 +03:00
return NULL ;
}
/*
* We want to clear everything except for rw_semaphore and the
* vfs_inode .
*/
2015-11-24 23:12:14 +03:00
memset ( & orangefs_inode - > refn . khandle , 0 , 16 ) ;
orangefs_inode - > refn . fs_id = ORANGEFS_FS_ID_NULL ;
orangefs_inode - > last_failed_block_index_read = 0 ;
memset ( orangefs_inode - > link_target , 0 , sizeof ( orangefs_inode - > link_target ) ) ;
orangefs_inode - > pinode_flags = 0 ;
2015-07-17 17:38:15 +03:00
gossip_debug ( GOSSIP_SUPER_DEBUG ,
2015-11-24 23:12:14 +03:00
" orangefs_alloc_inode: allocated %p \n " ,
& orangefs_inode - > vfs_inode ) ;
return & orangefs_inode - > vfs_inode ;
2015-07-17 17:38:15 +03:00
}
2015-11-24 23:12:14 +03:00
static void orangefs_destroy_inode ( struct inode * inode )
2015-07-17 17:38:15 +03:00
{
2015-11-24 23:12:14 +03:00
struct orangefs_inode_s * orangefs_inode = ORANGEFS_I ( inode ) ;
2015-07-17 17:38:15 +03:00
gossip_debug ( GOSSIP_SUPER_DEBUG ,
" %s: deallocated %p destroying inode %pU \n " ,
2015-11-24 23:12:14 +03:00
__func__ , orangefs_inode , get_khandle_from_ino ( inode ) ) ;
2015-07-17 17:38:15 +03:00
2015-11-24 23:12:14 +03:00
kmem_cache_free ( orangefs_inode_cache , orangefs_inode ) ;
2015-07-17 17:38:15 +03:00
}
/*
* NOTE : information filled in here is typically reflected in the
* output of the system command ' df '
*/
2015-11-24 23:12:14 +03:00
static int orangefs_statfs ( struct dentry * dentry , struct kstatfs * buf )
2015-07-17 17:38:15 +03:00
{
int ret = - ENOMEM ;
2015-11-24 23:12:14 +03:00
struct orangefs_kernel_op_s * new_op = NULL ;
2015-07-17 17:38:15 +03:00
int flags = 0 ;
struct super_block * sb = NULL ;
sb = dentry - > d_sb ;
gossip_debug ( GOSSIP_SUPER_DEBUG ,
2015-11-24 23:12:14 +03:00
" orangefs_statfs: called on sb %p (fs_id is %d) \n " ,
2015-07-17 17:38:15 +03:00
sb ,
2015-11-24 23:12:14 +03:00
( int ) ( ORANGEFS_SB ( sb ) - > fs_id ) ) ;
2015-07-17 17:38:15 +03:00
2015-11-24 23:12:14 +03:00
new_op = op_alloc ( ORANGEFS_VFS_OP_STATFS ) ;
2015-07-17 17:38:15 +03:00
if ( ! new_op )
return ret ;
2015-11-24 23:12:14 +03:00
new_op - > upcall . req . statfs . fs_id = ORANGEFS_SB ( sb ) - > fs_id ;
2015-07-17 17:38:15 +03:00
2015-11-24 23:12:14 +03:00
if ( ORANGEFS_SB ( sb ) - > flags & ORANGEFS_OPT_INTR )
flags = ORANGEFS_OP_INTERRUPTIBLE ;
2015-07-17 17:38:15 +03:00
2015-11-24 23:12:14 +03:00
ret = service_operation ( new_op , " orangefs_statfs " , flags ) ;
2015-07-17 17:38:15 +03:00
if ( new_op - > downcall . status < 0 )
goto out_op_release ;
gossip_debug ( GOSSIP_SUPER_DEBUG ,
2016-01-13 19:38:14 +03:00
" %s: got %ld blocks available | "
" %ld blocks total | %ld block size | "
" %ld files total | %ld files avail \n " ,
__func__ ,
2015-07-17 17:38:15 +03:00
( long ) new_op - > downcall . resp . statfs . blocks_avail ,
( long ) new_op - > downcall . resp . statfs . blocks_total ,
2016-01-13 19:38:14 +03:00
( long ) new_op - > downcall . resp . statfs . block_size ,
( long ) new_op - > downcall . resp . statfs . files_total ,
( long ) new_op - > downcall . resp . statfs . files_avail ) ;
2015-07-17 17:38:15 +03:00
buf - > f_type = sb - > s_magic ;
2015-11-24 23:12:14 +03:00
memcpy ( & buf - > f_fsid , & ORANGEFS_SB ( sb ) - > fs_id , sizeof ( buf - > f_fsid ) ) ;
2015-07-17 17:38:15 +03:00
buf - > f_bsize = new_op - > downcall . resp . statfs . block_size ;
2015-11-24 23:12:14 +03:00
buf - > f_namelen = ORANGEFS_NAME_LEN ;
2015-07-17 17:38:15 +03:00
buf - > f_blocks = ( sector_t ) new_op - > downcall . resp . statfs . blocks_total ;
buf - > f_bfree = ( sector_t ) new_op - > downcall . resp . statfs . blocks_avail ;
buf - > f_bavail = ( sector_t ) new_op - > downcall . resp . statfs . blocks_avail ;
buf - > f_files = ( sector_t ) new_op - > downcall . resp . statfs . files_total ;
buf - > f_ffree = ( sector_t ) new_op - > downcall . resp . statfs . files_avail ;
buf - > f_frsize = sb - > s_blocksize ;
out_op_release :
op_release ( new_op ) ;
2015-11-24 23:12:14 +03:00
gossip_debug ( GOSSIP_SUPER_DEBUG , " orangefs_statfs: returning %d \n " , ret ) ;
2015-07-17 17:38:15 +03:00
return ret ;
}
/*
* Remount as initiated by VFS layer . We just need to reparse the mount
* options , no need to signal pvfs2 - client - core about it .
*/
2015-11-24 23:12:14 +03:00
static int orangefs_remount_fs ( struct super_block * sb , int * flags , char * data )
2015-07-17 17:38:15 +03:00
{
2015-11-24 23:12:14 +03:00
gossip_debug ( GOSSIP_SUPER_DEBUG , " orangefs_remount_fs: called \n " ) ;
2015-07-17 17:38:15 +03:00
return parse_mount_options ( sb , data , 1 ) ;
}
/*
* Remount as initiated by pvfs2 - client - core on restart . This is used to
* repopulate mount information left from previous pvfs2 - client - core .
*
* the idea here is that given a valid superblock , we ' re
* re - initializing the user space client with the initial mount
* information specified when the super block was first initialized .
* this is very different than the first initialization / creation of a
* superblock . we use the special service_priority_operation to make
* sure that the mount gets ahead of any other pending operation that
* is waiting for servicing . this means that the pvfs2 - client won ' t
* fail to start several times for all other pending operations before
* the client regains all of the mount information from us .
* NOTE : this function assumes that the request_mutex is already acquired !
*/
2015-11-24 23:12:14 +03:00
int orangefs_remount ( struct super_block * sb )
2015-07-17 17:38:15 +03:00
{
2015-11-24 23:12:14 +03:00
struct orangefs_kernel_op_s * new_op ;
2015-07-17 17:38:15 +03:00
int ret = - EINVAL ;
2015-11-24 23:12:14 +03:00
gossip_debug ( GOSSIP_SUPER_DEBUG , " orangefs_remount: called \n " ) ;
2015-07-17 17:38:15 +03:00
2015-11-24 23:12:14 +03:00
new_op = op_alloc ( ORANGEFS_VFS_OP_FS_MOUNT ) ;
2015-07-17 17:38:15 +03:00
if ( ! new_op )
return - ENOMEM ;
2015-11-24 23:12:14 +03:00
strncpy ( new_op - > upcall . req . fs_mount . orangefs_config_server ,
ORANGEFS_SB ( sb ) - > devname ,
ORANGEFS_MAX_SERVER_ADDR_LEN ) ;
2015-07-17 17:38:15 +03:00
gossip_debug ( GOSSIP_SUPER_DEBUG ,
2015-11-24 23:12:14 +03:00
" Attempting ORANGEFS Remount via host %s \n " ,
new_op - > upcall . req . fs_mount . orangefs_config_server ) ;
2015-07-17 17:38:15 +03:00
/*
2016-02-25 00:54:27 +03:00
* we assume that the calling function has already acquired the
2015-07-17 17:38:15 +03:00
* request_mutex to prevent other operations from bypassing
* this one
*/
2015-11-24 23:12:14 +03:00
ret = service_operation ( new_op , " orangefs_remount " ,
2016-02-25 00:54:27 +03:00
ORANGEFS_OP_PRIORITY | ORANGEFS_OP_NO_MUTEX ) ;
2015-07-17 17:38:15 +03:00
gossip_debug ( GOSSIP_SUPER_DEBUG ,
2015-11-24 23:12:14 +03:00
" orangefs_remount: mount got return value of %d \n " ,
2015-07-17 17:38:15 +03:00
ret ) ;
if ( ret = = 0 ) {
/*
* store the id assigned to this sb - - it ' s just a
* short - lived mapping that the system interface uses
* to map this superblock to a particular mount entry
*/
2015-11-24 23:12:14 +03:00
ORANGEFS_SB ( sb ) - > id = new_op - > downcall . resp . fs_mount . id ;
ORANGEFS_SB ( sb ) - > mount_pending = 0 ;
2015-07-17 17:38:15 +03:00
}
op_release ( new_op ) ;
return ret ;
}
int fsid_key_table_initialize ( void )
{
return 0 ;
}
void fsid_key_table_finalize ( void )
{
}
/* Called whenever the VFS dirties the inode in response to atime updates */
2015-11-24 23:12:14 +03:00
static void orangefs_dirty_inode ( struct inode * inode , int flags )
2015-07-17 17:38:15 +03:00
{
2015-11-24 23:12:14 +03:00
struct orangefs_inode_s * orangefs_inode = ORANGEFS_I ( inode ) ;
2015-07-17 17:38:15 +03:00
gossip_debug ( GOSSIP_SUPER_DEBUG ,
2015-11-24 23:12:14 +03:00
" orangefs_dirty_inode: %pU \n " ,
2015-07-17 17:38:15 +03:00
get_khandle_from_ino ( inode ) ) ;
2015-11-24 23:12:14 +03:00
SetAtimeFlag ( orangefs_inode ) ;
2015-07-17 17:38:15 +03:00
}
2015-11-24 23:12:14 +03:00
static const struct super_operations orangefs_s_ops = {
. alloc_inode = orangefs_alloc_inode ,
. destroy_inode = orangefs_destroy_inode ,
. dirty_inode = orangefs_dirty_inode ,
2015-07-17 17:38:15 +03:00
. drop_inode = generic_delete_inode ,
2015-11-24 23:12:14 +03:00
. statfs = orangefs_statfs ,
. remount_fs = orangefs_remount_fs ,
2015-07-17 17:38:15 +03:00
. show_options = generic_show_options ,
} ;
2015-11-24 23:12:14 +03:00
static struct dentry * orangefs_fh_to_dentry ( struct super_block * sb ,
2015-07-17 17:38:15 +03:00
struct fid * fid ,
int fh_len ,
int fh_type )
{
2015-11-24 23:12:14 +03:00
struct orangefs_object_kref refn ;
2015-07-17 17:38:15 +03:00
if ( fh_len < 5 | | fh_type > 2 )
return NULL ;
2015-11-24 23:12:14 +03:00
ORANGEFS_khandle_from ( & ( refn . khandle ) , fid - > raw , 16 ) ;
2015-07-17 17:38:15 +03:00
refn . fs_id = ( u32 ) fid - > raw [ 4 ] ;
gossip_debug ( GOSSIP_SUPER_DEBUG ,
" fh_to_dentry: handle %pU, fs_id %d \n " ,
& refn . khandle ,
refn . fs_id ) ;
2015-11-24 23:12:14 +03:00
return d_obtain_alias ( orangefs_iget ( sb , & refn ) ) ;
2015-07-17 17:38:15 +03:00
}
2015-11-24 23:12:14 +03:00
static int orangefs_encode_fh ( struct inode * inode ,
2015-07-17 17:38:15 +03:00
__u32 * fh ,
int * max_len ,
struct inode * parent )
{
int len = parent ? 10 : 5 ;
int type = 1 ;
2015-11-24 23:12:14 +03:00
struct orangefs_object_kref refn ;
2015-07-17 17:38:15 +03:00
if ( * max_len < len ) {
gossip_lerr ( " fh buffer is too small for encoding \n " ) ;
* max_len = len ;
type = 255 ;
goto out ;
}
2015-11-24 23:12:14 +03:00
refn = ORANGEFS_I ( inode ) - > refn ;
ORANGEFS_khandle_to ( & refn . khandle , fh , 16 ) ;
2015-07-17 17:38:15 +03:00
fh [ 4 ] = refn . fs_id ;
gossip_debug ( GOSSIP_SUPER_DEBUG ,
" Encoding fh: handle %pU, fsid %u \n " ,
& refn . khandle ,
refn . fs_id ) ;
if ( parent ) {
2015-11-24 23:12:14 +03:00
refn = ORANGEFS_I ( parent ) - > refn ;
ORANGEFS_khandle_to ( & refn . khandle , ( char * ) fh + 20 , 16 ) ;
2015-07-17 17:38:15 +03:00
fh [ 9 ] = refn . fs_id ;
type = 2 ;
gossip_debug ( GOSSIP_SUPER_DEBUG ,
" Encoding parent: handle %pU, fsid %u \n " ,
& refn . khandle ,
refn . fs_id ) ;
}
* max_len = len ;
out :
return type ;
}
2016-01-01 12:01:52 +03:00
static const struct export_operations orangefs_export_ops = {
2015-11-24 23:12:14 +03:00
. encode_fh = orangefs_encode_fh ,
. fh_to_dentry = orangefs_fh_to_dentry ,
2015-07-17 17:38:15 +03:00
} ;
2015-11-24 23:12:14 +03:00
static int orangefs_fill_sb ( struct super_block * sb ,
struct orangefs_fs_mount_response * fs_mount ,
2015-10-09 03:22:43 +03:00
void * data , int silent )
2015-07-17 17:38:15 +03:00
{
int ret = - EINVAL ;
struct inode * root = NULL ;
struct dentry * root_dentry = NULL ;
2015-11-24 23:12:14 +03:00
struct orangefs_object_kref root_object ;
2015-07-17 17:38:15 +03:00
2015-11-24 23:12:14 +03:00
/* alloc and init our private orangefs sb info */
2015-07-17 17:38:15 +03:00
sb - > s_fs_info =
2015-11-24 23:12:14 +03:00
kzalloc ( sizeof ( struct orangefs_sb_info_s ) , ORANGEFS_GFP_FLAGS ) ;
if ( ! ORANGEFS_SB ( sb ) )
2015-07-17 17:38:15 +03:00
return - ENOMEM ;
2015-11-24 23:12:14 +03:00
ORANGEFS_SB ( sb ) - > sb = sb ;
2015-07-17 17:38:15 +03:00
2015-11-24 23:12:14 +03:00
ORANGEFS_SB ( sb ) - > root_khandle = fs_mount - > root_khandle ;
ORANGEFS_SB ( sb ) - > fs_id = fs_mount - > fs_id ;
ORANGEFS_SB ( sb ) - > id = fs_mount - > id ;
2015-07-17 17:38:15 +03:00
2015-10-09 03:22:43 +03:00
if ( data ) {
ret = parse_mount_options ( sb , data , silent ) ;
2015-07-17 17:38:15 +03:00
if ( ret )
return ret ;
}
/* Hang the xattr handlers off the superblock */
2015-11-24 23:12:14 +03:00
sb - > s_xattr = orangefs_xattr_handlers ;
sb - > s_magic = ORANGEFS_SUPER_MAGIC ;
sb - > s_op = & orangefs_s_ops ;
sb - > s_d_op = & orangefs_dentry_operations ;
2015-07-17 17:38:15 +03:00
2015-11-24 23:12:14 +03:00
sb - > s_blocksize = orangefs_bufmap_size_query ( ) ;
sb - > s_blocksize_bits = orangefs_bufmap_shift_query ( ) ;
2015-07-17 17:38:15 +03:00
sb - > s_maxbytes = MAX_LFS_FILESIZE ;
2015-11-24 23:12:14 +03:00
root_object . khandle = ORANGEFS_SB ( sb ) - > root_khandle ;
root_object . fs_id = ORANGEFS_SB ( sb ) - > fs_id ;
2015-07-17 17:38:15 +03:00
gossip_debug ( GOSSIP_SUPER_DEBUG ,
" get inode %pU, fsid %d \n " ,
& root_object . khandle ,
root_object . fs_id ) ;
2015-11-24 23:12:14 +03:00
root = orangefs_iget ( sb , & root_object ) ;
2015-07-17 17:38:15 +03:00
if ( IS_ERR ( root ) )
return PTR_ERR ( root ) ;
gossip_debug ( GOSSIP_SUPER_DEBUG ,
" Allocated root inode [%p] with mode %x \n " ,
root ,
root - > i_mode ) ;
/* allocates and places root dentry in dcache */
root_dentry = d_make_root ( root ) ;
2015-10-09 03:18:00 +03:00
if ( ! root_dentry )
2015-07-17 17:38:15 +03:00
return - ENOMEM ;
2015-11-24 23:12:14 +03:00
sb - > s_export_op = & orangefs_export_ops ;
2015-07-17 17:38:15 +03:00
sb - > s_root = root_dentry ;
return 0 ;
}
2015-11-24 23:12:14 +03:00
struct dentry * orangefs_mount ( struct file_system_type * fst ,
2015-07-17 17:38:15 +03:00
int flags ,
const char * devname ,
void * data )
{
int ret = - EINVAL ;
struct super_block * sb = ERR_PTR ( - EINVAL ) ;
2015-11-24 23:12:14 +03:00
struct orangefs_kernel_op_s * new_op ;
2015-09-29 22:26:37 +03:00
struct dentry * d = ERR_PTR ( - EINVAL ) ;
2015-07-17 17:38:15 +03:00
gossip_debug ( GOSSIP_SUPER_DEBUG ,
2015-11-24 23:12:14 +03:00
" orangefs_mount: called with devname %s \n " ,
2015-07-17 17:38:15 +03:00
devname ) ;
if ( ! devname ) {
gossip_err ( " ERROR: device name not specified. \n " ) ;
return ERR_PTR ( - EINVAL ) ;
}
2015-11-24 23:12:14 +03:00
new_op = op_alloc ( ORANGEFS_VFS_OP_FS_MOUNT ) ;
2015-07-17 17:38:15 +03:00
if ( ! new_op )
return ERR_PTR ( - ENOMEM ) ;
2015-11-24 23:12:14 +03:00
strncpy ( new_op - > upcall . req . fs_mount . orangefs_config_server ,
2015-07-17 17:38:15 +03:00
devname ,
2015-11-24 23:12:14 +03:00
ORANGEFS_MAX_SERVER_ADDR_LEN ) ;
2015-07-17 17:38:15 +03:00
gossip_debug ( GOSSIP_SUPER_DEBUG ,
2015-11-24 23:12:14 +03:00
" Attempting ORANGEFS Mount via host %s \n " ,
new_op - > upcall . req . fs_mount . orangefs_config_server ) ;
2015-07-17 17:38:15 +03:00
2015-11-24 23:12:14 +03:00
ret = service_operation ( new_op , " orangefs_mount " , 0 ) ;
2015-07-17 17:38:15 +03:00
gossip_debug ( GOSSIP_SUPER_DEBUG ,
2015-11-24 23:12:14 +03:00
" orangefs_mount: mount got return value of %d \n " , ret ) ;
2015-07-17 17:38:15 +03:00
if ( ret )
goto free_op ;
2015-11-24 23:12:14 +03:00
if ( new_op - > downcall . resp . fs_mount . fs_id = = ORANGEFS_FS_ID_NULL ) {
2015-07-17 17:38:15 +03:00
gossip_err ( " ERROR: Retrieved null fs_id \n " ) ;
ret = - EINVAL ;
goto free_op ;
}
2015-09-29 22:26:37 +03:00
sb = sget ( fst , NULL , set_anon_super , flags , NULL ) ;
if ( IS_ERR ( sb ) ) {
d = ERR_CAST ( sb ) ;
2015-07-17 17:38:15 +03:00
goto free_op ;
}
2015-11-24 23:12:14 +03:00
ret = orangefs_fill_sb ( sb ,
2015-10-09 03:22:43 +03:00
& new_op - > downcall . resp . fs_mount , data ,
2015-09-29 22:26:37 +03:00
flags & MS_SILENT ? 1 : 0 ) ;
if ( ret ) {
d = ERR_PTR ( ret ) ;
goto free_op ;
}
2015-07-17 17:38:15 +03:00
/*
* on successful mount , store the devname and data
* used
*/
2015-11-24 23:12:14 +03:00
strncpy ( ORANGEFS_SB ( sb ) - > devname ,
2015-07-17 17:38:15 +03:00
devname ,
2015-11-24 23:12:14 +03:00
ORANGEFS_MAX_SERVER_ADDR_LEN ) ;
2015-07-17 17:38:15 +03:00
/* mount_pending must be cleared */
2015-11-24 23:12:14 +03:00
ORANGEFS_SB ( sb ) - > mount_pending = 0 ;
2015-07-17 17:38:15 +03:00
/*
2015-11-24 23:12:14 +03:00
* finally , add this sb to our list of known orangefs
2015-07-17 17:38:15 +03:00
* sb ' s
*/
2015-11-24 23:12:14 +03:00
add_orangefs_sb ( sb ) ;
2015-07-17 17:38:15 +03:00
op_release ( new_op ) ;
2015-09-29 22:26:37 +03:00
return dget ( sb - > s_root ) ;
2015-07-17 17:38:15 +03:00
free_op :
2015-11-24 23:12:14 +03:00
gossip_err ( " orangefs_mount: mount request failed with %d \n " , ret ) ;
2015-07-17 17:38:15 +03:00
if ( ret = = - EINVAL ) {
2015-11-24 23:12:14 +03:00
gossip_err ( " Ensure that all orangefs-servers have the same FS configuration files \n " ) ;
2015-07-17 17:38:15 +03:00
gossip_err ( " Look at pvfs2-client-core log file (typically /tmp/pvfs2-client.log) for more details \n " ) ;
}
op_release ( new_op ) ;
2015-09-29 22:26:37 +03:00
return d ;
2015-07-17 17:38:15 +03:00
}
2015-11-24 23:12:14 +03:00
void orangefs_kill_sb ( struct super_block * sb )
2015-07-17 17:38:15 +03:00
{
2015-11-24 23:12:14 +03:00
gossip_debug ( GOSSIP_SUPER_DEBUG , " orangefs_kill_sb: called \n " ) ;
2015-07-17 17:38:15 +03:00
/*
* issue the unmount to userspace to tell it to remove the
* dynamic mount info it has for this superblock
*/
2015-11-24 23:12:14 +03:00
orangefs_unmount_sb ( sb ) ;
2015-07-17 17:38:15 +03:00
2015-11-24 23:12:14 +03:00
/* remove the sb from our list of orangefs specific sb's */
remove_orangefs_sb ( sb ) ;
2015-07-17 17:38:15 +03:00
/* provided sb cleanup */
kill_anon_super ( sb ) ;
2015-11-24 23:12:14 +03:00
/* free the orangefs superblock private data */
kfree ( ORANGEFS_SB ( sb ) ) ;
2015-07-17 17:38:15 +03:00
}
2015-11-24 23:12:14 +03:00
int orangefs_inode_cache_initialize ( void )
2015-07-17 17:38:15 +03:00
{
2015-11-24 23:12:14 +03:00
orangefs_inode_cache = kmem_cache_create ( " orangefs_inode_cache " ,
sizeof ( struct orangefs_inode_s ) ,
2015-07-17 17:38:15 +03:00
0 ,
2015-11-24 23:12:14 +03:00
ORANGEFS_CACHE_CREATE_FLAGS ,
orangefs_inode_cache_ctor ) ;
2015-07-17 17:38:15 +03:00
2015-11-24 23:12:14 +03:00
if ( ! orangefs_inode_cache ) {
gossip_err ( " Cannot create orangefs_inode_cache \n " ) ;
2015-07-17 17:38:15 +03:00
return - ENOMEM ;
}
return 0 ;
}
2015-11-24 23:12:14 +03:00
int orangefs_inode_cache_finalize ( void )
2015-07-17 17:38:15 +03:00
{
2015-11-24 23:12:14 +03:00
kmem_cache_destroy ( orangefs_inode_cache ) ;
2015-07-17 17:38:15 +03:00
return 0 ;
}