diff options
| author | Linus Torvalds <torvalds@athlon.transmeta.com> | 2002-02-04 20:33:15 -0800 |
|---|---|---|
| committer | Linus Torvalds <torvalds@athlon.transmeta.com> | 2002-02-04 20:33:15 -0800 |
| commit | d40d1af9f0aebf7e108f1dfb66ac5af671bc9719 (patch) | |
| tree | 7a2518e82986a8eb5b4eb76553df04d8ba6e4642 /include | |
| parent | a8a2069f432c5597bdf9c83ab3045b9ef32ab5e3 (diff) | |
v2.4.14.2 -> v2.4.14.3
- Alan Cox: more driver merging
- Al Viro: make ext2 group allocation more readable
Diffstat (limited to 'include')
| -rw-r--r-- | include/asm-i386/pgtable.h | 12 | ||||
| -rw-r--r-- | include/asm-ia64/pgtable.h | 5 | ||||
| -rw-r--r-- | include/asm-parisc/pgtable.h | 5 | ||||
| -rw-r--r-- | include/asm-ppc/pgtable.h | 5 | ||||
| -rw-r--r-- | include/asm-sh/pgtable.h | 5 | ||||
| -rw-r--r-- | include/asm-sparc/pgtable.h | 5 | ||||
| -rw-r--r-- | include/asm-sparc64/pgtable.h | 5 | ||||
| -rw-r--r-- | include/linux/fsfilter.h | 129 | ||||
| -rw-r--r-- | include/linux/intermezzo_fs.h | 731 | ||||
| -rw-r--r-- | include/linux/intermezzo_journal.h | 26 | ||||
| -rw-r--r-- | include/linux/intermezzo_kml.h | 261 | ||||
| -rw-r--r-- | include/linux/intermezzo_psdev.h | 72 | ||||
| -rw-r--r-- | include/linux/intermezzo_upcall.h | 146 | ||||
| -rw-r--r-- | include/linux/lvm.h | 326 | ||||
| -rw-r--r-- | include/linux/mm.h | 3 | ||||
| -rw-r--r-- | include/linux/seq_file.h | 55 | ||||
| -rw-r--r-- | include/linux/sysctl.h | 3 |
17 files changed, 1567 insertions, 227 deletions
diff --git a/include/asm-i386/pgtable.h b/include/asm-i386/pgtable.h index 28f1b7b26976..6f99b61e87f3 100644 --- a/include/asm-i386/pgtable.h +++ b/include/asm-i386/pgtable.h @@ -105,8 +105,20 @@ extern unsigned long empty_zero_page[1024]; #ifndef __ASSEMBLY__ #if CONFIG_X86_PAE # include <asm/pgtable-3level.h> + +/* + * Need to initialise the X86 PAE caches + */ +extern void pgtable_cache_init(void); + #else # include <asm/pgtable-2level.h> + +/* + * No page table caches to initialise + */ +#define pgtable_cache_init() do { } while (0) + #endif #endif diff --git a/include/asm-ia64/pgtable.h b/include/asm-ia64/pgtable.h index c6279c8f7264..edc2104509d5 100644 --- a/include/asm-ia64/pgtable.h +++ b/include/asm-ia64/pgtable.h @@ -483,4 +483,9 @@ extern unsigned long empty_zero_page[PAGE_SIZE/sizeof(unsigned long)]; #define KERNEL_TR_PAGE_SIZE (1 << KERNEL_TR_PAGE_SHIFT) #define KERNEL_TR_PAGE_NUM ((KERNEL_START - PAGE_OFFSET) / KERNEL_TR_PAGE_SIZE) +/* + * No page table caches to initialise + */ +#define pgtable_cache_init() do { } while (0) + #endif /* _ASM_IA64_PGTABLE_H */ diff --git a/include/asm-parisc/pgtable.h b/include/asm-parisc/pgtable.h index 6213ab8504f2..1e2fdf53ec4d 100644 --- a/include/asm-parisc/pgtable.h +++ b/include/asm-parisc/pgtable.h @@ -334,4 +334,9 @@ extern inline void update_mmu_cache(struct vm_area_struct * vma, #define io_remap_page_range remap_page_range +/* + * No page table caches to initialise + */ +#define pgtable_cache_init() do { } while (0) + #endif /* _PARISC_PAGE_H */ diff --git a/include/asm-ppc/pgtable.h b/include/asm-ppc/pgtable.h index 81dbec806dcf..47aa26cdc47c 100644 --- a/include/asm-ppc/pgtable.h +++ b/include/asm-ppc/pgtable.h @@ -555,6 +555,11 @@ extern void kernel_set_cachemode (unsigned long address, unsigned long size, #define io_remap_page_range remap_page_range +/* + * No page table caches to initialise + */ +#define pgtable_cache_init() do { } while (0) + #endif /* __ASSEMBLY__ */ #endif /* _PPC_PGTABLE_H */ #endif /* __KERNEL__ */ diff --git a/include/asm-sh/pgtable.h b/include/asm-sh/pgtable.h index 6bd7e49ae83c..cc962def542d 100644 --- a/include/asm-sh/pgtable.h +++ b/include/asm-sh/pgtable.h @@ -308,4 +308,9 @@ extern void update_mmu_cache(struct vm_area_struct * vma, #define io_remap_page_range remap_page_range +/* + * No page table caches to initialise + */ +#define pgtable_cache_init() do { } while (0) + #endif /* __ASM_SH_PAGE_H */ diff --git a/include/asm-sparc/pgtable.h b/include/asm-sparc/pgtable.h index fa318a5b581c..a2a3777f1fb4 100644 --- a/include/asm-sparc/pgtable.h +++ b/include/asm-sparc/pgtable.h @@ -454,4 +454,9 @@ extern int io_remap_page_range(unsigned long from, unsigned long to, /* We provide our own get_unmapped_area to cope with VA holes for userland */ #define HAVE_ARCH_UNMAPPED_AREA +/* + * No page table caches to initialise + */ +#define pgtable_cache_init() do { } while (0) + #endif /* !(_SPARC_PGTABLE_H) */ diff --git a/include/asm-sparc64/pgtable.h b/include/asm-sparc64/pgtable.h index 7acc74ef4b54..22aec51acd22 100644 --- a/include/asm-sparc64/pgtable.h +++ b/include/asm-sparc64/pgtable.h @@ -344,4 +344,9 @@ extern unsigned long get_fb_unmapped_area(struct file *filp, unsigned long, unsi #endif /* !(__ASSEMBLY__) */ +/* + * No page table caches to initialise + */ +#define pgtable_cache_init() do { } while (0) + #endif /* !(_SPARC64_PGTABLE_H) */ diff --git a/include/linux/fsfilter.h b/include/linux/fsfilter.h new file mode 100644 index 000000000000..89e870450d3d --- /dev/null +++ b/include/linux/fsfilter.h @@ -0,0 +1,129 @@ +#ifndef __FILTER_H_ +#define __FILTER_H_ 1 + +#ifdef __KERNEL__ + +/* cachetype.c */ + +/* + * it is important that things like inode, super and file operations + * for intermezzo are not defined statically. If methods are NULL + * the VFS takes special action based on that. Given that different + * cache types have NULL ops at different slots, we must install opeation + * talbes for InterMezzo with NULL's in the same spot + */ + +struct filter_ops { + struct super_operations filter_sops; + + struct inode_operations filter_dir_iops; + struct inode_operations filter_file_iops; + struct inode_operations filter_sym_iops; + + struct file_operations filter_dir_fops; + struct file_operations filter_file_fops; + struct file_operations filter_sym_fops; + + struct dentry_operations filter_dentry_ops; +}; + +struct cache_ops { + /* operations on the file store */ + struct super_operations *cache_sops; + + struct inode_operations *cache_dir_iops; + struct inode_operations *cache_file_iops; + struct inode_operations *cache_sym_iops; + + struct file_operations *cache_dir_fops; + struct file_operations *cache_file_fops; + struct file_operations *cache_sym_fops; + + struct dentry_operations *cache_dentry_ops; +}; + + +#define FILTER_DID_SUPER_OPS 0x1 +#define FILTER_DID_INODE_OPS 0x2 +#define FILTER_DID_FILE_OPS 0x4 +#define FILTER_DID_DENTRY_OPS 0x8 +#define FILTER_DID_DEV_OPS 0x10 +#define FILTER_DID_SYMLINK_OPS 0x20 +#define FILTER_DID_DIR_OPS 0x40 + +struct filter_fs { + int o_flags; + struct filter_ops o_fops; + struct cache_ops o_caops; + struct journal_ops *o_trops; + struct snapshot_ops *o_snops; +}; + +#define FILTER_FS_TYPES 5 +#define FILTER_FS_EXT2 0 +#define FILTER_FS_EXT3 1 +#define FILTER_FS_REISERFS 2 +#define FILTER_FS_XFS 3 +#define FILTER_FS_OBDFS 4 +extern struct filter_fs filter_oppar[FILTER_FS_TYPES]; + +struct filter_fs *filter_get_filter_fs(const char *cache_type); +void filter_setup_journal_ops(struct filter_fs *ops, char *cache_type); +inline struct super_operations *filter_c2usops(struct filter_fs *cache); +inline struct inode_operations *filter_c2ufiops(struct filter_fs *cache); +inline struct inode_operations *filter_c2udiops(struct filter_fs *cache); +inline struct inode_operations *filter_c2usiops(struct filter_fs *cache); +inline struct file_operations *filter_c2uffops(struct filter_fs *cache); +inline struct file_operations *filter_c2udfops(struct filter_fs *cache); +inline struct file_operations *filter_c2usfops(struct filter_fs *cache); +inline struct super_operations *filter_c2csops(struct filter_fs *cache); +inline struct inode_operations *filter_c2cfiops(struct filter_fs *cache); +inline struct inode_operations *filter_c2cdiops(struct filter_fs *cache); +inline struct inode_operations *filter_c2csiops(struct filter_fs *cache); +inline struct file_operations *filter_c2cffops(struct filter_fs *cache); +inline struct file_operations *filter_c2cdfops(struct filter_fs *cache); +inline struct file_operations *filter_c2csfops(struct filter_fs *cache); +inline struct dentry_operations *filter_c2cdops(struct filter_fs *cache); +inline struct dentry_operations *filter_c2udops(struct filter_fs *cache); + +void filter_setup_super_ops(struct filter_fs *cache, struct super_operations *cache_ops, struct super_operations *filter_sops); +void filter_setup_dir_ops(struct filter_fs *cache, struct inode *cache_inode, struct inode_operations *filter_iops, struct file_operations *ffops); +void filter_setup_file_ops(struct filter_fs *cache, struct inode *cache_inode, struct inode_operations *filter_iops, struct file_operations *filter_op); +void filter_setup_symlink_ops(struct filter_fs *cache, struct inode *cache_inode, struct inode_operations *filter_iops, struct file_operations *filter_op); +void filter_setup_dentry_ops(struct filter_fs *cache, struct dentry_operations *cache_dop, struct dentry_operations *filter_dop); + + +#define PRESTO_DEBUG +#ifdef PRESTO_DEBUG +/* debugging masks */ +#define D_SUPER 1 /* print results returned by Venus */ +#define D_INODE 2 /* print entry and exit into procedure */ +#define D_FILE 4 +#define D_CACHE 8 /* cache debugging */ +#define D_MALLOC 16 /* print malloc, de-alloc information */ +#define D_JOURNAL 32 +#define D_UPCALL 64 /* up and downcall debugging */ +#define D_PSDEV 128 +#define D_PIOCTL 256 +#define D_SPECIAL 512 +#define D_TIMING 1024 +#define D_DOWNCALL 2048 + +#define FDEBUG(mask, format, a...) \ + do { \ + if (filter_debug & mask) { \ + printk("(%s,l. %d): ", __FUNCTION__, __LINE__); \ + printk(format, ##a); } \ + } while (0) + +#define FENTRY \ + if(filter_print_entry) \ + printk("Process %d entered %s\n", current->pid, __FUNCTION__) + +#define FEXIT \ + if(filter_print_entry) \ + printk("Process %d leaving %s at %d\n", current->pid, \ + __FUNCTION__,__LINE__) +#endif +#endif +#endif diff --git a/include/linux/intermezzo_fs.h b/include/linux/intermezzo_fs.h new file mode 100644 index 000000000000..012060243874 --- /dev/null +++ b/include/linux/intermezzo_fs.h @@ -0,0 +1,731 @@ +/* + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License as + * published by the Free Software Foundation; either version 2 of the + * License, or (at your option) any later version. + * + * Copyright (C) 2000 Stelias Computing, Inc. + * Copyright (C) 2000 Red Hat, Inc. + * Copyright (C) 2000 TurboLinux, Inc. + * Copyright (C) 2000 Los Alamos National Laboratory. + * Copyright (C) 2001 Tacitus Systems, Inc. + * Copyright (C) 2001 Cluster File Systems, Inc. + */ + +#ifndef __INTERMEZZO_FS_H_ +#define __INTERMEZZO_FS_H_ 1 + +#ifdef __KERNEL__ +#include <linux/smp.h> +#include <linux/fsfilter.h> + +/* fixups for fs.h */ +#ifndef fs_down +#define fs_down(sem) down(sem) +#endif + +#ifndef fs_up +#define fs_up(sem) up(sem) +#endif + +/* We will be more tolerant than the default ea patch with attr name sizes and + * the size of value. If these come via VFS from the default ea patches, the + * corresponding character strings will be truncated anyway. During journalling- * we journal length for both name and value. See journal_set_ext_attr. + */ +#define PRESTO_EXT_ATTR_NAME_MAX 128 +#define PRESTO_EXT_ATTR_VALUE_MAX 8192 + +#define KML_IDLE 0 +#define KML_DECODE 1 +#define KML_OPTIMIZE 2 +#define KML_REINT 3 + +#define KML_OPEN_REINT 0x0100 +#define KML_REINT_BEGIN 0x0200 +#define KML_BACKFETCH 0x0400 +#define KML_REINT_END 0x0800 +#define KML_CLOSE_REINT 0x1000 +#define FSET_GET_KMLDATA(fset) fset->fset_kmldata +#define KML_REINT_MAXBUF (64 * 1024) + +struct kml_fsdata +{ + int kml_state; + + /* kml optimize support */ + struct list_head kml_kop_cache; + + /* kml reint support */ + int kml_reint_state; + struct list_head kml_reint_cache; + struct list_head *kml_reint_current; + int kml_maxsize; /* max buffer */ + int kml_len; + char * kml_buf; + loff_t kml_reintpos; + int kml_count; +}; + +/* super.c */ +struct presto_cache *presto_find_cache(kdev_t dev) ; +extern struct file_system_type presto_fs_type; +extern int init_intermezzo_fs(void); + +#define CACHE_TYPE_LENGTH 16 + +int presto_ispresto(struct inode *); + +#define CACHE_CLIENT_RO 0x4 +#define CACHE_LENTO_RO 0x8 +#define CACHE_FSETROOT_SET 0x10 + + +struct presto_cache { + spinlock_t cache_lock; + loff_t cache_reserved; + struct list_head cache_chain; /* for the dev/cache hash */ + + int cache_flags; + char *cache_root_fileset; /* fileset mounted on cache "/" */ + + kdev_t cache_dev; /* underlying block device */ + struct super_block *cache_sb; + struct dentry *cache_mtde; /* unix mtpt of cache XXX NOT VALID XXX */ + char *cache_mtpt; /* again */ + + char *cache_type; /* filesystem type of cache */ + struct filter_fs *cache_filter; + + struct upc_comm *cache_psdev; /* points to /dev/intermezzo? we use */ + struct list_head cache_psdev_chain; + + struct list_head cache_fset_list; /* filesets mounted in cache */ +}; + + + + +/* file sets */ +#define CHUNK_BITS 16 + +struct presto_log_fd { + rwlock_t fd_lock; + loff_t fd_offset; /* offset where next record should go */ + struct file *fd_file; + int fd_truncating; + unsigned int fd_recno; /* last recno written */ + struct list_head fd_reservations; +}; + +struct presto_file_set { + struct list_head fset_list; + struct presto_log_fd fset_kml; + struct presto_log_fd fset_lml; + struct file *fset_last_rcvd; + struct dentry *fset_mtpt; + struct nameidata fset_nd; + struct presto_cache *fset_cache; + + unsigned int fset_lento_recno; /* last recno mentioned to lento */ + loff_t fset_lento_off; /* last offset mentioned to lento */ + char * fset_name; + + int fset_flags; + int fset_permit_count; + int fset_permit_cookie; + int fset_chunkbits; + struct kml_fsdata *fset_kmldata; + loff_t fset_file_maxio; /* writing more than this causes a close */ +}; + +/* This is the default number of bytes written before a close is recorded*/ +#define FSET_DEFAULT_MAX_FILEIO (1024<<10) + +struct journal_ops { + loff_t (*tr_avail)(struct presto_cache *fset, struct super_block *); + void *(*tr_start)(struct presto_file_set *, struct inode *, int op); + void (*tr_commit)(struct presto_file_set *, void *handle); + void (*tr_journal_data)(struct inode *); +}; + + +extern struct journal_ops presto_ext2_journal_ops; +extern struct journal_ops presto_ext3_journal_ops; +extern struct journal_ops presto_xfs_journal_ops; +extern struct journal_ops presto_reiserfs_journal_ops; +extern struct journal_ops presto_obdfs_journal_ops; +struct lento_vfs_context { + __u32 slot_offset; + __u32 recno; + __u64 kml_offset; + __u32 flags; + __u32 updated_time; +}; + + +#define LENTO_FL_KML 0x0001 +#define LENTO_FL_EXPECT 0x0002 +#define LENTO_FL_VFSCHECK 0x0004 +#define LENTO_FL_JUSTLOG 0x0008 +#define LENTO_FL_WRITE_KML 0x0010 +#define LENTO_FL_CANCEL_LML 0x0020 +#define LENTO_FL_WRITE_EXPECT 0x0040 +#define LENTO_FL_IGNORE_TIME 0x0080 + +struct presto_cache *presto_get_cache(struct inode *inode) ; +int presto_sprint_mounts(char *buf, int buflen, int minor); +struct presto_file_set *presto_fset(struct dentry *de); +int presto_journal(struct dentry *dentry, char *buf, size_t size); +int presto_fwrite(struct file *file, const char *str, int len, loff_t *off); + +/* psdev.c */ +int presto_psdev_init(void); +extern void presto_psdev_cleanup(void); +inline int presto_lento_up(int minor); + +/* inode.c */ +extern struct super_operations presto_super_ops; +extern int presto_excluded_gid; +#define PRESTO_EXCL_GID 4711 +void presto_set_ops(struct inode *inode, struct filter_fs *filter); +void presto_read_inode(struct inode *inode); +void presto_put_super(struct super_block *); + +/* journal.c */ +void presto_trans_commit(struct presto_file_set *fset, void *handle); +void *presto_trans_start(struct presto_file_set *fset, struct inode *inode, + int op); + +/* dcache.c */ +void presto_frob_dop(struct dentry *de) ; +char * presto_path(struct dentry *dentry, struct dentry *root, + char *buffer, int buflen); +void presto_set_dd(struct dentry *); +void presto_init_ddata_cache(void); +void presto_cleanup_ddata_cache(void); +extern struct dentry_operations presto_dentry_ops; + + + +/* dir.c */ +extern struct inode_operations presto_dir_iops; +extern struct inode_operations presto_file_iops; +extern struct inode_operations presto_sym_iops; +extern struct file_operations presto_dir_fops; +extern struct file_operations presto_file_fops; +extern struct file_operations presto_sym_fops; +int presto_setattr(struct dentry *de, struct iattr *iattr); +extern int presto_ilookup_uid; +#define PRESTO_ILOOKUP_MAGIC "...ino:" +#define PRESTO_ILOOKUP_SEP ':' + +struct dentry *presto_lookup(struct inode * dir, struct dentry *dentry); + +/* file.c */ +struct presto_reservation_data { + unsigned int ri_recno; + loff_t ri_offset; + loff_t ri_size; + struct list_head ri_list; +}; + + +struct presto_dentry_data { + int dd_count; /* how mnay dentries are using this dentry */ + struct presto_file_set *dd_fset; + loff_t dd_kml_offset; + int dd_flags; + +}; + +struct presto_file_data { + int fd_do_lml; + loff_t fd_lml_offset; + uid_t fd_fsuid; + gid_t fd_fsgid; + uid_t fd_uid; + gid_t fd_gid; + mode_t fd_mode; + int fd_ngroups; + size_t fd_bytes_written; /* Number of bytes written so far on this fd*/ + gid_t fd_groups[NGROUPS_MAX]; +}; + + +/* presto.c and Lento::Downcall */ +struct presto_version { + __u64 pv_mtime; + __u64 pv_ctime; + __u64 pv_size; +}; +inline struct presto_dentry_data *presto_d2d(struct dentry *); +int presto_walk(const char *name, struct nameidata *nd); +int presto_clear_fsetroot(char *path); +int presto_clear_all_fsetroots(char *path); +int presto_get_kmlsize(char *path, size_t *size); +int presto_get_lastrecno(char *path, off_t *size); +int presto_set_fsetroot(char *path, char *fsetname, unsigned int fsetid, + unsigned int flags); +int presto_has_all_data(struct inode *inode); +inline int presto_is_read_only(struct presto_file_set *); +int presto_truncate_lml(struct presto_file_set *fset); +int lento_write_lml(char *path, + __u64 remote_ino, + __u32 remote_generation, + __u32 remote_version, + struct presto_version *remote_file_version); +int lento_reset_fset(char *path, __u64 offset, __u32 recno); +int lento_complete_closes(char *path); +int lento_cancel_lml(char *path, + __u64 lml_offset, + __u64 remote_ino, + __u32 remote_generation, + __u32 remote_version, + struct lento_vfs_context *info); +inline int presto_f2m(struct presto_file_set *fset); + +/* cache.c */ +#define PRESTO_REQLOW (3 * 4096) +#define PRESTO_REQHIGH (6 * 4096) +void presto_release_space(struct presto_cache *cache, loff_t req); +int presto_reserve_space(struct presto_cache *cache, loff_t req); + +/* NOTE: PRESTO_FSETROOT MUST be 0x1: + - if this bit is set dentry->d_fsdata points to a file_set + - the address of the file_set if d_fsdata - 1 +*/ + +#define PRESTO_FSETROOT 0x00000001 /* dentry is fileset root */ +#define PRESTO_DATA 0x00000002 /* cached data is valid */ +#define PRESTO_ATTR 0x00000004 /* attributes cached */ + +#define EISFSETROOT 0x2001 + + +struct presto_file_set *presto_path2fileset(const char *name); +int presto_permit_downcall(const char *path, int *cookie); +int presto_chk(struct dentry *dentry, int flag); +void presto_set(struct dentry *dentry, int flag); +int presto_get_permit(struct inode *inode); +int presto_put_permit(struct inode *inode); +int presto_mark_dentry(const char *path, int and, int or, int *res); +int presto_mark_cache(const char *path, int and_bits, int or_bits, int *); +int presto_mark_fset(const char *path, int and_bits, int or_bits, int *); +void presto_getversion(struct presto_version *pv, struct inode *inode); +int presto_i2m(struct inode *inode); +int presto_c2m(struct presto_cache *cache); + +/* journal.c */ +struct rec_info { + loff_t offset; + int size; + int recno; + int is_kml; +}; +void presto_trans_commit(struct presto_file_set *fset, void *handle); +void *presto_trans_start(struct presto_file_set *fset, struct inode *inode, + int op); +int presto_clear_lml_close(struct presto_file_set *fset, + loff_t lml_offset); +int presto_write_lml_close(struct rec_info *rec, + struct presto_file_set *fset, + struct file *file, + __u64 remote_ino, + __u32 remote_generation, + __u32 remote_version, + struct presto_version *new_file_ver); +int presto_complete_lml(struct presto_file_set *fset); + +/* vfs.c */ +int presto_do_setattr(struct presto_file_set *fset, struct dentry *dentry, + struct iattr *iattr, struct lento_vfs_context *info); +int presto_do_create(struct presto_file_set *fset, struct dentry *dir, + struct dentry *dentry, int mode, + struct lento_vfs_context *info); +int presto_do_link(struct presto_file_set *fset, struct dentry *dir, + struct dentry *old_dentry, struct dentry *new_dentry, + struct lento_vfs_context *info); +int presto_do_unlink(struct presto_file_set *fset, struct dentry *dir, + struct dentry *dentry, struct lento_vfs_context *info); +int presto_do_symlink(struct presto_file_set *fset, struct dentry *dir, + struct dentry *dentry, const char *name, + struct lento_vfs_context *info); +int presto_do_mkdir(struct presto_file_set *fset, struct dentry *dir, + struct dentry *dentry, int mode, + struct lento_vfs_context *info); +int presto_do_rmdir(struct presto_file_set *fset, struct dentry *dir, + struct dentry *dentry, struct lento_vfs_context *info); +int presto_do_mknod(struct presto_file_set *fset, struct dentry *dir, + struct dentry *dentry, int mode, dev_t dev, + struct lento_vfs_context *info); +int presto_do_rename(struct presto_file_set *fset, struct dentry *old_dir, + struct dentry *old_dentry, struct dentry *new_dir, + struct dentry *new_dentry, struct lento_vfs_context *info); +int presto_do_statfs (struct presto_file_set *fset, + struct statfs * buf); + +int lento_setattr(const char *name, struct iattr *iattr, + struct lento_vfs_context *info); +int lento_create(const char *name, int mode, struct lento_vfs_context *info); +int lento_link(const char *oldname, const char *newname, + struct lento_vfs_context *info); +int lento_unlink(const char *name, struct lento_vfs_context *info); +int lento_symlink(const char *oldname,const char *newname, + struct lento_vfs_context *info); +int lento_mkdir(const char *name, int mode, struct lento_vfs_context *info); +int lento_rmdir(const char *name, struct lento_vfs_context *info); +int lento_mknod(const char *name, int mode, dev_t dev, + struct lento_vfs_context *info); +int lento_rename(const char *oldname, const char *newname, + struct lento_vfs_context *info); +int lento_iopen(const char *name, ino_t ino, unsigned int generation,int flags); +int lento_close(unsigned int fd, struct lento_vfs_context *info); + + +/* journal.c */ + +#define JOURNAL_PAGE_SZ PAGE_SIZE + +__inline__ int presto_no_journal(struct presto_file_set *fset); +int journal_fetch(int minor); +int presto_journal_write(struct rec_info *rec, struct presto_file_set *fset, + struct file *file); +int presto_journal_setattr(struct rec_info *rec, struct presto_file_set *fset, + struct dentry *dentry, + struct presto_version *old_ver, + struct iattr *iattr); +int presto_journal_create(struct rec_info *rec, struct presto_file_set *fset, + struct dentry *dentry, + struct presto_version *tgt_dir_ver, + struct presto_version *new_file_ver, int mode); +int presto_journal_link(struct rec_info *rec, struct presto_file_set *fset, + struct dentry *src, struct dentry *tgt, + struct presto_version *tgt_dir_ver, + struct presto_version *new_link_ver); +int presto_journal_unlink(struct rec_info *rec, struct presto_file_set *fset, + struct dentry *dentry, + struct presto_version *tgt_dir_ver, + struct presto_version *old_file_ver, int len, + const char *name); +int presto_journal_symlink(struct rec_info *rec, struct presto_file_set *fset, + struct dentry *dentry, const char *target, + struct presto_version *tgt_dir_ver, + struct presto_version *new_link_ver); +int presto_journal_mkdir(struct rec_info *rec, struct presto_file_set *fset, + struct dentry *dentry, + struct presto_version *tgt_dir_ver, + struct presto_version *new_dir_ver, int mode); +int presto_journal_rmdir(struct rec_info *rec, struct presto_file_set *fset, + struct dentry *dentry, + struct presto_version *tgt_dir_ver, + struct presto_version *old_dir_ver, int len, + const char *name); +int presto_journal_mknod(struct rec_info *rec, struct presto_file_set *fset, + struct dentry *dentry, + struct presto_version *tgt_dir_ver, + struct presto_version *new_node_ver, int mode, + int dmajor, int dminor); +int presto_journal_rename(struct rec_info *rec, struct presto_file_set *fset, + struct dentry *src, struct dentry *tgt, + struct presto_version *src_dir_ver, + struct presto_version *tgt_dir_ver); +int presto_journal_open(struct rec_info *rec, struct presto_file_set *fset, + struct dentry *dentry, struct presto_version *old_ver); +int presto_journal_close(struct rec_info *rec, struct presto_file_set *fset, + struct file *file, + struct dentry *dentry, + struct presto_version *new_ver); +int presto_close_journal_file(struct presto_file_set *fset); +void presto_log_op(void *data, int len); +int presto_write_last_rcvd(struct rec_info *recinfo, + struct presto_file_set *fset, + struct lento_vfs_context *info); + +/* journal_ext3.c */ +struct ext3_journal_data { + struct file *jd_file; +}; +extern struct ext3_journal_data e3jd; + + + + +/* sysctl.c */ +int init_intermezzo_sysctl(void); +void cleanup_intermezzo_sysctl(void); + +/* ext_attr.c */ +#ifdef CONFIG_FS_EXT_ATTR +/* XXX: Borrowed from vfs.c. Once the ea patch is into CVS + * move this prototype -SHP + */ +int presto_do_set_ext_attr(struct presto_file_set *fset, + struct dentry *dentry, + const char *name, void *buffer, + size_t buffer_len, int flags, mode_t *mode, + struct lento_vfs_context *info); +int presto_set_ext_attr(struct inode *inode, + const char *name, void *buffer, + size_t buffer_len, int flags); +int lento_set_ext_attr(const char *path, const char *name, + void *buffer, size_t buffer_len, int flags, + mode_t mode, struct lento_vfs_context *info); +/* XXX: Borrowed from journal.c. Once the ea patch is into CVS + * move this prototype -SHP + */ +int presto_journal_set_ext_attr (struct rec_info *rec, + struct presto_file_set *fset, + struct dentry *dentry, + struct presto_version *ver, const char *name, + const char *buffer, int buffer_len, + int flags); +#endif + + +/* global variables */ +extern int presto_debug; +extern int presto_print_entry; + +#define PRESTO_DEBUG +#ifdef PRESTO_DEBUG +/* debugging masks */ +#define D_SUPER 1 /* print results returned by Venus */ +#define D_INODE 2 /* print entry and exit into procedure */ +#define D_FILE 4 +#define D_CACHE 8 /* cache debugging */ +#define D_MALLOC 16 /* print malloc, de-alloc information */ +#define D_JOURNAL 32 +#define D_UPCALL 64 /* up and downcall debugging */ +#define D_PSDEV 128 +#define D_PIOCTL 256 +#define D_SPECIAL 512 +#define D_TIMING 1024 +#define D_DOWNCALL 2048 +#define D_KML 4096 + +#define CDEBUG(mask, format, a...) \ + do { \ + if (presto_debug & mask) { \ + printk("(%s:%s,l. %d %d): ", __FILE__, __FUNCTION__, __LINE__, current->pid); \ + printk(format, ##a); } \ + } while (0) + +#define ENTRY \ + if(presto_print_entry) \ + printk("Process %d entered %s\n", current->pid, __FUNCTION__) + +#define EXIT \ + if(presto_print_entry) \ + printk("Process %d leaving %s at %d\n", current->pid, \ + __FUNCTION__,__LINE__) + +extern long presto_kmemory; +extern long presto_vmemory; + +#define presto_kmem_inc(ptr, size) presto_kmemory += (size) +#define presto_kmem_dec(ptr, size) presto_kmemory -= (size) +#define presto_vmem_inc(ptr, size) presto_vmemory += (size) +#define presto_vmem_dec(ptr, size) presto_vmemory -= (size) +#else /* !PRESTO_DEBUG */ +#define CDEBUG(mask, format, a...) do {} while (0) +#define ENTRY do {} while (0) +#define EXIT do {} while (0) +#define presto_kmem_inc(ptr, size) do {} while (0) +#define presto_kmem_dec(ptr, size) do {} while (0) +#define presto_vmem_inc(ptr, size) do {} while (0) +#define presto_vmem_dec(ptr, size) do {} while (0) +#endif /* PRESTO_DEBUG */ + + +#define PRESTO_ALLOC(ptr, cast, size) \ +do { \ + if (size <= 4096) { \ + ptr = (cast)kmalloc((unsigned long) size, GFP_KERNEL); \ + CDEBUG(D_MALLOC, "kmalloced: %ld at %p.\n", (long)size, ptr); \ + presto_kmem_inc(ptr, size); \ + } else { \ + ptr = (cast)vmalloc((unsigned long) size); \ + CDEBUG(D_MALLOC, "vmalloced: %ld at %p.\n", (long)size, ptr); \ + presto_vmem_inc(ptr, size); \ + } \ + if ((ptr) == 0) \ + printk("PRESTO: out of memory at %s:%d\n", __FILE__, __LINE__); \ + else \ + memset( ptr, 0, size ); \ +} while (0) + + + +#define PRESTO_FREE(ptr,size) \ +do { \ + if (!ptr) { \ + printk("PRESTO: free NULL pointer (%ld bytes) at %s:%d\n", \ + (long)size, __FILE__, __LINE__); \ + break; \ + } \ + if (size <= 4096) { \ + CDEBUG(D_MALLOC, "kfreed: %ld at %p.\n", (long)size, ptr); \ + presto_kmem_dec(ptr, size); \ + kfree((ptr)); \ + } else { \ + CDEBUG(D_MALLOC, "vfreed: %ld at %p.\n", (long)size, ptr); \ + presto_vmem_dec(ptr, size); \ + vfree((ptr)); \ + } \ +} while (0) + +#define MYPATHLEN(buffer,path) (buffer + PAGE_SIZE - path - 1) + +#else /* __KERNEL__ */ +#include <asm/types.h> +#include <sys/ioctl.h> +struct lento_vfs_context { + __u32 slot_offset; + __u32 recno; + __u64 kml_offset; + __u32 flags; + __u32 updated_time; +}; +#endif /* __KERNEL__*/ + + +/* marking flags for fsets */ +#define FSET_CLIENT_RO 0x00000001 +#define FSET_LENTO_RO 0x00000002 +#define FSET_HASPERMIT 0x00000004 /* we have a permit to WB */ +#define FSET_INSYNC 0x00000008 /* this fileset is in sync */ +#define FSET_PERMIT_WAITING 0x00000010 /* Lento is waiting for permit */ +#define FSET_STEAL_PERMIT 0x00000020 /* take permit if Lento is dead */ +#define FSET_JCLOSE_ON_WRITE 0x00000040 /* Journal closes on writes */ + + +/* what to mark indicator (ioctl parameter) */ +#define MARK_DENTRY 101 +#define MARK_FSET 102 +#define MARK_CACHE 103 +#define MARK_GETFL 104 + + + +struct readmount { + int io_len; /* this is IN & OUT: true length of str is returned */ + char *io_string; +}; + +/* modeled after setsockopt */ +/* so if you have no /proc, oh well. */ +/* for now it's all ints. We may grow this later for non-ints. */ +struct psdev_opt { + int optname; + int optval; +}; + +struct lento_input { + char *name; + struct lento_vfs_context info; +}; + +struct lento_input_attr { + char *name; +#if BITS_PER_LONG < 64 + __u32 dummy; /* XXX on 64-bit platforms, this is not needed */ +#endif + __u32 valid; + __u32 mode; + __u32 uid; + __u32 gid; + __u64 size; + __s64 atime; + __s64 mtime; + __s64 ctime; + __u32 attr_flags; + struct lento_vfs_context info; +}; + +struct lento_input_mode { + char *name; + __u32 mode; + struct lento_vfs_context info; +}; + +struct lento_input_old_new { + char *oldname; + char *newname; + struct lento_vfs_context info; +}; + +struct lento_input_dev { + char *name; + __u32 mode; + __u32 major; + __u32 minor; + struct lento_vfs_context info; +}; + +struct lento_input_iopen { + char *name; +#if BITS_PER_LONG < 64 + __u32 dummy; /* XXX on 64-bit platforms, this is not needed */ +#endif + __u64 ino; + __u32 generation; + __u32 flags; + __s32 fd; +}; + +struct lento_input_close { + __u32 fd; + struct lento_vfs_context info; +}; + +/* XXX: check for alignment */ +struct lento_input_ext_attr { + char *path; + char *name; + __u32 name_len; + char *buffer; + __u32 buffer_len; + __u32 flags; + __u32 mode; + struct lento_vfs_context info; +}; + +/* XXX should PRESTO_GET_* actually be of type _IOR, since we are reading? */ +#define PRESTO_GETMOUNT _IOW ('p',0x03, struct readmount *) +#define PRESTO_SETPID _IOW ('p',0x04, struct readmount *) +#define PRESTO_CLOSE_JOURNALF _IOW ('p',0x06, struct readmount *) +#define PRESTO_SET_FSETROOT _IOW ('p',0x07, struct readmount *) +#define PRESTO_CLEAR_FSETROOT _IOW ('p',0x08, struct readmount *) +#define PRESTO_SETOPT _IOW ('p',0x09, struct psdev_opt *) +#define PRESTO_GETOPT _IOW ('p',0x0a, struct psdev_opt *) +#define PRESTO_GET_KMLSIZE _IOW ('p',0x0b, struct psdev_opt *) +#define PRESTO_GET_RECNO _IOW ('p',0x0c, struct psdev_opt *) +#define PRESTO_VFS_SETATTR _IOW ('p',0x10, struct lento_input_attr *) +#define PRESTO_VFS_CREATE _IOW ('p',0x11, struct lento_input_mode *) +#define PRESTO_VFS_LINK _IOW ('p',0x12, struct lento_input_old_new *) +#define PRESTO_VFS_UNLINK _IOW ('p',0x13, struct lento_input *) +#define PRESTO_VFS_SYMLINK _IOW ('p',0x14, struct lento_input_old_new *) +#define PRESTO_VFS_MKDIR _IOW ('p',0x15, struct lento_input_mode *) +#define PRESTO_VFS_RMDIR _IOW ('p',0x16, struct lento_input *) +#define PRESTO_VFS_MKNOD _IOW ('p',0x17, struct lento_input_dev *) +#define PRESTO_VFS_RENAME _IOW ('p',0x18, struct lento_input_old_new *) +#define PRESTO_VFS_CLOSE _IOW ('p',0x1a, struct lento_input_close *) +#define PRESTO_VFS_IOPEN _IOW ('p',0x1b, struct lento_input_iopen *) +#define PRESTO_VFS_SETEXTATTR _IOW ('p',0x1c, struct lento_input_ext_attr *) +#define PRESTO_VFS_DELEXTATTR _IOW ('p',0x1d, struct lento_input_ext_attr *) + +#define PRESTO_MARK _IOW ('p',0x20, struct lento_input_open *) +#define PRESTO_RELEASE_PERMIT _IOW ('p',0x21, struct lento_input_open *) +#define PRESTO_CLEAR_ALL_FSETROOTS _IOW ('p',0x22, struct readmount *) +#define PRESTO_BACKFETCH_LML _IOW ('p',0x23, struct readmount *) +#define PRESTO_REINT _IOW ('p',0x24, struct readmount *) +#define PRESTO_CANCEL_LML _IOW ('p',0x25, struct readmount *) +#define PRESTO_RESET_FSET _IOW ('p',0x26, struct readmount *) +#define PRESTO_COMPLETE_CLOSES _IOW ('p',0x27, struct readmount *) + +#define PRESTO_REINT_BEGIN _IOW ('p',0x30, struct readmount *) +#define PRESTO_DO_REINT _IOW ('p',0x31, struct readmount *) +#define PRESTO_REINT_END _IOW ('p',0x32, struct readmount *) + +#endif diff --git a/include/linux/intermezzo_journal.h b/include/linux/intermezzo_journal.h new file mode 100644 index 000000000000..75ec0977e33d --- /dev/null +++ b/include/linux/intermezzo_journal.h @@ -0,0 +1,26 @@ +#ifndef __PRESTO_JOURNAL_H +#define __PRESTO_JOURNAL_H + + +#include <linux/version.h> + +struct journal_prefix { + int len; + u32 version; + int pid; + int uid; + int fsuid; + int fsgid; + int opcode; + u32 ngroups; + u32 groups[0]; +}; + +struct journal_suffix { + unsigned long prevrec; /* offset of previous record for dentry */ + int recno; + int time; + int len; +}; + +#endif diff --git a/include/linux/intermezzo_kml.h b/include/linux/intermezzo_kml.h new file mode 100644 index 000000000000..da11b5dcabdc --- /dev/null +++ b/include/linux/intermezzo_kml.h @@ -0,0 +1,261 @@ +#ifndef __INTERMEZZO_KML_H +#define __INTERMEZZO_KML_H + +#include <linux/version.h> +#include <linux/intermezzo_psdev.h> +#include <linux/fs.h> +#include <linux/intermezzo_journal.h> + +#define PRESTO_KML_MAJOR_VERSION 0x00010000 +#define PRESTO_KML_MINOR_VERSION 0x00002001 +#define PRESTO_OP_NOOP 0 +#define PRESTO_OP_CREATE 1 +#define PRESTO_OP_MKDIR 2 +#define PRESTO_OP_UNLINK 3 +#define PRESTO_OP_RMDIR 4 +#define PRESTO_OP_CLOSE 5 +#define PRESTO_OP_SYMLINK 6 +#define PRESTO_OP_RENAME 7 +#define PRESTO_OP_SETATTR 8 +#define PRESTO_OP_LINK 9 +#define PRESTO_OP_OPEN 10 +#define PRESTO_OP_MKNOD 11 +#define PRESTO_OP_WRITE 12 +#define PRESTO_OP_RELEASE 13 +#define PRESTO_OP_TRUNC 14 +#define PRESTO_OP_SETEXTATTR 15 +#define PRESTO_OP_DELEXTATTR 16 + +#define PRESTO_LML_DONE 1 /* flag to get first write to do LML */ +#define KML_KOP_MARK 0xffff + +struct presto_lml_data { + loff_t rec_offset; +}; + +struct big_journal_prefix { + u32 len; + u32 version; + u32 pid; + u32 uid; + u32 fsuid; + u32 fsgid; + u32 opcode; + u32 ngroups; + u32 groups[NGROUPS_MAX]; +}; + +enum kml_opcode { + KML_CREATE = 1, + KML_MKDIR, + KML_UNLINK, + KML_RMDIR, + KML_CLOSE, + KML_SYMLINK, + KML_RENAME, + KML_SETATTR, + KML_LINK, + KML_OPEN, + KML_MKNOD, + KML_ENDMARK = 0xff +}; + +struct kml_create { + char *path; + struct presto_version new_objectv, + old_parentv, + new_parentv; + int mode; + int uid; + int gid; +}; + +struct kml_open { +}; + +struct kml_mkdir { + char *path; + struct presto_version new_objectv, + old_parentv, + new_parentv; + int mode; + int uid; + int gid; +}; + +struct kml_unlink { + char *path, + *name; + struct presto_version old_tgtv, + old_parentv, + new_parentv; +}; + +struct kml_rmdir { + char *path, + *name; + struct presto_version old_tgtv, + old_parentv, + new_parentv; +}; + +struct kml_close { + int open_mode, + open_uid, + open_gid; + char *path; + struct presto_version new_objectv; + __u64 ino; + int generation; +}; + +struct kml_symlink { + char *sourcepath, + *targetpath; + struct presto_version new_objectv, + old_parentv, + new_parentv; + int uid; + int gid; +}; + +struct kml_rename { + char *sourcepath, + *targetpath; + struct presto_version old_objectv, + new_objectv, + old_tgtv, + new_tgtv; +}; + +struct kml_setattr { + char *path; + struct presto_version old_objectv; + struct iattr iattr; +}; + +struct kml_link { + char *sourcepath, + *targetpath; + struct presto_version new_objectv, + old_parentv, + new_parentv; +}; + +struct kml_mknod { + char *path; + struct presto_version new_objectv, + old_parentv, + new_parentv; + int mode; + int uid; + int gid; + int major; + int minor; +}; + +/* kml record items for optimizing */ +struct kml_kop_node +{ + u32 kml_recno; + u32 kml_flag; + u32 kml_op; + nlink_t i_nlink; + u32 i_ino; +}; + +struct kml_kop_lnode +{ + struct list_head chains; + struct kml_kop_node node; +}; + +struct kml_endmark { + u32 total; + struct kml_kop_node *kop; +}; + +/* kml_flag */ +#define KML_REC_DELETE 1 +#define KML_REC_EXIST 0 + +struct kml_optimize { + struct list_head kml_chains; + u32 kml_flag; + u32 kml_op; + nlink_t i_nlink; + u32 i_ino; +}; + +struct kml_rec { + /* attribute of this record */ + int rec_size; + int rec_kml_offset; + + struct big_journal_prefix rec_head; + union { + struct kml_create create; + struct kml_open open; + struct kml_mkdir mkdir; + struct kml_unlink unlink; + struct kml_rmdir rmdir; + struct kml_close close; + struct kml_symlink symlink; + struct kml_rename rename; + struct kml_setattr setattr; + struct kml_mknod mknod; + struct kml_link link; + struct kml_endmark endmark; + } rec_kml; + struct journal_suffix rec_tail; + + /* for kml optimize only */ + struct kml_optimize kml_optimize; +}; + +/* kml record items for optimizing */ +extern void kml_kop_init (struct presto_file_set *fset); +extern void kml_kop_addrec (struct presto_file_set *fset, + struct inode *ino, u32 op, u32 flag); +extern int kml_kop_flush (struct presto_file_set *fset); + +/* defined in kml_setup.c */ +extern int kml_init (struct presto_file_set *fset); +extern int kml_cleanup (struct presto_file_set *fset); + +/* defined in kml.c */ +extern int begin_kml_reint (struct file *file, unsigned long arg); +extern int do_kml_reint (struct file *file, unsigned long arg); +extern int end_kml_reint (struct file *file, unsigned long arg); + +/* kml_utils.c */ +extern char *dlogit (void *tbuf, const void *sbuf, int size); +extern char * bdup_printf (char *format, ...); + +/* defined in kml_decode.c */ +/* printop */ +#define PRINT_KML_PREFIX 0x1 +#define PRINT_KML_SUFFIX 0x2 +#define PRINT_KML_REC 0x4 +#define PRINT_KML_OPTIMIZE 0x8 +#define PRINT_KML_EXIST 0x10 +#define PRINT_KML_DELETE 0x20 +extern void kml_printrec (struct kml_rec *rec, int printop); +extern int print_allkmlrec (struct list_head *head, int printop); +extern int delete_kmlrec (struct list_head *head); +extern int kml_decoderec (char *buf, int pos, int buflen, int *size, + struct kml_rec **newrec); +extern int decode_kmlrec (struct list_head *head, char *kml_buf, int buflen); +extern void kml_freerec (struct kml_rec *rec); + +/* defined in kml_reint.c */ +#define KML_CLOSE_BACKFETCH 1 +extern int kml_reintbuf (struct kml_fsdata *kml_fsdata, + char *mtpt, struct kml_rec **rec); + +/* defined in kml_setup.c */ +extern int kml_init (struct presto_file_set *fset); +extern int kml_cleanup (struct presto_file_set *fset); + +#endif + diff --git a/include/linux/intermezzo_psdev.h b/include/linux/intermezzo_psdev.h new file mode 100644 index 000000000000..9b1e557bdd7a --- /dev/null +++ b/include/linux/intermezzo_psdev.h @@ -0,0 +1,72 @@ +#ifndef __PRESTO_PSDEV_H +#define __PRESTO_PSDEV_H + +#ifdef PRESTO_DEVEL +# define PRESTO_FS_NAME "izofs" +# define PRESTO_PSDEV_NAME "/dev/izo" +# define PRESTO_PSDEV_MAJOR 186 +#else +# define PRESTO_FS_NAME "InterMezzo" +# define PRESTO_PSDEV_NAME "/dev/intermezzo" +# define PRESTO_PSDEV_MAJOR 185 +#endif + +#define MAX_PRESTODEV 16 + +#include <linux/version.h> + +#if (LINUX_VERSION_CODE < KERNEL_VERSION(2,3,0)) +#define wait_queue_head_t struct wait_queue * +#define DECLARE_WAITQUEUE(name,task) \ + struct wait_queue name = { task, NULL } +#define init_waitqueue_head(arg) +#else +#ifndef __initfunc +#define __initfunc(arg) arg +#endif +#endif + + +/* represents state of a /dev/presto */ +/* communication pending & processing queues */ +struct upc_comm { + unsigned int uc_seq; + wait_queue_head_t uc_waitq; /* Lento wait queue */ + struct list_head uc_pending; + struct list_head uc_processing; + int uc_pid; /* Lento's pid */ + int uc_hard; /* allows signals during upcalls */ + int uc_no_filter; + int uc_no_journal; + int uc_no_upcall; + int uc_timeout; /* . sec: signals will dequeue upc */ + long uc_errorval; /* for testing I/O failures */ + struct list_head uc_cache_list; + int uc_minor; + char * uc_devname; +}; + +#define ISLENTO(minor) (current->pid == upc_comms[minor].uc_pid \ + || current->p_pptr->pid == upc_comms[minor].uc_pid) + +extern struct upc_comm upc_comms[MAX_PRESTODEV]; + +/* messages between presto filesystem in kernel and Venus */ +#define REQ_READ 1 +#define REQ_WRITE 2 +#define REQ_ASYNC 4 +#define REQ_DEAD 8 + +struct upc_req { + struct list_head rq_chain; + caddr_t rq_data; + u_short rq_flags; + u_short rq_bufsize; + u_short rq_rep_size; + u_short rq_opcode; /* copied from data to save lookup */ + int rq_unique; + wait_queue_head_t rq_sleep; /* process' wait queue */ + unsigned long rq_posttime; +}; + +#endif diff --git a/include/linux/intermezzo_upcall.h b/include/linux/intermezzo_upcall.h new file mode 100644 index 000000000000..0b3e6ff74e3a --- /dev/null +++ b/include/linux/intermezzo_upcall.h @@ -0,0 +1,146 @@ +/* + * Based on cfs.h from Coda, but revamped for increased simplicity. + * Linux modifications by Peter Braam, Aug 1996 + * Rewritten for InterMezzo + */ + +#ifndef _PRESTO_HEADER_ +#define _PRESTO_HEADER_ + + +/* upcall.c */ +#define SYNCHRONOUS 0 +#define ASYNCHRONOUS 1 + +int lento_permit(int minor, int pathlen, int fsetnamelen, char *path, char *fset); +int lento_opendir(int minor, int pathlen, char *path, int async); +int lento_kml(int minor, unsigned int offset, unsigned int first_recno, + unsigned int length, unsigned int last_recno, int namelen, + char *fsetname); +int lento_open(int minor, int pathlen, char *path); +int lento_journal(int minor, char *page, int async); +int lento_release_permit(int minor, int cookie); + +/* + * Kernel <--> Lento communications. + */ +/* upcalls */ +#define LENTO_PERMIT 1 +#define LENTO_JOURNAL 2 +#define LENTO_OPENDIR 3 +#define LENTO_OPEN 4 +#define LENTO_SIGNAL 5 +#define LENTO_KML 6 +#define LENTO_COOKIE 7 + +/* Lento <-> Presto RPC arguments */ +struct lento_up_hdr { + unsigned int opcode; + unsigned int unique; /* Keep multiple outstanding msgs distinct */ + u_short pid; /* Common to all */ + u_short uid; +}; + +/* This structure _must_ sit at the beginning of the buffer */ +struct lento_down_hdr { + unsigned int opcode; + unsigned int unique; + unsigned int result; +}; + +/* lento_permit: */ +struct lento_permit_in { + struct lento_up_hdr uh; + int pathlen; + int fsetnamelen; + char path[0]; +}; +struct lento_permit_out { + struct lento_down_hdr dh; +}; + + +/* lento_opendir: */ +struct lento_opendir_in { + struct lento_up_hdr uh; + int async; + int pathlen; + char path[0]; +}; +struct lento_opendir_out { + struct lento_down_hdr dh; +}; + + +/* lento_kml: */ +struct lento_kml_in { + struct lento_up_hdr uh; + unsigned int offset; + unsigned int first_recno; + unsigned int length; + unsigned int last_recno; + int namelen; + char fsetname[0]; +}; + +struct lento_kml_out { + struct lento_down_hdr dh; +}; + + +/* lento_open: */ +struct lento_open_in { + struct lento_up_hdr uh; + int pathlen; + char path[0]; +}; +struct lento_open_out { + struct lento_down_hdr dh; +}; + +/* lento_response_cookie */ +struct lento_response_cookie_in { + struct lento_up_hdr uh; + int cookie; +}; + +struct lento_response_cookie_out { + struct lento_down_hdr dh; +}; + + +struct lento_mknod { + struct lento_down_hdr dh; + int major; + int minor; + int mode; + char path[0]; +}; + + +/* NB: every struct below begins with an up_hdr */ +union up_args { + struct lento_up_hdr uh; + struct lento_permit_in lento_permit; + struct lento_open_in lento_open; + struct lento_opendir_in lento_opendir; + struct lento_kml_in lento_kml; + struct lento_response_cookie_in lento_response_cookie; +}; + +union down_args { + struct lento_down_hdr dh; + struct lento_permit_out lento_permit; + struct lento_open_out lento_open; + struct lento_opendir_out lento_opendir; + struct lento_kml_out lento_kml; + struct lento_response_cookie_out lento_response_cookie; +}; + +#include "intermezzo_psdev.h" + +int lento_upcall(int minor, int read_size, int *rep_size, + union up_args *buffer, int async, + struct upc_req *rq ); +#endif + diff --git a/include/linux/lvm.h b/include/linux/lvm.h index b1bc98c045a9..b3e68a6db266 100644 --- a/include/linux/lvm.h +++ b/include/linux/lvm.h @@ -52,6 +52,7 @@ * 08/12/1999 - changed LVM_LV_SIZE_MAX macro to reflect current 1TB limit * 01/01/2000 - extended lv_v2 core structure by wait_queue member * 12/02/2000 - integrated Andrea Arcagnelli's snapshot work + * 14/02/2001 - changed LVM_SNAPSHOT_MIN_CHUNK to 1 page * 18/02/2000 - seperated user and kernel space parts by * #ifdef them with __KERNEL__ * 08/03/2000 - implemented cluster/shared bits for vg_access @@ -60,6 +61,11 @@ * 12/11/2000 - removed unneeded timestamp definitions * 24/12/2000 - removed LVM_TO_{CORE,DISK}*, use cpu_{from, to}_le* * instead - Christoph Hellwig + * 01/03/2001 - Rename VG_CREATE to VG_CREATE_OLD and add new VG_CREATE + * 08/03/2001 - new lv_t (in core) version number 5: changed page member + * to (struct kiobuf *) to use for COW exception table io + * 23/03/2001 - Change a (presumably) mistyped pv_t* to an lv_t* + * 26/03/2001 - changed lv_v4 to lv_v5 in structure definition [HM] * */ @@ -67,9 +73,11 @@ #ifndef _LVM_H_INCLUDE #define _LVM_H_INCLUDE -#define _LVM_KERNEL_H_VERSION "LVM 0.9.1_beta2 (18/01/2001)" +#define LVM_RELEASE_NAME "1.0.1-rc4(ish)" +#define LVM_RELEASE_DATE "03/10/2001" + +#define _LVM_KERNEL_H_VERSION "LVM "LVM_RELEASE_NAME" ("LVM_RELEASE_DATE")" -#include <linux/config.h> #include <linux/version.h> /* @@ -127,24 +135,11 @@ #define SECTOR_SIZE 512 #endif -#define LVM_STRUCT_VERSION 1 /* structure version */ +/* structure version */ +#define LVM_STRUCT_VERSION 1 #define LVM_DIR_PREFIX "/dev/" -/* set the default structure version */ -#if ( LVM_STRUCT_VERSION == 1) -#define pv_t pv_v2_t -#define lv_t lv_v4_t -#define vg_t vg_v3_t -#define pv_disk_t pv_disk_v2_t -#define lv_disk_t lv_disk_v3_t -#define vg_disk_t vg_disk_v2_t -#define lv_block_exception_t lv_block_exception_v1_t -#define lv_COW_table_disk_t lv_COW_table_disk_v1_t -#endif - - - /* * i/o protocol version * @@ -194,67 +189,6 @@ /* - * VGDA: default disk spaces and offsets - * - * there's space after the structures for later extensions. - * - * offset what size - * --------------- ---------------------------------- ------------ - * 0 physical volume structure ~500 byte - * - * 1K volume group structure ~200 byte - * - * 6K namelist of physical volumes 128 byte each - * - * 6k + n * ~300byte n logical volume structures ~300 byte each - * - * + m * 4byte m physical extent alloc. structs 4 byte each - * - * End of disk - first physical extent typically 4 megabyte - * PE total * - * PE size - * - * - */ - -/* DONT TOUCH THESE !!! */ -/* base of PV structure in disk partition */ -#define LVM_PV_DISK_BASE 0L - -/* size reserved for PV structure on disk */ -#define LVM_PV_DISK_SIZE 1024L - -/* base of VG structure in disk partition */ -#define LVM_VG_DISK_BASE LVM_PV_DISK_SIZE - -/* size reserved for VG structure */ -#define LVM_VG_DISK_SIZE ( 9 * 512L) - -/* size reserved for timekeeping */ -#define LVM_TIMESTAMP_DISK_BASE ( LVM_VG_DISK_BASE + LVM_VG_DISK_SIZE) -#define LVM_TIMESTAMP_DISK_SIZE 512L /* reserved for timekeeping */ - -/* name list of physical volumes on disk */ -#define LVM_PV_UUIDLIST_DISK_BASE ( LVM_TIMESTAMP_DISK_BASE + \ - LVM_TIMESTAMP_DISK_SIZE) - -/* now for the dynamically calculated parts of the VGDA */ -#define LVM_LV_DISK_OFFSET(a, b) ( (a)->lv_on_disk.base + \ - sizeof ( lv_disk_t) * b) -#define LVM_DISK_SIZE(pv) ( (pv)->pe_on_disk.base + \ - (pv)->pe_on_disk.size) -#define LVM_PE_DISK_OFFSET(pe, pv) ( pe * pv->pe_size + \ - ( LVM_DISK_SIZE ( pv) / SECTOR_SIZE)) -#define LVM_PE_ON_DISK_BASE(pv) \ - { int rest; \ - pv->pe_on_disk.base = pv->lv_on_disk.base + pv->lv_on_disk.size; \ - if ( ( rest = pv->pe_on_disk.base % SECTOR_SIZE) != 0) \ - pv->pe_on_disk.base += ( SECTOR_SIZE - rest); \ - } -/* END default disk spaces and offsets for PVs */ - - -/* * LVM_PE_T_MAX corresponds to: * * 8KB PE size can map a ~512 MB logical volume at the cost of 1MB memory, @@ -283,9 +217,8 @@ #define LVM_MAX_STRIPES 128 /* max # of stripes */ #define LVM_MAX_SIZE ( 1024LU * 1024 / SECTOR_SIZE * 1024 * 1024) /* 1TB[sectors] */ #define LVM_MAX_MIRRORS 2 /* future use */ -#define LVM_MIN_READ_AHEAD 0 /* minimum read ahead sectors */ -#define LVM_DEFAULT_READ_AHEAD 1024 /* default read ahead sectors for 512k scsi segments */ -#define LVM_MAX_READ_AHEAD 10000 /* maximum read ahead sectors */ +#define LVM_MIN_READ_AHEAD 2 /* minimum read ahead sectors */ +#define LVM_MAX_READ_AHEAD 120 /* maximum read ahead sectors */ #define LVM_MAX_LV_IO_TIMEOUT 60 /* seconds I/O timeout (future use) */ #define LVM_PARTITION 0xfe /* LVM partition id */ #define LVM_NEW_PARTITION 0x8e /* new LVM partition id (10/09/1999) */ @@ -296,28 +229,15 @@ #define LVM_SNAPSHOT_MIN_CHUNK (PAGE_SIZE/1024) /* 4 or 8 KB */ #define UNDEF -1 -#define FALSE 0 -#define TRUE 1 - - -#define LVM_GET_COW_TABLE_CHUNKS_PER_PE(vg, lv) ( \ - vg->pe_size / lv->lv_chunk_size) - -#define LVM_GET_COW_TABLE_ENTRIES_PER_PE(vg, lv) ( \ -{ \ - int COW_table_entries_per_PE; \ - int COW_table_chunks_per_PE; \ -\ - COW_table_entries_per_PE = LVM_GET_COW_TABLE_CHUNKS_PER_PE(vg, lv); \ - COW_table_chunks_per_PE = ( COW_table_entries_per_PE * sizeof(lv_COW_table_disk_t) / SECTOR_SIZE + lv->lv_chunk_size - 1) / lv->lv_chunk_size; \ - COW_table_entries_per_PE - COW_table_chunks_per_PE;}) - /* * ioctls + * FIXME: the last parameter to _IO{W,R,WR} is a data type. The macro will + * expand this using sizeof(), so putting "1" there is misleading + * because sizeof(1) = sizeof(int) = sizeof(2) = 4 on a 32-bit machine! */ /* volume group */ -#define VG_CREATE _IOW ( 0xfe, 0x00, 1) +#define VG_CREATE_OLD _IOW ( 0xfe, 0x00, 1) #define VG_REMOVE _IOW ( 0xfe, 0x01, 1) #define VG_EXTEND _IOW ( 0xfe, 0x03, 1) @@ -330,6 +250,8 @@ #define VG_SET_EXTENDABLE _IOW ( 0xfe, 0x08, 1) #define VG_RENAME _IOW ( 0xfe, 0x09, 1) +/* Since 0.9beta6 */ +#define VG_CREATE _IOW ( 0xfe, 0x0a, 1) /* logical volume */ #define LV_CREATE _IOW ( 0xfe, 0x20, 1) @@ -412,6 +334,9 @@ #define PV_ALLOCATABLE 0x02 /* pv_allocatable */ +/* misc */ +#define LVM_SNAPSHOT_DROPPED_SECTOR 1 + /* * Structure definitions core/disk follow * @@ -424,21 +349,21 @@ #define UUID_LEN 32 /* don't change!!! */ /* copy on write tables in disk format */ -typedef struct { +typedef struct lv_COW_table_disk_v1 { uint64_t pv_org_number; uint64_t pv_org_rsector; uint64_t pv_snap_number; uint64_t pv_snap_rsector; -} lv_COW_table_disk_v1_t; +} lv_COW_table_disk_t; /* remap physical sector/rdev pairs including hash */ -typedef struct { +typedef struct lv_block_exception_v1 { struct list_head hash; - ulong rsector_org; - kdev_t rdev_org; - ulong rsector_new; - kdev_t rdev_new; -} lv_block_exception_v1_t; + uint32_t rsector_org; + kdev_t rdev_org; + uint32_t rsector_new; + kdev_t rdev_new; +} lv_block_exception_t; /* disk stored pe information */ typedef struct { @@ -454,37 +379,11 @@ typedef struct { /* - * Structure Physical Volume (PV) Version 1 + * physical volume structures */ /* core */ -typedef struct { - char id[2]; /* Identifier */ - unsigned short version; /* HM lvm version */ - lvm_disk_data_t pv_on_disk; - lvm_disk_data_t vg_on_disk; - lvm_disk_data_t pv_namelist_on_disk; - lvm_disk_data_t lv_on_disk; - lvm_disk_data_t pe_on_disk; - char pv_name[NAME_LEN]; - char vg_name[NAME_LEN]; - char system_id[NAME_LEN]; /* for vgexport/vgimport */ - kdev_t pv_dev; - uint pv_number; - uint pv_status; - uint pv_allocatable; - uint pv_size; /* HM */ - uint lv_cur; - uint pe_size; - uint pe_total; - uint pe_allocated; - uint pe_stale; /* for future use */ - pe_disk_t *pe; /* HM */ - struct inode *inode; /* HM */ -} pv_v1_t; - -/* core */ -typedef struct { +typedef struct pv_v2 { char id[2]; /* Identifier */ unsigned short version; /* HM lvm version */ lvm_disk_data_t pv_on_disk; @@ -506,36 +405,17 @@ typedef struct { uint pe_allocated; uint pe_stale; /* for future use */ pe_disk_t *pe; /* HM */ - struct inode *inode; /* HM */ + struct block_device *bd; char pv_uuid[UUID_LEN+1]; -} pv_v2_t; +#ifndef __KERNEL__ + uint32_t pe_start; /* in sectors */ +#endif +} pv_t; -/* disk */ -typedef struct { - uint8_t id[2]; /* Identifier */ - uint16_t version; /* HM lvm version */ - lvm_disk_data_t pv_on_disk; - lvm_disk_data_t vg_on_disk; - lvm_disk_data_t pv_namelist_on_disk; - lvm_disk_data_t lv_on_disk; - lvm_disk_data_t pe_on_disk; - uint8_t pv_name[NAME_LEN]; - uint8_t vg_name[NAME_LEN]; - uint8_t system_id[NAME_LEN]; /* for vgexport/vgimport */ - uint32_t pv_major; - uint32_t pv_number; - uint32_t pv_status; - uint32_t pv_allocatable; - uint32_t pv_size; /* HM */ - uint32_t lv_cur; - uint32_t pe_size; - uint32_t pe_total; - uint32_t pe_allocated; -} pv_disk_v1_t; /* disk */ -typedef struct { +typedef struct pv_disk_v2 { uint8_t id[2]; /* Identifier */ uint16_t version; /* HM lvm version */ lvm_disk_data_t pv_on_disk; @@ -555,7 +435,11 @@ typedef struct { uint32_t pe_size; uint32_t pe_total; uint32_t pe_allocated; -} pv_disk_v2_t; + + /* new in struct version 2 */ + uint32_t pe_start; /* in sectors */ + +} pv_disk_t; /* @@ -565,17 +449,17 @@ typedef struct { /* core PE information */ typedef struct { kdev_t dev; - ulong pe; /* to be changed if > 2TB */ - ulong reads; - ulong writes; + uint32_t pe; /* to be changed if > 2TB */ + uint32_t reads; + uint32_t writes; } pe_t; typedef struct { char lv_name[NAME_LEN]; kdev_t old_dev; kdev_t new_dev; - ulong old_pe; - ulong new_pe; + uint32_t old_pe; + uint32_t new_pe; } le_remap_req_t; typedef struct lv_bmap { @@ -588,7 +472,7 @@ typedef struct lv_bmap { */ /* core */ -typedef struct lv_v4 { +typedef struct lv_v5 { char lv_name[NAME_LEN]; char vg_name[NAME_LEN]; uint lv_access; @@ -611,9 +495,9 @@ typedef struct lv_v4 { uint lv_read_ahead; /* delta to version 1 starts here */ - struct lv_v4 *lv_snapshot_org; - struct lv_v4 *lv_snapshot_prev; - struct lv_v4 *lv_snapshot_next; + struct lv_v5 *lv_snapshot_org; + struct lv_v5 *lv_snapshot_prev; + struct lv_v5 *lv_snapshot_next; lv_block_exception_t *lv_block_exception; uint lv_remap_ptr; uint lv_remap_end; @@ -621,23 +505,23 @@ typedef struct lv_v4 { uint lv_snapshot_minor; #ifdef __KERNEL__ struct kiobuf *lv_iobuf; - struct semaphore lv_snapshot_sem; + struct kiobuf *lv_COW_table_iobuf; + struct rw_semaphore lv_lock; struct list_head *lv_snapshot_hash_table; - ulong lv_snapshot_hash_table_size; - ulong lv_snapshot_hash_mask; - struct page *lv_COW_table_page; + uint32_t lv_snapshot_hash_table_size; + uint32_t lv_snapshot_hash_mask; wait_queue_head_t lv_snapshot_wait; int lv_snapshot_use_rate; - void *vg; + struct vg_v3 *vg; uint lv_allocated_snapshot_le; #else char dummy[200]; #endif -} lv_v4_t; +} lv_t; /* disk */ -typedef struct { +typedef struct lv_disk_v3 { uint8_t lv_name[NAME_LEN]; uint8_t vg_name[NAME_LEN]; uint32_t lv_access; @@ -659,36 +543,14 @@ typedef struct { uint32_t lv_allocation; uint32_t lv_io_timeout; /* for future use */ uint32_t lv_read_ahead; /* HM */ -} lv_disk_v3_t; +} lv_disk_t; /* * Structure Volume Group (VG) Version 1 */ /* core */ -typedef struct { - char vg_name[NAME_LEN]; /* volume group name */ - uint vg_number; /* volume group number */ - uint vg_access; /* read/write */ - uint vg_status; /* active or not */ - uint lv_max; /* maximum logical volumes */ - uint lv_cur; /* current logical volumes */ - uint lv_open; /* open logical volumes */ - uint pv_max; /* maximum physical volumes */ - uint pv_cur; /* current physical volumes FU */ - uint pv_act; /* active physical volumes */ - uint dummy; /* was obsolete max_pe_per_pv */ - uint vgda; /* volume group descriptor arrays FU */ - uint pe_size; /* physical extent size in sectors */ - uint pe_total; /* total of physical extents */ - uint pe_allocated; /* allocated physical extents */ - uint pvg_total; /* physical volume groups FU */ - struct proc_dir_entry *proc; - pv_t *pv[ABS_MAX_PV + 1]; /* physical volume struct pointers */ - lv_t *lv[ABS_MAX_LV + 1]; /* logical volume struct pointers */ -} vg_v1_t; - -typedef struct { +typedef struct vg_v3 { char vg_name[NAME_LEN]; /* volume group name */ uint vg_number; /* volume group number */ uint vg_access; /* read/write */ @@ -716,30 +578,11 @@ typedef struct { #else char dummy1[200]; #endif -} vg_v3_t; +} vg_t; /* disk */ -typedef struct { - uint8_t vg_name[NAME_LEN]; /* volume group name */ - uint32_t vg_number; /* volume group number */ - uint32_t vg_access; /* read/write */ - uint32_t vg_status; /* active or not */ - uint32_t lv_max; /* maximum logical volumes */ - uint32_t lv_cur; /* current logical volumes */ - uint32_t lv_open; /* open logical volumes */ - uint32_t pv_max; /* maximum physical volumes */ - uint32_t pv_cur; /* current physical volumes FU */ - uint32_t pv_act; /* active physical volumes */ - uint32_t dummy; - uint32_t vgda; /* volume group descriptor arrays FU */ - uint32_t pe_size; /* physical extent size in sectors */ - uint32_t pe_total; /* total of physical extents */ - uint32_t pe_allocated; /* allocated physical extents */ - uint32_t pvg_total; /* physical volume groups FU */ -} vg_disk_v1_t; - -typedef struct { +typedef struct vg_disk_v2 { uint8_t vg_uuid[UUID_LEN]; /* volume group UUID */ uint8_t vg_name_dummy[NAME_LEN-UUID_LEN]; /* rest of v1 VG name */ uint32_t vg_number; /* volume group number */ @@ -757,7 +600,7 @@ typedef struct { uint32_t pe_total; /* total of physical extents */ uint32_t pe_allocated; /* allocated physical extents */ uint32_t pvg_total; /* physical volume groups FU */ -} vg_disk_v2_t; +} vg_disk_t; /* @@ -785,7 +628,7 @@ typedef struct { struct { kdev_t lv_dev; kdev_t pv_dev; - ulong pv_offset; + uint32_t pv_offset; } data; } pe_lock_req_t; @@ -798,7 +641,7 @@ typedef struct { /* Request structure LV_STATUS_BYINDEX */ typedef struct { - ulong lv_index; + uint32_t lv_index; lv_t *lv; /* Transfer size because user space and kernel space differ */ ushort size; @@ -807,7 +650,7 @@ typedef struct { /* Request structure LV_STATUS_BYDEV... */ typedef struct { dev_t dev; - pv_t *lv; + lv_t *lv; } lv_status_bydev_req_t; @@ -817,4 +660,37 @@ typedef struct { int rate; } lv_snapshot_use_rate_req_t; + +/* useful inlines */ +static inline ulong round_up(ulong n, ulong size) { + size--; + return (n + size) & ~size; +} + +static inline ulong div_up(ulong n, ulong size) { + return round_up(n, size) / size; +} + +static int inline LVM_GET_COW_TABLE_CHUNKS_PER_PE(vg_t *vg, lv_t *lv) { + return vg->pe_size / lv->lv_chunk_size; +} + +static int inline LVM_GET_COW_TABLE_ENTRIES_PER_PE(vg_t *vg, lv_t *lv) { + ulong chunks = vg->pe_size / lv->lv_chunk_size; + ulong entry_size = sizeof(lv_COW_table_disk_t); + ulong chunk_size = lv->lv_chunk_size * SECTOR_SIZE; + ulong entries = (vg->pe_size * SECTOR_SIZE) / + (entry_size + chunk_size); + + if(chunks < 2) + return 0; + + for(; entries; entries--) + if((div_up(entries * entry_size, chunk_size) + entries) <= + chunks) + break; + + return entries; +} + #endif /* #ifndef _LVM_H_INCLUDE */ diff --git a/include/linux/mm.h b/include/linux/mm.h index 171bf9e410d1..7737d585b0a2 100644 --- a/include/linux/mm.h +++ b/include/linux/mm.h @@ -43,7 +43,8 @@ extern struct list_head inactive_list; struct vm_area_struct { struct mm_struct * vm_mm; /* The address space we belong to. */ unsigned long vm_start; /* Our start address within vm_mm. */ - unsigned long vm_end; /* Our end address within vm_mm. */ + unsigned long vm_end; /* The first byte after our end address + within vm_mm. */ /* linked list of VM areas per task, sorted by address */ struct vm_area_struct *vm_next; diff --git a/include/linux/seq_file.h b/include/linux/seq_file.h new file mode 100644 index 000000000000..1cf66cd69e6c --- /dev/null +++ b/include/linux/seq_file.h @@ -0,0 +1,55 @@ +#ifndef _LINUX_SEQ_FILE_H +#define _LINUX_SEQ_FILE_H +#ifdef __KERNEL__ + +struct seq_operations; + +struct seq_file { + char *buf; + size_t size; + size_t from; + size_t count; + loff_t index; + struct semaphore sem; + struct seq_operations *op; +}; + +struct seq_operations { + void * (*start) (struct seq_file *m, loff_t *pos); + void (*stop) (struct seq_file *m, void *v); + void * (*next) (struct seq_file *m, void *v, loff_t *pos); + int (*show) (struct seq_file *m, void *v); +}; + +int seq_open(struct file *, struct seq_operations *); +ssize_t seq_read(struct file *, char *, size_t, loff_t *); +loff_t seq_lseek(struct file *, loff_t, int); +int seq_release(struct inode *, struct file *); +int seq_escape(struct seq_file *, const char *, const char *); + +static inline int seq_putc(struct seq_file *m, char c) +{ + if (m->count < m->size) { + m->buf[m->count++] = c; + return 0; + } + return -1; +} + +static inline int seq_puts(struct seq_file *m, const char *s) +{ + int len = strlen(s); + if (m->count + len < m->size) { + memcpy(m->buf + m->count, s, len); + m->count += len; + return 0; + } + m->count = m->size; + return -1; +} + +int seq_printf(struct seq_file *, const char *, ...) + __attribute__ ((format (printf,2,3))); + +#endif +#endif diff --git a/include/linux/sysctl.h b/include/linux/sysctl.h index de85345183a7..938560387354 100644 --- a/include/linux/sysctl.h +++ b/include/linux/sysctl.h @@ -62,7 +62,8 @@ enum CTL_DEBUG=6, /* Debugging */ CTL_DEV=7, /* Devices */ CTL_BUS=8, /* Busses */ - CTL_ABI=9 /* Binary emulation */ + CTL_ABI=9, /* Binary emulation */ + CTL_CPU=10 /* CPU stuff (speed scaling, etc) */ }; /* CTL_BUS names: */ |
