reiserfslib: add basic extended attribute helpers
Signed-off-by: Jeff Mahoney <jeffm@suse.com>
This commit is contained in:
1 parent
e51777cf55
commit
6bdb171b9e
4 files changed
+147
-2
No files matched your search
@@ -1402,6 +1402,32 @@ struct buffer_info {
|
||||
#define MAX_DIRECT_ITEM_LEN(size) ((size) - BLKH_SIZE - 2*IH_SIZE - SD_SIZE - UNFM_P_SIZE)
|
||||
#define MAX_INDIRECT_ITEM_LEN(size) MAX_ITEM_LEN(size)
|
||||
|
||||
/* Extended attributes */
|
||||
/* Magic value in header */
|
||||
#define REISERFS_XATTR_MAGIC 0x52465841 /* "RFXA" */
|
||||
|
||||
struct reiserfs_xattr_header {
|
||||
__le32 h_magic;
|
||||
__le32 h_hash;
|
||||
};
|
||||
|
||||
/* ACLs */
|
||||
#define REISERFS_ACL_VERSION 0x0001
|
||||
struct reiserfs_acl_entry {
|
||||
__le16 e_tag;
|
||||
__le16 e_perm;
|
||||
__le32 e_id;
|
||||
};
|
||||
|
||||
struct reiserfs_acl_entry_short {
|
||||
__le16 e_tag;
|
||||
__le16 e_perm;
|
||||
};
|
||||
|
||||
struct reiserfs_acl_header {
|
||||
__le32 a_version;
|
||||
};
|
||||
|
||||
/***************************************************************************/
|
||||
/* FUNCTION DECLARATIONS */
|
||||
/***************************************************************************/
|
||||
|
||||
@@ -431,5 +431,8 @@ int can_we_format_it(char *device_name, int force);
|
||||
return 0;\
|
||||
}\
|
||||
|
||||
|
||||
/* xattr.c */
|
||||
__u32 reiserfs_xattr_hash(const char *msg, int len);
|
||||
int reiserfs_check_xattr(const void *body, int len);
|
||||
int reiserfs_acl_count(size_t size);
|
||||
#endif /* REISERFSPROGS_LIB_H */
|
||||
@@ -2,7 +2,7 @@ lib_LTLIBRARIES = libreiserfscore.la
|
||||
|
||||
libreiserfscore_la_SOURCES = do_balan.c fix_node.c hashes.c ibalance.c \
|
||||
lbalance.c prints.c stree.c node_formats.c \
|
||||
reiserfslib.c bitmap.c journal.c includes.h
|
||||
reiserfslib.c bitmap.c journal.c xattr.c includes.h
|
||||
libreiserfscore_la_LIBADD = ../lib/libmisc.la
|
||||
|
||||
pkgconfigdir = $(libdir)/pkgconfig
|
||||
|
||||
@@ -0,0 +1,116 @@
|
||||
#include <sys/types.h>
|
||||
#include <stdio.h>
|
||||
#include <errno.h>
|
||||
#include <sys/acl.h>
|
||||
#include "reiserfs_lib.h"
|
||||
|
||||
static inline unsigned short from32to16(unsigned int x)
|
||||
{
|
||||
/* add up 16-bit and 16-bit for 16+c bit */
|
||||
x = (x & 0xffff) + (x >> 16);
|
||||
/* add up carry.. */
|
||||
x = (x & 0xffff) + (x >> 16);
|
||||
return x;
|
||||
}
|
||||
|
||||
static unsigned int do_csum(const unsigned char *buff, int len)
|
||||
{
|
||||
int odd;
|
||||
unsigned int result = 0;
|
||||
|
||||
if (len <= 0)
|
||||
goto out;
|
||||
odd = 1 & (unsigned long) buff;
|
||||
if (odd) {
|
||||
#ifdef __LITTLE_ENDIAN
|
||||
result += (*buff << 8);
|
||||
#else
|
||||
result = *buff;
|
||||
#endif
|
||||
len--;
|
||||
buff++;
|
||||
}
|
||||
if (len >= 2) {
|
||||
if (2 & (unsigned long) buff) {
|
||||
result += *(unsigned short *) buff;
|
||||
len -= 2;
|
||||
buff += 2;
|
||||
}
|
||||
if (len >= 4) {
|
||||
const unsigned char *end = buff + ((unsigned)len & ~3);
|
||||
unsigned int carry = 0;
|
||||
do {
|
||||
unsigned int w = *(unsigned int *) buff;
|
||||
buff += 4;
|
||||
result += carry;
|
||||
result += w;
|
||||
carry = (w > result);
|
||||
} while (buff < end);
|
||||
result += carry;
|
||||
result = (result & 0xffff) + (result >> 16);
|
||||
}
|
||||
if (len & 2) {
|
||||
result += *(unsigned short *) buff;
|
||||
buff += 2;
|
||||
}
|
||||
}
|
||||
if (len & 1)
|
||||
#ifdef __LITTLE_ENDIAN
|
||||
result += *buff;
|
||||
#else
|
||||
result += (*buff << 8);
|
||||
#endif
|
||||
result = from32to16(result);
|
||||
if (odd)
|
||||
result = ((result >> 8) & 0xff) | ((result & 0xff) << 8);
|
||||
out:
|
||||
return result;
|
||||
}
|
||||
|
||||
__wsum csum_partial(const void *buff, int len, __wsum wsum)
|
||||
{
|
||||
unsigned int sum = (__force unsigned int)wsum;
|
||||
unsigned int result = do_csum(buff, len);
|
||||
|
||||
/* add in old sum, and carry.. */
|
||||
result += sum;
|
||||
if (sum > result)
|
||||
result += 1;
|
||||
return (__force __wsum)result;
|
||||
}
|
||||
|
||||
inline __u32 reiserfs_xattr_hash(const char *msg, int len)
|
||||
{
|
||||
return csum_partial(msg, len, 0);
|
||||
}
|
||||
|
||||
|
||||
int reiserfs_check_xattr(const void *body, int len)
|
||||
{
|
||||
const struct reiserfs_xattr_header *xah = body;
|
||||
int hdrsz = sizeof(struct reiserfs_xattr_header);
|
||||
__u32 hash;
|
||||
|
||||
if (len < hdrsz)
|
||||
return -EINVAL;
|
||||
|
||||
hash = reiserfs_xattr_hash(body + hdrsz, len - hdrsz);
|
||||
return xah->h_magic == cpu_to_le32(REISERFS_XATTR_MAGIC) &&
|
||||
le32_to_cpu(xah->h_hash) == hash;
|
||||
}
|
||||
|
||||
int reiserfs_acl_count(size_t size)
|
||||
{
|
||||
ssize_t s;
|
||||
size -= sizeof(struct reiserfs_acl_header);
|
||||
s = size - 4 * sizeof(struct reiserfs_acl_entry_short);
|
||||
if (s < 0) {
|
||||
if (size % sizeof(struct reiserfs_acl_entry_short))
|
||||
return -1;
|
||||
return size / sizeof(struct reiserfs_acl_entry_short);
|
||||
} else {
|
||||
if (s % sizeof(struct reiserfs_acl_entry))
|
||||
return -1;
|
||||
return s / sizeof(struct reiserfs_acl_entry) + 4;
|
||||
}
|
||||
}
|
||||
Reference in new issue
Block a user