/*
* linux/fs/hpfs/dnode.c
*
* Mikulas Patocka (mikulas@artax.karlin.mff.cuni.cz), 1998-1999
*
* handling directory dnode tree - adding, deleteing & searching for dirents
*/
#include "hpfs_fn.h"
static loff_t get_pos(struct dnode *d, struct hpfs_dirent *fde)
{
struct hpfs_dirent *de;
struct hpfs_dirent *de_end = dnode_end_de(d);
int i = 1;
for (de = dnode_first_de(d); de < de_end; de = de_next_de(de)) {
if (de == fde) return ((loff_t) le32_to_cpu(d->self) << 4) | (loff_t)i;
i++;
}
printk("HPFS: get_pos: not_found\n");
return ((loff_t)le32_to_cpu(d->self) << 4) | (loff_t)1;
}
void hpfs_add_pos(struct inode *inode, loff_t *pos)
{
struct hpfs_inode_info *hpfs_inode = hpfs_i(inode);
int i = 0;
loff_t **ppos;
if (hpfs_inode->i_rddir_off)
for (; hpfs_inode->i_rddir_off[i]; i++)
if (hpfs_inode->i_rddir_off[i] == pos) return;
if (!(i&0x0f)) {
if (!(ppos = kmalloc((i+0x11) * sizeof(loff_t*), GFP_NOFS))) {
printk("HPFS: out of memory for position list\n");
return;
}
if (hpfs_inode->i_rddir_off) {
memcpy(ppos, hpfs_inode->i_rddir_off, i * sizeof(loff_t));
kfree(hpfs_inode->i_rddir_off);
}
hpfs_inode->i_rddir_off = ppos;
}
hpfs_inode->i_rddir_off[i] = pos;
hpfs_inode->i_rddir_off[i + 1] = NULL;
}
void hpfs_del_pos(struct inode *inode, loff_t *pos)
{
struct hpfs_inode_info *hpfs_inode = hpfs_i(inode);
loff_t **i, **j;
if (!hpfs_inode->i_rddir_off) goto not_f;
for (i = hpfs_inode->i_rddir_off; *i; i++) if (*i == pos) goto fnd;
goto not_f;
fnd:
for (j = i + 1; *j; j++) ;
*i = *(j - 1);
*(j - 1) = NULL;
if (j - 1 == hpfs_inode->i_rddir_off) {
kfree(hpfs_inode->i_rddir_off);
hpfs_inode->i_rddir_off = NULL;
}
return;
not_f:
/*printk("HPFS: warning: position pointer %p->%08x not found\n", pos, (int)*pos);*/
return;
}
static void for_all_poss(struct inode *inode, void (*f)(loff_t *, loff_t, loff_t),
loff_t p1, loff_t p2)
{
struct hpfs_inode_info *hpfs_inode = hpfs_i(inode);
loff_t **i;
if (!hpfs_inode->i_rddir_off) return;
for (i = hpfs_inode->i_rddir_off; *i; i++) (*f)(*i, p1, p2);
return;
}
static void hpfs_pos_subst(loff_t *p, loff_t f, loff_t t)
{
if (*p == f) *p = t;
}
/*void hpfs_hpfs_pos_substd(loff_t *p, loff_t f, loff_t t)
{
if ((*p & ~0x3f) == (f & ~0x3f)) *p = (t & ~0x3f) | (*p & 0x3f);
}*/
static void hpfs_p