Hi,
Seems like i was not clear enough. But anynway i found a solution to my
problem, without changing kernel sources. I post it here FYI. The
following code changes the xattr handler in the superblock structure to
install its own namespace.
Chris
/* virtual xattr stuff */
#define NGACL_XATTR_PREFIX "ngacl."
#define NGACL_XATTR_UID_SUFFIX "uid"
#define for_each_xattr_handler(handlers, handler) \
for ((handler) = *(handlers)++; \
(handler) != NULL; \
(handler) = *(handlers)++)
size_t ngacl_xattr_list(struct inode *inode, char *list, size_t
list_size, const char *name, size_t name_len) {
printk(KERN_INFO "ngacl_list\n");
return 0;
}
int ngacl_xattr_get(struct inode *inode, const char *name, void *buffer,
size_t size) {
printk(KERN_INFO "ngacl_get\n");
const char *subname;
subname = name;
subname = subname + strlen(NGACL_XATTR_PREFIX);
printk(KERN_INFO "with name %s\n", subname);
if (!(strncmp(name,
NGACL_XATTR_UID_SUFFIX,strlen(NGACL_XATTR_UID_SUFFIX) -1))) {
/* Check if buffer is long enough
it should be (sizeof(uid_t) / 3) +1 */
if (buffer == NULL) {
return (sizeof(uid_t) / 3) +1;
} else if (size < ((sizeof(inode->i_uid) / 3) +1)) {
return -ERANGE;
}
return snprintf(buffer,size,"%u",inode->i_uid);
}
return -EINVAL;
}
int ngacl_xattr_set(struct inode *inode, const char *name, const void
*buffer, size_t size, int flags) {
printk(KERN_INFO "ngacl_set\n");
const char *subname;
subname = name;
subname = subname + strlen(NGACL_XATTR_PREFIX);
printk(KERN_INFO "with name %s\n", subname);
if (!(strncmp(name,
NGACL_XATTR_UID_SUFFIX,strlen(NGACL_XATTR_UID_SUFFIX) -1))) {
struct iattr attr;
struct dentry *dentry;
char *endp;
endp = buffer + size;
uid_t owner;
ngacl_dbg(debug, "this is an owner for us!\n");
owner = simple_strtoul(buffer, &endp,10);
ngacl_dbg(debug,"and his uid is %u\n",owner);
attr.ia_valid = ATTR_UID | ATTR_FORCE;
attr.ia_uid = owner;
dentry = d_find_alias(inode);
if (dentry == NULL) {
return -EINVAL;
}
notify_change(dentry,&attr);
return 0;
}
return -EINVAL;
}
struct xattr_handler ngacl_xattr_handler = {
.prefix = NGACL_XATTR_PREFIX,
.list = ngacl_xattr_list,
.get = ngacl_xattr_get,
.set = ngacl_xattr_set,
};
int ngacl_sb_kern_mount(struct super_block *sb, void *data) {
int entries=0;
int i,alloc_size=0;
struct xattr_handler **old_handlers, **new_handlers, **handlers,
*old_handler;
old_handlers = sb->s_xattr;
if (sb == NULL) {
goto out;
}
if (sb->s_xattr == NULL) {
goto out;
}
for_each_xattr_handler(old_handlers, old_handler) {
entries++;
}
if ( entries == 0 ) {
goto out;
}
alloc_size=(entries+2)*(sizeof(old_handler));
printk(KERN_INFO "%i\n", alloc_size);
handlers=kmalloc(alloc_size, GFP_KERNEL);
if (handlers == NULL) {
printk(KERN_INFO "handlers is null\n");
}
new_handlers = handlers;
old_handlers=sb->s_xattr;
for_each_xattr_handler(old_handlers, old_handler) {
*new_handlers = old_handler;
printk(KERN_INFO "Copying %s %s\n", old_handler->prefix,
(*new_handlers)->prefix);
*(new_handlers)++;
}
*new_handlers = &ngacl_xattr_handler;
*(new_handlers)++;
*new_handlers = NULL;
sb->s_xattr = handlers;
old_handlers=handlers;
for_each_xattr_handler(old_handlers, old_handler) {
printk(KERN_INFO "Newmember: %s\n",
old_handler->prefix);
}
printk(KERN_INFO "kern_mount out %i\n", entries);
out:
return 0;
}
This archive was generated by hypermail 2.1.3 : Thu Sep 15 2005 - 01:56:53 PDT