Commit 7f4238a0 authored by Linus Torvalds's avatar Linus Torvalds

Merge branch 'hpfs'

* hpfs:
  HPFS: Remove unused variable
  HPFS: Move declaration up, so that there are no out-of-scope pointers
  HPFS: Fix some unaligned accesses
  HPFS: Fix endianity. Make hpfs work on big-endian machines
  HPFS: Implement fsync for hpfs
  HPFS: Fix a bug that filesystem was not marked dirty when remounting it
  HPFS: Restrict uid and gid to 16-bit values
  HPFS: When marking or clearing the dirty bit, sync the filesystem
  HPFS: Use types with defined width
  HPFS: Remove mark_inode_dirty
  HPFS: Remove CR/LF conversion option
  HPFS: Remove remaining locks
  HPFS: Introduce a global mutex and lock it on every callback from VFS.
  HPFS: Make HPFS compile on preempt and SMP
parents 8b061610 88f4e9e8
config HPFS_FS config HPFS_FS
tristate "OS/2 HPFS file system support" tristate "OS/2 HPFS file system support"
depends on BLOCK depends on BLOCK
depends on BROKEN || !PREEMPT
help help
OS/2 is IBM's operating system for PC's, the same as Warp, and HPFS OS/2 is IBM's operating system for PC's, the same as Warp, and HPFS
is the file system used for organizing files on OS/2 hard disk is the file system used for organizing files on OS/2 hard disk
......
...@@ -8,8 +8,6 @@ ...@@ -8,8 +8,6 @@
#include "hpfs_fn.h" #include "hpfs_fn.h"
static int hpfs_alloc_if_possible_nolock(struct super_block *s, secno sec);
/* /*
* Check if a sector is allocated in bitmap * Check if a sector is allocated in bitmap
* This is really slow. Turned on only if chk==2 * This is really slow. Turned on only if chk==2
...@@ -18,9 +16,9 @@ static int hpfs_alloc_if_possible_nolock(struct super_block *s, secno sec); ...@@ -18,9 +16,9 @@ static int hpfs_alloc_if_possible_nolock(struct super_block *s, secno sec);
static int chk_if_allocated(struct super_block *s, secno sec, char *msg) static int chk_if_allocated(struct super_block *s, secno sec, char *msg)
{ {
struct quad_buffer_head qbh; struct quad_buffer_head qbh;
unsigned *bmp; u32 *bmp;
if (!(bmp = hpfs_map_bitmap(s, sec >> 14, &qbh, "chk"))) goto fail; if (!(bmp = hpfs_map_bitmap(s, sec >> 14, &qbh, "chk"))) goto fail;
if ((bmp[(sec & 0x3fff) >> 5] >> (sec & 0x1f)) & 1) { if ((cpu_to_le32(bmp[(sec & 0x3fff) >> 5]) >> (sec & 0x1f)) & 1) {
hpfs_error(s, "sector '%s' - %08x not allocated in bitmap", msg, sec); hpfs_error(s, "sector '%s' - %08x not allocated in bitmap", msg, sec);
goto fail1; goto fail1;
} }
...@@ -28,7 +26,7 @@ static int chk_if_allocated(struct super_block *s, secno sec, char *msg) ...@@ -28,7 +26,7 @@ static int chk_if_allocated(struct super_block *s, secno sec, char *msg)
if (sec >= hpfs_sb(s)->sb_dirband_start && sec < hpfs_sb(s)->sb_dirband_start + hpfs_sb(s)->sb_dirband_size) { if (sec >= hpfs_sb(s)->sb_dirband_start && sec < hpfs_sb(s)->sb_dirband_start + hpfs_sb(s)->sb_dirband_size) {
unsigned ssec = (sec - hpfs_sb(s)->sb_dirband_start) / 4; unsigned ssec = (sec - hpfs_sb(s)->sb_dirband_start) / 4;
if (!(bmp = hpfs_map_dnode_bitmap(s, &qbh))) goto fail; if (!(bmp = hpfs_map_dnode_bitmap(s, &qbh))) goto fail;
if ((bmp[ssec >> 5] >> (ssec & 0x1f)) & 1) { if ((le32_to_cpu(bmp[ssec >> 5]) >> (ssec & 0x1f)) & 1) {
hpfs_error(s, "sector '%s' - %08x not allocated in directory bitmap", msg, sec); hpfs_error(s, "sector '%s' - %08x not allocated in directory bitmap", msg, sec);
goto fail1; goto fail1;
} }
...@@ -75,7 +73,6 @@ static secno alloc_in_bmp(struct super_block *s, secno near, unsigned n, unsigne ...@@ -75,7 +73,6 @@ static secno alloc_in_bmp(struct super_block *s, secno near, unsigned n, unsigne
hpfs_error(s, "Bad allocation size: %d", n); hpfs_error(s, "Bad allocation size: %d", n);
return 0; return 0;
} }
lock_super(s);
if (bs != ~0x3fff) { if (bs != ~0x3fff) {
if (!(bmp = hpfs_map_bitmap(s, near >> 14, &qbh, "aib"))) goto uls; if (!(bmp = hpfs_map_bitmap(s, near >> 14, &qbh, "aib"))) goto uls;
} else { } else {
...@@ -85,10 +82,6 @@ static secno alloc_in_bmp(struct super_block *s, secno near, unsigned n, unsigne ...@@ -85,10 +82,6 @@ static secno alloc_in_bmp(struct super_block *s, secno near, unsigned n, unsigne
ret = bs + nr; ret = bs + nr;
goto rt; goto rt;
} }
/*if (!tstbits(bmp, nr + n, n + forward)) {
ret = bs + nr + n;
goto rt;
}*/
q = nr + n; b = 0; q = nr + n; b = 0;
while ((a = tstbits(bmp, q, n + forward)) != 0) { while ((a = tstbits(bmp, q, n + forward)) != 0) {
q += a; q += a;
...@@ -105,14 +98,14 @@ static secno alloc_in_bmp(struct super_block *s, secno near, unsigned n, unsigne ...@@ -105,14 +98,14 @@ static secno alloc_in_bmp(struct super_block *s, secno near, unsigned n, unsigne
goto rt; goto rt;
} }
nr >>= 5; nr >>= 5;
/*for (i = nr + 1; i != nr; i++, i &= 0x1ff) {*/ /*for (i = nr + 1; i != nr; i++, i &= 0x1ff) */
i = nr; i = nr;
do { do {
if (!bmp[i]) goto cont; if (!le32_to_cpu(bmp[i])) goto cont;
if (n + forward >= 0x3f && bmp[i] != -1) goto cont; if (n + forward >= 0x3f && le32_to_cpu(bmp[i]) != 0xffffffff) goto cont;
q = i<<5; q = i<<5;
if (i > 0) { if (i > 0) {
unsigned k = bmp[i-1]; unsigned k = le32_to_cpu(bmp[i-1]);
while (k & 0x80000000) { while (k & 0x80000000) {
q--; k <<= 1; q--; k <<= 1;
} }
...@@ -132,18 +125,17 @@ static secno alloc_in_bmp(struct super_block *s, secno near, unsigned n, unsigne ...@@ -132,18 +125,17 @@ static secno alloc_in_bmp(struct super_block *s, secno near, unsigned n, unsigne
} while (i != nr); } while (i != nr);
rt: rt:
if (ret) { if (ret) {
if (hpfs_sb(s)->sb_chk && ((ret >> 14) != (bs >> 14) || (bmp[(ret & 0x3fff) >> 5] | ~(((1 << n) - 1) << (ret & 0x1f))) != 0xffffffff)) { if (hpfs_sb(s)->sb_chk && ((ret >> 14) != (bs >> 14) || (le32_to_cpu(bmp[(ret & 0x3fff) >> 5]) | ~(((1 << n) - 1) << (ret & 0x1f))) != 0xffffffff)) {
hpfs_error(s, "Allocation doesn't work! Wanted %d, allocated at %08x", n, ret); hpfs_error(s, "Allocation doesn't work! Wanted %d, allocated at %08x", n, ret);
ret = 0; ret = 0;
goto b; goto b;
} }
bmp[(ret & 0x3fff) >> 5] &= ~(((1 << n) - 1) << (ret & 0x1f)); bmp[(ret & 0x3fff) >> 5] &= cpu_to_le32(~(((1 << n) - 1) << (ret & 0x1f)));
hpfs_mark_4buffers_dirty(&qbh); hpfs_mark_4buffers_dirty(&qbh);
} }
b: b:
hpfs_brelse4(&qbh); hpfs_brelse4(&qbh);
uls: uls:
unlock_super(s);
return ret; return ret;
} }
...@@ -155,7 +147,7 @@ static secno alloc_in_bmp(struct super_block *s, secno near, unsigned n, unsigne ...@@ -155,7 +147,7 @@ static secno alloc_in_bmp(struct super_block *s, secno near, unsigned n, unsigne
* sectors * sectors
*/ */
secno hpfs_alloc_sector(struct super_block *s, secno near, unsigned n, int forward, int lock) secno hpfs_alloc_sector(struct super_block *s, secno near, unsigned n, int forward)
{ {
secno sec; secno sec;
int i; int i;
...@@ -167,7 +159,6 @@ secno hpfs_alloc_sector(struct super_block *s, secno near, unsigned n, int forwa ...@@ -167,7 +159,6 @@ secno hpfs_alloc_sector(struct super_block *s, secno near, unsigned n, int forwa
forward = -forward; forward = -forward;
f_p = 1; f_p = 1;
} }
if (lock) hpfs_lock_creation(s);
n_bmps = (sbi->sb_fs_size + 0x4000 - 1) >> 14; n_bmps = (sbi->sb_fs_size + 0x4000 - 1) >> 14;
if (near && near < sbi->sb_fs_size) { if (near && near < sbi->sb_fs_size) {
if ((sec = alloc_in_bmp(s, near, n, f_p ? forward : forward/4))) goto ret; if ((sec = alloc_in_bmp(s, near, n, f_p ? forward : forward/4))) goto ret;
...@@ -214,18 +205,17 @@ secno hpfs_alloc_sector(struct super_block *s, secno near, unsigned n, int forwa ...@@ -214,18 +205,17 @@ secno hpfs_alloc_sector(struct super_block *s, secno near, unsigned n, int forwa
ret: ret:
if (sec && f_p) { if (sec && f_p) {
for (i = 0; i < forward; i++) { for (i = 0; i < forward; i++) {
if (!hpfs_alloc_if_possible_nolock(s, sec + i + 1)) { if (!hpfs_alloc_if_possible(s, sec + i + 1)) {
hpfs_error(s, "Prealloc doesn't work! Wanted %d, allocated at %08x, can't allocate %d", forward, sec, i); hpfs_error(s, "Prealloc doesn't work! Wanted %d, allocated at %08x, can't allocate %d", forward, sec, i);
sec = 0; sec = 0;
break; break;
} }
} }
} }
if (lock) hpfs_unlock_creation(s);
return sec; return sec;
} }
static secno alloc_in_dirband(struct super_block *s, secno near, int lock) static secno alloc_in_dirband(struct super_block *s, secno near)
{ {
unsigned nr = near; unsigned nr = near;
secno sec; secno sec;
...@@ -236,49 +226,35 @@ static secno alloc_in_dirband(struct super_block *s, secno near, int lock) ...@@ -236,49 +226,35 @@ static secno alloc_in_dirband(struct super_block *s, secno near, int lock)
nr = sbi->sb_dirband_start + sbi->sb_dirband_size - 4; nr = sbi->sb_dirband_start + sbi->sb_dirband_size - 4;
nr -= sbi->sb_dirband_start; nr -= sbi->sb_dirband_start;
nr >>= 2; nr >>= 2;
if (lock) hpfs_lock_creation(s);
sec = alloc_in_bmp(s, (~0x3fff) | nr, 1, 0); sec = alloc_in_bmp(s, (~0x3fff) | nr, 1, 0);
if (lock) hpfs_unlock_creation(s);
if (!sec) return 0; if (!sec) return 0;
return ((sec & 0x3fff) << 2) + sbi->sb_dirband_start; return ((sec & 0x3fff) << 2) + sbi->sb_dirband_start;
} }
/* Alloc sector if it's free */ /* Alloc sector if it's free */
static int hpfs_alloc_if_possible_nolock(struct super_block *s, secno sec) int hpfs_alloc_if_possible(struct super_block *s, secno sec)
{ {
struct quad_buffer_head qbh; struct quad_buffer_head qbh;
unsigned *bmp; u32 *bmp;
lock_super(s);
if (!(bmp = hpfs_map_bitmap(s, sec >> 14, &qbh, "aip"))) goto end; if (!(bmp = hpfs_map_bitmap(s, sec >> 14, &qbh, "aip"))) goto end;
if (bmp[(sec & 0x3fff) >> 5] & (1 << (sec & 0x1f))) { if (le32_to_cpu(bmp[(sec & 0x3fff) >> 5]) & (1 << (sec & 0x1f))) {
bmp[(sec & 0x3fff) >> 5] &= ~(1 << (sec & 0x1f)); bmp[(sec & 0x3fff) >> 5] &= cpu_to_le32(~(1 << (sec & 0x1f)));
hpfs_mark_4buffers_dirty(&qbh); hpfs_mark_4buffers_dirty(&qbh);
hpfs_brelse4(&qbh); hpfs_brelse4(&qbh);
unlock_super(s);
return 1; return 1;
} }
hpfs_brelse4(&qbh); hpfs_brelse4(&qbh);
end: end:
unlock_super(s);
return 0; return 0;
} }
int hpfs_alloc_if_possible(struct super_block *s, secno sec)
{
int r;
hpfs_lock_creation(s);
r = hpfs_alloc_if_possible_nolock(s, sec);
hpfs_unlock_creation(s);
return r;
}
/* Free sectors in bitmaps */ /* Free sectors in bitmaps */
void hpfs_free_sectors(struct super_block *s, secno sec, unsigned n) void hpfs_free_sectors(struct super_block *s, secno sec, unsigned n)
{ {
struct quad_buffer_head qbh; struct quad_buffer_head qbh;
unsigned *bmp; u32 *bmp;
struct hpfs_sb_info *sbi = hpfs_sb(s); struct hpfs_sb_info *sbi = hpfs_sb(s);
/*printk("2 - ");*/ /*printk("2 - ");*/
if (!n) return; if (!n) return;
...@@ -286,26 +262,22 @@ void hpfs_free_sectors(struct super_block *s, secno sec, unsigned n) ...@@ -286,26 +262,22 @@ void hpfs_free_sectors(struct super_block *s, secno sec, unsigned n)
hpfs_error(s, "Trying to free reserved sector %08x", sec); hpfs_error(s, "Trying to free reserved sector %08x", sec);
return; return;
} }
lock_super(s);
sbi->sb_max_fwd_alloc += n > 0xffff ? 0xffff : n; sbi->sb_max_fwd_alloc += n > 0xffff ? 0xffff : n;
if (sbi->sb_max_fwd_alloc > 0xffffff) sbi->sb_max_fwd_alloc = 0xffffff; if (sbi->sb_max_fwd_alloc > 0xffffff) sbi->sb_max_fwd_alloc = 0xffffff;
new_map: new_map:
if (!(bmp = hpfs_map_bitmap(s, sec >> 14, &qbh, "free"))) { if (!(bmp = hpfs_map_bitmap(s, sec >> 14, &qbh, "free"))) {
unlock_super(s);
return; return;
} }
new_tst: new_tst:
if ((bmp[(sec & 0x3fff) >> 5] >> (sec & 0x1f) & 1)) { if ((le32_to_cpu(bmp[(sec & 0x3fff) >> 5]) >> (sec & 0x1f) & 1)) {
hpfs_error(s, "sector %08x not allocated", sec); hpfs_error(s, "sector %08x not allocated", sec);
hpfs_brelse4(&qbh); hpfs_brelse4(&qbh);
unlock_super(s);
return; return;
} }
bmp[(sec & 0x3fff) >> 5] |= 1 << (sec & 0x1f); bmp[(sec & 0x3fff) >> 5] |= cpu_to_le32(1 << (sec & 0x1f));
if (!--n) { if (!--n) {
hpfs_mark_4buffers_dirty(&qbh); hpfs_mark_4buffers_dirty(&qbh);
hpfs_brelse4(&qbh); hpfs_brelse4(&qbh);
unlock_super(s);
return; return;
} }
if (!(++sec & 0x3fff)) { if (!(++sec & 0x3fff)) {
...@@ -327,13 +299,13 @@ int hpfs_check_free_dnodes(struct super_block *s, int n) ...@@ -327,13 +299,13 @@ int hpfs_check_free_dnodes(struct super_block *s, int n)
int n_bmps = (hpfs_sb(s)->sb_fs_size + 0x4000 - 1) >> 14; int n_bmps = (hpfs_sb(s)->sb_fs_size + 0x4000 - 1) >> 14;
int b = hpfs_sb(s)->sb_c_bitmap & 0x0fffffff; int b = hpfs_sb(s)->sb_c_bitmap & 0x0fffffff;
int i, j; int i, j;
unsigned *bmp; u32 *bmp;
struct quad_buffer_head qbh; struct quad_buffer_head qbh;
if ((bmp = hpfs_map_dnode_bitmap(s, &qbh))) { if ((bmp = hpfs_map_dnode_bitmap(s, &qbh))) {
for (j = 0; j < 512; j++) { for (j = 0; j < 512; j++) {
unsigned k; unsigned k;
if (!bmp[j]) continue; if (!le32_to_cpu(bmp[j])) continue;
for (k = bmp[j]; k; k >>= 1) if (k & 1) if (!--n) { for (k = le32_to_cpu(bmp[j]); k; k >>= 1) if (k & 1) if (!--n) {
hpfs_brelse4(&qbh); hpfs_brelse4(&qbh);
return 0; return 0;
} }
...@@ -352,10 +324,10 @@ int hpfs_check_free_dnodes(struct super_block *s, int n) ...@@ -352,10 +324,10 @@ int hpfs_check_free_dnodes(struct super_block *s, int n)
chk_bmp: chk_bmp:
if (bmp) { if (bmp) {
for (j = 0; j < 512; j++) { for (j = 0; j < 512; j++) {
unsigned k; u32 k;
if (!bmp[j]) continue; if (!le32_to_cpu(bmp[j])) continue;
for (k = 0xf; k; k <<= 4) for (k = 0xf; k; k <<= 4)
if ((bmp[j] & k) == k) { if ((le32_to_cpu(bmp[j]) & k) == k) {
if (!--n) { if (!--n) {
hpfs_brelse4(&qbh); hpfs_brelse4(&qbh);
return 0; return 0;
...@@ -379,44 +351,40 @@ void hpfs_free_dnode(struct super_block *s, dnode_secno dno) ...@@ -379,44 +351,40 @@ void hpfs_free_dnode(struct super_block *s, dnode_secno dno)
hpfs_free_sectors(s, dno, 4); hpfs_free_sectors(s, dno, 4);
} else { } else {
struct quad_buffer_head qbh; struct quad_buffer_head qbh;
unsigned *bmp; u32 *bmp;
unsigned ssec = (dno - hpfs_sb(s)->sb_dirband_start) / 4; unsigned ssec = (dno - hpfs_sb(s)->sb_dirband_start) / 4;
lock_super(s);
if (!(bmp = hpfs_map_dnode_bitmap(s, &qbh))) { if (!(bmp = hpfs_map_dnode_bitmap(s, &qbh))) {
unlock_super(s);
return; return;
} }
bmp[ssec >> 5] |= 1 << (ssec & 0x1f); bmp[ssec >> 5] |= cpu_to_le32(1 << (ssec & 0x1f));
hpfs_mark_4buffers_dirty(&qbh); hpfs_mark_4buffers_dirty(&qbh);
hpfs_brelse4(&qbh); hpfs_brelse4(&qbh);
unlock_super(s);
} }
} }
struct dnode *hpfs_alloc_dnode(struct super_block *s, secno near, struct dnode *hpfs_alloc_dnode(struct super_block *s, secno near,
dnode_secno *dno, struct quad_buffer_head *qbh, dnode_secno *dno, struct quad_buffer_head *qbh)
int lock)
{ {
struct dnode *d; struct dnode *d;
if (hpfs_count_one_bitmap(s, hpfs_sb(s)->sb_dmap) > FREE_DNODES_ADD) { if (hpfs_count_one_bitmap(s, hpfs_sb(s)->sb_dmap) > FREE_DNODES_ADD) {
if (!(*dno = alloc_in_dirband(s, near, lock))) if (!(*dno = alloc_in_dirband(s, near)))
if (!(*dno = hpfs_alloc_sector(s, near, 4, 0, lock))) return NULL; if (!(*dno = hpfs_alloc_sector(s, near, 4, 0))) return NULL;
} else { } else {
if (!(*dno = hpfs_alloc_sector(s, near, 4, 0, lock))) if (!(*dno = hpfs_alloc_sector(s, near, 4, 0)))
if (!(*dno = alloc_in_dirband(s, near, lock))) return NULL; if (!(*dno = alloc_in_dirband(s, near))) return NULL;
} }
if (!(d = hpfs_get_4sectors(s, *dno, qbh))) { if (!(d = hpfs_get_4sectors(s, *dno, qbh))) {
hpfs_free_dnode(s, *dno); hpfs_free_dnode(s, *dno);
return NULL; return NULL;
} }
memset(d, 0, 2048); memset(d, 0, 2048);
d->magic = DNODE_MAGIC; d->magic = cpu_to_le32(DNODE_MAGIC);
d->first_free = 52; d->first_free = cpu_to_le32(52);
d->dirent[0] = 32; d->dirent[0] = 32;
d->dirent[2] = 8; d->dirent[2] = 8;
d->dirent[30] = 1; d->dirent[30] = 1;
d->dirent[31] = 255; d->dirent[31] = 255;
d->self = *dno; d->self = cpu_to_le32(*dno);
return d; return d;
} }
...@@ -424,16 +392,16 @@ struct fnode *hpfs_alloc_fnode(struct super_block *s, secno near, fnode_secno *f ...@@ -424,16 +392,16 @@ struct fnode *hpfs_alloc_fnode(struct super_block *s, secno near, fnode_secno *f
struct buffer_head **bh) struct buffer_head **bh)
{ {
struct fnode *f; struct fnode *f;
if (!(*fno = hpfs_alloc_sector(s, near, 1, FNODE_ALLOC_FWD, 1))) return NULL; if (!(*fno = hpfs_alloc_sector(s, near, 1, FNODE_ALLOC_FWD))) return NULL;
if (!(f = hpfs_get_sector(s, *fno, bh))) { if (!(f = hpfs_get_sector(s, *fno, bh))) {
hpfs_free_sectors(s, *fno, 1); hpfs_free_sectors(s, *fno, 1);
return NULL; return NULL;
} }
memset(f, 0, 512); memset(f, 0, 512);
f->magic = FNODE_MAGIC; f->magic = cpu_to_le32(FNODE_MAGIC);
f->ea_offs = 0xc4; f->ea_offs = cpu_to_le16(0xc4);
f->btree.n_free_nodes = 8; f->btree.n_free_nodes = 8;
f->btree.first_free = 8; f->btree.first_free = cpu_to_le16(8);
return f; return f;
} }
...@@ -441,16 +409,16 @@ struct anode *hpfs_alloc_anode(struct super_block *s, secno near, anode_secno *a ...@@ -441,16 +409,16 @@ struct anode *hpfs_alloc_anode(struct super_block *s, secno near, anode_secno *a
struct buffer_head **bh) struct buffer_head **bh)
{ {
struct anode *a; struct anode *a;
if (!(*ano = hpfs_alloc_sector(s, near, 1, ANODE_ALLOC_FWD, 1))) return NULL; if (!(*ano = hpfs_alloc_sector(s, near, 1, ANODE_ALLOC_FWD))) return NULL;
if (!(a = hpfs_get_sector(s, *ano, bh))) { if (!(a = hpfs_get_sector(s, *ano, bh))) {
hpfs_free_sectors(s, *ano, 1); hpfs_free_sectors(s, *ano, 1);
return NULL; return NULL;
} }
memset(a, 0, 512); memset(a, 0, 512);
a->magic = ANODE_MAGIC; a->magic = cpu_to_le32(ANODE_MAGIC);
a->self = *ano; a->self = cpu_to_le32(*ano);
a->btree.n_free_nodes = 40; a->btree.n_free_nodes = 40;
a->btree.n_used_nodes = 0; a->btree.n_used_nodes = 0;
a->btree.first_free = 8; a->btree.first_free = cpu_to_le16(8);
return a; return a;
} }
...@@ -22,8 +22,8 @@ secno hpfs_bplus_lookup(struct super_block *s, struct inode *inode, ...@@ -22,8 +22,8 @@ secno hpfs_bplus_lookup(struct super_block *s, struct inode *inode,
if (hpfs_sb(s)->sb_chk) if (hpfs_stop_cycles(s, a, &c1, &c2, "hpfs_bplus_lookup")) return -1; if (hpfs_sb(s)->sb_chk) if (hpfs_stop_cycles(s, a, &c1, &c2, "hpfs_bplus_lookup")) return -1;
if (btree->internal) { if (btree->internal) {
for (i = 0; i < btree->n_used_nodes; i++) for (i = 0; i < btree->n_used_nodes; i++)
if (btree->u.internal[i].file_secno > sec) { if (le32_to_cpu(btree->u.internal[i].file_secno) > sec) {
a = btree->u.internal[i].down; a = le32_to_cpu(btree->u.internal[i].down);
brelse(bh); brelse(bh);
if (!(anode = hpfs_map_anode(s, a, &bh))) return -1; if (!(anode = hpfs_map_anode(s, a, &bh))) return -1;
btree = &anode->btree; btree = &anode->btree;
...@@ -34,18 +34,18 @@ secno hpfs_bplus_lookup(struct super_block *s, struct inode *inode, ...@@ -34,18 +34,18 @@ secno hpfs_bplus_lookup(struct super_block *s, struct inode *inode,
return -1; return -1;
} }
for (i = 0; i < btree->n_used_nodes; i++) for (i = 0; i < btree->n_used_nodes; i++)
if (btree->u.external[i].file_secno <= sec && if (le32_to_cpu(btree->u.external[i].file_secno) <= sec &&
btree->u.external[i].file_secno + btree->u.external[i].length > sec) { le32_to_cpu(btree->u.external[i].file_secno) + le32_to_cpu(btree->u.external[i].length) > sec) {
a = btree->u.external[i].disk_secno + sec - btree->u.external[i].file_secno; a = le32_to_cpu(btree->u.external[i].disk_secno) + sec - le32_to_cpu(btree->u.external[i].file_secno);
if (hpfs_sb(s)->sb_chk) if (hpfs_chk_sectors(s, a, 1, "data")) { if (hpfs_sb(s)->sb_chk) if (hpfs_chk_sectors(s, a, 1, "data")) {
brelse(bh); brelse(bh);
return -1; return -1;
} }
if (inode) { if (inode) {
struct hpfs_inode_info *hpfs_inode = hpfs_i(inode); struct hpfs_inode_info *hpfs_inode = hpfs_i(inode);
hpfs_inode->i_file_sec = btree->u.external[i].file_secno; hpfs_inode->i_file_sec = le32_to_cpu(btree->u.external[i].file_secno);
hpfs_inode->i_disk_sec = btree->u.external[i].disk_secno; hpfs_inode->i_disk_sec = le32_to_cpu(btree->u.external[i].disk_secno);
hpfs_inode->i_n_secs = btree->u.external[i].length; hpfs_inode->i_n_secs = le32_to_cpu(btree->u.external[i].length);
} }
brelse(bh); brelse(bh);
return a; return a;
...@@ -83,8 +83,8 @@ secno hpfs_add_sector_to_btree(struct super_block *s, secno node, int fnod, unsi ...@@ -83,8 +83,8 @@ secno hpfs_add_sector_to_btree(struct super_block *s, secno node, int fnod, unsi
return -1; return -1;
} }
if (btree->internal) { if (btree->internal) {
a = btree->u.internal[n].down; a = le32_to_cpu(btree->u.internal[n].down);
btree->u.internal[n].file_secno = -1; btree->u.internal[n].file_secno = cpu_to_le32(-1);
mark_buffer_dirty(bh); mark_buffer_dirty(bh);
brelse(bh); brelse(bh);
if (hpfs_sb(s)->sb_chk) if (hpfs_sb(s)->sb_chk)
...@@ -94,15 +94,15 @@ secno hpfs_add_sector_to_btree(struct super_block *s, secno node, int fnod, unsi ...@@ -94,15 +94,15 @@ secno hpfs_add_sector_to_btree(struct super_block *s, secno node, int fnod, unsi
goto go_down; goto go_down;
} }
if (n >= 0) { if (n >= 0) {
if (btree->u.external[n].file_secno + btree->u.external[n].length != fsecno) { if (le32_to_cpu(btree->u.external[n].file_secno) + le32_to_cpu(btree->u.external[n].length) != fsecno) {
hpfs_error(s, "allocated size %08x, trying to add sector %08x, %cnode %08x", hpfs_error(s, "allocated size %08x, trying to add sector %08x, %cnode %08x",
btree->u.external[n].file_secno + btree->u.external[n].length, fsecno, le32_to_cpu(btree->u.external[n].file_secno) + le32_to_cpu(btree->u.external[n].length), fsecno,
fnod?'f':'a', node); fnod?'f':'a', node);
brelse(bh); brelse(bh);
return -1; return -1;
} }
if (hpfs_alloc_if_possible(s, se = btree->u.external[n].disk_secno + btree->u.external[n].length)) { if (hpfs_alloc_if_possible(s, se = le32_to_cpu(btree->u.external[n].disk_secno) + le32_to_cpu(btree->u.external[n].length))) {
btree->u.external[n].length++; btree->u.external[n].length = cpu_to_le32(le32_to_cpu(btree->u.external[n].length) + 1);
mark_buffer_dirty(bh); mark_buffer_dirty(bh);
brelse(bh); brelse(bh);
return se; return se;
...@@ -115,20 +115,20 @@ secno hpfs_add_sector_to_btree(struct super_block *s, secno node, int fnod, unsi ...@@ -115,20 +115,20 @@ secno hpfs_add_sector_to_btree(struct super_block *s, secno node, int fnod, unsi
} }
se = !fnod ? node : (node + 16384) & ~16383; se = !fnod ? node : (node + 16384) & ~16383;
} }
if (!(se = hpfs_alloc_sector(s, se, 1, fsecno*ALLOC_M>ALLOC_FWD_MAX ? ALLOC_FWD_MAX : fsecno*ALLOC_M<ALLOC_FWD_MIN ? ALLOC_FWD_MIN : fsecno*ALLOC_M, 1))) { if (!(se = hpfs_alloc_sector(s, se, 1, fsecno*ALLOC_M>ALLOC_FWD_MAX ? ALLOC_FWD_MAX : fsecno*ALLOC_M<ALLOC_FWD_MIN ? ALLOC_FWD_MIN : fsecno*ALLOC_M))) {
brelse(bh); brelse(bh);
return -1; return -1;
} }
fs = n < 0 ? 0 : btree->u.external[n].file_secno + btree->u.external[n].length; fs = n < 0 ? 0 : le32_to_cpu(btree->u.external[n].file_secno) + le32_to_cpu(btree->u.external[n].length);
if (!btree->n_free_nodes) { if (!btree->n_free_nodes) {
up = a != node ? anode->up : -1; up = a != node ? le32_to_cpu(anode->up) : -1;
if (!(anode = hpfs_alloc_anode(s, a, &na, &bh1))) { if (!(anode = hpfs_alloc_anode(s, a, &na, &bh1))) {
brelse(bh); brelse(bh);
hpfs_free_sectors(s, se, 1); hpfs_free_sectors(s, se, 1);
return -1; return -1;
} }
if (a == node && fnod) { if (a == node && fnod) {
anode->up = node; anode->up = cpu_to_le32(node);
anode->btree.fnode_parent = 1; anode->btree.fnode_parent = 1;
anode->btree.n_used_nodes = btree->n_used_nodes; anode->btree.n_used_nodes = btree->n_used_nodes;
anode->btree.first_free = btree->first_free; anode->btree.first_free = btree->first_free;
...@@ -137,9 +137,9 @@ secno hpfs_add_sector_to_btree(struct super_block *s, secno node, int fnod, unsi ...@@ -137,9 +137,9 @@ secno hpfs_add_sector_to_btree(struct super_block *s, secno node, int fnod, unsi
btree->internal = 1; btree->internal = 1;
btree->n_free_nodes = 11; btree->n_free_nodes = 11;
btree->n_used_nodes = 1; btree->n_used_nodes = 1;
btree->first_free = (char *)&(btree->u.internal[1]) - (char *)btree; btree->first_free = cpu_to_le16((char *)&(btree->u.internal[1]) - (char *)btree);
btree->u.internal[0].file_secno = -1; btree->u.internal[0].file_secno = cpu_to_le32(-1);
btree->u.internal[0].down = na; btree->u.internal[0].down = cpu_to_le32(na);
mark_buffer_dirty(bh); mark_buffer_dirty(bh);
} else if (!(ranode = hpfs_alloc_anode(s, /*a*/0, &ra, &bh2))) { } else if (!(ranode = hpfs_alloc_anode(s, /*a*/0, &ra, &bh2))) {
brelse(bh); brelse(bh);
...@@ -153,15 +153,15 @@ secno hpfs_add_sector_to_btree(struct super_block *s, secno node, int fnod, unsi ...@@ -153,15 +153,15 @@ secno hpfs_add_sector_to_btree(struct super_block *s, secno node, int fnod, unsi
btree = &anode->btree; btree = &anode->btree;
} }
btree->n_free_nodes--; n = btree->n_used_nodes++; btree->n_free_nodes--; n = btree->n_used_nodes++;
btree->first_free += 12; btree->first_free = cpu_to_le16(le16_to_cpu(btree->first_free) + 12);
btree->u.external[n].disk_secno = se; btree->u.external[n].disk_secno = cpu_to_le32(se);
btree->u.external[n].file_secno = fs; btree->u.external[n].file_secno = cpu_to_le32(fs);
btree->u.external[n].length = 1; btree->u.external[n].length = cpu_to_le32(1);
mark_buffer_dirty(bh); mark_buffer_dirty(bh);
brelse(bh); brelse(bh);
if ((a == node && fnod) || na == -1) return se; if ((a == node && fnod) || na == -1) return se;
c2 = 0; c2 = 0;
while (up != -1) { while (up != (anode_secno)-1) {
struct anode *new_anode; struct anode *new_anode;
if (hpfs_sb(s)->sb_chk) if (hpfs_sb(s)->sb_chk)
if (hpfs_stop_cycles(s, up, &c1, &c2, "hpfs_add_sector_to_btree #2")) return -1; if (hpfs_stop_cycles(s, up, &c1, &c2, "hpfs_add_sector_to_btree #2")) return -1;
...@@ -174,47 +174,47 @@ secno hpfs_add_sector_to_btree(struct super_block *s, secno node, int fnod, unsi ...@@ -174,47 +174,47 @@ secno hpfs_add_sector_to_btree(struct super_block *s, secno node, int fnod, unsi
} }
if (btree->n_free_nodes) { if (btree->n_free_nodes) {
btree->n_free_nodes--; n = btree->n_used_nodes++; btree->n_free_nodes--; n = btree->n_used_nodes++;
btree->first_free += 8; btree->first_free = cpu_to_le16(le16_to_cpu(btree->first_free) + 8);
btree->u.internal[n].file_secno = -1; btree->u.internal[n].file_secno = cpu_to_le32(-1);
btree->u.internal[n].down = na; btree->u.internal[n].down = cpu_to_le32(na);
btree->u.internal[n-1].file_secno = fs; btree->u.internal[n-1].file_secno = cpu_to_le32(fs);
mark_buffer_dirty(bh); mark_buffer_dirty(bh);
brelse(bh); brelse(bh);
brelse(bh2); brelse(bh2);
hpfs_free_sectors(s, ra, 1); hpfs_free_sectors(s, ra, 1);
if ((anode = hpfs_map_anode(s, na, &bh))) { if ((anode = hpfs_map_anode(s, na, &bh))) {
anode->up = up; anode->up = cpu_to_le32(up);
anode->btree.fnode_parent = up == node && fnod; anode->btree.fnode_parent = up == node && fnod;
mark_buffer_dirty(bh); mark_buffer_dirty(bh);
brelse(bh); brelse(bh);
} }
return se; return se;
} }
up = up != node ? anode->up : -1; up = up != node ? le32_to_cpu(anode->up) : -1;
btree->u.internal[btree->n_used_nodes - 1].file_secno = /*fs*/-1; btree->u.internal[btree->n_used_nodes - 1].file_secno = cpu_to_le32(/*fs*/-1);
mark_buffer_dirty(bh); mark_buffer_dirty(bh);
brelse(bh); brelse(bh);
a = na; a = na;
if ((new_anode = hpfs_alloc_anode(s, a, &na, &bh))) { if ((new_anode = hpfs_alloc_anode(s, a, &na, &bh))) {
anode = new_anode; anode = new_anode;
/*anode->up = up != -1 ? up : ra;*/ /*anode->up = cpu_to_le32(up != -1 ? up : ra);*/
anode->btree.internal = 1; anode->btree.internal = 1;
anode->btree.n_used_nodes = 1; anode->btree.n_used_nodes = 1;
anode->btree.n_free_nodes = 59; anode->btree.n_free_nodes = 59;
anode->btree.first_free = 16; anode->btree.first_free = cpu_to_le16(16);
anode->btree.u.internal[0].down = a; anode->btree.u.internal[0].down = cpu_to_le32(a);
anode->btree.u.internal[0].file_secno = -1; anode->btree.u.internal[0].file_secno = cpu_to_le32(-1);
mark_buffer_dirty(bh); mark_buffer_dirty(bh);
brelse(bh); brelse(bh);
if ((anode = hpfs_map_anode(s, a, &bh))) { if ((anode = hpfs_map_anode(s, a, &bh))) {
anode->up = na; anode->up = cpu_to_le32(na);
mark_buffer_dirty(bh); mark_buffer_dirty(bh);
brelse(bh); brelse(bh);
} }
} else na = a; } else na = a;
} }
if ((anode = hpfs_map_anode(s, na, &bh))) { if ((anode = hpfs_map_anode(s, na, &bh))) {
anode->up = node; anode->up = cpu_to_le32(node);
if (fnod) anode->btree.fnode_parent = 1; if (fnod) anode->btree.fnode_parent = 1;
mark_buffer_dirty(bh); mark_buffer_dirty(bh);
brelse(bh); brelse(bh);
...@@ -232,14 +232,14 @@ secno hpfs_add_sector_to_btree(struct super_block *s, secno node, int fnod, unsi ...@@ -232,14 +232,14 @@ secno hpfs_add_sector_to_btree(struct super_block *s, secno node, int fnod, unsi
} }
btree = &fnode->btree; btree = &fnode->btree;
} }
ranode->up = node; ranode->up = cpu_to_le32(node);
memcpy(&ranode->btree, btree, btree->first_free); memcpy(&ranode->btree, btree, le16_to_cpu(btree->first_free));
if (fnod) ranode->btree.fnode_parent = 1; if (fnod) ranode->btree.fnode_parent = 1;
ranode->btree.n_free_nodes = (ranode->btree.internal ? 60 : 40) - ranode->btree.n_used_nodes; 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 (ranode->btree.internal) for (n = 0; n < ranode->btree.n_used_nodes; n++) {
struct anode *unode; struct anode *unode;
if ((unode = hpfs_map_anode(s, ranode->u.internal[n].down, &bh1))) { if ((unode = hpfs_map_anode(s, le32_to_cpu(ranode->u.internal[n].down), &bh1))) {
unode->up = ra; unode->up = cpu_to_le32(ra);
unode->btree.fnode_parent = 0; unode->btree.fnode_parent = 0;
mark_buffer_dirty(bh1); mark_buffer_dirty(bh1);
brelse(bh1); brelse(bh1);
...@@ -248,11 +248,11 @@ secno hpfs_add_sector_to_btree(struct super_block *s, secno node, int fnod, unsi ...@@ -248,11 +248,11 @@ secno hpfs_add_sector_to_btree(struct super_block *s, secno node, int fnod, unsi
btree->internal = 1; btree->internal = 1;
btree->n_free_nodes = fnod ? 10 : 58; btree->n_free_nodes = fnod ? 10 : 58;
btree->n_used_nodes = 2; btree->n_used_nodes = 2;
btree->first_free = (char *)&btree->u.internal[2] - (char *)btree; btree->first_free = cpu_to_le16((char *)&btree->u.internal[2] - (char *)btree);
btree->u.internal[0].file_secno = fs; btree->u.internal[0].file_secno = cpu_to_le32(fs);
btree->u.internal[0].down = ra; btree->u.internal[0].down = cpu_to_le32(ra);
btree->u.internal[1].file_secno = -1; btree->u.internal[1].file_secno = cpu_to_le32(-1);
btree->u.internal[1].down = na; btree->u.internal[1].down = cpu_to_le32(na);
mark_buffer_dirty(bh); mark_buffer_dirty(bh);
brelse(bh); brelse(bh);
mark_buffer_dirty(bh2); mark_buffer_dirty(bh2);
...@@ -279,7 +279,7 @@ void hpfs_remove_btree(struct super_block *s, struct bplus_header *btree) ...@@ -279,7 +279,7 @@ void hpfs_remove_btree(struct super_block *s, struct bplus_header *btree)
go_down: go_down:
d2 = 0; d2 = 0;
while (btree1->internal) { while (btree1->internal) {
ano = btree1->u.internal[pos].down; ano = le32_to_cpu(btree1->u.internal[pos].down);
if (level) brelse(bh); if (level) brelse(bh);
if (hpfs_sb(s)->sb_chk) if (hpfs_sb(s)->sb_chk)
if (hpfs_stop_cycles(s, ano, &d1, &d2, "hpfs_remove_btree #1")) if (hpfs_stop_cycles(s, ano, &d1, &d2, "hpfs_remove_btree #1"))
...@@ -290,7 +290,7 @@ void hpfs_remove_btree(struct super_block *s, struct bplus_header *btree) ...@@ -290,7 +290,7 @@ void hpfs_remove_btree(struct super_block *s, struct bplus_header *btree)
pos = 0; pos = 0;
} }
for (i = 0; i < btree1->n_used_nodes; i++) for (i = 0; i < btree1->n_used_nodes; i++)
hpfs_free_sectors(s, btree1->u.external[i].disk_secno, btree1->u.external[i].length); hpfs_free_sectors(s, le32_to_cpu(btree1->u.external[i].disk_secno), le32_to_cpu(btree1->u.external[i].length));
go_up: go_up:
if (!level) return; if (!level) return;
brelse(bh); brelse(bh);
...@@ -298,13 +298,13 @@ void hpfs_remove_btree(struct super_block *s, struct bplus_header *btree) ...@@ -298,13 +298,13 @@ void hpfs_remove_btree(struct super_block *s, struct bplus_header *btree)
if (hpfs_stop_cycles(s, ano, &c1, &c2, "hpfs_remove_btree #2")) return; if (hpfs_stop_cycles(s, ano, &c1, &c2, "hpfs_remove_btree #2")) return;
hpfs_free_sectors(s, ano, 1); hpfs_free_sectors(s, ano, 1);
oano = ano; oano = ano;
ano = anode->up; ano = le32_to_cpu(anode->up);
if (--level) { if (--level) {
if (!(anode = hpfs_map_anode(s, ano, &bh))) return; if (!(anode = hpfs_map_anode(s, ano, &bh))) return;
btree1 = &anode->btree; btree1 = &anode->btree;
} else btree1 = btree; } else btree1 = btree;
for (i = 0; i < btree1->n_used_nodes; i++) { for (i = 0; i < btree1->n_used_nodes; i++) {
if (btree1->u.internal[i].down == oano) { if (le32_to_cpu(btree1->u.internal[i].down) == oano) {
if ((pos = i + 1) < btree1->n_used_nodes) if ((pos = i + 1) < btree1->n_used_nodes)
goto go_down; goto go_down;
else else
...@@ -411,7 +411,7 @@ void hpfs_truncate_btree(struct super_block *s, secno f, int fno, unsigned secs) ...@@ -411,7 +411,7 @@ void hpfs_truncate_btree(struct super_block *s, secno f, int fno, unsigned secs)
if (fno) { if (fno) {
btree->n_free_nodes = 8; btree->n_free_nodes = 8;
btree->n_used_nodes = 0; btree->n_used_nodes = 0;
btree->first_free = 8; btree->first_free = cpu_to_le16(8);
btree->internal = 0; btree->internal = 0;
mark_buffer_dirty(bh); mark_buffer_dirty(bh);
} else hpfs_free_sectors(s, f, 1); } else hpfs_free_sectors(s, f, 1);
...@@ -421,22 +421,22 @@ void hpfs_truncate_btree(struct super_block *s, secno f, int fno, unsigned secs) ...@@ -421,22 +421,22 @@ void hpfs_truncate_btree(struct super_block *s, secno f, int fno, unsigned secs)
while (btree->internal) { while (btree->internal) {
nodes = btree->n_used_nodes + btree->n_free_nodes; nodes = btree->n_used_nodes + btree->n_free_nodes;
for (i = 0; i < btree->n_used_nodes; i++) for (i = 0; i < btree->n_used_nodes; i++)
if (btree->u.internal[i].file_secno >= secs) goto f; if (le32_to_cpu(btree->u.internal[i].file_secno) >= secs) goto f;
brelse(bh); brelse(bh);
hpfs_error(s, "internal btree %08x doesn't end with -1", node); hpfs_error(s, "internal btree %08x doesn't end with -1", node);
return; return;
f: f:
for (j = i + 1; j < btree->n_used_nodes; j++) for (j = i + 1; j < btree->n_used_nodes; j++)
hpfs_ea_remove(s, btree->u.internal[j].down, 1, 0); hpfs_ea_remove(s, le32_to_cpu(btree->u.internal[j].down), 1, 0);
btree->n_used_nodes = i + 1; btree->n_used_nodes = i + 1;
btree->n_free_nodes = nodes - btree->n_used_nodes; btree->n_free_nodes = nodes - btree->n_used_nodes;
btree->first_free = 8 + 8 * btree->n_used_nodes; btree->first_free = cpu_to_le16(8 + 8 * btree->n_used_nodes);
mark_buffer_dirty(bh); mark_buffer_dirty(bh);
if (btree->u.internal[i].file_secno == secs) { if (btree->u.internal[i].file_secno == cpu_to_le32(secs)) {
brelse(bh); brelse(bh);
return; return;
} }
node = btree->u.internal[i].down; node = le32_to_cpu(btree->u.internal[i].down);
brelse(bh); brelse(bh);
if (hpfs_sb(s)->sb_chk) if (hpfs_sb(s)->sb_chk)
if (hpfs_stop_cycles(s, node, &c1, &c2, "hpfs_truncate_btree")) if (hpfs_stop_cycles(s, node, &c1, &c2, "hpfs_truncate_btree"))
...@@ -446,25 +446,25 @@ void hpfs_truncate_btree(struct super_block *s, secno f, int fno, unsigned secs) ...@@ -446,25 +446,25 @@ void hpfs_truncate_btree(struct super_block *s, secno f, int fno, unsigned secs)
} }
nodes = btree->n_used_nodes + btree->n_free_nodes; nodes = btree->n_used_nodes + btree->n_free_nodes;
for (i = 0; i < btree->n_used_nodes; i++) for (i = 0; i < btree->n_used_nodes; i++)
if (btree->u.external[i].file_secno + btree->u.external[i].length >= secs) goto ff; if (le32_to_cpu(btree->u.external[i].file_secno) + le32_to_cpu(btree->u.external[i].length) >= secs) goto ff;
brelse(bh); brelse(bh);
return; return;
ff: ff:
if (secs <= btree->u.external[i].file_secno) { if (secs <= le32_to_cpu(btree->u.external[i].file_secno)) {
hpfs_error(s, "there is an allocation error in file %08x, sector %08x", f, secs); hpfs_error(s, "there is an allocation error in file %08x, sector %08x", f, secs);
if (i) i--; if (i) i--;
} }
else if (btree->u.external[i].file_secno + btree->u.external[i].length > secs) { else if (le32_to_cpu(btree->u.external[i].file_secno) + le32_to_cpu(btree->u.external[i].length) > secs) {
hpfs_free_sectors(s, btree->u.external[i].disk_secno + secs - hpfs_free_sectors(s, le32_to_cpu(btree->u.external[i].disk_secno) + secs -
btree->u.external[i].file_secno, btree->u.external[i].length le32_to_cpu(btree->u.external[i].file_secno), le32_to_cpu(btree->u.external[i].length)
- secs + btree->u.external[i].file_secno); /* I hope gcc optimizes this :-) */ - secs + le32_to_cpu(btree->u.external[i].file_secno)); /* I hope gcc optimizes this :-) */
btree->u.external[i].length = secs - btree->u.external[i].file_secno; btree->u.external[i].length = cpu_to_le32(secs - le32_to_cpu(btree->u.external[i].file_secno));
} }
for (j = i + 1; j < btree->n_used_nodes; j++) for (j = i + 1; j < btree->n_used_nodes; j++)
hpfs_free_sectors(s, btree->u.external[j].disk_secno, btree->u.external[j].length); hpfs_free_sectors(s, le32_to_cpu(btree->u.external[j].disk_secno), le32_to_cpu(btree->u.external[j].length));
btree->n_used_nodes = i + 1; btree->n_used_nodes = i + 1;
btree->n_free_nodes = nodes - btree->n_used_nodes; btree->n_free_nodes = nodes - btree->n_used_nodes;
btree->first_free = 8 + 12 * btree->n_used_nodes; btree->first_free = cpu_to_le16(8 + 12 * btree->n_used_nodes);
mark_buffer_dirty(bh); mark_buffer_dirty(bh);
brelse(bh); brelse(bh);
} }
...@@ -480,12 +480,12 @@ void hpfs_remove_fnode(struct super_block *s, fnode_secno fno) ...@@ -480,12 +480,12 @@ void hpfs_remove_fnode(struct super_block *s, fnode_secno fno)
struct extended_attribute *ea_end; struct extended_attribute *ea_end;
if (!(fnode = hpfs_map_fnode(s, fno, &bh))) return; if (!(fnode = hpfs_map_fnode(s, fno, &bh))) return;
if (!fnode->dirflag) hpfs_remove_btree(s, &fnode->btree); if (!fnode->dirflag) hpfs_remove_btree(s, &fnode->btree);
else hpfs_remove_dtree(s, fnode->u.external[0].disk_secno); else hpfs_remove_dtree(s, le32_to_cpu(fnode->u.external[0].disk_secno));
ea_end = fnode_end_ea(fnode); ea_end = fnode_end_ea(fnode);
for (ea = fnode_ea(fnode); ea < ea_end; ea = next_ea(ea)) for (ea = fnode_ea(fnode); ea < ea_end; ea = next_ea(ea))
if (ea->indirect) if (ea->indirect)
hpfs_ea_remove(s, ea_sec(ea), ea->anode, ea_len(ea)); hpfs_ea_remove(s, ea_sec(ea), ea->anode, ea_len(ea));
hpfs_ea_ext_remove(s, fnode->ea_secno, fnode->ea_anode, fnode->ea_size_l); hpfs_ea_ext_remove(s, le32_to_cpu(fnode->ea_secno), fnode->ea_anode, le32_to_cpu(fnode->ea_size_l));
brelse(bh); brelse(bh);
hpfs_free_sectors(s, fno, 1); hpfs_free_sectors(s, fno, 1);
} }
...@@ -9,22 +9,6 @@ ...@@ -9,22 +9,6 @@
#include <linux/slab.h> #include <linux/slab.h>
#include "hpfs_fn.h" #include "hpfs_fn.h"
void hpfs_lock_creation(struct super_block *s)
{
#ifdef DEBUG_LOCKS
printk("lock creation\n");
#endif
mutex_lock(&hpfs_sb(s)->hpfs_creation_de);
}
void hpfs_unlock_creation(struct super_block *s)
{
#ifdef DEBUG_LOCKS
printk("unlock creation\n");
#endif
mutex_unlock(&hpfs_sb(s)->hpfs_creation_de);
}
/* Map a sector into a buffer and return pointers to it and to the buffer. */ /* Map a sector into a buffer and return pointers to it and to the buffer. */
void *hpfs_map_sector(struct super_block *s, unsigned secno, struct buffer_head **bhp, void *hpfs_map_sector(struct super_block *s, unsigned secno, struct buffer_head **bhp,
...@@ -32,6 +16,8 @@ void *hpfs_map_sector(struct super_block *s, unsigned secno, struct buffer_head ...@@ -32,6 +16,8 @@ void *hpfs_map_sector(struct super_block *s, unsigned secno, struct buffer_head
{ {
struct buffer_head *bh; struct buffer_head *bh;
hpfs_lock_assert(s);
cond_resched(); cond_resched();
*bhp = bh = sb_bread(s, secno); *bhp = bh = sb_bread(s, secno);
...@@ -50,6 +36,8 @@ void *hpfs_get_sector(struct super_block *s, unsigned secno, struct buffer_head ...@@ -50,6 +36,8 @@ void *hpfs_get_sector(struct super_block *s, unsigned secno, struct buffer_head
struct buffer_head *bh; struct buffer_head *bh;
/*return hpfs_map_sector(s, secno, bhp, 0);*/ /*return hpfs_map_sector(s, secno, bhp, 0);*/
hpfs_lock_assert(s);
cond_resched(); cond_resched();
if ((*bhp = bh = sb_getblk(s, secno)) != NULL) { if ((*bhp = bh = sb_getblk(s, secno)) != NULL) {
...@@ -70,6 +58,8 @@ void *hpfs_map_4sectors(struct super_block *s, unsigned secno, struct quad_buffe ...@@ -70,6 +58,8 @@ void *hpfs_map_4sectors(struct super_block *s, unsigned secno, struct quad_buffe
struct buffer_head *bh; struct buffer_head *bh;
char *data; char *data;
hpfs_lock_assert(s);
cond_resched(); cond_resched();
if (secno & 3) { if (secno & 3) {
...@@ -125,6 +115,8 @@ void *hpfs_get_4sectors(struct super_block *s, unsigned secno, ...@@ -125,6 +115,8 @@ void *hpfs_get_4sectors(struct super_block *s, unsigned secno,
{ {
cond_resched(); cond_resched();
hpfs_lock_assert(s);
if (secno & 3) { if (secno & 3) {
printk("HPFS: hpfs_get_4sectors: unaligned read\n"); printk("HPFS: hpfs_get_4sectors: unaligned read\n");
return NULL; return NULL;
......
...@@ -88,9 +88,9 @@ static int hpfs_readdir(struct file *filp, void *dirent, filldir_t filldir) ...@@ -88,9 +88,9 @@ static int hpfs_readdir(struct file *filp, void *dirent, filldir_t filldir)
hpfs_error(inode->i_sb, "not a directory, fnode %08lx", hpfs_error(inode->i_sb, "not a directory, fnode %08lx",
(unsigned long)inode->i_ino); (unsigned long)inode->i_ino);
} }
if (hpfs_inode->i_dno != fno->u.external[0].disk_secno) { if (hpfs_inode->i_dno != le32_to_cpu(fno->u.external[0].disk_secno)) {
e = 1; e = 1;
hpfs_error(inode->i_sb, "corrupted inode: i_dno == %08x, fnode -> dnode == %08x", hpfs_inode->i_dno, fno->u.external[0].disk_secno); hpfs_error(inode->i_sb, "corrupted inode: i_dno == %08x, fnode -> dnode == %08x", hpfs_inode->i_dno, le32_to_cpu(fno->u.external[0].disk_secno));
} }
brelse(bh); brelse(bh);
if (e) { if (e) {
...@@ -156,7 +156,7 @@ static int hpfs_readdir(struct file *filp, void *dirent, filldir_t filldir) ...@@ -156,7 +156,7 @@ static int hpfs_readdir(struct file *filp, void *dirent, filldir_t filldir)
goto again; goto again;
} }
tempname = hpfs_translate_name(inode->i_sb, de->name, de->namelen, lc, de->not_8x3); tempname = hpfs_translate_name(inode->i_sb, de->name, de->namelen, lc, de->not_8x3);
if (filldir(dirent, tempname, de->namelen, old_pos, de->fnode, DT_UNKNOWN) < 0) { if (filldir(dirent, tempname, de->namelen, old_pos, le32_to_cpu(de->fnode), DT_UNKNOWN) < 0) {
filp->f_pos = old_pos; filp->f_pos = old_pos;
if (tempname != de->name) kfree(tempname); if (tempname != de->name) kfree(tempname);
hpfs_brelse4(&qbh); hpfs_brelse4(&qbh);
...@@ -221,7 +221,7 @@ struct dentry *hpfs_lookup(struct inode *dir, struct dentry *dentry, struct name ...@@ -221,7 +221,7 @@ struct dentry *hpfs_lookup(struct inode *dir, struct dentry *dentry, struct name
* Get inode number, what we're after. * Get inode number, what we're after.
*/ */
ino = de->fnode; ino = le32_to_cpu(de->fnode);
/* /*
* Go find or make an inode. * Go find or make an inode.
...@@ -236,7 +236,7 @@ struct dentry *hpfs_lookup(struct inode *dir, struct dentry *dentry, struct name ...@@ -236,7 +236,7 @@ struct dentry *hpfs_lookup(struct inode *dir, struct dentry *dentry, struct name
hpfs_init_inode(result); hpfs_init_inode(result);
if (de->directory) if (de->directory)
hpfs_read_inode(result); hpfs_read_inode(result);
else if (de->ea_size && hpfs_sb(dir->i_sb)->sb_eas) else if (le32_to_cpu(de->ea_size) && hpfs_sb(dir->i_sb)->sb_eas)
hpfs_read_inode(result); hpfs_read_inode(result);
else { else {
result->i_mode |= S_IFREG; result->i_mode |= S_IFREG;
...@@ -250,8 +250,6 @@ struct dentry *hpfs_lookup(struct inode *dir, struct dentry *dentry, struct name ...@@ -250,8 +250,6 @@ struct dentry *hpfs_lookup(struct inode *dir, struct dentry *dentry, struct name
hpfs_result = hpfs_i(result); hpfs_result = hpfs_i(result);
if (!de->directory) hpfs_result->i_parent_dir = dir->i_ino; if (!de->directory) hpfs_result->i_parent_dir = dir->i_ino;
hpfs_decide_conv(result, name, len);
if (de->has_acl || de->has_xtd_perm) if (!(dir->i_sb->s_flags & MS_RDONLY)) { if (de->has_acl || de->has_xtd_perm) if (!(dir->i_sb->s_flags & MS_RDONLY)) {
hpfs_error(result->i_sb, "ACLs or XPERM found. This is probably HPFS386. This driver doesn't support it now. Send me some info on these structures"); hpfs_error(result->i_sb, "ACLs or XPERM found. This is probably HPFS386. This driver doesn't support it now. Send me some info on these structures");
goto bail1; goto bail1;
...@@ -263,19 +261,19 @@ struct dentry *hpfs_lookup(struct inode *dir, struct dentry *dentry, struct name ...@@ -263,19 +261,19 @@ struct dentry *hpfs_lookup(struct inode *dir, struct dentry *dentry, struct name
*/ */
if (!result->i_ctime.tv_sec) { if (!result->i_ctime.tv_sec) {
if (!(result->i_ctime.tv_sec = local_to_gmt(dir->i_sb, de->creation_date))) if (!(result->i_ctime.tv_sec = local_to_gmt(dir->i_sb, le32_to_cpu(de->creation_date))))
result->i_ctime.tv_sec = 1; result->i_ctime.tv_sec = 1;
result->i_ctime.tv_nsec = 0; result->i_ctime.tv_nsec = 0;
result->i_mtime.tv_sec = local_to_gmt(dir->i_sb, de->write_date); result->i_mtime.tv_sec = local_to_gmt(dir->i_sb, le32_to_cpu(de->write_date));
result->i_mtime.tv_nsec = 0; result->i_mtime.tv_nsec = 0;
result->i_atime.tv_sec = local_to_gmt(dir->i_sb, de->read_date); result->i_atime.tv_sec = local_to_gmt(dir->i_sb, le32_to_cpu(de->read_date));
result->i_atime.tv_nsec = 0; result->i_atime.tv_nsec = 0;
hpfs_result->i_ea_size = de->ea_size; hpfs_result->i_ea_size = le32_to_cpu(de->ea_size);
if (!hpfs_result->i_ea_mode && de->read_only) if (!hpfs_result->i_ea_mode && de->read_only)
result->i_mode &= ~0222; result->i_mode &= ~0222;
if (!de->directory) { if (!de->directory) {
if (result->i_size == -1) { if (result->i_size == -1) {
result->i_size = de->file_size; result->i_size = le32_to_cpu(de->file_size);
result->i_data.a_ops = &hpfs_aops; result->i_data.a_ops = &hpfs_aops;
hpfs_i(result)->mmu_private = result->i_size; hpfs_i(result)->mmu_private = result->i_size;
/* /*
......
...@@ -14,11 +14,11 @@ static loff_t get_pos(struct dnode *d, struct hpfs_dirent *fde) ...@@ -14,11 +14,11 @@ static loff_t get_pos(struct dnode *d, struct hpfs_dirent *fde)
struct hpfs_dirent *de_end = dnode_end_de(d); struct hpfs_dirent *de_end = dnode_end_de(d);
int i = 1; int i = 1;
for (de = dnode_first_de(d); de < de_end; de = de_next_de(de)) { for (de = dnode_first_de(d); de < de_end; de = de_next_de(de)) {
if (de == fde) return ((loff_t) d->self << 4) | (loff_t)i; if (de == fde) return ((loff_t) le32_to_cpu(d->self) << 4) | (loff_t)i;
i++; i++;
} }
printk("HPFS: get_pos: not_found\n"); printk("HPFS: get_pos: not_found\n");
return ((loff_t)d->self << 4) | (loff_t)1; return ((loff_t)le32_to_cpu(d->self) << 4) | (loff_t)1;
} }
void hpfs_add_pos(struct inode *inode, loff_t *pos) void hpfs_add_pos(struct inode *inode, loff_t *pos)
...@@ -130,29 +130,30 @@ static void set_last_pointer(struct super_block *s, struct dnode *d, dnode_secno ...@@ -130,29 +130,30 @@ static void set_last_pointer(struct super_block *s, struct dnode *d, dnode_secno
{ {
struct hpfs_dirent *de; struct hpfs_dirent *de;
if (!(de = dnode_last_de(d))) { if (!(de = dnode_last_de(d))) {
hpfs_error(s, "set_last_pointer: empty dnode %08x", d->self); hpfs_error(s, "set_last_pointer: empty dnode %08x", le32_to_cpu(d->self));
return; return;
} }
if (hpfs_sb(s)->sb_chk) { if (hpfs_sb(s)->sb_chk) {
if (de->down) { if (de->down) {
hpfs_error(s, "set_last_pointer: dnode %08x has already last pointer %08x", hpfs_error(s, "set_last_pointer: dnode %08x has already last pointer %08x",
d->self, de_down_pointer(de)); le32_to_cpu(d->self), de_down_pointer(de));
return; return;
} }
if (de->length != 32) { if (le16_to_cpu(de->length) != 32) {
hpfs_error(s, "set_last_pointer: bad last dirent in dnode %08x", d->self); hpfs_error(s, "set_last_pointer: bad last dirent in dnode %08x", le32_to_cpu(d->self));
return; return;
} }
} }
if (ptr) { if (ptr) {
if ((d->first_free += 4) > 2048) { d->first_free = cpu_to_le32(le32_to_cpu(d->first_free) + 4);
hpfs_error(s,"set_last_pointer: too long dnode %08x", d->self); if (le32_to_cpu(d->first_free) > 2048) {
d->first_free -= 4; hpfs_error(s, "set_last_pointer: too long dnode %08x", le32_to_cpu(d->self));
d->first_free = cpu_to_le32(le32_to_cpu(d->first_free) - 4);
return; return;
} }
de->length = 36; de->length = cpu_to_le16(36);
de->down = 1; de->down = 1;
*(dnode_secno *)((char *)de + 32) = ptr; *(dnode_secno *)((char *)de + 32) = cpu_to_le32(ptr);
} }
} }
...@@ -168,7 +169,7 @@ struct hpfs_dirent *hpfs_add_de(struct super_block *s, struct dnode *d, ...@@ -168,7 +169,7 @@ struct hpfs_dirent *hpfs_add_de(struct super_block *s, struct dnode *d,
for (de = dnode_first_de(d); de < de_end; de = de_next_de(de)) { for (de = dnode_first_de(d); de < de_end; de = de_next_de(de)) {
int c = hpfs_compare_names(s, name, namelen, de->name, de->namelen, de->last); int c = hpfs_compare_names(s, name, namelen, de->name, de->namelen, de->last);
if (!c) { if (!c) {
hpfs_error(s, "name (%c,%d) already exists in dnode %08x", *name, namelen, d->self); hpfs_error(s, "name (%c,%d) already exists in dnode %08x", *name, namelen, le32_to_cpu(d->self));
return NULL; return NULL;
} }
if (c < 0) break; if (c < 0) break;
...@@ -176,15 +177,14 @@ struct hpfs_dirent *hpfs_add_de(struct super_block *s, struct dnode *d, ...@@ -176,15 +177,14 @@ struct hpfs_dirent *hpfs_add_de(struct super_block *s, struct dnode *d,
memmove((char *)de + d_size, de, (char *)de_end - (char *)de); memmove((char *)de + d_size, de, (char *)de_end - (char *)de);
memset(de, 0, d_size); memset(de, 0, d_size);
if (down_ptr) { if (down_ptr) {
*(int *)((char *)de + d_size - 4) = down_ptr; *(dnode_secno *)((char *)de + d_size - 4) = cpu_to_le32(down_ptr);
de->down = 1; de->down = 1;
} }
de->length = d_size; de->length = cpu_to_le16(d_size);
if (down_ptr) de->down = 1;
de->not_8x3 = hpfs_is_name_long(name, namelen); de->not_8x3 = hpfs_is_name_long(name, namelen);
de->namelen = namelen; de->namelen = namelen;
memcpy(de->name, name, namelen); memcpy(de->name, name, namelen);
d->first_free += d_size; d->first_free = cpu_to_le32(le32_to_cpu(d->first_free) + d_size);
return de; return de;
} }
...@@ -194,25 +194,25 @@ static void hpfs_delete_de(struct super_block *s, struct dnode *d, ...@@ -194,25 +194,25 @@ static void hpfs_delete_de(struct super_block *s, struct dnode *d,
struct hpfs_dirent *de) struct hpfs_dirent *de)
{ {
if (de->last) { if (de->last) {
hpfs_error(s, "attempt to delete last dirent in dnode %08x", d->self); hpfs_error(s, "attempt to delete last dirent in dnode %08x", le32_to_cpu(d->self));
return; return;
} }
d->first_free -= de->length; d->first_free = cpu_to_le32(le32_to_cpu(d->first_free) - le16_to_cpu(de->length));
memmove(de, de_next_de(de), d->first_free + (char *)d - (char *)de); memmove(de, de_next_de(de), le32_to_cpu(d->first_free) + (char *)d - (char *)de);
} }
static void fix_up_ptrs(struct super_block *s, struct dnode *d) static void fix_up_ptrs(struct super_block *s, struct dnode *d)
{ {
struct hpfs_dirent *de; struct hpfs_dirent *de;
struct hpfs_dirent *de_end = dnode_end_de(d); struct hpfs_dirent *de_end = dnode_end_de(d);
dnode_secno dno = d->self; dnode_secno dno = le32_to_cpu(d->self);
for (de = dnode_first_de(d); de < de_end; de = de_next_de(de)) for (de = dnode_first_de(d); de < de_end; de = de_next_de(de))
if (de->down) { if (de->down) {
struct quad_buffer_head qbh; struct quad_buffer_head qbh;
struct dnode *dd; struct dnode *dd;
if ((dd = hpfs_map_dnode(s, de_down_pointer(de), &qbh))) { if ((dd = hpfs_map_dnode(s, de_down_pointer(de), &qbh))) {
if (dd->up != dno || dd->root_dnode) { if (le32_to_cpu(dd->up) != dno || dd->root_dnode) {
dd->up = dno; dd->up = cpu_to_le32(dno);
dd->root_dnode = 0; dd->root_dnode = 0;
hpfs_mark_4buffers_dirty(&qbh); hpfs_mark_4buffers_dirty(&qbh);
} }
...@@ -262,7 +262,7 @@ static int hpfs_add_to_dnode(struct inode *i, dnode_secno dno, ...@@ -262,7 +262,7 @@ static int hpfs_add_to_dnode(struct inode *i, dnode_secno dno,
kfree(nname); kfree(nname);
return 1; return 1;
} }
if (d->first_free + de_size(namelen, down_ptr) <= 2048) { if (le32_to_cpu(d->first_free) + de_size(namelen, down_ptr) <= 2048) {
loff_t t; loff_t t;
copy_de(de=hpfs_add_de(i->i_sb, d, name, namelen, down_ptr), new_de); copy_de(de=hpfs_add_de(i->i_sb, d, name, namelen, down_ptr), new_de);
t = get_pos(d, de); t = get_pos(d, de);
...@@ -286,11 +286,11 @@ static int hpfs_add_to_dnode(struct inode *i, dnode_secno dno, ...@@ -286,11 +286,11 @@ static int hpfs_add_to_dnode(struct inode *i, dnode_secno dno,
kfree(nname); kfree(nname);
return 1; return 1;
} }
memcpy(nd, d, d->first_free); memcpy(nd, d, le32_to_cpu(d->first_free));
copy_de(de = hpfs_add_de(i->i_sb, nd, name, namelen, down_ptr), new_de); copy_de(de = hpfs_add_de(i->i_sb, nd, name, namelen, down_ptr), new_de);
for_all_poss(i, hpfs_pos_ins, get_pos(nd, de), 1); for_all_poss(i, hpfs_pos_ins, get_pos(nd, de), 1);
h = ((char *)dnode_last_de(nd) - (char *)nd) / 2 + 10; h = ((char *)dnode_last_de(nd) - (char *)nd) / 2 + 10;
if (!(ad = hpfs_alloc_dnode(i->i_sb, d->up, &adno, &qbh1, 0))) { if (!(ad = hpfs_alloc_dnode(i->i_sb, le32_to_cpu(d->up), &adno, &qbh1))) {
hpfs_error(i->i_sb, "unable to alloc dnode - dnode tree will be corrupted"); hpfs_error(i->i_sb, "unable to alloc dnode - dnode tree will be corrupted");
hpfs_brelse4(&qbh); hpfs_brelse4(&qbh);
kfree(nd); kfree(nd);
...@@ -313,20 +313,21 @@ static int hpfs_add_to_dnode(struct inode *i, dnode_secno dno, ...@@ -313,20 +313,21 @@ static int hpfs_add_to_dnode(struct inode *i, dnode_secno dno,
down_ptr = adno; down_ptr = adno;
set_last_pointer(i->i_sb, ad, de->down ? de_down_pointer(de) : 0); set_last_pointer(i->i_sb, ad, de->down ? de_down_pointer(de) : 0);
de = de_next_de(de); de = de_next_de(de);
memmove((char *)nd + 20, de, nd->first_free + (char *)nd - (char *)de); memmove((char *)nd + 20, de, le32_to_cpu(nd->first_free) + (char *)nd - (char *)de);
nd->first_free -= (char *)de - (char *)nd - 20; nd->first_free = cpu_to_le32(le32_to_cpu(nd->first_free) - ((char *)de - (char *)nd - 20));
memcpy(d, nd, nd->first_free); memcpy(d, nd, le32_to_cpu(nd->first_free));
for_all_poss(i, hpfs_pos_del, (loff_t)dno << 4, pos); for_all_poss(i, hpfs_pos_del, (loff_t)dno << 4, pos);
fix_up_ptrs(i->i_sb, ad); fix_up_ptrs(i->i_sb, ad);
if (!d->root_dnode) { if (!d->root_dnode) {
dno = ad->up = d->up; ad->up = d->up;
dno = le32_to_cpu(ad->up);
hpfs_mark_4buffers_dirty(&qbh); hpfs_mark_4buffers_dirty(&qbh);
hpfs_brelse4(&qbh); hpfs_brelse4(&qbh);
hpfs_mark_4buffers_dirty(&qbh1); hpfs_mark_4buffers_dirty(&qbh1);
hpfs_brelse4(&qbh1); hpfs_brelse4(&qbh1);
goto go_up; goto go_up;
} }
if (!(rd = hpfs_alloc_dnode(i->i_sb, d->up, &rdno, &qbh2, 0))) { if (!(rd = hpfs_alloc_dnode(i->i_sb, le32_to_cpu(d->up), &rdno, &qbh2))) {
hpfs_error(i->i_sb, "unable to alloc dnode - dnode tree will be corrupted"); hpfs_error(i->i_sb, "unable to alloc dnode - dnode tree will be corrupted");
hpfs_brelse4(&qbh); hpfs_brelse4(&qbh);
hpfs_brelse4(&qbh1); hpfs_brelse4(&qbh1);
...@@ -338,7 +339,7 @@ static int hpfs_add_to_dnode(struct inode *i, dnode_secno dno, ...@@ -338,7 +339,7 @@ static int hpfs_add_to_dnode(struct inode *i, dnode_secno dno,
i->i_blocks += 4; i->i_blocks += 4;
rd->root_dnode = 1; rd->root_dnode = 1;
rd->up = d->up; rd->up = d->up;
if (!(fnode = hpfs_map_fnode(i->i_sb, d->up, &bh))) { if (!(fnode = hpfs_map_fnode(i->i_sb, le32_to_cpu(d->up), &bh))) {
hpfs_free_dnode(i->i_sb, rdno); hpfs_free_dnode(i->i_sb, rdno);
hpfs_brelse4(&qbh); hpfs_brelse4(&qbh);
hpfs_brelse4(&qbh1); hpfs_brelse4(&qbh1);
...@@ -347,10 +348,11 @@ static int hpfs_add_to_dnode(struct inode *i, dnode_secno dno, ...@@ -347,10 +348,11 @@ static int hpfs_add_to_dnode(struct inode *i, dnode_secno dno,
kfree(nname); kfree(nname);
return 1; return 1;
} }
fnode->u.external[0].disk_secno = rdno; fnode->u.external[0].disk_secno = cpu_to_le32(rdno);
mark_buffer_dirty(bh); mark_buffer_dirty(bh);
brelse(bh); brelse(bh);
d->up = ad->up = hpfs_i(i)->i_dno = rdno; hpfs_i(i)->i_dno = rdno;
d->up = ad->up = cpu_to_le32(rdno);
d->root_dnode = ad->root_dnode = 0; d->root_dnode = ad->root_dnode = 0;
hpfs_mark_4buffers_dirty(&qbh); hpfs_mark_4buffers_dirty(&qbh);
hpfs_brelse4(&qbh); hpfs_brelse4(&qbh);
...@@ -373,7 +375,7 @@ static int hpfs_add_to_dnode(struct inode *i, dnode_secno dno, ...@@ -373,7 +375,7 @@ static int hpfs_add_to_dnode(struct inode *i, dnode_secno dno,
int hpfs_add_dirent(struct inode *i, int hpfs_add_dirent(struct inode *i,
const unsigned char *name, unsigned namelen, const unsigned char *name, unsigned namelen,
struct hpfs_dirent *new_de, int cdepth) struct hpfs_dirent *new_de)
{ {
struct hpfs_inode_info *hpfs_inode = hpfs_i(i); struct hpfs_inode_info *hpfs_inode = hpfs_i(i);
struct dnode *d; struct dnode *d;
...@@ -403,7 +405,6 @@ int hpfs_add_dirent(struct inode *i, ...@@ -403,7 +405,6 @@ int hpfs_add_dirent(struct inode *i,
} }
} }
hpfs_brelse4(&qbh); hpfs_brelse4(&qbh);
if (!cdepth) hpfs_lock_creation(i->i_sb);
if (hpfs_check_free_dnodes(i->i_sb, FREE_DNODES_ADD)) { if (hpfs_check_free_dnodes(i->i_sb, FREE_DNODES_ADD)) {
c = 1; c = 1;
goto ret; goto ret;
...@@ -411,7 +412,6 @@ int hpfs_add_dirent(struct inode *i, ...@@ -411,7 +412,6 @@ int hpfs_add_dirent(struct inode *i,
i->i_version++; i->i_version++;
c = hpfs_add_to_dnode(i, dno, name, namelen, new_de, 0); c = hpfs_add_to_dnode(i, dno, name, namelen, new_de, 0);
ret: ret:
if (!cdepth) hpfs_unlock_creation(i->i_sb);
return c; return c;
} }
...@@ -437,9 +437,9 @@ static secno move_to_top(struct inode *i, dnode_secno from, dnode_secno to) ...@@ -437,9 +437,9 @@ static secno move_to_top(struct inode *i, dnode_secno from, dnode_secno to)
return 0; return 0;
if (!(dnode = hpfs_map_dnode(i->i_sb, dno, &qbh))) return 0; if (!(dnode = hpfs_map_dnode(i->i_sb, dno, &qbh))) return 0;
if (hpfs_sb(i->i_sb)->sb_chk) { if (hpfs_sb(i->i_sb)->sb_chk) {
if (dnode->up != chk_up) { if (le32_to_cpu(dnode->up) != chk_up) {
hpfs_error(i->i_sb, "move_to_top: up pointer from %08x should be %08x, is %08x", hpfs_error(i->i_sb, "move_to_top: up pointer from %08x should be %08x, is %08x",
dno, chk_up, dnode->up); dno, chk_up, le32_to_cpu(dnode->up));
hpfs_brelse4(&qbh); hpfs_brelse4(&qbh);
return 0; return 0;
} }
...@@ -455,7 +455,7 @@ static secno move_to_top(struct inode *i, dnode_secno from, dnode_secno to) ...@@ -455,7 +455,7 @@ static secno move_to_top(struct inode *i, dnode_secno from, dnode_secno to)
hpfs_brelse4(&qbh); hpfs_brelse4(&qbh);
} }
while (!(de = dnode_pre_last_de(dnode))) { while (!(de = dnode_pre_last_de(dnode))) {
dnode_secno up = dnode->up; dnode_secno up = le32_to_cpu(dnode->up);
hpfs_brelse4(&qbh); hpfs_brelse4(&qbh);
hpfs_free_dnode(i->i_sb, dno); hpfs_free_dnode(i->i_sb, dno);
i->i_size -= 2048; i->i_size -= 2048;
...@@ -474,8 +474,8 @@ static secno move_to_top(struct inode *i, dnode_secno from, dnode_secno to) ...@@ -474,8 +474,8 @@ static secno move_to_top(struct inode *i, dnode_secno from, dnode_secno to)
hpfs_brelse4(&qbh); hpfs_brelse4(&qbh);
return 0; return 0;
} }
dnode->first_free -= 4; dnode->first_free = cpu_to_le32(le32_to_cpu(dnode->first_free) - 4);
de->length -= 4; de->length = cpu_to_le16(le16_to_cpu(de->length) - 4);
de->down = 0; de->down = 0;
hpfs_mark_4buffers_dirty(&qbh); hpfs_mark_4buffers_dirty(&qbh);
dno = up; dno = up;
...@@ -483,12 +483,12 @@ static secno move_to_top(struct inode *i, dnode_secno from, dnode_secno to) ...@@ -483,12 +483,12 @@ static secno move_to_top(struct inode *i, dnode_secno from, dnode_secno to)
t = get_pos(dnode, de); t = get_pos(dnode, de);
for_all_poss(i, hpfs_pos_subst, t, 4); for_all_poss(i, hpfs_pos_subst, t, 4);
for_all_poss(i, hpfs_pos_subst, t + 1, 5); for_all_poss(i, hpfs_pos_subst, t + 1, 5);
if (!(nde = kmalloc(de->length, GFP_NOFS))) { if (!(nde = kmalloc(le16_to_cpu(de->length), GFP_NOFS))) {
hpfs_error(i->i_sb, "out of memory for dirent - directory will be corrupted"); hpfs_error(i->i_sb, "out of memory for dirent - directory will be corrupted");
hpfs_brelse4(&qbh); hpfs_brelse4(&qbh);
return 0; return 0;
} }
memcpy(nde, de, de->length); memcpy(nde, de, le16_to_cpu(de->length));
ddno = de->down ? de_down_pointer(de) : 0; ddno = de->down ? de_down_pointer(de) : 0;
hpfs_delete_de(i->i_sb, dnode, de); hpfs_delete_de(i->i_sb, dnode, de);
set_last_pointer(i->i_sb, dnode, ddno); set_last_pointer(i->i_sb, dnode, ddno);
...@@ -517,11 +517,11 @@ static void delete_empty_dnode(struct inode *i, dnode_secno dno) ...@@ -517,11 +517,11 @@ static void delete_empty_dnode(struct inode *i, dnode_secno dno)
try_it_again: try_it_again:
if (hpfs_stop_cycles(i->i_sb, dno, &c1, &c2, "delete_empty_dnode")) return; if (hpfs_stop_cycles(i->i_sb, dno, &c1, &c2, "delete_empty_dnode")) return;
if (!(dnode = hpfs_map_dnode(i->i_sb, dno, &qbh))) return; if (!(dnode = hpfs_map_dnode(i->i_sb, dno, &qbh))) return;
if (dnode->first_free > 56) goto end; if (le32_to_cpu(dnode->first_free) > 56) goto end;
if (dnode->first_free == 52 || dnode->first_free == 56) { if (le32_to_cpu(dnode->first_free) == 52 || le32_to_cpu(dnode->first_free) == 56) {
struct hpfs_dirent *de_end; struct hpfs_dirent *de_end;
int root = dnode->root_dnode; int root = dnode->root_dnode;
up = dnode->up; up = le32_to_cpu(dnode->up);
de = dnode_first_de(dnode); de = dnode_first_de(dnode);
down = de->down ? de_down_pointer(de) : 0; down = de->down ? de_down_pointer(de) : 0;
if (hpfs_sb(i->i_sb)->sb_chk) if (root && !down) { if (hpfs_sb(i->i_sb)->sb_chk) if (root && !down) {
...@@ -545,13 +545,13 @@ static void delete_empty_dnode(struct inode *i, dnode_secno dno) ...@@ -545,13 +545,13 @@ static void delete_empty_dnode(struct inode *i, dnode_secno dno)
return; return;
} }
if ((d1 = hpfs_map_dnode(i->i_sb, down, &qbh1))) { if ((d1 = hpfs_map_dnode(i->i_sb, down, &qbh1))) {
d1->up = up; d1->up = cpu_to_le32(up);
d1->root_dnode = 1; d1->root_dnode = 1;
hpfs_mark_4buffers_dirty(&qbh1); hpfs_mark_4buffers_dirty(&qbh1);
hpfs_brelse4(&qbh1); hpfs_brelse4(&qbh1);
} }
if ((fnode = hpfs_map_fnode(i->i_sb, up, &bh))) { if ((fnode = hpfs_map_fnode(i->i_sb, up, &bh))) {
fnode->u.external[0].disk_secno = down; fnode->u.external[0].disk_secno = cpu_to_le32(down);
mark_buffer_dirty(bh); mark_buffer_dirty(bh);
brelse(bh); brelse(bh);
} }
...@@ -570,22 +570,22 @@ static void delete_empty_dnode(struct inode *i, dnode_secno dno) ...@@ -570,22 +570,22 @@ static void delete_empty_dnode(struct inode *i, dnode_secno dno)
for_all_poss(i, hpfs_pos_subst, ((loff_t)dno << 4) | 1, ((loff_t)up << 4) | p); for_all_poss(i, hpfs_pos_subst, ((loff_t)dno << 4) | 1, ((loff_t)up << 4) | p);
if (!down) { if (!down) {
de->down = 0; de->down = 0;
de->length -= 4; de->length = cpu_to_le16(le16_to_cpu(de->length) - 4);
dnode->first_free -= 4; dnode->first_free = cpu_to_le32(le32_to_cpu(dnode->first_free) - 4);
memmove(de_next_de(de), (char *)de_next_de(de) + 4, memmove(de_next_de(de), (char *)de_next_de(de) + 4,
(char *)dnode + dnode->first_free - (char *)de_next_de(de)); (char *)dnode + le32_to_cpu(dnode->first_free) - (char *)de_next_de(de));
} else { } else {
struct dnode *d1; struct dnode *d1;
struct quad_buffer_head qbh1; struct quad_buffer_head qbh1;
*(dnode_secno *) ((void *) de + de->length - 4) = down; *(dnode_secno *) ((void *) de + le16_to_cpu(de->length) - 4) = down;
if ((d1 = hpfs_map_dnode(i->i_sb, down, &qbh1))) { if ((d1 = hpfs_map_dnode(i->i_sb, down, &qbh1))) {
d1->up = up; d1->up = cpu_to_le32(up);
hpfs_mark_4buffers_dirty(&qbh1); hpfs_mark_4buffers_dirty(&qbh1);
hpfs_brelse4(&qbh1); hpfs_brelse4(&qbh1);
} }
} }
} else { } else {
hpfs_error(i->i_sb, "delete_empty_dnode: dnode %08x, first_free == %03x", dno, dnode->first_free); hpfs_error(i->i_sb, "delete_empty_dnode: dnode %08x, first_free == %03x", dno, le32_to_cpu(dnode->first_free));
goto end; goto end;
} }
...@@ -596,18 +596,18 @@ static void delete_empty_dnode(struct inode *i, dnode_secno dno) ...@@ -596,18 +596,18 @@ static void delete_empty_dnode(struct inode *i, dnode_secno dno)
struct quad_buffer_head qbh1; struct quad_buffer_head qbh1;
if (!de_next->down) goto endm; if (!de_next->down) goto endm;
ndown = de_down_pointer(de_next); ndown = de_down_pointer(de_next);
if (!(de_cp = kmalloc(de->length, GFP_NOFS))) { if (!(de_cp = kmalloc(le16_to_cpu(de->length), GFP_NOFS))) {
printk("HPFS: out of memory for dtree balancing\n"); printk("HPFS: out of memory for dtree balancing\n");
goto endm; goto endm;
} }
memcpy(de_cp, de, de->length); memcpy(de_cp, de, le16_to_cpu(de->length));
hpfs_delete_de(i->i_sb, dnode, de); hpfs_delete_de(i->i_sb, dnode, de);
hpfs_mark_4buffers_dirty(&qbh); hpfs_mark_4buffers_dirty(&qbh);
hpfs_brelse4(&qbh); hpfs_brelse4(&qbh);
for_all_poss(i, hpfs_pos_subst, ((loff_t)up << 4) | p, 4); for_all_poss(i, hpfs_pos_subst, ((loff_t)up << 4) | p, 4);
for_all_poss(i, hpfs_pos_del, ((loff_t)up << 4) | p, 1); for_all_poss(i, hpfs_pos_del, ((loff_t)up << 4) | p, 1);
if (de_cp->down) if ((d1 = hpfs_map_dnode(i->i_sb, de_down_pointer(de_cp), &qbh1))) { if (de_cp->down) if ((d1 = hpfs_map_dnode(i->i_sb, de_down_pointer(de_cp), &qbh1))) {
d1->up = ndown; d1->up = cpu_to_le32(ndown);
hpfs_mark_4buffers_dirty(&qbh1); hpfs_mark_4buffers_dirty(&qbh1);
hpfs_brelse4(&qbh1); hpfs_brelse4(&qbh1);
} }
...@@ -635,7 +635,7 @@ static void delete_empty_dnode(struct inode *i, dnode_secno dno) ...@@ -635,7 +635,7 @@ static void delete_empty_dnode(struct inode *i, dnode_secno dno)
struct hpfs_dirent *del = dnode_last_de(d1); struct hpfs_dirent *del = dnode_last_de(d1);
dlp = del->down ? de_down_pointer(del) : 0; dlp = del->down ? de_down_pointer(del) : 0;
if (!dlp && down) { if (!dlp && down) {
if (d1->first_free > 2044) { if (le32_to_cpu(d1->first_free) > 2044) {
if (hpfs_sb(i->i_sb)->sb_chk >= 2) { if (hpfs_sb(i->i_sb)->sb_chk >= 2) {
printk("HPFS: warning: unbalanced dnode tree, see hpfs.txt 4 more info\n"); printk("HPFS: warning: unbalanced dnode tree, see hpfs.txt 4 more info\n");
printk("HPFS: warning: terminating balancing operation\n"); printk("HPFS: warning: terminating balancing operation\n");
...@@ -647,38 +647,38 @@ static void delete_empty_dnode(struct inode *i, dnode_secno dno) ...@@ -647,38 +647,38 @@ static void delete_empty_dnode(struct inode *i, dnode_secno dno)
printk("HPFS: warning: unbalanced dnode tree, see hpfs.txt 4 more info\n"); printk("HPFS: warning: unbalanced dnode tree, see hpfs.txt 4 more info\n");
printk("HPFS: warning: goin'on\n"); printk("HPFS: warning: goin'on\n");
} }
del->length += 4; del->length = cpu_to_le16(le16_to_cpu(del->length) + 4);
del->down = 1; del->down = 1;
d1->first_free += 4; d1->first_free = cpu_to_le32(le32_to_cpu(d1->first_free) + 4);
} }
if (dlp && !down) { if (dlp && !down) {
del->length -= 4; del->length = cpu_to_le16(le16_to_cpu(del->length) - 4);
del->down = 0; del->down = 0;
d1->first_free -= 4; d1->first_free = cpu_to_le32(le32_to_cpu(d1->first_free) - 4);
} else if (down) } else if (down)
*(dnode_secno *) ((void *) del + del->length - 4) = down; *(dnode_secno *) ((void *) del + le16_to_cpu(del->length) - 4) = cpu_to_le32(down);
} else goto endm; } else goto endm;
if (!(de_cp = kmalloc(de_prev->length, GFP_NOFS))) { if (!(de_cp = kmalloc(le16_to_cpu(de_prev->length), GFP_NOFS))) {
printk("HPFS: out of memory for dtree balancing\n"); printk("HPFS: out of memory for dtree balancing\n");
hpfs_brelse4(&qbh1); hpfs_brelse4(&qbh1);
goto endm; goto endm;
} }
hpfs_mark_4buffers_dirty(&qbh1); hpfs_mark_4buffers_dirty(&qbh1);
hpfs_brelse4(&qbh1); hpfs_brelse4(&qbh1);
memcpy(de_cp, de_prev, de_prev->length); memcpy(de_cp, de_prev, le16_to_cpu(de_prev->length));
hpfs_delete_de(i->i_sb, dnode, de_prev); hpfs_delete_de(i->i_sb, dnode, de_prev);
if (!de_prev->down) { if (!de_prev->down) {
de_prev->length += 4; de_prev->length = cpu_to_le16(le16_to_cpu(de_prev->length) + 4);
de_prev->down = 1; de_prev->down = 1;
dnode->first_free += 4; dnode->first_free = cpu_to_le32(le32_to_cpu(dnode->first_free) + 4);
} }
*(dnode_secno *) ((void *) de_prev + de_prev->length - 4) = ndown; *(dnode_secno *) ((void *) de_prev + le16_to_cpu(de_prev->length) - 4) = cpu_to_le32(ndown);
hpfs_mark_4buffers_dirty(&qbh); hpfs_mark_4buffers_dirty(&qbh);
hpfs_brelse4(&qbh); hpfs_brelse4(&qbh);
for_all_poss(i, hpfs_pos_subst, ((loff_t)up << 4) | (p - 1), 4); for_all_poss(i, hpfs_pos_subst, ((loff_t)up << 4) | (p - 1), 4);
for_all_poss(i, hpfs_pos_subst, ((loff_t)up << 4) | p, ((loff_t)up << 4) | (p - 1)); for_all_poss(i, hpfs_pos_subst, ((loff_t)up << 4) | p, ((loff_t)up << 4) | (p - 1));
if (down) if ((d1 = hpfs_map_dnode(i->i_sb, de_down_pointer(de), &qbh1))) { if (down) if ((d1 = hpfs_map_dnode(i->i_sb, de_down_pointer(de), &qbh1))) {
d1->up = ndown; d1->up = cpu_to_le32(ndown);
hpfs_mark_4buffers_dirty(&qbh1); hpfs_mark_4buffers_dirty(&qbh1);
hpfs_brelse4(&qbh1); hpfs_brelse4(&qbh1);
} }
...@@ -701,7 +701,6 @@ int hpfs_remove_dirent(struct inode *i, dnode_secno dno, struct hpfs_dirent *de, ...@@ -701,7 +701,6 @@ int hpfs_remove_dirent(struct inode *i, dnode_secno dno, struct hpfs_dirent *de,
{ {
struct dnode *dnode = qbh->data; struct dnode *dnode = qbh->data;
dnode_secno down = 0; dnode_secno down = 0;
int lock = 0;
loff_t t; loff_t t;
if (de->first || de->last) { if (de->first || de->last) {
hpfs_error(i->i_sb, "hpfs_remove_dirent: attempt to delete first or last dirent in dnode %08x", dno); hpfs_error(i->i_sb, "hpfs_remove_dirent: attempt to delete first or last dirent in dnode %08x", dno);
...@@ -710,11 +709,8 @@ int hpfs_remove_dirent(struct inode *i, dnode_secno dno, struct hpfs_dirent *de, ...@@ -710,11 +709,8 @@ int hpfs_remove_dirent(struct inode *i, dnode_secno dno, struct hpfs_dirent *de,
} }
if (de->down) down = de_down_pointer(de); if (de->down) down = de_down_pointer(de);
if (depth && (de->down || (de == dnode_first_de(dnode) && de_next_de(de)->last))) { if (depth && (de->down || (de == dnode_first_de(dnode) && de_next_de(de)->last))) {
lock = 1;
hpfs_lock_creation(i->i_sb);
if (hpfs_check_free_dnodes(i->i_sb, FREE_DNODES_DEL)) { if (hpfs_check_free_dnodes(i->i_sb, FREE_DNODES_DEL)) {
hpfs_brelse4(qbh); hpfs_brelse4(qbh);
hpfs_unlock_creation(i->i_sb);
return 2; return 2;
} }
} }
...@@ -727,11 +723,9 @@ int hpfs_remove_dirent(struct inode *i, dnode_secno dno, struct hpfs_dirent *de, ...@@ -727,11 +723,9 @@ int hpfs_remove_dirent(struct inode *i, dnode_secno dno, struct hpfs_dirent *de,
dnode_secno a = move_to_top(i, down, dno); dnode_secno a = move_to_top(i, down, dno);
for_all_poss(i, hpfs_pos_subst, 5, t); for_all_poss(i, hpfs_pos_subst, 5, t);
if (a) delete_empty_dnode(i, a); if (a) delete_empty_dnode(i, a);
if (lock) hpfs_unlock_creation(i->i_sb);
return !a; return !a;
} }
delete_empty_dnode(i, dno); delete_empty_dnode(i, dno);
if (lock) hpfs_unlock_creation(i->i_sb);
return 0; return 0;
} }
...@@ -751,8 +745,8 @@ void hpfs_count_dnodes(struct super_block *s, dnode_secno dno, int *n_dnodes, ...@@ -751,8 +745,8 @@ void hpfs_count_dnodes(struct super_block *s, dnode_secno dno, int *n_dnodes,
ptr = 0; ptr = 0;
go_up: go_up:
if (!(dnode = hpfs_map_dnode(s, dno, &qbh))) return; if (!(dnode = hpfs_map_dnode(s, dno, &qbh))) return;
if (hpfs_sb(s)->sb_chk) if (odno && odno != -1 && dnode->up != odno) if (hpfs_sb(s)->sb_chk) if (odno && odno != -1 && le32_to_cpu(dnode->up) != odno)
hpfs_error(s, "hpfs_count_dnodes: bad up pointer; dnode %08x, down %08x points to %08x", odno, dno, dnode->up); hpfs_error(s, "hpfs_count_dnodes: bad up pointer; dnode %08x, down %08x points to %08x", odno, dno, le32_to_cpu(dnode->up));
de = dnode_first_de(dnode); de = dnode_first_de(dnode);
if (ptr) while(1) { if (ptr) while(1) {
if (de->down) if (de_down_pointer(de) == ptr) goto process_de; if (de->down) if (de_down_pointer(de) == ptr) goto process_de;
...@@ -776,7 +770,7 @@ void hpfs_count_dnodes(struct super_block *s, dnode_secno dno, int *n_dnodes, ...@@ -776,7 +770,7 @@ void hpfs_count_dnodes(struct super_block *s, dnode_secno dno, int *n_dnodes,
if (!de->first && !de->last && n_items) (*n_items)++; if (!de->first && !de->last && n_items) (*n_items)++;
if ((de = de_next_de(de)) < dnode_end_de(dnode)) goto next_de; if ((de = de_next_de(de)) < dnode_end_de(dnode)) goto next_de;
ptr = dno; ptr = dno;
dno = dnode->up; dno = le32_to_cpu(dnode->up);
if (dnode->root_dnode) { if (dnode->root_dnode) {
hpfs_brelse4(&qbh); hpfs_brelse4(&qbh);
return; return;
...@@ -824,8 +818,8 @@ dnode_secno hpfs_de_as_down_as_possible(struct super_block *s, dnode_secno dno) ...@@ -824,8 +818,8 @@ dnode_secno hpfs_de_as_down_as_possible(struct super_block *s, dnode_secno dno)
return d; return d;
if (!(de = map_nth_dirent(s, d, 1, &qbh, NULL))) return dno; if (!(de = map_nth_dirent(s, d, 1, &qbh, NULL))) return dno;
if (hpfs_sb(s)->sb_chk) if (hpfs_sb(s)->sb_chk)
if (up && ((struct dnode *)qbh.data)->up != up) if (up && le32_to_cpu(((struct dnode *)qbh.data)->up) != up)
hpfs_error(s, "hpfs_de_as_down_as_possible: bad up pointer; dnode %08x, down %08x points to %08x", up, d, ((struct dnode *)qbh.data)->up); hpfs_error(s, "hpfs_de_as_down_as_possible: bad up pointer; dnode %08x, down %08x points to %08x", up, d, le32_to_cpu(((struct dnode *)qbh.data)->up));
if (!de->down) { if (!de->down) {
hpfs_brelse4(&qbh); hpfs_brelse4(&qbh);
return d; return d;
...@@ -874,7 +868,7 @@ struct hpfs_dirent *map_pos_dirent(struct inode *inode, loff_t *posp, ...@@ -874,7 +868,7 @@ struct hpfs_dirent *map_pos_dirent(struct inode *inode, loff_t *posp,
/* Going up */ /* Going up */
if (dnode->root_dnode) goto bail; if (dnode->root_dnode) goto bail;
if (!(up_dnode = hpfs_map_dnode(inode->i_sb, dnode->up, &qbh0))) if (!(up_dnode = hpfs_map_dnode(inode->i_sb, le32_to_cpu(dnode->up), &qbh0)))
goto bail; goto bail;
end_up_de = dnode_end_de(up_dnode); end_up_de = dnode_end_de(up_dnode);
...@@ -882,16 +876,16 @@ struct hpfs_dirent *map_pos_dirent(struct inode *inode, loff_t *posp, ...@@ -882,16 +876,16 @@ struct hpfs_dirent *map_pos_dirent(struct inode *inode, loff_t *posp,
for (up_de = dnode_first_de(up_dnode); up_de < end_up_de; for (up_de = dnode_first_de(up_dnode); up_de < end_up_de;
up_de = de_next_de(up_de)) { up_de = de_next_de(up_de)) {
if (!(++c & 077)) hpfs_error(inode->i_sb, if (!(++c & 077)) hpfs_error(inode->i_sb,
"map_pos_dirent: pos crossed dnode boundary; dnode = %08x", dnode->up); "map_pos_dirent: pos crossed dnode boundary; dnode = %08x", le32_to_cpu(dnode->up));
if (up_de->down && de_down_pointer(up_de) == dno) { if (up_de->down && de_down_pointer(up_de) == dno) {
*posp = ((loff_t) dnode->up << 4) + c; *posp = ((loff_t) le32_to_cpu(dnode->up) << 4) + c;
hpfs_brelse4(&qbh0); hpfs_brelse4(&qbh0);
return de; return de;
} }
} }
hpfs_error(inode->i_sb, "map_pos_dirent: pointer to dnode %08x not found in parent dnode %08x", hpfs_error(inode->i_sb, "map_pos_dirent: pointer to dnode %08x not found in parent dnode %08x",
dno, dnode->up); dno, le32_to_cpu(dnode->up));
hpfs_brelse4(&qbh0); hpfs_brelse4(&qbh0);
bail: bail:
...@@ -1017,17 +1011,17 @@ struct hpfs_dirent *map_fnode_dirent(struct super_block *s, fnode_secno fno, ...@@ -1017,17 +1011,17 @@ struct hpfs_dirent *map_fnode_dirent(struct super_block *s, fnode_secno fno,
/*name2[15] = 0xff;*/ /*name2[15] = 0xff;*/
name1len = 15; name2len = 256; name1len = 15; name2len = 256;
} }
if (!(upf = hpfs_map_fnode(s, f->up, &bh))) { if (!(upf = hpfs_map_fnode(s, le32_to_cpu(f->up), &bh))) {
kfree(name2); kfree(name2);
return NULL; return NULL;
} }
if (!upf->dirflag) { if (!upf->dirflag) {
brelse(bh); brelse(bh);
hpfs_error(s, "fnode %08x has non-directory parent %08x", fno, f->up); hpfs_error(s, "fnode %08x has non-directory parent %08x", fno, le32_to_cpu(f->up));
kfree(name2); kfree(name2);
return NULL; return NULL;
} }
dno = upf->u.external[0].disk_secno; dno = le32_to_cpu(upf->u.external[0].disk_secno);
brelse(bh); brelse(bh);
go_down: go_down:
downd = 0; downd = 0;
...@@ -1049,7 +1043,7 @@ struct hpfs_dirent *map_fnode_dirent(struct super_block *s, fnode_secno fno, ...@@ -1049,7 +1043,7 @@ struct hpfs_dirent *map_fnode_dirent(struct super_block *s, fnode_secno fno,
return NULL; return NULL;
} }
next_de: next_de:
if (de->fnode == fno) { if (le32_to_cpu(de->fnode) == fno) {
kfree(name2); kfree(name2);
return de; return de;
} }
...@@ -1065,7 +1059,7 @@ struct hpfs_dirent *map_fnode_dirent(struct super_block *s, fnode_secno fno, ...@@ -1065,7 +1059,7 @@ struct hpfs_dirent *map_fnode_dirent(struct super_block *s, fnode_secno fno,
goto go_down; goto go_down;
} }
f: f:
if (de->fnode == fno) { if (le32_to_cpu(de->fnode) == fno) {
kfree(name2); kfree(name2);
return de; return de;
} }
...@@ -1074,7 +1068,7 @@ struct hpfs_dirent *map_fnode_dirent(struct super_block *s, fnode_secno fno, ...@@ -1074,7 +1068,7 @@ struct hpfs_dirent *map_fnode_dirent(struct super_block *s, fnode_secno fno,
if ((de = de_next_de(de)) < de_end) goto next_de; if ((de = de_next_de(de)) < de_end) goto next_de;
if (d->root_dnode) goto not_found; if (d->root_dnode) goto not_found;
downd = dno; downd = dno;
dno = d->up; dno = le32_to_cpu(d->up);
hpfs_brelse4(qbh); hpfs_brelse4(qbh);
if (hpfs_sb(s)->sb_chk) if (hpfs_sb(s)->sb_chk)
if (hpfs_stop_cycles(s, downd, &d1, &d2, "map_fnode_dirent #2")) { if (hpfs_stop_cycles(s, downd, &d1, &d2, "map_fnode_dirent #2")) {
......
...@@ -24,7 +24,7 @@ void hpfs_ea_ext_remove(struct super_block *s, secno a, int ano, unsigned len) ...@@ -24,7 +24,7 @@ void hpfs_ea_ext_remove(struct super_block *s, secno a, int ano, unsigned len)
} }
if (hpfs_ea_read(s, a, ano, pos, 4, ex)) return; if (hpfs_ea_read(s, a, ano, pos, 4, ex)) return;
if (ea->indirect) { if (ea->indirect) {
if (ea->valuelen != 8) { if (ea_valuelen(ea) != 8) {
hpfs_error(s, "ea->indirect set while ea->valuelen!=8, %s %08x, pos %08x", hpfs_error(s, "ea->indirect set while ea->valuelen!=8, %s %08x, pos %08x",
ano ? "anode" : "sectors", a, pos); ano ? "anode" : "sectors", a, pos);
return; return;
...@@ -33,7 +33,7 @@ void hpfs_ea_ext_remove(struct super_block *s, secno a, int ano, unsigned len) ...@@ -33,7 +33,7 @@ void hpfs_ea_ext_remove(struct super_block *s, secno a, int ano, unsigned len)
return; return;
hpfs_ea_remove(s, ea_sec(ea), ea->anode, ea_len(ea)); hpfs_ea_remove(s, ea_sec(ea), ea->anode, ea_len(ea));
} }
pos += ea->namelen + ea->valuelen + 5; pos += ea->namelen + ea_valuelen(ea) + 5;
} }
if (!ano) hpfs_free_sectors(s, a, (len+511) >> 9); if (!ano) hpfs_free_sectors(s, a, (len+511) >> 9);
else { else {
...@@ -76,24 +76,24 @@ int hpfs_read_ea(struct super_block *s, struct fnode *fnode, char *key, ...@@ -76,24 +76,24 @@ int hpfs_read_ea(struct super_block *s, struct fnode *fnode, char *key,
unsigned pos; unsigned pos;
int ano, len; int ano, len;
secno a; secno a;
char ex[4 + 255 + 1 + 8];
struct extended_attribute *ea; struct extended_attribute *ea;
struct extended_attribute *ea_end = fnode_end_ea(fnode); struct extended_attribute *ea_end = fnode_end_ea(fnode);
for (ea = fnode_ea(fnode); ea < ea_end; ea = next_ea(ea)) for (ea = fnode_ea(fnode); ea < ea_end; ea = next_ea(ea))
if (!strcmp(ea->name, key)) { if (!strcmp(ea->name, key)) {
if (ea->indirect) if (ea->indirect)
goto indirect; goto indirect;
if (ea->valuelen >= size) if (ea_valuelen(ea) >= size)
return -EINVAL; return -EINVAL;
memcpy(buf, ea_data(ea), ea->valuelen); memcpy(buf, ea_data(ea), ea_valuelen(ea));
buf[ea->valuelen] = 0; buf[ea_valuelen(ea)] = 0;
return 0; return 0;
} }
a = fnode->ea_secno; a = le32_to_cpu(fnode->ea_secno);
len = fnode->ea_size_l; len = le32_to_cpu(fnode->ea_size_l);
ano = fnode->ea_anode; ano = fnode->ea_anode;
pos = 0; pos = 0;
while (pos < len) { while (pos < len) {
char ex[4 + 255 + 1 + 8];
ea = (struct extended_attribute *)ex; ea = (struct extended_attribute *)ex;
if (pos + 4 > len) { if (pos + 4 > len) {
hpfs_error(s, "EAs don't end correctly, %s %08x, len %08x", hpfs_error(s, "EAs don't end correctly, %s %08x, len %08x",
...@@ -106,14 +106,14 @@ int hpfs_read_ea(struct super_block *s, struct fnode *fnode, char *key, ...@@ -106,14 +106,14 @@ int hpfs_read_ea(struct super_block *s, struct fnode *fnode, char *key,
if (!strcmp(ea->name, key)) { if (!strcmp(ea->name, key)) {
if (ea->indirect) if (ea->indirect)
goto indirect; goto indirect;
if (ea->valuelen >= size) if (ea_valuelen(ea) >= size)
return -EINVAL; return -EINVAL;
if (hpfs_ea_read(s, a, ano, pos + 4 + ea->namelen + 1, ea->valuelen, buf)) if (hpfs_ea_read(s, a, ano, pos + 4 + ea->namelen + 1, ea_valuelen(ea), buf))
return -EIO; return -EIO;
buf[ea->valuelen] = 0; buf[ea_valuelen(ea)] = 0;
return 0; return 0;
} }
pos += ea->namelen + ea->valuelen + 5; pos += ea->namelen + ea_valuelen(ea) + 5;
} }
return -ENOENT; return -ENOENT;
indirect: indirect:
...@@ -138,16 +138,16 @@ char *hpfs_get_ea(struct super_block *s, struct fnode *fnode, char *key, int *si ...@@ -138,16 +138,16 @@ char *hpfs_get_ea(struct super_block *s, struct fnode *fnode, char *key, int *si
if (!strcmp(ea->name, key)) { if (!strcmp(ea->name, key)) {
if (ea->indirect) if (ea->indirect)
return get_indirect_ea(s, ea->anode, ea_sec(ea), *size = ea_len(ea)); return get_indirect_ea(s, ea->anode, ea_sec(ea), *size = ea_len(ea));
if (!(ret = kmalloc((*size = ea->valuelen) + 1, GFP_NOFS))) { if (!(ret = kmalloc((*size = ea_valuelen(ea)) + 1, GFP_NOFS))) {
printk("HPFS: out of memory for EA\n"); printk("HPFS: out of memory for EA\n");
return NULL; return NULL;
} }
memcpy(ret, ea_data(ea), ea->valuelen); memcpy(ret, ea_data(ea), ea_valuelen(ea));
ret[ea->valuelen] = 0; ret[ea_valuelen(ea)] = 0;
return ret; return ret;
} }
a = fnode->ea_secno; a = le32_to_cpu(fnode->ea_secno);
len = fnode->ea_size_l; len = le32_to_cpu(fnode->ea_size_l);
ano = fnode->ea_anode; ano = fnode->ea_anode;
pos = 0; pos = 0;
while (pos < len) { while (pos < len) {
...@@ -164,18 +164,18 @@ char *hpfs_get_ea(struct super_block *s, struct fnode *fnode, char *key, int *si ...@@ -164,18 +164,18 @@ char *hpfs_get_ea(struct super_block *s, struct fnode *fnode, char *key, int *si
if (!strcmp(ea->name, key)) { if (!strcmp(ea->name, key)) {
if (ea->indirect) if (ea->indirect)
return get_indirect_ea(s, ea->anode, ea_sec(ea), *size = ea_len(ea)); return get_indirect_ea(s, ea->anode, ea_sec(ea), *size = ea_len(ea));
if (!(ret = kmalloc((*size = ea->valuelen) + 1, GFP_NOFS))) { if (!(ret = kmalloc((*size = ea_valuelen(ea)) + 1, GFP_NOFS))) {
printk("HPFS: out of memory for EA\n"); printk("HPFS: out of memory for EA\n");
return NULL; return NULL;
} }
if (hpfs_ea_read(s, a, ano, pos + 4 + ea->namelen + 1, ea->valuelen, ret)) { if (hpfs_ea_read(s, a, ano, pos + 4 + ea->namelen + 1, ea_valuelen(ea), ret)) {
kfree(ret); kfree(ret);
return NULL; return NULL;
} }
ret[ea->valuelen] = 0; ret[ea_valuelen(ea)] = 0;
return ret; return ret;
} }
pos += ea->namelen + ea->valuelen + 5; pos += ea->namelen + ea_valuelen(ea) + 5;
} }
return NULL; return NULL;
} }
...@@ -202,13 +202,13 @@ void hpfs_set_ea(struct inode *inode, struct fnode *fnode, const char *key, ...@@ -202,13 +202,13 @@ void hpfs_set_ea(struct inode *inode, struct fnode *fnode, const char *key,
if (ea->indirect) { if (ea->indirect) {
if (ea_len(ea) == size) if (ea_len(ea) == size)
set_indirect_ea(s, ea->anode, ea_sec(ea), data, size); set_indirect_ea(s, ea->anode, ea_sec(ea), data, size);
} else if (ea->valuelen == size) { } else if (ea_valuelen(ea) == size) {
memcpy(ea_data(ea), data, size); memcpy(ea_data(ea), data, size);
} }
return; return;
} }
a = fnode->ea_secno; a = le32_to_cpu(fnode->ea_secno);
len = fnode->ea_size_l; len = le32_to_cpu(fnode->ea_size_l);
ano = fnode->ea_anode; ano = fnode->ea_anode;
pos = 0; pos = 0;
while (pos < len) { while (pos < len) {
...@@ -228,68 +228,70 @@ void hpfs_set_ea(struct inode *inode, struct fnode *fnode, const char *key, ...@@ -228,68 +228,70 @@ void hpfs_set_ea(struct inode *inode, struct fnode *fnode, const char *key,
set_indirect_ea(s, ea->anode, ea_sec(ea), data, size); set_indirect_ea(s, ea->anode, ea_sec(ea), data, size);
} }
else { else {
if (ea->valuelen == size) if (ea_valuelen(ea) == size)
hpfs_ea_write(s, a, ano, pos + 4 + ea->namelen + 1, size, data); hpfs_ea_write(s, a, ano, pos + 4 + ea->namelen + 1, size, data);
} }
return; return;
} }
pos += ea->namelen + ea->valuelen + 5; pos += ea->namelen + ea_valuelen(ea) + 5;
} }
if (!fnode->ea_offs) { if (!le16_to_cpu(fnode->ea_offs)) {
/*if (fnode->ea_size_s) { /*if (le16_to_cpu(fnode->ea_size_s)) {
hpfs_error(s, "fnode %08x: ea_size_s == %03x, ea_offs == 0", hpfs_error(s, "fnode %08x: ea_size_s == %03x, ea_offs == 0",
inode->i_ino, fnode->ea_size_s); inode->i_ino, le16_to_cpu(fnode->ea_size_s));
return; return;
}*/ }*/
fnode->ea_offs = 0xc4; fnode->ea_offs = cpu_to_le16(0xc4);
} }
if (fnode->ea_offs < 0xc4 || fnode->ea_offs + fnode->acl_size_s + fnode->ea_size_s > 0x200) { 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", hpfs_error(s, "fnode %08lx: ea_offs == %03x, ea_size_s == %03x",
(unsigned long)inode->i_ino, (unsigned long)inode->i_ino,
fnode->ea_offs, fnode->ea_size_s); le32_to_cpu(fnode->ea_offs), le16_to_cpu(fnode->ea_size_s));
return; return;
} }
if ((fnode->ea_size_s || !fnode->ea_size_l) && if ((le16_to_cpu(fnode->ea_size_s) || !le32_to_cpu(fnode->ea_size_l)) &&
fnode->ea_offs + fnode->acl_size_s + fnode->ea_size_s + strlen(key) + size + 5 <= 0x200) { le16_to_cpu(fnode->ea_offs) + le16_to_cpu(fnode->acl_size_s) + le16_to_cpu(fnode->ea_size_s) + strlen(key) + size + 5 <= 0x200) {
ea = fnode_end_ea(fnode); ea = fnode_end_ea(fnode);
*(char *)ea = 0; *(char *)ea = 0;
ea->namelen = strlen(key); ea->namelen = strlen(key);
ea->valuelen = size; ea->valuelen_lo = size;
ea->valuelen_hi = size >> 8;
strcpy(ea->name, key); strcpy(ea->name, key);
memcpy(ea_data(ea), data, size); memcpy(ea_data(ea), data, size);
fnode->ea_size_s += strlen(key) + size + 5; fnode->ea_size_s = cpu_to_le16(le16_to_cpu(fnode->ea_size_s) + strlen(key) + size + 5);
goto ret; goto ret;
} }
/* Most the code here is 99.9993422% unused. I hope there are no bugs. /* Most the code here is 99.9993422% unused. I hope there are no bugs.
But what .. HPFS.IFS has also bugs in ea management. */ But what .. HPFS.IFS has also bugs in ea management. */
if (fnode->ea_size_s && !fnode->ea_size_l) { if (le16_to_cpu(fnode->ea_size_s) && !le32_to_cpu(fnode->ea_size_l)) {
secno n; secno n;
struct buffer_head *bh; struct buffer_head *bh;
char *data; char *data;
if (!(n = hpfs_alloc_sector(s, fno, 1, 0, 1))) return; if (!(n = hpfs_alloc_sector(s, fno, 1, 0))) return;
if (!(data = hpfs_get_sector(s, n, &bh))) { if (!(data = hpfs_get_sector(s, n, &bh))) {
hpfs_free_sectors(s, n, 1); hpfs_free_sectors(s, n, 1);
return; return;
} }
memcpy(data, fnode_ea(fnode), fnode->ea_size_s); memcpy(data, fnode_ea(fnode), le16_to_cpu(fnode->ea_size_s));
fnode->ea_size_l = fnode->ea_size_s; fnode->ea_size_l = cpu_to_le32(le16_to_cpu(fnode->ea_size_s));
fnode->ea_size_s = 0; fnode->ea_size_s = cpu_to_le16(0);
fnode->ea_secno = n; fnode->ea_secno = cpu_to_le32(n);
fnode->ea_anode = 0; fnode->ea_anode = cpu_to_le32(0);
mark_buffer_dirty(bh); mark_buffer_dirty(bh);
brelse(bh); brelse(bh);
} }
pos = fnode->ea_size_l + 5 + strlen(key) + size; pos = le32_to_cpu(fnode->ea_size_l) + 5 + strlen(key) + size;
len = (fnode->ea_size_l + 511) >> 9; len = (le32_to_cpu(fnode->ea_size_l) + 511) >> 9;
if (pos >= 30000) goto bail; if (pos >= 30000) goto bail;
while (((pos + 511) >> 9) > len) { while (((pos + 511) >> 9) > len) {
if (!len) { if (!len) {
if (!(fnode->ea_secno = hpfs_alloc_sector(s, fno, 1, 0, 1))) secno q = hpfs_alloc_sector(s, fno, 1, 0);
goto bail; if (!q) goto bail;
fnode->ea_secno = cpu_to_le32(q);
fnode->ea_anode = 0; fnode->ea_anode = 0;
len++; len++;
} else if (!fnode->ea_anode) { } else if (!fnode->ea_anode) {
if (hpfs_alloc_if_possible(s, fnode->ea_secno + len)) { if (hpfs_alloc_if_possible(s, le32_to_cpu(fnode->ea_secno) + len)) {
len++; len++;
} else { } else {
/* Aargh... don't know how to create ea anodes :-( */ /* Aargh... don't know how to create ea anodes :-( */
...@@ -298,26 +300,26 @@ void hpfs_set_ea(struct inode *inode, struct fnode *fnode, const char *key, ...@@ -298,26 +300,26 @@ void hpfs_set_ea(struct inode *inode, struct fnode *fnode, const char *key,
anode_secno a_s; anode_secno a_s;
if (!(anode = hpfs_alloc_anode(s, fno, &a_s, &bh))) if (!(anode = hpfs_alloc_anode(s, fno, &a_s, &bh)))
goto bail; goto bail;
anode->up = fno; anode->up = cpu_to_le32(fno);
anode->btree.fnode_parent = 1; anode->btree.fnode_parent = 1;
anode->btree.n_free_nodes--; anode->btree.n_free_nodes--;
anode->btree.n_used_nodes++; anode->btree.n_used_nodes++;
anode->btree.first_free += 12; anode->btree.first_free = cpu_to_le16(le16_to_cpu(anode->btree.first_free) + 12);
anode->u.external[0].disk_secno = fnode->ea_secno; anode->u.external[0].disk_secno = cpu_to_le32(le32_to_cpu(fnode->ea_secno));
anode->u.external[0].file_secno = 0; anode->u.external[0].file_secno = cpu_to_le32(0);
anode->u.external[0].length = len; anode->u.external[0].length = cpu_to_le32(len);
mark_buffer_dirty(bh); mark_buffer_dirty(bh);
brelse(bh); brelse(bh);
fnode->ea_anode = 1; fnode->ea_anode = 1;
fnode->ea_secno = a_s;*/ fnode->ea_secno = cpu_to_le32(a_s);*/
secno new_sec; secno new_sec;
int i; int i;
if (!(new_sec = hpfs_alloc_sector(s, fno, 1, 1 - ((pos + 511) >> 9), 1))) if (!(new_sec = hpfs_alloc_sector(s, fno, 1, 1 - ((pos + 511) >> 9))))
goto bail; goto bail;
for (i = 0; i < len; i++) { for (i = 0; i < len; i++) {
struct buffer_head *bh1, *bh2; struct buffer_head *bh1, *bh2;
void *b1, *b2; void *b1, *b2;
if (!(b1 = hpfs_map_sector(s, fnode->ea_secno + i, &bh1, len - i - 1))) { if (!(b1 = hpfs_map_sector(s, le32_to_cpu(fnode->ea_secno) + i, &bh1, len - i - 1))) {
hpfs_free_sectors(s, new_sec, (pos + 511) >> 9); hpfs_free_sectors(s, new_sec, (pos + 511) >> 9);
goto bail; goto bail;
} }
...@@ -331,13 +333,13 @@ void hpfs_set_ea(struct inode *inode, struct fnode *fnode, const char *key, ...@@ -331,13 +333,13 @@ void hpfs_set_ea(struct inode *inode, struct fnode *fnode, const char *key,
mark_buffer_dirty(bh2); mark_buffer_dirty(bh2);
brelse(bh2); brelse(bh2);
} }
hpfs_free_sectors(s, fnode->ea_secno, len); hpfs_free_sectors(s, le32_to_cpu(fnode->ea_secno), len);
fnode->ea_secno = new_sec; fnode->ea_secno = cpu_to_le32(new_sec);
len = (pos + 511) >> 9; len = (pos + 511) >> 9;
} }
} }
if (fnode->ea_anode) { if (fnode->ea_anode) {
if (hpfs_add_sector_to_btree(s, fnode->ea_secno, if (hpfs_add_sector_to_btree(s, le32_to_cpu(fnode->ea_secno),
0, len) != -1) { 0, len) != -1) {
len++; len++;
} else { } else {
...@@ -349,17 +351,17 @@ void hpfs_set_ea(struct inode *inode, struct fnode *fnode, const char *key, ...@@ -349,17 +351,17 @@ void hpfs_set_ea(struct inode *inode, struct fnode *fnode, const char *key,
h[1] = strlen(key); h[1] = strlen(key);
h[2] = size & 0xff; h[2] = size & 0xff;
h[3] = size >> 8; h[3] = size >> 8;
if (hpfs_ea_write(s, fnode->ea_secno, fnode->ea_anode, 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)) goto bail;
if (hpfs_ea_write(s, fnode->ea_secno, fnode->ea_anode, 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) + 4, h[1] + 1, key)) goto bail;
if (hpfs_ea_write(s, fnode->ea_secno, fnode->ea_anode, fnode->ea_size_l + 5 + h[1], size, data)) 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;
fnode->ea_size_l = pos; fnode->ea_size_l = cpu_to_le32(pos);
ret: ret:
hpfs_i(inode)->i_ea_size += 5 + strlen(key) + size; hpfs_i(inode)->i_ea_size += 5 + strlen(key) + size;
return; return;
bail: bail:
if (fnode->ea_secno) if (le32_to_cpu(fnode->ea_secno))
if (fnode->ea_anode) hpfs_truncate_btree(s, fnode->ea_secno, 1, (fnode->ea_size_l + 511) >> 9); if (fnode->ea_anode) 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, fnode->ea_secno + ((fnode->ea_size_l + 511) >> 9), len - ((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 = 0; else fnode->ea_secno = fnode->ea_size_l = cpu_to_le32(0);
} }
...@@ -20,8 +20,8 @@ static int hpfs_file_release(struct inode *inode, struct file *file) ...@@ -20,8 +20,8 @@ static int hpfs_file_release(struct inode *inode, struct file *file)
int hpfs_file_fsync(struct file *file, int datasync) int hpfs_file_fsync(struct file *file, int datasync)
{ {
/*return file_fsync(file, datasync);*/ struct inode *inode = file->f_mapping->host;
return 0; /* Don't fsync :-) */ return sync_blockdev(inode->i_sb->s_bdev);
} }
/* /*
...@@ -48,38 +48,46 @@ static secno hpfs_bmap(struct inode *inode, unsigned file_secno) ...@@ -48,38 +48,46 @@ static secno hpfs_bmap(struct inode *inode, unsigned file_secno)
static void hpfs_truncate(struct inode *i) static void hpfs_truncate(struct inode *i)
{ {
if (IS_IMMUTABLE(i)) return /*-EPERM*/; if (IS_IMMUTABLE(i)) return /*-EPERM*/;
hpfs_lock(i->i_sb); hpfs_lock_assert(i->i_sb);
hpfs_i(i)->i_n_secs = 0; hpfs_i(i)->i_n_secs = 0;
i->i_blocks = 1 + ((i->i_size + 511) >> 9); i->i_blocks = 1 + ((i->i_size + 511) >> 9);
hpfs_i(i)->mmu_private = i->i_size; hpfs_i(i)->mmu_private = i->i_size;
hpfs_truncate_btree(i->i_sb, i->i_ino, 1, ((i->i_size + 511) >> 9)); hpfs_truncate_btree(i->i_sb, i->i_ino, 1, ((i->i_size + 511) >> 9));
hpfs_write_inode(i); hpfs_write_inode(i);
hpfs_i(i)->i_n_secs = 0; hpfs_i(i)->i_n_secs = 0;
hpfs_unlock(i->i_sb);
} }
static int hpfs_get_block(struct inode *inode, sector_t iblock, struct buffer_head *bh_result, int create) static int hpfs_get_block(struct inode *inode, sector_t iblock, struct buffer_head *bh_result, int create)
{ {
int r;
secno s; secno s;
hpfs_lock(inode->i_sb);
s = hpfs_bmap(inode, iblock); s = hpfs_bmap(inode, iblock);
if (s) { if (s) {
map_bh(bh_result, inode->i_sb, s); map_bh(bh_result, inode->i_sb, s);
return 0; goto ret_0;
} }
if (!create) return 0; if (!create) goto ret_0;
if (iblock<<9 != hpfs_i(inode)->mmu_private) { if (iblock<<9 != hpfs_i(inode)->mmu_private) {
BUG(); BUG();
return -EIO; r = -EIO;
goto ret_r;
} }
if ((s = hpfs_add_sector_to_btree(inode->i_sb, inode->i_ino, 1, inode->i_blocks - 1)) == -1) { if ((s = hpfs_add_sector_to_btree(inode->i_sb, inode->i_ino, 1, inode->i_blocks - 1)) == -1) {
hpfs_truncate_btree(inode->i_sb, inode->i_ino, 1, inode->i_blocks - 1); hpfs_truncate_btree(inode->i_sb, inode->i_ino, 1, inode->i_blocks - 1);
return -ENOSPC; r = -ENOSPC;
goto ret_r;
} }
inode->i_blocks++; inode->i_blocks++;
hpfs_i(inode)->mmu_private += 512; hpfs_i(inode)->mmu_private += 512;
set_buffer_new(bh_result); set_buffer_new(bh_result);
map_bh(bh_result, inode->i_sb, s); map_bh(bh_result, inode->i_sb, s);
return 0; ret_0:
r = 0;
ret_r:
hpfs_unlock(inode->i_sb);
return r;
} }
static int hpfs_writepage(struct page *page, struct writeback_control *wbc) static int hpfs_writepage(struct page *page, struct writeback_control *wbc)
...@@ -130,8 +138,11 @@ static ssize_t hpfs_file_write(struct file *file, const char __user *buf, ...@@ -130,8 +138,11 @@ static ssize_t hpfs_file_write(struct file *file, const char __user *buf,
ssize_t retval; ssize_t retval;
retval = do_sync_write(file, buf, count, ppos); retval = do_sync_write(file, buf, count, ppos);
if (retval > 0) if (retval > 0) {
hpfs_lock(file->f_path.dentry->d_sb);
hpfs_i(file->f_path.dentry->d_inode)->i_dirty = 1; hpfs_i(file->f_path.dentry->d_inode)->i_dirty = 1;
hpfs_unlock(file->f_path.dentry->d_sb);
}
return retval; return retval;
} }
......
...@@ -19,9 +19,13 @@ ...@@ -19,9 +19,13 @@
For definitive information on HPFS, ask somebody else -- this is guesswork. For definitive information on HPFS, ask somebody else -- this is guesswork.
There are certain to be many mistakes. */ There are certain to be many mistakes. */
#if !defined(__LITTLE_ENDIAN) && !defined(__BIG_ENDIAN)
#error unknown endian
#endif
/* Notation */ /* Notation */
typedef unsigned secno; /* sector number, partition relative */ typedef u32 secno; /* sector number, partition relative */
typedef secno dnode_secno; /* sector number of a dnode */ typedef secno dnode_secno; /* sector number of a dnode */
typedef secno fnode_secno; /* sector number of an fnode */ typedef secno fnode_secno; /* sector number of an fnode */
...@@ -38,28 +42,28 @@ typedef u32 time32_t; /* 32-bit time_t type */ ...@@ -38,28 +42,28 @@ typedef u32 time32_t; /* 32-bit time_t type */
struct hpfs_boot_block struct hpfs_boot_block
{ {
unsigned char jmp[3]; u8 jmp[3];
unsigned char oem_id[8]; u8 oem_id[8];
unsigned char bytes_per_sector[2]; /* 512 */ u8 bytes_per_sector[2]; /* 512 */
unsigned char sectors_per_cluster; u8 sectors_per_cluster;
unsigned char n_reserved_sectors[2]; u8 n_reserved_sectors[2];
unsigned char n_fats; u8 n_fats;
unsigned char n_rootdir_entries[2]; u8 n_rootdir_entries[2];
unsigned char n_sectors_s[2]; u8 n_sectors_s[2];
unsigned char media_byte; u8 media_byte;
unsigned short sectors_per_fat; u16 sectors_per_fat;
unsigned short sectors_per_track; u16 sectors_per_track;
unsigned short heads_per_cyl; u16 heads_per_cyl;
unsigned int n_hidden_sectors; u32 n_hidden_sectors;
unsigned int n_sectors_l; /* size of partition */ u32 n_sectors_l; /* size of partition */
unsigned char drive_number; u8 drive_number;
unsigned char mbz; u8 mbz;
unsigned char sig_28h; /* 28h */ u8 sig_28h; /* 28h */
unsigned char vol_serno[4]; u8 vol_serno[4];
unsigned char vol_label[11]; u8 vol_label[11];
unsigned char sig_hpfs[8]; /* "HPFS " */ u8 sig_hpfs[8]; /* "HPFS " */
unsigned char pad[448]; u8 pad[448];
unsigned short magic; /* aa55 */ u16 magic; /* aa55 */
}; };
...@@ -71,31 +75,29 @@ struct hpfs_boot_block ...@@ -71,31 +75,29 @@ struct hpfs_boot_block
struct hpfs_super_block struct hpfs_super_block
{ {
unsigned magic; /* f995 e849 */ u32 magic; /* f995 e849 */
unsigned magic1; /* fa53 e9c5, more magic? */ u32 magic1; /* fa53 e9c5, more magic? */
/*unsigned huh202;*/ /* ?? 202 = N. of B. in 1.00390625 S.*/ u8 version; /* version of a filesystem usually 2 */
char version; /* version of a filesystem usually 2 */ u8 funcversion; /* functional version - oldest version
char funcversion; /* functional version - oldest version
of filesystem that can understand of filesystem that can understand
this disk */ this disk */
unsigned short int zero; /* 0 */ u16 zero; /* 0 */
fnode_secno root; /* fnode of root directory */ fnode_secno root; /* fnode of root directory */
secno n_sectors; /* size of filesystem */ secno n_sectors; /* size of filesystem */
unsigned n_badblocks; /* number of bad blocks */ u32 n_badblocks; /* number of bad blocks */
secno bitmaps; /* pointers to free space bit maps */ secno bitmaps; /* pointers to free space bit maps */
unsigned zero1; /* 0 */ u32 zero1; /* 0 */
secno badblocks; /* bad block list */ secno badblocks; /* bad block list */
unsigned zero3; /* 0 */ u32 zero3; /* 0 */
time32_t last_chkdsk; /* date last checked, 0 if never */ time32_t last_chkdsk; /* date last checked, 0 if never */
/*unsigned zero4;*/ /* 0 */ time32_t last_optimize; /* date last optimized, 0 if never */
time32_t last_optimize; /* date last optimized, 0 if never */
secno n_dir_band; /* number of sectors in dir band */ secno n_dir_band; /* number of sectors in dir band */
secno dir_band_start; /* first sector in dir band */ secno dir_band_start; /* first sector in dir band */
secno dir_band_end; /* last sector in dir band */ secno dir_band_end; /* last sector in dir band */
secno dir_band_bitmap; /* free space map, 1 dnode per bit */ secno dir_band_bitmap; /* free space map, 1 dnode per bit */
char volume_name[32]; /* not used */ u8 volume_name[32]; /* not used */
secno user_id_table; /* 8 preallocated sectors - user id */ secno user_id_table; /* 8 preallocated sectors - user id */
unsigned zero6[103]; /* 0 */ u32 zero6[103]; /* 0 */
}; };
...@@ -107,44 +109,65 @@ struct hpfs_super_block ...@@ -107,44 +109,65 @@ struct hpfs_super_block
struct hpfs_spare_block struct hpfs_spare_block
{ {
unsigned magic; /* f991 1849 */ u32 magic; /* f991 1849 */
unsigned magic1; /* fa52 29c5, more magic? */ u32 magic1; /* fa52 29c5, more magic? */
unsigned dirty: 1; /* 0 clean, 1 "improperly stopped" */ #ifdef __LITTLE_ENDIAN
/*unsigned flag1234: 4;*/ /* unknown flags */ u8 dirty: 1; /* 0 clean, 1 "improperly stopped" */
unsigned sparedir_used: 1; /* spare dirblks used */ u8 sparedir_used: 1; /* spare dirblks used */
unsigned hotfixes_used: 1; /* hotfixes used */ u8 hotfixes_used: 1; /* hotfixes used */
unsigned bad_sector: 1; /* bad sector, corrupted disk (???) */ u8 bad_sector: 1; /* bad sector, corrupted disk (???) */
unsigned bad_bitmap: 1; /* bad bitmap */ u8 bad_bitmap: 1; /* bad bitmap */
unsigned fast: 1; /* partition was fast formatted */ u8 fast: 1; /* partition was fast formatted */
unsigned old_wrote: 1; /* old version wrote to partion */ u8 old_wrote: 1; /* old version wrote to partion */
unsigned old_wrote_1: 1; /* old version wrote to partion (?) */ u8 old_wrote_1: 1; /* old version wrote to partion (?) */
unsigned install_dasd_limits: 1; /* HPFS386 flags */ #else
unsigned resynch_dasd_limits: 1; u8 old_wrote_1: 1; /* old version wrote to partion (?) */
unsigned dasd_limits_operational: 1; u8 old_wrote: 1; /* old version wrote to partion */
unsigned multimedia_active: 1; u8 fast: 1; /* partition was fast formatted */
unsigned dce_acls_active: 1; u8 bad_bitmap: 1; /* bad bitmap */
unsigned dasd_limits_dirty: 1; u8 bad_sector: 1; /* bad sector, corrupted disk (???) */
unsigned flag67: 2; u8 hotfixes_used: 1; /* hotfixes used */
unsigned char mm_contlgulty; u8 sparedir_used: 1; /* spare dirblks used */
unsigned char unused; u8 dirty: 1; /* 0 clean, 1 "improperly stopped" */
#endif
#ifdef __LITTLE_ENDIAN
u8 install_dasd_limits: 1; /* HPFS386 flags */
u8 resynch_dasd_limits: 1;
u8 dasd_limits_operational: 1;
u8 multimedia_active: 1;
u8 dce_acls_active: 1;
u8 dasd_limits_dirty: 1;
u8 flag67: 2;
#else
u8 flag67: 2;
u8 dasd_limits_dirty: 1;
u8 dce_acls_active: 1;
u8 multimedia_active: 1;
u8 dasd_limits_operational: 1;
u8 resynch_dasd_limits: 1;
u8 install_dasd_limits: 1; /* HPFS386 flags */
#endif
u8 mm_contlgulty;
u8 unused;
secno hotfix_map; /* info about remapped bad sectors */ secno hotfix_map; /* info about remapped bad sectors */
unsigned n_spares_used; /* number of hotfixes */ u32 n_spares_used; /* number of hotfixes */
unsigned n_spares; /* number of spares in hotfix map */ u32 n_spares; /* number of spares in hotfix map */
unsigned n_dnode_spares_free; /* spare dnodes unused */ u32 n_dnode_spares_free; /* spare dnodes unused */
unsigned n_dnode_spares; /* length of spare_dnodes[] list, u32 n_dnode_spares; /* length of spare_dnodes[] list,
follows in this block*/ follows in this block*/
secno code_page_dir; /* code page directory block */ secno code_page_dir; /* code page directory block */
unsigned n_code_pages; /* number of code pages */ u32 n_code_pages; /* number of code pages */
/*unsigned large_numbers[2];*/ /* ?? */ u32 super_crc; /* on HPFS386 and LAN Server this is
unsigned super_crc; /* on HPFS386 and LAN Server this is
checksum of superblock, on normal checksum of superblock, on normal
OS/2 unused */ OS/2 unused */
unsigned spare_crc; /* on HPFS386 checksum of spareblock */ u32 spare_crc; /* on HPFS386 checksum of spareblock */
unsigned zero1[15]; /* unused */ u32 zero1[15]; /* unused */
dnode_secno spare_dnodes[100]; /* emergency free dnode list */ dnode_secno spare_dnodes[100]; /* emergency free dnode list */
unsigned zero2[1]; /* room for more? */ u32 zero2[1]; /* room for more? */
}; };
/* The bad block list is 4 sectors long. The first word must be zero, /* The bad block list is 4 sectors long. The first word must be zero,
...@@ -179,18 +202,18 @@ struct hpfs_spare_block ...@@ -179,18 +202,18 @@ struct hpfs_spare_block
struct code_page_directory struct code_page_directory
{ {
unsigned magic; /* 4945 21f7 */ u32 magic; /* 4945 21f7 */
unsigned n_code_pages; /* number of pointers following */ u32 n_code_pages; /* number of pointers following */
unsigned zero1[2]; u32 zero1[2];
struct { struct {
unsigned short ix; /* index */ u16 ix; /* index */
unsigned short code_page_number; /* code page number */ u16 code_page_number; /* code page number */
unsigned bounds; /* matches corresponding word u32 bounds; /* matches corresponding word
in data block */ in data block */
secno code_page_data; /* sector number of a code_page_data secno code_page_data; /* sector number of a code_page_data
containing c.p. array */ containing c.p. array */
unsigned short index; /* index in c.p. array in that sector*/ u16 index; /* index in c.p. array in that sector*/
unsigned short unknown; /* some unknown value; usually 0; u16 unknown; /* some unknown value; usually 0;
2 in Japanese version */ 2 in Japanese version */
} array[31]; /* unknown length */ } array[31]; /* unknown length */
}; };
...@@ -201,21 +224,21 @@ struct code_page_directory ...@@ -201,21 +224,21 @@ struct code_page_directory
struct code_page_data struct code_page_data
{ {
unsigned magic; /* 8945 21f7 */ u32 magic; /* 8945 21f7 */
unsigned n_used; /* # elements used in c_p_data[] */ u32 n_used; /* # elements used in c_p_data[] */
unsigned bounds[3]; /* looks a bit like u32 bounds[3]; /* looks a bit like
(beg1,end1), (beg2,end2) (beg1,end1), (beg2,end2)
one byte each */ one byte each */
unsigned short offs[3]; /* offsets from start of sector u16 offs[3]; /* offsets from start of sector
to start of c_p_data[ix] */ to start of c_p_data[ix] */
struct { struct {
unsigned short ix; /* index */ u16 ix; /* index */
unsigned short code_page_number; /* code page number */ u16 code_page_number; /* code page number */
unsigned short unknown; /* the same as in cp directory */ u16 unknown; /* the same as in cp directory */
unsigned char map[128]; /* upcase table for chars 80..ff */ u8 map[128]; /* upcase table for chars 80..ff */
unsigned short zero2; u16 zero2;
} code_page[3]; } code_page[3];
unsigned char incognita[78]; u8 incognita[78];
}; };
...@@ -255,50 +278,84 @@ struct code_page_data ...@@ -255,50 +278,84 @@ struct code_page_data
#define DNODE_MAGIC 0x77e40aae #define DNODE_MAGIC 0x77e40aae
struct dnode { struct dnode {
unsigned magic; /* 77e4 0aae */ u32 magic; /* 77e4 0aae */
unsigned first_free; /* offset from start of dnode to u32 first_free; /* offset from start of dnode to
first free dir entry */ first free dir entry */
unsigned root_dnode:1; /* Is it root dnode? */ #ifdef __LITTLE_ENDIAN
unsigned increment_me:31; /* some kind of activity counter? u8 root_dnode: 1; /* Is it root dnode? */
Neither HPFS.IFS nor CHKDSK cares u8 increment_me: 7; /* some kind of activity counter? */
/* Neither HPFS.IFS nor CHKDSK cares
if you change this word */
#else
u8 increment_me: 7; /* some kind of activity counter? */
/* Neither HPFS.IFS nor CHKDSK cares
if you change this word */ if you change this word */
u8 root_dnode: 1; /* Is it root dnode? */
#endif
u8 increment_me2[3];
secno up; /* (root dnode) directory's fnode secno up; /* (root dnode) directory's fnode
(nonroot) parent dnode */ (nonroot) parent dnode */
dnode_secno self; /* pointer to this dnode */ dnode_secno self; /* pointer to this dnode */
unsigned char dirent[2028]; /* one or more dirents */ u8 dirent[2028]; /* one or more dirents */
}; };
struct hpfs_dirent { struct hpfs_dirent {
unsigned short length; /* offset to next dirent */ u16 length; /* offset to next dirent */
unsigned first: 1; /* set on phony ^A^A (".") entry */
unsigned has_acl: 1; #ifdef __LITTLE_ENDIAN
unsigned down: 1; /* down pointer present (after name) */ u8 first: 1; /* set on phony ^A^A (".") entry */
unsigned last: 1; /* set on phony \377 entry */ u8 has_acl: 1;
unsigned has_ea: 1; /* entry has EA */ u8 down: 1; /* down pointer present (after name) */
unsigned has_xtd_perm: 1; /* has extended perm list (???) */ u8 last: 1; /* set on phony \377 entry */
unsigned has_explicit_acl: 1; u8 has_ea: 1; /* entry has EA */
unsigned has_needea: 1; /* ?? some EA has NEEDEA set u8 has_xtd_perm: 1; /* has extended perm list (???) */
u8 has_explicit_acl: 1;
u8 has_needea: 1; /* ?? some EA has NEEDEA set
I have no idea why this is
interesting in a dir entry */
#else
u8 has_needea: 1; /* ?? some EA has NEEDEA set
I have no idea why this is I have no idea why this is
interesting in a dir entry */ interesting in a dir entry */
unsigned read_only: 1; /* dos attrib */ u8 has_explicit_acl: 1;
unsigned hidden: 1; /* dos attrib */ u8 has_xtd_perm: 1; /* has extended perm list (???) */
unsigned system: 1; /* dos attrib */ u8 has_ea: 1; /* entry has EA */
unsigned flag11: 1; /* would be volume label dos attrib */ u8 last: 1; /* set on phony \377 entry */
unsigned directory: 1; /* dos attrib */ u8 down: 1; /* down pointer present (after name) */
unsigned archive: 1; /* dos attrib */ u8 has_acl: 1;
unsigned not_8x3: 1; /* name is not 8.3 */ u8 first: 1; /* set on phony ^A^A (".") entry */
unsigned flag15: 1; #endif
#ifdef __LITTLE_ENDIAN
u8 read_only: 1; /* dos attrib */
u8 hidden: 1; /* dos attrib */
u8 system: 1; /* dos attrib */
u8 flag11: 1; /* would be volume label dos attrib */
u8 directory: 1; /* dos attrib */
u8 archive: 1; /* dos attrib */
u8 not_8x3: 1; /* name is not 8.3 */
u8 flag15: 1;
#else
u8 flag15: 1;
u8 not_8x3: 1; /* name is not 8.3 */
u8 archive: 1; /* dos attrib */
u8 directory: 1; /* dos attrib */
u8 flag11: 1; /* would be volume label dos attrib */
u8 system: 1; /* dos attrib */
u8 hidden: 1; /* dos attrib */
u8 read_only: 1; /* dos attrib */
#endif
fnode_secno fnode; /* fnode giving allocation info */ fnode_secno fnode; /* fnode giving allocation info */
time32_t write_date; /* mtime */ time32_t write_date; /* mtime */
unsigned file_size; /* file length, bytes */ u32 file_size; /* file length, bytes */
time32_t read_date; /* atime */ time32_t read_date; /* atime */
time32_t creation_date; /* ctime */ time32_t creation_date; /* ctime */
unsigned ea_size; /* total EA length, bytes */ u32 ea_size; /* total EA length, bytes */
unsigned char no_of_acls : 3; /* number of ACL's */ u8 no_of_acls; /* number of ACL's (low 3 bits) */
unsigned char reserver : 5; u8 ix; /* code page index (of filename), see
unsigned char ix; /* code page index (of filename), see
struct code_page_data */ struct code_page_data */
unsigned char namelen, name[1]; /* file name */ u8 namelen, name[1]; /* file name */
/* dnode_secno down; btree down pointer, if present, /* dnode_secno down; btree down pointer, if present,
follows name on next word boundary, or maybe it follows name on next word boundary, or maybe it
precedes next dirent, which is on a word boundary. */ precedes next dirent, which is on a word boundary. */
...@@ -318,38 +375,50 @@ struct hpfs_dirent { ...@@ -318,38 +375,50 @@ struct hpfs_dirent {
struct bplus_leaf_node struct bplus_leaf_node
{ {
unsigned file_secno; /* first file sector in extent */ u32 file_secno; /* first file sector in extent */
unsigned length; /* length, sectors */ u32 length; /* length, sectors */
secno disk_secno; /* first corresponding disk sector */ secno disk_secno; /* first corresponding disk sector */
}; };
struct bplus_internal_node struct bplus_internal_node
{ {
unsigned file_secno; /* subtree maps sectors < this */ u32 file_secno; /* subtree maps sectors < this */
anode_secno down; /* pointer to subtree */ anode_secno down; /* pointer to subtree */
}; };
struct bplus_header struct bplus_header
{ {
unsigned hbff: 1; /* high bit of first free entry offset */ #ifdef __LITTLE_ENDIAN
unsigned flag1: 1; u8 hbff: 1; /* high bit of first free entry offset */
unsigned flag2: 1; u8 flag1234: 4;
unsigned flag3: 1; u8 fnode_parent: 1; /* ? we're pointed to by an fnode,
unsigned flag4: 1;
unsigned fnode_parent: 1; /* ? we're pointed to by an fnode,
the data btree or some ea or the the data btree or some ea or the
main ea bootage pointer ea_secno */ main ea bootage pointer ea_secno */
/* also can get set in fnodes, which /* also can get set in fnodes, which
may be a chkdsk glitch or may mean may be a chkdsk glitch or may mean
this bit is irrelevant in fnodes, this bit is irrelevant in fnodes,
or this interpretation is all wet */ or this interpretation is all wet */
unsigned binary_search: 1; /* suggest binary search (unused) */ u8 binary_search: 1; /* suggest binary search (unused) */
unsigned internal: 1; /* 1 -> (internal) tree of anodes 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 */ 0 -> (leaf) list of extents */
unsigned char fill[3]; u8 binary_search: 1; /* suggest binary search (unused) */
unsigned char n_free_nodes; /* free nodes in following array */ u8 fnode_parent: 1; /* ? we're pointed to by an fnode,
unsigned char n_used_nodes; /* used nodes in following array */ the data btree or some ea or the
unsigned short first_free; /* offset from start of header to 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
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
first free node in array */ first free node in array */
union { union {
struct bplus_internal_node internal[0]; /* (internal) 2-word entries giving struct bplus_internal_node internal[0]; /* (internal) 2-word entries giving
...@@ -369,37 +438,38 @@ struct bplus_header ...@@ -369,37 +438,38 @@ struct bplus_header
struct fnode struct fnode
{ {
unsigned magic; /* f7e4 0aae */ u32 magic; /* f7e4 0aae */
unsigned zero1[2]; /* read history */ u32 zero1[2]; /* read history */
unsigned char len, name[15]; /* true length, truncated name */ u8 len, name[15]; /* true length, truncated name */
fnode_secno up; /* pointer to file's directory fnode */ fnode_secno up; /* pointer to file's directory fnode */
/*unsigned zero2[3];*/
secno acl_size_l; secno acl_size_l;
secno acl_secno; secno acl_secno;
unsigned short acl_size_s; u16 acl_size_s;
char acl_anode; u8 acl_anode;
char zero2; /* history bit count */ u8 zero2; /* history bit count */
unsigned ea_size_l; /* length of disk-resident ea's */ u32 ea_size_l; /* length of disk-resident ea's */
secno ea_secno; /* first sector of disk-resident ea's*/ secno ea_secno; /* first sector of disk-resident ea's*/
unsigned short ea_size_s; /* length of fnode-resident ea's */ u16 ea_size_s; /* length of fnode-resident ea's */
unsigned flag0: 1; #ifdef __LITTLE_ENDIAN
unsigned ea_anode: 1; /* 1 -> ea_secno is an anode */ u8 flag0: 1;
unsigned flag2: 1; u8 ea_anode: 1; /* 1 -> ea_secno is an anode */
unsigned flag3: 1; u8 flag234567: 6;
unsigned flag4: 1; #else
unsigned flag5: 1; u8 flag234567: 6;
unsigned flag6: 1; u8 ea_anode: 1; /* 1 -> ea_secno is an anode */
unsigned flag7: 1; u8 flag0: 1;
unsigned dirflag: 1; /* 1 -> directory. first & only extent #endif
#ifdef __LITTLE_ENDIAN
u8 dirflag: 1; /* 1 -> directory. first & only extent
points to dnode. */ points to dnode. */
unsigned flag9: 1; u8 flag9012345: 7;
unsigned flag10: 1; #else
unsigned flag11: 1; u8 flag9012345: 7;
unsigned flag12: 1; u8 dirflag: 1; /* 1 -> directory. first & only extent
unsigned flag13: 1; points to dnode. */
unsigned flag14: 1; #endif
unsigned flag15: 1;
struct bplus_header btree; /* b+ tree, 8 extents or 12 subtrees */ struct bplus_header btree; /* b+ tree, 8 extents or 12 subtrees */
union { union {
...@@ -407,17 +477,16 @@ struct fnode ...@@ -407,17 +477,16 @@ struct fnode
struct bplus_internal_node internal[12]; struct bplus_internal_node internal[12];
} u; } u;
unsigned file_size; /* file length, bytes */ u32 file_size; /* file length, bytes */
unsigned n_needea; /* number of EA's with NEEDEA set */ u32 n_needea; /* number of EA's with NEEDEA set */
char user_id[16]; /* unused */ u8 user_id[16]; /* unused */
unsigned short ea_offs; /* offset from start of fnode u16 ea_offs; /* offset from start of fnode
to first fnode-resident ea */ to first fnode-resident ea */
char dasd_limit_treshhold; u8 dasd_limit_treshhold;
char dasd_limit_delta; u8 dasd_limit_delta;
unsigned dasd_limit; u32 dasd_limit;
unsigned dasd_usage; u32 dasd_usage;
/*unsigned zero5[2];*/ u8 ea[316]; /* zero or more EA's, packed together
unsigned char ea[316]; /* zero or more EA's, packed together
with no alignment padding. with no alignment padding.
(Do not use this name, get here (Do not use this name, get here
via fnode + ea_offs. I think.) */ via fnode + ea_offs. I think.) */
...@@ -430,7 +499,7 @@ struct fnode ...@@ -430,7 +499,7 @@ struct fnode
struct anode struct anode
{ {
unsigned magic; /* 37e4 0aae */ u32 magic; /* 37e4 0aae */
anode_secno self; /* pointer to this anode */ anode_secno self; /* pointer to this anode */
secno up; /* parent anode or fnode */ secno up; /* parent anode or fnode */
...@@ -440,7 +509,7 @@ struct anode ...@@ -440,7 +509,7 @@ struct anode
struct bplus_internal_node internal[60]; struct bplus_internal_node internal[60];
} u; } u;
unsigned fill[3]; /* unused */ u32 fill[3]; /* unused */
}; };
...@@ -461,25 +530,31 @@ struct anode ...@@ -461,25 +530,31 @@ struct anode
struct extended_attribute struct extended_attribute
{ {
unsigned indirect: 1; /* 1 -> value gives sector number #ifdef __LITTLE_ENDIAN
u8 indirect: 1; /* 1 -> value gives sector number
where real value starts */ where real value starts */
unsigned anode: 1; /* 1 -> sector is an anode u8 anode: 1; /* 1 -> 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 */ that points to fragmented value */
unsigned flag2: 1; u8 indirect: 1; /* 1 -> value gives sector number
unsigned flag3: 1; where real value starts */
unsigned flag4: 1; #endif
unsigned flag5: 1; u8 namelen; /* length of name, bytes */
unsigned flag6: 1; u8 valuelen_lo; /* length of value, bytes */
unsigned needea: 1; /* required ea */ u8 valuelen_hi; /* length of value, bytes */
unsigned char namelen; /* length of name, bytes */ u8 name[0];
unsigned short valuelen; /* length of value, bytes */
unsigned char name[0];
/* /*
unsigned char name[namelen]; ascii attrib name u8 name[namelen]; ascii attrib name
unsigned char nul; terminating '\0', not counted u8 nul; terminating '\0', not counted
unsigned char value[valuelen]; value, arbitrary u8 value[valuelen]; value, arbitrary
if this.indirect, valuelen is 8 and the value is if this.indirect, valuelen is 8 and the value is
unsigned length; real length of value, bytes u32 length; real length of value, bytes
secno secno; sector address where it starts secno secno; sector address where it starts
if this.anode, the above sector number is the root of an anode tree if this.anode, the above sector number is the root of an anode tree
which points to the value. which points to the value.
......
...@@ -13,6 +13,7 @@ ...@@ -13,6 +13,7 @@
#include <linux/pagemap.h> #include <linux/pagemap.h>
#include <linux/buffer_head.h> #include <linux/buffer_head.h>
#include <linux/slab.h> #include <linux/slab.h>
#include <asm/unaligned.h>
#include "hpfs.h" #include "hpfs.h"
...@@ -51,18 +52,16 @@ struct hpfs_inode_info { ...@@ -51,18 +52,16 @@ struct hpfs_inode_info {
unsigned i_disk_sec; /* (files) minimalist cache of alloc info */ unsigned i_disk_sec; /* (files) minimalist cache of alloc info */
unsigned i_n_secs; /* (files) minimalist cache of alloc info */ unsigned i_n_secs; /* (files) minimalist cache of alloc info */
unsigned i_ea_size; /* size of extended attributes */ unsigned i_ea_size; /* size of extended attributes */
unsigned i_conv : 2; /* (files) crlf->newline hackery */
unsigned i_ea_mode : 1; /* file's permission is stored in ea */ unsigned i_ea_mode : 1; /* file's permission is stored in ea */
unsigned i_ea_uid : 1; /* file's uid is stored in ea */ unsigned i_ea_uid : 1; /* file's uid is stored in ea */
unsigned i_ea_gid : 1; /* file's gid is stored in ea */ unsigned i_ea_gid : 1; /* file's gid is stored in ea */
unsigned i_dirty : 1; unsigned i_dirty : 1;
struct mutex i_mutex;
struct mutex i_parent_mutex;
loff_t **i_rddir_off; loff_t **i_rddir_off;
struct inode vfs_inode; struct inode vfs_inode;
}; };
struct hpfs_sb_info { struct hpfs_sb_info {
struct mutex hpfs_mutex; /* global hpfs lock */
ino_t sb_root; /* inode number of root dir */ ino_t sb_root; /* inode number of root dir */
unsigned sb_fs_size; /* file system size, sectors */ unsigned sb_fs_size; /* file system size, sectors */
unsigned sb_bitmaps; /* sector number of bitmap list */ unsigned sb_bitmaps; /* sector number of bitmap list */
...@@ -74,7 +73,6 @@ struct hpfs_sb_info { ...@@ -74,7 +73,6 @@ struct hpfs_sb_info {
uid_t sb_uid; /* uid from mount options */ uid_t sb_uid; /* uid from mount options */
gid_t sb_gid; /* gid from mount options */ gid_t sb_gid; /* gid from mount options */
umode_t sb_mode; /* mode from mount options */ umode_t sb_mode; /* mode from mount options */
unsigned sb_conv : 2; /* crlf->newline hackery */
unsigned sb_eas : 2; /* eas: 0-ignore, 1-ro, 2-rw */ unsigned sb_eas : 2; /* eas: 0-ignore, 1-ro, 2-rw */
unsigned sb_err : 2; /* on errs: 0-cont, 1-ro, 2-panic */ unsigned sb_err : 2; /* on errs: 0-cont, 1-ro, 2-panic */
unsigned sb_chk : 2; /* checks: 0-no, 1-normal, 2-strict */ unsigned sb_chk : 2; /* checks: 0-no, 1-normal, 2-strict */
...@@ -87,20 +85,9 @@ struct hpfs_sb_info { ...@@ -87,20 +85,9 @@ struct hpfs_sb_info {
unsigned *sb_bmp_dir; /* main bitmap directory */ unsigned *sb_bmp_dir; /* main bitmap directory */
unsigned sb_c_bitmap; /* current bitmap */ unsigned sb_c_bitmap; /* current bitmap */
unsigned sb_max_fwd_alloc; /* max forwad allocation */ unsigned sb_max_fwd_alloc; /* max forwad allocation */
struct mutex hpfs_creation_de; /* when creating dirents, nobody else
can alloc blocks */
/*unsigned sb_mounting : 1;*/
int sb_timeshift; int sb_timeshift;
}; };
/*
* conv= options
*/
#define CONV_BINARY 0 /* no conversion */
#define CONV_TEXT 1 /* crlf->newline */
#define CONV_AUTO 2 /* decide based on file contents */
/* Four 512-byte buffers and the 2k block obtained by concatenating them */ /* Four 512-byte buffers and the 2k block obtained by concatenating them */
struct quad_buffer_head { struct quad_buffer_head {
...@@ -113,7 +100,7 @@ struct quad_buffer_head { ...@@ -113,7 +100,7 @@ struct quad_buffer_head {
static inline dnode_secno de_down_pointer (struct hpfs_dirent *de) static inline dnode_secno de_down_pointer (struct hpfs_dirent *de)
{ {
CHKCOND(de->down,("HPFS: de_down_pointer: !de->down\n")); CHKCOND(de->down,("HPFS: de_down_pointer: !de->down\n"));
return *(dnode_secno *) ((void *) de + de->length - 4); return le32_to_cpu(*(dnode_secno *) ((void *) de + le16_to_cpu(de->length) - 4));
} }
/* The first dir entry in a dnode */ /* The first dir entry in a dnode */
...@@ -127,41 +114,46 @@ static inline struct hpfs_dirent *dnode_first_de (struct dnode *dnode) ...@@ -127,41 +114,46 @@ static inline struct hpfs_dirent *dnode_first_de (struct dnode *dnode)
static inline struct hpfs_dirent *dnode_end_de (struct dnode *dnode) static inline struct hpfs_dirent *dnode_end_de (struct dnode *dnode)
{ {
CHKCOND(dnode->first_free>=0x14 && dnode->first_free<=0xa00,("HPFS: dnode_end_de: dnode->first_free = %d\n",(int)dnode->first_free)); CHKCOND(le32_to_cpu(dnode->first_free)>=0x14 && le32_to_cpu(dnode->first_free)<=0xa00,("HPFS: dnode_end_de: dnode->first_free = %x\n",(unsigned)le32_to_cpu(dnode->first_free)));
return (void *) dnode + dnode->first_free; return (void *) dnode + le32_to_cpu(dnode->first_free);
} }
/* The dir entry after dir entry de */ /* The dir entry after dir entry de */
static inline struct hpfs_dirent *de_next_de (struct hpfs_dirent *de) static inline struct hpfs_dirent *de_next_de (struct hpfs_dirent *de)
{ {
CHKCOND(de->length>=0x20 && de->length<0x800,("HPFS: de_next_de: de->length = %d\n",(int)de->length)); CHKCOND(le16_to_cpu(de->length)>=0x20 && le16_to_cpu(de->length)<0x800,("HPFS: de_next_de: de->length = %x\n",(unsigned)le16_to_cpu(de->length)));
return (void *) de + de->length; return (void *) de + le16_to_cpu(de->length);
} }
static inline struct extended_attribute *fnode_ea(struct fnode *fnode) static inline struct extended_attribute *fnode_ea(struct fnode *fnode)
{ {
return (struct extended_attribute *)((char *)fnode + fnode->ea_offs + fnode->acl_size_s); return (struct extended_attribute *)((char *)fnode + le16_to_cpu(fnode->ea_offs) + le16_to_cpu(fnode->acl_size_s));
} }
static inline struct extended_attribute *fnode_end_ea(struct fnode *fnode) static inline struct extended_attribute *fnode_end_ea(struct fnode *fnode)
{ {
return (struct extended_attribute *)((char *)fnode + fnode->ea_offs + fnode->acl_size_s + fnode->ea_size_s); return (struct extended_attribute *)((char *)fnode + le16_to_cpu(fnode->ea_offs) + le16_to_cpu(fnode->acl_size_s) + le16_to_cpu(fnode->ea_size_s));
}
static unsigned ea_valuelen(struct extended_attribute *ea)
{
return ea->valuelen_lo + 256 * ea->valuelen_hi;
} }
static inline struct extended_attribute *next_ea(struct extended_attribute *ea) static inline struct extended_attribute *next_ea(struct extended_attribute *ea)
{ {
return (struct extended_attribute *)((char *)ea + 5 + ea->namelen + ea->valuelen); return (struct extended_attribute *)((char *)ea + 5 + ea->namelen + ea_valuelen(ea));
} }
static inline secno ea_sec(struct extended_attribute *ea) static inline secno ea_sec(struct extended_attribute *ea)
{ {
return *(secno *)((char *)ea + 9 + ea->namelen); return le32_to_cpu(get_unaligned((secno *)((char *)ea + 9 + ea->namelen)));
} }
static inline secno ea_len(struct extended_attribute *ea) static inline secno ea_len(struct extended_attribute *ea)
{ {
return *(secno *)((char *)ea + 5 + ea->namelen); return le32_to_cpu(get_unaligned((secno *)((char *)ea + 5 + ea->namelen)));
} }
static inline char *ea_data(struct extended_attribute *ea) static inline char *ea_data(struct extended_attribute *ea)
...@@ -186,13 +178,13 @@ static inline void copy_de(struct hpfs_dirent *dst, struct hpfs_dirent *src) ...@@ -186,13 +178,13 @@ static inline void copy_de(struct hpfs_dirent *dst, struct hpfs_dirent *src)
dst->not_8x3 = n; dst->not_8x3 = n;
} }
static inline unsigned tstbits(unsigned *bmp, unsigned b, unsigned n) static inline unsigned tstbits(u32 *bmp, unsigned b, unsigned n)
{ {
int i; int i;
if ((b >= 0x4000) || (b + n - 1 >= 0x4000)) return n; if ((b >= 0x4000) || (b + n - 1 >= 0x4000)) return n;
if (!((bmp[(b & 0x3fff) >> 5] >> (b & 0x1f)) & 1)) return 1; if (!((le32_to_cpu(bmp[(b & 0x3fff) >> 5]) >> (b & 0x1f)) & 1)) return 1;
for (i = 1; i < n; i++) for (i = 1; i < n; i++)
if (/*b+i < 0x4000 &&*/ !((bmp[((b+i) & 0x3fff) >> 5] >> ((b+i) & 0x1f)) & 1)) if (!((le32_to_cpu(bmp[((b+i) & 0x3fff) >> 5]) >> ((b+i) & 0x1f)) & 1))
return i + 1; return i + 1;
return 0; return 0;
} }
...@@ -200,12 +192,12 @@ static inline unsigned tstbits(unsigned *bmp, unsigned b, unsigned n) ...@@ -200,12 +192,12 @@ static inline unsigned tstbits(unsigned *bmp, unsigned b, unsigned n)
/* alloc.c */ /* alloc.c */
int hpfs_chk_sectors(struct super_block *, secno, int, char *); int hpfs_chk_sectors(struct super_block *, secno, int, char *);
secno hpfs_alloc_sector(struct super_block *, secno, unsigned, int, int); secno hpfs_alloc_sector(struct super_block *, secno, unsigned, int);
int hpfs_alloc_if_possible(struct super_block *, secno); int hpfs_alloc_if_possible(struct super_block *, secno);
void hpfs_free_sectors(struct super_block *, secno, unsigned); void hpfs_free_sectors(struct super_block *, secno, unsigned);
int hpfs_check_free_dnodes(struct super_block *, int); int hpfs_check_free_dnodes(struct super_block *, int);
void hpfs_free_dnode(struct super_block *, secno); void hpfs_free_dnode(struct super_block *, secno);
struct dnode *hpfs_alloc_dnode(struct super_block *, secno, dnode_secno *, struct quad_buffer_head *, int); struct dnode *hpfs_alloc_dnode(struct super_block *, secno, dnode_secno *, struct quad_buffer_head *);
struct fnode *hpfs_alloc_fnode(struct super_block *, secno, fnode_secno *, struct buffer_head **); struct fnode *hpfs_alloc_fnode(struct super_block *, secno, fnode_secno *, struct buffer_head **);
struct anode *hpfs_alloc_anode(struct super_block *, secno, anode_secno *, struct buffer_head **); struct anode *hpfs_alloc_anode(struct super_block *, secno, anode_secno *, struct buffer_head **);
...@@ -222,8 +214,6 @@ void hpfs_remove_fnode(struct super_block *, fnode_secno fno); ...@@ -222,8 +214,6 @@ void hpfs_remove_fnode(struct super_block *, fnode_secno fno);
/* buffer.c */ /* buffer.c */
void hpfs_lock_creation(struct super_block *);
void hpfs_unlock_creation(struct super_block *);
void *hpfs_map_sector(struct super_block *, unsigned, struct buffer_head **, int); void *hpfs_map_sector(struct super_block *, unsigned, struct buffer_head **, int);
void *hpfs_get_sector(struct super_block *, unsigned, struct buffer_head **); void *hpfs_get_sector(struct super_block *, unsigned, struct buffer_head **);
void *hpfs_map_4sectors(struct super_block *, unsigned, struct quad_buffer_head *, int); void *hpfs_map_4sectors(struct super_block *, unsigned, struct quad_buffer_head *, int);
...@@ -247,7 +237,7 @@ void hpfs_del_pos(struct inode *, loff_t *); ...@@ -247,7 +237,7 @@ void hpfs_del_pos(struct inode *, loff_t *);
struct hpfs_dirent *hpfs_add_de(struct super_block *, struct dnode *, struct hpfs_dirent *hpfs_add_de(struct super_block *, struct dnode *,
const unsigned char *, unsigned, secno); const unsigned char *, unsigned, secno);
int hpfs_add_dirent(struct inode *, const unsigned char *, unsigned, int hpfs_add_dirent(struct inode *, const unsigned char *, unsigned,
struct hpfs_dirent *, int); struct hpfs_dirent *);
int hpfs_remove_dirent(struct inode *, dnode_secno, struct hpfs_dirent *, struct quad_buffer_head *, int); int hpfs_remove_dirent(struct inode *, dnode_secno, struct hpfs_dirent *, struct quad_buffer_head *, int);
void hpfs_count_dnodes(struct super_block *, dnode_secno, int *, int *, int *); void hpfs_count_dnodes(struct super_block *, dnode_secno, int *, int *, int *);
dnode_secno hpfs_de_as_down_as_possible(struct super_block *, dnode_secno dno); dnode_secno hpfs_de_as_down_as_possible(struct super_block *, dnode_secno dno);
...@@ -303,7 +293,6 @@ int hpfs_compare_names(struct super_block *, const unsigned char *, unsigned, ...@@ -303,7 +293,6 @@ int hpfs_compare_names(struct super_block *, const unsigned char *, unsigned,
const unsigned char *, unsigned, int); const unsigned char *, unsigned, int);
int hpfs_is_name_long(const unsigned char *, unsigned); int hpfs_is_name_long(const unsigned char *, unsigned);
void hpfs_adjust_length(const unsigned char *, unsigned *); void hpfs_adjust_length(const unsigned char *, unsigned *);
void hpfs_decide_conv(struct inode *, const unsigned char *, unsigned);
/* namei.c */ /* namei.c */
...@@ -346,21 +335,26 @@ static inline time32_t gmt_to_local(struct super_block *s, time_t t) ...@@ -346,21 +335,26 @@ static inline time32_t gmt_to_local(struct super_block *s, time_t t)
/* /*
* Locking: * Locking:
* *
* hpfs_lock() is a leftover from the big kernel lock. * hpfs_lock() locks the whole filesystem. It must be taken
* Right now, these functions are empty and only left * on any method called by the VFS.
* for documentation purposes. The file system no longer
* works on SMP systems, so the lock is not needed
* any more.
* *
* If someone is interested in making it work again, this * We don't do any per-file locking anymore, it is hard to
* would be the place to start by adding a per-superblock * review and HPFS is not performance-sensitive anyway.
* mutex and fixing all the bugs and performance issues
* caused by that.
*/ */
static inline void hpfs_lock(struct super_block *s) static inline void hpfs_lock(struct super_block *s)
{ {
struct hpfs_sb_info *sbi = hpfs_sb(s);
mutex_lock(&sbi->hpfs_mutex);
} }
static inline void hpfs_unlock(struct super_block *s) static inline void hpfs_unlock(struct super_block *s)
{ {
struct hpfs_sb_info *sbi = hpfs_sb(s);
mutex_unlock(&sbi->hpfs_mutex);
}
static inline void hpfs_lock_assert(struct super_block *s)
{
struct hpfs_sb_info *sbi = hpfs_sb(s);
WARN_ON(!mutex_is_locked(&sbi->hpfs_mutex));
} }
...@@ -17,7 +17,6 @@ void hpfs_init_inode(struct inode *i) ...@@ -17,7 +17,6 @@ void hpfs_init_inode(struct inode *i)
i->i_uid = hpfs_sb(sb)->sb_uid; i->i_uid = hpfs_sb(sb)->sb_uid;
i->i_gid = hpfs_sb(sb)->sb_gid; i->i_gid = hpfs_sb(sb)->sb_gid;
i->i_mode = hpfs_sb(sb)->sb_mode; i->i_mode = hpfs_sb(sb)->sb_mode;
hpfs_inode->i_conv = hpfs_sb(sb)->sb_conv;
i->i_size = -1; i->i_size = -1;
i->i_blocks = -1; i->i_blocks = -1;
...@@ -116,8 +115,8 @@ void hpfs_read_inode(struct inode *i) ...@@ -116,8 +115,8 @@ void hpfs_read_inode(struct inode *i)
i->i_mode |= S_IFDIR; i->i_mode |= S_IFDIR;
i->i_op = &hpfs_dir_iops; i->i_op = &hpfs_dir_iops;
i->i_fop = &hpfs_dir_ops; i->i_fop = &hpfs_dir_ops;
hpfs_inode->i_parent_dir = fnode->up; hpfs_inode->i_parent_dir = le32_to_cpu(fnode->up);
hpfs_inode->i_dno = fnode->u.external[0].disk_secno; hpfs_inode->i_dno = le32_to_cpu(fnode->u.external[0].disk_secno);
if (hpfs_sb(sb)->sb_chk >= 2) { if (hpfs_sb(sb)->sb_chk >= 2) {
struct buffer_head *bh0; struct buffer_head *bh0;
if (hpfs_map_fnode(sb, hpfs_inode->i_parent_dir, &bh0)) brelse(bh0); if (hpfs_map_fnode(sb, hpfs_inode->i_parent_dir, &bh0)) brelse(bh0);
...@@ -133,7 +132,7 @@ void hpfs_read_inode(struct inode *i) ...@@ -133,7 +132,7 @@ void hpfs_read_inode(struct inode *i)
i->i_op = &hpfs_file_iops; i->i_op = &hpfs_file_iops;
i->i_fop = &hpfs_file_ops; i->i_fop = &hpfs_file_ops;
i->i_nlink = 1; i->i_nlink = 1;
i->i_size = fnode->file_size; i->i_size = le32_to_cpu(fnode->file_size);
i->i_blocks = ((i->i_size + 511) >> 9) + 1; i->i_blocks = ((i->i_size + 511) >> 9) + 1;
i->i_data.a_ops = &hpfs_aops; i->i_data.a_ops = &hpfs_aops;
hpfs_i(i)->mmu_private = i->i_size; hpfs_i(i)->mmu_private = i->i_size;
...@@ -144,7 +143,7 @@ void hpfs_read_inode(struct inode *i) ...@@ -144,7 +143,7 @@ void hpfs_read_inode(struct inode *i)
static void hpfs_write_inode_ea(struct inode *i, struct fnode *fnode) static void hpfs_write_inode_ea(struct inode *i, struct fnode *fnode)
{ {
struct hpfs_inode_info *hpfs_inode = hpfs_i(i); struct hpfs_inode_info *hpfs_inode = hpfs_i(i);
/*if (fnode->acl_size_l || fnode->acl_size_s) { /*if (le32_to_cpu(fnode->acl_size_l) || le16_to_cpu(fnode->acl_size_s)) {
Some unknown structures like ACL may be in fnode, Some unknown structures like ACL may be in fnode,
we'd better not overwrite them we'd better not overwrite them
hpfs_error(i->i_sb, "fnode %08x has some unknown HPFS386 stuctures", i->i_ino); hpfs_error(i->i_sb, "fnode %08x has some unknown HPFS386 stuctures", i->i_ino);
...@@ -187,9 +186,7 @@ void hpfs_write_inode(struct inode *i) ...@@ -187,9 +186,7 @@ void hpfs_write_inode(struct inode *i)
kfree(hpfs_inode->i_rddir_off); kfree(hpfs_inode->i_rddir_off);
hpfs_inode->i_rddir_off = NULL; hpfs_inode->i_rddir_off = NULL;
} }
mutex_lock(&hpfs_inode->i_parent_mutex);
if (!i->i_nlink) { if (!i->i_nlink) {
mutex_unlock(&hpfs_inode->i_parent_mutex);
return; return;
} }
parent = iget_locked(i->i_sb, hpfs_inode->i_parent_dir); parent = iget_locked(i->i_sb, hpfs_inode->i_parent_dir);
...@@ -200,14 +197,9 @@ void hpfs_write_inode(struct inode *i) ...@@ -200,14 +197,9 @@ void hpfs_write_inode(struct inode *i)
hpfs_read_inode(parent); hpfs_read_inode(parent);
unlock_new_inode(parent); unlock_new_inode(parent);
} }
mutex_lock(&hpfs_inode->i_mutex);
hpfs_write_inode_nolock(i); hpfs_write_inode_nolock(i);
mutex_unlock(&hpfs_inode->i_mutex);
iput(parent); iput(parent);
} else {
mark_inode_dirty(i);
} }
mutex_unlock(&hpfs_inode->i_parent_mutex);
} }
void hpfs_write_inode_nolock(struct inode *i) void hpfs_write_inode_nolock(struct inode *i)
...@@ -226,30 +218,30 @@ void hpfs_write_inode_nolock(struct inode *i) ...@@ -226,30 +218,30 @@ void hpfs_write_inode_nolock(struct inode *i)
} }
} else de = NULL; } else de = NULL;
if (S_ISREG(i->i_mode)) { if (S_ISREG(i->i_mode)) {
fnode->file_size = i->i_size; fnode->file_size = cpu_to_le32(i->i_size);
if (de) de->file_size = i->i_size; if (de) de->file_size = cpu_to_le32(i->i_size);
} else if (S_ISDIR(i->i_mode)) { } else if (S_ISDIR(i->i_mode)) {
fnode->file_size = 0; fnode->file_size = cpu_to_le32(0);
if (de) de->file_size = 0; if (de) de->file_size = cpu_to_le32(0);
} }
hpfs_write_inode_ea(i, fnode); hpfs_write_inode_ea(i, fnode);
if (de) { if (de) {
de->write_date = gmt_to_local(i->i_sb, i->i_mtime.tv_sec); de->write_date = cpu_to_le32(gmt_to_local(i->i_sb, i->i_mtime.tv_sec));
de->read_date = gmt_to_local(i->i_sb, i->i_atime.tv_sec); de->read_date = cpu_to_le32(gmt_to_local(i->i_sb, i->i_atime.tv_sec));
de->creation_date = gmt_to_local(i->i_sb, i->i_ctime.tv_sec); de->creation_date = cpu_to_le32(gmt_to_local(i->i_sb, i->i_ctime.tv_sec));
de->read_only = !(i->i_mode & 0222); de->read_only = !(i->i_mode & 0222);
de->ea_size = hpfs_inode->i_ea_size; de->ea_size = cpu_to_le32(hpfs_inode->i_ea_size);
hpfs_mark_4buffers_dirty(&qbh); hpfs_mark_4buffers_dirty(&qbh);
hpfs_brelse4(&qbh); hpfs_brelse4(&qbh);
} }
if (S_ISDIR(i->i_mode)) { if (S_ISDIR(i->i_mode)) {
if ((de = map_dirent(i, hpfs_inode->i_dno, "\001\001", 2, NULL, &qbh))) { if ((de = map_dirent(i, hpfs_inode->i_dno, "\001\001", 2, NULL, &qbh))) {
de->write_date = gmt_to_local(i->i_sb, i->i_mtime.tv_sec); de->write_date = cpu_to_le32(gmt_to_local(i->i_sb, i->i_mtime.tv_sec));
de->read_date = gmt_to_local(i->i_sb, i->i_atime.tv_sec); de->read_date = cpu_to_le32(gmt_to_local(i->i_sb, i->i_atime.tv_sec));
de->creation_date = gmt_to_local(i->i_sb, i->i_ctime.tv_sec); de->creation_date = cpu_to_le32(gmt_to_local(i->i_sb, i->i_ctime.tv_sec));
de->read_only = !(i->i_mode & 0222); de->read_only = !(i->i_mode & 0222);
de->ea_size = /*hpfs_inode->i_ea_size*/0; de->ea_size = cpu_to_le32(/*hpfs_inode->i_ea_size*/0);
de->file_size = 0; de->file_size = cpu_to_le32(0);
hpfs_mark_4buffers_dirty(&qbh); hpfs_mark_4buffers_dirty(&qbh);
hpfs_brelse4(&qbh); hpfs_brelse4(&qbh);
} else } else
...@@ -269,6 +261,10 @@ int hpfs_setattr(struct dentry *dentry, struct iattr *attr) ...@@ -269,6 +261,10 @@ int hpfs_setattr(struct dentry *dentry, struct iattr *attr)
hpfs_lock(inode->i_sb); hpfs_lock(inode->i_sb);
if (inode->i_ino == hpfs_sb(inode->i_sb)->sb_root) if (inode->i_ino == hpfs_sb(inode->i_sb)->sb_root)
goto out_unlock; goto out_unlock;
if ((attr->ia_valid & ATTR_UID) && attr->ia_uid >= 0x10000)
goto out_unlock;
if ((attr->ia_valid & ATTR_GID) && attr->ia_gid >= 0x10000)
goto out_unlock;
if ((attr->ia_valid & ATTR_SIZE) && attr->ia_size > inode->i_size) if ((attr->ia_valid & ATTR_SIZE) && attr->ia_size > inode->i_size)
goto out_unlock; goto out_unlock;
...@@ -284,7 +280,6 @@ int hpfs_setattr(struct dentry *dentry, struct iattr *attr) ...@@ -284,7 +280,6 @@ int hpfs_setattr(struct dentry *dentry, struct iattr *attr)
} }
setattr_copy(inode, attr); setattr_copy(inode, attr);
mark_inode_dirty(inode);
hpfs_write_inode(inode); hpfs_write_inode(inode);
......
...@@ -21,7 +21,7 @@ unsigned int *hpfs_map_bitmap(struct super_block *s, unsigned bmp_block, ...@@ -21,7 +21,7 @@ unsigned int *hpfs_map_bitmap(struct super_block *s, unsigned bmp_block,
hpfs_error(s, "hpfs_map_bitmap called with bad parameter: %08x at %s", bmp_block, id); hpfs_error(s, "hpfs_map_bitmap called with bad parameter: %08x at %s", bmp_block, id);
return NULL; return NULL;
} }
sec = hpfs_sb(s)->sb_bmp_dir[bmp_block]; sec = le32_to_cpu(hpfs_sb(s)->sb_bmp_dir[bmp_block]);
if (!sec || sec > hpfs_sb(s)->sb_fs_size-4) { if (!sec || sec > hpfs_sb(s)->sb_fs_size-4) {
hpfs_error(s, "invalid bitmap block pointer %08x -> %08x at %s", bmp_block, sec, id); hpfs_error(s, "invalid bitmap block pointer %08x -> %08x at %s", bmp_block, sec, id);
return NULL; return NULL;
...@@ -46,18 +46,18 @@ unsigned char *hpfs_load_code_page(struct super_block *s, secno cps) ...@@ -46,18 +46,18 @@ unsigned char *hpfs_load_code_page(struct super_block *s, secno cps)
struct code_page_data *cpd; struct code_page_data *cpd;
struct code_page_directory *cp = hpfs_map_sector(s, cps, &bh, 0); struct code_page_directory *cp = hpfs_map_sector(s, cps, &bh, 0);
if (!cp) return NULL; if (!cp) return NULL;
if (cp->magic != CP_DIR_MAGIC) { if (le32_to_cpu(cp->magic) != CP_DIR_MAGIC) {
printk("HPFS: Code page directory magic doesn't match (magic = %08x)\n", cp->magic); printk("HPFS: Code page directory magic doesn't match (magic = %08x)\n", le32_to_cpu(cp->magic));
brelse(bh); brelse(bh);
return NULL; return NULL;
} }
if (!cp->n_code_pages) { if (!le32_to_cpu(cp->n_code_pages)) {
printk("HPFS: n_code_pages == 0\n"); printk("HPFS: n_code_pages == 0\n");
brelse(bh); brelse(bh);
return NULL; return NULL;
} }
cpds = cp->array[0].code_page_data; cpds = le32_to_cpu(cp->array[0].code_page_data);
cpi = cp->array[0].index; cpi = le16_to_cpu(cp->array[0].index);
brelse(bh); brelse(bh);
if (cpi >= 3) { if (cpi >= 3) {
...@@ -66,12 +66,12 @@ unsigned char *hpfs_load_code_page(struct super_block *s, secno cps) ...@@ -66,12 +66,12 @@ unsigned char *hpfs_load_code_page(struct super_block *s, secno cps)
} }
if (!(cpd = hpfs_map_sector(s, cpds, &bh, 0))) return NULL; if (!(cpd = hpfs_map_sector(s, cpds, &bh, 0))) return NULL;
if ((unsigned)cpd->offs[cpi] > 0x178) { if (le16_to_cpu(cpd->offs[cpi]) > 0x178) {
printk("HPFS: Code page index out of sector\n"); printk("HPFS: Code page index out of sector\n");
brelse(bh); brelse(bh);
return NULL; return NULL;
} }
ptr = (unsigned char *)cpd + cpd->offs[cpi] + 6; ptr = (unsigned char *)cpd + le16_to_cpu(cpd->offs[cpi]) + 6;
if (!(cp_table = kmalloc(256, GFP_KERNEL))) { if (!(cp_table = kmalloc(256, GFP_KERNEL))) {
printk("HPFS: out of memory for code page table\n"); printk("HPFS: out of memory for code page table\n");
brelse(bh); brelse(bh);
...@@ -125,7 +125,7 @@ struct fnode *hpfs_map_fnode(struct super_block *s, ino_t ino, struct buffer_hea ...@@ -125,7 +125,7 @@ struct fnode *hpfs_map_fnode(struct super_block *s, ino_t ino, struct buffer_hea
if (hpfs_sb(s)->sb_chk) { if (hpfs_sb(s)->sb_chk) {
struct extended_attribute *ea; struct extended_attribute *ea;
struct extended_attribute *ea_end; struct extended_attribute *ea_end;
if (fnode->magic != FNODE_MAGIC) { if (le32_to_cpu(fnode->magic) != FNODE_MAGIC) {
hpfs_error(s, "bad magic on fnode %08lx", hpfs_error(s, "bad magic on fnode %08lx",
(unsigned long)ino); (unsigned long)ino);
goto bail; goto bail;
...@@ -138,7 +138,7 @@ struct fnode *hpfs_map_fnode(struct super_block *s, ino_t ino, struct buffer_hea ...@@ -138,7 +138,7 @@ struct fnode *hpfs_map_fnode(struct super_block *s, ino_t ino, struct buffer_hea
(unsigned long)ino); (unsigned long)ino);
goto bail; goto bail;
} }
if (fnode->btree.first_free != 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 * (fnode->btree.internal ? 8 : 12)) {
hpfs_error(s, hpfs_error(s,
"bad first_free pointer in fnode %08lx", "bad first_free pointer in fnode %08lx",
...@@ -146,12 +146,12 @@ struct fnode *hpfs_map_fnode(struct super_block *s, ino_t ino, struct buffer_hea ...@@ -146,12 +146,12 @@ struct fnode *hpfs_map_fnode(struct super_block *s, ino_t ino, struct buffer_hea
goto bail; goto bail;
} }
} }
if (fnode->ea_size_s && ((signed int)fnode->ea_offs < 0xc4 || if (le16_to_cpu(fnode->ea_size_s) && (le16_to_cpu(fnode->ea_offs) < 0xc4 ||
(signed int)fnode->ea_offs + fnode->acl_size_s + fnode->ea_size_s > 0x200)) { le16_to_cpu(fnode->ea_offs) + le16_to_cpu(fnode->acl_size_s) + le16_to_cpu(fnode->ea_size_s) > 0x200)) {
hpfs_error(s, hpfs_error(s,
"bad EA info in fnode %08lx: ea_offs == %04x ea_size_s == %04x", "bad EA info in fnode %08lx: ea_offs == %04x ea_size_s == %04x",
(unsigned long)ino, (unsigned long)ino,
fnode->ea_offs, fnode->ea_size_s); le16_to_cpu(fnode->ea_offs), le16_to_cpu(fnode->ea_size_s));
goto bail; goto bail;
} }
ea = fnode_ea(fnode); ea = fnode_ea(fnode);
...@@ -178,16 +178,20 @@ struct anode *hpfs_map_anode(struct super_block *s, anode_secno ano, struct buff ...@@ -178,16 +178,20 @@ struct anode *hpfs_map_anode(struct super_block *s, anode_secno ano, struct buff
if (hpfs_sb(s)->sb_chk) if (hpfs_chk_sectors(s, ano, 1, "anode")) return NULL; if (hpfs_sb(s)->sb_chk) if (hpfs_chk_sectors(s, ano, 1, "anode")) return NULL;
if ((anode = hpfs_map_sector(s, ano, bhp, ANODE_RD_AHEAD))) if ((anode = hpfs_map_sector(s, ano, bhp, ANODE_RD_AHEAD)))
if (hpfs_sb(s)->sb_chk) { if (hpfs_sb(s)->sb_chk) {
if (anode->magic != ANODE_MAGIC || anode->self != ano) { if (le32_to_cpu(anode->magic) != ANODE_MAGIC) {
hpfs_error(s, "bad magic on anode %08x", ano); hpfs_error(s, "bad magic on anode %08x", ano);
goto bail; goto bail;
} }
if (le32_to_cpu(anode->self) != ano) {
hpfs_error(s, "self pointer invalid on anode %08x", ano);
goto bail;
}
if ((unsigned)anode->btree.n_used_nodes + (unsigned)anode->btree.n_free_nodes != if ((unsigned)anode->btree.n_used_nodes + (unsigned)anode->btree.n_free_nodes !=
(anode->btree.internal ? 60 : 40)) { (anode->btree.internal ? 60 : 40)) {
hpfs_error(s, "bad number of nodes in anode %08x", ano); hpfs_error(s, "bad number of nodes in anode %08x", ano);
goto bail; goto bail;
} }
if (anode->btree.first_free != 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 * (anode->btree.internal ? 8 : 12)) {
hpfs_error(s, "bad first_free pointer in anode %08x", ano); hpfs_error(s, "bad first_free pointer in anode %08x", ano);
goto bail; goto bail;
...@@ -219,26 +223,26 @@ struct dnode *hpfs_map_dnode(struct super_block *s, unsigned secno, ...@@ -219,26 +223,26 @@ struct dnode *hpfs_map_dnode(struct super_block *s, unsigned secno,
unsigned p, pp = 0; unsigned p, pp = 0;
unsigned char *d = (unsigned char *)dnode; unsigned char *d = (unsigned char *)dnode;
int b = 0; int b = 0;
if (dnode->magic != DNODE_MAGIC) { if (le32_to_cpu(dnode->magic) != DNODE_MAGIC) {
hpfs_error(s, "bad magic on dnode %08x", secno); hpfs_error(s, "bad magic on dnode %08x", secno);
goto bail; goto bail;
} }
if (dnode->self != secno) if (le32_to_cpu(dnode->self) != secno)
hpfs_error(s, "bad self pointer on dnode %08x self = %08x", secno, dnode->self); hpfs_error(s, "bad self pointer on dnode %08x self = %08x", secno, le32_to_cpu(dnode->self));
/* Check dirents - bad dirents would cause infinite /* Check dirents - bad dirents would cause infinite
loops or shooting to memory */ loops or shooting to memory */
if (dnode->first_free > 2048/* || dnode->first_free < 84*/) { if (le32_to_cpu(dnode->first_free) > 2048) {
hpfs_error(s, "dnode %08x has first_free == %08x", secno, dnode->first_free); hpfs_error(s, "dnode %08x has first_free == %08x", secno, le32_to_cpu(dnode->first_free));
goto bail; goto bail;
} }
for (p = 20; p < dnode->first_free; p += d[p] + (d[p+1] << 8)) { for (p = 20; p < le32_to_cpu(dnode->first_free); p += d[p] + (d[p+1] << 8)) {
struct hpfs_dirent *de = (struct hpfs_dirent *)((char *)dnode + p); struct hpfs_dirent *de = (struct hpfs_dirent *)((char *)dnode + p);
if (de->length > 292 || (de->length < 32) || (de->length & 3) || p + de->length > 2048) { if (le16_to_cpu(de->length) > 292 || (le16_to_cpu(de->length) < 32) || (le16_to_cpu(de->length) & 3) || p + le16_to_cpu(de->length) > 2048) {
hpfs_error(s, "bad dirent size in dnode %08x, dirent %03x, last %03x", secno, p, pp); hpfs_error(s, "bad dirent size in dnode %08x, dirent %03x, last %03x", secno, p, pp);
goto bail; goto bail;
} }
if (((31 + de->namelen + de->down*4 + 3) & ~3) != de->length) { if (((31 + de->namelen + de->down*4 + 3) & ~3) != le16_to_cpu(de->length)) {
if (((31 + de->namelen + de->down*4 + 3) & ~3) < de->length && s->s_flags & MS_RDONLY) goto ok; if (((31 + de->namelen + de->down*4 + 3) & ~3) < le16_to_cpu(de->length) && s->s_flags & MS_RDONLY) goto ok;
hpfs_error(s, "namelen does not match dirent size in dnode %08x, dirent %03x, last %03x", secno, p, pp); hpfs_error(s, "namelen does not match dirent size in dnode %08x, dirent %03x, last %03x", secno, p, pp);
goto bail; goto bail;
} }
...@@ -251,7 +255,7 @@ struct dnode *hpfs_map_dnode(struct super_block *s, unsigned secno, ...@@ -251,7 +255,7 @@ struct dnode *hpfs_map_dnode(struct super_block *s, unsigned secno,
pp = p; pp = p;
} }
if (p != dnode->first_free) { if (p != le32_to_cpu(dnode->first_free)) {
hpfs_error(s, "size on last dirent does not match first_free; dnode %08x", secno); hpfs_error(s, "size on last dirent does not match first_free; dnode %08x", secno);
goto bail; goto bail;
} }
...@@ -277,7 +281,7 @@ dnode_secno hpfs_fnode_dno(struct super_block *s, ino_t ino) ...@@ -277,7 +281,7 @@ dnode_secno hpfs_fnode_dno(struct super_block *s, ino_t ino)
if (!fnode) if (!fnode)
return 0; return 0;
dno = fnode->u.external[0].disk_secno; dno = le32_to_cpu(fnode->u.external[0].disk_secno);
brelse(bh); brelse(bh);
return dno; return dno;
} }
...@@ -8,39 +8,6 @@ ...@@ -8,39 +8,6 @@
#include "hpfs_fn.h" #include "hpfs_fn.h"
static const char *text_postfix[]={
".ASM", ".BAS", ".BAT", ".C", ".CC", ".CFG", ".CMD", ".CON", ".CPP", ".DEF",
".DOC", ".DPR", ".ERX", ".H", ".HPP", ".HTM", ".HTML", ".JAVA", ".LOG", ".PAS",
".RC", ".TEX", ".TXT", ".Y", ""};
static const char *text_prefix[]={
"AUTOEXEC.", "CHANGES", "COPYING", "CONFIG.", "CREDITS", "FAQ", "FILE_ID.DIZ",
"MAKEFILE", "READ.ME", "README", "TERMCAP", ""};
void hpfs_decide_conv(struct inode *inode, const unsigned char *name, unsigned len)
{
struct hpfs_inode_info *hpfs_inode = hpfs_i(inode);
int i;
if (hpfs_inode->i_conv != CONV_AUTO) return;
for (i = 0; *text_postfix[i]; i++) {
int l = strlen(text_postfix[i]);
if (l <= len)
if (!hpfs_compare_names(inode->i_sb, text_postfix[i], l, name + len - l, l, 0))
goto text;
}
for (i = 0; *text_prefix[i]; i++) {
int l = strlen(text_prefix[i]);
if (l <= len)
if (!hpfs_compare_names(inode->i_sb, text_prefix[i], l, name, l, 0))
goto text;
}
hpfs_inode->i_conv = CONV_BINARY;
return;
text:
hpfs_inode->i_conv = CONV_TEXT;
return;
}
static inline int not_allowed_char(unsigned char c) static inline int not_allowed_char(unsigned char c)
{ {
return c<' ' || c=='"' || c=='*' || c=='/' || c==':' || c=='<' || return c<' ' || c=='"' || c=='*' || c=='/' || c==':' || c=='<' ||
......
...@@ -29,7 +29,7 @@ static int hpfs_mkdir(struct inode *dir, struct dentry *dentry, int mode) ...@@ -29,7 +29,7 @@ static int hpfs_mkdir(struct inode *dir, struct dentry *dentry, int mode)
fnode = hpfs_alloc_fnode(dir->i_sb, hpfs_i(dir)->i_dno, &fno, &bh); fnode = hpfs_alloc_fnode(dir->i_sb, hpfs_i(dir)->i_dno, &fno, &bh);
if (!fnode) if (!fnode)
goto bail; goto bail;
dnode = hpfs_alloc_dnode(dir->i_sb, fno, &dno, &qbh0, 1); dnode = hpfs_alloc_dnode(dir->i_sb, fno, &dno, &qbh0);
if (!dnode) if (!dnode)
goto bail1; goto bail1;
memset(&dee, 0, sizeof dee); memset(&dee, 0, sizeof dee);
...@@ -37,8 +37,8 @@ static int hpfs_mkdir(struct inode *dir, struct dentry *dentry, int mode) ...@@ -37,8 +37,8 @@ static int hpfs_mkdir(struct inode *dir, struct dentry *dentry, int mode)
if (!(mode & 0222)) dee.read_only = 1; if (!(mode & 0222)) dee.read_only = 1;
/*dee.archive = 0;*/ /*dee.archive = 0;*/
dee.hidden = name[0] == '.'; dee.hidden = name[0] == '.';
dee.fnode = fno; dee.fnode = cpu_to_le32(fno);
dee.creation_date = dee.write_date = dee.read_date = gmt_to_local(dir->i_sb, get_seconds()); dee.creation_date = dee.write_date = dee.read_date = cpu_to_le32(gmt_to_local(dir->i_sb, get_seconds()));
result = new_inode(dir->i_sb); result = new_inode(dir->i_sb);
if (!result) if (!result)
goto bail2; goto bail2;
...@@ -46,7 +46,7 @@ static int hpfs_mkdir(struct inode *dir, struct dentry *dentry, int mode) ...@@ -46,7 +46,7 @@ static int hpfs_mkdir(struct inode *dir, struct dentry *dentry, int mode)
result->i_ino = fno; result->i_ino = fno;
hpfs_i(result)->i_parent_dir = dir->i_ino; hpfs_i(result)->i_parent_dir = dir->i_ino;
hpfs_i(result)->i_dno = dno; hpfs_i(result)->i_dno = dno;
result->i_ctime.tv_sec = result->i_mtime.tv_sec = result->i_atime.tv_sec = local_to_gmt(dir->i_sb, dee.creation_date); result->i_ctime.tv_sec = result->i_mtime.tv_sec = result->i_atime.tv_sec = local_to_gmt(dir->i_sb, le32_to_cpu(dee.creation_date));
result->i_ctime.tv_nsec = 0; result->i_ctime.tv_nsec = 0;
result->i_mtime.tv_nsec = 0; result->i_mtime.tv_nsec = 0;
result->i_atime.tv_nsec = 0; result->i_atime.tv_nsec = 0;
...@@ -60,8 +60,7 @@ static int hpfs_mkdir(struct inode *dir, struct dentry *dentry, int mode) ...@@ -60,8 +60,7 @@ static int hpfs_mkdir(struct inode *dir, struct dentry *dentry, int mode)
if (dee.read_only) if (dee.read_only)
result->i_mode &= ~0222; result->i_mode &= ~0222;
mutex_lock(&hpfs_i(dir)->i_mutex); r = hpfs_add_dirent(dir, name, len, &dee);
r = hpfs_add_dirent(dir, name, len, &dee, 0);
if (r == 1) if (r == 1)
goto bail3; goto bail3;
if (r == -1) { if (r == -1) {
...@@ -70,21 +69,21 @@ static int hpfs_mkdir(struct inode *dir, struct dentry *dentry, int mode) ...@@ -70,21 +69,21 @@ static int hpfs_mkdir(struct inode *dir, struct dentry *dentry, int mode)
} }
fnode->len = len; fnode->len = len;
memcpy(fnode->name, name, len > 15 ? 15 : len); memcpy(fnode->name, name, len > 15 ? 15 : len);
fnode->up = dir->i_ino; fnode->up = cpu_to_le32(dir->i_ino);
fnode->dirflag = 1; fnode->dirflag = 1;
fnode->btree.n_free_nodes = 7; fnode->btree.n_free_nodes = 7;
fnode->btree.n_used_nodes = 1; fnode->btree.n_used_nodes = 1;
fnode->btree.first_free = 0x14; fnode->btree.first_free = cpu_to_le16(0x14);
fnode->u.external[0].disk_secno = dno; fnode->u.external[0].disk_secno = cpu_to_le32(dno);
fnode->u.external[0].file_secno = -1; fnode->u.external[0].file_secno = cpu_to_le32(-1);
dnode->root_dnode = 1; dnode->root_dnode = 1;
dnode->up = fno; dnode->up = cpu_to_le32(fno);
de = hpfs_add_de(dir->i_sb, dnode, "\001\001", 2, 0); de = hpfs_add_de(dir->i_sb, dnode, "\001\001", 2, 0);
de->creation_date = de->write_date = de->read_date = gmt_to_local(dir->i_sb, get_seconds()); de->creation_date = de->write_date = de->read_date = cpu_to_le32(gmt_to_local(dir->i_sb, get_seconds()));
if (!(mode & 0222)) de->read_only = 1; if (!(mode & 0222)) de->read_only = 1;
de->first = de->directory = 1; de->first = de->directory = 1;
/*de->hidden = de->system = 0;*/ /*de->hidden = de->system = 0;*/
de->fnode = fno; de->fnode = cpu_to_le32(fno);
mark_buffer_dirty(bh); mark_buffer_dirty(bh);
brelse(bh); brelse(bh);
hpfs_mark_4buffers_dirty(&qbh0); hpfs_mark_4buffers_dirty(&qbh0);
...@@ -101,11 +100,9 @@ static int hpfs_mkdir(struct inode *dir, struct dentry *dentry, int mode) ...@@ -101,11 +100,9 @@ static int hpfs_mkdir(struct inode *dir, struct dentry *dentry, int mode)
hpfs_write_inode_nolock(result); hpfs_write_inode_nolock(result);
} }
d_instantiate(dentry, result); d_instantiate(dentry, result);
mutex_unlock(&hpfs_i(dir)->i_mutex);
hpfs_unlock(dir->i_sb); hpfs_unlock(dir->i_sb);
return 0; return 0;
bail3: bail3:
mutex_unlock(&hpfs_i(dir)->i_mutex);
iput(result); iput(result);
bail2: bail2:
hpfs_brelse4(&qbh0); hpfs_brelse4(&qbh0);
...@@ -140,8 +137,8 @@ static int hpfs_create(struct inode *dir, struct dentry *dentry, int mode, struc ...@@ -140,8 +137,8 @@ static int hpfs_create(struct inode *dir, struct dentry *dentry, int mode, struc
if (!(mode & 0222)) dee.read_only = 1; if (!(mode & 0222)) dee.read_only = 1;
dee.archive = 1; dee.archive = 1;
dee.hidden = name[0] == '.'; dee.hidden = name[0] == '.';
dee.fnode = fno; dee.fnode = cpu_to_le32(fno);
dee.creation_date = dee.write_date = dee.read_date = gmt_to_local(dir->i_sb, get_seconds()); dee.creation_date = dee.write_date = dee.read_date = cpu_to_le32(gmt_to_local(dir->i_sb, get_seconds()));
result = new_inode(dir->i_sb); result = new_inode(dir->i_sb);
if (!result) if (!result)
...@@ -154,9 +151,8 @@ static int hpfs_create(struct inode *dir, struct dentry *dentry, int mode, struc ...@@ -154,9 +151,8 @@ static int hpfs_create(struct inode *dir, struct dentry *dentry, int mode, struc
result->i_op = &hpfs_file_iops; result->i_op = &hpfs_file_iops;
result->i_fop = &hpfs_file_ops; result->i_fop = &hpfs_file_ops;
result->i_nlink = 1; result->i_nlink = 1;
hpfs_decide_conv(result, name, len);
hpfs_i(result)->i_parent_dir = dir->i_ino; hpfs_i(result)->i_parent_dir = dir->i_ino;
result->i_ctime.tv_sec = result->i_mtime.tv_sec = result->i_atime.tv_sec = local_to_gmt(dir->i_sb, dee.creation_date); result->i_ctime.tv_sec = result->i_mtime.tv_sec = result->i_atime.tv_sec = local_to_gmt(dir->i_sb, le32_to_cpu(dee.creation_date));
result->i_ctime.tv_nsec = 0; result->i_ctime.tv_nsec = 0;
result->i_mtime.tv_nsec = 0; result->i_mtime.tv_nsec = 0;
result->i_atime.tv_nsec = 0; result->i_atime.tv_nsec = 0;
...@@ -168,8 +164,7 @@ static int hpfs_create(struct inode *dir, struct dentry *dentry, int mode, struc ...@@ -168,8 +164,7 @@ static int hpfs_create(struct inode *dir, struct dentry *dentry, int mode, struc
result->i_data.a_ops = &hpfs_aops; result->i_data.a_ops = &hpfs_aops;
hpfs_i(result)->mmu_private = 0; hpfs_i(result)->mmu_private = 0;
mutex_lock(&hpfs_i(dir)->i_mutex); r = hpfs_add_dirent(dir, name, len, &dee);
r = hpfs_add_dirent(dir, name, len, &dee, 0);
if (r == 1) if (r == 1)
goto bail2; goto bail2;
if (r == -1) { if (r == -1) {
...@@ -178,7 +173,7 @@ static int hpfs_create(struct inode *dir, struct dentry *dentry, int mode, struc ...@@ -178,7 +173,7 @@ static int hpfs_create(struct inode *dir, struct dentry *dentry, int mode, struc
} }
fnode->len = len; fnode->len = len;
memcpy(fnode->name, name, len > 15 ? 15 : len); memcpy(fnode->name, name, len > 15 ? 15 : len);
fnode->up = dir->i_ino; fnode->up = cpu_to_le32(dir->i_ino);
mark_buffer_dirty(bh); mark_buffer_dirty(bh);
brelse(bh); brelse(bh);
...@@ -193,12 +188,10 @@ static int hpfs_create(struct inode *dir, struct dentry *dentry, int mode, struc ...@@ -193,12 +188,10 @@ static int hpfs_create(struct inode *dir, struct dentry *dentry, int mode, struc
hpfs_write_inode_nolock(result); hpfs_write_inode_nolock(result);
} }
d_instantiate(dentry, result); d_instantiate(dentry, result);
mutex_unlock(&hpfs_i(dir)->i_mutex);
hpfs_unlock(dir->i_sb); hpfs_unlock(dir->i_sb);
return 0; return 0;
bail2: bail2:
mutex_unlock(&hpfs_i(dir)->i_mutex);
iput(result); iput(result);
bail1: bail1:
brelse(bh); brelse(bh);
...@@ -232,8 +225,8 @@ static int hpfs_mknod(struct inode *dir, struct dentry *dentry, int mode, dev_t ...@@ -232,8 +225,8 @@ static int hpfs_mknod(struct inode *dir, struct dentry *dentry, int mode, dev_t
if (!(mode & 0222)) dee.read_only = 1; if (!(mode & 0222)) dee.read_only = 1;
dee.archive = 1; dee.archive = 1;
dee.hidden = name[0] == '.'; dee.hidden = name[0] == '.';
dee.fnode = fno; dee.fnode = cpu_to_le32(fno);
dee.creation_date = dee.write_date = dee.read_date = gmt_to_local(dir->i_sb, get_seconds()); dee.creation_date = dee.write_date = dee.read_date = cpu_to_le32(gmt_to_local(dir->i_sb, get_seconds()));
result = new_inode(dir->i_sb); result = new_inode(dir->i_sb);
if (!result) if (!result)
...@@ -242,7 +235,7 @@ static int hpfs_mknod(struct inode *dir, struct dentry *dentry, int mode, dev_t ...@@ -242,7 +235,7 @@ static int hpfs_mknod(struct inode *dir, struct dentry *dentry, int mode, dev_t
hpfs_init_inode(result); hpfs_init_inode(result);
result->i_ino = fno; result->i_ino = fno;
hpfs_i(result)->i_parent_dir = dir->i_ino; hpfs_i(result)->i_parent_dir = dir->i_ino;
result->i_ctime.tv_sec = result->i_mtime.tv_sec = result->i_atime.tv_sec = local_to_gmt(dir->i_sb, dee.creation_date); result->i_ctime.tv_sec = result->i_mtime.tv_sec = result->i_atime.tv_sec = local_to_gmt(dir->i_sb, le32_to_cpu(dee.creation_date));
result->i_ctime.tv_nsec = 0; result->i_ctime.tv_nsec = 0;
result->i_mtime.tv_nsec = 0; result->i_mtime.tv_nsec = 0;
result->i_atime.tv_nsec = 0; result->i_atime.tv_nsec = 0;
...@@ -254,8 +247,7 @@ static int hpfs_mknod(struct inode *dir, struct dentry *dentry, int mode, dev_t ...@@ -254,8 +247,7 @@ static int hpfs_mknod(struct inode *dir, struct dentry *dentry, int mode, dev_t
result->i_blocks = 1; result->i_blocks = 1;
init_special_inode(result, mode, rdev); init_special_inode(result, mode, rdev);
mutex_lock(&hpfs_i(dir)->i_mutex); r = hpfs_add_dirent(dir, name, len, &dee);
r = hpfs_add_dirent(dir, name, len, &dee, 0);
if (r == 1) if (r == 1)
goto bail2; goto bail2;
if (r == -1) { if (r == -1) {
...@@ -264,19 +256,17 @@ static int hpfs_mknod(struct inode *dir, struct dentry *dentry, int mode, dev_t ...@@ -264,19 +256,17 @@ static int hpfs_mknod(struct inode *dir, struct dentry *dentry, int mode, dev_t
} }
fnode->len = len; fnode->len = len;
memcpy(fnode->name, name, len > 15 ? 15 : len); memcpy(fnode->name, name, len > 15 ? 15 : len);
fnode->up = dir->i_ino; fnode->up = cpu_to_le32(dir->i_ino);
mark_buffer_dirty(bh); mark_buffer_dirty(bh);
insert_inode_hash(result); insert_inode_hash(result);
hpfs_write_inode_nolock(result); hpfs_write_inode_nolock(result);
d_instantiate(dentry, result); d_instantiate(dentry, result);
mutex_unlock(&hpfs_i(dir)->i_mutex);
brelse(bh); brelse(bh);
hpfs_unlock(dir->i_sb); hpfs_unlock(dir->i_sb);
return 0; return 0;
bail2: bail2:
mutex_unlock(&hpfs_i(dir)->i_mutex);
iput(result); iput(result);
bail1: bail1:
brelse(bh); brelse(bh);
...@@ -310,8 +300,8 @@ static int hpfs_symlink(struct inode *dir, struct dentry *dentry, const char *sy ...@@ -310,8 +300,8 @@ static int hpfs_symlink(struct inode *dir, struct dentry *dentry, const char *sy
memset(&dee, 0, sizeof dee); memset(&dee, 0, sizeof dee);
dee.archive = 1; dee.archive = 1;
dee.hidden = name[0] == '.'; dee.hidden = name[0] == '.';
dee.fnode = fno; dee.fnode = cpu_to_le32(fno);
dee.creation_date = dee.write_date = dee.read_date = gmt_to_local(dir->i_sb, get_seconds()); dee.creation_date = dee.write_date = dee.read_date = cpu_to_le32(gmt_to_local(dir->i_sb, get_seconds()));
result = new_inode(dir->i_sb); result = new_inode(dir->i_sb);
if (!result) if (!result)
...@@ -319,7 +309,7 @@ static int hpfs_symlink(struct inode *dir, struct dentry *dentry, const char *sy ...@@ -319,7 +309,7 @@ static int hpfs_symlink(struct inode *dir, struct dentry *dentry, const char *sy
result->i_ino = fno; result->i_ino = fno;
hpfs_init_inode(result); hpfs_init_inode(result);
hpfs_i(result)->i_parent_dir = dir->i_ino; hpfs_i(result)->i_parent_dir = dir->i_ino;
result->i_ctime.tv_sec = result->i_mtime.tv_sec = result->i_atime.tv_sec = local_to_gmt(dir->i_sb, dee.creation_date); result->i_ctime.tv_sec = result->i_mtime.tv_sec = result->i_atime.tv_sec = local_to_gmt(dir->i_sb, le32_to_cpu(dee.creation_date));
result->i_ctime.tv_nsec = 0; result->i_ctime.tv_nsec = 0;
result->i_mtime.tv_nsec = 0; result->i_mtime.tv_nsec = 0;
result->i_atime.tv_nsec = 0; result->i_atime.tv_nsec = 0;
...@@ -333,8 +323,7 @@ static int hpfs_symlink(struct inode *dir, struct dentry *dentry, const char *sy ...@@ -333,8 +323,7 @@ static int hpfs_symlink(struct inode *dir, struct dentry *dentry, const char *sy
result->i_op = &page_symlink_inode_operations; result->i_op = &page_symlink_inode_operations;
result->i_data.a_ops = &hpfs_symlink_aops; result->i_data.a_ops = &hpfs_symlink_aops;
mutex_lock(&hpfs_i(dir)->i_mutex); r = hpfs_add_dirent(dir, name, len, &dee);
r = hpfs_add_dirent(dir, name, len, &dee, 0);
if (r == 1) if (r == 1)
goto bail2; goto bail2;
if (r == -1) { if (r == -1) {
...@@ -343,7 +332,7 @@ static int hpfs_symlink(struct inode *dir, struct dentry *dentry, const char *sy ...@@ -343,7 +332,7 @@ static int hpfs_symlink(struct inode *dir, struct dentry *dentry, const char *sy
} }
fnode->len = len; fnode->len = len;
memcpy(fnode->name, name, len > 15 ? 15 : len); memcpy(fnode->name, name, len > 15 ? 15 : len);
fnode->up = dir->i_ino; fnode->up = cpu_to_le32(dir->i_ino);
hpfs_set_ea(result, fnode, "SYMLINK", symlink, strlen(symlink)); hpfs_set_ea(result, fnode, "SYMLINK", symlink, strlen(symlink));
mark_buffer_dirty(bh); mark_buffer_dirty(bh);
brelse(bh); brelse(bh);
...@@ -352,11 +341,9 @@ static int hpfs_symlink(struct inode *dir, struct dentry *dentry, const char *sy ...@@ -352,11 +341,9 @@ static int hpfs_symlink(struct inode *dir, struct dentry *dentry, const char *sy
hpfs_write_inode_nolock(result); hpfs_write_inode_nolock(result);
d_instantiate(dentry, result); d_instantiate(dentry, result);
mutex_unlock(&hpfs_i(dir)->i_mutex);
hpfs_unlock(dir->i_sb); hpfs_unlock(dir->i_sb);
return 0; return 0;
bail2: bail2:
mutex_unlock(&hpfs_i(dir)->i_mutex);
iput(result); iput(result);
bail1: bail1:
brelse(bh); brelse(bh);
...@@ -374,7 +361,6 @@ static int hpfs_unlink(struct inode *dir, struct dentry *dentry) ...@@ -374,7 +361,6 @@ static int hpfs_unlink(struct inode *dir, struct dentry *dentry)
struct hpfs_dirent *de; struct hpfs_dirent *de;
struct inode *inode = dentry->d_inode; struct inode *inode = dentry->d_inode;
dnode_secno dno; dnode_secno dno;
fnode_secno fno;
int r; int r;
int rep = 0; int rep = 0;
int err; int err;
...@@ -382,8 +368,6 @@ static int hpfs_unlink(struct inode *dir, struct dentry *dentry) ...@@ -382,8 +368,6 @@ static int hpfs_unlink(struct inode *dir, struct dentry *dentry)
hpfs_lock(dir->i_sb); hpfs_lock(dir->i_sb);
hpfs_adjust_length(name, &len); hpfs_adjust_length(name, &len);
again: again:
mutex_lock(&hpfs_i(inode)->i_parent_mutex);
mutex_lock(&hpfs_i(dir)->i_mutex);
err = -ENOENT; err = -ENOENT;
de = map_dirent(dir, hpfs_i(dir)->i_dno, name, len, &dno, &qbh); de = map_dirent(dir, hpfs_i(dir)->i_dno, name, len, &dno, &qbh);
if (!de) if (!de)
...@@ -397,7 +381,6 @@ static int hpfs_unlink(struct inode *dir, struct dentry *dentry) ...@@ -397,7 +381,6 @@ static int hpfs_unlink(struct inode *dir, struct dentry *dentry)
if (de->directory) if (de->directory)
goto out1; goto out1;
fno = de->fnode;
r = hpfs_remove_dirent(dir, dno, de, &qbh, 1); r = hpfs_remove_dirent(dir, dno, de, &qbh, 1);
switch (r) { switch (r) {
case 1: case 1:
...@@ -410,8 +393,6 @@ static int hpfs_unlink(struct inode *dir, struct dentry *dentry) ...@@ -410,8 +393,6 @@ static int hpfs_unlink(struct inode *dir, struct dentry *dentry)
if (rep++) if (rep++)
break; break;
mutex_unlock(&hpfs_i(dir)->i_mutex);
mutex_unlock(&hpfs_i(inode)->i_parent_mutex);
dentry_unhash(dentry); dentry_unhash(dentry);
if (!d_unhashed(dentry)) { if (!d_unhashed(dentry)) {
dput(dentry); dput(dentry);
...@@ -445,8 +426,6 @@ static int hpfs_unlink(struct inode *dir, struct dentry *dentry) ...@@ -445,8 +426,6 @@ static int hpfs_unlink(struct inode *dir, struct dentry *dentry)
out1: out1:
hpfs_brelse4(&qbh); hpfs_brelse4(&qbh);
out: out:
mutex_unlock(&hpfs_i(dir)->i_mutex);
mutex_unlock(&hpfs_i(inode)->i_parent_mutex);
hpfs_unlock(dir->i_sb); hpfs_unlock(dir->i_sb);
return err; return err;
} }
...@@ -459,15 +438,12 @@ static int hpfs_rmdir(struct inode *dir, struct dentry *dentry) ...@@ -459,15 +438,12 @@ static int hpfs_rmdir(struct inode *dir, struct dentry *dentry)
struct hpfs_dirent *de; struct hpfs_dirent *de;
struct inode *inode = dentry->d_inode; struct inode *inode = dentry->d_inode;
dnode_secno dno; dnode_secno dno;
fnode_secno fno;
int n_items = 0; int n_items = 0;
int err; int err;
int r; int r;
hpfs_adjust_length(name, &len); hpfs_adjust_length(name, &len);
hpfs_lock(dir->i_sb); hpfs_lock(dir->i_sb);
mutex_lock(&hpfs_i(inode)->i_parent_mutex);
mutex_lock(&hpfs_i(dir)->i_mutex);
err = -ENOENT; err = -ENOENT;
de = map_dirent(dir, hpfs_i(dir)->i_dno, name, len, &dno, &qbh); de = map_dirent(dir, hpfs_i(dir)->i_dno, name, len, &dno, &qbh);
if (!de) if (!de)
...@@ -486,7 +462,6 @@ static int hpfs_rmdir(struct inode *dir, struct dentry *dentry) ...@@ -486,7 +462,6 @@ static int hpfs_rmdir(struct inode *dir, struct dentry *dentry)
if (n_items) if (n_items)
goto out1; goto out1;
fno = de->fnode;
r = hpfs_remove_dirent(dir, dno, de, &qbh, 1); r = hpfs_remove_dirent(dir, dno, de, &qbh, 1);
switch (r) { switch (r) {
case 1: case 1:
...@@ -505,8 +480,6 @@ static int hpfs_rmdir(struct inode *dir, struct dentry *dentry) ...@@ -505,8 +480,6 @@ static int hpfs_rmdir(struct inode *dir, struct dentry *dentry)
out1: out1:
hpfs_brelse4(&qbh); hpfs_brelse4(&qbh);
out: out:
mutex_unlock(&hpfs_i(dir)->i_mutex);
mutex_unlock(&hpfs_i(inode)->i_parent_mutex);
hpfs_unlock(dir->i_sb); hpfs_unlock(dir->i_sb);
return err; return err;
} }
...@@ -568,12 +541,6 @@ static int hpfs_rename(struct inode *old_dir, struct dentry *old_dentry, ...@@ -568,12 +541,6 @@ static int hpfs_rename(struct inode *old_dir, struct dentry *old_dentry,
hpfs_lock(i->i_sb); hpfs_lock(i->i_sb);
/* order doesn't matter, due to VFS exclusion */ /* order doesn't matter, due to VFS exclusion */
mutex_lock(&hpfs_i(i)->i_parent_mutex);
if (new_inode)
mutex_lock(&hpfs_i(new_inode)->i_parent_mutex);
mutex_lock(&hpfs_i(old_dir)->i_mutex);
if (new_dir != old_dir)
mutex_lock(&hpfs_i(new_dir)->i_mutex);
/* Erm? Moving over the empty non-busy directory is perfectly legal */ /* Erm? Moving over the empty non-busy directory is perfectly legal */
if (new_inode && S_ISDIR(new_inode->i_mode)) { if (new_inode && S_ISDIR(new_inode->i_mode)) {
...@@ -610,9 +577,7 @@ static int hpfs_rename(struct inode *old_dir, struct dentry *old_dentry, ...@@ -610,9 +577,7 @@ static int hpfs_rename(struct inode *old_dir, struct dentry *old_dentry,
if (new_dir == old_dir) hpfs_brelse4(&qbh); if (new_dir == old_dir) hpfs_brelse4(&qbh);
hpfs_lock_creation(i->i_sb); if ((r = hpfs_add_dirent(new_dir, new_name, new_len, &de))) {
if ((r = hpfs_add_dirent(new_dir, new_name, new_len, &de, 1))) {
hpfs_unlock_creation(i->i_sb);
if (r == -1) hpfs_error(new_dir->i_sb, "hpfs_rename: dirent already exists!"); if (r == -1) hpfs_error(new_dir->i_sb, "hpfs_rename: dirent already exists!");
err = r == 1 ? -ENOSPC : -EFSERROR; err = r == 1 ? -ENOSPC : -EFSERROR;
if (new_dir != old_dir) hpfs_brelse4(&qbh); if (new_dir != old_dir) hpfs_brelse4(&qbh);
...@@ -621,20 +586,17 @@ static int hpfs_rename(struct inode *old_dir, struct dentry *old_dentry, ...@@ -621,20 +586,17 @@ static int hpfs_rename(struct inode *old_dir, struct dentry *old_dentry,
if (new_dir == old_dir) if (new_dir == old_dir)
if (!(dep = map_dirent(old_dir, hpfs_i(old_dir)->i_dno, old_name, old_len, &dno, &qbh))) { if (!(dep = map_dirent(old_dir, hpfs_i(old_dir)->i_dno, old_name, old_len, &dno, &qbh))) {
hpfs_unlock_creation(i->i_sb);
hpfs_error(i->i_sb, "lookup succeeded but map dirent failed at #2"); hpfs_error(i->i_sb, "lookup succeeded but map dirent failed at #2");
err = -ENOENT; err = -ENOENT;
goto end1; goto end1;
} }
if ((r = hpfs_remove_dirent(old_dir, dno, dep, &qbh, 0))) { if ((r = hpfs_remove_dirent(old_dir, dno, dep, &qbh, 0))) {
hpfs_unlock_creation(i->i_sb);
hpfs_error(i->i_sb, "hpfs_rename: could not remove dirent"); hpfs_error(i->i_sb, "hpfs_rename: could not remove dirent");
err = r == 2 ? -ENOSPC : -EFSERROR; err = r == 2 ? -ENOSPC : -EFSERROR;
goto end1; goto end1;
} }
hpfs_unlock_creation(i->i_sb);
end: end:
hpfs_i(i)->i_parent_dir = new_dir->i_ino; hpfs_i(i)->i_parent_dir = new_dir->i_ino;
if (S_ISDIR(i->i_mode)) { if (S_ISDIR(i->i_mode)) {
...@@ -642,22 +604,14 @@ static int hpfs_rename(struct inode *old_dir, struct dentry *old_dentry, ...@@ -642,22 +604,14 @@ static int hpfs_rename(struct inode *old_dir, struct dentry *old_dentry,
drop_nlink(old_dir); drop_nlink(old_dir);
} }
if ((fnode = hpfs_map_fnode(i->i_sb, i->i_ino, &bh))) { if ((fnode = hpfs_map_fnode(i->i_sb, i->i_ino, &bh))) {
fnode->up = new_dir->i_ino; fnode->up = cpu_to_le32(new_dir->i_ino);
fnode->len = new_len; fnode->len = new_len;
memcpy(fnode->name, new_name, new_len>15?15:new_len); memcpy(fnode->name, new_name, new_len>15?15:new_len);
if (new_len < 15) memset(&fnode->name[new_len], 0, 15 - new_len); if (new_len < 15) memset(&fnode->name[new_len], 0, 15 - new_len);
mark_buffer_dirty(bh); mark_buffer_dirty(bh);
brelse(bh); brelse(bh);
} }
hpfs_i(i)->i_conv = hpfs_sb(i->i_sb)->sb_conv;
hpfs_decide_conv(i, new_name, new_len);
end1: end1:
if (old_dir != new_dir)
mutex_unlock(&hpfs_i(new_dir)->i_mutex);
mutex_unlock(&hpfs_i(old_dir)->i_mutex);
mutex_unlock(&hpfs_i(i)->i_parent_mutex);
if (new_inode)
mutex_unlock(&hpfs_i(new_inode)->i_parent_mutex);
hpfs_unlock(i->i_sb); hpfs_unlock(i->i_sb);
return err; return err;
} }
......
...@@ -18,15 +18,16 @@ ...@@ -18,15 +18,16 @@
/* Mark the filesystem dirty, so that chkdsk checks it when os/2 booted */ /* Mark the filesystem dirty, so that chkdsk checks it when os/2 booted */
static void mark_dirty(struct super_block *s) static void mark_dirty(struct super_block *s, int remount)
{ {
if (hpfs_sb(s)->sb_chkdsk && !(s->s_flags & MS_RDONLY)) { if (hpfs_sb(s)->sb_chkdsk && (remount || !(s->s_flags & MS_RDONLY))) {
struct buffer_head *bh; struct buffer_head *bh;
struct hpfs_spare_block *sb; struct hpfs_spare_block *sb;
if ((sb = hpfs_map_sector(s, 17, &bh, 0))) { if ((sb = hpfs_map_sector(s, 17, &bh, 0))) {
sb->dirty = 1; sb->dirty = 1;
sb->old_wrote = 0; sb->old_wrote = 0;
mark_buffer_dirty(bh); mark_buffer_dirty(bh);
sync_dirty_buffer(bh);
brelse(bh); brelse(bh);
} }
} }
...@@ -40,10 +41,12 @@ static void unmark_dirty(struct super_block *s) ...@@ -40,10 +41,12 @@ static void unmark_dirty(struct super_block *s)
struct buffer_head *bh; struct buffer_head *bh;
struct hpfs_spare_block *sb; struct hpfs_spare_block *sb;
if (s->s_flags & MS_RDONLY) return; if (s->s_flags & MS_RDONLY) return;
sync_blockdev(s->s_bdev);
if ((sb = hpfs_map_sector(s, 17, &bh, 0))) { if ((sb = hpfs_map_sector(s, 17, &bh, 0))) {
sb->dirty = hpfs_sb(s)->sb_chkdsk > 1 - hpfs_sb(s)->sb_was_error; sb->dirty = hpfs_sb(s)->sb_chkdsk > 1 - hpfs_sb(s)->sb_was_error;
sb->old_wrote = hpfs_sb(s)->sb_chkdsk >= 2 && !hpfs_sb(s)->sb_was_error; sb->old_wrote = hpfs_sb(s)->sb_chkdsk >= 2 && !hpfs_sb(s)->sb_was_error;
mark_buffer_dirty(bh); mark_buffer_dirty(bh);
sync_dirty_buffer(bh);
brelse(bh); brelse(bh);
} }
} }
...@@ -63,13 +66,13 @@ void hpfs_error(struct super_block *s, const char *fmt, ...) ...@@ -63,13 +66,13 @@ void hpfs_error(struct super_block *s, const char *fmt, ...)
if (!hpfs_sb(s)->sb_was_error) { if (!hpfs_sb(s)->sb_was_error) {
if (hpfs_sb(s)->sb_err == 2) { if (hpfs_sb(s)->sb_err == 2) {
printk("; crashing the system because you wanted it\n"); printk("; crashing the system because you wanted it\n");
mark_dirty(s); mark_dirty(s, 0);
panic("HPFS panic"); panic("HPFS panic");
} else if (hpfs_sb(s)->sb_err == 1) { } else if (hpfs_sb(s)->sb_err == 1) {
if (s->s_flags & MS_RDONLY) printk("; already mounted read-only\n"); if (s->s_flags & MS_RDONLY) printk("; already mounted read-only\n");
else { else {
printk("; remounting read-only\n"); printk("; remounting read-only\n");
mark_dirty(s); mark_dirty(s, 0);
s->s_flags |= MS_RDONLY; s->s_flags |= MS_RDONLY;
} }
} else if (s->s_flags & MS_RDONLY) printk("; going on - but anything won't be destroyed because it's read-only\n"); } else if (s->s_flags & MS_RDONLY) printk("; going on - but anything won't be destroyed because it's read-only\n");
...@@ -102,9 +105,12 @@ static void hpfs_put_super(struct super_block *s) ...@@ -102,9 +105,12 @@ static void hpfs_put_super(struct super_block *s)
{ {
struct hpfs_sb_info *sbi = hpfs_sb(s); struct hpfs_sb_info *sbi = hpfs_sb(s);
hpfs_lock(s);
unmark_dirty(s);
hpfs_unlock(s);
kfree(sbi->sb_cp_table); kfree(sbi->sb_cp_table);
kfree(sbi->sb_bmp_dir); kfree(sbi->sb_bmp_dir);
unmark_dirty(s);
s->s_fs_info = NULL; s->s_fs_info = NULL;
kfree(sbi); kfree(sbi);
} }
...@@ -129,7 +135,7 @@ static unsigned count_bitmaps(struct super_block *s) ...@@ -129,7 +135,7 @@ static unsigned count_bitmaps(struct super_block *s)
n_bands = (hpfs_sb(s)->sb_fs_size + 0x3fff) >> 14; n_bands = (hpfs_sb(s)->sb_fs_size + 0x3fff) >> 14;
count = 0; count = 0;
for (n = 0; n < n_bands; n++) for (n = 0; n < n_bands; n++)
count += hpfs_count_one_bitmap(s, hpfs_sb(s)->sb_bmp_dir[n]); count += hpfs_count_one_bitmap(s, le32_to_cpu(hpfs_sb(s)->sb_bmp_dir[n]));
return count; return count;
} }
...@@ -188,8 +194,6 @@ static void init_once(void *foo) ...@@ -188,8 +194,6 @@ static void init_once(void *foo)
{ {
struct hpfs_inode_info *ei = (struct hpfs_inode_info *) foo; struct hpfs_inode_info *ei = (struct hpfs_inode_info *) foo;
mutex_init(&ei->i_mutex);
mutex_init(&ei->i_parent_mutex);
inode_init_once(&ei->vfs_inode); inode_init_once(&ei->vfs_inode);
} }
...@@ -218,7 +222,6 @@ static void destroy_inodecache(void) ...@@ -218,7 +222,6 @@ static void destroy_inodecache(void)
enum { enum {
Opt_help, Opt_uid, Opt_gid, Opt_umask, Opt_case_lower, Opt_case_asis, Opt_help, Opt_uid, Opt_gid, Opt_umask, Opt_case_lower, Opt_case_asis,
Opt_conv_binary, Opt_conv_text, Opt_conv_auto,
Opt_check_none, Opt_check_normal, Opt_check_strict, Opt_check_none, Opt_check_normal, Opt_check_strict,
Opt_err_cont, Opt_err_ro, Opt_err_panic, Opt_err_cont, Opt_err_ro, Opt_err_panic,
Opt_eas_no, Opt_eas_ro, Opt_eas_rw, Opt_eas_no, Opt_eas_ro, Opt_eas_rw,
...@@ -233,9 +236,6 @@ static const match_table_t tokens = { ...@@ -233,9 +236,6 @@ static const match_table_t tokens = {
{Opt_umask, "umask=%o"}, {Opt_umask, "umask=%o"},
{Opt_case_lower, "case=lower"}, {Opt_case_lower, "case=lower"},
{Opt_case_asis, "case=asis"}, {Opt_case_asis, "case=asis"},
{Opt_conv_binary, "conv=binary"},
{Opt_conv_text, "conv=text"},
{Opt_conv_auto, "conv=auto"},
{Opt_check_none, "check=none"}, {Opt_check_none, "check=none"},
{Opt_check_normal, "check=normal"}, {Opt_check_normal, "check=normal"},
{Opt_check_strict, "check=strict"}, {Opt_check_strict, "check=strict"},
...@@ -253,7 +253,7 @@ static const match_table_t tokens = { ...@@ -253,7 +253,7 @@ static const match_table_t tokens = {
}; };
static int parse_opts(char *opts, uid_t *uid, gid_t *gid, umode_t *umask, static int parse_opts(char *opts, uid_t *uid, gid_t *gid, umode_t *umask,
int *lowercase, int *conv, int *eas, int *chk, int *errs, int *lowercase, int *eas, int *chk, int *errs,
int *chkdsk, int *timeshift) int *chkdsk, int *timeshift)
{ {
char *p; char *p;
...@@ -295,15 +295,6 @@ static int parse_opts(char *opts, uid_t *uid, gid_t *gid, umode_t *umask, ...@@ -295,15 +295,6 @@ static int parse_opts(char *opts, uid_t *uid, gid_t *gid, umode_t *umask,
case Opt_case_asis: case Opt_case_asis:
*lowercase = 0; *lowercase = 0;
break; break;
case Opt_conv_binary:
*conv = CONV_BINARY;
break;
case Opt_conv_text:
*conv = CONV_TEXT;
break;
case Opt_conv_auto:
*conv = CONV_AUTO;
break;
case Opt_check_none: case Opt_check_none:
*chk = 0; *chk = 0;
break; break;
...@@ -370,9 +361,6 @@ HPFS filesystem options:\n\ ...@@ -370,9 +361,6 @@ HPFS filesystem options:\n\
umask=xxx set mode of files that don't have mode specified in eas\n\ umask=xxx set mode of files that don't have mode specified in eas\n\
case=lower lowercase all files\n\ case=lower lowercase all files\n\
case=asis do not lowercase files (default)\n\ case=asis do not lowercase files (default)\n\
conv=binary do not convert CR/LF -> LF (default)\n\
conv=auto convert only files with known text extensions\n\
conv=text convert all files\n\
check=none no fs checks - kernel may crash on corrupted filesystem\n\ check=none no fs checks - kernel may crash on corrupted filesystem\n\
check=normal do some checks - it should not crash (default)\n\ check=normal do some checks - it should not crash (default)\n\
check=strict do extra time-consuming checks, used for debugging\n\ check=strict do extra time-consuming checks, used for debugging\n\
...@@ -394,7 +382,7 @@ static int hpfs_remount_fs(struct super_block *s, int *flags, char *data) ...@@ -394,7 +382,7 @@ static int hpfs_remount_fs(struct super_block *s, int *flags, char *data)
uid_t uid; uid_t uid;
gid_t gid; gid_t gid;
umode_t umask; umode_t umask;
int lowercase, conv, eas, chk, errs, chkdsk, timeshift; int lowercase, eas, chk, errs, chkdsk, timeshift;
int o; int o;
struct hpfs_sb_info *sbi = hpfs_sb(s); struct hpfs_sb_info *sbi = hpfs_sb(s);
char *new_opts = kstrdup(data, GFP_KERNEL); char *new_opts = kstrdup(data, GFP_KERNEL);
...@@ -405,11 +393,11 @@ static int hpfs_remount_fs(struct super_block *s, int *flags, char *data) ...@@ -405,11 +393,11 @@ static int hpfs_remount_fs(struct super_block *s, int *flags, char *data)
lock_super(s); lock_super(s);
uid = sbi->sb_uid; gid = sbi->sb_gid; uid = sbi->sb_uid; gid = sbi->sb_gid;
umask = 0777 & ~sbi->sb_mode; umask = 0777 & ~sbi->sb_mode;
lowercase = sbi->sb_lowercase; conv = sbi->sb_conv; lowercase = sbi->sb_lowercase;
eas = sbi->sb_eas; chk = sbi->sb_chk; chkdsk = sbi->sb_chkdsk; eas = sbi->sb_eas; chk = sbi->sb_chk; chkdsk = sbi->sb_chkdsk;
errs = sbi->sb_err; timeshift = sbi->sb_timeshift; errs = sbi->sb_err; timeshift = sbi->sb_timeshift;
if (!(o = parse_opts(data, &uid, &gid, &umask, &lowercase, &conv, if (!(o = parse_opts(data, &uid, &gid, &umask, &lowercase,
&eas, &chk, &errs, &chkdsk, &timeshift))) { &eas, &chk, &errs, &chkdsk, &timeshift))) {
printk("HPFS: bad mount options.\n"); printk("HPFS: bad mount options.\n");
goto out_err; goto out_err;
...@@ -427,11 +415,11 @@ static int hpfs_remount_fs(struct super_block *s, int *flags, char *data) ...@@ -427,11 +415,11 @@ static int hpfs_remount_fs(struct super_block *s, int *flags, char *data)
sbi->sb_uid = uid; sbi->sb_gid = gid; sbi->sb_uid = uid; sbi->sb_gid = gid;
sbi->sb_mode = 0777 & ~umask; sbi->sb_mode = 0777 & ~umask;
sbi->sb_lowercase = lowercase; sbi->sb_conv = conv; sbi->sb_lowercase = lowercase;
sbi->sb_eas = eas; sbi->sb_chk = chk; sbi->sb_chkdsk = chkdsk; sbi->sb_eas = eas; sbi->sb_chk = chk; sbi->sb_chkdsk = chkdsk;
sbi->sb_err = errs; sbi->sb_timeshift = timeshift; sbi->sb_err = errs; sbi->sb_timeshift = timeshift;
if (!(*flags & MS_RDONLY)) mark_dirty(s); if (!(*flags & MS_RDONLY)) mark_dirty(s, 1);
replace_mount_options(s, new_opts); replace_mount_options(s, new_opts);
...@@ -471,7 +459,7 @@ static int hpfs_fill_super(struct super_block *s, void *options, int silent) ...@@ -471,7 +459,7 @@ static int hpfs_fill_super(struct super_block *s, void *options, int silent)
uid_t uid; uid_t uid;
gid_t gid; gid_t gid;
umode_t umask; umode_t umask;
int lowercase, conv, eas, chk, errs, chkdsk, timeshift; int lowercase, eas, chk, errs, chkdsk, timeshift;
dnode_secno root_dno; dnode_secno root_dno;
struct hpfs_dirent *de = NULL; struct hpfs_dirent *de = NULL;
...@@ -479,11 +467,6 @@ static int hpfs_fill_super(struct super_block *s, void *options, int silent) ...@@ -479,11 +467,6 @@ static int hpfs_fill_super(struct super_block *s, void *options, int silent)
int o; int o;
if (num_possible_cpus() > 1) {
printk(KERN_ERR "HPFS is not SMP safe\n");
return -EINVAL;
}
save_mount_options(s, options); save_mount_options(s, options);
sbi = kzalloc(sizeof(*sbi), GFP_KERNEL); sbi = kzalloc(sizeof(*sbi), GFP_KERNEL);
...@@ -495,20 +478,20 @@ static int hpfs_fill_super(struct super_block *s, void *options, int silent) ...@@ -495,20 +478,20 @@ static int hpfs_fill_super(struct super_block *s, void *options, int silent)
sbi->sb_bmp_dir = NULL; sbi->sb_bmp_dir = NULL;
sbi->sb_cp_table = NULL; sbi->sb_cp_table = NULL;
mutex_init(&sbi->hpfs_creation_de); mutex_init(&sbi->hpfs_mutex);
hpfs_lock(s);
uid = current_uid(); uid = current_uid();
gid = current_gid(); gid = current_gid();
umask = current_umask(); umask = current_umask();
lowercase = 0; lowercase = 0;
conv = CONV_BINARY;
eas = 2; eas = 2;
chk = 1; chk = 1;
errs = 1; errs = 1;
chkdsk = 1; chkdsk = 1;
timeshift = 0; timeshift = 0;
if (!(o = parse_opts(options, &uid, &gid, &umask, &lowercase, &conv, if (!(o = parse_opts(options, &uid, &gid, &umask, &lowercase,
&eas, &chk, &errs, &chkdsk, &timeshift))) { &eas, &chk, &errs, &chkdsk, &timeshift))) {
printk("HPFS: bad mount options.\n"); printk("HPFS: bad mount options.\n");
goto bail0; goto bail0;
...@@ -526,9 +509,9 @@ static int hpfs_fill_super(struct super_block *s, void *options, int silent) ...@@ -526,9 +509,9 @@ static int hpfs_fill_super(struct super_block *s, void *options, int silent)
if (!(spareblock = hpfs_map_sector(s, 17, &bh2, 0))) goto bail3; if (!(spareblock = hpfs_map_sector(s, 17, &bh2, 0))) goto bail3;
/* Check magics */ /* Check magics */
if (/*bootblock->magic != BB_MAGIC if (/*le16_to_cpu(bootblock->magic) != BB_MAGIC
||*/ superblock->magic != SB_MAGIC ||*/ le32_to_cpu(superblock->magic) != SB_MAGIC
|| spareblock->magic != SP_MAGIC) { || le32_to_cpu(spareblock->magic) != SP_MAGIC) {
if (!silent) printk("HPFS: Bad magic ... probably not HPFS\n"); if (!silent) printk("HPFS: Bad magic ... probably not HPFS\n");
goto bail4; goto bail4;
} }
...@@ -549,19 +532,18 @@ static int hpfs_fill_super(struct super_block *s, void *options, int silent) ...@@ -549,19 +532,18 @@ static int hpfs_fill_super(struct super_block *s, void *options, int silent)
s->s_op = &hpfs_sops; s->s_op = &hpfs_sops;
s->s_d_op = &hpfs_dentry_operations; s->s_d_op = &hpfs_dentry_operations;
sbi->sb_root = superblock->root; sbi->sb_root = le32_to_cpu(superblock->root);
sbi->sb_fs_size = superblock->n_sectors; sbi->sb_fs_size = le32_to_cpu(superblock->n_sectors);
sbi->sb_bitmaps = superblock->bitmaps; sbi->sb_bitmaps = le32_to_cpu(superblock->bitmaps);
sbi->sb_dirband_start = superblock->dir_band_start; sbi->sb_dirband_start = le32_to_cpu(superblock->dir_band_start);
sbi->sb_dirband_size = superblock->n_dir_band; sbi->sb_dirband_size = le32_to_cpu(superblock->n_dir_band);
sbi->sb_dmap = superblock->dir_band_bitmap; sbi->sb_dmap = le32_to_cpu(superblock->dir_band_bitmap);
sbi->sb_uid = uid; sbi->sb_uid = uid;
sbi->sb_gid = gid; sbi->sb_gid = gid;
sbi->sb_mode = 0777 & ~umask; sbi->sb_mode = 0777 & ~umask;
sbi->sb_n_free = -1; sbi->sb_n_free = -1;
sbi->sb_n_free_dnodes = -1; sbi->sb_n_free_dnodes = -1;
sbi->sb_lowercase = lowercase; sbi->sb_lowercase = lowercase;
sbi->sb_conv = conv;
sbi->sb_eas = eas; sbi->sb_eas = eas;
sbi->sb_chk = chk; sbi->sb_chk = chk;
sbi->sb_chkdsk = chkdsk; sbi->sb_chkdsk = chkdsk;
...@@ -573,7 +555,7 @@ static int hpfs_fill_super(struct super_block *s, void *options, int silent) ...@@ -573,7 +555,7 @@ static int hpfs_fill_super(struct super_block *s, void *options, int silent)
sbi->sb_max_fwd_alloc = 0xffffff; sbi->sb_max_fwd_alloc = 0xffffff;
/* Load bitmap directory */ /* Load bitmap directory */
if (!(sbi->sb_bmp_dir = hpfs_load_bitmap_directory(s, superblock->bitmaps))) if (!(sbi->sb_bmp_dir = hpfs_load_bitmap_directory(s, le32_to_cpu(superblock->bitmaps))))
goto bail4; goto bail4;
/* Check for general fs errors*/ /* Check for general fs errors*/
...@@ -591,20 +573,20 @@ static int hpfs_fill_super(struct super_block *s, void *options, int silent) ...@@ -591,20 +573,20 @@ static int hpfs_fill_super(struct super_block *s, void *options, int silent)
mark_buffer_dirty(bh2); mark_buffer_dirty(bh2);
} }
if (spareblock->hotfixes_used || spareblock->n_spares_used) { if (le32_to_cpu(spareblock->hotfixes_used) || le32_to_cpu(spareblock->n_spares_used)) {
if (errs >= 2) { if (errs >= 2) {
printk("HPFS: Hotfixes not supported here, try chkdsk\n"); printk("HPFS: Hotfixes not supported here, try chkdsk\n");
mark_dirty(s); mark_dirty(s, 0);
goto bail4; goto bail4;
} }
hpfs_error(s, "hotfixes not supported here, try chkdsk"); hpfs_error(s, "hotfixes not supported here, try chkdsk");
if (errs == 0) printk("HPFS: Proceeding, but your filesystem will be probably corrupted by this driver...\n"); if (errs == 0) printk("HPFS: Proceeding, but your filesystem will be probably corrupted by this driver...\n");
else printk("HPFS: This driver may read bad files or crash when operating on disk with hotfixes.\n"); else printk("HPFS: This driver may read bad files or crash when operating on disk with hotfixes.\n");
} }
if (spareblock->n_dnode_spares != spareblock->n_dnode_spares_free) { if (le32_to_cpu(spareblock->n_dnode_spares) != le32_to_cpu(spareblock->n_dnode_spares_free)) {
if (errs >= 2) { if (errs >= 2) {
printk("HPFS: Spare dnodes used, try chkdsk\n"); printk("HPFS: Spare dnodes used, try chkdsk\n");
mark_dirty(s); mark_dirty(s, 0);
goto bail4; goto bail4;
} }
hpfs_error(s, "warning: spare dnodes used, try chkdsk"); hpfs_error(s, "warning: spare dnodes used, try chkdsk");
...@@ -612,26 +594,26 @@ static int hpfs_fill_super(struct super_block *s, void *options, int silent) ...@@ -612,26 +594,26 @@ static int hpfs_fill_super(struct super_block *s, void *options, int silent)
} }
if (chk) { if (chk) {
unsigned a; unsigned a;
if (superblock->dir_band_end - superblock->dir_band_start + 1 != superblock->n_dir_band || if (le32_to_cpu(superblock->dir_band_end) - le32_to_cpu(superblock->dir_band_start) + 1 != le32_to_cpu(superblock->n_dir_band) ||
superblock->dir_band_end < superblock->dir_band_start || superblock->n_dir_band > 0x4000) { le32_to_cpu(superblock->dir_band_end) < le32_to_cpu(superblock->dir_band_start) || le32_to_cpu(superblock->n_dir_band) > 0x4000) {
hpfs_error(s, "dir band size mismatch: dir_band_start==%08x, dir_band_end==%08x, n_dir_band==%08x", hpfs_error(s, "dir band size mismatch: dir_band_start==%08x, dir_band_end==%08x, n_dir_band==%08x",
superblock->dir_band_start, superblock->dir_band_end, superblock->n_dir_band); le32_to_cpu(superblock->dir_band_start), le32_to_cpu(superblock->dir_band_end), le32_to_cpu(superblock->n_dir_band));
goto bail4; goto bail4;
} }
a = sbi->sb_dirband_size; a = sbi->sb_dirband_size;
sbi->sb_dirband_size = 0; sbi->sb_dirband_size = 0;
if (hpfs_chk_sectors(s, superblock->dir_band_start, superblock->n_dir_band, "dir_band") || if (hpfs_chk_sectors(s, le32_to_cpu(superblock->dir_band_start), le32_to_cpu(superblock->n_dir_band), "dir_band") ||
hpfs_chk_sectors(s, superblock->dir_band_bitmap, 4, "dir_band_bitmap") || hpfs_chk_sectors(s, le32_to_cpu(superblock->dir_band_bitmap), 4, "dir_band_bitmap") ||
hpfs_chk_sectors(s, superblock->bitmaps, 4, "bitmaps")) { hpfs_chk_sectors(s, le32_to_cpu(superblock->bitmaps), 4, "bitmaps")) {
mark_dirty(s); mark_dirty(s, 0);
goto bail4; goto bail4;
} }
sbi->sb_dirband_size = a; sbi->sb_dirband_size = a;
} else printk("HPFS: You really don't want any checks? You are crazy...\n"); } else printk("HPFS: You really don't want any checks? You are crazy...\n");
/* Load code page table */ /* Load code page table */
if (spareblock->n_code_pages) if (le32_to_cpu(spareblock->n_code_pages))
if (!(sbi->sb_cp_table = hpfs_load_code_page(s, spareblock->code_page_dir))) if (!(sbi->sb_cp_table = hpfs_load_code_page(s, le32_to_cpu(spareblock->code_page_dir))))
printk("HPFS: Warning: code page support is disabled\n"); printk("HPFS: Warning: code page support is disabled\n");
brelse(bh2); brelse(bh2);
...@@ -660,13 +642,13 @@ static int hpfs_fill_super(struct super_block *s, void *options, int silent) ...@@ -660,13 +642,13 @@ static int hpfs_fill_super(struct super_block *s, void *options, int silent)
if (!de) if (!de)
hpfs_error(s, "unable to find root dir"); hpfs_error(s, "unable to find root dir");
else { else {
root->i_atime.tv_sec = local_to_gmt(s, de->read_date); root->i_atime.tv_sec = local_to_gmt(s, le32_to_cpu(de->read_date));
root->i_atime.tv_nsec = 0; root->i_atime.tv_nsec = 0;
root->i_mtime.tv_sec = local_to_gmt(s, de->write_date); root->i_mtime.tv_sec = local_to_gmt(s, le32_to_cpu(de->write_date));
root->i_mtime.tv_nsec = 0; root->i_mtime.tv_nsec = 0;
root->i_ctime.tv_sec = local_to_gmt(s, de->creation_date); root->i_ctime.tv_sec = local_to_gmt(s, le32_to_cpu(de->creation_date));
root->i_ctime.tv_nsec = 0; root->i_ctime.tv_nsec = 0;
hpfs_i(root)->i_ea_size = de->ea_size; hpfs_i(root)->i_ea_size = le16_to_cpu(de->ea_size);
hpfs_i(root)->i_parent_dir = root->i_ino; hpfs_i(root)->i_parent_dir = root->i_ino;
if (root->i_size == -1) if (root->i_size == -1)
root->i_size = 2048; root->i_size = 2048;
...@@ -674,6 +656,7 @@ static int hpfs_fill_super(struct super_block *s, void *options, int silent) ...@@ -674,6 +656,7 @@ static int hpfs_fill_super(struct super_block *s, void *options, int silent)
root->i_blocks = 5; root->i_blocks = 5;
hpfs_brelse4(&qbh); hpfs_brelse4(&qbh);
} }
hpfs_unlock(s);
return 0; return 0;
bail4: brelse(bh2); bail4: brelse(bh2);
...@@ -681,6 +664,7 @@ bail3: brelse(bh1); ...@@ -681,6 +664,7 @@ bail3: brelse(bh1);
bail2: brelse(bh0); bail2: brelse(bh0);
bail1: bail1:
bail0: bail0:
hpfs_unlock(s);
kfree(sbi->sb_bmp_dir); kfree(sbi->sb_bmp_dir);
kfree(sbi->sb_cp_table); kfree(sbi->sb_cp_table);
s->s_fs_info = NULL; s->s_fs_info = NULL;
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment