From: Jeff Mahoney <jeffm@suse.com>
Subject: xfs/dmapi: Initialize the function pointer vector statically
Patch-mainline: Depends on DMAPI

 xfs_dm_get_dmapiops() re-initializes the static function pointer vector
 every time it is called, and it's called a lot. There's a static
 variable that probably was intended to make this happen once but it's
 never actually set to something nonzero, so it gets set up every time.

 The static array is overwritten every time the function is called, without
 locking. Since it is always overwritten with the same contents, we don't
 run into problems. It's still wrong.

 This patch initializes the array with named members and just passes back
 the pointer without changing anything.

Signed-off-by: Jeff Mahoney <jeffm@suse.com>
---
 fs/xfs/dmapi/xfs_dm.c |  233 +++++++++++++++++++++++++++++++-------------------
 1 file changed, 147 insertions(+), 86 deletions(-)

--- a/fs/xfs/dmapi/xfs_dm.c
+++ b/fs/xfs/dmapi/xfs_dm.c
@@ -2708,100 +2708,161 @@ xfs_dm_obj_ref_hold(
 }
 
 
-static fsys_function_vector_t	xfs_fsys_vector[DM_FSYS_MAX];
-
+static fsys_function_vector_t xfs_fsys_vector[DM_FSYS_MAX] = {
+	{
+	  .func_no = DM_FSYS_CLEAR_INHERIT,
+	  .u_fc.clear_inherit = xfs_dm_clear_inherit,
+	},
+	{
+	  .func_no = DM_FSYS_CREATE_BY_HANDLE,
+	  .u_fc.create_by_handle = xfs_dm_create_by_handle,
+	},
+	{
+	  .func_no = DM_FSYS_DOWNGRADE_RIGHT,
+	  .u_fc.downgrade_right = xfs_dm_downgrade_right,
+	},
+	{
+	  .func_no = DM_FSYS_GET_ALLOCINFO_RVP,
+	  .u_fc.get_allocinfo_rvp = xfs_dm_get_allocinfo_rvp,
+	},
+	{
+	  .func_no = DM_FSYS_GET_BULKALL_RVP,
+	  .u_fc.get_bulkall_rvp = xfs_dm_get_bulkall_rvp,
+	},
+	{
+	  .func_no = DM_FSYS_GET_BULKATTR_RVP,
+	  .u_fc.get_bulkattr_rvp = xfs_dm_get_bulkattr_rvp,
+	},
+	{
+	  .func_no = DM_FSYS_GET_CONFIG,
+	  .u_fc.get_config = xfs_dm_get_config,
+	},
+	{
+	  .func_no = DM_FSYS_GET_CONFIG_EVENTS,
+	  .u_fc.get_config_events = xfs_dm_get_config_events,
+	},
+	{
+	  .func_no = DM_FSYS_GET_DESTROY_DMATTR,
+	  .u_fc.get_destroy_dmattr = xfs_dm_get_destroy_dmattr,
+	},
+	{
+	  .func_no = DM_FSYS_GET_DIOINFO,
+	  .u_fc.get_dioinfo = xfs_dm_get_dioinfo,
+	},
+	{
+	  .func_no = DM_FSYS_GET_DIRATTRS_RVP,
+	  .u_fc.get_dirattrs_rvp = xfs_dm_get_dirattrs_rvp,
+	},
+	{
+	  .func_no = DM_FSYS_GET_DMATTR,
+	  .u_fc.get_dmattr = xfs_dm_get_dmattr,
+	},
+	{
+	  .func_no = DM_FSYS_GET_EVENTLIST,
+	  .u_fc.get_eventlist = xfs_dm_get_eventlist,
+	},
+	{
+	  .func_no = DM_FSYS_GET_FILEATTR,
+	  .u_fc.get_fileattr = xfs_dm_get_fileattr,
+	},
+	{
+	  .func_no = DM_FSYS_GET_REGION,
+	  .u_fc.get_region = xfs_dm_get_region,
+	},
+	{
+	  .func_no = DM_FSYS_GETALL_DMATTR,
+	  .u_fc.getall_dmattr = xfs_dm_getall_dmattr,
+	},
+	{
+	  .func_no = DM_FSYS_GETALL_INHERIT,
+	  .u_fc.getall_inherit = xfs_dm_getall_inherit,
+	},
+	{
+	  .func_no = DM_FSYS_INIT_ATTRLOC,
+	  .u_fc.init_attrloc = xfs_dm_init_attrloc,
+	},
+	{
+	  .func_no = DM_FSYS_MKDIR_BY_HANDLE,
+	  .u_fc.mkdir_by_handle = xfs_dm_mkdir_by_handle,
+	},
+	{
+	  .func_no = DM_FSYS_PROBE_HOLE,
+	  .u_fc.probe_hole = xfs_dm_probe_hole,
+	},
+	{
+	  .func_no = DM_FSYS_PUNCH_HOLE,
+	  .u_fc.punch_hole = xfs_dm_punch_hole,
+	},
+	{
+	  .func_no = DM_FSYS_READ_INVIS_RVP,
+	  .u_fc.read_invis_rvp = xfs_dm_read_invis_rvp,
+	},
+	{
+	  .func_no = DM_FSYS_RELEASE_RIGHT,
+	  .u_fc.release_right = xfs_dm_release_right,
+	},
+	{
+	  .func_no = DM_FSYS_REMOVE_DMATTR,
+	  .u_fc.remove_dmattr = xfs_dm_remove_dmattr,
+	},
+	{
+	  .func_no = DM_FSYS_REQUEST_RIGHT,
+	  .u_fc.request_right = xfs_dm_request_right,
+	},
+	{
+	  .func_no = DM_FSYS_SET_DMATTR,
+	  .u_fc.set_dmattr = xfs_dm_set_dmattr,
+	},
+	{
+	  .func_no = DM_FSYS_SET_EVENTLIST,
+	  .u_fc.set_eventlist = xfs_dm_set_eventlist,
+	},
+	{
+	  .func_no = DM_FSYS_SET_FILEATTR,
+	  .u_fc.set_fileattr = xfs_dm_set_fileattr,
+	},
+	{
+	  .func_no = DM_FSYS_SET_INHERIT,
+	  .u_fc.set_inherit = xfs_dm_set_inherit,
+	},
+	{
+	  .func_no = DM_FSYS_SET_REGION,
+	  .u_fc.set_region = xfs_dm_set_region,
+	},
+	{
+	  .func_no = DM_FSYS_SYMLINK_BY_HANDLE,
+	  .u_fc.symlink_by_handle = xfs_dm_symlink_by_handle,
+	},
+	{
+	  .func_no = DM_FSYS_SYNC_BY_HANDLE,
+	  .u_fc.sync_by_handle = xfs_dm_sync_by_handle,
+	},
+	{
+	  .func_no = DM_FSYS_UPGRADE_RIGHT,
+	  .u_fc.upgrade_right = xfs_dm_upgrade_right,
+	},
+	{
+	  .func_no = DM_FSYS_WRITE_INVIS_RVP,
+	  .u_fc.write_invis_rvp = xfs_dm_write_invis_rvp,
+	},
+	{
+	  .func_no = DM_FSYS_OBJ_REF_HOLD,
+	  .u_fc.obj_ref_hold = xfs_dm_obj_ref_hold,
+	},
+};
 
 STATIC int
 xfs_dm_get_dmapiops(
 	struct super_block	*sb,
 	void			*addr)
 {
-	static	int		initialized = 0;
-	dm_fcntl_vector_t	*vecrq;
-	fsys_function_vector_t	*vecp;
-	int			i = 0;
-
-	vecrq = (dm_fcntl_vector_t *)addr;
-	vecrq->count =
-		sizeof(xfs_fsys_vector) / sizeof(xfs_fsys_vector[0]);
-	vecrq->vecp = xfs_fsys_vector;
-	if (initialized)
-		return(0);
-	vecrq->code_level = DM_CLVL_XOPEN;
-	vecp = xfs_fsys_vector;
+	dm_fcntl_vector_t	*vecrq = (dm_fcntl_vector_t *)addr;
 
-	vecp[i].func_no = DM_FSYS_CLEAR_INHERIT;
-	vecp[i++].u_fc.clear_inherit = xfs_dm_clear_inherit;
-	vecp[i].func_no = DM_FSYS_CREATE_BY_HANDLE;
-	vecp[i++].u_fc.create_by_handle = xfs_dm_create_by_handle;
-	vecp[i].func_no = DM_FSYS_DOWNGRADE_RIGHT;
-	vecp[i++].u_fc.downgrade_right = xfs_dm_downgrade_right;
-	vecp[i].func_no = DM_FSYS_GET_ALLOCINFO_RVP;
-	vecp[i++].u_fc.get_allocinfo_rvp = xfs_dm_get_allocinfo_rvp;
-	vecp[i].func_no = DM_FSYS_GET_BULKALL_RVP;
-	vecp[i++].u_fc.get_bulkall_rvp = xfs_dm_get_bulkall_rvp;
-	vecp[i].func_no = DM_FSYS_GET_BULKATTR_RVP;
-	vecp[i++].u_fc.get_bulkattr_rvp = xfs_dm_get_bulkattr_rvp;
-	vecp[i].func_no = DM_FSYS_GET_CONFIG;
-	vecp[i++].u_fc.get_config = xfs_dm_get_config;
-	vecp[i].func_no = DM_FSYS_GET_CONFIG_EVENTS;
-	vecp[i++].u_fc.get_config_events = xfs_dm_get_config_events;
-	vecp[i].func_no = DM_FSYS_GET_DESTROY_DMATTR;
-	vecp[i++].u_fc.get_destroy_dmattr = xfs_dm_get_destroy_dmattr;
-	vecp[i].func_no = DM_FSYS_GET_DIOINFO;
-	vecp[i++].u_fc.get_dioinfo = xfs_dm_get_dioinfo;
-	vecp[i].func_no = DM_FSYS_GET_DIRATTRS_RVP;
-	vecp[i++].u_fc.get_dirattrs_rvp = xfs_dm_get_dirattrs_rvp;
-	vecp[i].func_no = DM_FSYS_GET_DMATTR;
-	vecp[i++].u_fc.get_dmattr = xfs_dm_get_dmattr;
-	vecp[i].func_no = DM_FSYS_GET_EVENTLIST;
-	vecp[i++].u_fc.get_eventlist = xfs_dm_get_eventlist;
-	vecp[i].func_no = DM_FSYS_GET_FILEATTR;
-	vecp[i++].u_fc.get_fileattr = xfs_dm_get_fileattr;
-	vecp[i].func_no = DM_FSYS_GET_REGION;
-	vecp[i++].u_fc.get_region = xfs_dm_get_region;
-	vecp[i].func_no = DM_FSYS_GETALL_DMATTR;
-	vecp[i++].u_fc.getall_dmattr = xfs_dm_getall_dmattr;
-	vecp[i].func_no = DM_FSYS_GETALL_INHERIT;
-	vecp[i++].u_fc.getall_inherit = xfs_dm_getall_inherit;
-	vecp[i].func_no = DM_FSYS_INIT_ATTRLOC;
-	vecp[i++].u_fc.init_attrloc = xfs_dm_init_attrloc;
-	vecp[i].func_no = DM_FSYS_MKDIR_BY_HANDLE;
-	vecp[i++].u_fc.mkdir_by_handle = xfs_dm_mkdir_by_handle;
-	vecp[i].func_no = DM_FSYS_PROBE_HOLE;
-	vecp[i++].u_fc.probe_hole = xfs_dm_probe_hole;
-	vecp[i].func_no = DM_FSYS_PUNCH_HOLE;
-	vecp[i++].u_fc.punch_hole = xfs_dm_punch_hole;
-	vecp[i].func_no = DM_FSYS_READ_INVIS_RVP;
-	vecp[i++].u_fc.read_invis_rvp = xfs_dm_read_invis_rvp;
-	vecp[i].func_no = DM_FSYS_RELEASE_RIGHT;
-	vecp[i++].u_fc.release_right = xfs_dm_release_right;
-	vecp[i].func_no = DM_FSYS_REMOVE_DMATTR;
-	vecp[i++].u_fc.remove_dmattr = xfs_dm_remove_dmattr;
-	vecp[i].func_no = DM_FSYS_REQUEST_RIGHT;
-	vecp[i++].u_fc.request_right = xfs_dm_request_right;
-	vecp[i].func_no = DM_FSYS_SET_DMATTR;
-	vecp[i++].u_fc.set_dmattr = xfs_dm_set_dmattr;
-	vecp[i].func_no = DM_FSYS_SET_EVENTLIST;
-	vecp[i++].u_fc.set_eventlist = xfs_dm_set_eventlist;
-	vecp[i].func_no = DM_FSYS_SET_FILEATTR;
-	vecp[i++].u_fc.set_fileattr = xfs_dm_set_fileattr;
-	vecp[i].func_no = DM_FSYS_SET_INHERIT;
-	vecp[i++].u_fc.set_inherit = xfs_dm_set_inherit;
-	vecp[i].func_no = DM_FSYS_SET_REGION;
-	vecp[i++].u_fc.set_region = xfs_dm_set_region;
-	vecp[i].func_no = DM_FSYS_SYMLINK_BY_HANDLE;
-	vecp[i++].u_fc.symlink_by_handle = xfs_dm_symlink_by_handle;
-	vecp[i].func_no = DM_FSYS_SYNC_BY_HANDLE;
-	vecp[i++].u_fc.sync_by_handle = xfs_dm_sync_by_handle;
-	vecp[i].func_no = DM_FSYS_UPGRADE_RIGHT;
-	vecp[i++].u_fc.upgrade_right = xfs_dm_upgrade_right;
-	vecp[i].func_no = DM_FSYS_WRITE_INVIS_RVP;
-	vecp[i++].u_fc.write_invis_rvp = xfs_dm_write_invis_rvp;
-	vecp[i].func_no = DM_FSYS_OBJ_REF_HOLD;
-	vecp[i++].u_fc.obj_ref_hold = xfs_dm_obj_ref_hold;
+	vecrq->code_level = DM_CLVL_XOPEN;
+	vecrq->count = ARRAY_SIZE(xfs_fsys_vector);
+	vecrq->vecp = xfs_fsys_vector;
 
-	return(0);
+	return 0 ;
 }
 
 

