Skip to content
Snippets Groups Projects
Commit 271be050 authored by Wang Di's avatar Wang Di
Browse files

update smfs.c 1)fix bugs of inode and dentry in dir.c

parent 0343ecb7
No related branches found
No related tags found
No related merge requests found
......@@ -12,15 +12,75 @@
#include "smfs_internal.h"
static void d_unalloc(struct dentry *dentry)
#define NAME_ALLOC_LEN(len) ((len+16) & ~15)
struct dentry parent;
struct dentry cache_dentry;
static void smfs_clear_dentry(struct dentry *dentry)
{
if (dentry) {
list_del(&dentry->d_hash);
INIT_LIST_HEAD(&dentry->d_hash);
dput(dentry);
struct qstr *name = NULL;
if (dentry) {
if (!atomic_dec_and_lock(&dentry->d_count, &dcache_lock))
return;
list_del(&dentry->d_hash);
INIT_LIST_HEAD(&dentry->d_hash);
list_del(&dentry->d_child);
if (dentry->d_inode) {
dentry->d_inode = NULL;
list_del_init(&dentry->d_alias);
}
name = &(dentry->d_name);
if (name->len > DNAME_INLINE_LEN-1) {
SM_FREE((char *)name->name, NAME_ALLOC_LEN(name->len));
}
}
}
int smfs_prepare_dentry(struct dentry *dentry,
struct dentry *parent,
struct qstr *name)
{
char *str = NULL;
if (name->len > DNAME_INLINE_LEN-1) {
SM_ALLOC(str, NAME_ALLOC_LEN(name->len));
if (!str)
return (-ENOMEM);
} else
str = dentry->d_iname;
memcpy(str, name->name, name->len);
str[name->len] = 0;
atomic_set(&dentry->d_count, 1);
dentry->d_vfs_flags = 0;
dentry->d_flags = 0;
dentry->d_inode = NULL;
dentry->d_parent = NULL;
dentry->d_sb = NULL;
dentry->d_name.name = str;
dentry->d_name.len = name->len;
dentry->d_name.hash = name->hash;
dentry->d_op = NULL;
dentry->d_fsdata = NULL;
dentry->d_mounted = 0;
INIT_LIST_HEAD(&dentry->d_hash);
INIT_LIST_HEAD(&dentry->d_lru);
INIT_LIST_HEAD(&dentry->d_subdirs);
INIT_LIST_HEAD(&dentry->d_alias);
if (parent) {
dentry->d_parent = dget(parent);
dentry->d_sb = parent->d_sb;
list_add(&dentry->d_child, &parent->d_subdirs);
} else
INIT_LIST_HEAD(&dentry->d_child);
return 0;
}
static void prepare_parent_dentry(struct dentry *dentry, struct inode *inode)
{
atomic_set(&dentry->d_count, 1);
......@@ -35,15 +95,12 @@ static void prepare_parent_dentry(struct dentry *dentry, struct inode *inode)
INIT_LIST_HEAD(&dentry->d_subdirs);
INIT_LIST_HEAD(&dentry->d_alias);
}
static int smfs_create(struct inode *dir,
struct dentry *dentry,
int mode)
{
struct inode *cache_dir;
struct inode *cache_inode, *inode;
struct dentry tmp;
struct dentry *cache_dentry;
int rc;
ENTRY;
......@@ -52,18 +109,15 @@ static int smfs_create(struct inode *dir,
if (!cache_dir)
RETURN(-ENOENT);
prepare_parent_dentry(&tmp, cache_dir);
cache_dentry = d_alloc(&tmp, &dentry->d_name);
if (!cache_dentry)
RETURN(-ENOENT);
if(cache_dir && cache_dir->i_op->create)
rc = cache_dir->i_op->create(cache_dir, cache_dentry, mode);
prepare_parent_dentry(&parent, cache_dir);
smfs_prepare_dentry(&cache_dentry, &parent, &dentry->d_name);
if (cache_dir && cache_dir->i_op->create)
rc = cache_dir->i_op->create(cache_dir, &cache_dentry, mode);
if (rc)
GOTO(exit, rc);
cache_inode = cache_dentry->d_inode;
cache_inode = cache_dentry.d_inode;
inode = iget(dir->i_sb, cache_inode->i_ino);
......@@ -74,7 +128,8 @@ static int smfs_create(struct inode *dir,
sm_set_inode_ops(cache_inode, inode);
exit:
d_unalloc(cache_dentry);
smfs_clear_dentry(&cache_dentry);
iput(cache_inode);
RETURN(rc);
}
......@@ -84,7 +139,7 @@ static struct dentry *smfs_lookup(struct inode *dir,
struct inode *cache_dir;
struct inode *cache_inode, *inode;
struct dentry tmp;
struct dentry *cache_dentry;
struct dentry cache_dentry;
struct dentry *rc = NULL;
ENTRY;
......@@ -93,27 +148,26 @@ static struct dentry *smfs_lookup(struct inode *dir,
if (!cache_dir)
RETURN(ERR_PTR(-ENOENT));
prepare_parent_dentry(&tmp, cache_dir);
cache_dentry = d_alloc(&tmp, &dentry->d_name);
smfs_prepare_dentry(&cache_dentry, &tmp, &dentry->d_name);
if (!cache_dentry)
RETURN(ERR_PTR(-ENOENT));
if(cache_dir && cache_dir->i_op->lookup)
rc = cache_dir->i_op->lookup(cache_dir, cache_dentry);
rc = cache_dir->i_op->lookup(cache_dir, &cache_dentry);
if (rc || !cache_dentry->d_inode ||
is_bad_inode(cache_dentry->d_inode) ||
IS_ERR(cache_dentry->d_inode)) {
if (rc || !cache_dentry.d_inode ||
is_bad_inode(cache_dentry.d_inode) ||
IS_ERR(cache_dentry.d_inode)) {
GOTO(exit, rc);
}
cache_inode = cache_dentry->d_inode;
cache_inode = cache_dentry.d_inode;
inode = iget(dir->i_sb, cache_inode->i_ino);
d_add(dentry, inode);
exit:
d_unalloc(cache_dentry);
smfs_clear_dentry(&cache_dentry);
iput(cache_inode);
RETURN(rc);
}
......@@ -140,7 +194,7 @@ static int smfs_link(struct dentry * old_dentry,
struct inode *cache_old_inode = NULL;
struct inode *cache_dir = I2CI(dir);
struct inode *inode = NULL;
struct dentry *cache_dentry = NULL;
struct dentry cache_dentry;
struct dentry tmp;
struct dentry tmp_old;
int rc = 0;
......@@ -153,19 +207,17 @@ static int smfs_link(struct dentry * old_dentry,
RETURN(-ENOENT);
prepare_parent_dentry(&tmp_old, cache_old_inode);
smfs_prepare_dentry(&cache_dentry, &tmp, &dentry->d_name);
prepare_parent_dentry(&tmp, cache_dir);
cache_dentry = d_alloc(&tmp, &dentry->d_name);
if (cache_dir->i_op->link)
rc = cache_dir->i_op->link(&tmp, cache_dir, cache_dentry);
rc = cache_dir->i_op->link(&tmp, cache_dir, &cache_dentry);
if (rc == 0) {
d_instantiate(dentry, inode);
}
d_unalloc(cache_dentry);
smfs_clear_dentry(&cache_dentry);
RETURN(rc);
}
static int smfs_unlink(struct inode * dir,
......@@ -173,7 +225,7 @@ static int smfs_unlink(struct inode * dir,
{
struct inode *cache_dir = I2CI(dir);
struct inode *cache_inode = I2CI(dentry->d_inode);
struct dentry *cache_dentry = NULL;
struct dentry cache_dentry;
struct dentry tmp;
int rc = 0;
......@@ -181,18 +233,21 @@ static int smfs_unlink(struct inode * dir,
RETURN(-ENOENT);
prepare_parent_dentry(&tmp, cache_dir);
cache_dentry = d_alloc(&tmp, &dentry->d_name);
d_add(cache_dentry, cache_inode);
smfs_prepare_dentry(&cache_dentry, &tmp, &dentry->d_name);
d_add(&cache_dentry, cache_inode);
igrab(cache_inode);
if (cache_dir->i_op->unlink)
rc = cache_dir->i_op->unlink(cache_dir, cache_dentry);
rc = cache_dir->i_op->unlink(cache_dir, &cache_dentry);
duplicate_inode(cache_dentry->d_inode, dentry->d_inode);
duplicate_inode(cache_dentry.d_inode, dentry->d_inode);
duplicate_inode(cache_dir, dir);
d_unalloc(cache_dentry);
iput(cache_dentry.d_inode);
smfs_clear_dentry(&cache_dentry);
RETURN(rc);
}
static int smfs_symlink (struct inode * dir,
......@@ -202,7 +257,7 @@ static int smfs_symlink (struct inode * dir,
struct inode *cache_dir = I2CI(dir);
struct inode *cache_inode = NULL;
struct inode *inode = NULL;
struct dentry *cache_dentry = NULL;
struct dentry cache_dentry;
struct dentry tmp;
int rc = 0;
......@@ -210,12 +265,12 @@ static int smfs_symlink (struct inode * dir,
RETURN(-ENOENT);
prepare_parent_dentry(&tmp, NULL);
cache_dentry = d_alloc(&tmp, &dentry->d_name);
smfs_prepare_dentry(&cache_dentry, &tmp, &dentry->d_name);
if (cache_inode->i_op->symlink)
rc = cache_dir->i_op->symlink(cache_dir, cache_dentry, symname);
rc = cache_dir->i_op->symlink(cache_dir, &cache_dentry, symname);
cache_inode = cache_dentry->d_inode;
cache_inode = cache_dentry.d_inode;
inode = iget(dir->i_sb, cache_inode->i_ino);
......@@ -224,7 +279,7 @@ static int smfs_symlink (struct inode * dir,
else
rc = -ENOENT;
d_unalloc(cache_dentry);
smfs_clear_dentry(&cache_dentry);
RETURN(rc);
}
static int smfs_mkdir(struct inode * dir,
......@@ -234,7 +289,7 @@ static int smfs_mkdir(struct inode * dir,
struct inode *cache_dir = I2CI(dir);
struct inode *cache_inode = NULL;
struct inode *inode = NULL;
struct dentry *cache_dentry = NULL;
struct dentry cache_dentry;
struct dentry tmp;
int rc = 0;
......@@ -242,12 +297,12 @@ static int smfs_mkdir(struct inode * dir,
RETURN(-ENOENT);
prepare_parent_dentry(&tmp, NULL);
cache_dentry = d_alloc(&tmp, &dentry->d_name);
smfs_prepare_dentry(&cache_dentry, &tmp, &dentry->d_name);
if (cache_dir->i_op->mkdir)
rc = cache_dir->i_op->mkdir(cache_dir, cache_dentry, mode);
rc = cache_dir->i_op->mkdir(cache_dir, &cache_dentry, mode);
cache_inode = cache_dentry->d_inode;
cache_inode = cache_dentry.d_inode;
inode = iget(dir->i_sb, cache_inode->i_ino);
......@@ -257,14 +312,14 @@ static int smfs_mkdir(struct inode * dir,
d_instantiate(dentry, inode);
duplicate_inode(cache_dir, dir);
exit:
d_unalloc(cache_dentry);
smfs_clear_dentry(&cache_dentry);
RETURN(rc);
}
static int smfs_rmdir(struct inode * dir,
struct dentry *dentry)
{
struct inode *cache_dir = I2CI(dir);
struct dentry *cache_dentry = NULL;
struct dentry cache_dentry;
struct dentry tmp;
int rc = 0;
......@@ -272,15 +327,15 @@ static int smfs_rmdir(struct inode * dir,
RETURN(-ENOENT);
prepare_parent_dentry(&tmp, NULL);
cache_dentry = d_alloc(&tmp, &dentry->d_name);
smfs_prepare_dentry(&cache_dentry, &tmp, &dentry->d_name);
if (cache_dir->i_op->rmdir)
rc = cache_dir->i_op->rmdir(cache_dir, cache_dentry);
rc = cache_dir->i_op->rmdir(cache_dir, &cache_dentry);
duplicate_inode(cache_dir, dir);
duplicate_inode(cache_dentry->d_inode, dentry->d_inode);
duplicate_inode(cache_dentry.d_inode, dentry->d_inode);
d_unalloc(cache_dentry);
smfs_clear_dentry(&cache_dentry);
RETURN(rc);
}
......@@ -288,7 +343,7 @@ static int smfs_mknod(struct inode * dir, struct dentry *dentry,
int mode, int rdev)
{
struct inode *cache_dir = I2CI(dir);
struct dentry *cache_dentry = NULL;
struct dentry cache_dentry;
struct dentry tmp;
int rc = 0;
......@@ -296,15 +351,15 @@ static int smfs_mknod(struct inode * dir, struct dentry *dentry,
RETURN(-ENOENT);
prepare_parent_dentry(&tmp, NULL);
cache_dentry = d_alloc(&tmp, &dentry->d_name);
smfs_prepare_dentry(&cache_dentry, &tmp, &dentry->d_name);
if (cache_dir->i_op->mknod)
rc = cache_dir->i_op->mknod(cache_dir, dentry, mode, rdev);
rc = cache_dir->i_op->mknod(cache_dir, &cache_dentry, mode, rdev);
duplicate_inode(cache_dir, dir);
duplicate_inode(cache_dentry->d_inode, dentry->d_inode);
duplicate_inode(cache_dentry.d_inode, dentry->d_inode);
d_unalloc(cache_dentry);
smfs_clear_dentry(&cache_dentry);
RETURN(rc);
}
static int smfs_rename(struct inode * old_dir, struct dentry *old_dentry,
......@@ -315,8 +370,8 @@ static int smfs_rename(struct inode * old_dir, struct dentry *old_dentry,
struct inode *cache_old_inode = I2CI(old_dentry->d_inode);
struct inode *cache_new_inode = NULL;
struct inode *new_inode = NULL;
struct dentry *cache_old_dentry = NULL;
struct dentry *cache_new_dentry = NULL;
struct dentry cache_old_dentry;
struct dentry cache_new_dentry;
struct dentry tmp_new;
struct dentry tmp_old;
int rc = 0;
......@@ -325,17 +380,17 @@ static int smfs_rename(struct inode * old_dir, struct dentry *old_dentry,
RETURN(-ENOENT);
prepare_parent_dentry(&tmp_old, old_dir);
cache_old_dentry = d_alloc(&tmp_old, &old_dentry->d_name);
d_add(cache_old_dentry, cache_old_inode);
smfs_prepare_dentry(&cache_old_dentry, &tmp_old, &old_dentry->d_name);
d_add(&cache_old_dentry, cache_old_inode);
prepare_parent_dentry(&tmp_new, NULL);
cache_new_dentry = d_alloc(&tmp_new, &new_dentry->d_name);
smfs_prepare_dentry(&cache_new_dentry, &tmp_new, &new_dentry->d_name);
if (cache_old_dir->i_op->rename)
rc = cache_old_dir->i_op->rename(cache_old_dir, cache_old_dentry,
cache_new_dir, cache_new_dentry);
rc = cache_old_dir->i_op->rename(cache_old_dir, &cache_old_dentry,
cache_new_dir, &cache_new_dentry);
cache_new_inode = cache_new_dentry->d_inode;
cache_new_inode = cache_new_dentry.d_inode;
new_inode = iget(new_dir->i_sb, cache_new_inode->i_ino);
d_instantiate(new_dentry, new_inode);
......@@ -343,8 +398,8 @@ static int smfs_rename(struct inode * old_dir, struct dentry *old_dentry,
duplicate_inode(cache_old_dir, old_dir);
duplicate_inode(cache_new_dir, new_dir);
d_unalloc(cache_old_dentry);
d_unalloc(cache_new_dentry);
smfs_clear_dentry(&cache_old_dentry);
smfs_clear_dentry(&cache_new_dentry);
RETURN(rc);
}
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment