X-Git-Url: https://git.whamcloud.com/?a=blobdiff_plain;f=lustre%2Fobdfs%2Fnamei.c;h=340f4a5033b8a2441fddcd4ae68e922043f1fbc6;hb=726c9cf39547151a7cf85118c8a23b9ecf8220f5;hp=a360c3a238944efc0eaa99153d75bfbc854103cf;hpb=00102f342959b094f035b618c0b7acf477de35b4;p=fs%2Flustre-release.git diff --git a/lustre/obdfs/namei.c b/lustre/obdfs/namei.c index a360c3a..340f4a5 100644 --- a/lustre/obdfs/namei.c +++ b/lustre/obdfs/namei.c @@ -33,8 +33,8 @@ #define DEBUG_SUBSYSTEM S_OBDFS -#include #include +#include extern struct address_space_operations obdfs_aops; /* from super.c */ @@ -46,76 +46,76 @@ extern int ext2_add_link (struct dentry *dentry, struct inode *inode); ino_t obdfs_inode_by_name(struct inode * dir, struct dentry *dentry, int *typ); int ext2_make_empty(struct inode *inode, struct inode *parent); struct ext2_dir_entry_2 * ext2_find_entry (struct inode * dir, - struct dentry *dentry, struct page ** res_page); + struct dentry *dentry, struct page ** res_page); int ext2_delete_entry (struct ext2_dir_entry_2 * dir, struct page * page ); int ext2_empty_dir (struct inode * inode); struct ext2_dir_entry_2 * ext2_dotdot (struct inode *dir, struct page **p); void ext2_set_link(struct inode *dir, struct ext2_dir_entry_2 *de, - struct page *page, struct inode *inode); + struct page *page, struct inode *inode); /* * Couple of helper functions - make the code slightly cleaner. */ static inline void ext2_inc_count(struct inode *inode) { - inode->i_nlink++; - obdfs_change_inode(inode); + inode->i_nlink++; + obdfs_change_inode(inode); } /* postpone the disk update until the inode really goes away */ static inline void ext2_dec_count(struct inode *inode) { - inode->i_nlink--; - if (inode->i_nlink > 0) - obdfs_change_inode(inode); + inode->i_nlink--; + if (inode->i_nlink > 0) + obdfs_change_inode(inode); } static inline int ext2_add_nondir(struct dentry *dentry, struct inode *inode) { - int err; - err = ext2_add_link(dentry, inode); - if (!err) { - d_instantiate(dentry, inode); - return 0; - } - ext2_dec_count(inode); - iput(inode); - return err; + int err; + err = ext2_add_link(dentry, inode); + if (!err) { + d_instantiate(dentry, inode); + return 0; + } + ext2_dec_count(inode); + iput(inode); + return err; } /* methods */ static struct dentry *obdfs_lookup(struct inode * dir, struct dentry *dentry) { struct obdo *oa; - struct inode * inode = NULL; - int type; - ino_t ino; - + struct inode * inode = NULL; + int type; + ino_t ino; + ENTRY; - if (dentry->d_name.len > EXT2_NAME_LEN) - return ERR_PTR(-ENAMETOOLONG); + if (dentry->d_name.len > EXT2_NAME_LEN) + return ERR_PTR(-ENAMETOOLONG); - ino = obdfs_inode_by_name(dir, dentry, &type); - if (!ino) - goto negative; + ino = obdfs_inode_by_name(dir, dentry, &type); + if (!ino) + goto negative; oa = obdo_fromid(IID(dir), ino, type, - OBD_MD_FLNOTOBD | OBD_MD_FLBLOCKS); + OBD_MD_FLNOTOBD | OBD_MD_FLBLOCKS); if ( IS_ERR(oa) ) { - printk(__FUNCTION__ ": obdo_fromid failed\n"); + CERROR("obdo_fromid failed\n"); EXIT; return ERR_PTR(-EACCES); } - inode = iget4(dir->i_sb, ino, NULL, oa); + inode = iget4(dir->i_sb, ino, NULL, oa); obdo_free(oa); - if (!inode) - return ERR_PTR(-EACCES); + if (!inode) + return ERR_PTR(-EACCES); negative: - d_add(dentry, inode); - return NULL; + d_add(dentry, inode); + return NULL; } @@ -151,35 +151,35 @@ static struct inode *obdfs_new_inode(struct inode *dir, int mode) /* Send a hint to the create method on the type of file to create */ oa->o_mode = mode; oa->o_valid |= OBD_MD_FLMODE; - CDEBUG(D_INODE, "\n"); + CDEBUG(D_INODE, "\n"); err = obd_create(IID(dir), oa); - CDEBUG(D_INODE, "\n"); + CDEBUG(D_INODE, "\n"); if ( err ) { - printk("new_inode - fatal: err %d\n", err); + CERROR("new_inode - fatal: err %d\n", err); obdo_free(oa); EXIT; return ERR_PTR(err); } - CDEBUG(D_INODE, "obdo mode %o\n", oa->o_mode); + CDEBUG(D_INODE, "obdo mode %o\n", oa->o_mode); inode = iget4(dir->i_sb, (ino_t)oa->o_id, NULL, oa); - CDEBUG(D_INODE, "\n"); + CDEBUG(D_INODE, "\n"); if (!inode) { - printk("new_inode -fatal: %ld\n", (long)oa->o_id); + CERROR("new_inode -fatal: %ld\n", (long)oa->o_id); obd_destroy(IID(dir), oa); - obdo_free(oa); + obdo_free(oa); EXIT; return ERR_PTR(-EIO); } obdo_free(oa); if (!list_empty(&inode->i_dentry)) { - printk("new_inode -fatal: aliases %ld, ct %d lnk %d\n", - (long)oa->o_id, - atomic_read(&inode->i_count), - inode->i_nlink); + CERROR("new_inode -fatal: aliases %ld, ct %d lnk %d\n", + (long)oa->o_id, + atomic_read(&inode->i_count), + inode->i_nlink); obd_destroy(IID(dir), oa); iput(inode); EXIT; @@ -201,266 +201,266 @@ static struct inode *obdfs_new_inode(struct inode *dir, int mode) */ static int obdfs_create (struct inode * dir, struct dentry * dentry, int mode) { - struct inode * inode = obdfs_new_inode (dir, mode); - int err = PTR_ERR(inode); - if (!IS_ERR(inode)) { - inode->i_op = &obdfs_file_inode_operations; - inode->i_fop = &obdfs_file_operations; - inode->i_mapping->a_ops = &obdfs_aops; - err = ext2_add_nondir(dentry, inode); - } - return err; + struct inode * inode = obdfs_new_inode (dir, mode); + int err = PTR_ERR(inode); + if (!IS_ERR(inode)) { + inode->i_op = &obdfs_file_inode_operations; + inode->i_fop = &obdfs_file_operations; + inode->i_mapping->a_ops = &obdfs_aops; + err = ext2_add_nondir(dentry, inode); + } + return err; } /* obdfs_create */ static int obdfs_mknod (struct inode * dir, struct dentry *dentry, int mode, int rdev) { - struct inode * inode = obdfs_new_inode (dir, mode); - int err = PTR_ERR(inode); - if (!IS_ERR(inode)) { - init_special_inode(inode, mode, rdev); - obdfs_change_inode(inode); - err = ext2_add_nondir(dentry, inode); - } - return err; + struct inode * inode = obdfs_new_inode (dir, mode); + int err = PTR_ERR(inode); + if (!IS_ERR(inode)) { + init_special_inode(inode, mode, rdev); + obdfs_change_inode(inode); + err = ext2_add_nondir(dentry, inode); + } + return err; } static int obdfs_symlink (struct inode * dir, struct dentry * dentry, - const char * symname) + const char * symname) { - struct super_block * sb = dir->i_sb; - int err = -ENAMETOOLONG; - unsigned l = strlen(symname)+1; - struct inode * inode; + struct super_block * sb = dir->i_sb; + int err = -ENAMETOOLONG; + unsigned l = strlen(symname)+1; + struct inode * inode; struct obdfs_inode_info *oinfo; - if (l > sb->s_blocksize) - goto out; + if (l > sb->s_blocksize) + goto out; - inode = obdfs_new_inode (dir, S_IFLNK | S_IRWXUGO); - err = PTR_ERR(inode); - if (IS_ERR(inode)) - goto out; + inode = obdfs_new_inode (dir, S_IFLNK | S_IRWXUGO); + err = PTR_ERR(inode); + if (IS_ERR(inode)) + goto out; oinfo = obdfs_i2info(inode); if (l >= sizeof(oinfo->oi_inline)) { - /* slow symlink */ - inode->i_op = &page_symlink_inode_operations; - inode->i_mapping->a_ops = &obdfs_aops; - err = block_symlink(inode, symname, l); - if (err) - goto out_fail; - } else { - /* fast symlink */ - inode->i_op = &obdfs_fast_symlink_inode_operations; - memcpy(oinfo->oi_inline, symname, l); - inode->i_size = l-1; - } - obdfs_change_inode(inode); - - err = ext2_add_nondir(dentry, inode); + /* slow symlink */ + inode->i_op = &page_symlink_inode_operations; + inode->i_mapping->a_ops = &obdfs_aops; + err = block_symlink(inode, symname, l); + if (err) + goto out_fail; + } else { + /* fast symlink */ + inode->i_op = &obdfs_fast_symlink_inode_operations; + memcpy(oinfo->oi_inline, symname, l); + inode->i_size = l-1; + } + obdfs_change_inode(inode); + + err = ext2_add_nondir(dentry, inode); out: - return err; + return err; out_fail: - ext2_dec_count(inode); - iput (inode); - goto out; + ext2_dec_count(inode); + iput (inode); + goto out; } static int obdfs_link (struct dentry * old_dentry, struct inode * dir, - struct dentry *dentry) + struct dentry *dentry) { - struct inode *inode = old_dentry->d_inode; + struct inode *inode = old_dentry->d_inode; - if (S_ISDIR(inode->i_mode)) - return -EPERM; + if (S_ISDIR(inode->i_mode)) + return -EPERM; - if (inode->i_nlink >= EXT2_LINK_MAX) - return -EMLINK; + if (inode->i_nlink >= EXT2_LINK_MAX) + return -EMLINK; - inode->i_ctime = CURRENT_TIME; - ext2_inc_count(inode); - atomic_inc(&inode->i_count); + inode->i_ctime = CURRENT_TIME; + ext2_inc_count(inode); + atomic_inc(&inode->i_count); - return ext2_add_nondir(dentry, inode); + return ext2_add_nondir(dentry, inode); } static int obdfs_mkdir(struct inode * dir, struct dentry * dentry, int mode) { - struct inode * inode; - int err = -EMLINK; - ENTRY; + struct inode * inode; + int err = -EMLINK; + ENTRY; - if (dir->i_nlink >= EXT2_LINK_MAX) - goto out; + if (dir->i_nlink >= EXT2_LINK_MAX) + goto out; - ext2_inc_count(dir); + ext2_inc_count(dir); - inode = obdfs_new_inode (dir, S_IFDIR | mode); - err = PTR_ERR(inode); - if (IS_ERR(inode)) - goto out_dir; + inode = obdfs_new_inode (dir, S_IFDIR | mode); + err = PTR_ERR(inode); + if (IS_ERR(inode)) + goto out_dir; - inode->i_op = &obdfs_dir_inode_operations; - inode->i_fop = &obdfs_dir_operations; - inode->i_mapping->a_ops = &obdfs_aops; + inode->i_op = &obdfs_dir_inode_operations; + inode->i_fop = &obdfs_dir_operations; + inode->i_mapping->a_ops = &obdfs_aops; - ext2_inc_count(inode); + ext2_inc_count(inode); - err = ext2_make_empty(inode, dir); - if (err) - goto out_fail; + err = ext2_make_empty(inode, dir); + if (err) + goto out_fail; - err = ext2_add_link(dentry, inode); - if (err) - goto out_fail; + err = ext2_add_link(dentry, inode); + if (err) + goto out_fail; - d_instantiate(dentry, inode); + d_instantiate(dentry, inode); out: - EXIT; - return err; + EXIT; + return err; out_fail: - ext2_dec_count(inode); - ext2_dec_count(inode); - iput(inode); - EXIT; + ext2_dec_count(inode); + ext2_dec_count(inode); + iput(inode); + EXIT; out_dir: - ext2_dec_count(dir); - EXIT; - goto out; + ext2_dec_count(dir); + EXIT; + goto out; } static int obdfs_unlink(struct inode * dir, struct dentry *dentry) { - struct inode * inode = dentry->d_inode; - struct ext2_dir_entry_2 * de; - struct page * page; - int err = -ENOENT; - - de = ext2_find_entry (dir, dentry, &page); - if (!de) - goto out; - - err = ext2_delete_entry (de, page); - if (err) - goto out; - - inode->i_ctime = dir->i_ctime; - ext2_dec_count(inode); - err = 0; + struct inode * inode = dentry->d_inode; + struct ext2_dir_entry_2 * de; + struct page * page; + int err = -ENOENT; + + de = ext2_find_entry (dir, dentry, &page); + if (!de) + goto out; + + err = ext2_delete_entry (de, page); + if (err) + goto out; + + inode->i_ctime = dir->i_ctime; + ext2_dec_count(inode); + err = 0; out: - return err; + return err; } static int obdfs_rmdir (struct inode * dir, struct dentry *dentry) { - struct inode * inode = dentry->d_inode; - int err = -ENOTEMPTY; - - if (ext2_empty_dir(inode)) { - err = obdfs_unlink(dir, dentry); - if (!err) { - inode->i_size = 0; - ext2_dec_count(inode); - ext2_dec_count(dir); - } - } - return err; + struct inode * inode = dentry->d_inode; + int err = -ENOTEMPTY; + + if (ext2_empty_dir(inode)) { + err = obdfs_unlink(dir, dentry); + if (!err) { + inode->i_size = 0; + ext2_dec_count(inode); + ext2_dec_count(dir); + } + } + return err; } static int obdfs_rename (struct inode * old_dir, struct dentry * old_dentry, - struct inode * new_dir, struct dentry * new_dentry ) + struct inode * new_dir, struct dentry * new_dentry ) { - struct inode * old_inode = old_dentry->d_inode; - struct inode * new_inode = new_dentry->d_inode; - struct page * dir_page = NULL; - struct ext2_dir_entry_2 * dir_de = NULL; - struct page * old_page; - struct ext2_dir_entry_2 * old_de; - int err = -ENOENT; - - old_de = ext2_find_entry (old_dir, old_dentry, &old_page); - if (!old_de) - goto out; - - if (S_ISDIR(old_inode->i_mode)) { - err = -EIO; - dir_de = ext2_dotdot(old_inode, &dir_page); - if (!dir_de) - goto out_old; - } - - if (new_inode) { - struct page *new_page; - struct ext2_dir_entry_2 *new_de; - - err = -ENOTEMPTY; - if (dir_de && !ext2_empty_dir (new_inode)) - goto out_dir; - - err = -ENOENT; - new_de = ext2_find_entry (new_dir, new_dentry, &new_page); - if (!new_de) - goto out_dir; - ext2_inc_count(old_inode); - ext2_set_link(new_dir, new_de, new_page, old_inode); - new_inode->i_ctime = CURRENT_TIME; - if (dir_de) - new_inode->i_nlink--; - ext2_dec_count(new_inode); - } else { - if (dir_de) { - err = -EMLINK; - if (new_dir->i_nlink >= EXT2_LINK_MAX) - goto out_dir; - } - ext2_inc_count(old_inode); - err = ext2_add_link(new_dentry, old_inode); - if (err) { - ext2_dec_count(old_inode); - goto out_dir; - } - if (dir_de) - ext2_inc_count(new_dir); - } - - ext2_delete_entry (old_de, old_page); - ext2_dec_count(old_inode); - - if (dir_de) { - ext2_set_link(old_inode, dir_de, dir_page, new_dir); - ext2_dec_count(old_dir); - } - return 0; + struct inode * old_inode = old_dentry->d_inode; + struct inode * new_inode = new_dentry->d_inode; + struct page * dir_page = NULL; + struct ext2_dir_entry_2 * dir_de = NULL; + struct page * old_page; + struct ext2_dir_entry_2 * old_de; + int err = -ENOENT; + + old_de = ext2_find_entry (old_dir, old_dentry, &old_page); + if (!old_de) + goto out; + + if (S_ISDIR(old_inode->i_mode)) { + err = -EIO; + dir_de = ext2_dotdot(old_inode, &dir_page); + if (!dir_de) + goto out_old; + } + + if (new_inode) { + struct page *new_page; + struct ext2_dir_entry_2 *new_de; + + err = -ENOTEMPTY; + if (dir_de && !ext2_empty_dir (new_inode)) + goto out_dir; + + err = -ENOENT; + new_de = ext2_find_entry (new_dir, new_dentry, &new_page); + if (!new_de) + goto out_dir; + ext2_inc_count(old_inode); + ext2_set_link(new_dir, new_de, new_page, old_inode); + new_inode->i_ctime = CURRENT_TIME; + if (dir_de) + new_inode->i_nlink--; + ext2_dec_count(new_inode); + } else { + if (dir_de) { + err = -EMLINK; + if (new_dir->i_nlink >= EXT2_LINK_MAX) + goto out_dir; + } + ext2_inc_count(old_inode); + err = ext2_add_link(new_dentry, old_inode); + if (err) { + ext2_dec_count(old_inode); + goto out_dir; + } + if (dir_de) + ext2_inc_count(new_dir); + } + + ext2_delete_entry (old_de, old_page); + ext2_dec_count(old_inode); + + if (dir_de) { + ext2_set_link(old_inode, dir_de, dir_page, new_dir); + ext2_dec_count(old_dir); + } + return 0; out_dir: - if (dir_de) { - kunmap(dir_page); - page_cache_release(dir_page); - } + if (dir_de) { + kunmap(dir_page); + page_cache_release(dir_page); + } out_old: - kunmap(old_page); - page_cache_release(old_page); + kunmap(old_page); + page_cache_release(old_page); out: - return err; + return err; } struct inode_operations obdfs_dir_inode_operations = { - create: obdfs_create, - lookup: obdfs_lookup, - link: obdfs_link, - unlink: obdfs_unlink, - symlink: obdfs_symlink, - mkdir: obdfs_mkdir, - rmdir: obdfs_rmdir, - mknod: obdfs_mknod, - rename: obdfs_rename, - setattr: obdfs_setattr + create: obdfs_create, + lookup: obdfs_lookup, + link: obdfs_link, + unlink: obdfs_unlink, + symlink: obdfs_symlink, + mkdir: obdfs_mkdir, + rmdir: obdfs_rmdir, + mknod: obdfs_mknod, + rename: obdfs_rename, + setattr: obdfs_setattr };