mirror of
git://sourceware.org/git/lvm2.git
synced 2025-02-28 05:57:49 +03:00
o More updates
This commit is contained in:
parent
8b0cd95e73
commit
66d905325c
@ -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);
|
||||
|
@ -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;
|
||||
|
@ -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--;
|
||||
|
Loading…
x
Reference in New Issue
Block a user