ocfs2: use all extent block suballocators
[safe/jmp/linux-2.6] / fs / ocfs2 / namei.c
index 21db45d..36289e6 100644 (file)
@@ -175,8 +175,6 @@ static struct dentry *ocfs2_lookup(struct inode *dir, struct dentry *dentry,
 
        inode = ocfs2_iget(OCFS2_SB(dir->i_sb), blkno, 0);
        if (IS_ERR(inode)) {
-               mlog(ML_ERROR, "Unable to create inode %llu\n",
-                    (unsigned long long)blkno);
                ret = ERR_PTR(-EACCES);
                goto bail_unlock;
        }
@@ -189,7 +187,6 @@ static struct dentry *ocfs2_lookup(struct inode *dir, struct dentry *dentry,
         * unlink. */
        spin_lock(&oi->ip_lock);
        oi->ip_flags &= ~OCFS2_INODE_MAYBE_ORPHANED;
-       oi->ip_orphaned_slot = OCFS2_INVALID_SLOT;
        spin_unlock(&oi->ip_lock);
 
 bail_add:
@@ -288,7 +285,7 @@ static int ocfs2_fill_new_dir(struct ocfs2_super *osb,
 
        i_size_write(inode, inode->i_sb->s_blocksize);
        inode->i_nlink = 2;
-       inode->i_blocks = ocfs2_align_bytes_to_sectors(inode->i_sb->s_blocksize);
+       inode->i_blocks = ocfs2_inode_sector_count(inode);
        status = ocfs2_mark_inode_dirty(handle, inode, fe_bh);
        if (status < 0) {
                mlog_errno(status);
@@ -581,15 +578,18 @@ static int ocfs2_mknod_locked(struct ocfs2_super *osb,
        if (ocfs2_populate_inode(inode, fe, 1) < 0) {
                mlog(ML_ERROR, "populate inode failed! bh->b_blocknr=%llu, "
                     "i_blkno=%llu, i_ino=%lu\n",
-                    (unsigned long long) (*new_fe_bh)->b_blocknr,
-                    (unsigned long long)fe->i_blkno, inode->i_ino);
+                    (unsigned long long)(*new_fe_bh)->b_blocknr,
+                    (unsigned long long)le64_to_cpu(fe->i_blkno),
+                    inode->i_ino);
                BUG();
        }
 
        ocfs2_inode_set_new(osb, inode);
-       status = ocfs2_create_new_inode_locks(inode);
-       if (status < 0)
-               mlog_errno(status);
+       if (!ocfs2_mount_local(osb)) {
+               status = ocfs2_create_new_inode_locks(inode);
+               if (status < 0)
+                       mlog_errno(status);
+       }
 
        status = 0; /* error in ocfs2_create_new_inode_locks is not
                     * critical */
@@ -930,14 +930,15 @@ static int ocfs2_unlink(struct inode *dir,
                goto leave;
        }
 
-       if (S_ISDIR(inode->i_mode)) {
+       dir->i_ctime = dir->i_mtime = CURRENT_TIME;
+       if (S_ISDIR(inode->i_mode))
                drop_nlink(dir);
-               status = ocfs2_mark_inode_dirty(handle, dir,
-                                               parent_node_bh);
-               if (status < 0) {
-                       mlog_errno(status);
+
+       status = ocfs2_mark_inode_dirty(handle, dir, parent_node_bh);
+       if (status < 0) {
+               mlog_errno(status);
+               if (S_ISDIR(inode->i_mode))
                        inc_nlink(dir);
-               }
        }
 
 leave:
@@ -1066,6 +1067,7 @@ static int ocfs2_rename(struct inode *old_dir,
        char orphan_name[OCFS2_ORPHAN_NAMELEN + 1];
        struct buffer_head *orphan_entry_bh = NULL;
        struct buffer_head *newfe_bh = NULL;
+       struct buffer_head *old_inode_bh = NULL;
        struct buffer_head *insert_entry_bh = NULL;
        struct ocfs2_super *osb = NULL;
        u64 newfe_blkno;
@@ -1077,7 +1079,7 @@ static int ocfs2_rename(struct inode *old_dir,
        struct buffer_head *new_de_bh = NULL, *old_de_bh = NULL; // bhs for above
        struct buffer_head *old_inode_de_bh = NULL; // if old_dentry is a dir,
                                                    // this is the 1st dirent bh
-       nlink_t old_dir_nlink = old_dir->i_nlink, new_dir_nlink = new_dir->i_nlink;
+       nlink_t old_dir_nlink = old_dir->i_nlink;
 
        /* At some point it might be nice to break this function up a
         * bit. */
@@ -1094,7 +1096,7 @@ static int ocfs2_rename(struct inode *old_dir,
                        BUG();
        }
 
-       /* Assume a directory heirarchy thusly:
+       /* Assume a directory hierarchy thusly:
         * a/b/c
         * a/d
         * a,b,c, and d are all directories.
@@ -1137,12 +1139,11 @@ static int ocfs2_rename(struct inode *old_dir,
        }
 
        /*
-        * Though we don't require an inode meta data update if
-        * old_inode is not a directory, we lock anyway here to ensure
-        * the vote thread on other nodes won't have to concurrently
-        * downconvert the inode and the dentry locks.
+        * Aside from allowing a meta data update, the locking here
+        * also ensures that the vote thread on other nodes won't have
+        * to concurrently downconvert the inode and the dentry locks.
         */
-       status = ocfs2_meta_lock(old_inode, NULL, 1);
+       status = ocfs2_meta_lock(old_inode, &old_inode_bh, 1);
        if (status < 0) {
                if (status != -ENOENT)
                        mlog_errno(status);
@@ -1353,6 +1354,7 @@ static int ocfs2_rename(struct inode *old_dir,
 
        old_inode->i_ctime = CURRENT_TIME;
        mark_inode_dirty(old_inode);
+       ocfs2_mark_inode_dirty(handle, old_inode, old_inode_bh);
 
        /* now that the name has been added to new_dir, remove the old name */
        status = ocfs2_delete_entry(handle, old_dir, old_de, old_de_bh);
@@ -1382,27 +1384,22 @@ static int ocfs2_rename(struct inode *old_dir,
                }
        }
        mark_inode_dirty(old_dir);
-       if (new_inode)
+       ocfs2_mark_inode_dirty(handle, old_dir, old_dir_bh);
+       if (new_inode) {
                mark_inode_dirty(new_inode);
+               ocfs2_mark_inode_dirty(handle, new_inode, newfe_bh);
+       }
 
-       if (old_dir != new_dir)
-               if (new_dir_nlink != new_dir->i_nlink) {
-                       if (!new_dir_bh) {
-                               mlog(ML_ERROR, "need to change nlink for new "
-                                    "dir %llu from %d to %d but bh is NULL\n",
-                                    (unsigned long long)OCFS2_I(new_dir)->ip_blkno,
-                                    (int)new_dir_nlink, new_dir->i_nlink);
-                       } else {
-                               struct ocfs2_dinode *fe;
-                               status = ocfs2_journal_access(handle,
-                                                             new_dir,
-                                                             new_dir_bh,
-                                                             OCFS2_JOURNAL_ACCESS_WRITE);
-                               fe = (struct ocfs2_dinode *) new_dir_bh->b_data;
-                               fe->i_links_count = cpu_to_le16(new_dir->i_nlink);
-                               status = ocfs2_journal_dirty(handle, new_dir_bh);
-                       }
-               }
+       if (old_dir != new_dir) {
+               /* Keep the same times on both directories.*/
+               new_dir->i_ctime = new_dir->i_mtime = old_dir->i_ctime;
+
+               /*
+                * This will also pick up the i_nlink change from the
+                * block above.
+                */
+               ocfs2_mark_inode_dirty(handle, new_dir, new_dir_bh);
+       }
 
        if (old_dir_nlink != old_dir->i_nlink) {
                if (!old_dir_bh) {
@@ -1453,6 +1450,8 @@ bail:
                iput(new_inode);
        if (newfe_bh)
                brelse(newfe_bh);
+       if (old_inode_bh)
+               brelse(old_inode_bh);
        if (old_dir_bh)
                brelse(old_dir_bh);
        if (new_dir_bh)
@@ -1485,8 +1484,7 @@ static int ocfs2_create_symlink_data(struct ocfs2_super *osb,
        struct buffer_head **bhs = NULL;
        const char *c;
        struct super_block *sb = osb->sb;
-       u64 p_blkno;
-       int p_blocks;
+       u64 p_blkno, p_blocks;
        int virtual, blocks, status, i, bytes_left;
 
        bytes_left = i_size_read(inode) + 1;
@@ -1513,8 +1511,8 @@ static int ocfs2_create_symlink_data(struct ocfs2_super *osb,
                goto bail;
        }
 
-       status = ocfs2_extent_map_get_blocks(inode, 0, 1, &p_blkno,
-                                            &p_blocks);
+       status = ocfs2_extent_map_get_blocks(inode, 0, &p_blkno, &p_blocks,
+                                            NULL);
        if (status < 0) {
                mlog_errno(status);
                goto bail;
@@ -1673,8 +1671,11 @@ static int ocfs2_symlink(struct inode *dir,
        inode->i_rdev = 0;
        newsize = l - 1;
        if (l > ocfs2_fast_symlink_chars(sb)) {
+               u32 offset = 0;
+
                inode->i_op = &ocfs2_symlink_inode_operations;
-               status = ocfs2_do_extend_allocation(osb, inode, 1, new_fe_bh,
+               status = ocfs2_do_extend_allocation(osb, inode, &offset, 1,
+                                                   new_fe_bh,
                                                    handle, data_ac, NULL,
                                                    NULL);
                if (status < 0) {
@@ -1688,7 +1689,7 @@ static int ocfs2_symlink(struct inode *dir,
                        goto bail;
                }
                i_size_write(inode, newsize);
-               inode->i_blocks = ocfs2_align_bytes_to_sectors(newsize);
+               inode->i_blocks = ocfs2_inode_sector_count(inode);
        } else {
                inode->i_op = &ocfs2_fast_symlink_inode_operations;
                memcpy((char *) fe->id2.i_symlink, symname, l);
@@ -1824,6 +1825,13 @@ static int __ocfs2_add_entry(handle_t *handle,
                     (le16_to_cpu(de->rec_len) >= rec_len)) ||
                    (le16_to_cpu(de->rec_len) >=
                     (OCFS2_DIR_REC_LEN(de->name_len) + rec_len))) {
+                       dir->i_mtime = dir->i_ctime = CURRENT_TIME;
+                       retval = ocfs2_mark_inode_dirty(handle, dir, parent_fe_bh);
+                       if (retval < 0) {
+                               mlog_errno(retval);
+                               goto bail;
+                       }
+
                        status = ocfs2_journal_access(handle, dir, insert_bh,
                                                      OCFS2_JOURNAL_ACCESS_WRITE);
                        /* By now the buffer is marked for journaling */
@@ -1846,7 +1854,6 @@ static int __ocfs2_add_entry(handle_t *handle,
                        de->name_len = namelen;
                        memcpy(de->name, name, namelen);
 
-                       dir->i_mtime = dir->i_ctime = CURRENT_TIME;
                        dir->i_version++;
                        status = ocfs2_journal_dirty(handle, insert_bh);
                        retval = 0;
@@ -2215,9 +2222,7 @@ static int ocfs2_orphan_add(struct ocfs2_super *osb,
        /* Record which orphan dir our inode now resides
         * in. delete_inode will use this to determine which orphan
         * dir to lock. */
-       spin_lock(&OCFS2_I(inode)->ip_lock);
-       OCFS2_I(inode)->ip_orphaned_slot = osb->slot_num;
-       spin_unlock(&OCFS2_I(inode)->ip_lock);
+       fe->i_orphaned_slot = cpu_to_le16(osb->slot_num);
 
        mlog(0, "Inode %llu orphaned in slot %d\n",
             (unsigned long long)OCFS2_I(inode)->ip_blkno, osb->slot_num);
@@ -2299,7 +2304,7 @@ leave:
        return status;
 }
 
-struct inode_operations ocfs2_dir_iops = {
+const struct inode_operations ocfs2_dir_iops = {
        .create         = ocfs2_create,
        .lookup         = ocfs2_lookup,
        .link           = ocfs2_link,