mirror of
https://github.com/BobTheBlinker/android_kernel_motorola_sm6375.git
synced 2026-10-30 11:41:38 -04:00
Merge branch 'for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/viro/vfs
Pull vfs changes from Al Viro.
"A lot of misc stuff. The obvious groups:
* Miklos' atomic_open series; kills the damn abuse of
->d_revalidate() by NFS, which was the major stumbling block for
all work in that area.
* ripping security_file_mmap() and dealing with deadlocks in the
area; sanitizing the neighborhood of vm_mmap()/vm_munmap() in
general.
* ->encode_fh() switched to saner API; insane fake dentry in
mm/cleancache.c gone.
* assorted annotations in fs (endianness, __user)
* parts of Artem's ->s_dirty work (jff2 and reiserfs parts)
* ->update_time() work from Josef.
* other bits and pieces all over the place.
Normally it would've been in two or three pull requests, but
signal.git stuff had eaten a lot of time during this cycle ;-/"
Fix up trivial conflicts in Documentation/filesystems/vfs.txt (the
'truncate_range' inode method was removed by the VM changes, the VFS
update adds an 'update_time()' method), and in fs/btrfs/ulist.[ch] (due
to sparse fix added twice, with other changes nearby).
* 'for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/viro/vfs: (95 commits)
nfs: don't open in ->d_revalidate
vfs: retry last component if opening stale dentry
vfs: nameidata_to_filp(): don't throw away file on error
vfs: nameidata_to_filp(): inline __dentry_open()
vfs: do_dentry_open(): don't put filp
vfs: split __dentry_open()
vfs: do_last() common post lookup
vfs: do_last(): add audit_inode before open
vfs: do_last(): only return EISDIR for O_CREAT
vfs: do_last(): check LOOKUP_DIRECTORY
vfs: do_last(): make ENOENT exit RCU safe
vfs: make follow_link check RCU safe
vfs: do_last(): use inode variable
vfs: do_last(): inline walk_component()
vfs: do_last(): make exit RCU safe
vfs: split do_lookup()
Btrfs: move over to use ->update_time
fs: introduce inode operation ->update_time
reiserfs: get rid of resierfs_sync_super
reiserfs: mark the superblock as dirty a bit later
...
This commit is contained in:
commit
1193755ac6
148 changed files with 1495 additions and 1618 deletions
|
|
@ -16,9 +16,9 @@
|
|||
static int chk_if_allocated(struct super_block *s, secno sec, char *msg)
|
||||
{
|
||||
struct quad_buffer_head qbh;
|
||||
u32 *bmp;
|
||||
__le32 *bmp;
|
||||
if (!(bmp = hpfs_map_bitmap(s, sec >> 14, &qbh, "chk"))) goto fail;
|
||||
if ((cpu_to_le32(bmp[(sec & 0x3fff) >> 5]) >> (sec & 0x1f)) & 1) {
|
||||
if ((le32_to_cpu(bmp[(sec & 0x3fff) >> 5]) >> (sec & 0x1f)) & 1) {
|
||||
hpfs_error(s, "sector '%s' - %08x not allocated in bitmap", msg, sec);
|
||||
goto fail1;
|
||||
}
|
||||
|
|
@ -62,7 +62,7 @@ int hpfs_chk_sectors(struct super_block *s, secno start, int len, char *msg)
|
|||
static secno alloc_in_bmp(struct super_block *s, secno near, unsigned n, unsigned forward)
|
||||
{
|
||||
struct quad_buffer_head qbh;
|
||||
unsigned *bmp;
|
||||
__le32 *bmp;
|
||||
unsigned bs = near & ~0x3fff;
|
||||
unsigned nr = (near & 0x3fff) & ~(n - 1);
|
||||
/*unsigned mnr;*/
|
||||
|
|
@ -236,7 +236,7 @@ static secno alloc_in_dirband(struct super_block *s, secno near)
|
|||
int hpfs_alloc_if_possible(struct super_block *s, secno sec)
|
||||
{
|
||||
struct quad_buffer_head qbh;
|
||||
u32 *bmp;
|
||||
__le32 *bmp;
|
||||
if (!(bmp = hpfs_map_bitmap(s, sec >> 14, &qbh, "aip"))) goto end;
|
||||
if (le32_to_cpu(bmp[(sec & 0x3fff) >> 5]) & (1 << (sec & 0x1f))) {
|
||||
bmp[(sec & 0x3fff) >> 5] &= cpu_to_le32(~(1 << (sec & 0x1f)));
|
||||
|
|
@ -254,7 +254,7 @@ int hpfs_alloc_if_possible(struct super_block *s, secno sec)
|
|||
void hpfs_free_sectors(struct super_block *s, secno sec, unsigned n)
|
||||
{
|
||||
struct quad_buffer_head qbh;
|
||||
u32 *bmp;
|
||||
__le32 *bmp;
|
||||
struct hpfs_sb_info *sbi = hpfs_sb(s);
|
||||
/*printk("2 - ");*/
|
||||
if (!n) return;
|
||||
|
|
@ -299,7 +299,7 @@ int hpfs_check_free_dnodes(struct super_block *s, int n)
|
|||
int n_bmps = (hpfs_sb(s)->sb_fs_size + 0x4000 - 1) >> 14;
|
||||
int b = hpfs_sb(s)->sb_c_bitmap & 0x0fffffff;
|
||||
int i, j;
|
||||
u32 *bmp;
|
||||
__le32 *bmp;
|
||||
struct quad_buffer_head qbh;
|
||||
if ((bmp = hpfs_map_dnode_bitmap(s, &qbh))) {
|
||||
for (j = 0; j < 512; j++) {
|
||||
|
|
@ -351,7 +351,7 @@ void hpfs_free_dnode(struct super_block *s, dnode_secno dno)
|
|||
hpfs_free_sectors(s, dno, 4);
|
||||
} else {
|
||||
struct quad_buffer_head qbh;
|
||||
u32 *bmp;
|
||||
__le32 *bmp;
|
||||
unsigned ssec = (dno - hpfs_sb(s)->sb_dirband_start) / 4;
|
||||
if (!(bmp = hpfs_map_dnode_bitmap(s, &qbh))) {
|
||||
return;
|
||||
|
|
|
|||
|
|
@ -20,7 +20,7 @@ secno hpfs_bplus_lookup(struct super_block *s, struct inode *inode,
|
|||
int c1, c2 = 0;
|
||||
go_down:
|
||||
if (hpfs_sb(s)->sb_chk) if (hpfs_stop_cycles(s, a, &c1, &c2, "hpfs_bplus_lookup")) return -1;
|
||||
if (btree->internal) {
|
||||
if (bp_internal(btree)) {
|
||||
for (i = 0; i < btree->n_used_nodes; i++)
|
||||
if (le32_to_cpu(btree->u.internal[i].file_secno) > sec) {
|
||||
a = le32_to_cpu(btree->u.internal[i].down);
|
||||
|
|
@ -82,7 +82,7 @@ secno hpfs_add_sector_to_btree(struct super_block *s, secno node, int fnod, unsi
|
|||
brelse(bh);
|
||||
return -1;
|
||||
}
|
||||
if (btree->internal) {
|
||||
if (bp_internal(btree)) {
|
||||
a = le32_to_cpu(btree->u.internal[n].down);
|
||||
btree->u.internal[n].file_secno = cpu_to_le32(-1);
|
||||
mark_buffer_dirty(bh);
|
||||
|
|
@ -129,12 +129,12 @@ secno hpfs_add_sector_to_btree(struct super_block *s, secno node, int fnod, unsi
|
|||
}
|
||||
if (a == node && fnod) {
|
||||
anode->up = cpu_to_le32(node);
|
||||
anode->btree.fnode_parent = 1;
|
||||
anode->btree.flags |= BP_fnode_parent;
|
||||
anode->btree.n_used_nodes = btree->n_used_nodes;
|
||||
anode->btree.first_free = btree->first_free;
|
||||
anode->btree.n_free_nodes = 40 - anode->btree.n_used_nodes;
|
||||
memcpy(&anode->u, &btree->u, btree->n_used_nodes * 12);
|
||||
btree->internal = 1;
|
||||
btree->flags |= BP_internal;
|
||||
btree->n_free_nodes = 11;
|
||||
btree->n_used_nodes = 1;
|
||||
btree->first_free = cpu_to_le16((char *)&(btree->u.internal[1]) - (char *)btree);
|
||||
|
|
@ -184,7 +184,10 @@ secno hpfs_add_sector_to_btree(struct super_block *s, secno node, int fnod, unsi
|
|||
hpfs_free_sectors(s, ra, 1);
|
||||
if ((anode = hpfs_map_anode(s, na, &bh))) {
|
||||
anode->up = cpu_to_le32(up);
|
||||
anode->btree.fnode_parent = up == node && fnod;
|
||||
if (up == node && fnod)
|
||||
anode->btree.flags |= BP_fnode_parent;
|
||||
else
|
||||
anode->btree.flags &= ~BP_fnode_parent;
|
||||
mark_buffer_dirty(bh);
|
||||
brelse(bh);
|
||||
}
|
||||
|
|
@ -198,7 +201,7 @@ secno hpfs_add_sector_to_btree(struct super_block *s, secno node, int fnod, unsi
|
|||
if ((new_anode = hpfs_alloc_anode(s, a, &na, &bh))) {
|
||||
anode = new_anode;
|
||||
/*anode->up = cpu_to_le32(up != -1 ? up : ra);*/
|
||||
anode->btree.internal = 1;
|
||||
anode->btree.flags |= BP_internal;
|
||||
anode->btree.n_used_nodes = 1;
|
||||
anode->btree.n_free_nodes = 59;
|
||||
anode->btree.first_free = cpu_to_le16(16);
|
||||
|
|
@ -215,7 +218,8 @@ secno hpfs_add_sector_to_btree(struct super_block *s, secno node, int fnod, unsi
|
|||
}
|
||||
if ((anode = hpfs_map_anode(s, na, &bh))) {
|
||||
anode->up = cpu_to_le32(node);
|
||||
if (fnod) anode->btree.fnode_parent = 1;
|
||||
if (fnod)
|
||||
anode->btree.flags |= BP_fnode_parent;
|
||||
mark_buffer_dirty(bh);
|
||||
brelse(bh);
|
||||
}
|
||||
|
|
@ -234,18 +238,19 @@ secno hpfs_add_sector_to_btree(struct super_block *s, secno node, int fnod, unsi
|
|||
}
|
||||
ranode->up = cpu_to_le32(node);
|
||||
memcpy(&ranode->btree, btree, le16_to_cpu(btree->first_free));
|
||||
if (fnod) ranode->btree.fnode_parent = 1;
|
||||
ranode->btree.n_free_nodes = (ranode->btree.internal ? 60 : 40) - ranode->btree.n_used_nodes;
|
||||
if (ranode->btree.internal) for (n = 0; n < ranode->btree.n_used_nodes; n++) {
|
||||
if (fnod)
|
||||
ranode->btree.flags |= BP_fnode_parent;
|
||||
ranode->btree.n_free_nodes = (bp_internal(&ranode->btree) ? 60 : 40) - ranode->btree.n_used_nodes;
|
||||
if (bp_internal(&ranode->btree)) for (n = 0; n < ranode->btree.n_used_nodes; n++) {
|
||||
struct anode *unode;
|
||||
if ((unode = hpfs_map_anode(s, le32_to_cpu(ranode->u.internal[n].down), &bh1))) {
|
||||
unode->up = cpu_to_le32(ra);
|
||||
unode->btree.fnode_parent = 0;
|
||||
unode->btree.flags &= ~BP_fnode_parent;
|
||||
mark_buffer_dirty(bh1);
|
||||
brelse(bh1);
|
||||
}
|
||||
}
|
||||
btree->internal = 1;
|
||||
btree->flags |= BP_internal;
|
||||
btree->n_free_nodes = fnod ? 10 : 58;
|
||||
btree->n_used_nodes = 2;
|
||||
btree->first_free = cpu_to_le16((char *)&btree->u.internal[2] - (char *)btree);
|
||||
|
|
@ -278,7 +283,7 @@ void hpfs_remove_btree(struct super_block *s, struct bplus_header *btree)
|
|||
int d1, d2;
|
||||
go_down:
|
||||
d2 = 0;
|
||||
while (btree1->internal) {
|
||||
while (bp_internal(btree1)) {
|
||||
ano = le32_to_cpu(btree1->u.internal[pos].down);
|
||||
if (level) brelse(bh);
|
||||
if (hpfs_sb(s)->sb_chk)
|
||||
|
|
@ -412,13 +417,13 @@ void hpfs_truncate_btree(struct super_block *s, secno f, int fno, unsigned secs)
|
|||
btree->n_free_nodes = 8;
|
||||
btree->n_used_nodes = 0;
|
||||
btree->first_free = cpu_to_le16(8);
|
||||
btree->internal = 0;
|
||||
btree->flags &= ~BP_internal;
|
||||
mark_buffer_dirty(bh);
|
||||
} else hpfs_free_sectors(s, f, 1);
|
||||
brelse(bh);
|
||||
return;
|
||||
}
|
||||
while (btree->internal) {
|
||||
while (bp_internal(btree)) {
|
||||
nodes = btree->n_used_nodes + btree->n_free_nodes;
|
||||
for (i = 0; i < btree->n_used_nodes; i++)
|
||||
if (le32_to_cpu(btree->u.internal[i].file_secno) >= secs) goto f;
|
||||
|
|
@ -479,13 +484,13 @@ void hpfs_remove_fnode(struct super_block *s, fnode_secno fno)
|
|||
struct extended_attribute *ea;
|
||||
struct extended_attribute *ea_end;
|
||||
if (!(fnode = hpfs_map_fnode(s, fno, &bh))) return;
|
||||
if (!fnode->dirflag) hpfs_remove_btree(s, &fnode->btree);
|
||||
if (!fnode_is_dir(fnode)) hpfs_remove_btree(s, &fnode->btree);
|
||||
else hpfs_remove_dtree(s, le32_to_cpu(fnode->u.external[0].disk_secno));
|
||||
ea_end = fnode_end_ea(fnode);
|
||||
for (ea = fnode_ea(fnode); ea < ea_end; ea = next_ea(ea))
|
||||
if (ea->indirect)
|
||||
hpfs_ea_remove(s, ea_sec(ea), ea->anode, ea_len(ea));
|
||||
hpfs_ea_ext_remove(s, le32_to_cpu(fnode->ea_secno), fnode->ea_anode, le32_to_cpu(fnode->ea_size_l));
|
||||
if (ea_indirect(ea))
|
||||
hpfs_ea_remove(s, ea_sec(ea), ea_in_anode(ea), ea_len(ea));
|
||||
hpfs_ea_ext_remove(s, le32_to_cpu(fnode->ea_secno), fnode_in_anode(fnode), le32_to_cpu(fnode->ea_size_l));
|
||||
brelse(bh);
|
||||
hpfs_free_sectors(s, fno, 1);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -87,7 +87,7 @@ static int hpfs_readdir(struct file *filp, void *dirent, filldir_t filldir)
|
|||
ret = -EIOERROR;
|
||||
goto out;
|
||||
}
|
||||
if (!fno->dirflag) {
|
||||
if (!fnode_is_dir(fno)) {
|
||||
e = 1;
|
||||
hpfs_error(inode->i_sb, "not a directory, fnode %08lx",
|
||||
(unsigned long)inode->i_ino);
|
||||
|
|
|
|||
|
|
@ -153,7 +153,7 @@ static void set_last_pointer(struct super_block *s, struct dnode *d, dnode_secno
|
|||
}
|
||||
de->length = cpu_to_le16(36);
|
||||
de->down = 1;
|
||||
*(dnode_secno *)((char *)de + 32) = cpu_to_le32(ptr);
|
||||
*(__le32 *)((char *)de + 32) = cpu_to_le32(ptr);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -177,7 +177,7 @@ struct hpfs_dirent *hpfs_add_de(struct super_block *s, struct dnode *d,
|
|||
memmove((char *)de + d_size, de, (char *)de_end - (char *)de);
|
||||
memset(de, 0, d_size);
|
||||
if (down_ptr) {
|
||||
*(dnode_secno *)((char *)de + d_size - 4) = cpu_to_le32(down_ptr);
|
||||
*(__le32 *)((char *)de + d_size - 4) = cpu_to_le32(down_ptr);
|
||||
de->down = 1;
|
||||
}
|
||||
de->length = cpu_to_le16(d_size);
|
||||
|
|
@ -656,7 +656,7 @@ static void delete_empty_dnode(struct inode *i, dnode_secno dno)
|
|||
del->down = 0;
|
||||
d1->first_free = cpu_to_le32(le32_to_cpu(d1->first_free) - 4);
|
||||
} else if (down)
|
||||
*(dnode_secno *) ((void *) del + le16_to_cpu(del->length) - 4) = cpu_to_le32(down);
|
||||
*(__le32 *) ((void *) del + le16_to_cpu(del->length) - 4) = cpu_to_le32(down);
|
||||
} else goto endm;
|
||||
if (!(de_cp = kmalloc(le16_to_cpu(de_prev->length), GFP_NOFS))) {
|
||||
printk("HPFS: out of memory for dtree balancing\n");
|
||||
|
|
@ -672,7 +672,7 @@ static void delete_empty_dnode(struct inode *i, dnode_secno dno)
|
|||
de_prev->down = 1;
|
||||
dnode->first_free = cpu_to_le32(le32_to_cpu(dnode->first_free) + 4);
|
||||
}
|
||||
*(dnode_secno *) ((void *) de_prev + le16_to_cpu(de_prev->length) - 4) = cpu_to_le32(ndown);
|
||||
*(__le32 *) ((void *) de_prev + le16_to_cpu(de_prev->length) - 4) = cpu_to_le32(ndown);
|
||||
hpfs_mark_4buffers_dirty(&qbh);
|
||||
hpfs_brelse4(&qbh);
|
||||
for_all_poss(i, hpfs_pos_subst, ((loff_t)up << 4) | (p - 1), 4);
|
||||
|
|
@ -1015,7 +1015,7 @@ struct hpfs_dirent *map_fnode_dirent(struct super_block *s, fnode_secno fno,
|
|||
kfree(name2);
|
||||
return NULL;
|
||||
}
|
||||
if (!upf->dirflag) {
|
||||
if (!fnode_is_dir(upf)) {
|
||||
brelse(bh);
|
||||
hpfs_error(s, "fnode %08x has non-directory parent %08x", fno, le32_to_cpu(f->up));
|
||||
kfree(name2);
|
||||
|
|
|
|||
60
fs/hpfs/ea.c
60
fs/hpfs/ea.c
|
|
@ -23,15 +23,15 @@ void hpfs_ea_ext_remove(struct super_block *s, secno a, int ano, unsigned len)
|
|||
return;
|
||||
}
|
||||
if (hpfs_ea_read(s, a, ano, pos, 4, ex)) return;
|
||||
if (ea->indirect) {
|
||||
if (ea_indirect(ea)) {
|
||||
if (ea_valuelen(ea) != 8) {
|
||||
hpfs_error(s, "ea->indirect set while ea->valuelen!=8, %s %08x, pos %08x",
|
||||
hpfs_error(s, "ea_indirect(ea) set while ea->valuelen!=8, %s %08x, pos %08x",
|
||||
ano ? "anode" : "sectors", a, pos);
|
||||
return;
|
||||
}
|
||||
if (hpfs_ea_read(s, a, ano, pos + 4, ea->namelen + 9, ex+4))
|
||||
return;
|
||||
hpfs_ea_remove(s, ea_sec(ea), ea->anode, ea_len(ea));
|
||||
hpfs_ea_remove(s, ea_sec(ea), ea_in_anode(ea), ea_len(ea));
|
||||
}
|
||||
pos += ea->namelen + ea_valuelen(ea) + 5;
|
||||
}
|
||||
|
|
@ -81,7 +81,7 @@ int hpfs_read_ea(struct super_block *s, struct fnode *fnode, char *key,
|
|||
struct extended_attribute *ea_end = fnode_end_ea(fnode);
|
||||
for (ea = fnode_ea(fnode); ea < ea_end; ea = next_ea(ea))
|
||||
if (!strcmp(ea->name, key)) {
|
||||
if (ea->indirect)
|
||||
if (ea_indirect(ea))
|
||||
goto indirect;
|
||||
if (ea_valuelen(ea) >= size)
|
||||
return -EINVAL;
|
||||
|
|
@ -91,7 +91,7 @@ int hpfs_read_ea(struct super_block *s, struct fnode *fnode, char *key,
|
|||
}
|
||||
a = le32_to_cpu(fnode->ea_secno);
|
||||
len = le32_to_cpu(fnode->ea_size_l);
|
||||
ano = fnode->ea_anode;
|
||||
ano = fnode_in_anode(fnode);
|
||||
pos = 0;
|
||||
while (pos < len) {
|
||||
ea = (struct extended_attribute *)ex;
|
||||
|
|
@ -101,10 +101,10 @@ int hpfs_read_ea(struct super_block *s, struct fnode *fnode, char *key,
|
|||
return -EIO;
|
||||
}
|
||||
if (hpfs_ea_read(s, a, ano, pos, 4, ex)) return -EIO;
|
||||
if (hpfs_ea_read(s, a, ano, pos + 4, ea->namelen + 1 + (ea->indirect ? 8 : 0), ex + 4))
|
||||
if (hpfs_ea_read(s, a, ano, pos + 4, ea->namelen + 1 + (ea_indirect(ea) ? 8 : 0), ex + 4))
|
||||
return -EIO;
|
||||
if (!strcmp(ea->name, key)) {
|
||||
if (ea->indirect)
|
||||
if (ea_indirect(ea))
|
||||
goto indirect;
|
||||
if (ea_valuelen(ea) >= size)
|
||||
return -EINVAL;
|
||||
|
|
@ -119,7 +119,7 @@ int hpfs_read_ea(struct super_block *s, struct fnode *fnode, char *key,
|
|||
indirect:
|
||||
if (ea_len(ea) >= size)
|
||||
return -EINVAL;
|
||||
if (hpfs_ea_read(s, ea_sec(ea), ea->anode, 0, ea_len(ea), buf))
|
||||
if (hpfs_ea_read(s, ea_sec(ea), ea_in_anode(ea), 0, ea_len(ea), buf))
|
||||
return -EIO;
|
||||
buf[ea_len(ea)] = 0;
|
||||
return 0;
|
||||
|
|
@ -136,8 +136,8 @@ char *hpfs_get_ea(struct super_block *s, struct fnode *fnode, char *key, int *si
|
|||
struct extended_attribute *ea_end = fnode_end_ea(fnode);
|
||||
for (ea = fnode_ea(fnode); ea < ea_end; ea = next_ea(ea))
|
||||
if (!strcmp(ea->name, key)) {
|
||||
if (ea->indirect)
|
||||
return get_indirect_ea(s, ea->anode, ea_sec(ea), *size = ea_len(ea));
|
||||
if (ea_indirect(ea))
|
||||
return get_indirect_ea(s, ea_in_anode(ea), ea_sec(ea), *size = ea_len(ea));
|
||||
if (!(ret = kmalloc((*size = ea_valuelen(ea)) + 1, GFP_NOFS))) {
|
||||
printk("HPFS: out of memory for EA\n");
|
||||
return NULL;
|
||||
|
|
@ -148,7 +148,7 @@ char *hpfs_get_ea(struct super_block *s, struct fnode *fnode, char *key, int *si
|
|||
}
|
||||
a = le32_to_cpu(fnode->ea_secno);
|
||||
len = le32_to_cpu(fnode->ea_size_l);
|
||||
ano = fnode->ea_anode;
|
||||
ano = fnode_in_anode(fnode);
|
||||
pos = 0;
|
||||
while (pos < len) {
|
||||
char ex[4 + 255 + 1 + 8];
|
||||
|
|
@ -159,11 +159,11 @@ char *hpfs_get_ea(struct super_block *s, struct fnode *fnode, char *key, int *si
|
|||
return NULL;
|
||||
}
|
||||
if (hpfs_ea_read(s, a, ano, pos, 4, ex)) return NULL;
|
||||
if (hpfs_ea_read(s, a, ano, pos + 4, ea->namelen + 1 + (ea->indirect ? 8 : 0), ex + 4))
|
||||
if (hpfs_ea_read(s, a, ano, pos + 4, ea->namelen + 1 + (ea_indirect(ea) ? 8 : 0), ex + 4))
|
||||
return NULL;
|
||||
if (!strcmp(ea->name, key)) {
|
||||
if (ea->indirect)
|
||||
return get_indirect_ea(s, ea->anode, ea_sec(ea), *size = ea_len(ea));
|
||||
if (ea_indirect(ea))
|
||||
return get_indirect_ea(s, ea_in_anode(ea), ea_sec(ea), *size = ea_len(ea));
|
||||
if (!(ret = kmalloc((*size = ea_valuelen(ea)) + 1, GFP_NOFS))) {
|
||||
printk("HPFS: out of memory for EA\n");
|
||||
return NULL;
|
||||
|
|
@ -199,9 +199,9 @@ void hpfs_set_ea(struct inode *inode, struct fnode *fnode, const char *key,
|
|||
struct extended_attribute *ea_end = fnode_end_ea(fnode);
|
||||
for (ea = fnode_ea(fnode); ea < ea_end; ea = next_ea(ea))
|
||||
if (!strcmp(ea->name, key)) {
|
||||
if (ea->indirect) {
|
||||
if (ea_indirect(ea)) {
|
||||
if (ea_len(ea) == size)
|
||||
set_indirect_ea(s, ea->anode, ea_sec(ea), data, size);
|
||||
set_indirect_ea(s, ea_in_anode(ea), ea_sec(ea), data, size);
|
||||
} else if (ea_valuelen(ea) == size) {
|
||||
memcpy(ea_data(ea), data, size);
|
||||
}
|
||||
|
|
@ -209,7 +209,7 @@ void hpfs_set_ea(struct inode *inode, struct fnode *fnode, const char *key,
|
|||
}
|
||||
a = le32_to_cpu(fnode->ea_secno);
|
||||
len = le32_to_cpu(fnode->ea_size_l);
|
||||
ano = fnode->ea_anode;
|
||||
ano = fnode_in_anode(fnode);
|
||||
pos = 0;
|
||||
while (pos < len) {
|
||||
char ex[4 + 255 + 1 + 8];
|
||||
|
|
@ -220,12 +220,12 @@ void hpfs_set_ea(struct inode *inode, struct fnode *fnode, const char *key,
|
|||
return;
|
||||
}
|
||||
if (hpfs_ea_read(s, a, ano, pos, 4, ex)) return;
|
||||
if (hpfs_ea_read(s, a, ano, pos + 4, ea->namelen + 1 + (ea->indirect ? 8 : 0), ex + 4))
|
||||
if (hpfs_ea_read(s, a, ano, pos + 4, ea->namelen + 1 + (ea_indirect(ea) ? 8 : 0), ex + 4))
|
||||
return;
|
||||
if (!strcmp(ea->name, key)) {
|
||||
if (ea->indirect) {
|
||||
if (ea_indirect(ea)) {
|
||||
if (ea_len(ea) == size)
|
||||
set_indirect_ea(s, ea->anode, ea_sec(ea), data, size);
|
||||
set_indirect_ea(s, ea_in_anode(ea), ea_sec(ea), data, size);
|
||||
}
|
||||
else {
|
||||
if (ea_valuelen(ea) == size)
|
||||
|
|
@ -246,7 +246,7 @@ void hpfs_set_ea(struct inode *inode, struct fnode *fnode, const char *key,
|
|||
if (le16_to_cpu(fnode->ea_offs) < 0xc4 || le16_to_cpu(fnode->ea_offs) + le16_to_cpu(fnode->acl_size_s) + le16_to_cpu(fnode->ea_size_s) > 0x200) {
|
||||
hpfs_error(s, "fnode %08lx: ea_offs == %03x, ea_size_s == %03x",
|
||||
(unsigned long)inode->i_ino,
|
||||
le32_to_cpu(fnode->ea_offs), le16_to_cpu(fnode->ea_size_s));
|
||||
le16_to_cpu(fnode->ea_offs), le16_to_cpu(fnode->ea_size_s));
|
||||
return;
|
||||
}
|
||||
if ((le16_to_cpu(fnode->ea_size_s) || !le32_to_cpu(fnode->ea_size_l)) &&
|
||||
|
|
@ -276,7 +276,7 @@ void hpfs_set_ea(struct inode *inode, struct fnode *fnode, const char *key,
|
|||
fnode->ea_size_l = cpu_to_le32(le16_to_cpu(fnode->ea_size_s));
|
||||
fnode->ea_size_s = cpu_to_le16(0);
|
||||
fnode->ea_secno = cpu_to_le32(n);
|
||||
fnode->ea_anode = cpu_to_le32(0);
|
||||
fnode->flags &= ~FNODE_anode;
|
||||
mark_buffer_dirty(bh);
|
||||
brelse(bh);
|
||||
}
|
||||
|
|
@ -288,9 +288,9 @@ void hpfs_set_ea(struct inode *inode, struct fnode *fnode, const char *key,
|
|||
secno q = hpfs_alloc_sector(s, fno, 1, 0);
|
||||
if (!q) goto bail;
|
||||
fnode->ea_secno = cpu_to_le32(q);
|
||||
fnode->ea_anode = 0;
|
||||
fnode->flags &= ~FNODE_anode;
|
||||
len++;
|
||||
} else if (!fnode->ea_anode) {
|
||||
} else if (!fnode_in_anode(fnode)) {
|
||||
if (hpfs_alloc_if_possible(s, le32_to_cpu(fnode->ea_secno) + len)) {
|
||||
len++;
|
||||
} else {
|
||||
|
|
@ -310,7 +310,7 @@ void hpfs_set_ea(struct inode *inode, struct fnode *fnode, const char *key,
|
|||
anode->u.external[0].length = cpu_to_le32(len);
|
||||
mark_buffer_dirty(bh);
|
||||
brelse(bh);
|
||||
fnode->ea_anode = 1;
|
||||
fnode->flags |= FNODE_anode;
|
||||
fnode->ea_secno = cpu_to_le32(a_s);*/
|
||||
secno new_sec;
|
||||
int i;
|
||||
|
|
@ -338,7 +338,7 @@ void hpfs_set_ea(struct inode *inode, struct fnode *fnode, const char *key,
|
|||
len = (pos + 511) >> 9;
|
||||
}
|
||||
}
|
||||
if (fnode->ea_anode) {
|
||||
if (fnode_in_anode(fnode)) {
|
||||
if (hpfs_add_sector_to_btree(s, le32_to_cpu(fnode->ea_secno),
|
||||
0, len) != -1) {
|
||||
len++;
|
||||
|
|
@ -351,16 +351,16 @@ void hpfs_set_ea(struct inode *inode, struct fnode *fnode, const char *key,
|
|||
h[1] = strlen(key);
|
||||
h[2] = size & 0xff;
|
||||
h[3] = size >> 8;
|
||||
if (hpfs_ea_write(s, le32_to_cpu(fnode->ea_secno), fnode->ea_anode, le32_to_cpu(fnode->ea_size_l), 4, h)) goto bail;
|
||||
if (hpfs_ea_write(s, le32_to_cpu(fnode->ea_secno), fnode->ea_anode, le32_to_cpu(fnode->ea_size_l) + 4, h[1] + 1, key)) goto bail;
|
||||
if (hpfs_ea_write(s, le32_to_cpu(fnode->ea_secno), fnode->ea_anode, le32_to_cpu(fnode->ea_size_l) + 5 + h[1], size, data)) goto bail;
|
||||
if (hpfs_ea_write(s, le32_to_cpu(fnode->ea_secno), fnode_in_anode(fnode), le32_to_cpu(fnode->ea_size_l), 4, h)) goto bail;
|
||||
if (hpfs_ea_write(s, le32_to_cpu(fnode->ea_secno), fnode_in_anode(fnode), le32_to_cpu(fnode->ea_size_l) + 4, h[1] + 1, key)) goto bail;
|
||||
if (hpfs_ea_write(s, le32_to_cpu(fnode->ea_secno), fnode_in_anode(fnode), le32_to_cpu(fnode->ea_size_l) + 5 + h[1], size, data)) goto bail;
|
||||
fnode->ea_size_l = cpu_to_le32(pos);
|
||||
ret:
|
||||
hpfs_i(inode)->i_ea_size += 5 + strlen(key) + size;
|
||||
return;
|
||||
bail:
|
||||
if (le32_to_cpu(fnode->ea_secno))
|
||||
if (fnode->ea_anode) hpfs_truncate_btree(s, le32_to_cpu(fnode->ea_secno), 1, (le32_to_cpu(fnode->ea_size_l) + 511) >> 9);
|
||||
if (fnode_in_anode(fnode)) hpfs_truncate_btree(s, le32_to_cpu(fnode->ea_secno), 1, (le32_to_cpu(fnode->ea_size_l) + 511) >> 9);
|
||||
else hpfs_free_sectors(s, le32_to_cpu(fnode->ea_secno) + ((le32_to_cpu(fnode->ea_size_l) + 511) >> 9), len - ((le32_to_cpu(fnode->ea_size_l) + 511) >> 9));
|
||||
else fnode->ea_secno = fnode->ea_size_l = cpu_to_le32(0);
|
||||
}
|
||||
|
|
|
|||
289
fs/hpfs/hpfs.h
289
fs/hpfs/hpfs.h
|
|
@ -51,11 +51,11 @@ struct hpfs_boot_block
|
|||
u8 n_rootdir_entries[2];
|
||||
u8 n_sectors_s[2];
|
||||
u8 media_byte;
|
||||
u16 sectors_per_fat;
|
||||
u16 sectors_per_track;
|
||||
u16 heads_per_cyl;
|
||||
u32 n_hidden_sectors;
|
||||
u32 n_sectors_l; /* size of partition */
|
||||
__le16 sectors_per_fat;
|
||||
__le16 sectors_per_track;
|
||||
__le16 heads_per_cyl;
|
||||
__le32 n_hidden_sectors;
|
||||
__le32 n_sectors_l; /* size of partition */
|
||||
u8 drive_number;
|
||||
u8 mbz;
|
||||
u8 sig_28h; /* 28h */
|
||||
|
|
@ -63,7 +63,7 @@ struct hpfs_boot_block
|
|||
u8 vol_label[11];
|
||||
u8 sig_hpfs[8]; /* "HPFS " */
|
||||
u8 pad[448];
|
||||
u16 magic; /* aa55 */
|
||||
__le16 magic; /* aa55 */
|
||||
};
|
||||
|
||||
|
||||
|
|
@ -75,28 +75,28 @@ struct hpfs_boot_block
|
|||
|
||||
struct hpfs_super_block
|
||||
{
|
||||
u32 magic; /* f995 e849 */
|
||||
u32 magic1; /* fa53 e9c5, more magic? */
|
||||
__le32 magic; /* f995 e849 */
|
||||
__le32 magic1; /* fa53 e9c5, more magic? */
|
||||
u8 version; /* version of a filesystem usually 2 */
|
||||
u8 funcversion; /* functional version - oldest version
|
||||
of filesystem that can understand
|
||||
this disk */
|
||||
u16 zero; /* 0 */
|
||||
fnode_secno root; /* fnode of root directory */
|
||||
secno n_sectors; /* size of filesystem */
|
||||
u32 n_badblocks; /* number of bad blocks */
|
||||
secno bitmaps; /* pointers to free space bit maps */
|
||||
u32 zero1; /* 0 */
|
||||
secno badblocks; /* bad block list */
|
||||
u32 zero3; /* 0 */
|
||||
time32_t last_chkdsk; /* date last checked, 0 if never */
|
||||
time32_t last_optimize; /* date last optimized, 0 if never */
|
||||
secno n_dir_band; /* number of sectors in dir band */
|
||||
secno dir_band_start; /* first sector in dir band */
|
||||
secno dir_band_end; /* last sector in dir band */
|
||||
secno dir_band_bitmap; /* free space map, 1 dnode per bit */
|
||||
__le16 zero; /* 0 */
|
||||
__le32 root; /* fnode of root directory */
|
||||
__le32 n_sectors; /* size of filesystem */
|
||||
__le32 n_badblocks; /* number of bad blocks */
|
||||
__le32 bitmaps; /* pointers to free space bit maps */
|
||||
__le32 zero1; /* 0 */
|
||||
__le32 badblocks; /* bad block list */
|
||||
__le32 zero3; /* 0 */
|
||||
__le32 last_chkdsk; /* date last checked, 0 if never */
|
||||
__le32 last_optimize; /* date last optimized, 0 if never */
|
||||
__le32 n_dir_band; /* number of sectors in dir band */
|
||||
__le32 dir_band_start; /* first sector in dir band */
|
||||
__le32 dir_band_end; /* last sector in dir band */
|
||||
__le32 dir_band_bitmap; /* free space map, 1 dnode per bit */
|
||||
u8 volume_name[32]; /* not used */
|
||||
secno user_id_table; /* 8 preallocated sectors - user id */
|
||||
__le32 user_id_table; /* 8 preallocated sectors - user id */
|
||||
u32 zero6[103]; /* 0 */
|
||||
};
|
||||
|
||||
|
|
@ -109,8 +109,8 @@ struct hpfs_super_block
|
|||
|
||||
struct hpfs_spare_block
|
||||
{
|
||||
u32 magic; /* f991 1849 */
|
||||
u32 magic1; /* fa52 29c5, more magic? */
|
||||
__le32 magic; /* f991 1849 */
|
||||
__le32 magic1; /* fa52 29c5, more magic? */
|
||||
|
||||
#ifdef __LITTLE_ENDIAN
|
||||
u8 dirty: 1; /* 0 clean, 1 "improperly stopped" */
|
||||
|
|
@ -153,21 +153,21 @@ struct hpfs_spare_block
|
|||
u8 mm_contlgulty;
|
||||
u8 unused;
|
||||
|
||||
secno hotfix_map; /* info about remapped bad sectors */
|
||||
u32 n_spares_used; /* number of hotfixes */
|
||||
u32 n_spares; /* number of spares in hotfix map */
|
||||
u32 n_dnode_spares_free; /* spare dnodes unused */
|
||||
u32 n_dnode_spares; /* length of spare_dnodes[] list,
|
||||
__le32 hotfix_map; /* info about remapped bad sectors */
|
||||
__le32 n_spares_used; /* number of hotfixes */
|
||||
__le32 n_spares; /* number of spares in hotfix map */
|
||||
__le32 n_dnode_spares_free; /* spare dnodes unused */
|
||||
__le32 n_dnode_spares; /* length of spare_dnodes[] list,
|
||||
follows in this block*/
|
||||
secno code_page_dir; /* code page directory block */
|
||||
u32 n_code_pages; /* number of code pages */
|
||||
u32 super_crc; /* on HPFS386 and LAN Server this is
|
||||
__le32 code_page_dir; /* code page directory block */
|
||||
__le32 n_code_pages; /* number of code pages */
|
||||
__le32 super_crc; /* on HPFS386 and LAN Server this is
|
||||
checksum of superblock, on normal
|
||||
OS/2 unused */
|
||||
u32 spare_crc; /* on HPFS386 checksum of spareblock */
|
||||
u32 zero1[15]; /* unused */
|
||||
dnode_secno spare_dnodes[100]; /* emergency free dnode list */
|
||||
u32 zero2[1]; /* room for more? */
|
||||
__le32 spare_crc; /* on HPFS386 checksum of spareblock */
|
||||
__le32 zero1[15]; /* unused */
|
||||
__le32 spare_dnodes[100]; /* emergency free dnode list */
|
||||
__le32 zero2[1]; /* room for more? */
|
||||
};
|
||||
|
||||
/* The bad block list is 4 sectors long. The first word must be zero,
|
||||
|
|
@ -202,18 +202,18 @@ struct hpfs_spare_block
|
|||
|
||||
struct code_page_directory
|
||||
{
|
||||
u32 magic; /* 4945 21f7 */
|
||||
u32 n_code_pages; /* number of pointers following */
|
||||
u32 zero1[2];
|
||||
__le32 magic; /* 4945 21f7 */
|
||||
__le32 n_code_pages; /* number of pointers following */
|
||||
__le32 zero1[2];
|
||||
struct {
|
||||
u16 ix; /* index */
|
||||
u16 code_page_number; /* code page number */
|
||||
u32 bounds; /* matches corresponding word
|
||||
__le16 ix; /* index */
|
||||
__le16 code_page_number; /* code page number */
|
||||
__le32 bounds; /* matches corresponding word
|
||||
in data block */
|
||||
secno code_page_data; /* sector number of a code_page_data
|
||||
__le32 code_page_data; /* sector number of a code_page_data
|
||||
containing c.p. array */
|
||||
u16 index; /* index in c.p. array in that sector*/
|
||||
u16 unknown; /* some unknown value; usually 0;
|
||||
__le16 index; /* index in c.p. array in that sector*/
|
||||
__le16 unknown; /* some unknown value; usually 0;
|
||||
2 in Japanese version */
|
||||
} array[31]; /* unknown length */
|
||||
};
|
||||
|
|
@ -224,19 +224,19 @@ struct code_page_directory
|
|||
|
||||
struct code_page_data
|
||||
{
|
||||
u32 magic; /* 8945 21f7 */
|
||||
u32 n_used; /* # elements used in c_p_data[] */
|
||||
u32 bounds[3]; /* looks a bit like
|
||||
__le32 magic; /* 8945 21f7 */
|
||||
__le32 n_used; /* # elements used in c_p_data[] */
|
||||
__le32 bounds[3]; /* looks a bit like
|
||||
(beg1,end1), (beg2,end2)
|
||||
one byte each */
|
||||
u16 offs[3]; /* offsets from start of sector
|
||||
__le16 offs[3]; /* offsets from start of sector
|
||||
to start of c_p_data[ix] */
|
||||
struct {
|
||||
u16 ix; /* index */
|
||||
u16 code_page_number; /* code page number */
|
||||
u16 unknown; /* the same as in cp directory */
|
||||
__le16 ix; /* index */
|
||||
__le16 code_page_number; /* code page number */
|
||||
__le16 unknown; /* the same as in cp directory */
|
||||
u8 map[128]; /* upcase table for chars 80..ff */
|
||||
u16 zero2;
|
||||
__le16 zero2;
|
||||
} code_page[3];
|
||||
u8 incognita[78];
|
||||
};
|
||||
|
|
@ -278,8 +278,8 @@ struct code_page_data
|
|||
#define DNODE_MAGIC 0x77e40aae
|
||||
|
||||
struct dnode {
|
||||
u32 magic; /* 77e4 0aae */
|
||||
u32 first_free; /* offset from start of dnode to
|
||||
__le32 magic; /* 77e4 0aae */
|
||||
__le32 first_free; /* offset from start of dnode to
|
||||
first free dir entry */
|
||||
#ifdef __LITTLE_ENDIAN
|
||||
u8 root_dnode: 1; /* Is it root dnode? */
|
||||
|
|
@ -293,14 +293,14 @@ struct dnode {
|
|||
u8 root_dnode: 1; /* Is it root dnode? */
|
||||
#endif
|
||||
u8 increment_me2[3];
|
||||
secno up; /* (root dnode) directory's fnode
|
||||
__le32 up; /* (root dnode) directory's fnode
|
||||
(nonroot) parent dnode */
|
||||
dnode_secno self; /* pointer to this dnode */
|
||||
__le32 self; /* pointer to this dnode */
|
||||
u8 dirent[2028]; /* one or more dirents */
|
||||
};
|
||||
|
||||
struct hpfs_dirent {
|
||||
u16 length; /* offset to next dirent */
|
||||
__le16 length; /* offset to next dirent */
|
||||
|
||||
#ifdef __LITTLE_ENDIAN
|
||||
u8 first: 1; /* set on phony ^A^A (".") entry */
|
||||
|
|
@ -346,12 +346,12 @@ struct hpfs_dirent {
|
|||
u8 read_only: 1; /* dos attrib */
|
||||
#endif
|
||||
|
||||
fnode_secno fnode; /* fnode giving allocation info */
|
||||
time32_t write_date; /* mtime */
|
||||
u32 file_size; /* file length, bytes */
|
||||
time32_t read_date; /* atime */
|
||||
time32_t creation_date; /* ctime */
|
||||
u32 ea_size; /* total EA length, bytes */
|
||||
__le32 fnode; /* fnode giving allocation info */
|
||||
__le32 write_date; /* mtime */
|
||||
__le32 file_size; /* file length, bytes */
|
||||
__le32 read_date; /* atime */
|
||||
__le32 creation_date; /* ctime */
|
||||
__le32 ea_size; /* total EA length, bytes */
|
||||
u8 no_of_acls; /* number of ACL's (low 3 bits) */
|
||||
u8 ix; /* code page index (of filename), see
|
||||
struct code_page_data */
|
||||
|
|
@ -375,50 +375,36 @@ struct hpfs_dirent {
|
|||
|
||||
struct bplus_leaf_node
|
||||
{
|
||||
u32 file_secno; /* first file sector in extent */
|
||||
u32 length; /* length, sectors */
|
||||
secno disk_secno; /* first corresponding disk sector */
|
||||
__le32 file_secno; /* first file sector in extent */
|
||||
__le32 length; /* length, sectors */
|
||||
__le32 disk_secno; /* first corresponding disk sector */
|
||||
};
|
||||
|
||||
struct bplus_internal_node
|
||||
{
|
||||
u32 file_secno; /* subtree maps sectors < this */
|
||||
anode_secno down; /* pointer to subtree */
|
||||
__le32 file_secno; /* subtree maps sectors < this */
|
||||
__le32 down; /* pointer to subtree */
|
||||
};
|
||||
|
||||
enum {
|
||||
BP_hbff = 1,
|
||||
BP_fnode_parent = 0x20,
|
||||
BP_binary_search = 0x40,
|
||||
BP_internal = 0x80
|
||||
};
|
||||
struct bplus_header
|
||||
{
|
||||
#ifdef __LITTLE_ENDIAN
|
||||
u8 hbff: 1; /* high bit of first free entry offset */
|
||||
u8 flag1234: 4;
|
||||
u8 fnode_parent: 1; /* ? we're pointed to by an fnode,
|
||||
u8 flags; /* bit 0 - high bit of first free entry offset
|
||||
bit 5 - we're pointed to by an fnode,
|
||||
the data btree or some ea or the
|
||||
main ea bootage pointer ea_secno */
|
||||
/* also can get set in fnodes, which
|
||||
may be a chkdsk glitch or may mean
|
||||
this bit is irrelevant in fnodes,
|
||||
or this interpretation is all wet */
|
||||
u8 binary_search: 1; /* suggest binary search (unused) */
|
||||
u8 internal: 1; /* 1 -> (internal) tree of anodes
|
||||
0 -> (leaf) list of extents */
|
||||
#else
|
||||
u8 internal: 1; /* 1 -> (internal) tree of anodes
|
||||
0 -> (leaf) list of extents */
|
||||
u8 binary_search: 1; /* suggest binary search (unused) */
|
||||
u8 fnode_parent: 1; /* ? we're pointed to by an fnode,
|
||||
the data btree or some ea or the
|
||||
main ea bootage pointer ea_secno */
|
||||
/* also can get set in fnodes, which
|
||||
may be a chkdsk glitch or may mean
|
||||
this bit is irrelevant in fnodes,
|
||||
or this interpretation is all wet */
|
||||
u8 flag1234: 4;
|
||||
u8 hbff: 1; /* high bit of first free entry offset */
|
||||
#endif
|
||||
main ea bootage pointer ea_secno
|
||||
bit 6 - suggest binary search (unused)
|
||||
bit 7 - 1 -> (internal) tree of anodes
|
||||
0 -> (leaf) list of extents */
|
||||
u8 fill[3];
|
||||
u8 n_free_nodes; /* free nodes in following array */
|
||||
u8 n_used_nodes; /* used nodes in following array */
|
||||
u16 first_free; /* offset from start of header to
|
||||
__le16 first_free; /* offset from start of header to
|
||||
first free node in array */
|
||||
union {
|
||||
struct bplus_internal_node internal[0]; /* (internal) 2-word entries giving
|
||||
|
|
@ -428,6 +414,16 @@ struct bplus_header
|
|||
} u;
|
||||
};
|
||||
|
||||
static inline bool bp_internal(struct bplus_header *bp)
|
||||
{
|
||||
return bp->flags & BP_internal;
|
||||
}
|
||||
|
||||
static inline bool bp_fnode_parent(struct bplus_header *bp)
|
||||
{
|
||||
return bp->flags & BP_fnode_parent;
|
||||
}
|
||||
|
||||
/* fnode: root of allocation b+ tree, and EA's */
|
||||
|
||||
/* Every file and every directory has one fnode, pointed to by the directory
|
||||
|
|
@ -436,62 +432,56 @@ struct bplus_header
|
|||
|
||||
#define FNODE_MAGIC 0xf7e40aae
|
||||
|
||||
enum {FNODE_anode = cpu_to_le16(2), FNODE_dir = cpu_to_le16(256)};
|
||||
struct fnode
|
||||
{
|
||||
u32 magic; /* f7e4 0aae */
|
||||
u32 zero1[2]; /* read history */
|
||||
__le32 magic; /* f7e4 0aae */
|
||||
__le32 zero1[2]; /* read history */
|
||||
u8 len, name[15]; /* true length, truncated name */
|
||||
fnode_secno up; /* pointer to file's directory fnode */
|
||||
secno acl_size_l;
|
||||
secno acl_secno;
|
||||
u16 acl_size_s;
|
||||
__le32 up; /* pointer to file's directory fnode */
|
||||
__le32 acl_size_l;
|
||||
__le32 acl_secno;
|
||||
__le16 acl_size_s;
|
||||
u8 acl_anode;
|
||||
u8 zero2; /* history bit count */
|
||||
u32 ea_size_l; /* length of disk-resident ea's */
|
||||
secno ea_secno; /* first sector of disk-resident ea's*/
|
||||
u16 ea_size_s; /* length of fnode-resident ea's */
|
||||
__le32 ea_size_l; /* length of disk-resident ea's */
|
||||
__le32 ea_secno; /* first sector of disk-resident ea's*/
|
||||
__le16 ea_size_s; /* length of fnode-resident ea's */
|
||||
|
||||
#ifdef __LITTLE_ENDIAN
|
||||
u8 flag0: 1;
|
||||
u8 ea_anode: 1; /* 1 -> ea_secno is an anode */
|
||||
u8 flag234567: 6;
|
||||
#else
|
||||
u8 flag234567: 6;
|
||||
u8 ea_anode: 1; /* 1 -> ea_secno is an anode */
|
||||
u8 flag0: 1;
|
||||
#endif
|
||||
|
||||
#ifdef __LITTLE_ENDIAN
|
||||
u8 dirflag: 1; /* 1 -> directory. first & only extent
|
||||
__le16 flags; /* bit 1 set -> ea_secno is an anode */
|
||||
/* bit 8 set -> directory. first & only extent
|
||||
points to dnode. */
|
||||
u8 flag9012345: 7;
|
||||
#else
|
||||
u8 flag9012345: 7;
|
||||
u8 dirflag: 1; /* 1 -> directory. first & only extent
|
||||
points to dnode. */
|
||||
#endif
|
||||
|
||||
struct bplus_header btree; /* b+ tree, 8 extents or 12 subtrees */
|
||||
union {
|
||||
struct bplus_leaf_node external[8];
|
||||
struct bplus_internal_node internal[12];
|
||||
} u;
|
||||
|
||||
u32 file_size; /* file length, bytes */
|
||||
u32 n_needea; /* number of EA's with NEEDEA set */
|
||||
__le32 file_size; /* file length, bytes */
|
||||
__le32 n_needea; /* number of EA's with NEEDEA set */
|
||||
u8 user_id[16]; /* unused */
|
||||
u16 ea_offs; /* offset from start of fnode
|
||||
__le16 ea_offs; /* offset from start of fnode
|
||||
to first fnode-resident ea */
|
||||
u8 dasd_limit_treshhold;
|
||||
u8 dasd_limit_delta;
|
||||
u32 dasd_limit;
|
||||
u32 dasd_usage;
|
||||
__le32 dasd_limit;
|
||||
__le32 dasd_usage;
|
||||
u8 ea[316]; /* zero or more EA's, packed together
|
||||
with no alignment padding.
|
||||
(Do not use this name, get here
|
||||
via fnode + ea_offs. I think.) */
|
||||
};
|
||||
|
||||
static inline bool fnode_in_anode(struct fnode *p)
|
||||
{
|
||||
return (p->flags & FNODE_anode) != 0;
|
||||
}
|
||||
|
||||
static inline bool fnode_is_dir(struct fnode *p)
|
||||
{
|
||||
return (p->flags & FNODE_dir) != 0;
|
||||
}
|
||||
|
||||
|
||||
/* anode: 99.44% pure allocation tree */
|
||||
|
||||
|
|
@ -499,9 +489,9 @@ struct fnode
|
|||
|
||||
struct anode
|
||||
{
|
||||
u32 magic; /* 37e4 0aae */
|
||||
anode_secno self; /* pointer to this anode */
|
||||
secno up; /* parent anode or fnode */
|
||||
__le32 magic; /* 37e4 0aae */
|
||||
__le32 self; /* pointer to this anode */
|
||||
__le32 up; /* parent anode or fnode */
|
||||
|
||||
struct bplus_header btree; /* b+tree, 40 extents or 60 subtrees */
|
||||
union {
|
||||
|
|
@ -509,7 +499,7 @@ struct anode
|
|||
struct bplus_internal_node internal[60];
|
||||
} u;
|
||||
|
||||
u32 fill[3]; /* unused */
|
||||
__le32 fill[3]; /* unused */
|
||||
};
|
||||
|
||||
|
||||
|
|
@ -528,32 +518,23 @@ struct anode
|
|||
run, or in multiple runs. Flags in the fnode tell whether the EA list
|
||||
is immediate, in a single run, or in multiple runs. */
|
||||
|
||||
enum {EA_indirect = 1, EA_anode = 2, EA_needea = 128 };
|
||||
struct extended_attribute
|
||||
{
|
||||
#ifdef __LITTLE_ENDIAN
|
||||
u8 indirect: 1; /* 1 -> value gives sector number
|
||||
u8 flags; /* bit 0 set -> value gives sector number
|
||||
where real value starts */
|
||||
u8 anode: 1; /* 1 -> sector is an anode
|
||||
/* bit 1 set -> sector is an anode
|
||||
that points to fragmented value */
|
||||
u8 flag23456: 5;
|
||||
u8 needea: 1; /* required ea */
|
||||
#else
|
||||
u8 needea: 1; /* required ea */
|
||||
u8 flag23456: 5;
|
||||
u8 anode: 1; /* 1 -> sector is an anode
|
||||
that points to fragmented value */
|
||||
u8 indirect: 1; /* 1 -> value gives sector number
|
||||
where real value starts */
|
||||
#endif
|
||||
/* bit 7 set -> required ea */
|
||||
u8 namelen; /* length of name, bytes */
|
||||
u8 valuelen_lo; /* length of value, bytes */
|
||||
u8 valuelen_hi; /* length of value, bytes */
|
||||
u8 name[0];
|
||||
u8 name[];
|
||||
/*
|
||||
u8 name[namelen]; ascii attrib name
|
||||
u8 nul; terminating '\0', not counted
|
||||
u8 value[valuelen]; value, arbitrary
|
||||
if this.indirect, valuelen is 8 and the value is
|
||||
if this.flags & 1, valuelen is 8 and the value is
|
||||
u32 length; real length of value, bytes
|
||||
secno secno; sector address where it starts
|
||||
if this.anode, the above sector number is the root of an anode tree
|
||||
|
|
@ -561,6 +542,16 @@ struct extended_attribute
|
|||
*/
|
||||
};
|
||||
|
||||
static inline bool ea_indirect(struct extended_attribute *ea)
|
||||
{
|
||||
return ea->flags & EA_indirect;
|
||||
}
|
||||
|
||||
static inline bool ea_in_anode(struct extended_attribute *ea)
|
||||
{
|
||||
return ea->flags & EA_anode;
|
||||
}
|
||||
|
||||
/*
|
||||
Local Variables:
|
||||
comment-column: 40
|
||||
|
|
|
|||
|
|
@ -75,7 +75,7 @@ struct hpfs_sb_info {
|
|||
unsigned char *sb_cp_table; /* code page tables: */
|
||||
/* 128 bytes uppercasing table & */
|
||||
/* 128 bytes lowercasing table */
|
||||
unsigned *sb_bmp_dir; /* main bitmap directory */
|
||||
__le32 *sb_bmp_dir; /* main bitmap directory */
|
||||
unsigned sb_c_bitmap; /* current bitmap */
|
||||
unsigned sb_max_fwd_alloc; /* max forwad allocation */
|
||||
int sb_timeshift;
|
||||
|
|
@ -93,7 +93,7 @@ struct quad_buffer_head {
|
|||
static inline dnode_secno de_down_pointer (struct hpfs_dirent *de)
|
||||
{
|
||||
CHKCOND(de->down,("HPFS: de_down_pointer: !de->down\n"));
|
||||
return le32_to_cpu(*(dnode_secno *) ((void *) de + le16_to_cpu(de->length) - 4));
|
||||
return le32_to_cpu(*(__le32 *) ((void *) de + le16_to_cpu(de->length) - 4));
|
||||
}
|
||||
|
||||
/* The first dir entry in a dnode */
|
||||
|
|
@ -141,12 +141,12 @@ static inline struct extended_attribute *next_ea(struct extended_attribute *ea)
|
|||
|
||||
static inline secno ea_sec(struct extended_attribute *ea)
|
||||
{
|
||||
return le32_to_cpu(get_unaligned((secno *)((char *)ea + 9 + ea->namelen)));
|
||||
return le32_to_cpu(get_unaligned((__le32 *)((char *)ea + 9 + ea->namelen)));
|
||||
}
|
||||
|
||||
static inline secno ea_len(struct extended_attribute *ea)
|
||||
{
|
||||
return le32_to_cpu(get_unaligned((secno *)((char *)ea + 5 + ea->namelen)));
|
||||
return le32_to_cpu(get_unaligned((__le32 *)((char *)ea + 5 + ea->namelen)));
|
||||
}
|
||||
|
||||
static inline char *ea_data(struct extended_attribute *ea)
|
||||
|
|
@ -171,7 +171,7 @@ static inline void copy_de(struct hpfs_dirent *dst, struct hpfs_dirent *src)
|
|||
dst->not_8x3 = n;
|
||||
}
|
||||
|
||||
static inline unsigned tstbits(u32 *bmp, unsigned b, unsigned n)
|
||||
static inline unsigned tstbits(__le32 *bmp, unsigned b, unsigned n)
|
||||
{
|
||||
int i;
|
||||
if ((b >= 0x4000) || (b + n - 1 >= 0x4000)) return n;
|
||||
|
|
@ -268,10 +268,10 @@ void hpfs_evict_inode(struct inode *);
|
|||
|
||||
/* map.c */
|
||||
|
||||
unsigned *hpfs_map_dnode_bitmap(struct super_block *, struct quad_buffer_head *);
|
||||
unsigned *hpfs_map_bitmap(struct super_block *, unsigned, struct quad_buffer_head *, char *);
|
||||
__le32 *hpfs_map_dnode_bitmap(struct super_block *, struct quad_buffer_head *);
|
||||
__le32 *hpfs_map_bitmap(struct super_block *, unsigned, struct quad_buffer_head *, char *);
|
||||
unsigned char *hpfs_load_code_page(struct super_block *, secno);
|
||||
secno *hpfs_load_bitmap_directory(struct super_block *, secno bmp);
|
||||
__le32 *hpfs_load_bitmap_directory(struct super_block *, secno bmp);
|
||||
struct fnode *hpfs_map_fnode(struct super_block *s, ino_t, struct buffer_head **);
|
||||
struct anode *hpfs_map_anode(struct super_block *s, anode_secno, struct buffer_head **);
|
||||
struct dnode *hpfs_map_dnode(struct super_block *s, dnode_secno, struct quad_buffer_head *);
|
||||
|
|
|
|||
|
|
@ -110,7 +110,7 @@ void hpfs_read_inode(struct inode *i)
|
|||
}
|
||||
}
|
||||
}
|
||||
if (fnode->dirflag) {
|
||||
if (fnode_is_dir(fnode)) {
|
||||
int n_dnodes, n_subdirs;
|
||||
i->i_mode |= S_IFDIR;
|
||||
i->i_op = &hpfs_dir_iops;
|
||||
|
|
|
|||
|
|
@ -8,12 +8,12 @@
|
|||
|
||||
#include "hpfs_fn.h"
|
||||
|
||||
unsigned *hpfs_map_dnode_bitmap(struct super_block *s, struct quad_buffer_head *qbh)
|
||||
__le32 *hpfs_map_dnode_bitmap(struct super_block *s, struct quad_buffer_head *qbh)
|
||||
{
|
||||
return hpfs_map_4sectors(s, hpfs_sb(s)->sb_dmap, qbh, 0);
|
||||
}
|
||||
|
||||
unsigned int *hpfs_map_bitmap(struct super_block *s, unsigned bmp_block,
|
||||
__le32 *hpfs_map_bitmap(struct super_block *s, unsigned bmp_block,
|
||||
struct quad_buffer_head *qbh, char *id)
|
||||
{
|
||||
secno sec;
|
||||
|
|
@ -89,18 +89,18 @@ unsigned char *hpfs_load_code_page(struct super_block *s, secno cps)
|
|||
return cp_table;
|
||||
}
|
||||
|
||||
secno *hpfs_load_bitmap_directory(struct super_block *s, secno bmp)
|
||||
__le32 *hpfs_load_bitmap_directory(struct super_block *s, secno bmp)
|
||||
{
|
||||
struct buffer_head *bh;
|
||||
int n = (hpfs_sb(s)->sb_fs_size + 0x200000 - 1) >> 21;
|
||||
int i;
|
||||
secno *b;
|
||||
__le32 *b;
|
||||
if (!(b = kmalloc(n * 512, GFP_KERNEL))) {
|
||||
printk("HPFS: can't allocate memory for bitmap directory\n");
|
||||
return NULL;
|
||||
}
|
||||
for (i=0;i<n;i++) {
|
||||
secno *d = hpfs_map_sector(s, bmp+i, &bh, n - i - 1);
|
||||
__le32 *d = hpfs_map_sector(s, bmp+i, &bh, n - i - 1);
|
||||
if (!d) {
|
||||
kfree(b);
|
||||
return NULL;
|
||||
|
|
@ -130,16 +130,16 @@ struct fnode *hpfs_map_fnode(struct super_block *s, ino_t ino, struct buffer_hea
|
|||
(unsigned long)ino);
|
||||
goto bail;
|
||||
}
|
||||
if (!fnode->dirflag) {
|
||||
if (!fnode_is_dir(fnode)) {
|
||||
if ((unsigned)fnode->btree.n_used_nodes + (unsigned)fnode->btree.n_free_nodes !=
|
||||
(fnode->btree.internal ? 12 : 8)) {
|
||||
(bp_internal(&fnode->btree) ? 12 : 8)) {
|
||||
hpfs_error(s,
|
||||
"bad number of nodes in fnode %08lx",
|
||||
(unsigned long)ino);
|
||||
goto bail;
|
||||
}
|
||||
if (le16_to_cpu(fnode->btree.first_free) !=
|
||||
8 + fnode->btree.n_used_nodes * (fnode->btree.internal ? 8 : 12)) {
|
||||
8 + fnode->btree.n_used_nodes * (bp_internal(&fnode->btree) ? 8 : 12)) {
|
||||
hpfs_error(s,
|
||||
"bad first_free pointer in fnode %08lx",
|
||||
(unsigned long)ino);
|
||||
|
|
@ -187,12 +187,12 @@ struct anode *hpfs_map_anode(struct super_block *s, anode_secno ano, struct buff
|
|||
goto bail;
|
||||
}
|
||||
if ((unsigned)anode->btree.n_used_nodes + (unsigned)anode->btree.n_free_nodes !=
|
||||
(anode->btree.internal ? 60 : 40)) {
|
||||
(bp_internal(&anode->btree) ? 60 : 40)) {
|
||||
hpfs_error(s, "bad number of nodes in anode %08x", ano);
|
||||
goto bail;
|
||||
}
|
||||
if (le16_to_cpu(anode->btree.first_free) !=
|
||||
8 + anode->btree.n_used_nodes * (anode->btree.internal ? 8 : 12)) {
|
||||
8 + anode->btree.n_used_nodes * (bp_internal(&anode->btree) ? 8 : 12)) {
|
||||
hpfs_error(s, "bad first_free pointer in anode %08x", ano);
|
||||
goto bail;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -70,7 +70,7 @@ static int hpfs_mkdir(struct inode *dir, struct dentry *dentry, umode_t mode)
|
|||
fnode->len = len;
|
||||
memcpy(fnode->name, name, len > 15 ? 15 : len);
|
||||
fnode->up = cpu_to_le32(dir->i_ino);
|
||||
fnode->dirflag = 1;
|
||||
fnode->flags |= FNODE_dir;
|
||||
fnode->btree.n_free_nodes = 7;
|
||||
fnode->btree.n_used_nodes = 1;
|
||||
fnode->btree.first_free = cpu_to_le16(0x14);
|
||||
|
|
|
|||
|
|
@ -572,7 +572,7 @@ static int hpfs_fill_super(struct super_block *s, void *options, int silent)
|
|||
mark_buffer_dirty(bh2);
|
||||
}
|
||||
|
||||
if (le32_to_cpu(spareblock->hotfixes_used) || le32_to_cpu(spareblock->n_spares_used)) {
|
||||
if (spareblock->hotfixes_used || spareblock->n_spares_used) {
|
||||
if (errs >= 2) {
|
||||
printk("HPFS: Hotfixes not supported here, try chkdsk\n");
|
||||
mark_dirty(s, 0);
|
||||
|
|
@ -645,7 +645,7 @@ static int hpfs_fill_super(struct super_block *s, void *options, int silent)
|
|||
root->i_mtime.tv_nsec = 0;
|
||||
root->i_ctime.tv_sec = local_to_gmt(s, le32_to_cpu(de->creation_date));
|
||||
root->i_ctime.tv_nsec = 0;
|
||||
hpfs_i(root)->i_ea_size = le16_to_cpu(de->ea_size);
|
||||
hpfs_i(root)->i_ea_size = le32_to_cpu(de->ea_size);
|
||||
hpfs_i(root)->i_parent_dir = root->i_ino;
|
||||
if (root->i_size == -1)
|
||||
root->i_size = 2048;
|
||||
|
|
|
|||
Loading…
Reference in a new issue