From ac4fc0b84ddff2e4c846bfcdcc036763605990c4 Mon Sep 17 00:00:00 2001 From: Steven Whitehouse Date: Wed, 26 Sep 2001 20:24:39 +0000 Subject: [PATCH] o Kill write funcs for error/status files o Redo write logic for table file o Relax rules for symlink content by removing the rewriting function Well I probably won't get a chance to work on this tomorrow, so this is my changeset to date. --- driver/device-mapper/dmfs-error.c | 8 --- driver/device-mapper/dmfs-lv.c | 51 ++++--------------- driver/device-mapper/dmfs-status.c | 6 --- driver/device-mapper/dmfs-table.c | 25 +++++++++ driver/device-mapper/dmfs-tdir.c | 81 ++---------------------------- 5 files changed, 40 insertions(+), 131 deletions(-) diff --git a/driver/device-mapper/dmfs-error.c b/driver/device-mapper/dmfs-error.c index 9c24510f8..19ef9c72a 100644 --- a/driver/device-mapper/dmfs-error.c +++ b/driver/device-mapper/dmfs-error.c @@ -28,13 +28,6 @@ static ssize_t dmfs_error_read(struct file *file, char *buf, size_t size, loff_t return size; } -static ssize_t dmfs_error_write(struct file *file, const char *buf, size_t size, loff_t *pos) -{ - struct inode *inode = file->f_dentry->d_inode; - - return size; -} - static int dmfs_error_sync(struct file *file, struct dentry *dentry, int datasync) { return 0; @@ -42,7 +35,6 @@ static int dmfs_error_sync(struct file *file, struct dentry *dentry, int datasyn static struct dm_table_file_operations = { read: dmfs_error_read, - write: dmfs_error_write, fsync: dmfs_error_sync, }; diff --git a/driver/device-mapper/dmfs-lv.c b/driver/device-mapper/dmfs-lv.c index 4d6168f35..09f3a9cbd 100644 --- a/driver/device-mapper/dmfs-lv.c +++ b/driver/device-mapper/dmfs-lv.c @@ -33,38 +33,25 @@ struct dentry *dmfs_verify_name(struct inode *dir, char *name) int err = -ENOENT; if (path_init(name, LOOKUP_FOLLOW, &nd)) - err = path_walk(path, &nd); + return ERR_PTR(-EINVAL); + err = path_walk(path, &nd); if (err) - return ERR_PTR(err); + goto err_out; + err = -EINVAL; if (nd.mnt->mnt->sb != dir->i_sb) - goto err; + goto err_out; if (nd.dentry->d_parent != dir) - goto err; + goto err_out; dget(nd.dentry); path_release(nd); return nd.dentry; -err: +err_out: path_release(nd); - return ERR_PTR(-EINVAL); -} - -char *dmfs_translate_name(struct dentry *de) -{ - int len = de->d_name.len + 3; - char *n = kmalloc(len); - if (n) { - char *p = n; - *p++ = '.'; - *p++ = '/'; - memcmp(p, de->d_name.name, de->d_name.len); - p += de->d_name.len - *p = 0; - } - return n; + return ERR_PTR(err); } struct inode *dmfs_create_symlink(struct inode *dir, int mode) @@ -91,7 +78,6 @@ static int dmfs_lv_symlink(struct inode *dir, struct dentry *dentry, { struct inode *inode; struct dentry *de; - char *realname; int rv; int l; @@ -99,11 +85,6 @@ static int dmfs_lv_symlink(struct inode *dir, struct dentry *dentry, if (IS_ERR(de)) return PTR_ERR(de); - realname = dmfs_translate_name(de); - dput(de); - if (realname == NULL); - return -ENOMEM; - inode = dmfs_create_symlink(dir, S_IRWXUGO); if (IS_ERR(inode)) { kfree(realname); @@ -113,12 +94,11 @@ static int dmfs_lv_symlink(struct inode *dir, struct dentry *dentry, d_instantiate(dentry, inode); dget(dentry); - l = strlen(realname) + 1; - rv = block_symlink(inode, realname, l); + l = strlen(symname) + 1; + rv = block_symlink(inode, symname, l); if (rv) { dput(dentry); } - kfree(realname); return rv; } @@ -218,16 +198,6 @@ static struct dentry *dmfs_lv_lookup(struct inode *dir, struct dentry *dentry) return NULL; } -static int dmfs_lv_rename(struct inode *old_dir, struct dentry *old_dentry, - struct inode *new_dir, struct dentry *new_dentry) -{ - /* Can only rename - not move between directories! */ - if (old_dir != new_dir) - return -EPERM; - - return -EINVAL; /* FIXME: a change of LV name here */ -} - static int dmfs_lv_sync(struct file *file, struct dentry *dentry, int datasync) { return 0; @@ -245,7 +215,6 @@ static struct dm_root_inode_operations = { symlink: dmfs_lv_symlink, mkdir: dmfs_lv_mkdir, rmdir: dmfs_lv_rmdir, - rename: dmfs_lv_rename, }; struct inode *dmfs_create_lv(struct super_block *sb, int mode) diff --git a/driver/device-mapper/dmfs-status.c b/driver/device-mapper/dmfs-status.c index 354aab79b..300db35f6 100644 --- a/driver/device-mapper/dmfs-status.c +++ b/driver/device-mapper/dmfs-status.c @@ -27,11 +27,6 @@ static ssize_t dmfs_status_read(struct file *file, char *buf, size_t size, loff_ return size; } -static ssize_t dmfs_status_write(struct file *file, const char *buf, size_t size, loff_t *pos) -{ - return size; -} - static int dmfs_status_sync(struct file *file, struct dentry *dentry, int datasync) { return 0; @@ -39,7 +34,6 @@ static int dmfs_status_sync(struct file *file, struct dentry *dentry, int datasy static struct dm_table_file_operations = { read: dmfs_status_read, - write: dmfs_status_write, fsync: dmfs_status_sync, }; diff --git a/driver/device-mapper/dmfs-table.c b/driver/device-mapper/dmfs-table.c index a35a6abf9..8cabe8ce7 100644 --- a/driver/device-mapper/dmfs-table.c +++ b/driver/device-mapper/dmfs-table.c @@ -252,6 +252,29 @@ static int dmfs_commit_write(struct file *file, struct page *page, return 0; } +static int dmfs_table_open(struct inode *inode, struct file *file) +{ + struct dentry *dentry = file->f_dentry; + struct inode *inode = dentry->d_parent->d_inode; + + if (file->f_mode & FMODE_WRITE) { + if (get_write_access(inode)) + return -EPERM; + } + + return 0; +} + +static int dmfs_table_release(struct inode *inode, struct file *file) +{ + if (file->f_mode & FMODE_WRITE) { + struct dentry *dentry = file->f_dentry; + struct inode *inode = dentry->d_parent->d_inode; + + put_write_access(inode); + } +} + static int dmfs_table_sync(struct file *file, struct dentry *dentry, int datasync) { return 0; @@ -268,6 +291,8 @@ static struct dmfs_table_file_operations = { llseek: generic_file_llseek, read: generic_file_read, write: generic_file_write, + open: dmfs_table_open, + release: dmfs_table_release, fsync: dmfs_table_sync, release: dmfs_release, }; diff --git a/driver/device-mapper/dmfs-tdir.c b/driver/device-mapper/dmfs-tdir.c index 971362bd7..634744ee9 100644 --- a/driver/device-mapper/dmfs-tdir.c +++ b/driver/device-mapper/dmfs-tdir.c @@ -29,89 +29,18 @@ extern struct inode *dmfs_create_table(struct inode *, int); extern struct inode *dmfs_create_status(struct inode *, int); -static inline positive(struct dentry *dentry) +int dm_lock_tdir(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 }; + struct file file = { f_dentry: dentry }; return deny_write_access(&file); } -static void dm_allow_dentry_list(struct dentry *list[], int i) +void dm_unlock_tdir(struct dentry *dentry) { - int x; - for(x = 0; x < i; x++) - atomic_inc(&list[x]->d_inode->i_writecount); -} + struct file file = { f_dentry: dentry }; -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; + allow_write_access(&file); } static int dmfs_tdir_unlink(struct inode *dir, struct dentry *dentry)