add file position info to proc
[powerpc.git] / fs / ext3 / namei.c
index 4df39c4..7edb617 100644 (file)
@@ -969,6 +969,7 @@ static struct buffer_head * ext3_dx_find_entry(struct dentry *dentry,
                                  (block<<EXT3_BLOCK_SIZE_BITS(sb))
                                          +((char *)de - bh->b_data))) {
                                brelse (bh);
+                               *err = ERR_BAD_DX_DIR;
                                goto errout;
                        }
                        *res_dir = de;
@@ -1134,9 +1135,9 @@ static struct ext3_dir_entry_2 *do_split(handle_t *handle, struct inode *dir,
        char *data1 = (*bh)->b_data, *data2;
        unsigned split;
        struct ext3_dir_entry_2 *de = NULL, *de2;
-       int     err;
+       int     err = 0;
 
-       bh2 = ext3_append (handle, dir, &newblock, error);
+       bh2 = ext3_append (handle, dir, &newblock, &err);
        if (!(bh2)) {
                brelse(*bh);
                *bh = NULL;
@@ -1145,14 +1146,9 @@ static struct ext3_dir_entry_2 *do_split(handle_t *handle, struct inode *dir,
 
        BUFFER_TRACE(*bh, "get_write_access");
        err = ext3_journal_get_write_access(handle, *bh);
-       if (err) {
-       journal_error:
-               brelse(*bh);
-               brelse(bh2);
-               *bh = NULL;
-               ext3_std_error(dir->i_sb, err);
-               goto errout;
-       }
+       if (err)
+               goto journal_error;
+
        BUFFER_TRACE(frame->bh, "get_write_access");
        err = ext3_journal_get_write_access(handle, frame->bh);
        if (err)
@@ -1195,8 +1191,16 @@ static struct ext3_dir_entry_2 *do_split(handle_t *handle, struct inode *dir,
                goto journal_error;
        brelse (bh2);
        dxtrace(dx_show_index ("frame", frame->entries));
-errout:
        return de;
+
+journal_error:
+       brelse(*bh);
+       brelse(bh2);
+       *bh = NULL;
+       ext3_std_error(dir->i_sb, err);
+errout:
+       *error = err;
+       return NULL;
 }
 #endif
 
@@ -1618,21 +1622,6 @@ static int ext3_delete_entry (handle_t *handle,
        return -ENOENT;
 }
 
-/*
- * ext3_mark_inode_dirty is somewhat expensive, so unlike ext2 we
- * do not perform it in these functions.  We perform it at the call site,
- * if it is needed.
- */
-static inline void ext3_inc_count(handle_t *handle, struct inode *inode)
-{
-       inc_nlink(inode);
-}
-
-static inline void ext3_dec_count(handle_t *handle, struct inode *inode)
-{
-       drop_nlink(inode);
-}
-
 static int ext3_add_nondir(handle_t *handle,
                struct dentry *dentry, struct inode *inode)
 {
@@ -1642,7 +1631,7 @@ static int ext3_add_nondir(handle_t *handle,
                d_instantiate(dentry, inode);
                return 0;
        }
-       ext3_dec_count(handle, inode);
+       drop_nlink(inode);
        iput(inode);
        return err;
 }
@@ -2163,7 +2152,7 @@ retry:
                err = __page_symlink(inode, symname, l,
                                mapping_gfp_mask(inode->i_mapping) & ~__GFP_FS);
                if (err) {
-                       ext3_dec_count(handle, inode);
+                       drop_nlink(inode);
                        ext3_mark_inode_dirty(handle, inode);
                        iput (inode);
                        goto out_stop;
@@ -2191,6 +2180,12 @@ static int ext3_link (struct dentry * old_dentry,
 
        if (inode->i_nlink >= EXT3_LINK_MAX)
                return -EMLINK;
+       /*
+        * Return -ENOENT if we've raced with unlink and i_nlink is 0.  Doing
+        * otherwise has the potential to corrupt the orphan inode list.
+        */
+       if (inode->i_nlink == 0)
+               return -ENOENT;
 
 retry:
        handle = ext3_journal_start(dir, EXT3_DATA_TRANS_BLOCKS(dir->i_sb) +
@@ -2202,7 +2197,7 @@ retry:
                handle->h_sync = 1;
 
        inode->i_ctime = CURRENT_TIME_SEC;
-       ext3_inc_count(handle, inode);
+       inc_nlink(inode);
        atomic_inc(&inode->i_count);
 
        err = ext3_add_nondir(handle, dentry, inode);
@@ -2374,7 +2369,7 @@ end_rename:
 /*
  * directories can handle most operations...
  */
-struct inode_operations ext3_dir_inode_operations = {
+const struct inode_operations ext3_dir_inode_operations = {
        .create         = ext3_create,
        .lookup         = ext3_lookup,
        .link           = ext3_link,
@@ -2394,7 +2389,7 @@ struct inode_operations ext3_dir_inode_operations = {
        .permission     = ext3_permission,
 };
 
-struct inode_operations ext3_special_inode_operations = {
+const struct inode_operations ext3_special_inode_operations = {
        .setattr        = ext3_setattr,
 #ifdef CONFIG_EXT3_FS_XATTR
        .setxattr       = generic_setxattr,