diff --git a/driver/device-mapper/dmfs-error.c b/driver/device-mapper/dmfs-error.c index 97009af13..871249975 100644 --- a/driver/device-mapper/dmfs-error.c +++ b/driver/device-mapper/dmfs-error.c @@ -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); } diff --git a/driver/device-mapper/dmfs-super.c b/driver/device-mapper/dmfs-super.c index cd0e1321f..a0f1c02a0 100644 --- a/driver/device-mapper/dmfs-super.c +++ b/driver/device-mapper/dmfs-super.c @@ -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); diff --git a/driver/device-mapper/dmfs.h b/driver/device-mapper/dmfs.h index 1cc0df350..98bcddaae 100644 --- a/driver/device-mapper/dmfs.h +++ b/driver/device-mapper/dmfs.h @@ -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) diff --git a/driver/device-mapper/projects.txt b/driver/device-mapper/projects.txt index 1f73d2996..e554062b4 100644 --- a/driver/device-mapper/projects.txt +++ b/driver/device-mapper/projects.txt @@ -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. -