1
0
mirror of git://sourceware.org/git/lvm2.git synced 2025-01-03 05:18:29 +03:00

o Fix module ref counts so that you can actually unload dm-mod

N.B. This means that you have to take very great care in the event that
   you want to access the dcache tree from in kernel

 o Added extra field to allow out of memory conditions to result in the
   correct error code. (This hasn't received a lot of testing...)

I've ditched the final project (which would have cleared my whole list)
since its got other complications which I don't have time to fix right
now. Still as Meatloaf says, two out of three ain't bad!
This commit is contained in:
Steven Whitehouse 2001-11-10 17:11:36 +00:00
parent 7858f6fb16
commit e55ef72786
4 changed files with 32 additions and 14 deletions

View File

@ -33,6 +33,19 @@ struct dmfs_error {
char *msg;
};
static struct dmfs_error oom_error;
static struct list_head oom_list = {
next: &oom_error.list,
prev: &oom_error.list,
};
static struct dmfs_error oom_error = {
list: { next: &oom_list, prev: &oom_list },
len: 39,
msg: "Out of memory during creation of table\n",
};
void dmfs_add_error(struct inode *inode, unsigned num, char *str)
{
struct dmfs_i *dmi = DMFS_I(inode);
@ -64,9 +77,16 @@ static void *e_start(void *context, loff_t *pos)
struct dmfs_i *dmi = context;
down(&dmi->sem);
list_for_each(p, &dmi->errors)
if (n-- == 0)
return list_entry(p, struct dmfs_error, list);
if (dmi->status) {
list_for_each(p, &oom_list)
if (n-- == 0)
return list_entry(p, struct dmfs_error, list);
} else {
list_for_each(p, &dmi->errors)
if (n-- == 0)
return list_entry(p, struct dmfs_error, list);
}
return NULL;
}
@ -75,7 +95,7 @@ static void *e_next(void *context, void *v, loff_t *pos)
struct dmfs_i *dmi = context;
struct list_head *p = ((struct dmfs_error *)v)->list.next;
(*pos)++;
return (p == &dmi->errors) ? NULL
return (p == &dmi->errors) || (p == &oom_list) ? NULL
: list_entry(p, struct dmfs_error, list);
}

View File

@ -53,6 +53,7 @@ static void dmfs_delete_inode(struct inode *inode)
if (!list_empty(&dmi->errors))
dmfs_zap_errors(inode);
kfree(dmi);
MOD_DEC_USE_COUNT; /* Don't remove */
}
inode->u.generic_ip = NULL;
@ -121,6 +122,7 @@ struct inode *dmfs_new_private_inode(struct super_block *sb, int mode)
init_MUTEX(&dmi->sem);
INIT_LIST_HEAD(&dmi->errors);
inode->u.generic_ip = dmi;
MOD_INC_USE_COUNT; /* Don't remove */
}
return inode;
}
@ -140,6 +142,8 @@ int __init dmfs_init(void)
if (IS_ERR(dmfs_mnt)) {
ret = PTR_ERR(dmfs_mnt);
unregister_filesystem(&dmfs_fstype);
} else {
MOD_DEC_USE_COUNT; /* Yes, this really is correct... */
}
out:
return ret;
@ -147,7 +151,9 @@ out:
int __exit dmfs_exit(void)
{
/* kern_umount(&dmfs_mnt); */
MOD_INC_USE_COUNT; /* So that it lands up being zero */
do_umount(dmfs_mnt, 0);
unregister_filesystem(&dmfs_fstype);

View File

@ -7,6 +7,7 @@ struct dmfs_i {
struct mapped_device *md;
struct dentry *dentry;
struct list_head errors;
int status;
};
#define DMFS_I(inode) ((struct dmfs_i *)(inode)->u.generic_ip)

View File

@ -1,15 +1,6 @@
List of projects, ideas and pending bug fixes
===============================================
o Need to work out how to make module use counts work correctly. The existing
scheme does not allow us to unload the module. A reference is taken during
kern_mount() which does not allow us to rmmod() so even if the right
umount() functions were exported (which they aren't) we'd never get to
call them anyway. This could be tricky.
o Check tables are an integer multiple of the underlying block size at
table load time.
o Error code (as well as error list) so that "out of memory" errors can
result in messages which can be read from the error file.