2 * Copyright 2000, International Business Machines Corporation and others.
5 * This software has been released under the terms of the IBM Public
6 * License. For details, see the LICENSE file in the top-level source
7 * directory or online at http://www.openafs.org/dl/license10.html
11 * Linux module support routines.
14 #include <afsconfig.h>
15 #include "afs/param.h"
18 #include <linux/module.h> /* early to avoid printf->printk mapping */
19 #ifdef HAVE_LINUX_SEQ_FILE_H
20 # include <linux/seq_file.h>
22 #include "afs/sysincludes.h"
23 #include "afsincludes.h"
24 #include "afs/nfsclient.h"
25 #include <linux/unistd.h> /* For syscall numbers. */
28 #ifdef AFS_AMD64_LINUX20_ENV
29 # include <asm/ia32_unistd.h>
32 #include <linux/slab.h>
33 #include <linux/init.h>
34 #include <linux/sched.h>
35 #include <linux/kernel.h>
37 #include "osi_compat.h"
39 struct proc_dir_entry
*openafs_procfs
;
41 #ifdef HAVE_LINUX_SEQ_FILE_H
43 c_start(struct seq_file
*m
, loff_t
*pos
)
45 struct afs_q
*cq
, *tq
;
49 ObtainReadLock(&afs_xcell
);
50 for (cq
= CellLRU
.next
; cq
!= &CellLRU
; cq
= tq
) {
64 c_next(struct seq_file
*m
, void *p
, loff_t
*pos
)
66 struct afs_q
*cq
= p
, *tq
;
80 c_stop(struct seq_file
*m
, void *p
)
83 ReleaseReadLock(&afs_xcell
);
88 c_show(struct seq_file
*m
, void *p
)
91 struct cell
*tc
= QTOC(cq
);
94 seq_printf(m
, ">%s #(%d/%d)\n", tc
->cellName
,
95 tc
->cellNum
, tc
->cellIndex
);
97 for (j
= 0; j
< AFS_MAXCELLHOSTS
; j
++) {
100 if (!tc
->cellHosts
[j
]) break;
102 addr
= tc
->cellHosts
[j
]->addr
->sa_ip
;
104 seq_printf(m
, "%u.%u.%u.%u #%u.%u.%u.%u\n",
105 NIPQUAD(addr
), NIPQUAD(addr
));
107 seq_printf(m
, "%pI4 #%pI4\n", &addr
, &addr
);
114 static struct seq_operations afs_csdb_op
= {
122 afs_csdb_open(struct inode
*inode
, struct file
*file
)
124 return seq_open(file
, &afs_csdb_op
);
127 static struct file_operations afs_csdb_operations
= {
128 .open
= afs_csdb_open
,
131 .release
= seq_release
,
135 uu_start(struct seq_file
*m
, loff_t
*pos
)
143 ObtainReadLock(&afs_xuser
);
152 for (i
= 0; i
< NUSERS
; i
++) {
153 for (tu
= afs_users
[i
]; tu
; tu
= tu
->next
) {
167 uu_next(struct seq_file
*m
, void *p
, loff_t
*pos
)
169 struct unixuser
*tu
= p
;
175 if (p
!= (void *)1) {
176 if (tu
->next
) return tu
->next
;
177 i
= UHash(tu
->uid
) + 1;
180 for (; i
< NUSERS
; i
++)
181 if (afs_users
[i
]) return afs_users
[i
];
186 uu_stop(struct seq_file
*m
, void *p
)
189 ReleaseReadLock(&afs_xuser
);
194 uu_show(struct seq_file
*m
, void *p
)
197 struct unixuser
*tu
= p
;
198 union tokenUnion
*token
;
201 if (p
== (void *)1) {
202 seq_printf(m
, "%10s %4s %-6s %-25s %10s",
203 "UID/PAG", "Refs", "States", "Cell", "ViceID");
204 seq_printf(m
, " %10s %10s %10s %3s",
205 "Tok Set", "Tok Begin", "Tok Expire", "vno");
206 seq_printf(m
, " %-15s %10s %10s %s\n",
207 "NFS Client", "UID/PAG", "Client UID", "Sysname(s)");
215 ReleaseReadLock(&afs_xuser
);
217 afs_LockUser(tu
, READ_LOCK
, 0);
219 if (tu
->cell
== -1) {
220 cellname
= "<default>";
222 tc
= afs_GetCellStale(tu
->cell
, READ_LOCK
);
223 if (tc
) cellname
= tc
->cellName
;
224 else cellname
= "<unknown>";
227 seq_printf(m
, "%10d %4d %04x %-25s %10d",
228 tu
->uid
, tu
->refCount
, tu
->states
, cellname
, tu
->viceId
);
230 if (tc
) afs_PutCell(tc
, READ_LOCK
);
232 if (tu
->states
& UHasTokens
) {
233 token
= afs_FindToken(tu
->tokens
, RX_SECIDX_KAD
);
234 seq_printf(m
, " %10d %10d %10d %3d",
236 (token
!=NULL
)?token
->rxkad
.clearToken
.BeginTimestamp
:0,
237 (token
!=NULL
)?token
->rxkad
.clearToken
.EndTimestamp
:0,
238 (token
!=NULL
)?token
->rxkad
.clearToken
.AuthHandle
:0);
240 seq_printf(m
, " %-36s", "Tokens Not Set");
243 if (tu
->exporter
&& tu
->exporter
->exp_type
== EXP_NFS
) {
244 struct nfsclientpag
*np
= (struct nfsclientpag
*)(tu
->exporter
);
249 sprintf(ipaddr
, "%u.%u.%u.%u", NIPQUAD(np
->host
));
251 sprintf(ipaddr
, "%pI4", &np
->host
);
253 seq_printf(m
, " %-15s %10d %10d", ipaddr
, np
->uid
, np
->client_uid
);
254 if (np
->sysnamecount
) {
255 for (i
= 0; i
< np
->sysnamecount
; i
++)
256 seq_printf(m
, " %s", np
->sysname
[i
]);
258 seq_printf(m
, " <no sysname list>");
261 } else if (tu
->exporter
) {
262 seq_printf(m
, " Unknown exporter type %d", tu
->exporter
->exp_type
);
266 afs_PutUser(tu
, READ_LOCK
);
267 ObtainReadLock(&afs_xuser
);
274 static struct seq_operations afs_unixuser_seqop
= {
282 afs_unixuser_open(struct inode
*inode
, struct file
*file
)
284 return seq_open(file
, &afs_unixuser_seqop
);
287 static struct file_operations afs_unixuser_fops
= {
288 .open
= afs_unixuser_open
,
291 .release
= seq_release
,
295 #else /* HAVE_LINUX_SEQ_FILE_H */
298 csdbproc_info(char *buffer
, char **start
, off_t offset
, int length
)
303 struct afs_q
*cq
, *tq
;
306 /* 90 - 64 cellname, 10 for 32 bit num and index, plus
313 ObtainReadLock(&afs_xcell
);
315 for (cq
= CellLRU
.next
; cq
!= &CellLRU
; cq
= tq
) {
316 tc
= QTOC(cq
); tq
= QNext(cq
);
323 sprintf(temp
, ">%s #(%d/%d)\n", tc
->cellName
,
324 tc
->cellNum
, tc
->cellIndex
);
325 sprintf(buffer
+ len
, "%-89s\n", temp
);
327 if (pos
>= offset
+length
) {
328 ReleaseReadLock(&afs_xcell
);
333 for (cnt
= 0; cnt
< AFS_MAXCELLHOSTS
; cnt
++) {
334 if (!tc
->cellHosts
[cnt
]) break;
339 addr
= ntohl(tc
->cellHosts
[cnt
]->addr
->sa_ip
);
340 sprintf(tbuffer
, "%d.%d.%d.%d",
341 (int)((addr
>>24) & 0xff),
342 (int)((addr
>>16) & 0xff),
343 (int)((addr
>>8) & 0xff), (int)( addr
& 0xff));
344 sprintf(temp
, "%s #%s\n", tbuffer
, tbuffer
);
345 sprintf(buffer
+ len
, "%-89s\n", temp
);
347 if (pos
>= offset
+length
) {
348 ReleaseReadLock(&afs_xcell
);
355 ReleaseReadLock(&afs_xcell
);
360 *start
= buffer
+ len
- (pos
- offset
);
367 #endif /* HAVE_LINUX_SEQ_FILE_H */
372 struct proc_dir_entry
*entry
;
373 #if !defined(EXPORTED_PROC_ROOT_FS)
377 #if defined(EXPORTED_PROC_ROOT_FS)
378 openafs_procfs
= proc_mkdir(PROC_FSDIRNAME
, proc_root_fs
);
380 sprintf(path
, "fs/%s", PROC_FSDIRNAME
);
381 openafs_procfs
= proc_mkdir(path
, NULL
);
383 #ifdef HAVE_LINUX_SEQ_FILE_H
384 entry
= afs_proc_create("unixusers", 0, openafs_procfs
, &afs_unixuser_fops
);
385 # if defined(STRUCT_PROC_DIR_ENTRY_HAS_OWNER)
387 entry
->owner
= THIS_MODULE
;
389 entry
= afs_proc_create(PROC_CELLSERVDB_NAME
, 0, openafs_procfs
, &afs_csdb_operations
);
391 entry
= create_proc_info_entry(PROC_CELLSERVDB_NAME
, (S_IFREG
|S_IRUGO
), openafs_procfs
, csdbproc_info
);
393 #if defined(STRUCT_PROC_DIR_ENTRY_HAS_OWNER)
395 entry
->owner
= THIS_MODULE
;
402 #if !defined(EXPORTED_PROC_ROOT_FS)
406 remove_proc_entry(PROC_CELLSERVDB_NAME
, openafs_procfs
);
407 #ifdef HAVE_LINUX_SEQ_FILE_H
408 remove_proc_entry("unixusers", openafs_procfs
);
410 #if defined(EXPORTED_PROC_ROOT_FS)
411 remove_proc_entry(PROC_FSDIRNAME
, proc_root_fs
);
413 sprintf(path
, "fs/%s", PROC_FSDIRNAME
);
414 remove_proc_entry(path
, NULL
);