X-Git-Url: https://git.whamcloud.com/?a=blobdiff_plain;f=lustre%2Fobdfs%2Fnamei.c;h=dfb3c00d7cb2b24717f6dbec3bf84452f4d98f5f;hb=6080efcd90128c21ff7cb8d9111f9423c7da97ac;hp=b874135f45318c3865c47185ef76d38b1db1f9a1;hpb=d16c3e7f2fca7daad6398f7f0432358a056d82f4;p=fs%2Flustre-release.git diff --git a/lustre/obdfs/namei.c b/lustre/obdfs/namei.c index b874135..dfb3c00 100644 --- a/lustre/obdfs/namei.c +++ b/lustre/obdfs/namei.c @@ -199,6 +199,9 @@ struct dentry *obdfs_lookup(struct inode * dir, struct dentry *dentry) * returns a locked and held page upon success */ + +/* XXX I believe these pages should in fact NOT be locked */ + static struct page *obdfs_add_entry (struct inode * dir, const char * name, int namelen, struct ext2_dir_entry_2 ** res_dir, @@ -440,6 +443,44 @@ static void show_dentry(struct list_head * dlist, int subdirs) #endif +struct inode *obdfs_new_inode(struct inode *dir) +{ + struct obdo *obdo; + struct inode *inode; + int err; + + obdo = obdo_alloc(); + if (!obdo) { + EXIT; + return ERR_PTR(-ENOMEM); + } + + err = IOPS(dir, create)(IID(dir), obdo); + if ( err ) + return ERR_PTR(err); + + inode = iget(dir->i_sb, (unsigned long)obdo->o_id); + if (!inode) { + obdo_free(obdo); + EXIT; + return ERR_PTR(-EIO); + } + + if (!list_empty(&inode->i_dentry)) { + CDEBUG(D_INODE, "New inode (%ld) has aliases!\n", + inode->i_ino); + iput(inode); + EXIT; + return ERR_PTR(-EIO); + } + + + obdo_free(obdo); + EXIT; + return inode; +} + + /* * By the time this is called, we already have created * the directory cache entry for the new file, but it @@ -454,21 +495,13 @@ int obdfs_create (struct inode * dir, struct dentry * dentry, int mode) struct page *page; struct ext2_dir_entry_2 * de; int err = -EIO; - objid id; ENTRY; - /* - * N.B. Several error exits in ext2_new_inode don't set err. - */ - err = iops(dir)->o_create(iid(dir), 0, &id); - if ( err ) - return err; - inode = iget(dir->i_sb, (ino_t)id); - if (!inode || !list_empty(&inode->i_dentry)) { - CDEBUG(D_INODE, "No inode, ino %ld\n", id); + inode = obdfs_new_inode(dir); + if ( IS_ERR(inode) ) { EXIT; - return -EIO; + return PTR_ERR(inode); } inode->i_op = &obdfs_file_inode_operations; @@ -485,18 +518,14 @@ int obdfs_create (struct inode * dir, struct dentry * dentry, int mode) de->inode = cpu_to_le32(inode->i_ino); ext2_set_de_type(dir->i_sb, de, S_IFREG); dir->i_version = ++event; - iops(dir)->o_brw(WRITE, iid(dir), dir, page, 0); + + err = obdfs_do_writepage(dir, page, IS_SYNC(dir)); UnlockPage(page); -#if 0 - if (IS_SYNC(dir)) { - ll_rw_block (WRITE, 1, &bh); - wait_on_buffer (bh); - } -#endif + page_cache_release(page); d_instantiate(dentry, inode); EXIT; - return 0; + return err; } int obdfs_mknod (struct inode * dir, struct dentry *dentry, int mode, int rdev) @@ -506,19 +535,13 @@ int obdfs_mknod (struct inode * dir, struct dentry *dentry, int mode, int rdev) struct ext2_dir_entry_2 * de; int err; - objid id; - ENTRY; - /* - * N.B. Several error exits in ext2_new_inode don't set err. - */ - err = iops(dir)->o_create(iid(dir), 0, &id); - if ( err ) - return err; - inode = iget(dir->i_sb, (ino_t)id); - if (!inode) - return -EIO; + inode = obdfs_new_inode(dir); + if ( IS_ERR(inode) ) { + EXIT; + return PTR_ERR(inode); + } inode->i_uid = current->fsuid; init_special_inode(inode, mode, rdev); @@ -529,15 +552,10 @@ int obdfs_mknod (struct inode * dir, struct dentry *dentry, int mode, int rdev) dir->i_version = ++event; ext2_set_de_type(dir->i_sb, de, inode->i_mode); mark_inode_dirty(inode); - iops(dir)->o_brw(WRITE, iid(dir), dir, page, 0); + + err = obdfs_do_writepage(dir, page, IS_SYNC(dir)); UnlockPage(page); -#if 0 - if (IS_SYNC(dir)) { - ll_rw_block (WRITE, 1, &bh); - wait_on_buffer (bh); - } -#endif d_instantiate(dentry, inode); page_cache_release(page); err = 0; @@ -557,7 +575,6 @@ int obdfs_mkdir(struct inode * dir, struct dentry * dentry, int mode) struct page *page, *inode_page; struct ext2_dir_entry_2 * de; int err; - objid id; ENTRY; @@ -565,13 +582,11 @@ int obdfs_mkdir(struct inode * dir, struct dentry * dentry, int mode) if (dir->i_nlink >= EXT2_LINK_MAX) goto out; - err = iops(dir)->o_create(iid(dir), 0, &id); - if ( err ) - return err; - inode = iget(dir->i_sb, (ino_t)id); - if (!inode) - return -EIO; - + inode = obdfs_new_inode(dir); + if ( IS_ERR(inode) ) { + EXIT; + return PTR_ERR(inode); + } inode->i_op = &obdfs_dir_inode_operations; inode->i_blocks = 0; @@ -598,11 +613,12 @@ int obdfs_mkdir(struct inode * dir, struct dentry * dentry, int mode) strcpy (de->name, ".."); ext2_set_de_type(dir->i_sb, de, S_IFDIR); - iops(dir)->o_brw(WRITE, iid(dir), inode, inode_page, 1); + err = obdfs_do_writepage(inode, inode_page, IS_SYNC(inode)); inode->i_blocks = PAGE_SIZE/inode->i_sb->s_blocksize; inode->i_size = PAGE_SIZE; UnlockPage(inode_page); page_cache_release(inode_page); + /* XXX handle err */ inode->i_nlink = 2; inode->i_mode = S_IFDIR | mode; @@ -620,17 +636,13 @@ int obdfs_mkdir(struct inode * dir, struct dentry * dentry, int mode) ext2_set_de_type(dir->i_sb, de, S_IFDIR); dir->i_version = ++event; -#if 0 - if (IS_SYNC(dir)) { - ll_rw_block (WRITE, 1, &bh); - wait_on_buffer (bh); - } -#endif dir->i_nlink++; dir->u.ext2_i.i_flags &= ~EXT2_BTREE_FL; mark_inode_dirty(dir); - iops(dir)->o_brw(WRITE, iid(dir), dir, page, 1); + err = obdfs_do_writepage(dir, page, IS_SYNC(dir)); + UnlockPage(page); + page_cache_release(page); d_instantiate(dentry, inode); err = 0; @@ -720,6 +732,7 @@ int obdfs_rmdir (struct inode * dir, struct dentry *dentry) struct inode * inode; struct page *page; struct ext2_dir_entry_2 * de; + int err; ENTRY; @@ -743,14 +756,9 @@ int obdfs_rmdir (struct inode * dir, struct dentry *dentry) dir->i_version = ++event; if (retval) goto end_rmdir; - iops(dir)->o_brw(WRITE, iid(dir), dir, page, 0); + err = obdfs_do_writepage(dir, page, IS_SYNC(dir)); UnlockPage(page); -#if 0 - if (IS_SYNC(dir)) { - ll_rw_block (WRITE, 1, &bh); - wait_on_buffer (bh); - } -#endif + if (inode->i_nlink != 2) ext2_warning (inode->i_sb, "ext2_rmdir", "empty directory has nlink!=2 (%d)", @@ -778,6 +786,7 @@ int obdfs_unlink(struct inode * dir, struct dentry *dentry) struct inode * inode; struct page *page; struct ext2_dir_entry_2 * de; + int err; ENTRY; @@ -803,14 +812,9 @@ int obdfs_unlink(struct inode * dir, struct dentry *dentry) if (retval) goto end_unlink; dir->i_version = ++event; - iops(dir)->o_brw(WRITE, iid(dir), dir, page, 0); + err = obdfs_do_writepage(dir, page, IS_SYNC(dir)); UnlockPage(page); -#if 0 - if (IS_SYNC(dir)) { - ll_rw_block (WRITE, 1, &bh); - wait_on_buffer (bh); - } -#endif + dir->i_ctime = dir->i_mtime = CURRENT_TIME; dir->u.ext2_i.i_flags &= ~EXT2_BTREE_FL; mark_inode_dirty(dir); @@ -835,22 +839,14 @@ int obdfs_symlink (struct inode * dir, struct dentry *dentry, const char * symna char * link; int i, l, err = -EIO; char c; - objid id; ENTRY; - /* - * N.B. Several error exits in ext2_new_inode don't set err. - */ - err = iops(dir)->o_create(iid(dir), 0, &id); - if ( err ) { + inode = obdfs_new_inode(dir); + if ( IS_ERR(inode) ) { EXIT; - return err; - } - inode = iget(dir->i_sb, (ino_t)id); - if (!inode) { - EXIT; - return err; + return PTR_ERR(inode); } + inode->i_mode = S_IFLNK | S_IRWXUGO; inode->i_op = &obdfs_symlink_inode_operations; for (l = 0; l < inode->i_sb->s_blocksize - 1 && @@ -880,7 +876,7 @@ int obdfs_symlink (struct inode * dir, struct dentry *dentry, const char * symna link[i++] = c; link[i] = 0; if (name_page) { - iops(inode)->o_brw(WRITE, iid(inode), inode, name_page, 1); + obdfs_do_writepage(inode, name_page, IS_SYNC(inode)); PDEBUG(name_page, "symlink"); UnlockPage(name_page); page_cache_release(name_page); @@ -894,14 +890,9 @@ int obdfs_symlink (struct inode * dir, struct dentry *dentry, const char * symna de->inode = cpu_to_le32(inode->i_ino); ext2_set_de_type(dir->i_sb, de, S_IFLNK); dir->i_version = ++event; - iops(dir)->o_brw(WRITE, iid(dir), dir, page, 1); + obdfs_do_writepage(dir, page, IS_SYNC(dir)); UnlockPage(page); -#if 0 - if (IS_SYNC(dir)) { - ll_rw_block (WRITE, 1, &bh); - wait_on_buffer (bh); - } -#endif + d_instantiate(dentry, inode); err = 0; out: @@ -938,15 +929,10 @@ int obdfs_link (struct dentry * old_dentry, de->inode = cpu_to_le32(inode->i_ino); ext2_set_de_type(dir->i_sb, de, inode->i_mode); dir->i_version = ++event; - iops(dir)->o_brw(WRITE, iid(dir), dir, page, 0); + + obdfs_do_writepage(dir, page, IS_SYNC(dir)); UnlockPage(page); -#if 0 - if (IS_SYNC(dir)) { - ll_rw_block (WRITE, 1, &bh); - wait_on_buffer (bh); - } -#endif page_cache_release(page); inode->i_nlink++; inode->i_ctime = CURRENT_TIME; @@ -1056,7 +1042,7 @@ int obdfs_rename (struct inode * old_dir, struct dentry *old_dentry, mark_inode_dirty(old_dir); if (dir_page) { PARENT_INO(page_address(dir_page)) = le32_to_cpu(new_dir->i_ino); - iops(old_inode)->o_brw(WRITE, iid(old_inode), old_inode, dir_page, 0); + obdfs_do_writepage(old_inode, dir_page, IS_SYNC(old_inode)); old_dir->i_nlink--; mark_inode_dirty(old_dir); if (new_inode) { @@ -1075,21 +1061,10 @@ int obdfs_rename (struct inode * old_dir, struct dentry *old_dentry, page_cache_release(old_page); old_page = obdfs_getpage(old_dir, index >> PAGE_SHIFT, 0, LOCKED); CDEBUG(D_INODE, "old_page at %p\n", old_page); - iops(old_dir)->o_brw(WRITE, iid(old_dir), old_dir, old_page,0); - } -#if 0 - if (IS_SYNC(old_dir)) { - ll_rw_block (WRITE, 1, &old_bh); - wait_on_buffer (old_bh); + obdfs_do_writepage(old_dir, old_page, IS_SYNC(old_dir)); } -#endif - iops(new_dir)->o_brw(WRITE, iid(new_dir), new_dir, new_page, 0); -#if 0 - if (IS_SYNC(new_dir)) { - ll_rw_block (WRITE, 1, &new_bh); - wait_on_buffer (new_bh); - } -#endif + + obdfs_do_writepage(new_dir, new_page, IS_SYNC(new_dir)); retval = 0;