2006-01-16 19:50:04 +03:00
/*
* Copyright ( C ) Sistina Software , Inc . 1997 - 2003 All rights reserved .
2006-05-18 23:09:15 +04:00
* Copyright ( C ) 2004 - 2006 Red Hat , Inc . All rights reserved .
2006-01-16 19:50:04 +03:00
*
* This copyrighted material is made available to anyone wishing to use ,
* modify , copy , or redistribute it subject to the terms and conditions
2006-09-01 19:05:15 +04:00
* of the GNU General Public License version 2.
2006-01-16 19:50:04 +03:00
*/
# include <linux/slab.h>
# include <linux/spinlock.h>
# include <linux/completion.h>
# include <linux/buffer_head.h>
# include <linux/delay.h>
2006-02-28 01:23:27 +03:00
# include <linux/gfs2_ondisk.h>
2006-09-19 09:56:29 +04:00
# include <linux/lm_interface.h>
2006-01-16 19:50:04 +03:00
# include "gfs2.h"
2006-02-28 01:23:27 +03:00
# include "incore.h"
2006-01-16 19:50:04 +03:00
# include "glock.h"
# include "lm.h"
# include "super.h"
2006-02-28 01:23:27 +03:00
# include "util.h"
2006-01-16 19:50:04 +03:00
/**
* gfs2_lm_mount - mount a locking protocol
* @ sdp : the filesystem
* @ args : mount arguements
* @ silent : if 1 , don ' t complain if the FS isn ' t a GFS2 fs
*
* Returns : errno
*/
int gfs2_lm_mount ( struct gfs2_sbd * sdp , int silent )
{
char * proto = sdp - > sd_proto_name ;
char * table = sdp - > sd_table_name ;
int flags = 0 ;
int error ;
if ( sdp - > sd_args . ar_spectator )
flags | = LM_MFLAG_SPECTATOR ;
fs_info ( sdp , " Trying to join cluster \" %s \" , \" %s \" \n " , proto , table ) ;
error = gfs2_mount_lockproto ( proto , table , sdp - > sd_args . ar_hostdata ,
gfs2_glock_cb , sdp ,
GFS2_MIN_LVB_SIZE , flags ,
& sdp - > sd_lockstruct , & sdp - > sd_kobj ) ;
if ( error ) {
fs_info ( sdp , " can't mount proto=%s, table=%s, hostdata=%s \n " ,
proto , table , sdp - > sd_args . ar_hostdata ) ;
goto out ;
}
if ( gfs2_assert_warn ( sdp , sdp - > sd_lockstruct . ls_lockspace ) | |
gfs2_assert_warn ( sdp , sdp - > sd_lockstruct . ls_ops ) | |
gfs2_assert_warn ( sdp , sdp - > sd_lockstruct . ls_lvb_size > =
GFS2_MIN_LVB_SIZE ) ) {
gfs2_unmount_lockproto ( & sdp - > sd_lockstruct ) ;
goto out ;
}
if ( sdp - > sd_args . ar_spectator )
snprintf ( sdp - > sd_fsname , GFS2_FSNAME_LEN , " %s.s " , table ) ;
else
snprintf ( sdp - > sd_fsname , GFS2_FSNAME_LEN , " %s.%u " , table ,
sdp - > sd_lockstruct . ls_jid ) ;
fs_info ( sdp , " Joined cluster. Now mounting FS... \n " ) ;
if ( ( sdp - > sd_lockstruct . ls_flags & LM_LSFLAG_LOCAL ) & &
! sdp - > sd_args . ar_ignore_local_fs ) {
sdp - > sd_args . ar_localflocks = 1 ;
sdp - > sd_args . ar_localcaching = 1 ;
}
2006-09-04 20:04:26 +04:00
out :
2006-01-16 19:50:04 +03:00
return error ;
}
void gfs2_lm_others_may_mount ( struct gfs2_sbd * sdp )
{
if ( likely ( ! test_bit ( SDF_SHUTDOWN , & sdp - > sd_flags ) ) )
2006-02-27 20:00:42 +03:00
sdp - > sd_lockstruct . ls_ops - > lm_others_may_mount (
sdp - > sd_lockstruct . ls_lockspace ) ;
2006-01-16 19:50:04 +03:00
}
void gfs2_lm_unmount ( struct gfs2_sbd * sdp )
{
if ( likely ( ! test_bit ( SDF_SHUTDOWN , & sdp - > sd_flags ) ) )
gfs2_unmount_lockproto ( & sdp - > sd_lockstruct ) ;
}
int gfs2_lm_withdraw ( struct gfs2_sbd * sdp , char * fmt , . . . )
{
va_list args ;
if ( test_and_set_bit ( SDF_SHUTDOWN , & sdp - > sd_flags ) )
return 0 ;
va_start ( args , fmt ) ;
vprintk ( fmt , args ) ;
va_end ( args ) ;
2006-12-06 20:46:33 +03:00
fs_err ( sdp , " about to withdraw this file system \n " ) ;
2006-02-27 19:00:37 +03:00
BUG_ON ( sdp - > sd_args . ar_debug ) ;
2006-09-25 17:26:04 +04:00
2006-01-16 19:50:04 +03:00
fs_err ( sdp , " telling LM to withdraw \n " ) ;
gfs2_withdraw_lockproto ( & sdp - > sd_lockstruct ) ;
fs_err ( sdp , " withdrawn \n " ) ;
dump_stack ( ) ;
return - 1 ;
}
int gfs2_lm_get_lock ( struct gfs2_sbd * sdp , struct lm_lockname * name ,
2006-09-08 18:17:58 +04:00
void * * lockp )
2006-01-16 19:50:04 +03:00
{
2006-09-04 17:49:55 +04:00
int error = - EIO ;
if ( likely ( ! test_bit ( SDF_SHUTDOWN , & sdp - > sd_flags ) ) )
2006-02-27 20:00:42 +03:00
error = sdp - > sd_lockstruct . ls_ops - > lm_get_lock (
sdp - > sd_lockstruct . ls_lockspace , name , lockp ) ;
2006-01-16 19:50:04 +03:00
return error ;
}
2006-09-08 18:17:58 +04:00
void gfs2_lm_put_lock ( struct gfs2_sbd * sdp , void * lock )
2006-01-16 19:50:04 +03:00
{
if ( likely ( ! test_bit ( SDF_SHUTDOWN , & sdp - > sd_flags ) ) )
sdp - > sd_lockstruct . ls_ops - > lm_put_lock ( lock ) ;
}
2006-09-08 18:17:58 +04:00
unsigned int gfs2_lm_lock ( struct gfs2_sbd * sdp , void * lock ,
2006-01-16 19:50:04 +03:00
unsigned int cur_state , unsigned int req_state ,
unsigned int flags )
{
2006-09-04 17:49:55 +04:00
int ret = 0 ;
if ( likely ( ! test_bit ( SDF_SHUTDOWN , & sdp - > sd_flags ) ) )
ret = sdp - > sd_lockstruct . ls_ops - > lm_lock ( lock , cur_state ,
2006-01-16 19:50:04 +03:00
req_state , flags ) ;
return ret ;
}
2006-09-08 18:17:58 +04:00
unsigned int gfs2_lm_unlock ( struct gfs2_sbd * sdp , void * lock ,
2006-01-16 19:50:04 +03:00
unsigned int cur_state )
{
2006-09-04 17:49:55 +04:00
int ret = 0 ;
if ( likely ( ! test_bit ( SDF_SHUTDOWN , & sdp - > sd_flags ) ) )
2006-01-16 19:50:04 +03:00
ret = sdp - > sd_lockstruct . ls_ops - > lm_unlock ( lock , cur_state ) ;
return ret ;
}
2006-09-08 18:17:58 +04:00
void gfs2_lm_cancel ( struct gfs2_sbd * sdp , void * lock )
2006-01-16 19:50:04 +03:00
{
if ( likely ( ! test_bit ( SDF_SHUTDOWN , & sdp - > sd_flags ) ) )
sdp - > sd_lockstruct . ls_ops - > lm_cancel ( lock ) ;
}
2006-09-08 18:17:58 +04:00
int gfs2_lm_hold_lvb ( struct gfs2_sbd * sdp , void * lock , char * * lvbp )
2006-01-16 19:50:04 +03:00
{
2006-09-04 17:49:55 +04:00
int error = - EIO ;
if ( likely ( ! test_bit ( SDF_SHUTDOWN , & sdp - > sd_flags ) ) )
2006-01-16 19:50:04 +03:00
error = sdp - > sd_lockstruct . ls_ops - > lm_hold_lvb ( lock , lvbp ) ;
return error ;
}
2006-09-08 18:17:58 +04:00
void gfs2_lm_unhold_lvb ( struct gfs2_sbd * sdp , void * lock , char * lvb )
2006-01-16 19:50:04 +03:00
{
if ( likely ( ! test_bit ( SDF_SHUTDOWN , & sdp - > sd_flags ) ) )
sdp - > sd_lockstruct . ls_ops - > lm_unhold_lvb ( lock , lvb ) ;
}
int gfs2_lm_plock_get ( struct gfs2_sbd * sdp , struct lm_lockname * name ,
struct file * file , struct file_lock * fl )
{
2006-09-04 17:49:55 +04:00
int error = - EIO ;
if ( likely ( ! test_bit ( SDF_SHUTDOWN , & sdp - > sd_flags ) ) )
2006-01-16 19:50:04 +03:00
error = sdp - > sd_lockstruct . ls_ops - > lm_plock_get (
2006-09-04 17:49:55 +04:00
sdp - > sd_lockstruct . ls_lockspace , name , file , fl ) ;
2006-01-16 19:50:04 +03:00
return error ;
}
int gfs2_lm_plock ( struct gfs2_sbd * sdp , struct lm_lockname * name ,
struct file * file , int cmd , struct file_lock * fl )
{
2006-09-04 17:49:55 +04:00
int error = - EIO ;
if ( likely ( ! test_bit ( SDF_SHUTDOWN , & sdp - > sd_flags ) ) )
2006-01-16 19:50:04 +03:00
error = sdp - > sd_lockstruct . ls_ops - > lm_plock (
2006-09-04 17:49:55 +04:00
sdp - > sd_lockstruct . ls_lockspace , name , file , cmd , fl ) ;
2006-01-16 19:50:04 +03:00
return error ;
}
int gfs2_lm_punlock ( struct gfs2_sbd * sdp , struct lm_lockname * name ,
struct file * file , struct file_lock * fl )
{
2006-09-04 17:49:55 +04:00
int error = - EIO ;
if ( likely ( ! test_bit ( SDF_SHUTDOWN , & sdp - > sd_flags ) ) )
2006-01-16 19:50:04 +03:00
error = sdp - > sd_lockstruct . ls_ops - > lm_punlock (
2006-09-04 17:49:55 +04:00
sdp - > sd_lockstruct . ls_lockspace , name , file , fl ) ;
2006-01-16 19:50:04 +03:00
return error ;
}
void gfs2_lm_recovery_done ( struct gfs2_sbd * sdp , unsigned int jid ,
unsigned int message )
{
if ( likely ( ! test_bit ( SDF_SHUTDOWN , & sdp - > sd_flags ) ) )
2006-02-27 20:00:42 +03:00
sdp - > sd_lockstruct . ls_ops - > lm_recovery_done (
sdp - > sd_lockstruct . ls_lockspace , jid , message ) ;
2006-01-16 19:50:04 +03:00
}