From 8de52778798fe39660a8d6b26f290e0c93202761 Mon Sep 17 00:00:00 2001 From: Al Viro Date: Mon, 6 Feb 2012 12:45:27 -0500 Subject: vfs: check i_nlink limits in vfs_{mkdir,rename_dir,link} New field of struct super_block - ->s_max_links. Maximal allowed value of ->i_nlink or 0; in the latter case all checks still need to be done in ->link/->mkdir/->rename instances. Note that this limit applies both to directoris and to non-directories. Signed-off-by: Al Viro --- include/linux/fs.h | 1 + 1 file changed, 1 insertion(+) (limited to 'include') diff --git a/include/linux/fs.h b/include/linux/fs.h index 69cd5bb640f5..0ab89426ba55 100644 --- a/include/linux/fs.h +++ b/include/linux/fs.h @@ -1459,6 +1459,7 @@ struct super_block { u8 s_uuid[16]; /* UUID */ void *s_fs_info; /* Filesystem private info */ + unsigned int s_max_links; fmode_t s_mode; /* Granularity of c/m/atime in ns. -- cgit v1.2.3 From b57ce9694ec43dcb6ef6f189d6540e4b3d2c5e7a Mon Sep 17 00:00:00 2001 From: Al Viro Date: Sun, 12 Feb 2012 02:38:16 -0500 Subject: vfs: drop_file_write_access() made static Signed-off-by: Al Viro --- include/linux/file.h | 1 - 1 file changed, 1 deletion(-) (limited to 'include') diff --git a/include/linux/file.h b/include/linux/file.h index 21a79958541c..58bf158c53d9 100644 --- a/include/linux/file.h +++ b/include/linux/file.h @@ -12,7 +12,6 @@ struct file; extern void fput(struct file *); -extern void drop_file_write_access(struct file *file); struct file_operations; struct vfsmount; -- cgit v1.2.3 From 9bcb4b733c22b7dbc4cf847e707ac98f751e9180 Mon Sep 17 00:00:00 2001 From: Al Viro Date: Sun, 12 Feb 2012 19:43:17 -0500 Subject: vfs: turn generic_drop_inode() into static inline Once upon a time it used to be much bigger, but these days there's no point whatsoever keeping it in fs/inode.c, especially since it's not even needed as initializer for ->drop_inode() - it's the default and leaving ->drop_inode NULL will do just as well. Signed-off-by: Al Viro --- include/linux/fs.h | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) (limited to 'include') diff --git a/include/linux/fs.h b/include/linux/fs.h index 0ab89426ba55..b89dc4d60d99 100644 --- a/include/linux/fs.h +++ b/include/linux/fs.h @@ -2305,7 +2305,10 @@ extern struct inode * igrab(struct inode *); extern ino_t iunique(struct super_block *, ino_t); extern int inode_needs_sync(struct inode *inode); extern int generic_delete_inode(struct inode *inode); -extern int generic_drop_inode(struct inode *inode); +static inline int generic_drop_inode(struct inode *inode) +{ + return !inode->i_nlink || inode_unhashed(inode); +} extern struct inode *ilookup5_nowait(struct super_block *sb, unsigned long hashval, int (*test)(struct inode *, void *), -- cgit v1.2.3 From 32991ab305ace7017c62f8eecbe5eb36dc32e13b Mon Sep 17 00:00:00 2001 From: Al Viro Date: Sun, 12 Feb 2012 22:15:47 -0500 Subject: vfs: d_alloc_root() gone all callers converted to d_make_root() by now Signed-off-by: Al Viro --- include/linux/dcache.h | 1 - 1 file changed, 1 deletion(-) (limited to 'include') diff --git a/include/linux/dcache.h b/include/linux/dcache.h index ff5f5256d175..7e11f1418203 100644 --- a/include/linux/dcache.h +++ b/include/linux/dcache.h @@ -222,7 +222,6 @@ extern void shrink_dcache_for_umount(struct super_block *); extern int d_invalidate(struct dentry *); /* only used at mount-time */ -extern struct dentry * d_alloc_root(struct inode *); extern struct dentry * d_make_root(struct inode *); /* - the ramfs-type tree */ -- cgit v1.2.3 From 5d026c7242201e7c9d0e12fcb2bcaffead9d59fd Mon Sep 17 00:00:00 2001 From: Kai Bankett Date: Fri, 17 Feb 2012 05:59:20 +0100 Subject: fs: initial qnx6fs addition Adds support for qnx6fs readonly support to the linux kernel. * Mount option The option mmi_fs can be used to mount Harman Becker/Audi MMI 3G HDD qnx6fs filesystems. * Documentation A high level filesystem stucture description can be found in the Documentation/filesystems directory. (qnx6.txt) * Additional features - Active (stable) superblock selection - Superblock checksum check (enforced) - Supports mount of qnx6 filesystems with to host different endianess - Automatic endianess detection - Longfilename support (with non-enfocing crc check) - All blocksizes (512, 1024, 2048 and 4096 supported) Signed-off-by: Kai Bankett Signed-off-by: Al Viro --- include/linux/magic.h | 1 + include/linux/qnx6_fs.h | 134 ++++++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 135 insertions(+) create mode 100644 include/linux/qnx6_fs.h (limited to 'include') diff --git a/include/linux/magic.h b/include/linux/magic.h index 2d4beab0d5b7..b7ed4759dbb2 100644 --- a/include/linux/magic.h +++ b/include/linux/magic.h @@ -42,6 +42,7 @@ #define OPENPROM_SUPER_MAGIC 0x9fa1 #define PROC_SUPER_MAGIC 0x9fa0 #define QNX4_SUPER_MAGIC 0x002f /* qnx4 fs detection */ +#define QNX6_SUPER_MAGIC 0x68191122 /* qnx6 fs detection */ #define REISERFS_SUPER_MAGIC 0x52654973 /* used by gcc */ /* used by file system utilities that diff --git a/include/linux/qnx6_fs.h b/include/linux/qnx6_fs.h new file mode 100644 index 000000000000..26049eab9010 --- /dev/null +++ b/include/linux/qnx6_fs.h @@ -0,0 +1,134 @@ +/* + * Name : qnx6_fs.h + * Author : Kai Bankett + * Function : qnx6 global filesystem definitions + * History : 17-01-2012 created + */ +#ifndef _LINUX_QNX6_FS_H +#define _LINUX_QNX6_FS_H + +#include +#include + +#define QNX6_ROOT_INO 1 + +/* for di_status */ +#define QNX6_FILE_DIRECTORY 0x01 +#define QNX6_FILE_DELETED 0x02 +#define QNX6_FILE_NORMAL 0x03 + +#define QNX6_SUPERBLOCK_SIZE 0x200 /* superblock always is 512 bytes */ +#define QNX6_SUPERBLOCK_AREA 0x1000 /* area reserved for superblock */ +#define QNX6_BOOTBLOCK_SIZE 0x2000 /* heading bootblock area */ +#define QNX6_DIR_ENTRY_SIZE 0x20 /* dir entry size of 32 bytes */ +#define QNX6_INODE_SIZE 0x80 /* each inode is 128 bytes */ +#define QNX6_INODE_SIZE_BITS 7 /* inode entry size shift */ + +#define QNX6_NO_DIRECT_POINTERS 16 /* 16 blockptrs in sbl/inode */ +#define QNX6_PTR_MAX_LEVELS 5 /* maximum indirect levels */ + +/* for filenames */ +#define QNX6_SHORT_NAME_MAX 27 +#define QNX6_LONG_NAME_MAX 510 + +/* list of mount options */ +#define QNX6_MOUNT_MMI_FS 0x010000 /* mount as Audi MMI 3G fs */ + +/* + * This is the original qnx6 inode layout on disk. + * Each inode is 128 byte long. + */ +struct qnx6_inode_entry { + __fs64 di_size; + __fs32 di_uid; + __fs32 di_gid; + __fs32 di_ftime; + __fs32 di_mtime; + __fs32 di_atime; + __fs32 di_ctime; + __fs16 di_mode; + __fs16 di_ext_mode; + __fs32 di_block_ptr[QNX6_NO_DIRECT_POINTERS]; + __u8 di_filelevels; + __u8 di_status; + __u8 di_unknown2[2]; + __fs32 di_zero2[6]; +}; + +/* + * Each directory entry is maximum 32 bytes long. + * If more characters or special characters required it is stored + * in the longfilenames structure. + */ +struct qnx6_dir_entry { + __fs32 de_inode; + __u8 de_size; + char de_fname[QNX6_SHORT_NAME_MAX]; +}; + +/* + * Longfilename direntries have a different structure + */ +struct qnx6_long_dir_entry { + __fs32 de_inode; + __u8 de_size; + __u8 de_unknown[3]; + __fs32 de_long_inode; + __fs32 de_checksum; +}; + +struct qnx6_long_filename { + __fs16 lf_size; + __u8 lf_fname[QNX6_LONG_NAME_MAX]; +}; + +struct qnx6_root_node { + __fs64 size; + __fs32 ptr[QNX6_NO_DIRECT_POINTERS]; + __u8 levels; + __u8 mode; + __u8 spare[6]; +}; + +struct qnx6_super_block { + __fs32 sb_magic; + __fs32 sb_checksum; + __fs64 sb_serial; + __fs32 sb_ctime; /* time the fs was created */ + __fs32 sb_atime; /* last access time */ + __fs32 sb_flags; + __fs16 sb_version1; /* filesystem version information */ + __fs16 sb_version2; /* filesystem version information */ + __u8 sb_volumeid[16]; + __fs32 sb_blocksize; + __fs32 sb_num_inodes; + __fs32 sb_free_inodes; + __fs32 sb_num_blocks; + __fs32 sb_free_blocks; + __fs32 sb_allocgroup; + struct qnx6_root_node Inode; + struct qnx6_root_node Bitmap; + struct qnx6_root_node Longfile; + struct qnx6_root_node Unknown; +}; + +/* Audi MMI 3G superblock layout is different to plain qnx6 */ +struct qnx6_mmi_super_block { + __fs32 sb_magic; + __fs32 sb_checksum; + __fs64 sb_serial; + __u8 sb_spare0[12]; + __u8 sb_id[12]; + __fs32 sb_blocksize; + __fs32 sb_num_inodes; + __fs32 sb_free_inodes; + __fs32 sb_num_blocks; + __fs32 sb_free_blocks; + __u8 sb_spare1[4]; + struct qnx6_root_node Inode; + struct qnx6_root_node Bitmap; + struct qnx6_root_node Longfile; + struct qnx6_root_node Unknown; +}; + +#endif -- cgit v1.2.3 From 66b3fad3f4c535c92b6a1184d535a97d6aa5d82a Mon Sep 17 00:00:00 2001 From: Al Viro Date: Wed, 14 Mar 2012 21:48:20 -0400 Subject: constify path argument of audit_log_d_path() Signed-off-by: Al Viro --- include/linux/audit.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'include') diff --git a/include/linux/audit.h b/include/linux/audit.h index 9ff7a2c48b50..ed3ef1972496 100644 --- a/include/linux/audit.h +++ b/include/linux/audit.h @@ -684,7 +684,7 @@ extern void audit_log_untrustedstring(struct audit_buffer *ab, const char *string); extern void audit_log_d_path(struct audit_buffer *ab, const char *prefix, - struct path *path); + const struct path *path); extern void audit_log_key(struct audit_buffer *ab, char *key); extern void audit_log_lost(const char *message); -- cgit v1.2.3 From 38eff2892628fa5c4fc8962a17b7296f42833ebe Mon Sep 17 00:00:00 2001 From: Al Viro Date: Wed, 14 Mar 2012 21:51:10 -0400 Subject: constify path argument of trace_seq_path() Signed-off-by: Al Viro --- include/linux/trace_seq.h | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'include') diff --git a/include/linux/trace_seq.h b/include/linux/trace_seq.h index 7dadc3df0c77..a32d86ec8bf2 100644 --- a/include/linux/trace_seq.h +++ b/include/linux/trace_seq.h @@ -44,7 +44,7 @@ extern int trace_seq_putmem(struct trace_seq *s, const void *mem, size_t len); extern int trace_seq_putmem_hex(struct trace_seq *s, const void *mem, size_t len); extern void *trace_seq_reserve(struct trace_seq *s, size_t len); -extern int trace_seq_path(struct trace_seq *s, struct path *path); +extern int trace_seq_path(struct trace_seq *s, const struct path *path); #else /* CONFIG_TRACING */ static inline int trace_seq_printf(struct trace_seq *s, const char *fmt, ...) @@ -88,7 +88,7 @@ static inline void *trace_seq_reserve(struct trace_seq *s, size_t len) { return NULL; } -static inline int trace_seq_path(struct trace_seq *s, struct path *path) +static inline int trace_seq_path(struct trace_seq *s, const struct path *path) { return 0; } -- cgit v1.2.3 From 40ffe67d2e89c7a475421d007becc11a2f88ea3d Mon Sep 17 00:00:00 2001 From: Al Viro Date: Wed, 14 Mar 2012 21:54:32 -0400 Subject: switch unix_sock to struct path Signed-off-by: Al Viro --- include/net/af_unix.h | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) (limited to 'include') diff --git a/include/net/af_unix.h b/include/net/af_unix.h index 5a4e29b168c9..ca68e2cef230 100644 --- a/include/net/af_unix.h +++ b/include/net/af_unix.h @@ -49,8 +49,7 @@ struct unix_sock { /* WARNING: sk has to be the first member */ struct sock sk; struct unix_address *addr; - struct dentry *dentry; - struct vfsmount *mnt; + struct path path; struct mutex readlock; struct sock *peer; struct sock *other; -- cgit v1.2.3 From 68ac1234fb949b66941d94dce4157742799fc581 Mon Sep 17 00:00:00 2001 From: Al Viro Date: Thu, 15 Mar 2012 08:21:57 -0400 Subject: switch touch_atime to struct path Signed-off-by: Al Viro --- include/linux/fs.h | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'include') diff --git a/include/linux/fs.h b/include/linux/fs.h index b89dc4d60d99..9bbe1a9ac432 100644 --- a/include/linux/fs.h +++ b/include/linux/fs.h @@ -1812,11 +1812,11 @@ static inline void inode_inc_iversion(struct inode *inode) spin_unlock(&inode->i_lock); } -extern void touch_atime(struct vfsmount *mnt, struct dentry *dentry); +extern void touch_atime(struct path *); static inline void file_accessed(struct file *file) { if (!(file->f_flags & O_NOATIME)) - touch_atime(file->f_path.mnt, file->f_path.dentry); + touch_atime(&file->f_path); } int sync_inode(struct inode *inode, struct writeback_control *wbc); -- cgit v1.2.3 From c45ac8887e778c4fa2b572c51a94a681a0955d4d Mon Sep 17 00:00:00 2001 From: Al Viro Date: Sat, 17 Mar 2012 00:59:06 -0400 Subject: take private bits of reiserfs_xattr.h to fs/reiserfs/xattr.h Signed-off-by: Al Viro --- include/linux/reiserfs_xattr.h | 128 ----------------------------------------- 1 file changed, 128 deletions(-) (limited to 'include') diff --git a/include/linux/reiserfs_xattr.h b/include/linux/reiserfs_xattr.h index c2b71473266e..d8ce17c2459a 100644 --- a/include/linux/reiserfs_xattr.h +++ b/include/linux/reiserfs_xattr.h @@ -21,132 +21,4 @@ struct reiserfs_security_handle { size_t length; }; -#ifdef __KERNEL__ - -#include -#include -#include -#include -#include - -struct inode; -struct dentry; -struct iattr; -struct super_block; -struct nameidata; - -int reiserfs_xattr_register_handlers(void) __init; -void reiserfs_xattr_unregister_handlers(void); -int reiserfs_xattr_init(struct super_block *sb, int mount_flags); -int reiserfs_lookup_privroot(struct super_block *sb); -int reiserfs_delete_xattrs(struct inode *inode); -int reiserfs_chown_xattrs(struct inode *inode, struct iattr *attrs); -int reiserfs_permission(struct inode *inode, int mask); - -#ifdef CONFIG_REISERFS_FS_XATTR -#define has_xattr_dir(inode) (REISERFS_I(inode)->i_flags & i_has_xattr_dir) -ssize_t reiserfs_getxattr(struct dentry *dentry, const char *name, - void *buffer, size_t size); -int reiserfs_setxattr(struct dentry *dentry, const char *name, - const void *value, size_t size, int flags); -ssize_t reiserfs_listxattr(struct dentry *dentry, char *buffer, size_t size); -int reiserfs_removexattr(struct dentry *dentry, const char *name); - -int reiserfs_xattr_get(struct inode *, const char *, void *, size_t); -int reiserfs_xattr_set(struct inode *, const char *, const void *, size_t, int); -int reiserfs_xattr_set_handle(struct reiserfs_transaction_handle *, - struct inode *, const char *, const void *, - size_t, int); - -extern const struct xattr_handler reiserfs_xattr_user_handler; -extern const struct xattr_handler reiserfs_xattr_trusted_handler; -extern const struct xattr_handler reiserfs_xattr_security_handler; -#ifdef CONFIG_REISERFS_FS_SECURITY -int reiserfs_security_init(struct inode *dir, struct inode *inode, - const struct qstr *qstr, - struct reiserfs_security_handle *sec); -int reiserfs_security_write(struct reiserfs_transaction_handle *th, - struct inode *inode, - struct reiserfs_security_handle *sec); -void reiserfs_security_free(struct reiserfs_security_handle *sec); -#endif - -static inline int reiserfs_xattrs_initialized(struct super_block *sb) -{ - return REISERFS_SB(sb)->priv_root != NULL; -} - -#define xattr_size(size) ((size) + sizeof(struct reiserfs_xattr_header)) -static inline loff_t reiserfs_xattr_nblocks(struct inode *inode, loff_t size) -{ - loff_t ret = 0; - if (reiserfs_file_data_log(inode)) { - ret = _ROUND_UP(xattr_size(size), inode->i_sb->s_blocksize); - ret >>= inode->i_sb->s_blocksize_bits; - } - return ret; -} - -/* We may have to create up to 3 objects: xattr root, xattr dir, xattr file. - * Let's try to be smart about it. - * xattr root: We cache it. If it's not cached, we may need to create it. - * xattr dir: If anything has been loaded for this inode, we can set a flag - * saying so. - * xattr file: Since we don't cache xattrs, we can't tell. We always include - * blocks for it. - * - * However, since root and dir can be created between calls - YOU MUST SAVE - * THIS VALUE. - */ -static inline size_t reiserfs_xattr_jcreate_nblocks(struct inode *inode) -{ - size_t nblocks = JOURNAL_BLOCKS_PER_OBJECT(inode->i_sb); - - if ((REISERFS_I(inode)->i_flags & i_has_xattr_dir) == 0) { - nblocks += JOURNAL_BLOCKS_PER_OBJECT(inode->i_sb); - if (!REISERFS_SB(inode->i_sb)->xattr_root->d_inode) - nblocks += JOURNAL_BLOCKS_PER_OBJECT(inode->i_sb); - } - - return nblocks; -} - -static inline void reiserfs_init_xattr_rwsem(struct inode *inode) -{ - init_rwsem(&REISERFS_I(inode)->i_xattr_sem); -} - -#else - -#define reiserfs_getxattr NULL -#define reiserfs_setxattr NULL -#define reiserfs_listxattr NULL -#define reiserfs_removexattr NULL - -static inline void reiserfs_init_xattr_rwsem(struct inode *inode) -{ -} -#endif /* CONFIG_REISERFS_FS_XATTR */ - -#ifndef CONFIG_REISERFS_FS_SECURITY -static inline int reiserfs_security_init(struct inode *dir, - struct inode *inode, - const struct qstr *qstr, - struct reiserfs_security_handle *sec) -{ - return 0; -} -static inline int -reiserfs_security_write(struct reiserfs_transaction_handle *th, - struct inode *inode, - struct reiserfs_security_handle *sec) -{ - return 0; -} -static inline void reiserfs_security_free(struct reiserfs_security_handle *sec) -{} -#endif - -#endif /* __KERNEL__ */ - #endif /* _LINUX_REISERFS_XATTR_H */ -- cgit v1.2.3 From a3063ab88fcbe5249f841cb95dfd626b8bf2674f Mon Sep 17 00:00:00 2001 From: Al Viro Date: Sat, 17 Mar 2012 01:03:10 -0400 Subject: move reiserfs_acl.h to fs/reiserfs/acl.h Signed-off-by: Al Viro --- include/linux/reiserfs_acl.h | 76 -------------------------------------------- 1 file changed, 76 deletions(-) delete mode 100644 include/linux/reiserfs_acl.h (limited to 'include') diff --git a/include/linux/reiserfs_acl.h b/include/linux/reiserfs_acl.h deleted file mode 100644 index f096b80e73d8..000000000000 --- a/include/linux/reiserfs_acl.h +++ /dev/null @@ -1,76 +0,0 @@ -#include -#include - -#define REISERFS_ACL_VERSION 0x0001 - -typedef struct { - __le16 e_tag; - __le16 e_perm; - __le32 e_id; -} reiserfs_acl_entry; - -typedef struct { - __le16 e_tag; - __le16 e_perm; -} reiserfs_acl_entry_short; - -typedef struct { - __le32 a_version; -} reiserfs_acl_header; - -static inline size_t reiserfs_acl_size(int count) -{ - if (count <= 4) { - return sizeof(reiserfs_acl_header) + - count * sizeof(reiserfs_acl_entry_short); - } else { - return sizeof(reiserfs_acl_header) + - 4 * sizeof(reiserfs_acl_entry_short) + - (count - 4) * sizeof(reiserfs_acl_entry); - } -} - -static inline int reiserfs_acl_count(size_t size) -{ - ssize_t s; - size -= sizeof(reiserfs_acl_header); - s = size - 4 * sizeof(reiserfs_acl_entry_short); - if (s < 0) { - if (size % sizeof(reiserfs_acl_entry_short)) - return -1; - return size / sizeof(reiserfs_acl_entry_short); - } else { - if (s % sizeof(reiserfs_acl_entry)) - return -1; - return s / sizeof(reiserfs_acl_entry) + 4; - } -} - -#ifdef CONFIG_REISERFS_FS_POSIX_ACL -struct posix_acl *reiserfs_get_acl(struct inode *inode, int type); -int reiserfs_acl_chmod(struct inode *inode); -int reiserfs_inherit_default_acl(struct reiserfs_transaction_handle *th, - struct inode *dir, struct dentry *dentry, - struct inode *inode); -int reiserfs_cache_default_acl(struct inode *dir); -extern const struct xattr_handler reiserfs_posix_acl_default_handler; -extern const struct xattr_handler reiserfs_posix_acl_access_handler; - -#else - -#define reiserfs_cache_default_acl(inode) 0 -#define reiserfs_get_acl NULL - -static inline int reiserfs_acl_chmod(struct inode *inode) -{ - return 0; -} - -static inline int -reiserfs_inherit_default_acl(struct reiserfs_transaction_handle *th, - const struct inode *dir, struct dentry *dentry, - struct inode *inode) -{ - return 0; -} -#endif -- cgit v1.2.3 From f466c6fdb3b1f043ff1977a8d2a1d0cd4dc164fa Mon Sep 17 00:00:00 2001 From: Al Viro Date: Sat, 17 Mar 2012 01:16:43 -0400 Subject: move private bits of reiserfs_fs.h to fs/reiserfs/reiserfs.h Signed-off-by: Al Viro --- include/linux/reiserfs_fs.h | 2334 ------------------------------------------- 1 file changed, 2334 deletions(-) (limited to 'include') diff --git a/include/linux/reiserfs_fs.h b/include/linux/reiserfs_fs.h index 2213ddcce20c..ea3700cd7367 100644 --- a/include/linux/reiserfs_fs.h +++ b/include/linux/reiserfs_fs.h @@ -1,32 +1,12 @@ /* * Copyright 1996, 1997, 1998 Hans Reiser, see reiserfs/README for licensing and copyright details */ - - /* this file has an amazingly stupid - name, yura please fix it to be - reiserfs.h, and merge all the rest - of our .h files that are in this - directory into it. */ - #ifndef _LINUX_REISER_FS_H #define _LINUX_REISER_FS_H #include #include -#ifdef __KERNEL__ -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#endif - /* * include/linux/reiser_fs.h * @@ -43,2318 +23,4 @@ #define REISERFS_IOC_GETVERSION FS_IOC_GETVERSION #define REISERFS_IOC_SETVERSION FS_IOC_SETVERSION -#ifdef __KERNEL__ -/* the 32 bit compat definitions with int argument */ -#define REISERFS_IOC32_UNPACK _IOW(0xCD, 1, int) -#define REISERFS_IOC32_GETFLAGS FS_IOC32_GETFLAGS -#define REISERFS_IOC32_SETFLAGS FS_IOC32_SETFLAGS -#define REISERFS_IOC32_GETVERSION FS_IOC32_GETVERSION -#define REISERFS_IOC32_SETVERSION FS_IOC32_SETVERSION - -/* - * Locking primitives. The write lock is a per superblock - * special mutex that has properties close to the Big Kernel Lock - * which was used in the previous locking scheme. - */ -void reiserfs_write_lock(struct super_block *s); -void reiserfs_write_unlock(struct super_block *s); -int reiserfs_write_lock_once(struct super_block *s); -void reiserfs_write_unlock_once(struct super_block *s, int lock_depth); - -#ifdef CONFIG_REISERFS_CHECK -void reiserfs_lock_check_recursive(struct super_block *s); -#else -static inline void reiserfs_lock_check_recursive(struct super_block *s) { } -#endif - -/* - * Several mutexes depend on the write lock. - * However sometimes we want to relax the write lock while we hold - * these mutexes, according to the release/reacquire on schedule() - * properties of the Bkl that were used. - * Reiserfs performances and locking were based on this scheme. - * Now that the write lock is a mutex and not the bkl anymore, doing so - * may result in a deadlock: - * - * A acquire write_lock - * A acquire j_commit_mutex - * A release write_lock and wait for something - * B acquire write_lock - * B can't acquire j_commit_mutex and sleep - * A can't acquire write lock anymore - * deadlock - * - * What we do here is avoiding such deadlock by playing the same game - * than the Bkl: if we can't acquire a mutex that depends on the write lock, - * we release the write lock, wait a bit and then retry. - * - * The mutexes concerned by this hack are: - * - The commit mutex of a journal list - * - The flush mutex - * - The journal lock - * - The inode mutex - */ -static inline void reiserfs_mutex_lock_safe(struct mutex *m, - struct super_block *s) -{ - reiserfs_lock_check_recursive(s); - reiserfs_write_unlock(s); - mutex_lock(m); - reiserfs_write_lock(s); -} - -static inline void -reiserfs_mutex_lock_nested_safe(struct mutex *m, unsigned int subclass, - struct super_block *s) -{ - reiserfs_lock_check_recursive(s); - reiserfs_write_unlock(s); - mutex_lock_nested(m, subclass); - reiserfs_write_lock(s); -} - -static inline void -reiserfs_down_read_safe(struct rw_semaphore *sem, struct super_block *s) -{ - reiserfs_lock_check_recursive(s); - reiserfs_write_unlock(s); - down_read(sem); - reiserfs_write_lock(s); -} - -/* - * When we schedule, we usually want to also release the write lock, - * according to the previous bkl based locking scheme of reiserfs. - */ -static inline void reiserfs_cond_resched(struct super_block *s) -{ - if (need_resched()) { - reiserfs_write_unlock(s); - schedule(); - reiserfs_write_lock(s); - } -} - -struct fid; - -/* in reading the #defines, it may help to understand that they employ - the following abbreviations: - - B = Buffer - I = Item header - H = Height within the tree (should be changed to LEV) - N = Number of the item in the node - STAT = stat data - DEH = Directory Entry Header - EC = Entry Count - E = Entry number - UL = Unsigned Long - BLKH = BLocK Header - UNFM = UNForMatted node - DC = Disk Child - P = Path - - These #defines are named by concatenating these abbreviations, - where first comes the arguments, and last comes the return value, - of the macro. - -*/ - -#define USE_INODE_GENERATION_COUNTER - -#define REISERFS_PREALLOCATE -#define DISPLACE_NEW_PACKING_LOCALITIES -#define PREALLOCATION_SIZE 9 - -/* n must be power of 2 */ -#define _ROUND_UP(x,n) (((x)+(n)-1u) & ~((n)-1u)) - -// to be ok for alpha and others we have to align structures to 8 byte -// boundary. -// FIXME: do not change 4 by anything else: there is code which relies on that -#define ROUND_UP(x) _ROUND_UP(x,8LL) - -/* debug levels. Right now, CONFIG_REISERFS_CHECK means print all debug -** messages. -*/ -#define REISERFS_DEBUG_CODE 5 /* extra messages to help find/debug errors */ - -void __reiserfs_warning(struct super_block *s, const char *id, - const char *func, const char *fmt, ...); -#define reiserfs_warning(s, id, fmt, args...) \ - __reiserfs_warning(s, id, __func__, fmt, ##args) -/* assertions handling */ - -/** always check a condition and panic if it's false. */ -#define __RASSERT(cond, scond, format, args...) \ -do { \ - if (!(cond)) \ - reiserfs_panic(NULL, "assertion failure", "(" #cond ") at " \ - __FILE__ ":%i:%s: " format "\n", \ - in_interrupt() ? -1 : task_pid_nr(current), \ - __LINE__, __func__ , ##args); \ -} while (0) - -#define RASSERT(cond, format, args...) __RASSERT(cond, #cond, format, ##args) - -#if defined( CONFIG_REISERFS_CHECK ) -#define RFALSE(cond, format, args...) __RASSERT(!(cond), "!(" #cond ")", format, ##args) -#else -#define RFALSE( cond, format, args... ) do {;} while( 0 ) -#endif - -#define CONSTF __attribute_const__ -/* - * Disk Data Structures - */ - -/***************************************************************************/ -/* SUPER BLOCK */ -/***************************************************************************/ - -/* - * Structure of super block on disk, a version of which in RAM is often accessed as REISERFS_SB(s)->s_rs - * the version in RAM is part of a larger structure containing fields never written to disk. - */ -#define UNSET_HASH 0 // read_super will guess about, what hash names - // in directories were sorted with -#define TEA_HASH 1 -#define YURA_HASH 2 -#define R5_HASH 3 -#define DEFAULT_HASH R5_HASH - -struct journal_params { - __le32 jp_journal_1st_block; /* where does journal start from on its - * device */ - __le32 jp_journal_dev; /* journal device st_rdev */ - __le32 jp_journal_size; /* size of the journal */ - __le32 jp_journal_trans_max; /* max number of blocks in a transaction. */ - __le32 jp_journal_magic; /* random value made on fs creation (this - * was sb_journal_block_count) */ - __le32 jp_journal_max_batch; /* max number of blocks to batch into a - * trans */ - __le32 jp_journal_max_commit_age; /* in seconds, how old can an async - * commit be */ - __le32 jp_journal_max_trans_age; /* in seconds, how old can a transaction - * be */ -}; - -/* this is the super from 3.5.X, where X >= 10 */ -struct reiserfs_super_block_v1 { - __le32 s_block_count; /* blocks count */ - __le32 s_free_blocks; /* free blocks count */ - __le32 s_root_block; /* root block number */ - struct journal_params s_journal; - __le16 s_blocksize; /* block size */ - __le16 s_oid_maxsize; /* max size of object id array, see - * get_objectid() commentary */ - __le16 s_oid_cursize; /* current size of object id array */ - __le16 s_umount_state; /* this is set to 1 when filesystem was - * umounted, to 2 - when not */ - char s_magic[10]; /* reiserfs magic string indicates that - * file system is reiserfs: - * "ReIsErFs" or "ReIsEr2Fs" or "ReIsEr3Fs" */ - __le16 s_fs_state; /* it is set to used by fsck to mark which - * phase of rebuilding is done */ - __le32 s_hash_function_code; /* indicate, what hash function is being use - * to sort names in a directory*/ - __le16 s_tree_height; /* height of disk tree */ - __le16 s_bmap_nr; /* amount of bitmap blocks needed to address - * each block of file system */ - __le16 s_version; /* this field is only reliable on filesystem - * with non-standard journal */ - __le16 s_reserved_for_journal; /* size in blocks of journal area on main - * device, we need to keep after - * making fs with non-standard journal */ -} __attribute__ ((__packed__)); - -#define SB_SIZE_V1 (sizeof(struct reiserfs_super_block_v1)) - -/* this is the on disk super block */ -struct reiserfs_super_block { - struct reiserfs_super_block_v1 s_v1; - __le32 s_inode_generation; - __le32 s_flags; /* Right now used only by inode-attributes, if enabled */ - unsigned char s_uuid[16]; /* filesystem unique identifier */ - unsigned char s_label[16]; /* filesystem volume label */ - __le16 s_mnt_count; /* Count of mounts since last fsck */ - __le16 s_max_mnt_count; /* Maximum mounts before check */ - __le32 s_lastcheck; /* Timestamp of last fsck */ - __le32 s_check_interval; /* Interval between checks */ - char s_unused[76]; /* zero filled by mkreiserfs and - * reiserfs_convert_objectid_map_v1() - * so any additions must be updated - * there as well. */ -} __attribute__ ((__packed__)); - -#define SB_SIZE (sizeof(struct reiserfs_super_block)) - -#define REISERFS_VERSION_1 0 -#define REISERFS_VERSION_2 2 - -// on-disk super block fields converted to cpu form -#define SB_DISK_SUPER_BLOCK(s) (REISERFS_SB(s)->s_rs) -#define SB_V1_DISK_SUPER_BLOCK(s) (&(SB_DISK_SUPER_BLOCK(s)->s_v1)) -#define SB_BLOCKSIZE(s) \ - le32_to_cpu ((SB_V1_DISK_SUPER_BLOCK(s)->s_blocksize)) -#define SB_BLOCK_COUNT(s) \ - le32_to_cpu ((SB_V1_DISK_SUPER_BLOCK(s)->s_block_count)) -#define SB_FREE_BLOCKS(s) \ - le32_to_cpu ((SB_V1_DISK_SUPER_BLOCK(s)->s_free_blocks)) -#define SB_REISERFS_MAGIC(s) \ - (SB_V1_DISK_SUPER_BLOCK(s)->s_magic) -#define SB_ROOT_BLOCK(s) \ - le32_to_cpu ((SB_V1_DISK_SUPER_BLOCK(s)->s_root_block)) -#define SB_TREE_HEIGHT(s) \ - le16_to_cpu ((SB_V1_DISK_SUPER_BLOCK(s)->s_tree_height)) -#define SB_REISERFS_STATE(s) \ - le16_to_cpu ((SB_V1_DISK_SUPER_BLOCK(s)->s_umount_state)) -#define SB_VERSION(s) le16_to_cpu ((SB_V1_DISK_SUPER_BLOCK(s)->s_version)) -#define SB_BMAP_NR(s) le16_to_cpu ((SB_V1_DISK_SUPER_BLOCK(s)->s_bmap_nr)) - -#define PUT_SB_BLOCK_COUNT(s, val) \ - do { SB_V1_DISK_SUPER_BLOCK(s)->s_block_count = cpu_to_le32(val); } while (0) -#define PUT_SB_FREE_BLOCKS(s, val) \ - do { SB_V1_DISK_SUPER_BLOCK(s)->s_free_blocks = cpu_to_le32(val); } while (0) -#define PUT_SB_ROOT_BLOCK(s, val) \ - do { SB_V1_DISK_SUPER_BLOCK(s)->s_root_block = cpu_to_le32(val); } while (0) -#define PUT_SB_TREE_HEIGHT(s, val) \ - do { SB_V1_DISK_SUPER_BLOCK(s)->s_tree_height = cpu_to_le16(val); } while (0) -#define PUT_SB_REISERFS_STATE(s, val) \ - do { SB_V1_DISK_SUPER_BLOCK(s)->s_umount_state = cpu_to_le16(val); } while (0) -#define PUT_SB_VERSION(s, val) \ - do { SB_V1_DISK_SUPER_BLOCK(s)->s_version = cpu_to_le16(val); } while (0) -#define PUT_SB_BMAP_NR(s, val) \ - do { SB_V1_DISK_SUPER_BLOCK(s)->s_bmap_nr = cpu_to_le16 (val); } while (0) - -#define SB_ONDISK_JP(s) (&SB_V1_DISK_SUPER_BLOCK(s)->s_journal) -#define SB_ONDISK_JOURNAL_SIZE(s) \ - le32_to_cpu ((SB_ONDISK_JP(s)->jp_journal_size)) -#define SB_ONDISK_JOURNAL_1st_BLOCK(s) \ - le32_to_cpu ((SB_ONDISK_JP(s)->jp_journal_1st_block)) -#define SB_ONDISK_JOURNAL_DEVICE(s) \ - le32_to_cpu ((SB_ONDISK_JP(s)->jp_journal_dev)) -#define SB_ONDISK_RESERVED_FOR_JOURNAL(s) \ - le16_to_cpu ((SB_V1_DISK_SUPER_BLOCK(s)->s_reserved_for_journal)) - -#define is_block_in_log_or_reserved_area(s, block) \ - block >= SB_JOURNAL_1st_RESERVED_BLOCK(s) \ - && block < SB_JOURNAL_1st_RESERVED_BLOCK(s) + \ - ((!is_reiserfs_jr(SB_DISK_SUPER_BLOCK(s)) ? \ - SB_ONDISK_JOURNAL_SIZE(s) + 1 : SB_ONDISK_RESERVED_FOR_JOURNAL(s))) - -int is_reiserfs_3_5(struct reiserfs_super_block *rs); -int is_reiserfs_3_6(struct reiserfs_super_block *rs); -int is_reiserfs_jr(struct reiserfs_super_block *rs); - -/* ReiserFS leaves the first 64k unused, so that partition labels have - enough space. If someone wants to write a fancy bootloader that - needs more than 64k, let us know, and this will be increased in size. - This number must be larger than than the largest block size on any - platform, or code will break. -Hans */ -#define REISERFS_DISK_OFFSET_IN_BYTES (64 * 1024) -#define REISERFS_FIRST_BLOCK unused_define -#define REISERFS_JOURNAL_OFFSET_IN_BYTES REISERFS_DISK_OFFSET_IN_BYTES - -/* the spot for the super in versions 3.5 - 3.5.10 (inclusive) */ -#define REISERFS_OLD_DISK_OFFSET_IN_BYTES (8 * 1024) - -/* reiserfs internal error code (used by search_by_key and fix_nodes)) */ -#define CARRY_ON 0 -#define REPEAT_SEARCH -1 -#define IO_ERROR -2 -#define NO_DISK_SPACE -3 -#define NO_BALANCING_NEEDED (-4) -#define NO_MORE_UNUSED_CONTIGUOUS_BLOCKS (-5) -#define QUOTA_EXCEEDED -6 - -typedef __u32 b_blocknr_t; -typedef __le32 unp_t; - -struct unfm_nodeinfo { - unp_t unfm_nodenum; - unsigned short unfm_freespace; -}; - -/* there are two formats of keys: 3.5 and 3.6 - */ -#define KEY_FORMAT_3_5 0 -#define KEY_FORMAT_3_6 1 - -/* there are two stat datas */ -#define STAT_DATA_V1 0 -#define STAT_DATA_V2 1 - -static inline struct reiserfs_inode_info *REISERFS_I(const struct inode *inode) -{ - return container_of(inode, struct reiserfs_inode_info, vfs_inode); -} - -static inline struct reiserfs_sb_info *REISERFS_SB(const struct super_block *sb) -{ - return sb->s_fs_info; -} - -/* Don't trust REISERFS_SB(sb)->s_bmap_nr, it's a u16 - * which overflows on large file systems. */ -static inline __u32 reiserfs_bmap_count(struct super_block *sb) -{ - return (SB_BLOCK_COUNT(sb) - 1) / (sb->s_blocksize * 8) + 1; -} - -static inline int bmap_would_wrap(unsigned bmap_nr) -{ - return bmap_nr > ((1LL << 16) - 1); -} - -/** this says about version of key of all items (but stat data) the - object consists of */ -#define get_inode_item_key_version( inode ) \ - ((REISERFS_I(inode)->i_flags & i_item_key_version_mask) ? KEY_FORMAT_3_6 : KEY_FORMAT_3_5) - -#define set_inode_item_key_version( inode, version ) \ - ({ if((version)==KEY_FORMAT_3_6) \ - REISERFS_I(inode)->i_flags |= i_item_key_version_mask; \ - else \ - REISERFS_I(inode)->i_flags &= ~i_item_key_version_mask; }) - -#define get_inode_sd_version(inode) \ - ((REISERFS_I(inode)->i_flags & i_stat_data_version_mask) ? STAT_DATA_V2 : STAT_DATA_V1) - -#define set_inode_sd_version(inode, version) \ - ({ if((version)==STAT_DATA_V2) \ - REISERFS_I(inode)->i_flags |= i_stat_data_version_mask; \ - else \ - REISERFS_I(inode)->i_flags &= ~i_stat_data_version_mask; }) - -/* This is an aggressive tail suppression policy, I am hoping it - improves our benchmarks. The principle behind it is that percentage - space saving is what matters, not absolute space saving. This is - non-intuitive, but it helps to understand it if you consider that the - cost to access 4 blocks is not much more than the cost to access 1 - block, if you have to do a seek and rotate. A tail risks a - non-linear disk access that is significant as a percentage of total - time cost for a 4 block file and saves an amount of space that is - less significant as a percentage of space, or so goes the hypothesis. - -Hans */ -#define STORE_TAIL_IN_UNFM_S1(n_file_size,n_tail_size,n_block_size) \ -(\ - (!(n_tail_size)) || \ - (((n_tail_size) > MAX_DIRECT_ITEM_LEN(n_block_size)) || \ - ( (n_file_size) >= (n_block_size) * 4 ) || \ - ( ( (n_file_size) >= (n_block_size) * 3 ) && \ - ( (n_tail_size) >= (MAX_DIRECT_ITEM_LEN(n_block_size))/4) ) || \ - ( ( (n_file_size) >= (n_block_size) * 2 ) && \ - ( (n_tail_size) >= (MAX_DIRECT_ITEM_LEN(n_block_size))/2) ) || \ - ( ( (n_file_size) >= (n_block_size) ) && \ - ( (n_tail_size) >= (MAX_DIRECT_ITEM_LEN(n_block_size) * 3)/4) ) ) \ -) - -/* Another strategy for tails, this one means only create a tail if all the - file would fit into one DIRECT item. - Primary intention for this one is to increase performance by decreasing - seeking. -*/ -#define STORE_TAIL_IN_UNFM_S2(n_file_size,n_tail_size,n_block_size) \ -(\ - (!(n_tail_size)) || \ - (((n_file_size) > MAX_DIRECT_ITEM_LEN(n_block_size)) ) \ -) - -/* - * values for s_umount_state field - */ -#define REISERFS_VALID_FS 1 -#define REISERFS_ERROR_FS 2 - -// -// there are 5 item types currently -// -#define TYPE_STAT_DATA 0 -#define TYPE_INDIRECT 1 -#define TYPE_DIRECT 2 -#define TYPE_DIRENTRY 3 -#define TYPE_MAXTYPE 3 -#define TYPE_ANY 15 // FIXME: comment is required - -/***************************************************************************/ -/* KEY & ITEM HEAD */ -/***************************************************************************/ - -// -// directories use this key as well as old files -// -struct offset_v1 { - __le32 k_offset; - __le32 k_uniqueness; -} __attribute__ ((__packed__)); - -struct offset_v2 { - __le64 v; -} __attribute__ ((__packed__)); - -static inline __u16 offset_v2_k_type(const struct offset_v2 *v2) -{ - __u8 type = le64_to_cpu(v2->v) >> 60; - return (type <= TYPE_MAXTYPE) ? type : TYPE_ANY; -} - -static inline void set_offset_v2_k_type(struct offset_v2 *v2, int type) -{ - v2->v = - (v2->v & cpu_to_le64(~0ULL >> 4)) | cpu_to_le64((__u64) type << 60); -} - -static inline loff_t offset_v2_k_offset(const struct offset_v2 *v2) -{ - return le64_to_cpu(v2->v) & (~0ULL >> 4); -} - -static inline void set_offset_v2_k_offset(struct offset_v2 *v2, loff_t offset) -{ - offset &= (~0ULL >> 4); - v2->v = (v2->v & cpu_to_le64(15ULL << 60)) | cpu_to_le64(offset); -} - -/* Key of an item determines its location in the S+tree, and - is composed of 4 components */ -struct reiserfs_key { - __le32 k_dir_id; /* packing locality: by default parent - directory object id */ - __le32 k_objectid; /* object identifier */ - union { - struct offset_v1 k_offset_v1; - struct offset_v2 k_offset_v2; - } __attribute__ ((__packed__)) u; -} __attribute__ ((__packed__)); - -struct in_core_key { - __u32 k_dir_id; /* packing locality: by default parent - directory object id */ - __u32 k_objectid; /* object identifier */ - __u64 k_offset; - __u8 k_type; -}; - -struct cpu_key { - struct in_core_key on_disk_key; - int version; - int key_length; /* 3 in all cases but direct2indirect and - indirect2direct conversion */ -}; - -/* Our function for comparing keys can compare keys of different - lengths. It takes as a parameter the length of the keys it is to - compare. These defines are used in determining what is to be passed - to it as that parameter. */ -#define REISERFS_FULL_KEY_LEN 4 -#define REISERFS_SHORT_KEY_LEN 2 - -/* The result of the key compare */ -#define FIRST_GREATER 1 -#define SECOND_GREATER -1 -#define KEYS_IDENTICAL 0 -#define KEY_FOUND 1 -#define KEY_NOT_FOUND 0 - -#define KEY_SIZE (sizeof(struct reiserfs_key)) -#define SHORT_KEY_SIZE (sizeof (__u32) + sizeof (__u32)) - -/* return values for search_by_key and clones */ -#define ITEM_FOUND 1 -#define ITEM_NOT_FOUND 0 -#define ENTRY_FOUND 1 -#define ENTRY_NOT_FOUND 0 -#define DIRECTORY_NOT_FOUND -1 -#define REGULAR_FILE_FOUND -2 -#define DIRECTORY_FOUND -3 -#define BYTE_FOUND 1 -#define BYTE_NOT_FOUND 0 -#define FILE_NOT_FOUND -1 - -#define POSITION_FOUND 1 -#define POSITION_NOT_FOUND 0 - -// return values for reiserfs_find_entry and search_by_entry_key -#define NAME_FOUND 1 -#define NAME_NOT_FOUND 0 -#define GOTO_PREVIOUS_ITEM 2 -#define NAME_FOUND_INVISIBLE 3 - -/* Everything in the filesystem is stored as a set of items. The - item head contains the key of the item, its free space (for - indirect items) and specifies the location of the item itself - within the block. */ - -struct item_head { - /* Everything in the tree is found by searching for it based on - * its key.*/ - struct reiserfs_key ih_key; - union { - /* The free space in the last unformatted node of an - indirect item if this is an indirect item. This - equals 0xFFFF iff this is a direct item or stat data - item. Note that the key, not this field, is used to - determine the item type, and thus which field this - union contains. */ - __le16 ih_free_space_reserved; - /* Iff this is a directory item, this field equals the - number of directory entries in the directory item. */ - __le16 ih_entry_count; - } __attribute__ ((__packed__)) u; - __le16 ih_item_len; /* total size of the item body */ - __le16 ih_item_location; /* an offset to the item body - * within the block */ - __le16 ih_version; /* 0 for all old items, 2 for new - ones. Highest bit is set by fsck - temporary, cleaned after all - done */ -} __attribute__ ((__packed__)); -/* size of item header */ -#define IH_SIZE (sizeof(struct item_head)) - -#define ih_free_space(ih) le16_to_cpu((ih)->u.ih_free_space_reserved) -#define ih_version(ih) le16_to_cpu((ih)->ih_version) -#define ih_entry_count(ih) le16_to_cpu((ih)->u.ih_entry_count) -#define ih_location(ih) le16_to_cpu((ih)->ih_item_location) -#define ih_item_len(ih) le16_to_cpu((ih)->ih_item_len) - -#define put_ih_free_space(ih, val) do { (ih)->u.ih_free_space_reserved = cpu_to_le16(val); } while(0) -#define put_ih_version(ih, val) do { (ih)->ih_version = cpu_to_le16(val); } while (0) -#define put_ih_entry_count(ih, val) do { (ih)->u.ih_entry_count = cpu_to_le16(val); } while (0) -#define put_ih_location(ih, val) do { (ih)->ih_item_location = cpu_to_le16(val); } while (0) -#define put_ih_item_len(ih, val) do { (ih)->ih_item_len = cpu_to_le16(val); } while (0) - -#define unreachable_item(ih) (ih_version(ih) & (1 << 15)) - -#define get_ih_free_space(ih) (ih_version (ih) == KEY_FORMAT_3_6 ? 0 : ih_free_space (ih)) -#define set_ih_free_space(ih,val) put_ih_free_space((ih), ((ih_version(ih) == KEY_FORMAT_3_6) ? 0 : (val))) - -/* these operate on indirect items, where you've got an array of ints -** at a possibly unaligned location. These are a noop on ia32 -** -** p is the array of __u32, i is the index into the array, v is the value -** to store there. -*/ -#define get_block_num(p, i) get_unaligned_le32((p) + (i)) -#define put_block_num(p, i, v) put_unaligned_le32((v), (p) + (i)) - -// -// in old version uniqueness field shows key type -// -#define V1_SD_UNIQUENESS 0 -#define V1_INDIRECT_UNIQUENESS 0xfffffffe -#define V1_DIRECT_UNIQUENESS 0xffffffff -#define V1_DIRENTRY_UNIQUENESS 500 -#define V1_ANY_UNIQUENESS 555 // FIXME: comment is required - -// -// here are conversion routines -// -static inline int uniqueness2type(__u32 uniqueness) CONSTF; -static inline int uniqueness2type(__u32 uniqueness) -{ - switch ((int)uniqueness) { - case V1_SD_UNIQUENESS: - return TYPE_STAT_DATA; - case V1_INDIRECT_UNIQUENESS: - return TYPE_INDIRECT; - case V1_DIRECT_UNIQUENESS: - return TYPE_DIRECT; - case V1_DIRENTRY_UNIQUENESS: - return TYPE_DIRENTRY; - case V1_ANY_UNIQUENESS: - default: - return TYPE_ANY; - } -} - -static inline __u32 type2uniqueness(int type) CONSTF; -static inline __u32 type2uniqueness(int type) -{ - switch (type) { - case TYPE_STAT_DATA: - return V1_SD_UNIQUENESS; - case TYPE_INDIRECT: - return V1_INDIRECT_UNIQUENESS; - case TYPE_DIRECT: - return V1_DIRECT_UNIQUENESS; - case TYPE_DIRENTRY: - return V1_DIRENTRY_UNIQUENESS; - case TYPE_ANY: - default: - return V1_ANY_UNIQUENESS; - } -} - -// -// key is pointer to on disk key which is stored in le, result is cpu, -// there is no way to get version of object from key, so, provide -// version to these defines -// -static inline loff_t le_key_k_offset(int version, - const struct reiserfs_key *key) -{ - return (version == KEY_FORMAT_3_5) ? - le32_to_cpu(key->u.k_offset_v1.k_offset) : - offset_v2_k_offset(&(key->u.k_offset_v2)); -} - -static inline loff_t le_ih_k_offset(const struct item_head *ih) -{ - return le_key_k_offset(ih_version(ih), &(ih->ih_key)); -} - -static inline loff_t le_key_k_type(int version, const struct reiserfs_key *key) -{ - return (version == KEY_FORMAT_3_5) ? - uniqueness2type(le32_to_cpu(key->u.k_offset_v1.k_uniqueness)) : - offset_v2_k_type(&(key->u.k_offset_v2)); -} - -static inline loff_t le_ih_k_type(const struct item_head *ih) -{ - return le_key_k_type(ih_version(ih), &(ih->ih_key)); -} - -static inline void set_le_key_k_offset(int version, struct reiserfs_key *key, - loff_t offset) -{ - (version == KEY_FORMAT_3_5) ? (void)(key->u.k_offset_v1.k_offset = cpu_to_le32(offset)) : /* jdm check */ - (void)(set_offset_v2_k_offset(&(key->u.k_offset_v2), offset)); -} - -static inline void set_le_ih_k_offset(struct item_head *ih, loff_t offset) -{ - set_le_key_k_offset(ih_version(ih), &(ih->ih_key), offset); -} - -static inline void set_le_key_k_type(int version, struct reiserfs_key *key, - int type) -{ - (version == KEY_FORMAT_3_5) ? - (void)(key->u.k_offset_v1.k_uniqueness = - cpu_to_le32(type2uniqueness(type))) - : (void)(set_offset_v2_k_type(&(key->u.k_offset_v2), type)); -} - -static inline void set_le_ih_k_type(struct item_head *ih, int type) -{ - set_le_key_k_type(ih_version(ih), &(ih->ih_key), type); -} - -static inline int is_direntry_le_key(int version, struct reiserfs_key *key) -{ - return le_key_k_type(version, key) == TYPE_DIRENTRY; -} - -static inline int is_direct_le_key(int version, struct reiserfs_key *key) -{ - return le_key_k_type(version, key) == TYPE_DIRECT; -} - -static inline int is_indirect_le_key(int version, struct reiserfs_key *key) -{ - return le_key_k_type(version, key) == TYPE_INDIRECT; -} - -static inline int is_statdata_le_key(int version, struct reiserfs_key *key) -{ - return le_key_k_type(version, key) == TYPE_STAT_DATA; -} - -// -// item header has version. -// -static inline int is_direntry_le_ih(struct item_head *ih) -{ - return is_direntry_le_key(ih_version(ih), &ih->ih_key); -} - -static inline int is_direct_le_ih(struct item_head *ih) -{ - return is_direct_le_key(ih_version(ih), &ih->ih_key); -} - -static inline int is_indirect_le_ih(struct item_head *ih) -{ - return is_indirect_le_key(ih_version(ih), &ih->ih_key); -} - -static inline int is_statdata_le_ih(struct item_head *ih) -{ - return is_statdata_le_key(ih_version(ih), &ih->ih_key); -} - -// -// key is pointer to cpu key, result is cpu -// -static inline loff_t cpu_key_k_offset(const struct cpu_key *key) -{ - return key->on_disk_key.k_offset; -} - -static inline loff_t cpu_key_k_type(const struct cpu_key *key) -{ - return key->on_disk_key.k_type; -} - -static inline void set_cpu_key_k_offset(struct cpu_key *key, loff_t offset) -{ - key->on_disk_key.k_offset = offset; -} - -static inline void set_cpu_key_k_type(struct cpu_key *key, int type) -{ - key->on_disk_key.k_type = type; -} - -static inline void cpu_key_k_offset_dec(struct cpu_key *key) -{ - key->on_disk_key.k_offset--; -} - -#define is_direntry_cpu_key(key) (cpu_key_k_type (key) == TYPE_DIRENTRY) -#define is_direct_cpu_key(key) (cpu_key_k_type (key) == TYPE_DIRECT) -#define is_indirect_cpu_key(key) (cpu_key_k_type (key) == TYPE_INDIRECT) -#define is_statdata_cpu_key(key) (cpu_key_k_type (key) == TYPE_STAT_DATA) - -/* are these used ? */ -#define is_direntry_cpu_ih(ih) (is_direntry_cpu_key (&((ih)->ih_key))) -#define is_direct_cpu_ih(ih) (is_direct_cpu_key (&((ih)->ih_key))) -#define is_indirect_cpu_ih(ih) (is_indirect_cpu_key (&((ih)->ih_key))) -#define is_statdata_cpu_ih(ih) (is_statdata_cpu_key (&((ih)->ih_key))) - -#define I_K_KEY_IN_ITEM(ih, key, n_blocksize) \ - (!COMP_SHORT_KEYS(ih, key) && \ - I_OFF_BYTE_IN_ITEM(ih, k_offset(key), n_blocksize)) - -/* maximal length of item */ -#define MAX_ITEM_LEN(block_size) (block_size - BLKH_SIZE - IH_SIZE) -#define MIN_ITEM_LEN 1 - -/* object identifier for root dir */ -#define REISERFS_ROOT_OBJECTID 2 -#define REISERFS_ROOT_PARENT_OBJECTID 1 - -extern struct reiserfs_key root_key; - -/* - * Picture represents a leaf of the S+tree - * ______________________________________________________ - * | | Array of | | | - * |Block | Object-Item | F r e e | Objects- | - * | head | Headers | S p a c e | Items | - * |______|_______________|___________________|___________| - */ - -/* Header of a disk block. More precisely, header of a formatted leaf - or internal node, and not the header of an unformatted node. */ -struct block_head { - __le16 blk_level; /* Level of a block in the tree. */ - __le16 blk_nr_item; /* Number of keys/items in a block. */ - __le16 blk_free_space; /* Block free space in bytes. */ - __le16 blk_reserved; - /* dump this in v4/planA */ - struct reiserfs_key blk_right_delim_key; /* kept only for compatibility */ -}; - -#define BLKH_SIZE (sizeof(struct block_head)) -#define blkh_level(p_blkh) (le16_to_cpu((p_blkh)->blk_level)) -#define blkh_nr_item(p_blkh) (le16_to_cpu((p_blkh)->blk_nr_item)) -#define blkh_free_space(p_blkh) (le16_to_cpu((p_blkh)->blk_free_space)) -#define blkh_reserved(p_blkh) (le16_to_cpu((p_blkh)->blk_reserved)) -#define set_blkh_level(p_blkh,val) ((p_blkh)->blk_level = cpu_to_le16(val)) -#define set_blkh_nr_item(p_blkh,val) ((p_blkh)->blk_nr_item = cpu_to_le16(val)) -#define set_blkh_free_space(p_blkh,val) ((p_blkh)->blk_free_space = cpu_to_le16(val)) -#define set_blkh_reserved(p_blkh,val) ((p_blkh)->blk_reserved = cpu_to_le16(val)) -#define blkh_right_delim_key(p_blkh) ((p_blkh)->blk_right_delim_key) -#define set_blkh_right_delim_key(p_blkh,val) ((p_blkh)->blk_right_delim_key = val) - -/* - * values for blk_level field of the struct block_head - */ - -#define FREE_LEVEL 0 /* when node gets removed from the tree its - blk_level is set to FREE_LEVEL. It is then - used to see whether the node is still in the - tree */ - -#define DISK_LEAF_NODE_LEVEL 1 /* Leaf node level. */ - -/* Given the buffer head of a formatted node, resolve to the block head of that node. */ -#define B_BLK_HEAD(bh) ((struct block_head *)((bh)->b_data)) -/* Number of items that are in buffer. */ -#define B_NR_ITEMS(bh) (blkh_nr_item(B_BLK_HEAD(bh))) -#define B_LEVEL(bh) (blkh_level(B_BLK_HEAD(bh))) -#define B_FREE_SPACE(bh) (blkh_free_space(B_BLK_HEAD(bh))) - -#define PUT_B_NR_ITEMS(bh, val) do { set_blkh_nr_item(B_BLK_HEAD(bh), val); } while (0) -#define PUT_B_LEVEL(bh, val) do { set_blkh_level(B_BLK_HEAD(bh), val); } while (0) -#define PUT_B_FREE_SPACE(bh, val) do { set_blkh_free_space(B_BLK_HEAD(bh), val); } while (0) - -/* Get right delimiting key. -- little endian */ -#define B_PRIGHT_DELIM_KEY(bh) (&(blk_right_delim_key(B_BLK_HEAD(bh)))) - -/* Does the buffer contain a disk leaf. */ -#define B_IS_ITEMS_LEVEL(bh) (B_LEVEL(bh) == DISK_LEAF_NODE_LEVEL) - -/* Does the buffer contain a disk internal node */ -#define B_IS_KEYS_LEVEL(bh) (B_LEVEL(bh) > DISK_LEAF_NODE_LEVEL \ - && B_LEVEL(bh) <= MAX_HEIGHT) - -/***************************************************************************/ -/* STAT DATA */ -/***************************************************************************/ - -// -// old stat data is 32 bytes long. We are going to distinguish new one by -// different size -// -struct stat_data_v1 { - __le16 sd_mode; /* file type, permissions */ - __le16 sd_nlink; /* number of hard links */ - __le16 sd_uid; /* owner */ - __le16 sd_gid; /* group */ - __le32 sd_size; /* file size */ - __le32 sd_atime; /* time of last access */ - __le32 sd_mtime; /* time file was last modified */ - __le32 sd_ctime; /* time inode (stat data) was last changed (except changes to sd_atime and sd_mtime) */ - union { - __le32 sd_rdev; - __le32 sd_blocks; /* number of blocks file uses */ - } __attribute__ ((__packed__)) u; - __le32 sd_first_direct_byte; /* first byte of file which is stored - in a direct item: except that if it - equals 1 it is a symlink and if it - equals ~(__u32)0 there is no - direct item. The existence of this - field really grates on me. Let's - replace it with a macro based on - sd_size and our tail suppression - policy. Someday. -Hans */ -} __attribute__ ((__packed__)); - -#define SD_V1_SIZE (sizeof(struct stat_data_v1)) -#define stat_data_v1(ih) (ih_version (ih) == KEY_FORMAT_3_5) -#define sd_v1_mode(sdp) (le16_to_cpu((sdp)->sd_mode)) -#define set_sd_v1_mode(sdp,v) ((sdp)->sd_mode = cpu_to_le16(v)) -#define sd_v1_nlink(sdp) (le16_to_cpu((sdp)->sd_nlink)) -#define set_sd_v1_nlink(sdp,v) ((sdp)->sd_nlink = cpu_to_le16(v)) -#define sd_v1_uid(sdp) (le16_to_cpu((sdp)->sd_uid)) -#define set_sd_v1_uid(sdp,v) ((sdp)->sd_uid = cpu_to_le16(v)) -#define sd_v1_gid(sdp) (le16_to_cpu((sdp)->sd_gid)) -#define set_sd_v1_gid(sdp,v) ((sdp)->sd_gid = cpu_to_le16(v)) -#define sd_v1_size(sdp) (le32_to_cpu((sdp)->sd_size)) -#define set_sd_v1_size(sdp,v) ((sdp)->sd_size = cpu_to_le32(v)) -#define sd_v1_atime(sdp) (le32_to_cpu((sdp)->sd_atime)) -#define set_sd_v1_atime(sdp,v) ((sdp)->sd_atime = cpu_to_le32(v)) -#define sd_v1_mtime(sdp) (le32_to_cpu((sdp)->sd_mtime)) -#define set_sd_v1_mtime(sdp,v) ((sdp)->sd_mtime = cpu_to_le32(v)) -#define sd_v1_ctime(sdp) (le32_to_cpu((sdp)->sd_ctime)) -#define set_sd_v1_ctime(sdp,v) ((sdp)->sd_ctime = cpu_to_le32(v)) -#define sd_v1_rdev(sdp) (le32_to_cpu((sdp)->u.sd_rdev)) -#define set_sd_v1_rdev(sdp,v) ((sdp)->u.sd_rdev = cpu_to_le32(v)) -#define sd_v1_blocks(sdp) (le32_to_cpu((sdp)->u.sd_blocks)) -#define set_sd_v1_blocks(sdp,v) ((sdp)->u.sd_blocks = cpu_to_le32(v)) -#define sd_v1_first_direct_byte(sdp) \ - (le32_to_cpu((sdp)->sd_first_direct_byte)) -#define set_sd_v1_first_direct_byte(sdp,v) \ - ((sdp)->sd_first_direct_byte = cpu_to_le32(v)) - -/* inode flags stored in sd_attrs (nee sd_reserved) */ - -/* we want common flags to have the same values as in ext2, - so chattr(1) will work without problems */ -#define REISERFS_IMMUTABLE_FL FS_IMMUTABLE_FL -#define REISERFS_APPEND_FL FS_APPEND_FL -#define REISERFS_SYNC_FL FS_SYNC_FL -#define REISERFS_NOATIME_FL FS_NOATIME_FL -#define REISERFS_NODUMP_FL FS_NODUMP_FL -#define REISERFS_SECRM_FL FS_SECRM_FL -#define REISERFS_UNRM_FL FS_UNRM_FL -#define REISERFS_COMPR_FL FS_COMPR_FL -#define REISERFS_NOTAIL_FL FS_NOTAIL_FL - -/* persistent flags that file inherits from the parent directory */ -#define REISERFS_INHERIT_MASK ( REISERFS_IMMUTABLE_FL | \ - REISERFS_SYNC_FL | \ - REISERFS_NOATIME_FL | \ - REISERFS_NODUMP_FL | \ - REISERFS_SECRM_FL | \ - REISERFS_COMPR_FL | \ - REISERFS_NOTAIL_FL ) - -/* Stat Data on disk (reiserfs version of UFS disk inode minus the - address blocks) */ -struct stat_data { - __le16 sd_mode; /* file type, permissions */ - __le16 sd_attrs; /* persistent inode flags */ - __le32 sd_nlink; /* number of hard links */ - __le64 sd_size; /* file size */ - __le32 sd_uid; /* owner */ - __le32 sd_gid; /* group */ - __le32 sd_atime; /* time of last access */ - __le32 sd_mtime; /* time file was last modified */ - __le32 sd_ctime; /* time inode (stat data) was last changed (except changes to sd_atime and sd_mtime) */ - __le32 sd_blocks; - union { - __le32 sd_rdev; - __le32 sd_generation; - //__le32 sd_first_direct_byte; - /* first byte of file which is stored in a - direct item: except that if it equals 1 - it is a symlink and if it equals - ~(__u32)0 there is no direct item. The - existence of this field really grates - on me. Let's replace it with a macro - based on sd_size and our tail - suppression policy? */ - } __attribute__ ((__packed__)) u; -} __attribute__ ((__packed__)); -// -// this is 44 bytes long -// -#define SD_SIZE (sizeof(struct stat_data)) -#define SD_V2_SIZE SD_SIZE -#define stat_data_v2(ih) (ih_version (ih) == KEY_FORMAT_3_6) -#define sd_v2_mode(sdp) (le16_to_cpu((sdp)->sd_mode)) -#define set_sd_v2_mode(sdp,v) ((sdp)->sd_mode = cpu_to_le16(v)) -/* sd_reserved */ -/* set_sd_reserved */ -#define sd_v2_nlink(sdp) (le32_to_cpu((sdp)->sd_nlink)) -#define set_sd_v2_nlink(sdp,v) ((sdp)->sd_nlink = cpu_to_le32(v)) -#define sd_v2_size(sdp) (le64_to_cpu((sdp)->sd_size)) -#define set_sd_v2_size(sdp,v) ((sdp)->sd_size = cpu_to_le64(v)) -#define sd_v2_uid(sdp) (le32_to_cpu((sdp)->sd_uid)) -#define set_sd_v2_uid(sdp,v) ((sdp)->sd_uid = cpu_to_le32(v)) -#define sd_v2_gid(sdp) (le32_to_cpu((sdp)->sd_gid)) -#define set_sd_v2_gid(sdp,v) ((sdp)->sd_gid = cpu_to_le32(v)) -#define sd_v2_atime(sdp) (le32_to_cpu((sdp)->sd_atime)) -#define set_sd_v2_atime(sdp,v) ((sdp)->sd_atime = cpu_to_le32(v)) -#define sd_v2_mtime(sdp) (le32_to_cpu((sdp)->sd_mtime)) -#define set_sd_v2_mtime(sdp,v) ((sdp)->sd_mtime = cpu_to_le32(v)) -#define sd_v2_ctime(sdp) (le32_to_cpu((sdp)->sd_ctime)) -#define set_sd_v2_ctime(sdp,v) ((sdp)->sd_ctime = cpu_to_le32(v)) -#define sd_v2_blocks(sdp) (le32_to_cpu((sdp)->sd_blocks)) -#define set_sd_v2_blocks(sdp,v) ((sdp)->sd_blocks = cpu_to_le32(v)) -#define sd_v2_rdev(sdp) (le32_to_cpu((sdp)->u.sd_rdev)) -#define set_sd_v2_rdev(sdp,v) ((sdp)->u.sd_rdev = cpu_to_le32(v)) -#define sd_v2_generation(sdp) (le32_to_cpu((sdp)->u.sd_generation)) -#define set_sd_v2_generation(sdp,v) ((sdp)->u.sd_generation = cpu_to_le32(v)) -#define sd_v2_attrs(sdp) (le16_to_cpu((sdp)->sd_attrs)) -#define set_sd_v2_attrs(sdp,v) ((sdp)->sd_attrs = cpu_to_le16(v)) - -/***************************************************************************/ -/* DIRECTORY STRUCTURE */ -/***************************************************************************/ -/* - Picture represents the structure of directory items - ________________________________________________ - | Array of | | | | | | - | directory |N-1| N-2 | .... | 1st |0th| - | entry headers | | | | | | - |_______________|___|_____|________|_______|___| - <---- directory entries ------> - - First directory item has k_offset component 1. We store "." and ".." - in one item, always, we never split "." and ".." into differing - items. This makes, among other things, the code for removing - directories simpler. */ -#define SD_OFFSET 0 -#define SD_UNIQUENESS 0 -#define DOT_OFFSET 1 -#define DOT_DOT_OFFSET 2 -#define DIRENTRY_UNIQUENESS 500 - -/* */ -#define FIRST_ITEM_OFFSET 1 - -/* - Q: How to get key of object pointed to by entry from entry? - - A: Each directory entry has its header. This header has deh_dir_id and deh_objectid fields, those are key - of object, entry points to */ - -/* NOT IMPLEMENTED: - Directory will someday contain stat data of object */ - -struct reiserfs_de_head { - __le32 deh_offset; /* third component of the directory entry key */ - __le32 deh_dir_id; /* objectid of the parent directory of the object, that is referenced - by directory entry */ - __le32 deh_objectid; /* objectid of the object, that is referenced by directory entry */ - __le16 deh_location; /* offset of name in the whole item */ - __le16 deh_state; /* whether 1) entry contains stat data (for future), and 2) whether - entry is hidden (unlinked) */ -} __attribute__ ((__packed__)); -#define DEH_SIZE sizeof(struct reiserfs_de_head) -#define deh_offset(p_deh) (le32_to_cpu((p_deh)->deh_offset)) -#define deh_dir_id(p_deh) (le32_to_cpu((p_deh)->deh_dir_id)) -#define deh_objectid(p_deh) (le32_to_cpu((p_deh)->deh_objectid)) -#define deh_location(p_deh) (le16_to_cpu((p_deh)->deh_location)) -#define deh_state(p_deh) (le16_to_cpu((p_deh)->deh_state)) - -#define put_deh_offset(p_deh,v) ((p_deh)->deh_offset = cpu_to_le32((v))) -#define put_deh_dir_id(p_deh,v) ((p_deh)->deh_dir_id = cpu_to_le32((v))) -#define put_deh_objectid(p_deh,v) ((p_deh)->deh_objectid = cpu_to_le32((v))) -#define put_deh_location(p_deh,v) ((p_deh)->deh_location = cpu_to_le16((v))) -#define put_deh_state(p_deh,v) ((p_deh)->deh_state = cpu_to_le16((v))) - -/* empty directory contains two entries "." and ".." and their headers */ -#define EMPTY_DIR_SIZE \ -(DEH_SIZE * 2 + ROUND_UP (strlen (".")) + ROUND_UP (strlen (".."))) - -/* old format directories have this size when empty */ -#define EMPTY_DIR_SIZE_V1 (DEH_SIZE * 2 + 3) - -#define DEH_Statdata 0 /* not used now */ -#define DEH_Visible 2 - -/* 64 bit systems (and the S/390) need to be aligned explicitly -jdm */ -#if BITS_PER_LONG == 64 || defined(__s390__) || defined(__hppa__) -# define ADDR_UNALIGNED_BITS (3) -#endif - -/* These are only used to manipulate deh_state. - * Because of this, we'll use the ext2_ bit routines, - * since they are little endian */ -#ifdef ADDR_UNALIGNED_BITS - -# define aligned_address(addr) ((void *)((long)(addr) & ~((1UL << ADDR_UNALIGNED_BITS) - 1))) -# define unaligned_offset(addr) (((int)((long)(addr) & ((1 << ADDR_UNALIGNED_BITS) - 1))) << 3) - -# define set_bit_unaligned(nr, addr) \ - __test_and_set_bit_le((nr) + unaligned_offset(addr), aligned_address(addr)) -# define clear_bit_unaligned(nr, addr) \ - __test_and_clear_bit_le((nr) + unaligned_offset(addr), aligned_address(addr)) -# define test_bit_unaligned(nr, addr) \ - test_bit_le((nr) + unaligned_offset(addr), aligned_address(addr)) - -#else - -# define set_bit_unaligned(nr, addr) __test_and_set_bit_le(nr, addr) -# define clear_bit_unaligned(nr, addr) __test_and_clear_bit_le(nr, addr) -# define test_bit_unaligned(nr, addr) test_bit_le(nr, addr) - -#endif - -#define mark_de_with_sd(deh) set_bit_unaligned (DEH_Statdata, &((deh)->deh_state)) -#define mark_de_without_sd(deh) clear_bit_unaligned (DEH_Statdata, &((deh)->deh_state)) -#define mark_de_visible(deh) set_bit_unaligned (DEH_Visible, &((deh)->deh_state)) -#define mark_de_hidden(deh) clear_bit_unaligned (DEH_Visible, &((deh)->deh_state)) - -#define de_with_sd(deh) test_bit_unaligned (DEH_Statdata, &((deh)->deh_state)) -#define de_visible(deh) test_bit_unaligned (DEH_Visible, &((deh)->deh_state)) -#define de_hidden(deh) !test_bit_unaligned (DEH_Visible, &((deh)->deh_state)) - -extern void make_empty_dir_item_v1(char *body, __le32 dirid, __le32 objid, - __le32 par_dirid, __le32 par_objid); -extern void make_empty_dir_item(char *body, __le32 dirid, __le32 objid, - __le32 par_dirid, __le32 par_objid); - -/* array of the entry headers *