vserver 1.9.3
[linux-2.6.git] / fs / ext3 / namei.c
index d2ad34e..e7e287e 100644 (file)
@@ -71,9 +71,6 @@ static struct buffer_head *ext3_append(handle_t *handle,
 #define swap(x, y) do { typeof(x) z = x; x = y; y = z; } while (0)
 #endif
 
-typedef struct { u32 v; } le_u32;
-typedef struct { u16 v; } le_u16;
-
 #ifdef DX_DEBUG
 #define dxtrace(command) command
 #else
@@ -82,22 +79,22 @@ typedef struct { u16 v; } le_u16;
 
 struct fake_dirent
 {
-       /*le*/u32 inode;
-       /*le*/u16 rec_len;
+       __le32 inode;
+       __le16 rec_len;
        u8 name_len;
        u8 file_type;
 };
 
 struct dx_countlimit
 {
-       le_u16 limit;
-       le_u16 count;
+       __le16 limit;
+       __le16 count;
 };
 
 struct dx_entry
 {
-       le_u32 hash;
-       le_u32 block;
+       __le32 hash;
+       __le32 block;
 };
 
 /*
@@ -114,7 +111,7 @@ struct dx_root
        char dotdot_name[4];
        struct dx_root_info
        {
-               le_u32 reserved_zero;
+               __le32 reserved_zero;
                u8 hash_version;
                u8 info_length; /* 8 */
                u8 indirect_levels;
@@ -184,42 +181,42 @@ static int ext3_dx_add_entry(handle_t *handle, struct dentry *dentry,
 
 static inline unsigned dx_get_block (struct dx_entry *entry)
 {
-       return le32_to_cpu(entry->block.v) & 0x00ffffff;
+       return le32_to_cpu(entry->block) & 0x00ffffff;
 }
 
 static inline void dx_set_block (struct dx_entry *entry, unsigned value)
 {
-       entry->block.v = cpu_to_le32(value);
+       entry->block = cpu_to_le32(value);
 }
 
 static inline unsigned dx_get_hash (struct dx_entry *entry)
 {
-       return le32_to_cpu(entry->hash.v);
+       return le32_to_cpu(entry->hash);
 }
 
 static inline void dx_set_hash (struct dx_entry *entry, unsigned value)
 {
-       entry->hash.v = cpu_to_le32(value);
+       entry->hash = cpu_to_le32(value);
 }
 
 static inline unsigned dx_get_count (struct dx_entry *entries)
 {
-       return le16_to_cpu(((struct dx_countlimit *) entries)->count.v);
+       return le16_to_cpu(((struct dx_countlimit *) entries)->count);
 }
 
 static inline unsigned dx_get_limit (struct dx_entry *entries)
 {
-       return le16_to_cpu(((struct dx_countlimit *) entries)->limit.v);
+       return le16_to_cpu(((struct dx_countlimit *) entries)->limit);
 }
 
 static inline void dx_set_count (struct dx_entry *entries, unsigned value)
 {
-       ((struct dx_countlimit *) entries)->count.v = cpu_to_le16(value);
+       ((struct dx_countlimit *) entries)->count = cpu_to_le16(value);
 }
 
 static inline void dx_set_limit (struct dx_entry *entries, unsigned value)
 {
-       ((struct dx_countlimit *) entries)->limit.v = cpu_to_le16(value);
+       ((struct dx_countlimit *) entries)->limit = cpu_to_le16(value);
 }
 
 static inline unsigned dx_root_limit (struct inode *dir, unsigned infosize)
@@ -557,6 +554,8 @@ static int htree_dirblock_to_tree(struct file *dir_file,
                    ((hinfo->hash == start_hash) &&
                     (hinfo->minor_hash < start_minor_hash)))
                        continue;
+               if (de->inode == 0)
+                       continue;
                if ((err = ext3_htree_store_dirent(dir_file,
                                   hinfo->hash, hinfo->minor_hash, de)) != 0) {
                        brelse(bh);
@@ -602,7 +601,7 @@ int ext3_htree_fill_tree(struct file *dir_file, __u32 start_hash,
        }
        hinfo.hash = start_hash;
        hinfo.minor_hash = 0;
-       frame = dx_probe(0, dir_file->f_dentry->d_inode, &hinfo, frames, &err);
+       frame = dx_probe(NULL, dir_file->f_dentry->d_inode, &hinfo, frames, &err);
        if (!frame)
                return err;
 
@@ -928,7 +927,7 @@ static struct buffer_head * ext3_dx_find_entry(struct dentry *dentry,
        struct inode *dir = dentry->d_parent->d_inode;
 
        sb = dir->i_sb;
-       if (!(frame = dx_probe (dentry, 0, &hinfo, frames, err)))
+       if (!(frame = dx_probe(dentry, NULL, &hinfo, frames, err)))
                return NULL;
        hash = hinfo.hash;
        do {
@@ -954,7 +953,7 @@ static struct buffer_head * ext3_dx_find_entry(struct dentry *dentry,
                brelse (bh);
                /* Check to see if we should continue to search */
                retval = ext3_htree_next_block(dir, hash, frame,
-                                              frames, 0);
+                                              frames, NULL);
                if (retval < 0) {
                        ext3_warning(sb, __FUNCTION__,
                             "error reading index page in directory #%lu",
@@ -1390,7 +1389,7 @@ static int ext3_add_entry (handle_t *handle, struct dentry *dentry,
                bh = ext3_bread(handle, dir, block, 0, &retval);
                if(!bh)
                        return retval;
-               retval = add_dirent_to_buf(handle, dentry, inode, 0, bh);
+               retval = add_dirent_to_buf(handle, dentry, inode, NULL, bh);
                if (retval != -ENOSPC)
                        return retval;
 
@@ -1427,7 +1426,7 @@ static int ext3_dx_add_entry(handle_t *handle, struct dentry *dentry,
        struct ext3_dir_entry_2 *de;
        int err;
 
-       frame = dx_probe(dentry, 0, &hinfo, frames, &err);
+       frame = dx_probe(dentry, NULL, &hinfo, frames, &err);
        if (!frame)
                return err;
        entries = frame->entries;
@@ -1441,9 +1440,9 @@ static int ext3_dx_add_entry(handle_t *handle, struct dentry *dentry,
        if (err)
                goto journal_error;
 
-       err = add_dirent_to_buf(handle, dentry, inode, 0, bh);
+       err = add_dirent_to_buf(handle, dentry, inode, NULL, bh);
        if (err != -ENOSPC) {
-               bh = 0;
+               bh = NULL;
                goto cleanup;
        }
 
@@ -1535,7 +1534,7 @@ static int ext3_dx_add_entry(handle_t *handle, struct dentry *dentry,
        if (!de)
                goto cleanup;
        err = add_dirent_to_buf(handle, dentry, inode, de, bh);
-       bh = 0;
+       bh = NULL;
        goto cleanup;
 
 journal_error:
@@ -1630,8 +1629,9 @@ static int ext3_create (struct inode * dir, struct dentry * dentry, int mode,
 {
        handle_t *handle; 
        struct inode * inode;
-       int err;
+       int err, retries = 0;
 
+retry:
        handle = ext3_journal_start(dir, EXT3_DATA_TRANS_BLOCKS +
                                        EXT3_INDEX_EXTRA_TRANS_BLOCKS + 3 +
                                        2*EXT3_QUOTA_INIT_BLOCKS);
@@ -1650,6 +1650,8 @@ static int ext3_create (struct inode * dir, struct dentry * dentry, int mode,
                err = ext3_add_nondir(handle, dentry, inode);
        }
        ext3_journal_stop(handle);
+       if (err == -ENOSPC && ext3_should_retry_alloc(dir->i_sb, &retries))
+               goto retry;
        return err;
 }
 
@@ -1658,11 +1660,12 @@ static int ext3_mknod (struct inode * dir, struct dentry *dentry,
 {
        handle_t *handle;
        struct inode *inode;
-       int err;
+       int err, retries = 0;
 
        if (!new_valid_dev(rdev))
                return -EINVAL;
 
+retry:
        handle = ext3_journal_start(dir, EXT3_DATA_TRANS_BLOCKS +
                                        EXT3_INDEX_EXTRA_TRANS_BLOCKS + 3 +
                                        2*EXT3_QUOTA_INIT_BLOCKS);
@@ -1682,6 +1685,8 @@ static int ext3_mknod (struct inode * dir, struct dentry *dentry,
                err = ext3_add_nondir(handle, dentry, inode);
        }
        ext3_journal_stop(handle);
+       if (err == -ENOSPC && ext3_should_retry_alloc(dir->i_sb, &retries))
+               goto retry;
        return err;
 }
 
@@ -1691,11 +1696,12 @@ static int ext3_mkdir(struct inode * dir, struct dentry * dentry, int mode)
        struct inode * inode;
        struct buffer_head * dir_block;
        struct ext3_dir_entry_2 * de;
-       int err;
+       int err, retries = 0;
 
        if (dir->i_nlink >= EXT3_LINK_MAX)
                return -EMLINK;
 
+retry:
        handle = ext3_journal_start(dir, EXT3_DATA_TRANS_BLOCKS +
                                        EXT3_INDEX_EXTRA_TRANS_BLOCKS + 3 +
                                        2*EXT3_QUOTA_INIT_BLOCKS);
@@ -1753,6 +1759,8 @@ static int ext3_mkdir(struct inode * dir, struct dentry * dentry, int mode)
        d_instantiate(dentry, inode);
 out_stop:
        ext3_journal_stop(handle);
+       if (err == -ENOSPC && ext3_should_retry_alloc(dir->i_sb, &retries))
+               goto retry;
        return err;
 }
 
@@ -2092,12 +2100,13 @@ static int ext3_symlink (struct inode * dir,
 {
        handle_t *handle;
        struct inode * inode;
-       int l, err;
+       int l, err, retries = 0;
 
        l = strlen(symname)+1;
        if (l > dir->i_sb->s_blocksize)
                return -ENAMETOOLONG;
 
+retry:
        handle = ext3_journal_start(dir, EXT3_DATA_TRANS_BLOCKS +
                                        EXT3_INDEX_EXTRA_TRANS_BLOCKS + 5 +
                                        2*EXT3_QUOTA_INIT_BLOCKS);
@@ -2136,6 +2145,8 @@ static int ext3_symlink (struct inode * dir,
        err = ext3_add_nondir(handle, dentry, inode);
 out_stop:
        ext3_journal_stop(handle);
+       if (err == -ENOSPC && ext3_should_retry_alloc(dir->i_sb, &retries))
+               goto retry;
        return err;
 }
 
@@ -2144,11 +2155,12 @@ static int ext3_link (struct dentry * old_dentry,
 {
        handle_t *handle;
        struct inode *inode = old_dentry->d_inode;
-       int err;
+       int err, retries = 0;
 
        if (inode->i_nlink >= EXT3_LINK_MAX)
                return -EMLINK;
 
+retry:
        handle = ext3_journal_start(dir, EXT3_DATA_TRANS_BLOCKS +
                                        EXT3_INDEX_EXTRA_TRANS_BLOCKS);
        if (IS_ERR(handle))
@@ -2163,6 +2175,8 @@ static int ext3_link (struct dentry * old_dentry,
 
        err = ext3_add_nondir(handle, dentry, inode);
        ext3_journal_stop(handle);
+       if (err == -ENOSPC && ext3_should_retry_alloc(dir->i_sb, &retries))
+               goto retry;
        return err;
 }
 
@@ -2241,7 +2255,7 @@ static int ext3_rename (struct inode * old_dir, struct dentry *old_dentry,
        } else {
                BUFFER_TRACE(new_bh, "get write access");
                ext3_journal_get_write_access(handle, new_bh);
-               new_de->inode = le32_to_cpu(old_inode->i_ino);
+               new_de->inode = cpu_to_le32(old_inode->i_ino);
                if (EXT3_HAS_INCOMPAT_FEATURE(new_dir->i_sb,
                                              EXT3_FEATURE_INCOMPAT_FILETYPE))
                        new_de->file_type = old_de->file_type;
@@ -2296,7 +2310,7 @@ static int ext3_rename (struct inode * old_dir, struct dentry *old_dentry,
        if (dir_bh) {
                BUFFER_TRACE(dir_bh, "get_write_access");
                ext3_journal_get_write_access(handle, dir_bh);
-               PARENT_INO(dir_bh->b_data) = le32_to_cpu(new_dir->i_ino);
+               PARENT_INO(dir_bh->b_data) = cpu_to_le32(new_dir->i_ino);
                BUFFER_TRACE(dir_bh, "call ext3_journal_dirty_metadata");
                ext3_journal_dirty_metadata(handle, dir_bh);
                old_dir->i_nlink--;