109c434b8SThomas Gleixner // SPDX-License-Identifier: GPL-2.0-only
2575e9461SMike Marshall /*
3575e9461SMike Marshall * (C) 2001 Clemson University and The University of Chicago
4575e9461SMike Marshall *
5575e9461SMike Marshall * Changes by Acxiom Corporation to add proc file handler for pvfs2 client
6575e9461SMike Marshall * parameters, Copyright Acxiom Corporation, 2005.
7575e9461SMike Marshall *
8575e9461SMike Marshall * See COPYING in top-level directory.
9575e9461SMike Marshall */
10575e9461SMike Marshall
11575e9461SMike Marshall #include "protocol.h"
12575e9461SMike Marshall #include "orangefs-kernel.h"
13575e9461SMike Marshall #include "orangefs-debugfs.h"
14575e9461SMike Marshall #include "orangefs-sysfs.h"
15575e9461SMike Marshall
16575e9461SMike Marshall /* ORANGEFS_VERSION is a ./configure define */
17575e9461SMike Marshall #ifndef ORANGEFS_VERSION
184c27b327SMike Marshall #define ORANGEFS_VERSION "upstream"
19575e9461SMike Marshall #endif
20575e9461SMike Marshall
21575e9461SMike Marshall /*
22575e9461SMike Marshall * global variables declared here
23575e9461SMike Marshall */
24575e9461SMike Marshall
25889d5f1bSMartin Brandenburg struct orangefs_stats orangefs_stats;
26575e9461SMike Marshall
27575e9461SMike Marshall /* the size of the hash tables for ops in progress */
28575e9461SMike Marshall int hash_table_size = 509;
29575e9461SMike Marshall
30575e9461SMike Marshall static ulong module_parm_debug_mask;
3144f46410SMartin Brandenburg __u64 orangefs_gossip_debug_mask;
32575e9461SMike Marshall int op_timeout_secs = ORANGEFS_DEFAULT_OP_TIMEOUT_SECS;
33575e9461SMike Marshall int slot_timeout_secs = ORANGEFS_DEFAULT_SLOT_TIMEOUT_SECS;
34211f9f2eSMike Marshall int orangefs_cache_timeout_msecs = 500;
351d503617SMartin Brandenburg int orangefs_dcache_timeout_msecs = 50;
361d503617SMartin Brandenburg int orangefs_getattr_timeout_msecs = 50;
37575e9461SMike Marshall
38575e9461SMike Marshall MODULE_LICENSE("GPL");
39575e9461SMike Marshall MODULE_AUTHOR("ORANGEFS Development Team");
40575e9461SMike Marshall MODULE_DESCRIPTION("The Linux Kernel VFS interface to ORANGEFS");
41575e9461SMike Marshall MODULE_PARM_DESC(module_parm_debug_mask, "debugging level (see orangefs-debug.h for values)");
42575e9461SMike Marshall MODULE_PARM_DESC(op_timeout_secs, "Operation timeout in seconds");
43575e9461SMike Marshall MODULE_PARM_DESC(slot_timeout_secs, "Slot timeout in seconds");
44575e9461SMike Marshall MODULE_PARM_DESC(hash_table_size,
45575e9461SMike Marshall "size of hash table for operations in progress");
46575e9461SMike Marshall
47575e9461SMike Marshall static struct file_system_type orangefs_fs_type = {
48575e9461SMike Marshall .name = "pvfs2",
49575e9461SMike Marshall .mount = orangefs_mount,
50575e9461SMike Marshall .kill_sb = orangefs_kill_sb,
51575e9461SMike Marshall .owner = THIS_MODULE,
52575e9461SMike Marshall };
53575e9461SMike Marshall
54575e9461SMike Marshall module_param(hash_table_size, int, 0);
55575e9461SMike Marshall module_param(module_parm_debug_mask, ulong, 0644);
56575e9461SMike Marshall module_param(op_timeout_secs, int, 0);
57575e9461SMike Marshall module_param(slot_timeout_secs, int, 0);
58575e9461SMike Marshall
59575e9461SMike Marshall /*
60575e9461SMike Marshall * Blocks non-priority requests from being queued for servicing. This
61575e9461SMike Marshall * could be used for protecting the request list data structure, but
62575e9461SMike Marshall * for now it's only being used to stall the op addition to the request
63575e9461SMike Marshall * list
64575e9461SMike Marshall */
651d503617SMartin Brandenburg DEFINE_MUTEX(orangefs_request_mutex);
66575e9461SMike Marshall
67575e9461SMike Marshall /* hash table for storing operations waiting for matching downcall */
681d503617SMartin Brandenburg struct list_head *orangefs_htable_ops_in_progress;
691d503617SMartin Brandenburg DEFINE_SPINLOCK(orangefs_htable_ops_in_progress_lock);
70575e9461SMike Marshall
71575e9461SMike Marshall /* list for queueing upcall operations */
72575e9461SMike Marshall LIST_HEAD(orangefs_request_list);
73575e9461SMike Marshall
74575e9461SMike Marshall /* used to protect the above orangefs_request_list */
75575e9461SMike Marshall DEFINE_SPINLOCK(orangefs_request_list_lock);
76575e9461SMike Marshall
77575e9461SMike Marshall /* used for incoming request notification */
78575e9461SMike Marshall DECLARE_WAIT_QUEUE_HEAD(orangefs_request_list_waitq);
79575e9461SMike Marshall
orangefs_init(void)80575e9461SMike Marshall static int __init orangefs_init(void)
81575e9461SMike Marshall {
8222ce8561SColin Ian King int ret;
83575e9461SMike Marshall __u32 i = 0;
84575e9461SMike Marshall
85575e9461SMike Marshall if (op_timeout_secs < 0)
86575e9461SMike Marshall op_timeout_secs = 0;
87575e9461SMike Marshall
88575e9461SMike Marshall if (slot_timeout_secs < 0)
89575e9461SMike Marshall slot_timeout_secs = 0;
90575e9461SMike Marshall
91575e9461SMike Marshall /* initialize global book keeping data structures */
92575e9461SMike Marshall ret = op_cache_initialize();
93575e9461SMike Marshall if (ret < 0)
9470823b9bSJan Kara goto out;
95575e9461SMike Marshall
96575e9461SMike Marshall ret = orangefs_inode_cache_initialize();
97575e9461SMike Marshall if (ret < 0)
982d4cae0dSMike Marshall goto cleanup_op;
99575e9461SMike Marshall
1001d503617SMartin Brandenburg orangefs_htable_ops_in_progress =
101575e9461SMike Marshall kcalloc(hash_table_size, sizeof(struct list_head), GFP_KERNEL);
1021d503617SMartin Brandenburg if (!orangefs_htable_ops_in_progress) {
103575e9461SMike Marshall ret = -ENOMEM;
1042f83ace3SMartin Brandenburg goto cleanup_inode;
105575e9461SMike Marshall }
106575e9461SMike Marshall
107575e9461SMike Marshall /* initialize a doubly linked at each hash table index */
108575e9461SMike Marshall for (i = 0; i < hash_table_size; i++)
1091d503617SMartin Brandenburg INIT_LIST_HEAD(&orangefs_htable_ops_in_progress[i]);
110575e9461SMike Marshall
111575e9461SMike Marshall ret = fsid_key_table_initialize();
112575e9461SMike Marshall if (ret < 0)
113575e9461SMike Marshall goto cleanup_progress_table;
114575e9461SMike Marshall
115575e9461SMike Marshall /*
116575e9461SMike Marshall * Build the contents of /sys/kernel/debug/orangefs/debug-help
117575e9461SMike Marshall * from the keywords in the kernel keyword/mask array.
118575e9461SMike Marshall *
119575e9461SMike Marshall * The keywords in the client keyword/mask array are
120575e9461SMike Marshall * unknown at boot time.
121575e9461SMike Marshall *
122575e9461SMike Marshall * orangefs_prepare_debugfs_help_string will be used again
123dc033621SMike Marshall * later to rebuild the debug-help-string after the client starts
124575e9461SMike Marshall * and passes along the needed info. The argument signifies
125575e9461SMike Marshall * which time orangefs_prepare_debugfs_help_string is being
126575e9461SMike Marshall * called.
127575e9461SMike Marshall */
128575e9461SMike Marshall ret = orangefs_prepare_debugfs_help_string(1);
129575e9461SMike Marshall if (ret)
1301a0ce16dSMike Marshall goto cleanup_key_table;
131575e9461SMike Marshall
1320979cf95SGreg Kroah-Hartman orangefs_debugfs_init(module_parm_debug_mask);
1332180c52cSMike Marshall
1342180c52cSMike Marshall ret = orangefs_sysfs_init();
1352180c52cSMike Marshall if (ret)
1362180c52cSMike Marshall goto sysfs_init_failed;
137575e9461SMike Marshall
1382f83ace3SMartin Brandenburg /* Initialize the orangefsdev subsystem. */
1392f83ace3SMartin Brandenburg ret = orangefs_dev_init();
1402f83ace3SMartin Brandenburg if (ret < 0) {
1412f83ace3SMartin Brandenburg gossip_err("%s: could not initialize device subsystem %d!\n",
1422f83ace3SMartin Brandenburg __func__,
1432f83ace3SMartin Brandenburg ret);
144*ea60a4adSZhang Xiaoxu goto cleanup_sysfs;
1452f83ace3SMartin Brandenburg }
1462f83ace3SMartin Brandenburg
147575e9461SMike Marshall ret = register_filesystem(&orangefs_fs_type);
148575e9461SMike Marshall if (ret == 0) {
149dc033621SMike Marshall pr_info("%s: module version %s loaded\n",
150dc033621SMike Marshall __func__,
151dc033621SMike Marshall ORANGEFS_VERSION);
1522180c52cSMike Marshall goto out;
153575e9461SMike Marshall }
154575e9461SMike Marshall
1552f83ace3SMartin Brandenburg orangefs_dev_cleanup();
1562f83ace3SMartin Brandenburg
157*ea60a4adSZhang Xiaoxu cleanup_sysfs:
158*ea60a4adSZhang Xiaoxu orangefs_sysfs_exit();
159*ea60a4adSZhang Xiaoxu
1602180c52cSMike Marshall sysfs_init_failed:
1612180c52cSMike Marshall orangefs_debugfs_cleanup();
1622180c52cSMike Marshall
1631a0ce16dSMike Marshall cleanup_key_table:
1641a0ce16dSMike Marshall fsid_key_table_finalize();
1652180c52cSMike Marshall
166575e9461SMike Marshall cleanup_progress_table:
1671d503617SMartin Brandenburg kfree(orangefs_htable_ops_in_progress);
168575e9461SMike Marshall
169575e9461SMike Marshall cleanup_inode:
170575e9461SMike Marshall orangefs_inode_cache_finalize();
171575e9461SMike Marshall
172575e9461SMike Marshall cleanup_op:
173575e9461SMike Marshall op_cache_finalize();
174575e9461SMike Marshall
175575e9461SMike Marshall out:
176575e9461SMike Marshall return ret;
177575e9461SMike Marshall }
178575e9461SMike Marshall
orangefs_exit(void)179575e9461SMike Marshall static void __exit orangefs_exit(void)
180575e9461SMike Marshall {
181575e9461SMike Marshall int i = 0;
182575e9461SMike Marshall gossip_debug(GOSSIP_INIT_DEBUG, "orangefs: orangefs_exit called\n");
183575e9461SMike Marshall
184575e9461SMike Marshall unregister_filesystem(&orangefs_fs_type);
185575e9461SMike Marshall orangefs_debugfs_cleanup();
186575e9461SMike Marshall orangefs_sysfs_exit();
187575e9461SMike Marshall fsid_key_table_finalize();
188575e9461SMike Marshall orangefs_dev_cleanup();
18996acf9d6SAl Viro BUG_ON(!list_empty(&orangefs_request_list));
190575e9461SMike Marshall for (i = 0; i < hash_table_size; i++)
1911d503617SMartin Brandenburg BUG_ON(!list_empty(&orangefs_htable_ops_in_progress[i]));
192575e9461SMike Marshall
193575e9461SMike Marshall orangefs_inode_cache_finalize();
194575e9461SMike Marshall op_cache_finalize();
195575e9461SMike Marshall
1961d503617SMartin Brandenburg kfree(orangefs_htable_ops_in_progress);
197575e9461SMike Marshall
198575e9461SMike Marshall pr_info("orangefs: module version %s unloaded\n", ORANGEFS_VERSION);
199575e9461SMike Marshall }
200575e9461SMike Marshall
201575e9461SMike Marshall /*
202575e9461SMike Marshall * What we do in this function is to walk the list of operations
203575e9461SMike Marshall * that are in progress in the hash table and mark them as purged as well.
204575e9461SMike Marshall */
purge_inprogress_ops(void)205575e9461SMike Marshall void purge_inprogress_ops(void)
206575e9461SMike Marshall {
207575e9461SMike Marshall int i;
208575e9461SMike Marshall
209575e9461SMike Marshall for (i = 0; i < hash_table_size; i++) {
210575e9461SMike Marshall struct orangefs_kernel_op_s *op;
211575e9461SMike Marshall struct orangefs_kernel_op_s *next;
212575e9461SMike Marshall
2131d503617SMartin Brandenburg spin_lock(&orangefs_htable_ops_in_progress_lock);
214575e9461SMike Marshall list_for_each_entry_safe(op,
215575e9461SMike Marshall next,
2161d503617SMartin Brandenburg &orangefs_htable_ops_in_progress[i],
217575e9461SMike Marshall list) {
218575e9461SMike Marshall set_op_state_purged(op);
2199d9e7ba9SMike Marshall gossip_debug(GOSSIP_DEV_DEBUG,
2209d9e7ba9SMike Marshall "%s: op:%s: op_state:%d: process:%s:\n",
2219d9e7ba9SMike Marshall __func__,
2229d9e7ba9SMike Marshall get_opname_string(op),
2239d9e7ba9SMike Marshall op->op_state,
2249d9e7ba9SMike Marshall current->comm);
225575e9461SMike Marshall }
2261d503617SMartin Brandenburg spin_unlock(&orangefs_htable_ops_in_progress_lock);
227575e9461SMike Marshall }
228575e9461SMike Marshall }
229575e9461SMike Marshall
230575e9461SMike Marshall module_init(orangefs_init);
231575e9461SMike Marshall module_exit(orangefs_exit);
232