From: alebre <al...@us...> - 2010-12-11 19:14:57
|
This is an automated email from the git hooks/post-receive script. It was generated because a ref change was pushed to the repository containing the project "kdfs". The branch, make_kdfs_compile has been updated via 8bb8fee611cfe981850e8752ac394f6af4716f64 (commit) from 45671550ccc4be80b65ed03ca6224e2e588fcce2 (commit) Those revisions listed above that are new to this repository have not appeared on any other notification email; so we list those revisions in full, below. - Log ----------------------------------------------------------------- commit 8bb8fee611cfe981850e8752ac394f6af4716f64 Author: ad <leb...@fr...> Date: Sat Dec 11 20:14:16 2010 +0000 First progress on file deletions (still some bugs, please refer to the kerrighed-dev ML diff --git a/fs/kdfs/physical_fs.c b/fs/kdfs/physical_fs.c index 0f8801d..f450ef9 100644 --- a/fs/kdfs/physical_fs.c +++ b/fs/kdfs/physical_fs.c @@ -18,6 +18,11 @@ #include <linux/namei.h> #include <linux/fs_struct.h> + +// Used by unlink stuff... +#include <linux/mount.h> +#include <linux/security.h> + #include "physical_fs.h" #include "debug_kdfs.h" @@ -142,7 +147,7 @@ long remove_phys_dir(const char *pathname, uid_t uid, gid_t gid) goto out; } - dentry = file->f_dentry; + dentry = dget(file->f_dentry); dir = dentry->d_parent->d_inode; filp_close(file,current->files); @@ -153,18 +158,15 @@ long remove_phys_dir(const char *pathname, uid_t uid, gid_t gid) res = vfs_rmdir(dir, dentry); - DEBUG(DBG_INFO, "After vfs_rmdir dir %s from dir %s\n", dentry->d_name.name, - dentry->d_parent->d_name.name); + DEBUG(DBG_INFO, "After vfs_rmdir dir %s from dir %s (res=%ld)\n", dentry->d_name.name, + dentry->d_parent->d_name.name,res); - // TODO PRIORITY 3, Adrien Usefull / Useless ? - // Check Renaud code from kerrighed/fs/physical_fs.c dput(dentry); - put_filp(file); out: __revert_old_creds(overridden_creds, old_creds); - return res; + return res; } @@ -200,11 +202,7 @@ struct file *open_phys_file(const char *filename, int flags, int mode, uid_t uid lockdep_off(); file = filp_open(filename, flags, mode); lockdep_on(); - if (!IS_ERR(file)){ -// atomic_inc(file->f_dentry); - get_file(file); - filp_close(file, current->files); -} + DEBUG(DBG_INFO, "Open physical file %s done : %p\n", filename, file); out: @@ -229,15 +227,10 @@ out: int close_phys_file(struct file *file) { int res=1; - - struct dentry *dentry = file->f_dentry; - - + DEBUG(DBG_INFO, "Close physical file %s\n", file->f_dentry->d_name.name); -// res = filp_close(file, current->files); + res = filp_close(file, current->files); - dput(dentry); - put_filp(file); return res; } @@ -279,13 +272,13 @@ long check_create_phys_dir(const char *pathname, buf[0] = 0; strcpy(path, pathname); - fp = open_phys_file(path, O_LARGEFILE|O_RDONLY, 0644, 0, 0); + fp = open_phys_file(path, O_LARGEFILE|O_RDONLY, 0644, uid, gid); if (!IS_ERR(fp)) goto out_close; do { str_move_last_block(path, buf, '/'); - fp = open_phys_file(path, O_LARGEFILE|O_RDONLY, 0644, 0, 0); + fp = open_phys_file(path, O_LARGEFILE|O_RDONLY, 0644, uid, gid); if (!IS_ERR(fp)){ close_phys_file(fp); break; @@ -296,12 +289,12 @@ long check_create_phys_dir(const char *pathname, str_move_last_block(buf, path, '/'); error = create_phys_dir(path, mode, uid, gid); if (error != 0) - goto out_close; + goto out; } out_close: - if (!IS_ERR(fp)) close_phys_file(fp); +out: kfree(path); kfree(buf); return error; @@ -344,7 +337,7 @@ struct file* check_create_phys_file(const char *pathname, buf[0] = 0; strcpy(path, pathname); - fp = open_phys_file(path, O_CREAT|O_LARGEFILE|O_RDWR, mode, 0, 0); + fp = open_phys_file(path, O_CREAT|O_LARGEFILE|O_RDWR, mode, uid, gid); if (!IS_ERR(fp)) goto out; @@ -355,7 +348,7 @@ struct file* check_create_phys_file(const char *pathname, // Second, analyze what are the missing entries do { str_move_last_block(path, buf, '/'); - fp = open_phys_file(path, O_LARGEFILE|O_RDONLY, 0644, 0, 0); + fp = open_phys_file(path, O_LARGEFILE|O_RDONLY, 0644, uid, gid); if (!IS_ERR(fp)){ close_phys_file(fp); break; @@ -369,7 +362,7 @@ struct file* check_create_phys_file(const char *pathname, if (error != 0) goto out; } - fp = open_phys_file(pathname,O_CREAT|O_LARGEFILE|O_RDWR, mode, 0, 0); + fp = open_phys_file(pathname,O_CREAT|O_LARGEFILE|O_RDWR, mode, uid, gid); out: kfree(path); @@ -453,51 +446,74 @@ int kdfs_phys_write(struct file *file, char *addr, size_t len, loff_t *pos) * * @author Adrien Lebre * - * @param filename the file name to be removed + * @param pathname the path to the file to be removed * @param uid owner user id * @param gid owner group id * * @return 0 success * != 0 error code + * + * TODO PRIORITY 2, Adrien + * Merge remove_phys_dir and remove_phys_file in one function + * Note: the following code is strongly based on the do_unlinkat function from namei.c */ -int remove_phys_file(const char *filename, uid_t uid, gid_t gid) + +int remove_phys_file(const char *filepathname, uid_t uid, gid_t gid) { - struct file *file = NULL; - struct dentry *dentry; - struct inode *dir, *inode; + struct dentry *d_child; int res = 0; const struct cred *old_creds; struct cred *overridden_creds; - DEBUG(DBG_TRACE, "Remove file %s\n", filename); + struct inode *inode = NULL; + + struct nameidata nd; + + DEBUG(DBG_TRACE, "Remove file %s\n", filepathname); res = __change_creds(&overridden_creds, &old_creds, uid, gid); if (res) goto out; + + res = path_lookup(filepathname, LOOKUP_OPEN, &nd); + if (res){ + DEBUG(DBG_ALERT, "path_lookup for %s does not succeed\n", filepathname); + return res; + } + d_child = dget(nd.path.dentry); + mutex_lock_nested(&nd.path.dentry->d_parent->d_inode->i_mutex, I_MUTEX_PARENT); - file = filp_open(filename, O_LARGEFILE|O_RDONLY, 0644); - - if (IS_ERR(file) && PTR_ERR(file) == -ENOENT) { - DEBUG(DBG_INFO, "Can't access to physical file %s\n", filename); + if (IS_ERR(d_child)) { + DEBUG(DBG_ALERT, "Can't find the dentry for physical file %s\n", filepathname); + res = PTR_ERR(d_child); goto out; } - /* TODO PRIORITY 1, Adrien, the dentry could be dropped from the caches if we close the file before to remove it */ - dentry = file->f_dentry; - dir = dentry->d_parent->d_inode; - inode = dentry->d_inode; - filp_close(file,current->files); - -DEBUG(DBG_INFO, + DEBUG(DBG_INFO, "Remove file %s from dir %s\n", - dentry->d_name.name, dentry->d_parent->d_name.name); + d_child->d_name.name, d_child->d_parent->d_name.name); + inode = d_child->d_inode; + if (inode) + atomic_inc(&inode->i_count); + + res = mnt_want_write(nd.path.mnt); + if (res) + goto exit; + res = security_path_unlink(&nd.path, d_child); + if (res) + goto exit_umount; + + res = vfs_unlink(d_child->d_parent->d_inode, d_child); - res = vfs_unlink(dir, dentry); +exit_umount: + mnt_drop_write(nd.path.mnt); +exit: + dput(d_child); + mutex_unlock(&nd.path.dentry->d_parent->d_inode->i_mutex); - // TODO PRIORITY 3, Adrien Useful / Useless ? - // Check Renaud code from kerrighed/fs/physical_fs.c - // dput(dentry); - // put_filp(file); + if (inode) + iput(inode); /* truncate the inode here */ + path_put(&nd.path); DEBUG(DBG_INFO, "After vfs_unlink res = %d\n", res); out: @@ -505,106 +521,3 @@ out: return res; } - -// -///** -// * Prepares a directory operation by taking the mutex on the parent inode of -// * an entry and returning a dentry for the entry. -// * -// * @param child_name path to the entry, assumed absolute from configfs -// * scheduler subsystem entry. -// * -// * @return a valid dentry to the target entry, or error. The valid -// * dentry must be released with put_child_dentry. -// */ -//static struct dentry *get_child_dentry(const char *child_name) -//{ -// struct dentry *d_dir; -// struct dentry *d_child; -// const char *last_child_comp; -// const char *real_child_name = child_name; -// int err; -// -// d_dir = dget(krg_scheduler_subsys.su_group.cg_item.ci_dentry); -// -// last_child_comp = strrchr(child_name, '/'); -// if (last_child_comp) { -// struct nameidata nd; -// -// err = vfs_path_lookup(d_dir, scheduler_fs_mount, -// child_name, LOOKUP_PARENT, &nd); -// -// dput(d_dir); -// -// if (err) -// return ERR_PTR(err); -// -// d_dir = dget(nd.path.dentry); -// path_put(&nd.path); -// BUG_ON(!last_child_comp[1]); -// real_child_name = last_child_comp + 1; -// } -// -// mutex_lock_nested(&d_dir->d_inode->i_mutex, I_MUTEX_PARENT); -// d_child = lookup_one_len(real_child_name, d_dir, strlen(real_child_name)); -// if (IS_ERR(d_child)) -// mutex_unlock(&d_dir->d_inode->i_mutex); -// dput(d_dir); -// return d_child; -//} -// -// -// -// -// -// -// -//static void put_child_dentry(struct dentry *d_child) -//{ -// struct dentry *d_dir; -// -// d_dir = dget(d_child->d_parent); -// dput(d_child); -// mutex_unlock(&d_dir->d_inode->i_mutex); -// dput(d_dir); -//} -// -// -//int remove_phys_file(const char *filename, uid_t uid, gid_t gid) -//{ -// struct dentry *d_child; -// struct inode *dir; -// int res = 0; -// const struct cred *old_creds; -// struct cred *overridden_creds; -// -// DEBUG(DBG_TRACE, "Remove file %s\n", filename); -// -// res = __change_creds(&overridden_creds, &old_creds, uid, gid); -// if (res) -// goto out; -// -// d_child = get_child_dentry(filename); -// if (IS_ERR(d_child)) { -// DEBUG(DBG_INFO, "Can't find the dentry for physical file %s\n", filename); -// res = PTR_ERR(d_child); -// goto out; -// } -// -// DEBUG(DBG_INFO, -// "Remove file %s from dir %s\n", -// dentry->d_name.name, dentry->d_parent->d_name.name); -// -// res = vfs_unlink(dentr_>d_parent->d_inode, d_child); -// -// put_child_dentry(d_child); -// -// DEBUG(DBG_INFO, "After vfs_unlink res = %d\n", res); -// -//out: -// __revert_old_creds(overridden_creds, old_creds); -// -// return res; -//} -// -// diff --git a/fs/kdfs/super.c b/fs/kdfs/super.c index affc245..d68c0be 100644 --- a/fs/kdfs/super.c +++ b/fs/kdfs/super.c @@ -315,8 +315,11 @@ void kdfs_remove_local_ino(struct kdfs_super_block *k_sb, unsigned long ino) strcat(phys_dirname, "/" KDFS_INODE_FILENAME); DEBUG(DBG_INFO, "Try to remove phys_file %s\n", phys_dirname); - remove_phys_file(phys_dirname, 0, 0); - + res = remove_phys_file(phys_dirname, 0, 0); + if (res){ + DEBUG(DBG_ALERT, "Cannot remove phys file %s (res=%d)\n", phys_dirname, res); + goto exit; + } /* TODO NOW: Pierre, * Please, provide a clean way to integrate FS checkpoint mechanisms */ #if 0 @@ -336,7 +339,10 @@ void kdfs_remove_local_ino(struct kdfs_super_block *k_sb, unsigned long ino) DEBUG(DBG_INFO, "Try to remove phys_file %s\n", phys_dirname); // UNE LIGNE IMPORTANTE QUI POSE UN PROBLEME PUISQU'IL EN DECOULE une inode a null et donc un fichier qui ne pourra etre fermé proprement dans kdfs_iol_content_uninstantiate remove_phys_file(phys_dirname, 0, 0); - + if (res){ + DEBUG(DBG_ALERT, "Cannot remove phys file %s (res=%d)\n", phys_dirname, res); + goto exit; + } #if 0 kdfs_getphysicalpath(k_sb, ino, phys_dirname); sprintf(phys_dirname, "%s/.extents%d", phys_dirname, id_meta); @@ -352,8 +358,12 @@ void kdfs_remove_local_ino(struct kdfs_super_block *k_sb, unsigned long ino) kdfs_getphysicalpath(k_sb, ino, phys_dirname); DEBUG(DBG_INFO, "Try to remove phys_dir %s\n", phys_dirname); res = remove_phys_dir(phys_dirname, 0, 0); - BUG_ON(res < 0); + if (res){ + DEBUG(DBG_ALERT, "Cannot remove phys dir %s (res=%d)\n", phys_dirname, res); + goto exit; + } + exit: sb_bitmap_set_free(k_sb, KDFS_EXTRACT_INO(ino)); kfree(phys_dirname); @@ -1180,7 +1190,6 @@ void kdfs_delete_inode(struct inode *inode) // TODO check whether this is previously called by the vfs layer ? truncate_inode_pages(&inode->i_data, 0); -DEBUG(DBG_INFO, "kdfs idelete has not been called"); if (k_inode->content_setid != KDDM_SET_UNUSED) { DEBUG(DBG_INFO, "kdfs gonna uninstantiate the set"); ----------------------------------------------------------------------- Summary of changes: fs/kdfs/physical_fs.c | 217 +++++++++++++++---------------------------------- fs/kdfs/super.c | 19 +++- 2 files changed, 79 insertions(+), 157 deletions(-) hooks/post-receive -- kdfs |