From dd19ef9dd01ac11230e2846f54c683618a0019ce Mon Sep 17 00:00:00 2001 From: Steven Whitehouse Date: Wed, 26 Sep 2001 09:26:10 +0000 Subject: [PATCH] o More updates --- driver/device-mapper/dmfs-root.c | 39 ++------------ driver/device-mapper/dmfs-super.c | 2 + driver/device-mapper/dmfs-tdir.c | 86 +++++++++++++++++++++++++++++++ 3 files changed, 92 insertions(+), 35 deletions(-) diff --git a/driver/device-mapper/dmfs-root.c b/driver/device-mapper/dmfs-root.c index dab0c141e..7fd7e94db 100644 --- a/driver/device-mapper/dmfs-root.c +++ b/driver/device-mapper/dmfs-root.c @@ -47,6 +47,9 @@ static int dmfs_root_mkdir(struct inode *dir, struct dentry *dentry, int mode) if (!is_identifier(name, dentry->d_name.len)) return -EPERM; + if (dentry->d_name[0] == '.') + return -EINVAL; + inode = dmfs_create_lv(dir, dentry, mode); if (!IS_ERR(inode)) { md = dm_create(name, -1); @@ -70,8 +73,7 @@ static int dmfs_root_mkdir(struct inode *dir, struct dentry *dentry, int mode) */ static inline positive(struct dentry *dentry) { - return dentry->d_inode && dentry->d_inode->u.generic_ip && - !d_unhashed(dentry); + return dentry->d_inode && !d_unhashed(dentry); } static int empty(struct dentry *dentry) @@ -94,45 +96,12 @@ static int empty(struct dentry *dentry) return 1; } -static int dmfs_delete_virtual(struct inode *dir, struct dentry *dentry) -{ - struct list_head *list; - struct dentry *de; - int rv = 0; - - while(1) { - spin_lock(&dcache_lock); - list = dentry->d_subdirs.next; - if (list == &dentry->d_subdirs) { - spin_unlock(&dcache_lock); - break; - } - de = list_entry(list, struct dentry, d_child); - if (de->d_inode && !d_unhashed(de)) { - spin_unlock(&dcache_lock); - if (de->d_inode->u.generic_ip) - BUG(); - rv = de->d_inode->ops->unlink(dir, de); - if (rv == 0) { - d_delete(de); - continue; - } - break; - } - spin_unlock(&dcache_lock); - } - - return rv; -} - static int dmfs_root_rmdir(struct inode *dir, struct dentry *dentry) { int ret = -ENOTEMPTY; if (empty(dentry)) { struct inode *inode = dentry->d_inode; - - ret = dmfs_delete_virtual(dir, dentry); if (ret == 0) { inode->i_nlink--; dput(dentry); diff --git a/driver/device-mapper/dmfs-super.c b/driver/device-mapper/dmfs-super.c index a1c06d7ae..fb9233a72 100644 --- a/driver/device-mapper/dmfs-super.c +++ b/driver/device-mapper/dmfs-super.c @@ -24,6 +24,8 @@ #define DMFS_MAGIC 0x444D4653 +extern struct inode *dmfs_create_root(struct super_block *sb, int); + static int dmfs_statfs(struct super_block *sb, struct statfs *buf) { buf->f_type = sb->s_magic; diff --git a/driver/device-mapper/dmfs-tdir.c b/driver/device-mapper/dmfs-tdir.c index 04bd52971..971362bd7 100644 --- a/driver/device-mapper/dmfs-tdir.c +++ b/driver/device-mapper/dmfs-tdir.c @@ -28,6 +28,92 @@ extern struct inode *dmfs_create_error(struct inode *, int); extern struct inode *dmfs_create_table(struct inode *, int); extern struct inode *dmfs_create_status(struct inode *, int); + +static inline positive(struct dentry *dentry) +{ + return dentry->d_inode && !d_unhashed(dentry); +} + +static int dm_deny_write_access(struct dentry *dentry) +{ + struct file file { f_dentry: &dentry }; + + return deny_write_access(&file); +} + +static void dm_allow_dentry_list(struct dentry *list[], int i) +{ + int x; + for(x = 0; x < i; x++) + atomic_inc(&list[x]->d_inode->i_writecount); +} + +static int dm_deny_dentry_list(struct dentry *list[], int i) +{ + int x; + int rv; + + for(x = 0; x < i; x++) { + rv = dm_deny_write_access(list[x]); + if (rv) + goto error: + } + return 0; +error: + if (x > 0) { + dm_allow_dentry_list(list, x - 1); + } + return rv; +} + +static int dm_child_list(struct dentry *de_list[], struct dentry *dentry) +{ + struct list_head *list; + int i = 0; + int rv; + + spin_lock(&dcache_lock); + list = dentry->d_subdirs.next; + + while(list != &dentry->d_subdirs) { + struct dentry *de = list_entry(list, struct dentry, d_child); + + if (positive(de)) + de_list[i++] = dget(de); + list = list->next; + } + spin_unlock(&dcache_lock); + + return i; +} + +int dm_lock_tdir(struct dentry *dentry) +{ + struct dentry de_list[4]; + int n, rv; + + rv = n = dm_child_list(de_list, dentry); + if (n) { + rv = deny_dentry_list(de_list, n); + dput_list(de_list, n); + } + + return rv; +} + +int dm_unlock_tdir(struct dentry *dentry) +{ + struct dentry de_list[4]; + + rv = dm_child_list(de_list, dentry); + if (rv) { + dm_allow_dentry_list(de_list, rv); + dput_list(de_list, rv); + } + + return rv; +} + static int dmfs_tdir_unlink(struct inode *dir, struct dentry *dentry) { inode->i_nlink--; -- 2.43.5