Page Menu
Home
FreeBSD
Search
Configure Global Search
Log In
Files
F144875046
D10151.id26864.diff
No One
Temporary
Actions
View File
Edit File
Delete File
View Transforms
Subscribe
Mute Notifications
Flag For Later
Award Token
Size
18 KB
Referenced Files
None
Subscribers
None
D10151.id26864.diff
View Options
Index: sys/conf/files
===================================================================
--- sys/conf/files
+++ sys/conf/files
@@ -3533,6 +3533,7 @@
fs/ext2fs/ext2_alloc.c optional ext2fs
fs/ext2fs/ext2_balloc.c optional ext2fs
fs/ext2fs/ext2_bmap.c optional ext2fs
+fs/ext2fs/ext2_extattr.c optional ext2fs
fs/ext2fs/ext2_extents.c optional ext2fs
fs/ext2fs/ext2_inode.c optional ext2fs
fs/ext2fs/ext2_inode_cnv.c optional ext2fs
Index: sys/fs/ext2fs/ext2_extattr.h
===================================================================
--- /dev/null
+++ sys/fs/ext2fs/ext2_extattr.h
@@ -0,0 +1,104 @@
+/*-
+ * Copyright (c) 2017, Fedor Uporov
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ *
+ * $FreeBSD$
+ */
+
+#ifndef _FS_EXT2FS_EXT2_EXTARTTR_H_
+#define _FS_EXT2FS_EXT2_EXTARTTR_H_
+
+/* Linux xattr name indexes */
+#define EXT4_XATTR_INDEX_USER 1
+#define EXT4_XATTR_INDEX_POSIX_ACL_ACCESS 2
+#define EXT4_XATTR_INDEX_POSIX_ACL_DEFAULT 3
+#define EXT4_XATTR_INDEX_TRUSTED 4
+#define EXT4_XATTR_INDEX_LUSTRE 5
+#define EXT4_XATTR_INDEX_SECURITY 6
+#define EXT4_XATTR_INDEX_SYSTEM 7
+#define EXT4_XATTR_INDEX_RICHACL 8
+#define EXT4_XATTR_INDEX_ENCRYPTION 9
+
+/* Magic value in attribute blocks */
+#define EXTATTR_MAGIC 0xEA020000
+
+struct ext2fs_extattr_header {
+ int32_t h_magic; /* magic number for identification */
+ int32_t h_refcount; /* reference count */
+ int32_t h_blocks; /* number of disk blocks used */
+ int32_t h_hash; /* hash value of all attributes */
+ uint32_t h_reserved[4]; /* zero right now */
+};
+
+struct ext2fs_extattr_dinode_header {
+ int32_t h_magic; /* magic number for identification */
+};
+
+struct ext2fs_extattr_entry {
+ uint8_t e_name_len; /* length of name */
+ uint8_t e_name_index; /* attribute name index */
+ uint16_t e_value_offs; /* offset in disk block of value */
+ uint32_t e_value_block; /* disk block attribute is stored on (n/i) */
+ uint32_t e_value_size; /* size of attribute value */
+ uint32_t e_hash; /* hash value of name and value */
+ char e_name[0]; /* attribute name */
+};
+
+#define EXT2_IHDR(inode, raw_inode) \
+ ((struct ext4_xattr_ibody_header *) \
+ ((void *)raw_inode + \
+ EXT4_GOOD_OLD_INODE_SIZE + \
+ EXT4_I(inode)->i_extra_isize))
+
+#define EXT2_IFIRST(hdr) ((struct ext2fs_extattr_entry *)((hdr)+1))
+
+#define EXT2_HDR(bh) ((struct ext2fs_extattr_header *)((bh)->b_data))
+#define EXT2_ENTRY(ptr) ((struct ext2fs_extattr_entry *)(ptr))
+#define EXT2_FIRST_ENTRY(bh) EXT2_ENTRY(EXT2_HDR(bh)+1)
+#define EXT2_IS_LAST_ENTRY(entry) (*(uint32_t *)(entry) == 0)
+
+#define EXT2_EXTATTR_PAD_BITS 2
+#define EXT2_EXTATTR_PAD (1<<EXT2_EXTATTR_PAD_BITS)
+#define EXT2_EXTATTR_ROUND (EXT2_EXTATTR_PAD-1)
+#define EXT2_EXTATTR_LEN(name_len) \
+ (((name_len) + EXT2_EXTATTR_ROUND + \
+ sizeof(struct ext2fs_extattr_entry)) & ~EXT2_EXTATTR_ROUND)
+
+#define EXT2_EXTATTR_NEXT(entry) \
+ ( (struct ext2fs_extattr_entry *)( \
+ (char *)(entry) + EXT2_EXTATTR_LEN((entry)->e_name_len)) )
+
+int ext2_extattr_inode_list(struct inode *ip, int attrnamespace,
+ struct uio *uio, size_t *size);
+
+int ext2_extattr_block_list(struct inode *ip, int attrnamespace,
+ struct uio *uio, size_t *size);
+
+int ext2_extattr_inode_get(struct inode *ip, int attrnamespace,
+ const char *name, struct uio *uio, size_t *size);
+
+int ext2_extattr_block_get(struct inode *ip, int attrnamespace,
+ const char *name, struct uio *uio, size_t *size);
+
+#endif /* !_FS_EXT2FS_EXT2_EXTARTTR_H_ */
Index: sys/fs/ext2fs/ext2_extattr.c
===================================================================
--- /dev/null
+++ sys/fs/ext2fs/ext2_extattr.c
@@ -0,0 +1,330 @@
+/*-
+ * Copyright (c) 2017, Fedor Uporov
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ *
+ * $FreeBSD$
+ */
+
+#include <sys/param.h>
+#include <sys/systm.h>
+#include <sys/types.h>
+#include <sys/kernel.h>
+#include <sys/malloc.h>
+#include <sys/vnode.h>
+#include <sys/bio.h>
+#include <sys/buf.h>
+#include <sys/endian.h>
+#include <sys/conf.h>
+#include <sys/extattr.h>
+
+#include <fs/ext2fs/fs.h>
+#include <fs/ext2fs/ext2fs.h>
+#include <fs/ext2fs/inode.h>
+#include <fs/ext2fs/ext2_dinode.h>
+#include <fs/ext2fs/ext2_mount.h>
+#include <fs/ext2fs/ext2_extattr.h>
+
+
+static int
+ext2_extattr_index_to_bsd(int index)
+{
+ switch (index) {
+ case EXT4_XATTR_INDEX_USER:
+ return EXTATTR_NAMESPACE_USER;
+
+ case EXT4_XATTR_INDEX_SYSTEM:
+ return EXTATTR_NAMESPACE_SYSTEM;
+
+ default:
+ return EXTATTR_NAMESPACE_EMPTY;
+ }
+}
+
+int
+ext2_extattr_inode_list(struct inode *ip, int attrnamespace,
+ struct uio *uio, size_t *size)
+{
+ struct m_ext2fs *fs;
+ struct buf *bp;
+ struct ext2fs_extattr_dinode_header *header;
+ struct ext2fs_extattr_entry *entry;
+ struct ext2fs_extattr_entry *next;
+ char *end;
+ int error;
+
+ fs = ip->i_e2fs;
+
+ if ((error = bread(ip->i_devvp,
+ fsbtodb(fs, ino_to_fsba(fs, ip->i_number)),
+ (int)fs->e2fs_bsize, NOCRED, &bp)) != 0) {
+ brelse(bp);
+ return (error);
+ }
+
+ struct ext2fs_dinode *dinode = (struct ext2fs_dinode *)
+ ((char *)bp->b_data +
+ EXT2_INODE_SIZE(fs) * ino_to_fsbo(fs, ip->i_number));
+
+ /* Check attributes magic value */
+ header = (struct ext2fs_extattr_dinode_header *)((char *)dinode +
+ E2FS_REV0_INODE_SIZE + dinode->e2di_extra_isize);
+
+ if (header->h_magic != EXTATTR_MAGIC) {
+ brelse(bp);
+ return (0);
+ }
+
+ /* Check attributes integrity */
+ entry = EXT2_IFIRST(header);
+ end = (char *)dinode + EXT2_INODE_SIZE(fs);
+ while (!EXT2_IS_LAST_ENTRY(entry)) {
+ next = EXT2_EXTATTR_NEXT(entry);
+ if ((char *)next >= end) {
+ brelse(bp);
+ return (EIO);
+ }
+
+ entry = next;
+ }
+
+ for (entry = EXT2_IFIRST(header); !EXT2_IS_LAST_ENTRY(entry);
+ entry = EXT2_EXTATTR_NEXT(entry)) {
+ if (ext2_extattr_index_to_bsd(entry->e_name_index) != attrnamespace)
+ continue;
+
+ if (uio == NULL)
+ *size += entry->e_name_len + 1;
+ else {
+ char *attr_name = malloc(entry->e_name_len + 1, M_TEMP, M_WAITOK);
+ attr_name[0] = entry->e_name_len;
+ memcpy(&attr_name[1], entry->e_name, entry->e_name_len);
+ error = uiomove(attr_name, entry->e_name_len + 1, uio);
+ free(attr_name, M_TEMP);
+ }
+ }
+
+ brelse(bp);
+
+ return (0);
+}
+
+int
+ext2_extattr_block_list(struct inode *ip, int attrnamespace,
+ struct uio *uio, size_t *size)
+{
+ struct m_ext2fs *fs;
+ struct buf *bp;
+ struct ext2fs_extattr_header *header;
+ struct ext2fs_extattr_entry *entry;
+ struct ext2fs_extattr_entry *next;
+ char *end;
+ int error;
+
+ fs = ip->i_e2fs;
+
+ error = bread(ip->i_devvp, fsbtodb(fs, ip->i_facl),
+ fs->e2fs_bsize, NOCRED, &bp);
+ if (error) {
+ brelse(bp);
+ return (error);
+ }
+
+ /* Check attributes magic value */
+ header = EXT2_HDR(bp);
+ if (header->h_magic != EXTATTR_MAGIC || header->h_blocks != 1) {
+ brelse(bp);
+ return (EINVAL);
+ }
+
+ /* Check attributes integrity */
+ end = bp->b_data + bp->b_bufsize;
+ entry = EXT2_FIRST_ENTRY(bp);
+ while (!EXT2_IS_LAST_ENTRY(entry)) {
+ next = EXT2_EXTATTR_NEXT(entry);
+ if ((char *)next >= end) {
+ brelse(bp);
+ return (EIO);
+ }
+
+ entry = next;
+ }
+
+ for (entry = EXT2_FIRST_ENTRY(bp); !EXT2_IS_LAST_ENTRY(entry);
+ entry = EXT2_EXTATTR_NEXT(entry)) {
+ if (ext2_extattr_index_to_bsd(entry->e_name_index) != attrnamespace)
+ continue;
+
+ if (uio == NULL)
+ *size += entry->e_name_len + 1;
+ else {
+ char *attr_name = malloc(entry->e_name_len + 1, M_TEMP, M_WAITOK);
+ attr_name[0] = entry->e_name_len;
+ memcpy(&attr_name[1], entry->e_name, entry->e_name_len);
+ error = uiomove(attr_name, entry->e_name_len + 1, uio);
+ free(attr_name, M_TEMP);
+ }
+ }
+
+ brelse(bp);
+
+ return (0);
+}
+
+int
+ext2_extattr_inode_get(struct inode *ip, int attrnamespace,
+ const char *name, struct uio *uio, size_t *size)
+{
+ struct m_ext2fs *fs;
+ struct buf *bp;
+ struct ext2fs_extattr_dinode_header *header;
+ struct ext2fs_extattr_entry *entry;
+ struct ext2fs_extattr_entry *next;
+ char *end;
+ int error;
+
+ fs = ip->i_e2fs;
+
+ if ((error = bread(ip->i_devvp,
+ fsbtodb(fs, ino_to_fsba(fs, ip->i_number)),
+ (int)fs->e2fs_bsize, NOCRED, &bp)) != 0) {
+ brelse(bp);
+ return (error);
+ }
+
+ struct ext2fs_dinode *dinode = (struct ext2fs_dinode *)
+ ((char *)bp->b_data +
+ EXT2_INODE_SIZE(fs) * ino_to_fsbo(fs, ip->i_number));
+
+ /* Check attributes magic value */
+ header = (struct ext2fs_extattr_dinode_header *)((char *)dinode +
+ E2FS_REV0_INODE_SIZE + dinode->e2di_extra_isize);
+
+ if (header->h_magic != EXTATTR_MAGIC) {
+ brelse(bp);
+ return (0);
+ }
+
+ /* Check attributes integrity */
+ entry = EXT2_IFIRST(header);
+ end = (char *)dinode + EXT2_INODE_SIZE(fs);
+ while (!EXT2_IS_LAST_ENTRY(entry)) {
+ next = EXT2_EXTATTR_NEXT(entry);
+ if ((char *)next >= end) {
+ brelse(bp);
+ return (EIO);
+ }
+
+ entry = next;
+ }
+
+ for (entry = EXT2_IFIRST(header); !EXT2_IS_LAST_ENTRY(entry);
+ entry = EXT2_EXTATTR_NEXT(entry)) {
+ if (ext2_extattr_index_to_bsd(entry->e_name_index) != attrnamespace)
+ continue;
+
+ if (strlen(name) == entry->e_name_len &&
+ 0 == strncmp(entry->e_name, name, entry->e_name_len)) {
+ if (uio == NULL)
+ *size += entry->e_value_size;
+ else {
+ error = uiomove(((char *)EXT2_IFIRST(header)) + entry->e_value_offs,
+ entry->e_value_size, uio);
+ if (error) {
+ brelse(bp);
+ return (error);
+ }
+ }
+ }
+ }
+
+ brelse(bp);
+
+ return (0);
+}
+
+int
+ext2_extattr_block_get(struct inode *ip, int attrnamespace,
+ const char *name, struct uio *uio, size_t *size)
+{
+ struct m_ext2fs *fs;
+ struct buf *bp;
+ struct ext2fs_extattr_header *header;
+ struct ext2fs_extattr_entry *entry;
+ struct ext2fs_extattr_entry *next;
+ char *end;
+ int error;
+
+ fs = ip->i_e2fs;
+
+ error = bread(ip->i_devvp, fsbtodb(fs, ip->i_facl),
+ fs->e2fs_bsize, NOCRED, &bp);
+ if (error) {
+ brelse(bp);
+ return (error);
+ }
+
+ /* Check attributes magic value */
+ header = EXT2_HDR(bp);
+ if (header->h_magic != EXTATTR_MAGIC || header->h_blocks != 1) {
+ brelse(bp);
+ return (EINVAL);
+ }
+
+ /* Check attributes integrity */
+ end = bp->b_data + bp->b_bufsize;
+ entry = EXT2_FIRST_ENTRY(bp);
+ while (!EXT2_IS_LAST_ENTRY(entry)) {
+ next = EXT2_EXTATTR_NEXT(entry);
+ if ((char *)next >= end) {
+ brelse(bp);
+ return (EIO);
+ }
+
+ entry = next;
+ }
+
+ for (entry = EXT2_FIRST_ENTRY(bp); !EXT2_IS_LAST_ENTRY(entry);
+ entry = EXT2_EXTATTR_NEXT(entry)) {
+ if (ext2_extattr_index_to_bsd(entry->e_name_index) != attrnamespace)
+ continue;
+
+ if (strlen(name) == entry->e_name_len &&
+ 0 == strncmp(entry->e_name, name, entry->e_name_len)) {
+ if (uio == NULL)
+ *size += entry->e_value_size;
+ else {
+ error = uiomove(bp->b_data + entry->e_value_offs,
+ entry->e_value_size, uio);
+ if (error) {
+ brelse(bp);
+ return (error);
+ }
+ }
+ }
+ }
+
+ brelse(bp);
+
+ return (0);
+}
Index: sys/fs/ext2fs/ext2_inode_cnv.c
===================================================================
--- sys/fs/ext2fs/ext2_inode_cnv.c
+++ sys/fs/ext2fs/ext2_inode_cnv.c
@@ -114,8 +114,10 @@
ip->i_flag |= (ei->e2di_flags & EXT3_INDEX) ? IN_E3INDEX : 0;
ip->i_flag |= (ei->e2di_flags & EXT4_EXTENTS) ? IN_E4EXTENTS : 0;
ip->i_blocks = ei->e2di_nblock;
+ ip->i_facl = ei->e2di_facl;
if (E2DI_HAS_HUGE_FILE(ip)) {
ip->i_blocks |= (uint64_t)ei->e2di_nblock_high << 32;
+ ip->i_facl |= (uint64_t)ei->e2di_facl_high << 32;
if (ei->e2di_flags & EXT4_HUGE_FILE)
ip->i_blocks = fsbtodb(ip->i_e2fs, ip->i_blocks);
}
Index: sys/fs/ext2fs/ext2_vnops.c
===================================================================
--- sys/fs/ext2fs/ext2_vnops.c
+++ sys/fs/ext2fs/ext2_vnops.c
@@ -64,6 +64,7 @@
#include <sys/event.h>
#include <sys/conf.h>
#include <sys/file.h>
+#include <sys/extattr.h>
#include <vm/vm.h>
#include <vm/vm_param.h>
@@ -84,6 +85,7 @@
#include <fs/ext2fs/ext2_dinode.h>
#include <fs/ext2fs/ext2_dir.h>
#include <fs/ext2fs/ext2_mount.h>
+#include <fs/ext2fs/ext2_extattr.h>
static int ext2_makeinode(int mode, struct vnode *, struct vnode **, struct componentname *);
static void ext2_itimes_locked(struct vnode *);
@@ -114,6 +116,8 @@
static vop_strategy_t ext2_strategy;
static vop_symlink_t ext2_symlink;
static vop_write_t ext2_write;
+static vop_getextattr_t ext2_getextattr;
+static vop_listextattr_t ext2_listextattr;
static vop_vptofh_t ext2_vptofh;
static vop_close_t ext2fifo_close;
static vop_kqfilter_t ext2fifo_kqfilter;
@@ -152,6 +156,8 @@
.vop_strategy = ext2_strategy,
.vop_symlink = ext2_symlink,
.vop_write = ext2_write,
+ .vop_getextattr = ext2_getextattr,
+ .vop_listextattr = ext2_listextattr,
.vop_vptofh = ext2_vptofh,
};
@@ -1479,6 +1485,88 @@
}
/*
+ * Vnode operation to retrieve a named extended attribute.
+ */
+static int
+ext2_getextattr(struct vop_getextattr_args *ap)
+{
+ struct inode *ip;
+ struct m_ext2fs *fs;
+ int error;
+
+ ip = VTOI(ap->a_vp);
+ fs = ip->i_e2fs;
+
+ if (!EXT2_HAS_COMPAT_FEATURE(ip->i_e2fs, EXT2F_COMPAT_EXT_ATTR))
+ return (EOPNOTSUPP);
+
+ if (ap->a_vp->v_type == VCHR || ap->a_vp->v_type == VBLK)
+ return (EOPNOTSUPP);
+
+ error = extattr_check_cred(ap->a_vp, ap->a_attrnamespace,
+ ap->a_cred, ap->a_td, VREAD);
+ if (error)
+ return (error);
+
+ if (ap->a_size != NULL)
+ *ap->a_size = 0;
+
+ if (EXT2_INODE_SIZE(fs) != E2FS_REV0_INODE_SIZE) {
+ error = ext2_extattr_inode_get(ip, ap->a_attrnamespace,
+ ap->a_name, ap->a_uio, ap->a_size);
+ if (error)
+ return (error);
+ }
+
+ if (ip->i_facl)
+ error = ext2_extattr_block_get(ip, ap->a_attrnamespace,
+ ap->a_name, ap->a_uio, ap->a_size);
+
+ return (error);
+}
+
+/*
+ * Vnode operation to retrieve extended attributes on a vnode.
+ */
+static int
+ext2_listextattr(struct vop_listextattr_args *ap)
+{
+ struct inode *ip;
+ struct m_ext2fs *fs;
+ int error;
+
+ ip = VTOI(ap->a_vp);
+ fs = ip->i_e2fs;
+
+ if (!EXT2_HAS_COMPAT_FEATURE(ip->i_e2fs, EXT2F_COMPAT_EXT_ATTR))
+ return (EOPNOTSUPP);
+
+ if (ap->a_vp->v_type == VCHR || ap->a_vp->v_type == VBLK)
+ return (EOPNOTSUPP);
+
+ error = extattr_check_cred(ap->a_vp, ap->a_attrnamespace,
+ ap->a_cred, ap->a_td, VREAD);
+ if (error)
+ return (error);
+
+ if (ap->a_size != NULL)
+ *ap->a_size = 0;
+
+ if (EXT2_INODE_SIZE(fs) != E2FS_REV0_INODE_SIZE) {
+ error = ext2_extattr_inode_list(ip, ap->a_attrnamespace,
+ ap->a_uio, ap->a_size);
+ if(error)
+ return (error);
+ }
+
+ if(ip->i_facl)
+ error = ext2_extattr_block_list(ip, ap->a_attrnamespace,
+ ap->a_uio, ap->a_size);
+
+ return (error);
+}
+
+/*
* Vnode pointer to File handle
*/
/* ARGSUSED */
Index: sys/fs/ext2fs/ext2fs.h
===================================================================
--- sys/fs/ext2fs/ext2fs.h
+++ sys/fs/ext2fs/ext2fs.h
@@ -204,6 +204,7 @@
*/
#define EXT2F_COMPAT_PREALLOC 0x0001
#define EXT2F_COMPAT_HASJOURNAL 0x0004
+#define EXT2F_COMPAT_EXT_ATTR 0x0008
#define EXT2F_COMPAT_RESIZE 0x0010
#define EXT2F_COMPAT_DIRHASHINDEX 0x0020
#define EXT2F_COMPAT_SPARSESUPER2 0x0200
Index: sys/fs/ext2fs/inode.h
===================================================================
--- sys/fs/ext2fs/inode.h
+++ sys/fs/ext2fs/inode.h
@@ -105,6 +105,7 @@
int32_t i_ctimensec; /* Last inode change time. */
int32_t i_birthnsec; /* Inode creation time. */
uint32_t i_gen; /* Generation number. */
+ uint64_t i_facl; /* Extended attribute block number */
uint32_t i_flags; /* Status flags (chflags). */
uint32_t i_db[EXT2_NDADDR]; /* Direct disk blocks. */
uint32_t i_ib[EXT2_NIADDR]; /* Indirect disk blocks. */
Index: sys/modules/ext2fs/Makefile
===================================================================
--- sys/modules/ext2fs/Makefile
+++ sys/modules/ext2fs/Makefile
@@ -3,8 +3,8 @@
.PATH: ${SRCTOP}/sys/fs/ext2fs
KMOD= ext2fs
SRCS= opt_ddb.h opt_directio.h opt_quota.h opt_suiddir.h vnode_if.h \
- ext2_alloc.c ext2_balloc.c ext2_bmap.c ext2_extents.c ext2_hash.c \
- ext2_htree.c ext2_inode.c ext2_inode_cnv.c ext2_lookup.c ext2_subr.c \
- ext2_vfsops.c ext2_vnops.c
+ ext2_alloc.c ext2_balloc.c ext2_bmap.c ext2_extattr.c ext2_extents.c \
+ ext2_hash.c ext2_htree.c ext2_inode.c ext2_inode_cnv.c ext2_lookup.c \
+ ext2_subr.c ext2_vfsops.c ext2_vnops.c
.include <bsd.kmod.mk>
File Metadata
Details
Attached
Mime Type
text/plain
Expires
Sat, Feb 14, 3:57 PM (3 h, 36 m)
Storage Engine
blob
Storage Format
Raw Data
Storage Handle
28706226
Default Alt Text
D10151.id26864.diff (18 KB)
Attached To
Mode
D10151: ext2fs: add read-only support for extended attributes
Attached
Detach File
Event Timeline
Log In to Comment