From: Christopher Allen Wing Date: Sun, 8 May 2005 07:05:09 +0000 (+0000) Subject: linux-proc-read-seq-file-20050508 X-Git-Tag: openafs-devel-1_5_0~577 X-Git-Url: http://git.openafs.org/?p=openafs.git;a=commitdiff_plain;h=ccdab705071cf7ab1a508b06bf09b472806a8b1f linux-proc-read-seq-file-20050508 FIXES 18612 use sequenced file interface for proc copy of CellServDB --- diff --git a/acinclude.m4 b/acinclude.m4 index cf8df8b..bf446a9 100644 --- a/acinclude.m4 +++ b/acinclude.m4 @@ -580,6 +580,7 @@ case $AFS_SYSNAME in *_linux* | *_umlinux*) LINUX_IOP_NAMEIDATA LINUX_AOP_WRITEBACK_CONTROL LINUX_KERNEL_LINUX_SYSCALL_H + LINUX_KERNEL_LINUX_SEQ_FILE_H LINUX_KERNEL_SELINUX LINUX_KERNEL_SOCK_CREATE LINUX_KERNEL_PAGE_FOLLOW_LINK @@ -715,6 +716,9 @@ case $AFS_SYSNAME in *_linux* | *_umlinux*) if test "x$ac_linux_syscall" = "xyes" ; then AC_DEFINE(HAVE_KERNEL_LINUX_SYSCALL_H, 1, [define if your linux kernel has linux/syscall.h]) fi + if test "x$ac_linux_seq_file" = "xyes" ; then + AC_DEFINE(HAVE_KERNEL_LINUX_SEQ_FILE_H, 1, [define if your linux kernel has linux/seq_file.h]) + fi if test "x$ac_cv_linux_sched_struct_task_struct_has_parent" = "xyes"; then AC_DEFINE(STRUCT_TASK_STRUCT_HAS_PARENT, 1, [define if your struct task_struct has parent]) fi diff --git a/src/afs/LINUX/osi_module.c b/src/afs/LINUX/osi_module.c index c4e4834..3af213d 100644 --- a/src/afs/LINUX/osi_module.c +++ b/src/afs/LINUX/osi_module.c @@ -34,6 +34,10 @@ RCSID #include #endif +#ifdef HAVE_KERNEL_LINUX_SEQ_FILE_H +#include +#endif + extern struct file_system_type afs_fs_type; #if !defined(AFS_LINUX24_ENV) @@ -67,6 +71,86 @@ static struct file_operations afs_syscall_fops = { #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_info(char *buffer, char **start, off_t offset, int length) @@ -134,45 +218,7 @@ done: return len; } - -int -csdbproc_read(char *buffer, char **start, off_t offset, int count, - int *eof, void *data) -{ - int len, j; - struct afs_q *cq, *tq; - struct cell *tc; - char tbuffer[16]; - 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); - } - } - ReleaseReadLock(&afs_xcell); - - if (offset >= len) { - *start = buffer; - *eof = 1; - return 0; - } - *start = buffer + offset; - if ((len -= offset) > count) - return count; - *eof = 1; - return len; -} +#endif /* HAVE_KERNEL_LINUX_SEQ_FILE_H */ int peerproc_read(char *buffer, char **start, off_t offset, int count, @@ -508,6 +554,7 @@ static int ioctl32_done; static int afsproc_init(void) { + struct proc_dir_entry *entry2; struct proc_dir_entry *entry1; struct proc_dir_entry *entry; @@ -518,7 +565,13 @@ afsproc_init(void) entry1->owner = THIS_MODULE; - entry = create_proc_info_entry(PROC_CELLSERVDB_NAME, (S_IFREG|S_IRUGO), openafs_procfs, csdbproc_info); +#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); diff --git a/src/cf/linux-test3.m4 b/src/cf/linux-test3.m4 index f64c5ef..fc6b7c8 100644 --- a/src/cf/linux-test3.m4 +++ b/src/cf/linux-test3.m4 @@ -128,3 +128,14 @@ AC_TRY_COMPILE( ac_cv_linux_kernel_page_follow_link=no)]) AC_MSG_RESULT($ac_cv_linux_kernel_page_follow_link) CPPFLAGS="$save_CPPFLAGS"]) + +AC_DEFUN([LINUX_KERNEL_LINUX_SEQ_FILE_H],[ + AC_MSG_CHECKING(for linux/seq_file.h in kernel) + if test -f "${LINUX_KERNEL_PATH}/include/linux/seq_file.h"; then + ac_linux_seq_file=yes + AC_MSG_RESULT($ac_linux_seq_file) + else + ac_linux_seq_file=no + AC_MSG_RESULT($ac_linux_seq_file) + fi +])