#include <linux/sched.h>
#endif
+#ifdef HAVE_KERNEL_LINUX_SEQ_FILE_H
+#include <linux/seq_file.h>
+#endif
+
extern struct file_system_type afs_fs_type;
#if !defined(AFS_LINUX24_ENV)
unsigned long afs_linux_page_offset = 0; /* contains the PAGE_OFFSET value */
#endif
-
-static int afs_ioctl(struct inode *, struct file *, unsigned int,
+static inline int afs_ioctl(struct inode *, struct file *, unsigned int,
unsigned long);
+#if defined(HAVE_UNLOCKED_IOCTL) || defined(HAVE_COMPAT_IOCTL)
+static long afs_unlocked_ioctl(struct file *, unsigned int, unsigned long);
+#endif
static struct file_operations afs_syscall_fops = {
+#ifdef HAVE_UNLOCKED_IOCTL
+ .unlocked_ioctl = afs_unlocked_ioctl,
+#else
.ioctl = afs_ioctl,
+#endif
+#ifdef HAVE_COMPAT_IOCTL
+ .compat_ioctl = afs_unlocked_ioctl,
+#endif
+};
+
+#ifdef HAVE_KERNEL_LINUX_SEQ_FILE_H
+static void *c_start(struct seq_file *m, loff_t *pos)
+{
+ struct afs_q *cq, *tq;
+ loff_t n = 0;
+
+ ObtainReadLock(&afs_xcell);
+ for (cq = CellLRU.next; cq != &CellLRU; cq = tq) {
+ tq = QNext(cq);
+
+ if (n++ == *pos)
+ break;
+ }
+ if (cq == &CellLRU)
+ return NULL;
+
+ return cq;
+}
+
+static void *c_next(struct seq_file *m, void *p, loff_t *pos)
+{
+ struct afs_q *cq = p, *tq;
+
+ (*pos)++;
+ tq = QNext(cq);
+
+ if (tq == &CellLRU)
+ return NULL;
+
+ return tq;
+}
+
+static void c_stop(struct seq_file *m, void *p)
+{
+ ReleaseReadLock(&afs_xcell);
+}
+
+static int c_show(struct seq_file *m, void *p)
+{
+ struct afs_q *cq = p;
+ struct cell *tc = QTOC(cq);
+ int j;
+
+ seq_printf(m, ">%s #(%d/%d)\n", tc->cellName,
+ tc->cellNum, tc->cellIndex);
+
+ for (j = 0; j < MAXCELLHOSTS; j++) {
+ afs_uint32 addr;
+
+ if (!tc->cellHosts[j]) break;
+
+ addr = tc->cellHosts[j]->addr->sa_ip;
+ seq_printf(m, "%u.%u.%u.%u #%u.%u.%u.%u\n",
+ NIPQUAD(addr), NIPQUAD(addr));
+ }
+
+ return 0;
+}
+
+static struct seq_operations afs_csdb_op = {
+ .start = c_start,
+ .next = c_next,
+ .stop = c_stop,
+ .show = c_show,
};
+static int afs_csdb_open(struct inode *inode, struct file *file)
+{
+ return seq_open(file, &afs_csdb_op);
+}
+
+static struct file_operations afs_csdb_operations = {
+ .open = afs_csdb_open,
+ .read = seq_read,
+ .llseek = seq_lseek,
+ .release = seq_release,
+};
+
+#else /* HAVE_KERNEL_LINUX_SEQ_FILE_H */
+
int
-csdbproc_read(char *buffer, char **start, off_t offset, int count,
- int *eof, void *data)
+csdbproc_info(char *buffer, char **start, off_t offset, int
+length)
{
- int len, j;
+ int len = 0;
+ off_t pos = 0;
+ int cnt;
struct afs_q *cq, *tq;
struct cell *tc;
char tbuffer[16];
+ /* 90 - 64 cellname, 10 for 32 bit num and index, plus
+ decor */
+ char temp[91];
afs_uint32 addr;
- len = 0;
ObtainReadLock(&afs_xcell);
+
for (cq = CellLRU.next; cq != &CellLRU; cq = tq) {
- tc = QTOC(cq); tq = QNext(cq);
- len += sprintf(buffer + len, ">%s #(%d/%d)\n", tc->cellName,
- tc->cellNum, tc->cellIndex);
- for (j = 0; j < MAXCELLHOSTS; j++) {
- if (!tc->cellHosts[j]) break;
- addr = ntohl(tc->cellHosts[j]->addr->sa_ip);
- sprintf(tbuffer, "%d.%d.%d.%d",
- (int)((addr>>24) & 0xff), (int)((addr>>16) & 0xff),
- (int)((addr>>8) & 0xff), (int)( addr & 0xff));
- len += sprintf(buffer + len, "%s #%s\n", tbuffer, tbuffer);
- }
+ tc = QTOC(cq); tq = QNext(cq);
+
+ pos += 90;
+
+ if (pos <= offset) {
+ len = 0;
+ } else {
+ sprintf(temp, ">%s #(%d/%d)\n", tc->cellName,
+ tc->cellNum, tc->cellIndex);
+ sprintf(buffer + len, "%-89s\n", temp);
+ len += 90;
+ if (pos >= offset+length) {
+ ReleaseReadLock(&afs_xcell);
+ goto done;
+ }
+ }
+
+ for (cnt = 0; cnt < MAXCELLHOSTS; cnt++) {
+ if (!tc->cellHosts[cnt]) break;
+ pos += 90;
+ if (pos <= offset) {
+ len = 0;
+ } else {
+ addr = ntohl(tc->cellHosts[cnt]->addr->sa_ip);
+ sprintf(tbuffer, "%d.%d.%d.%d",
+ (int)((addr>>24) & 0xff),
+(int)((addr>>16) & 0xff),
+ (int)((addr>>8) & 0xff), (int)( addr & 0xff));
+ sprintf(temp, "%s #%s\n", tbuffer, tbuffer);
+ sprintf(buffer + len, "%-89s\n", temp);
+ len += 90;
+ if (pos >= offset+length) {
+ ReleaseReadLock(&afs_xcell);
+ goto done;
+ }
+ }
+ }
}
+
ReleaseReadLock(&afs_xcell);
- if (offset >= len) {
- *start = buffer;
- *eof = 1;
- return 0;
- }
- *start = buffer + offset;
- if ((len -= offset) > count)
- return count;
- *eof = 1;
+done:
+ *start = buffer + len - (pos - offset);
+ len = pos - offset;
+ if (len > length)
+ len = length;
return len;
}
+#endif /* HAVE_KERNEL_LINUX_SEQ_FILE_H */
+
int
peerproc_read(char *buffer, char **start, off_t offset, int count,
int *eof, void *data)
}
static struct proc_dir_entry *openafs_procfs;
-#if defined(AFS_LINUX_64BIT_KERNEL) && !defined(AFS_ALPHA_LINUX20_ENV) && !defined(AFS_IA64_LINUX20_ENV)
+#if defined(NEED_IOCTL32) && !defined(HAVE_COMPAT_IOCTL)
static int ioctl32_done;
#endif
+#ifdef AFS_LINUX24_ENV
static int
afsproc_init(void)
{
+ struct proc_dir_entry *entry2;
struct proc_dir_entry *entry1;
struct proc_dir_entry *entry;
entry1->owner = THIS_MODULE;
- entry = create_proc_read_entry(PROC_CELLSERVDB_NAME, (S_IFREG|S_IRUGO), openafs_procfs, csdbproc_read, NULL);
+#ifdef HAVE_KERNEL_LINUX_SEQ_FILE_H
+ entry2 = create_proc_entry(PROC_CELLSERVDB_NAME, 0, openafs_procfs);
+ if (entry2)
+ entry2->proc_fops = &afs_csdb_operations;
+#else
+ entry2 = create_proc_info_entry(PROC_CELLSERVDB_NAME, (S_IFREG|S_IRUGO), openafs_procfs, csdbproc_info);
+#endif
entry = create_proc_read_entry(PROC_PEER_NAME, (S_IFREG|S_IRUGO), openafs_procfs, peerproc_read, NULL);
entry = create_proc_read_entry(PROC_SERVICES_NAME, (S_IFREG|S_IRUGO), openafs_procfs, servicesproc_read, NULL);
entry = create_proc_read_entry(PROC_RXSTATS_NAME, (S_IFREG|S_IRUGO), openafs_procfs, rxstatsproc_read, NULL);
-#if defined(AFS_LINUX_64BIT_KERNEL) && !defined(AFS_ALPHA_LINUX20_ENV) && !defined(AFS_IA64_LINUX20_ENV)
+#if defined(NEED_IOCTL32) && !defined(HAVE_COMPAT_IOCTL)
if (register_ioctl32_conversion(VIOC_SYSCALL32, NULL) == 0)
ioctl32_done = 1;
#endif
remove_proc_entry(PROC_CELLSERVDB_NAME, openafs_procfs);
remove_proc_entry(PROC_SYSCALL_NAME, openafs_procfs);
remove_proc_entry(PROC_FSDIRNAME, proc_root_fs);
-#if defined(AFS_LINUX_64BIT_KERNEL) && !defined(AFS_ALPHA_LINUX20_ENV) && !defined(AFS_IA64_LINUX20_ENV)
+#if defined(NEED_IOCTL32) && !defined(HAVE_COMPAT_IOCTL)
if (ioctl32_done)
unregister_ioctl32_conversion(VIOC_SYSCALL32);
#endif
}
+#endif
extern asmlinkage long
afs_syscall(long syscall, long parm1, long parm2, long parm3, long parm4);
{
struct afsprocdata sysargs;
+#ifdef NEED_IOCTL32
struct afsprocdata32 sysargs32;
+#endif
if (cmd != VIOC_SYSCALL && cmd != VIOC_SYSCALL32) return -EINVAL;
-#if defined(AFS_LINUX_64BIT_KERNEL) && !defined(AFS_ALPHA_LINUX20_ENV) && !defined(AFS_IA64_LINUX20_ENV)
+#ifdef NEED_IOCTL32
#ifdef AFS_SPARC64_LINUX24_ENV
if (current->thread.flags & SPARC_FLAG_32BIT)
#elif defined(AFS_SPARC64_LINUX20_ENV)
#else /*Linux 2.6 */
if (current->thread.flags & PPC_FLAG_32BIT)
#endif
+#elif defined(AFS_S390X_LINUX26_ENV)
+ if (test_thread_flag(TIF_31BIT))
#elif defined(AFS_S390X_LINUX20_ENV)
if (current->thread.flags & S390_FLAG_31BIT)
#else
}
}
+#if defined(HAVE_UNLOCKED_IOCTL) || defined(HAVE_COMPAT_IOCTL)
+static long afs_unlocked_ioctl(struct file *file, unsigned int cmd,
+ unsigned long arg) {
+ return afs_ioctl(FILE_INODE(file), file, cmd, arg);
+}
+#endif
#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,4,0)
int __init
if (e) return e;
register_filesystem(&afs_fs_type);
osi_sysctl_init();
+#ifdef AFS_LINUX24_ENV
afsproc_init();
+#endif
return 0;
}
osi_linux_free_inode_pages(); /* Invalidate all pages using AFS inodes. */
osi_linux_free_afs_memory();
+#ifdef AFS_LINUX24_ENV
afsproc_exit();
+#endif
return;
}
#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,4,0)
+MODULE_LICENSE("http://www.openafs.org/dl/license10.html");
module_init(afs_init);
module_exit(afs_cleanup);
#endif