diff options
author | Linus Torvalds <torvalds@linux-foundation.org> | 2011-05-09 09:07:55 -0700 |
---|---|---|
committer | Linus Torvalds <torvalds@linux-foundation.org> | 2011-05-09 09:07:55 -0700 |
commit | 7f4238a0ef8858e1f9b02a874b5818f6e9846673 (patch) | |
tree | 2a63b6f59b9d0f5cb3665768893caf437077bdef /fs | |
parent | 8b061610dac3a3b89770c85ad63b481a47b0c38e (diff) | |
parent | 88f4e9e870c01452e57a6943c04c8d62f6a0a7a6 (diff) | |
download | op-kernel-dev-7f4238a0ef8858e1f9b02a874b5818f6e9846673.zip op-kernel-dev-7f4238a0ef8858e1f9b02a874b5818f6e9846673.tar.gz |
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
Diffstat (limited to 'fs')
-rw-r--r-- | fs/hpfs/Kconfig | 1 | ||||
-rw-r--r-- | fs/hpfs/alloc.c | 118 | ||||
-rw-r--r-- | fs/hpfs/anode.c | 138 | ||||
-rw-r--r-- | fs/hpfs/buffer.c | 24 | ||||
-rw-r--r-- | fs/hpfs/dir.c | 22 | ||||
-rw-r--r-- | fs/hpfs/dnode.c | 174 | ||||
-rw-r--r-- | fs/hpfs/ea.c | 136 | ||||
-rw-r--r-- | fs/hpfs/file.c | 31 | ||||
-rw-r--r-- | fs/hpfs/hpfs.h | 439 | ||||
-rw-r--r-- | fs/hpfs/hpfs_fn.h | 80 | ||||
-rw-r--r-- | fs/hpfs/inode.c | 47 | ||||
-rw-r--r-- | fs/hpfs/map.c | 56 | ||||
-rw-r--r-- | fs/hpfs/name.c | 33 | ||||
-rw-r--r-- | fs/hpfs/namei.c | 106 | ||||
-rw-r--r-- | fs/hpfs/super.c | 118 |
15 files changed, 730 insertions, 793 deletions
diff --git a/fs/hpfs/Kconfig b/fs/hpfs/Kconfig index 0c39dc3..56bd15c 100644 --- a/fs/hpfs/Kconfig +++ b/fs/hpfs/Kconfig @@ -1,7 +1,6 @@ config HPFS_FS tristate "OS/2 HPFS file system support" depends on BLOCK - depends on BROKEN || !PREEMPT help 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 diff --git a/fs/hpfs/alloc.c b/fs/hpfs/alloc.c index 5503e2c..7a5eb2c 100644 --- a/fs/hpfs/alloc.c +++ b/fs/hpfs/alloc.c @@ -8,8 +8,6 @@ #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 * 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); static int chk_if_allocated(struct super_block *s, secno sec, char *msg) { struct quad_buffer_head qbh; - unsigned *bmp; + u32 *bmp; 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); goto fail1; } @@ -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) { unsigned ssec = (sec - hpfs_sb(s)->sb_dirband_start) / 4; 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); goto fail1; } @@ -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); return 0; } - lock_super(s); if (bs != ~0x3fff) { if (!(bmp = hpfs_map_bitmap(s, near >> 14, &qbh, "aib"))) goto uls; } else { @@ -85,10 +82,6 @@ static secno alloc_in_bmp(struct super_block *s, secno near, unsigned n, unsigne ret = bs + nr; goto rt; } - /*if (!tstbits(bmp, nr + n, n + forward)) { - ret = bs + nr + n; - goto rt; - }*/ q = nr + n; b = 0; while ((a = tstbits(bmp, q, n + forward)) != 0) { q += a; @@ -105,14 +98,14 @@ static secno alloc_in_bmp(struct super_block *s, secno near, unsigned n, unsigne goto rt; } nr >>= 5; - /*for (i = nr + 1; i != nr; i++, i &= 0x1ff) {*/ + /*for (i = nr + 1; i != nr; i++, i &= 0x1ff) */ i = nr; do { - if (!bmp[i]) goto cont; - if (n + forward >= 0x3f && bmp[i] != -1) goto cont; + if (!le32_to_cpu(bmp[i])) goto cont; + if (n + forward >= 0x3f && le32_to_cpu(bmp[i]) != 0xffffffff) goto cont; q = i<<5; if (i > 0) { - unsigned k = bmp[i-1]; + unsigned k = le32_to_cpu(bmp[i-1]); while (k & 0x80000000) { q--; k <<= 1; } @@ -132,18 +125,17 @@ static secno alloc_in_bmp(struct super_block *s, secno near, unsigned n, unsigne } while (i != nr); rt: 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); ret = 0; 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); } b: hpfs_brelse4(&qbh); uls: - unlock_super(s); return ret; } @@ -155,7 +147,7 @@ static secno alloc_in_bmp(struct super_block *s, secno near, unsigned n, unsigne * 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; int i; @@ -167,7 +159,6 @@ secno hpfs_alloc_sector(struct super_block *s, secno near, unsigned n, int forwa forward = -forward; f_p = 1; } - if (lock) hpfs_lock_creation(s); n_bmps = (sbi->sb_fs_size + 0x4000 - 1) >> 14; if (near && near < sbi->sb_fs_size) { 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 ret: if (sec && f_p) { 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); sec = 0; break; } } } - if (lock) hpfs_unlock_creation(s); 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; secno sec; @@ -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; nr >>= 2; - if (lock) hpfs_lock_creation(s); sec = alloc_in_bmp(s, (~0x3fff) | nr, 1, 0); - if (lock) hpfs_unlock_creation(s); if (!sec) return 0; return ((sec & 0x3fff) << 2) + sbi->sb_dirband_start; } /* 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; - unsigned *bmp; - lock_super(s); + u32 *bmp; if (!(bmp = hpfs_map_bitmap(s, sec >> 14, &qbh, "aip"))) goto end; - if (bmp[(sec & 0x3fff) >> 5] & (1 << (sec & 0x1f))) { - bmp[(sec & 0x3fff) >> 5] &= ~(1 << (sec & 0x1f)); + if (le32_to_cpu(bmp[(sec & 0x3fff) >> 5]) & (1 << (sec & 0x1f))) { + bmp[(sec & 0x3fff) >> 5] &= cpu_to_le32(~(1 << (sec & 0x1f))); hpfs_mark_4buffers_dirty(&qbh); hpfs_brelse4(&qbh); - unlock_super(s); return 1; } hpfs_brelse4(&qbh); end: - unlock_super(s); 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 */ void hpfs_free_sectors(struct super_block *s, secno sec, unsigned n) { struct quad_buffer_head qbh; - unsigned *bmp; + u32 *bmp; struct hpfs_sb_info *sbi = hpfs_sb(s); /*printk("2 - ");*/ if (!n) return; @@ -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); return; } - lock_super(s); sbi->sb_max_fwd_alloc += n > 0xffff ? 0xffff : n; if (sbi->sb_max_fwd_alloc > 0xffffff) sbi->sb_max_fwd_alloc = 0xffffff; new_map: if (!(bmp = hpfs_map_bitmap(s, sec >> 14, &qbh, "free"))) { - unlock_super(s); return; } 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_brelse4(&qbh); - unlock_super(s); return; } - bmp[(sec & 0x3fff) >> 5] |= 1 << (sec & 0x1f); + bmp[(sec & 0x3fff) >> 5] |= cpu_to_le32(1 << (sec & 0x1f)); if (!--n) { hpfs_mark_4buffers_dirty(&qbh); hpfs_brelse4(&qbh); - unlock_super(s); return; } if (!(++sec & 0x3fff)) { @@ -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 b = hpfs_sb(s)->sb_c_bitmap & 0x0fffffff; int i, j; - unsigned *bmp; + u32 *bmp; struct quad_buffer_head qbh; if ((bmp = hpfs_map_dnode_bitmap(s, &qbh))) { for (j = 0; j < 512; j++) { unsigned k; - if (!bmp[j]) continue; - for (k = bmp[j]; k; k >>= 1) if (k & 1) if (!--n) { + if (!le32_to_cpu(bmp[j])) continue; + for (k = le32_to_cpu(bmp[j]); k; k >>= 1) if (k & 1) if (!--n) { hpfs_brelse4(&qbh); return 0; } @@ -352,10 +324,10 @@ int hpfs_check_free_dnodes(struct super_block *s, int n) chk_bmp: if (bmp) { for (j = 0; j < 512; j++) { - unsigned k; - if (!bmp[j]) continue; + u32 k; + if (!le32_to_cpu(bmp[j])) continue; for (k = 0xf; k; k <<= 4) - if ((bmp[j] & k) == k) { + if ((le32_to_cpu(bmp[j]) & k) == k) { if (!--n) { hpfs_brelse4(&qbh); return 0; @@ -379,44 +351,40 @@ void hpfs_free_dnode(struct super_block *s, dnode_secno dno) hpfs_free_sectors(s, dno, 4); } else { struct quad_buffer_head qbh; - unsigned *bmp; + u32 *bmp; unsigned ssec = (dno - hpfs_sb(s)->sb_dirband_start) / 4; - lock_super(s); if (!(bmp = hpfs_map_dnode_bitmap(s, &qbh))) { - unlock_super(s); return; } - bmp[ssec >> 5] |= 1 << (ssec & 0x1f); + bmp[ssec >> 5] |= cpu_to_le32(1 << (ssec & 0x1f)); hpfs_mark_4buffers_dirty(&qbh); hpfs_brelse4(&qbh); - unlock_super(s); } } struct dnode *hpfs_alloc_dnode(struct super_block *s, secno near, - dnode_secno *dno, struct quad_buffer_head *qbh, - int lock) + dnode_secno *dno, struct quad_buffer_head *qbh) { struct dnode *d; if (hpfs_count_one_bitmap(s, hpfs_sb(s)->sb_dmap) > FREE_DNODES_ADD) { - if (!(*dno = alloc_in_dirband(s, near, lock))) - if (!(*dno = hpfs_alloc_sector(s, near, 4, 0, lock))) return NULL; + if (!(*dno = alloc_in_dirband(s, near))) + if (!(*dno = hpfs_alloc_sector(s, near, 4, 0))) return NULL; } else { - if (!(*dno = hpfs_alloc_sector(s, near, 4, 0, lock))) - if (!(*dno = alloc_in_dirband(s, near, lock))) return NULL; + if (!(*dno = hpfs_alloc_sector(s, near, 4, 0))) + if (!(*dno = alloc_in_dirband(s, near))) return NULL; } if (!(d = hpfs_get_4sectors(s, *dno, qbh))) { hpfs_free_dnode(s, *dno); return NULL; } memset(d, 0, 2048); - d->magic = DNODE_MAGIC; - d->first_free = 52; + d->magic = cpu_to_le32(DNODE_MAGIC); + d->first_free = cpu_to_le32(52); d->dirent[0] = 32; d->dirent[2] = 8; d->dirent[30] = 1; d->dirent[31] = 255; - d->self = *dno; + d->self = cpu_to_le32(*dno); return d; } @@ -424,16 +392,16 @@ struct fnode *hpfs_alloc_fnode(struct super_block *s, secno near, fnode_secno *f struct buffer_head **bh) { 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))) { hpfs_free_sectors(s, *fno, 1); return NULL; } memset(f, 0, 512); - f->magic = FNODE_MAGIC; - f->ea_offs = 0xc4; + f->magic = cpu_to_le32(FNODE_MAGIC); + f->ea_offs = cpu_to_le16(0xc4); f->btree.n_free_nodes = 8; - f->btree.first_free = 8; + f->btree.first_free = cpu_to_le16(8); return f; } @@ -441,16 +409,16 @@ struct anode *hpfs_alloc_anode(struct super_block *s, secno near, anode_secno *a struct buffer_head **bh) { 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))) { hpfs_free_sectors(s, *ano, 1); return NULL; } memset(a, 0, 512); - a->magic = ANODE_MAGIC; - a->self = *ano; + a->magic = cpu_to_le32(ANODE_MAGIC); + a->self = cpu_to_le32(*ano); a->btree.n_free_nodes = 40; a->btree.n_used_nodes = 0; - a->btree.first_free = 8; + a->btree.first_free = cpu_to_le16(8); return a; } diff --git a/fs/hpfs/anode.c b/fs/hpfs/anode.c index 6a2f04b..08b503e8 100644 --- a/fs/hpfs/anode.c +++ b/fs/hpfs/anode.c @@ -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 (btree->internal) { for (i = 0; i < btree->n_used_nodes; i++) - if (btree->u.internal[i].file_secno > sec) { - a = btree->u.internal[i].down; + if (le32_to_cpu(btree->u.internal[i].file_secno) > sec) { + a = le32_to_cpu(btree->u.internal[i].down); brelse(bh); if (!(anode = hpfs_map_anode(s, a, &bh))) return -1; btree = &anode->btree; @@ -34,18 +34,18 @@ secno hpfs_bplus_lookup(struct super_block *s, struct inode *inode, return -1; } for (i = 0; i < btree->n_used_nodes; i++) - if (btree->u.external[i].file_secno <= sec && - btree->u.external[i].file_secno + btree->u.external[i].length > sec) { - a = btree->u.external[i].disk_secno + sec - btree->u.external[i].file_secno; + if (le32_to_cpu(btree->u.external[i].file_secno) <= sec && + le32_to_cpu(btree->u.external[i].file_secno) + le32_to_cpu(btree->u.external[i].length) > sec) { + 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")) { brelse(bh); return -1; } if (inode) { struct hpfs_inode_info *hpfs_inode = hpfs_i(inode); - hpfs_inode->i_file_sec = btree->u.external[i].file_secno; - hpfs_inode->i_disk_sec = btree->u.external[i].disk_secno; - hpfs_inode->i_n_secs = btree->u.external[i].length; + hpfs_inode->i_file_sec = le32_to_cpu(btree->u.external[i].file_secno); + hpfs_inode->i_disk_sec = le32_to_cpu(btree->u.external[i].disk_secno); + hpfs_inode->i_n_secs = le32_to_cpu(btree->u.external[i].length); } brelse(bh); return a; @@ -83,8 +83,8 @@ secno hpfs_add_sector_to_btree(struct super_block *s, secno node, int fnod, unsi return -1; } if (btree->internal) { - a = btree->u.internal[n].down; - btree->u.internal[n].file_secno = -1; + a = le32_to_cpu(btree->u.internal[n].down); + btree->u.internal[n].file_secno = cpu_to_le32(-1); mark_buffer_dirty(bh); brelse(bh); 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 goto go_down; } 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", - 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); brelse(bh); return -1; } - if (hpfs_alloc_if_possible(s, se = btree->u.external[n].disk_secno + btree->u.external[n].length)) { - 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 = cpu_to_le32(le32_to_cpu(btree->u.external[n].length) + 1); mark_buffer_dirty(bh); brelse(bh); return se; @@ -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; } - 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); 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) { - up = a != node ? anode->up : -1; + up = a != node ? le32_to_cpu(anode->up) : -1; if (!(anode = hpfs_alloc_anode(s, a, &na, &bh1))) { brelse(bh); hpfs_free_sectors(s, se, 1); return -1; } if (a == node && fnod) { - anode->up = node; + anode->up = cpu_to_le32(node); anode->btree.fnode_parent = 1; anode->btree.n_used_nodes = btree->n_used_nodes; 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 btree->internal = 1; btree->n_free_nodes = 11; btree->n_used_nodes = 1; - btree->first_free = (char *)&(btree->u.internal[1]) - (char *)btree; - btree->u.internal[0].file_secno = -1; - btree->u.internal[0].down = na; + btree->first_free = cpu_to_le16((char *)&(btree->u.internal[1]) - (char *)btree); + btree->u.internal[0].file_secno = cpu_to_le32(-1); + btree->u.internal[0].down = cpu_to_le32(na); mark_buffer_dirty(bh); } else if (!(ranode = hpfs_alloc_anode(s, /*a*/0, &ra, &bh2))) { brelse(bh); @@ -153,15 +153,15 @@ secno hpfs_add_sector_to_btree(struct super_block *s, secno node, int fnod, unsi btree = &anode->btree; } btree->n_free_nodes--; n = btree->n_used_nodes++; - btree->first_free += 12; - btree->u.external[n].disk_secno = se; - btree->u.external[n].file_secno = fs; - btree->u.external[n].length = 1; + btree->first_free = cpu_to_le16(le16_to_cpu(btree->first_free) + 12); + btree->u.external[n].disk_secno = cpu_to_le32(se); + btree->u.external[n].file_secno = cpu_to_le32(fs); + btree->u.external[n].length = cpu_to_le32(1); mark_buffer_dirty(bh); brelse(bh); if ((a == node && fnod) || na == -1) return se; c2 = 0; - while (up != -1) { + while (up != (anode_secno)-1) { struct anode *new_anode; if (hpfs_sb(s)->sb_chk) 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 } if (btree->n_free_nodes) { btree->n_free_nodes--; n = btree->n_used_nodes++; - btree->first_free += 8; - btree->u.internal[n].file_secno = -1; - btree->u.internal[n].down = na; - btree->u.internal[n-1].file_secno = fs; + btree->first_free = cpu_to_le16(le16_to_cpu(btree->first_free) + 8); + btree->u.internal[n].file_secno = cpu_to_le32(-1); + btree->u.internal[n].down = cpu_to_le32(na); + btree->u.internal[n-1].file_secno = cpu_to_le32(fs); mark_buffer_dirty(bh); brelse(bh); brelse(bh2); hpfs_free_sectors(s, ra, 1); if ((anode = hpfs_map_anode(s, na, &bh))) { - anode->up = up; + anode->up = cpu_to_le32(up); anode->btree.fnode_parent = up == node && fnod; mark_buffer_dirty(bh); brelse(bh); } return se; } - up = up != node ? anode->up : -1; - btree->u.internal[btree->n_used_nodes - 1].file_secno = /*fs*/-1; + up = up != node ? le32_to_cpu(anode->up) : -1; + btree->u.internal[btree->n_used_nodes - 1].file_secno = cpu_to_le32(/*fs*/-1); mark_buffer_dirty(bh); brelse(bh); a = na; if ((new_anode = hpfs_alloc_anode(s, a, &na, &bh))) { anode = new_anode; - /*anode->up = up != -1 ? up : ra;*/ + /*anode->up = cpu_to_le32(up != -1 ? up : ra);*/ anode->btree.internal = 1; anode->btree.n_used_nodes = 1; anode->btree.n_free_nodes = 59; - anode->btree.first_free = 16; - anode->btree.u.internal[0].down = a; - anode->btree.u.internal[0].file_secno = -1; + anode->btree.first_free = cpu_to_le16(16); + anode->btree.u.internal[0].down = cpu_to_le32(a); + anode->btree.u.internal[0].file_secno = cpu_to_le32(-1); mark_buffer_dirty(bh); brelse(bh); if ((anode = hpfs_map_anode(s, a, &bh))) { - anode->up = na; + anode->up = cpu_to_le32(na); mark_buffer_dirty(bh); brelse(bh); } } else na = a; } if ((anode = hpfs_map_anode(s, na, &bh))) { - anode->up = node; + anode->up = cpu_to_le32(node); if (fnod) anode->btree.fnode_parent = 1; mark_buffer_dirty(bh); brelse(bh); @@ -232,14 +232,14 @@ secno hpfs_add_sector_to_btree(struct super_block *s, secno node, int fnod, unsi } btree = &fnode->btree; } - ranode->up = node; - memcpy(&ranode->btree, btree, btree->first_free); + ranode->up = cpu_to_le32(node); + memcpy(&ranode->btree, btree, le16_to_cpu(btree->first_free)); if (fnod) ranode->btree.fnode_parent = 1; ranode->btree.n_free_nodes = (ranode->btree.internal ? 60 : 40) - ranode->btree.n_used_nodes; if (ranode->btree.internal) for (n = 0; n < ranode->btree.n_used_nodes; n++) { struct anode *unode; - if ((unode = hpfs_map_anode(s, ranode->u.internal[n].down, &bh1))) { - unode->up = ra; + if ((unode = hpfs_map_anode(s, le32_to_cpu(ranode->u.internal[n].down), &bh1))) { + unode->up = cpu_to_le32(ra); unode->btree.fnode_parent = 0; mark_buffer_dirty(bh1); brelse(bh1); @@ -248,11 +248,11 @@ secno hpfs_add_sector_to_btree(struct super_block *s, secno node, int fnod, unsi btree->internal = 1; btree->n_free_nodes = fnod ? 10 : 58; btree->n_used_nodes = 2; - btree->first_free = (char *)&btree->u.internal[2] - (char *)btree; - btree->u.internal[0].file_secno = fs; - btree->u.internal[0].down = ra; - btree->u.internal[1].file_secno = -1; - btree->u.internal[1].down = na; + btree->first_free = cpu_to_le16((char *)&btree->u.internal[2] - (char *)btree); + btree->u.internal[0].file_secno = cpu_to_le32(fs); + btree->u.internal[0].down = cpu_to_le32(ra); + btree->u.internal[1].file_secno = cpu_to_le32(-1); + btree->u.internal[1].down = cpu_to_le32(na); mark_buffer_dirty(bh); brelse(bh); mark_buffer_dirty(bh2); @@ -279,7 +279,7 @@ void hpfs_remove_btree(struct super_block *s, struct bplus_header *btree) go_down: d2 = 0; while (btree1->internal) { - ano = btree1->u.internal[pos].down; + ano = le32_to_cpu(btree1->u.internal[pos].down); if (level) brelse(bh); if (hpfs_sb(s)->sb_chk) 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) pos = 0; } 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: if (!level) return; brelse(bh); @@ -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; hpfs_free_sectors(s, ano, 1); oano = ano; - ano = anode->up; + ano = le32_to_cpu(anode->up); if (--level) { if (!(anode = hpfs_map_anode(s, ano, &bh))) return; btree1 = &anode->btree; } else btree1 = btree; 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) goto go_down; else @@ -411,7 +411,7 @@ void hpfs_truncate_btree(struct super_block *s, secno f, int fno, unsigned secs) if (fno) { btree->n_free_nodes = 8; btree->n_used_nodes = 0; - btree->first_free = 8; + btree->first_free = cpu_to_le16(8); btree->internal = 0; mark_buffer_dirty(bh); } 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) while (btree->internal) { nodes = btree->n_used_nodes + btree->n_free_nodes; 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); hpfs_error(s, "internal btree %08x doesn't end with -1", node); return; f: 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_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); - if (btree->u.internal[i].file_secno == secs) { + if (btree->u.internal[i].file_secno == cpu_to_le32(secs)) { brelse(bh); return; } - node = btree->u.internal[i].down; + node = le32_to_cpu(btree->u.internal[i].down); brelse(bh); if (hpfs_sb(s)->sb_chk) 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) } nodes = btree->n_used_nodes + btree->n_free_nodes; 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); return; 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); if (i) i--; } - else if (btree->u.external[i].file_secno + btree->u.external[i].length > secs) { - hpfs_free_sectors(s, btree->u.external[i].disk_secno + secs - - btree->u.external[i].file_secno, btree->u.external[i].length - - secs + btree->u.external[i].file_secno); /* I hope gcc optimizes this :-) */ - btree->u.external[i].length = secs - btree->u.external[i].file_secno; + else if (le32_to_cpu(btree->u.external[i].file_secno) + le32_to_cpu(btree->u.external[i].length) > secs) { + hpfs_free_sectors(s, le32_to_cpu(btree->u.external[i].disk_secno) + secs - + le32_to_cpu(btree->u.external[i].file_secno), le32_to_cpu(btree->u.external[i].length) + - secs + le32_to_cpu(btree->u.external[i].file_secno)); /* I hope gcc optimizes this :-) */ + 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++) - 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_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); brelse(bh); } @@ -480,12 +480,12 @@ void hpfs_remove_fnode(struct super_block *s, fnode_secno fno) struct extended_attribute *ea_end; if (!(fnode = hpfs_map_fnode(s, fno, &bh))) return; 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); for (ea = fnode_ea(fnode); ea < ea_end; ea = next_ea(ea)) if (ea->indirect) hpfs_ea_remove(s, ea_sec(ea), ea->anode, ea_len(ea)); - hpfs_ea_ext_remove(s, 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); hpfs_free_sectors(s, fno, 1); } diff --git a/fs/hpfs/buffer.c b/fs/hpfs/buffer.c index 793cb9d..9ecde27 100644 --- a/fs/hpfs/buffer.c +++ b/fs/hpfs/buffer.c @@ -9,22 +9,6 @@ #include <linux/slab.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. */ 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 { struct buffer_head *bh; + hpfs_lock_assert(s); + cond_resched(); *bhp = bh = sb_bread(s, secno); @@ -50,6 +36,8 @@ void *hpfs_get_sector(struct super_block *s, unsigned secno, struct buffer_head struct buffer_head *bh; /*return hpfs_map_sector(s, secno, bhp, 0);*/ + hpfs_lock_assert(s); + cond_resched(); 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 struct buffer_head *bh; char *data; + hpfs_lock_assert(s); + cond_resched(); if (secno & 3) { @@ -125,6 +115,8 @@ void *hpfs_get_4sectors(struct super_block *s, unsigned secno, { cond_resched(); + hpfs_lock_assert(s); + if (secno & 3) { printk("HPFS: hpfs_get_4sectors: unaligned read\n"); return NULL; diff --git a/fs/hpfs/dir.c b/fs/hpfs/dir.c index b3d7c0d..f46ae02 100644 --- a/fs/hpfs/dir.c +++ b/fs/hpfs/dir.c @@ -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", (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; - 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); if (e) { @@ -156,7 +156,7 @@ static int hpfs_readdir(struct file *filp, void *dirent, filldir_t filldir) goto again; } 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; if (tempname != de->name) kfree(tempname); hpfs_brelse4(&qbh); @@ -221,7 +221,7 @@ struct dentry *hpfs_lookup(struct inode *dir, struct dentry *dentry, struct name * Get inode number, what we're after. */ - ino = de->fnode; + ino = le32_to_cpu(de->fnode); /* * Go find or make an inode. @@ -236,7 +236,7 @@ struct dentry *hpfs_lookup(struct inode *dir, struct dentry *dentry, struct name hpfs_init_inode(result); if (de->directory) 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); else { result->i_mode |= S_IFREG; @@ -250,8 +250,6 @@ struct dentry *hpfs_lookup(struct inode *dir, struct dentry *dentry, struct name hpfs_result = hpfs_i(result); 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)) { 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; @@ -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 = 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_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_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; - 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) result->i_mode &= ~0222; if (!de->directory) { 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; hpfs_i(result)->mmu_private = result->i_size; /* diff --git a/fs/hpfs/dnode.c b/fs/hpfs/dnode.c index 9b2ffad..1e0e2ac 100644 --- a/fs/hpfs/dnode.c +++ b/fs/hpfs/dnode.c @@ -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); int i = 1; 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++; } 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) @@ -130,29 +130,30 @@ static void set_last_pointer(struct super_block *s, struct dnode *d, dnode_secno { struct hpfs_dirent *de; 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; } if (hpfs_sb(s)->sb_chk) { if (de->down) { 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; } - if (de->length != 32) { - hpfs_error(s, "set_last_pointer: bad last dirent in dnode %08x", d->self); + if (le16_to_cpu(de->length) != 32) { + hpfs_error(s, "set_last_pointer: bad last dirent in dnode %08x", le32_to_cpu(d->self)); return; } } if (ptr) { - if ((d->first_free += 4) > 2048) { - hpfs_error(s,"set_last_pointer: too long dnode %08x", d->self); - d->first_free -= 4; + d->first_free = cpu_to_le32(le32_to_cpu(d->first_free) + 4); + if (le32_to_cpu(d->first_free) > 2048) { + 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; } - de->length = 36; + de->length = cpu_to_le16(36); 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, 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); 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; } if (c < 0) break; @@ -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); memset(de, 0, d_size); 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->length = d_size; - if (down_ptr) de->down = 1; + de->length = cpu_to_le16(d_size); de->not_8x3 = hpfs_is_name_long(name, namelen); de->namelen = 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; } @@ -194,25 +194,25 @@ static void hpfs_delete_de(struct super_block *s, struct dnode *d, struct hpfs_dirent *de) { 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; } - d->first_free -= de->length; - memmove(de, de_next_de(de), d->first_free + (char *)d - (char *)de); + d->first_free = cpu_to_le32(le32_to_cpu(d->first_free) - le16_to_cpu(de->length)); + 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) { struct hpfs_dirent *de; 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)) if (de->down) { struct quad_buffer_head qbh; struct dnode *dd; if ((dd = hpfs_map_dnode(s, de_down_pointer(de), &qbh))) { - if (dd->up != dno || dd->root_dnode) { - dd->up = dno; + if (le32_to_cpu(dd->up) != dno || dd->root_dnode) { + dd->up = cpu_to_le32(dno); dd->root_dnode = 0; hpfs_mark_4buffers_dirty(&qbh); } @@ -262,7 +262,7 @@ static int hpfs_add_to_dnode(struct inode *i, dnode_secno dno, kfree(nname); 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; copy_de(de=hpfs_add_de(i->i_sb, d, name, namelen, down_ptr), new_de); t = get_pos(d, de); @@ -286,11 +286,11 @@ static int hpfs_add_to_dnode(struct inode *i, dnode_secno dno, kfree(nname); 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); for_all_poss(i, hpfs_pos_ins, get_pos(nd, de), 1); 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_brelse4(&qbh); kfree(nd); @@ -313,20 +313,21 @@ static int hpfs_add_to_dnode(struct inode *i, dnode_secno dno, down_ptr = adno; set_last_pointer(i->i_sb, ad, de->down ? de_down_pointer(de) : 0); de = de_next_de(de); - memmove((char *)nd + 20, de, nd->first_free + (char *)nd - (char *)de); - nd->first_free -= (char *)de - (char *)nd - 20; - memcpy(d, nd, nd->first_free); + memmove((char *)nd + 20, de, le32_to_cpu(nd->first_free) + (char *)nd - (char *)de); + nd->first_free = cpu_to_le32(le32_to_cpu(nd->first_free) - ((char *)de - (char *)nd - 20)); + memcpy(d, nd, le32_to_cpu(nd->first_free)); for_all_poss(i, hpfs_pos_del, (loff_t)dno << 4, pos); fix_up_ptrs(i->i_sb, ad); 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_brelse4(&qbh); hpfs_mark_4buffers_dirty(&qbh1); hpfs_brelse4(&qbh1); 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_brelse4(&qbh); hpfs_brelse4(&qbh1); @@ -338,7 +339,7 @@ static int hpfs_add_to_dnode(struct inode *i, dnode_secno dno, i->i_blocks += 4; rd->root_dnode = 1; 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_brelse4(&qbh); hpfs_brelse4(&qbh1); @@ -347,10 +348,11 @@ static int hpfs_add_to_dnode(struct inode *i, dnode_secno dno, kfree(nname); return 1; } - fnode->u.external[0].disk_secno = rdno; + fnode->u.external[0].disk_secno = cpu_to_le32(rdno); mark_buffer_dirty(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; hpfs_mark_4buffers_dirty(&qbh); hpfs_brelse4(&qbh); @@ -373,7 +375,7 @@ static int hpfs_add_to_dnode(struct inode *i, dnode_secno dno, int hpfs_add_dirent(struct inode *i, 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 dnode *d; @@ -403,7 +405,6 @@ int hpfs_add_dirent(struct inode *i, } } hpfs_brelse4(&qbh); - if (!cdepth) hpfs_lock_creation(i->i_sb); if (hpfs_check_free_dnodes(i->i_sb, FREE_DNODES_ADD)) { c = 1; goto ret; @@ -411,7 +412,6 @@ int hpfs_add_dirent(struct inode *i, i->i_version++; c = hpfs_add_to_dnode(i, dno, name, namelen, new_de, 0); ret: - if (!cdepth) hpfs_unlock_creation(i->i_sb); return c; } @@ -437,9 +437,9 @@ static secno move_to_top(struct inode *i, dnode_secno from, dnode_secno to) return 0; if (!(dnode = hpfs_map_dnode(i->i_sb, dno, &qbh))) return 0; 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", - dno, chk_up, dnode->up); + dno, chk_up, le32_to_cpu(dnode->up)); hpfs_brelse4(&qbh); return 0; } @@ -455,7 +455,7 @@ static secno move_to_top(struct inode *i, dnode_secno from, dnode_secno to) hpfs_brelse4(&qbh); } while (!(de = dnode_pre_last_de(dnode))) { - dnode_secno up = dnode->up; + dnode_secno up = le32_to_cpu(dnode->up); hpfs_brelse4(&qbh); hpfs_free_dnode(i->i_sb, dno); i->i_size -= 2048; @@ -474,8 +474,8 @@ static secno move_to_top(struct inode *i, dnode_secno from, dnode_secno to) hpfs_brelse4(&qbh); return 0; } - dnode->first_free -= 4; - de->length -= 4; + dnode->first_free = cpu_to_le32(le32_to_cpu(dnode->first_free) - 4); + de->length = cpu_to_le16(le16_to_cpu(de->length) - 4); de->down = 0; hpfs_mark_4buffers_dirty(&qbh); dno = up; @@ -483,12 +483,12 @@ static secno move_to_top(struct inode *i, dnode_secno from, dnode_secno to) t = get_pos(dnode, de); for_all_poss(i, hpfs_pos_subst, t, 4); 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_brelse4(&qbh); return 0; } - memcpy(nde, de, de->length); + memcpy(nde, de, le16_to_cpu(de->length)); ddno = de->down ? de_down_pointer(de) : 0; hpfs_delete_de(i->i_sb, dnode, de); set_last_pointer(i->i_sb, dnode, ddno); @@ -517,11 +517,11 @@ static void delete_empty_dnode(struct inode *i, dnode_secno dno) try_it_again: 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->first_free > 56) goto end; - if (dnode->first_free == 52 || dnode->first_free == 56) { + if (le32_to_cpu(dnode->first_free) > 56) goto end; + if (le32_to_cpu(dnode->first_free) == 52 || le32_to_cpu(dnode->first_free) == 56) { struct hpfs_dirent *de_end; int root = dnode->root_dnode; - up = dnode->up; + up = le32_to_cpu(dnode->up); de = dnode_first_de(dnode); down = de->down ? de_down_pointer(de) : 0; 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) return; } if ((d1 = hpfs_map_dnode(i->i_sb, down, &qbh1))) { - d1->up = up; + d1->up = cpu_to_le32(up); d1->root_dnode = 1; hpfs_mark_4buffers_dirty(&qbh1); hpfs_brelse4(&qbh1); } 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); brelse(bh); } @@ -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); if (!down) { de->down = 0; - de->length -= 4; - dnode->first_free -= 4; + de->length = cpu_to_le16(le16_to_cpu(de->length) - 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, - (char *)dnode + dnode->first_free - (char *)de_next_de(de)); + (char *)dnode + le32_to_cpu(dnode->first_free) - (char *)de_next_de(de)); } else { struct dnode *d1; 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))) { - d1->up = up; + d1->up = cpu_to_le32(up); hpfs_mark_4buffers_dirty(&qbh1); hpfs_brelse4(&qbh1); } } } 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; } @@ -596,18 +596,18 @@ static void delete_empty_dnode(struct inode *i, dnode_secno dno) struct quad_buffer_head qbh1; if (!de_next->down) goto endm; 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"); 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_mark_4buffers_dirty(&qbh); hpfs_brelse4(&qbh); 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); 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_brelse4(&qbh1); } @@ -635,7 +635,7 @@ static void delete_empty_dnode(struct inode *i, dnode_secno dno) struct hpfs_dirent *del = dnode_last_de(d1); dlp = del->down ? de_down_pointer(del) : 0; 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) { printk("HPFS: warning: unbalanced dnode tree, see hpfs.txt 4 more info\n"); printk("HPFS: warning: terminating balancing operation\n"); @@ -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: goin'on\n"); } - del->length += 4; + del->length = cpu_to_le16(le16_to_cpu(del->length) + 4); del->down = 1; - d1->first_free += 4; + d1->first_free = cpu_to_le32(le32_to_cpu(d1->first_free) + 4); } if (dlp && !down) { - del->length -= 4; + del->length = cpu_to_le16(le16_to_cpu(del->length) - 4); del->down = 0; - d1->first_free -= 4; + d1->first_free = cpu_to_le32(le32_to_cpu(d1->first_free) - 4); } 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; - 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"); hpfs_brelse4(&qbh1); goto endm; } hpfs_mark_4buffers_dirty(&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); 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; - 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_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, ((loff_t)up << 4) | (p - 1)); 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_brelse4(&qbh1); } @@ -701,7 +701,6 @@ int hpfs_remove_dirent(struct inode *i, dnode_secno dno, struct hpfs_dirent *de, { struct dnode *dnode = qbh->data; dnode_secno down = 0; - int lock = 0; loff_t t; if (de->first || de->last) { 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, } if (de->down) down = de_down_pointer(de); 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)) { hpfs_brelse4(qbh); - hpfs_unlock_creation(i->i_sb); return 2; } } @@ -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); for_all_poss(i, hpfs_pos_subst, 5, t); if (a) delete_empty_dnode(i, a); - if (lock) hpfs_unlock_creation(i->i_sb); return !a; } delete_empty_dnode(i, dno); - if (lock) hpfs_unlock_creation(i->i_sb); return 0; } @@ -751,8 +745,8 @@ void hpfs_count_dnodes(struct super_block *s, dnode_secno dno, int *n_dnodes, ptr = 0; go_up: if (!(dnode = hpfs_map_dnode(s, dno, &qbh))) return; - if (hpfs_sb(s)->sb_chk) if (odno && odno != -1 && dnode->up != odno) - hpfs_error(s, "hpfs_count_dnodes: bad up pointer; dnode %08x, down %08x points to %08x", odno, dno, dnode->up); + 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, le32_to_cpu(dnode->up)); de = dnode_first_de(dnode); if (ptr) while(1) { 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, if (!de->first && !de->last && n_items) (*n_items)++; if ((de = de_next_de(de)) < dnode_end_de(dnode)) goto next_de; ptr = dno; - dno = dnode->up; + dno = le32_to_cpu(dnode->up); if (dnode->root_dnode) { hpfs_brelse4(&qbh); return; @@ -824,8 +818,8 @@ dnode_secno hpfs_de_as_down_as_possible(struct super_block *s, dnode_secno dno) return d; if (!(de = map_nth_dirent(s, d, 1, &qbh, NULL))) return dno; if (hpfs_sb(s)->sb_chk) - if (up && ((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); + 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, le32_to_cpu(((struct dnode *)qbh.data)->up)); if (!de->down) { hpfs_brelse4(&qbh); return d; @@ -874,7 +868,7 @@ struct hpfs_dirent *map_pos_dirent(struct inode *inode, loff_t *posp, /* Going up */ 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; end_up_de = dnode_end_de(up_dnode); @@ -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; up_de = de_next_de(up_de)) { 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) { - *posp = ((loff_t) dnode->up << 4) + c; + *posp = ((loff_t) le32_to_cpu(dnode->up) << 4) + c; hpfs_brelse4(&qbh0); return de; } } 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); bail: @@ -1017,17 +1011,17 @@ struct hpfs_dirent *map_fnode_dirent(struct super_block *s, fnode_secno fno, /*name2[15] = 0xff;*/ 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); return NULL; } if (!upf->dirflag) { 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); return NULL; } - dno = upf->u.external[0].disk_secno; + dno = le32_to_cpu(upf->u.external[0].disk_secno); brelse(bh); go_down: downd = 0; @@ -1049,7 +1043,7 @@ struct hpfs_dirent *map_fnode_dirent(struct super_block *s, fnode_secno fno, return NULL; } next_de: - if (de->fnode == fno) { + if (le32_to_cpu(de->fnode) == fno) { kfree(name2); return de; } @@ -1065,7 +1059,7 @@ struct hpfs_dirent *map_fnode_dirent(struct super_block *s, fnode_secno fno, goto go_down; } f: - if (de->fnode == fno) { + if (le32_to_cpu(de->fnode) == fno) { kfree(name2); return de; } @@ -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 (d->root_dnode) goto not_found; downd = dno; - dno = d->up; + dno = le32_to_cpu(d->up); hpfs_brelse4(qbh); if (hpfs_sb(s)->sb_chk) if (hpfs_stop_cycles(s, downd, &d1, &d2, "map_fnode_dirent #2")) { diff --git a/fs/hpfs/ea.c b/fs/hpfs/ea.c index 45e53d9..d8b84d1 100644 --- a/fs/hpfs/ea.c +++ b/fs/hpfs/ea.c @@ -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 (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", ano ? "anode" : "sectors", a, pos); return; @@ -33,7 +33,7 @@ void hpfs_ea_ext_remove(struct super_block *s, secno a, int ano, unsigned len) return; 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); else { @@ -76,24 +76,24 @@ int hpfs_read_ea(struct super_block *s, struct fnode *fnode, char *key, unsigned pos; int ano, len; secno a; + char ex[4 + 255 + 1 + 8]; struct extended_attribute *ea; struct extended_attribute *ea_end = fnode_end_ea(fnode); for (ea = fnode_ea(fnode); ea < ea_end; ea = next_ea(ea)) if (!strcmp(ea->name, key)) { if (ea->indirect) goto indirect; - if (ea->valuelen >= size) + if (ea_valuelen(ea) >= size) return -EINVAL; - memcpy(buf, ea_data(ea), ea->valuelen); - buf[ea->valuelen] = 0; + memcpy(buf, ea_data(ea), ea_valuelen(ea)); + buf[ea_valuelen(ea)] = 0; return 0; } - a = fnode->ea_secno; - len = fnode->ea_size_l; + a = le32_to_cpu(fnode->ea_secno); + len = le32_to_cpu(fnode->ea_size_l); ano = fnode->ea_anode; pos = 0; while (pos < len) { - char ex[4 + 255 + 1 + 8]; ea = (struct extended_attribute *)ex; if (pos + 4 > len) { 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, if (!strcmp(ea->name, key)) { if (ea->indirect) goto indirect; - if (ea->valuelen >= size) + if (ea_valuelen(ea) >= size) 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; - buf[ea->valuelen] = 0; + buf[ea_valuelen(ea)] = 0; return 0; } - pos += ea->namelen + ea->valuelen + 5; + pos += ea->namelen + ea_valuelen(ea) + 5; } return -ENOENT; indirect: @@ -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 (ea->indirect) 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"); return NULL; } - memcpy(ret, ea_data(ea), ea->valuelen); - ret[ea->valuelen] = 0; + memcpy(ret, ea_data(ea), ea_valuelen(ea)); + ret[ea_valuelen(ea)] = 0; return ret; } - a = fnode->ea_secno; - len = fnode->ea_size_l; + a = le32_to_cpu(fnode->ea_secno); + len = le32_to_cpu(fnode->ea_size_l); ano = fnode->ea_anode; pos = 0; while (pos < len) { @@ -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 (ea->indirect) 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"); 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); return NULL; } - ret[ea->valuelen] = 0; + ret[ea_valuelen(ea)] = 0; return ret; } - pos += ea->namelen + ea->valuelen + 5; + pos += ea->namelen + ea_valuelen(ea) + 5; } return NULL; } @@ -202,13 +202,13 @@ void hpfs_set_ea(struct inode *inode, struct fnode *fnode, const char *key, if (ea->indirect) { if (ea_len(ea) == 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); } return; } - a = fnode->ea_secno; - len = fnode->ea_size_l; + a = le32_to_cpu(fnode->ea_secno); + len = le32_to_cpu(fnode->ea_size_l); ano = fnode->ea_anode; pos = 0; while (pos < len) { @@ -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); } else { - if (ea->valuelen == size) + if (ea_valuelen(ea) == size) hpfs_ea_write(s, a, ano, pos + 4 + ea->namelen + 1, size, data); } return; } - pos += ea->namelen + ea->valuelen + 5; + pos += ea->namelen + ea_valuelen(ea) + 5; } - if (!fnode->ea_offs) { - /*if (fnode->ea_size_s) { + if (!le16_to_cpu(fnode->ea_offs)) { + /*if (le16_to_cpu(fnode->ea_size_s)) { 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; }*/ - 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", (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; } - if ((fnode->ea_size_s || !fnode->ea_size_l) && - fnode->ea_offs + fnode->acl_size_s + fnode->ea_size_s + strlen(key) + size + 5 <= 0x200) { + if ((le16_to_cpu(fnode->ea_size_s) || !le32_to_cpu(fnode->ea_size_l)) && + 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); *(char *)ea = 0; ea->namelen = strlen(key); - ea->valuelen = size; + ea->valuelen_lo = size; + ea->valuelen_hi = size >> 8; strcpy(ea->name, key); 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; } /* Most the code here is 99.9993422% unused. I hope there are no bugs. 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; struct buffer_head *bh; 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))) { hpfs_free_sectors(s, n, 1); return; } - memcpy(data, fnode_ea(fnode), fnode->ea_size_s); - fnode->ea_size_l = fnode->ea_size_s; - fnode->ea_size_s = 0; - fnode->ea_secno = n; - fnode->ea_anode = 0; + memcpy(data, fnode_ea(fnode), le16_to_cpu(fnode->ea_size_s)); + fnode->ea_size_l = cpu_to_le32(le16_to_cpu(fnode->ea_size_s)); + fnode->ea_size_s = cpu_to_le16(0); + fnode->ea_secno = cpu_to_le32(n); + fnode->ea_anode = cpu_to_le32(0); mark_buffer_dirty(bh); brelse(bh); } - pos = fnode->ea_size_l + 5 + strlen(key) + size; - len = (fnode->ea_size_l + 511) >> 9; + pos = le32_to_cpu(fnode->ea_size_l) + 5 + strlen(key) + size; + len = (le32_to_cpu(fnode->ea_size_l) + 511) >> 9; if (pos >= 30000) goto bail; while (((pos + 511) >> 9) > len) { if (!len) { - if (!(fnode->ea_secno = hpfs_alloc_sector(s, fno, 1, 0, 1))) - goto bail; + secno q = hpfs_alloc_sector(s, fno, 1, 0); + if (!q) goto bail; + fnode->ea_secno = cpu_to_le32(q); fnode->ea_anode = 0; len++; } 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++; } else { /* 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, anode_secno a_s; if (!(anode = hpfs_alloc_anode(s, fno, &a_s, &bh))) goto bail; - anode->up = fno; + anode->up = cpu_to_le32(fno); anode->btree.fnode_parent = 1; anode->btree.n_free_nodes--; anode->btree.n_used_nodes++; - anode->btree.first_free += 12; - anode->u.external[0].disk_secno = fnode->ea_secno; - anode->u.external[0].file_secno = 0; - anode->u.external[0].length = len; + anode->btree.first_free = cpu_to_le16(le16_to_cpu(anode->btree.first_free) + 12); + anode->u.external[0].disk_secno = cpu_to_le32(le32_to_cpu(fnode->ea_secno)); + anode->u.external[0].file_secno = cpu_to_le32(0); + anode->u.external[0].length = cpu_to_le32(len); mark_buffer_dirty(bh); brelse(bh); fnode->ea_anode = 1; - fnode->ea_secno = a_s;*/ + fnode->ea_secno = cpu_to_le32(a_s);*/ secno new_sec; 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; for (i = 0; i < len; i++) { struct buffer_head *bh1, *bh2; 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); goto bail; } @@ -331,13 +333,13 @@ void hpfs_set_ea(struct inode *inode, struct fnode *fnode, const char *key, mark_buffer_dirty(bh2); brelse(bh2); } - hpfs_free_sectors(s, fnode->ea_secno, len); - fnode->ea_secno = new_sec; + hpfs_free_sectors(s, le32_to_cpu(fnode->ea_secno), len); + fnode->ea_secno = cpu_to_le32(new_sec); len = (pos + 511) >> 9; } } 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) { len++; } else { @@ -349,17 +351,17 @@ void hpfs_set_ea(struct inode *inode, struct fnode *fnode, const char *key, h[1] = strlen(key); h[2] = size & 0xff; h[3] = size >> 8; - if (hpfs_ea_write(s, fnode->ea_secno, fnode->ea_anode, 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, fnode->ea_secno, fnode->ea_anode, fnode->ea_size_l + 5 + h[1], size, data)) goto bail; - fnode->ea_size_l = pos; + if (hpfs_ea_write(s, le32_to_cpu(fnode->ea_secno), fnode->ea_anode, le32_to_cpu(fnode->ea_size_l), 4, h)) goto bail; + if (hpfs_ea_write(s, le32_to_cpu(fnode->ea_secno), fnode->ea_anode, le32_to_cpu(fnode->ea_size_l) + 4, h[1] + 1, key)) goto bail; + if (hpfs_ea_write(s, le32_to_cpu(fnode->ea_secno), fnode->ea_anode, le32_to_cpu(fnode->ea_size_l) + 5 + h[1], size, data)) goto bail; + fnode->ea_size_l = cpu_to_le32(pos); ret: hpfs_i(inode)->i_ea_size += 5 + strlen(key) + size; return; bail: - if (fnode->ea_secno) - if (fnode->ea_anode) hpfs_truncate_btree(s, fnode->ea_secno, 1, (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 fnode->ea_secno = fnode->ea_size_l = 0; + if (le32_to_cpu(fnode->ea_secno)) + if (fnode->ea_anode) hpfs_truncate_btree(s, le32_to_cpu(fnode->ea_secno), 1, (le32_to_cpu(fnode->ea_size_l) + 511) >> 9); + else hpfs_free_sectors(s, le32_to_cpu(fnode->ea_secno) + ((le32_to_cpu(fnode->ea_size_l) + 511) >> 9), len - ((le32_to_cpu(fnode->ea_size_l) + 511) >> 9)); + else fnode->ea_secno = fnode->ea_size_l = cpu_to_le32(0); } diff --git a/fs/hpfs/file.c b/fs/hpfs/file.c index 9b9eb69..89c500e 100644 --- a/fs/hpfs/file.c +++ b/fs/hpfs/file.c @@ -20,8 +20,8 @@ static int hpfs_file_release(struct inode *inode, struct file *file) int hpfs_file_fsync(struct file *file, int datasync) { - /*return file_fsync(file, datasync);*/ - return 0; /* Don't fsync :-) */ + struct inode *inode = file->f_mapping->host; + return sync_blockdev(inode->i_sb->s_bdev); } /* @@ -48,38 +48,46 @@ static secno hpfs_bmap(struct inode *inode, unsigned file_secno) static void hpfs_truncate(struct inode *i) { if (IS_IMMUTABLE(i)) return /*-EPERM*/; - hpfs_lock(i->i_sb); + hpfs_lock_assert(i->i_sb); + hpfs_i(i)->i_n_secs = 0; i->i_blocks = 1 + ((i->i_size + 511) >> 9); hpfs_i(i)->mmu_private = i->i_size; hpfs_truncate_btree(i->i_sb, i->i_ino, 1, ((i->i_size + 511) >> 9)); hpfs_write_inode(i); 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) { + int r; secno s; + hpfs_lock(inode->i_sb); s = hpfs_bmap(inode, iblock); if (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) { 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) { hpfs_truncate_btree(inode->i_sb, inode->i_ino, 1, inode->i_blocks - 1); - return -ENOSPC; + r = -ENOSPC; + goto ret_r; } inode->i_blocks++; hpfs_i(inode)->mmu_private += 512; set_buffer_new(bh_result); 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) @@ -130,8 +138,11 @@ static ssize_t hpfs_file_write(struct file *file, const char __user *buf, ssize_t retval; 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_unlock(file->f_path.dentry->d_sb); + } return retval; } diff --git a/fs/hpfs/hpfs.h b/fs/hpfs/hpfs.h index 0e84c73..8b0650a 100644 --- a/fs/hpfs/hpfs.h +++ b/fs/hpfs/hpfs.h @@ -19,9 +19,13 @@ For definitive information on HPFS, ask somebody else -- this is guesswork. There are certain to be many mistakes. */ +#if !defined(__LITTLE_ENDIAN) && !defined(__BIG_ENDIAN) +#error unknown endian +#endif + /* 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 fnode_secno; /* sector number of an fnode */ @@ -38,28 +42,28 @@ typedef u32 time32_t; /* 32-bit time_t type */ struct hpfs_boot_block { - unsigned char jmp[3]; - unsigned char oem_id[8]; - unsigned char bytes_per_sector[2]; /* 512 */ - unsigned char sectors_per_cluster; - unsigned char n_reserved_sectors[2]; - unsigned char n_fats; - unsigned char n_rootdir_entries[2]; - unsigned char n_sectors_s[2]; - unsigned char media_byte; - unsigned short sectors_per_fat; - unsigned short sectors_per_track; - unsigned short heads_per_cyl; - unsigned int n_hidden_sectors; - unsigned int n_sectors_l; /* size of partition */ - unsigned char drive_number; - unsigned char mbz; - unsigned char sig_28h; /* 28h */ - unsigned char vol_serno[4]; - unsigned char vol_label[11]; - unsigned char sig_hpfs[8]; /* "HPFS " */ - unsigned char pad[448]; - unsigned short magic; /* aa55 */ + u8 jmp[3]; + u8 oem_id[8]; + u8 bytes_per_sector[2]; /* 512 */ + u8 sectors_per_cluster; + u8 n_reserved_sectors[2]; + u8 n_fats; + u8 n_rootdir_entries[2]; + u8 n_sectors_s[2]; + u8 media_byte; + u16 sectors_per_fat; + u16 sectors_per_track; + u16 heads_per_cyl; + u32 n_hidden_sectors; + u32 n_sectors_l; /* size of partition */ + u8 drive_number; + u8 mbz; + u8 sig_28h; /* 28h */ + u8 vol_serno[4]; + u8 vol_label[11]; + u8 sig_hpfs[8]; /* "HPFS " */ + u8 pad[448]; + u16 magic; /* aa55 */ }; @@ -71,31 +75,29 @@ struct hpfs_boot_block struct hpfs_super_block { - unsigned magic; /* f995 e849 */ - unsigned magic1; /* fa53 e9c5, more magic? */ - /*unsigned huh202;*/ /* ?? 202 = N. of B. in 1.00390625 S.*/ - char version; /* version of a filesystem usually 2 */ - char funcversion; /* functional version - oldest version + u32 magic; /* f995 e849 */ + u32 magic1; /* fa53 e9c5, more magic? */ + u8 version; /* version of a filesystem usually 2 */ + u8 funcversion; /* functional version - oldest version of filesystem that can understand this disk */ - unsigned short int zero; /* 0 */ + u16 zero; /* 0 */ fnode_secno root; /* fnode of root directory */ 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 */ - unsigned zero1; /* 0 */ + u32 zero1; /* 0 */ secno badblocks; /* bad block list */ - unsigned zero3; /* 0 */ + u32 zero3; /* 0 */ 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 dir_band_start; /* first sector in dir band */ secno dir_band_end; /* last sector in dir band */ secno dir_band_bitmap; /* free space map, 1 dnode per bit */ - char volume_name[32]; /* not used */ + u8 volume_name[32]; /* not used */ 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 struct hpfs_spare_block { - unsigned magic; /* f991 1849 */ - unsigned magic1; /* fa52 29c5, more magic? */ - - unsigned dirty: 1; /* 0 clean, 1 "improperly stopped" */ - /*unsigned flag1234: 4;*/ /* unknown flags */ - unsigned sparedir_used: 1; /* spare dirblks used */ - unsigned hotfixes_used: 1; /* hotfixes used */ - unsigned bad_sector: 1; /* bad sector, corrupted disk (???) */ - unsigned bad_bitmap: 1; /* bad bitmap */ - unsigned fast: 1; /* partition was fast formatted */ - unsigned old_wrote: 1; /* old version wrote to partion */ - unsigned old_wrote_1: 1; /* old version wrote to partion (?) */ - unsigned install_dasd_limits: 1; /* HPFS386 flags */ - unsigned resynch_dasd_limits: 1; - unsigned dasd_limits_operational: 1; - unsigned multimedia_active: 1; - unsigned dce_acls_active: 1; - unsigned dasd_limits_dirty: 1; - unsigned flag67: 2; - unsigned char mm_contlgulty; - unsigned char unused; + u32 magic; /* f991 1849 */ + u32 magic1; /* fa52 29c5, more magic? */ + +#ifdef __LITTLE_ENDIAN + u8 dirty: 1; /* 0 clean, 1 "improperly stopped" */ + u8 sparedir_used: 1; /* spare dirblks used */ + u8 hotfixes_used: 1; /* hotfixes used */ + u8 bad_sector: 1; /* bad sector, corrupted disk (???) */ + u8 bad_bitmap: 1; /* bad bitmap */ + u8 fast: 1; /* partition was fast formatted */ + u8 old_wrote: 1; /* old version wrote to partion */ + u8 old_wrote_1: 1; /* old version wrote to partion (?) */ +#else + u8 old_wrote_1: 1; /* old version wrote to partion (?) */ + u8 old_wrote: 1; /* old version wrote to partion */ + u8 fast: 1; /* partition was fast formatted */ + u8 bad_bitmap: 1; /* bad bitmap */ + u8 bad_sector: 1; /* bad sector, corrupted disk (???) */ + u8 hotfixes_used: 1; /* hotfixes used */ + u8 sparedir_used: 1; /* spare dirblks used */ + 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 */ - unsigned n_spares_used; /* number of hotfixes */ - unsigned n_spares; /* number of spares in hotfix map */ - unsigned n_dnode_spares_free; /* spare dnodes unused */ - unsigned n_dnode_spares; /* length of spare_dnodes[] list, + u32 n_spares_used; /* number of hotfixes */ + u32 n_spares; /* number of spares in hotfix map */ + u32 n_dnode_spares_free; /* spare dnodes unused */ + u32 n_dnode_spares; /* length of spare_dnodes[] list, follows in this block*/ secno code_page_dir; /* code page directory block */ - unsigned n_code_pages; /* number of code pages */ - /*unsigned large_numbers[2];*/ /* ?? */ - unsigned super_crc; /* on HPFS386 and LAN Server this is + u32 n_code_pages; /* number of code pages */ + u32 super_crc; /* on HPFS386 and LAN Server this is checksum of superblock, on normal OS/2 unused */ - unsigned spare_crc; /* on HPFS386 checksum of spareblock */ - unsigned zero1[15]; /* unused */ + u32 spare_crc; /* on HPFS386 checksum of spareblock */ + u32 zero1[15]; /* unused */ 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, @@ -179,18 +202,18 @@ struct hpfs_spare_block struct code_page_directory { - unsigned magic; /* 4945 21f7 */ - unsigned n_code_pages; /* number of pointers following */ - unsigned zero1[2]; + u32 magic; /* 4945 21f7 */ + u32 n_code_pages; /* number of pointers following */ + u32 zero1[2]; struct { - unsigned short ix; /* index */ - unsigned short code_page_number; /* code page number */ - unsigned bounds; /* matches corresponding word + u16 ix; /* index */ + u16 code_page_number; /* code page number */ + u32 bounds; /* matches corresponding word in data block */ secno code_page_data; /* sector number of a code_page_data containing c.p. array */ - unsigned short index; /* index in c.p. array in that sector*/ - unsigned short unknown; /* some unknown value; usually 0; + u16 index; /* index in c.p. array in that sector*/ + u16 unknown; /* some unknown value; usually 0; 2 in Japanese version */ } array[31]; /* unknown length */ }; @@ -201,21 +224,21 @@ struct code_page_directory struct code_page_data { - unsigned magic; /* 8945 21f7 */ - unsigned n_used; /* # elements used in c_p_data[] */ - unsigned bounds[3]; /* looks a bit like + u32 magic; /* 8945 21f7 */ + u32 n_used; /* # elements used in c_p_data[] */ + u32 bounds[3]; /* looks a bit like (beg1,end1), (beg2,end2) 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] */ struct { - unsigned short ix; /* index */ - unsigned short code_page_number; /* code page number */ - unsigned short unknown; /* the same as in cp directory */ - unsigned char map[128]; /* upcase table for chars 80..ff */ - unsigned short zero2; + u16 ix; /* index */ + u16 code_page_number; /* code page number */ + u16 unknown; /* the same as in cp directory */ + u8 map[128]; /* upcase table for chars 80..ff */ + u16 zero2; } code_page[3]; - unsigned char incognita[78]; + u8 incognita[78]; }; @@ -255,50 +278,84 @@ struct code_page_data #define DNODE_MAGIC 0x77e40aae struct dnode { - unsigned magic; /* 77e4 0aae */ - unsigned first_free; /* offset from start of dnode to + u32 magic; /* 77e4 0aae */ + u32 first_free; /* offset from start of dnode to first free dir entry */ - unsigned root_dnode:1; /* Is it root dnode? */ - unsigned increment_me:31; /* some kind of activity counter? - Neither HPFS.IFS nor CHKDSK cares +#ifdef __LITTLE_ENDIAN + u8 root_dnode: 1; /* Is it root dnode? */ + 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 */ + u8 root_dnode: 1; /* Is it root dnode? */ +#endif + u8 increment_me2[3]; secno up; /* (root dnode) directory's fnode (nonroot) parent 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 { - unsigned short length; /* offset to next dirent */ - unsigned first: 1; /* set on phony ^A^A (".") entry */ - unsigned has_acl: 1; - unsigned down: 1; /* down pointer present (after name) */ - unsigned last: 1; /* set on phony \377 entry */ - unsigned has_ea: 1; /* entry has EA */ - unsigned has_xtd_perm: 1; /* has extended perm list (???) */ - unsigned has_explicit_acl: 1; - unsigned has_needea: 1; /* ?? some EA has NEEDEA set + u16 length; /* offset to next dirent */ + +#ifdef __LITTLE_ENDIAN + u8 first: 1; /* set on phony ^A^A (".") entry */ + u8 has_acl: 1; + u8 down: 1; /* down pointer present (after name) */ + u8 last: 1; /* set on phony \377 entry */ + u8 has_ea: 1; /* entry has EA */ + 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 interesting in a dir entry */ - unsigned read_only: 1; /* dos attrib */ - unsigned hidden: 1; /* dos attrib */ - unsigned system: 1; /* dos attrib */ - unsigned flag11: 1; /* would be volume label dos attrib */ - unsigned directory: 1; /* dos attrib */ - unsigned archive: 1; /* dos attrib */ - unsigned not_8x3: 1; /* name is not 8.3 */ - unsigned flag15: 1; + u8 has_explicit_acl: 1; + u8 has_xtd_perm: 1; /* has extended perm list (???) */ + u8 has_ea: 1; /* entry has EA */ + u8 last: 1; /* set on phony \377 entry */ + u8 down: 1; /* down pointer present (after name) */ + u8 has_acl: 1; + u8 first: 1; /* set on phony ^A^A (".") entry */ +#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 */ time32_t write_date; /* mtime */ - unsigned file_size; /* file length, bytes */ + u32 file_size; /* file length, bytes */ time32_t read_date; /* atime */ time32_t creation_date; /* ctime */ - unsigned ea_size; /* total EA length, bytes */ - unsigned char no_of_acls : 3; /* number of ACL's */ - unsigned char reserver : 5; - unsigned char ix; /* code page index (of filename), see + u32 ea_size; /* total EA length, bytes */ + u8 no_of_acls; /* number of ACL's (low 3 bits) */ + u8 ix; /* code page index (of filename), see struct code_page_data */ - unsigned char namelen, name[1]; /* file name */ + u8 namelen, name[1]; /* file name */ /* dnode_secno down; btree down pointer, if present, follows name on next word boundary, or maybe it precedes next dirent, which is on a word boundary. */ @@ -318,38 +375,50 @@ struct hpfs_dirent { struct bplus_leaf_node { - unsigned file_secno; /* first file sector in extent */ - unsigned length; /* length, sectors */ + u32 file_secno; /* first file sector in extent */ + u32 length; /* length, sectors */ secno disk_secno; /* first corresponding disk sector */ }; struct bplus_internal_node { - unsigned file_secno; /* subtree maps sectors < this */ + u32 file_secno; /* subtree maps sectors < this */ anode_secno down; /* pointer to subtree */ }; struct bplus_header { - unsigned hbff: 1; /* high bit of first free entry offset */ - unsigned flag1: 1; - unsigned flag2: 1; - unsigned flag3: 1; - unsigned flag4: 1; - unsigned fnode_parent: 1; /* ? we're pointed to by an fnode, +#ifdef __LITTLE_ENDIAN + u8 hbff: 1; /* high bit of first free entry offset */ + u8 flag1234: 4; + u8 fnode_parent: 1; /* ? we're pointed to by an fnode, the data btree or some ea or the main ea bootage pointer ea_secno */ /* also can get set in fnodes, which may be a chkdsk glitch or may mean this bit is irrelevant in fnodes, or this interpretation is all wet */ - unsigned binary_search: 1; /* suggest binary search (unused) */ - unsigned internal: 1; /* 1 -> (internal) tree of anodes + u8 binary_search: 1; /* suggest binary search (unused) */ + u8 internal: 1; /* 1 -> (internal) tree of anodes + 0 -> (leaf) list of extents */ +#else + u8 internal: 1; /* 1 -> (internal) tree of anodes 0 -> (leaf) list of extents */ - unsigned char fill[3]; - unsigned char n_free_nodes; /* free nodes in following array */ - unsigned char n_used_nodes; /* used nodes in following array */ - unsigned short first_free; /* offset from start of header to + u8 binary_search: 1; /* suggest binary search (unused) */ + u8 fnode_parent: 1; /* ? we're pointed to by an fnode, + the data btree or some ea or the + main ea bootage pointer ea_secno */ + /* also can get set in fnodes, which + may be a chkdsk glitch or may mean + this bit is irrelevant in fnodes, + or this interpretation is all wet */ + u8 flag1234: 4; + u8 hbff: 1; /* high bit of first free entry offset */ +#endif + 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 */ union { struct bplus_internal_node internal[0]; /* (internal) 2-word entries giving @@ -369,37 +438,38 @@ struct bplus_header struct fnode { - unsigned magic; /* f7e4 0aae */ - unsigned zero1[2]; /* read history */ - unsigned char len, name[15]; /* true length, truncated name */ + u32 magic; /* f7e4 0aae */ + u32 zero1[2]; /* read history */ + u8 len, name[15]; /* true length, truncated name */ fnode_secno up; /* pointer to file's directory fnode */ - /*unsigned zero2[3];*/ secno acl_size_l; secno acl_secno; - unsigned short acl_size_s; - char acl_anode; - char zero2; /* history bit count */ - unsigned ea_size_l; /* length of disk-resident ea's */ + u16 acl_size_s; + u8 acl_anode; + u8 zero2; /* history bit count */ + u32 ea_size_l; /* length of disk-resident ea's */ secno ea_secno; /* first sector of disk-resident ea's*/ - unsigned short ea_size_s; /* length of fnode-resident ea's */ - - unsigned flag0: 1; - unsigned ea_anode: 1; /* 1 -> ea_secno is an anode */ - unsigned flag2: 1; - unsigned flag3: 1; - unsigned flag4: 1; - unsigned flag5: 1; - unsigned flag6: 1; - unsigned flag7: 1; - unsigned dirflag: 1; /* 1 -> directory. first & only extent + u16 ea_size_s; /* length of fnode-resident ea's */ + +#ifdef __LITTLE_ENDIAN + u8 flag0: 1; + u8 ea_anode: 1; /* 1 -> ea_secno is an anode */ + u8 flag234567: 6; +#else + u8 flag234567: 6; + u8 ea_anode: 1; /* 1 -> ea_secno is an anode */ + u8 flag0: 1; +#endif + +#ifdef __LITTLE_ENDIAN + u8 dirflag: 1; /* 1 -> directory. first & only extent points to dnode. */ - unsigned flag9: 1; - unsigned flag10: 1; - unsigned flag11: 1; - unsigned flag12: 1; - unsigned flag13: 1; - unsigned flag14: 1; - unsigned flag15: 1; + u8 flag9012345: 7; +#else + u8 flag9012345: 7; + u8 dirflag: 1; /* 1 -> directory. first & only extent + points to dnode. */ +#endif struct bplus_header btree; /* b+ tree, 8 extents or 12 subtrees */ union { @@ -407,17 +477,16 @@ struct fnode struct bplus_internal_node internal[12]; } u; - unsigned file_size; /* file length, bytes */ - unsigned n_needea; /* number of EA's with NEEDEA set */ - char user_id[16]; /* unused */ - unsigned short ea_offs; /* offset from start of fnode + u32 file_size; /* file length, bytes */ + u32 n_needea; /* number of EA's with NEEDEA set */ + u8 user_id[16]; /* unused */ + u16 ea_offs; /* offset from start of fnode to first fnode-resident ea */ - char dasd_limit_treshhold; - char dasd_limit_delta; - unsigned dasd_limit; - unsigned dasd_usage; - /*unsigned zero5[2];*/ - unsigned char ea[316]; /* zero or more EA's, packed together + u8 dasd_limit_treshhold; + u8 dasd_limit_delta; + u32 dasd_limit; + u32 dasd_usage; + u8 ea[316]; /* zero or more EA's, packed together with no alignment padding. (Do not use this name, get here via fnode + ea_offs. I think.) */ @@ -430,7 +499,7 @@ struct fnode struct anode { - unsigned magic; /* 37e4 0aae */ + u32 magic; /* 37e4 0aae */ anode_secno self; /* pointer to this anode */ secno up; /* parent anode or fnode */ @@ -440,7 +509,7 @@ struct anode struct bplus_internal_node internal[60]; } u; - unsigned fill[3]; /* unused */ + u32 fill[3]; /* unused */ }; @@ -461,25 +530,31 @@ struct anode 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 */ - 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 */ - unsigned flag2: 1; - unsigned flag3: 1; - unsigned flag4: 1; - unsigned flag5: 1; - unsigned flag6: 1; - unsigned needea: 1; /* required ea */ - unsigned char namelen; /* length of name, bytes */ - unsigned short valuelen; /* length of value, bytes */ - unsigned char name[0]; + u8 indirect: 1; /* 1 -> value gives sector number + where real value starts */ +#endif + u8 namelen; /* length of name, bytes */ + u8 valuelen_lo; /* length of value, bytes */ + u8 valuelen_hi; /* length of value, bytes */ + u8 name[0]; /* - unsigned char name[namelen]; ascii attrib name - unsigned char nul; terminating '\0', not counted - unsigned char value[valuelen]; value, arbitrary + u8 name[namelen]; ascii attrib name + u8 nul; terminating '\0', not counted + u8 value[valuelen]; value, arbitrary if this.indirect, valuelen is 8 and the value is - unsigned length; real length of value, bytes + u32 length; real length of value, bytes secno secno; sector address where it starts if this.anode, the above sector number is the root of an anode tree which points to the value. diff --git a/fs/hpfs/hpfs_fn.h b/fs/hpfs/hpfs_fn.h index c15adbc..dd552f8 100644 --- a/fs/hpfs/hpfs_fn.h +++ b/fs/hpfs/hpfs_fn.h @@ -13,6 +13,7 @@ #include <linux/pagemap.h> #include <linux/buffer_head.h> #include <linux/slab.h> +#include <asm/unaligned.h> #include "hpfs.h" @@ -51,18 +52,16 @@ struct hpfs_inode_info { unsigned i_disk_sec; /* (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_conv : 2; /* (files) crlf->newline hackery */ 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_gid : 1; /* file's gid is stored in ea */ unsigned i_dirty : 1; - struct mutex i_mutex; - struct mutex i_parent_mutex; loff_t **i_rddir_off; struct inode vfs_inode; }; struct hpfs_sb_info { + struct mutex hpfs_mutex; /* global hpfs lock */ ino_t sb_root; /* inode number of root dir */ unsigned sb_fs_size; /* file system size, sectors */ unsigned sb_bitmaps; /* sector number of bitmap list */ @@ -74,7 +73,6 @@ struct hpfs_sb_info { uid_t sb_uid; /* uid from mount options */ gid_t sb_gid; /* gid 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_err : 2; /* on errs: 0-cont, 1-ro, 2-panic */ unsigned sb_chk : 2; /* checks: 0-no, 1-normal, 2-strict */ @@ -87,20 +85,9 @@ struct hpfs_sb_info { unsigned *sb_bmp_dir; /* main bitmap directory */ unsigned sb_c_bitmap; /* current bitmap */ 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; }; -/* - * 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 */ struct quad_buffer_head { @@ -113,7 +100,7 @@ struct quad_buffer_head { static inline dnode_secno de_down_pointer (struct hpfs_dirent *de) { CHKCOND(de->down,("HPFS: de_down_pointer: !de->down\n")); - return *(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 */ @@ -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) { - CHKCOND(dnode->first_free>=0x14 && dnode->first_free<=0xa00,("HPFS: dnode_end_de: dnode->first_free = %d\n",(int)dnode->first_free)); - return (void *) dnode + 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 + le32_to_cpu(dnode->first_free); } /* The dir entry after dir entry 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)); - return (void *) de + 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 + le16_to_cpu(de->length); } 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) { - 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) { - 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) { - 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) { - 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) @@ -186,13 +178,13 @@ static inline void copy_de(struct hpfs_dirent *dst, struct hpfs_dirent *src) 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; 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++) - 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 0; } @@ -200,12 +192,12 @@ static inline unsigned tstbits(unsigned *bmp, unsigned b, unsigned n) /* alloc.c */ 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); void hpfs_free_sectors(struct super_block *, secno, unsigned); int hpfs_check_free_dnodes(struct super_block *, int); 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 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); /* 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_get_sector(struct super_block *, unsigned, struct buffer_head **); 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 *); struct hpfs_dirent *hpfs_add_de(struct super_block *, struct dnode *, const unsigned char *, unsigned, secno); 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); 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); @@ -303,7 +293,6 @@ int hpfs_compare_names(struct super_block *, const unsigned char *, unsigned, const unsigned char *, unsigned, int); int hpfs_is_name_long(const unsigned char *, unsigned); void hpfs_adjust_length(const unsigned char *, unsigned *); -void hpfs_decide_conv(struct inode *, const unsigned char *, unsigned); /* namei.c */ @@ -346,21 +335,26 @@ static inline time32_t gmt_to_local(struct super_block *s, time_t t) /* * Locking: * - * hpfs_lock() is a leftover from the big kernel lock. - * Right now, these functions are empty and only left - * for documentation purposes. The file system no longer - * works on SMP systems, so the lock is not needed - * any more. + * hpfs_lock() locks the whole filesystem. It must be taken + * on any method called by the VFS. * - * If someone is interested in making it work again, this - * would be the place to start by adding a per-superblock - * mutex and fixing all the bugs and performance issues - * caused by that. + * We don't do any per-file locking anymore, it is hard to + * review and HPFS is not performance-sensitive anyway. */ 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) { + 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)); } diff --git a/fs/hpfs/inode.c b/fs/hpfs/inode.c index 87f1f78..338cd83 100644 --- a/fs/hpfs/inode.c +++ b/fs/hpfs/inode.c @@ -17,7 +17,6 @@ void hpfs_init_inode(struct inode *i) i->i_uid = hpfs_sb(sb)->sb_uid; i->i_gid = hpfs_sb(sb)->sb_gid; i->i_mode = hpfs_sb(sb)->sb_mode; - hpfs_inode->i_conv = hpfs_sb(sb)->sb_conv; i->i_size = -1; i->i_blocks = -1; @@ -116,8 +115,8 @@ void hpfs_read_inode(struct inode *i) i->i_mode |= S_IFDIR; i->i_op = &hpfs_dir_iops; i->i_fop = &hpfs_dir_ops; - hpfs_inode->i_parent_dir = fnode->up; - hpfs_inode->i_dno = fnode->u.external[0].disk_secno; + hpfs_inode->i_parent_dir = le32_to_cpu(fnode->up); + hpfs_inode->i_dno = le32_to_cpu(fnode->u.external[0].disk_secno); if (hpfs_sb(sb)->sb_chk >= 2) { struct buffer_head *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) i->i_op = &hpfs_file_iops; i->i_fop = &hpfs_file_ops; 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_data.a_ops = &hpfs_aops; hpfs_i(i)->mmu_private = i->i_size; @@ -144,7 +143,7 @@ void hpfs_read_inode(struct inode *i) static void hpfs_write_inode_ea(struct inode *i, struct fnode *fnode) { 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, we'd better not overwrite them 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) kfree(hpfs_inode->i_rddir_off); hpfs_inode->i_rddir_off = NULL; } - mutex_lock(&hpfs_inode->i_parent_mutex); if (!i->i_nlink) { - mutex_unlock(&hpfs_inode->i_parent_mutex); return; } parent = iget_locked(i->i_sb, hpfs_inode->i_parent_dir); @@ -200,14 +197,9 @@ void hpfs_write_inode(struct inode *i) hpfs_read_inode(parent); unlock_new_inode(parent); } - mutex_lock(&hpfs_inode->i_mutex); hpfs_write_inode_nolock(i); - mutex_unlock(&hpfs_inode->i_mutex); iput(parent); - } else { - mark_inode_dirty(i); } - mutex_unlock(&hpfs_inode->i_parent_mutex); } void hpfs_write_inode_nolock(struct inode *i) @@ -226,30 +218,30 @@ void hpfs_write_inode_nolock(struct inode *i) } } else de = NULL; if (S_ISREG(i->i_mode)) { - fnode->file_size = i->i_size; - if (de) de->file_size = i->i_size; + fnode->file_size = cpu_to_le32(i->i_size); + if (de) de->file_size = cpu_to_le32(i->i_size); } else if (S_ISDIR(i->i_mode)) { - fnode->file_size = 0; - if (de) de->file_size = 0; + fnode->file_size = cpu_to_le32(0); + if (de) de->file_size = cpu_to_le32(0); } hpfs_write_inode_ea(i, fnode); if (de) { - de->write_date = 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->creation_date = gmt_to_local(i->i_sb, i->i_ctime.tv_sec); + de->write_date = cpu_to_le32(gmt_to_local(i->i_sb, i->i_mtime.tv_sec)); + de->read_date = cpu_to_le32(gmt_to_local(i->i_sb, i->i_atime.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->ea_size = hpfs_inode->i_ea_size; + de->ea_size = cpu_to_le32(hpfs_inode->i_ea_size); hpfs_mark_4buffers_dirty(&qbh); hpfs_brelse4(&qbh); } if (S_ISDIR(i->i_mode)) { 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->read_date = 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->write_date = cpu_to_le32(gmt_to_local(i->i_sb, i->i_mtime.tv_sec)); + de->read_date = cpu_to_le32(gmt_to_local(i->i_sb, i->i_atime.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->ea_size = /*hpfs_inode->i_ea_size*/0; - de->file_size = 0; + de->ea_size = cpu_to_le32(/*hpfs_inode->i_ea_size*/0); + de->file_size = cpu_to_le32(0); hpfs_mark_4buffers_dirty(&qbh); hpfs_brelse4(&qbh); } else @@ -269,6 +261,10 @@ int hpfs_setattr(struct dentry *dentry, struct iattr *attr) hpfs_lock(inode->i_sb); if (inode->i_ino == hpfs_sb(inode->i_sb)->sb_root) 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) goto out_unlock; @@ -284,7 +280,6 @@ int hpfs_setattr(struct dentry *dentry, struct iattr *attr) } setattr_copy(inode, attr); - mark_inode_dirty(inode); hpfs_write_inode(inode); diff --git a/fs/hpfs/map.c b/fs/hpfs/map.c index 840d033..a790821 100644 --- a/fs/hpfs/map.c +++ b/fs/hpfs/map.c @@ -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); 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) { hpfs_error(s, "invalid bitmap block pointer %08x -> %08x at %s", bmp_block, sec, id); return NULL; @@ -46,18 +46,18 @@ unsigned char *hpfs_load_code_page(struct super_block *s, secno cps) struct code_page_data *cpd; struct code_page_directory *cp = hpfs_map_sector(s, cps, &bh, 0); if (!cp) return NULL; - if (cp->magic != CP_DIR_MAGIC) { - printk("HPFS: Code page directory magic doesn't match (magic = %08x)\n", cp->magic); + if (le32_to_cpu(cp->magic) != CP_DIR_MAGIC) { + printk("HPFS: Code page directory magic doesn't match (magic = %08x)\n", le32_to_cpu(cp->magic)); brelse(bh); return NULL; } - if (!cp->n_code_pages) { + if (!le32_to_cpu(cp->n_code_pages)) { printk("HPFS: n_code_pages == 0\n"); brelse(bh); return NULL; } - cpds = cp->array[0].code_page_data; - cpi = cp->array[0].index; + cpds = le32_to_cpu(cp->array[0].code_page_data); + cpi = le16_to_cpu(cp->array[0].index); brelse(bh); if (cpi >= 3) { @@ -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 ((unsigned)cpd->offs[cpi] > 0x178) { + if (le16_to_cpu(cpd->offs[cpi]) > 0x178) { printk("HPFS: Code page index out of sector\n"); brelse(bh); 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))) { printk("HPFS: out of memory for code page table\n"); brelse(bh); @@ -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) { struct extended_attribute *ea; 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", (unsigned long)ino); goto bail; @@ -138,7 +138,7 @@ struct fnode *hpfs_map_fnode(struct super_block *s, ino_t ino, struct buffer_hea (unsigned long)ino); 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)) { hpfs_error(s, "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 goto bail; } } - if (fnode->ea_size_s && ((signed int)fnode->ea_offs < 0xc4 || - (signed int)fnode->ea_offs + fnode->acl_size_s + fnode->ea_size_s > 0x200)) { + if (le16_to_cpu(fnode->ea_size_s) && (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, "bad EA info in fnode %08lx: ea_offs == %04x ea_size_s == %04x", (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; } ea = fnode_ea(fnode); @@ -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 ((anode = hpfs_map_sector(s, ano, bhp, ANODE_RD_AHEAD))) 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); 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 != (anode->btree.internal ? 60 : 40)) { hpfs_error(s, "bad number of nodes in anode %08x", ano); 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)) { hpfs_error(s, "bad first_free pointer in anode %08x", ano); goto bail; @@ -219,26 +223,26 @@ struct dnode *hpfs_map_dnode(struct super_block *s, unsigned secno, unsigned p, pp = 0; unsigned char *d = (unsigned char *)dnode; 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); goto bail; } - if (dnode->self != secno) - hpfs_error(s, "bad self pointer on dnode %08x self = %08x", secno, dnode->self); + if (le32_to_cpu(dnode->self) != secno) + hpfs_error(s, "bad self pointer on dnode %08x self = %08x", secno, le32_to_cpu(dnode->self)); /* Check dirents - bad dirents would cause infinite loops or shooting to memory */ - if (dnode->first_free > 2048/* || dnode->first_free < 84*/) { - hpfs_error(s, "dnode %08x has first_free == %08x", secno, dnode->first_free); + if (le32_to_cpu(dnode->first_free) > 2048) { + hpfs_error(s, "dnode %08x has first_free == %08x", secno, le32_to_cpu(dnode->first_free)); 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); - 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); goto bail; } - if (((31 + de->namelen + de->down*4 + 3) & ~3) != 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)) { + 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); goto bail; } @@ -251,7 +255,7 @@ struct dnode *hpfs_map_dnode(struct super_block *s, unsigned secno, 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); goto bail; } @@ -277,7 +281,7 @@ dnode_secno hpfs_fnode_dno(struct super_block *s, ino_t ino) if (!fnode) return 0; - dno = fnode->u.external[0].disk_secno; + dno = le32_to_cpu(fnode->u.external[0].disk_secno); brelse(bh); return dno; } diff --git a/fs/hpfs/name.c b/fs/hpfs/name.c index f24736d..9acdf33 100644 --- a/fs/hpfs/name.c +++ b/fs/hpfs/name.c @@ -8,39 +8,6 @@ #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) { return c<' ' || c=='"' || c=='*' || c=='/' || c==':' || c=='<' || diff --git a/fs/hpfs/namei.c b/fs/hpfs/namei.c index d5f8c8a..1f05839 100644 --- a/fs/hpfs/namei.c +++ b/fs/hpfs/namei.c @@ -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); if (!fnode) 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) goto bail1; memset(&dee, 0, sizeof dee); @@ -37,8 +37,8 @@ static int hpfs_mkdir(struct inode *dir, struct dentry *dentry, int mode) if (!(mode & 0222)) dee.read_only = 1; /*dee.archive = 0;*/ dee.hidden = name[0] == '.'; - dee.fnode = fno; - dee.creation_date = dee.write_date = dee.read_date = gmt_to_local(dir->i_sb, get_seconds()); + dee.fnode = cpu_to_le32(fno); + 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); if (!result) goto bail2; @@ -46,7 +46,7 @@ static int hpfs_mkdir(struct inode *dir, struct dentry *dentry, int mode) result->i_ino = fno; hpfs_i(result)->i_parent_dir = dir->i_ino; 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_mtime.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) if (dee.read_only) result->i_mode &= ~0222; - mutex_lock(&hpfs_i(dir)->i_mutex); - r = hpfs_add_dirent(dir, name, len, &dee, 0); + r = hpfs_add_dirent(dir, name, len, &dee); if (r == 1) goto bail3; if (r == -1) { @@ -70,21 +69,21 @@ static int hpfs_mkdir(struct inode *dir, struct dentry *dentry, int mode) } fnode->len = 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->btree.n_free_nodes = 7; fnode->btree.n_used_nodes = 1; - fnode->btree.first_free = 0x14; - fnode->u.external[0].disk_secno = dno; - fnode->u.external[0].file_secno = -1; + fnode->btree.first_free = cpu_to_le16(0x14); + fnode->u.external[0].disk_secno = cpu_to_le32(dno); + fnode->u.external[0].file_secno = cpu_to_le32(-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->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; de->first = de->directory = 1; /*de->hidden = de->system = 0;*/ - de->fnode = fno; + de->fnode = cpu_to_le32(fno); mark_buffer_dirty(bh); brelse(bh); hpfs_mark_4buffers_dirty(&qbh0); @@ -101,11 +100,9 @@ static int hpfs_mkdir(struct inode *dir, struct dentry *dentry, int mode) hpfs_write_inode_nolock(result); } d_instantiate(dentry, result); - mutex_unlock(&hpfs_i(dir)->i_mutex); hpfs_unlock(dir->i_sb); return 0; bail3: - mutex_unlock(&hpfs_i(dir)->i_mutex); iput(result); bail2: hpfs_brelse4(&qbh0); @@ -140,8 +137,8 @@ static int hpfs_create(struct inode *dir, struct dentry *dentry, int mode, struc if (!(mode & 0222)) dee.read_only = 1; dee.archive = 1; dee.hidden = name[0] == '.'; - dee.fnode = fno; - dee.creation_date = dee.write_date = dee.read_date = gmt_to_local(dir->i_sb, get_seconds()); + dee.fnode = cpu_to_le32(fno); + 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); if (!result) @@ -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_fop = &hpfs_file_ops; result->i_nlink = 1; - hpfs_decide_conv(result, name, len); 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_mtime.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 result->i_data.a_ops = &hpfs_aops; hpfs_i(result)->mmu_private = 0; - mutex_lock(&hpfs_i(dir)->i_mutex); - r = hpfs_add_dirent(dir, name, len, &dee, 0); + r = hpfs_add_dirent(dir, name, len, &dee); if (r == 1) goto bail2; if (r == -1) { @@ -178,7 +173,7 @@ static int hpfs_create(struct inode *dir, struct dentry *dentry, int mode, struc } fnode->len = 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); brelse(bh); @@ -193,12 +188,10 @@ static int hpfs_create(struct inode *dir, struct dentry *dentry, int mode, struc hpfs_write_inode_nolock(result); } d_instantiate(dentry, result); - mutex_unlock(&hpfs_i(dir)->i_mutex); hpfs_unlock(dir->i_sb); return 0; bail2: - mutex_unlock(&hpfs_i(dir)->i_mutex); iput(result); bail1: brelse(bh); @@ -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; dee.archive = 1; dee.hidden = name[0] == '.'; - dee.fnode = fno; - dee.creation_date = dee.write_date = dee.read_date = gmt_to_local(dir->i_sb, get_seconds()); + dee.fnode = cpu_to_le32(fno); + 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); if (!result) @@ -242,7 +235,7 @@ static int hpfs_mknod(struct inode *dir, struct dentry *dentry, int mode, dev_t hpfs_init_inode(result); result->i_ino = fno; 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_mtime.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 result->i_blocks = 1; init_special_inode(result, mode, rdev); - mutex_lock(&hpfs_i(dir)->i_mutex); - r = hpfs_add_dirent(dir, name, len, &dee, 0); + r = hpfs_add_dirent(dir, name, len, &dee); if (r == 1) goto bail2; if (r == -1) { @@ -264,19 +256,17 @@ static int hpfs_mknod(struct inode *dir, struct dentry *dentry, int mode, dev_t } fnode->len = 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); insert_inode_hash(result); hpfs_write_inode_nolock(result); d_instantiate(dentry, result); - mutex_unlock(&hpfs_i(dir)->i_mutex); brelse(bh); hpfs_unlock(dir->i_sb); return 0; bail2: - mutex_unlock(&hpfs_i(dir)->i_mutex); iput(result); bail1: brelse(bh); @@ -310,8 +300,8 @@ static int hpfs_symlink(struct inode *dir, struct dentry *dentry, const char *sy memset(&dee, 0, sizeof dee); dee.archive = 1; dee.hidden = name[0] == '.'; - dee.fnode = fno; - dee.creation_date = dee.write_date = dee.read_date = gmt_to_local(dir->i_sb, get_seconds()); + dee.fnode = cpu_to_le32(fno); + 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); if (!result) @@ -319,7 +309,7 @@ static int hpfs_symlink(struct inode *dir, struct dentry *dentry, const char *sy result->i_ino = fno; hpfs_init_inode(result); 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_mtime.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 result->i_op = &page_symlink_inode_operations; result->i_data.a_ops = &hpfs_symlink_aops; - mutex_lock(&hpfs_i(dir)->i_mutex); - r = hpfs_add_dirent(dir, name, len, &dee, 0); + r = hpfs_add_dirent(dir, name, len, &dee); if (r == 1) goto bail2; if (r == -1) { @@ -343,7 +332,7 @@ static int hpfs_symlink(struct inode *dir, struct dentry *dentry, const char *sy } fnode->len = 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)); mark_buffer_dirty(bh); brelse(bh); @@ -352,11 +341,9 @@ static int hpfs_symlink(struct inode *dir, struct dentry *dentry, const char *sy hpfs_write_inode_nolock(result); d_instantiate(dentry, result); - mutex_unlock(&hpfs_i(dir)->i_mutex); hpfs_unlock(dir->i_sb); return 0; bail2: - mutex_unlock(&hpfs_i(dir)->i_mutex); iput(result); bail1: brelse(bh); @@ -374,7 +361,6 @@ static int hpfs_unlink(struct inode *dir, struct dentry *dentry) struct hpfs_dirent *de; struct inode *inode = dentry->d_inode; dnode_secno dno; - fnode_secno fno; int r; int rep = 0; int err; @@ -382,8 +368,6 @@ static int hpfs_unlink(struct inode *dir, struct dentry *dentry) hpfs_lock(dir->i_sb); hpfs_adjust_length(name, &len); again: - mutex_lock(&hpfs_i(inode)->i_parent_mutex); - mutex_lock(&hpfs_i(dir)->i_mutex); err = -ENOENT; de = map_dirent(dir, hpfs_i(dir)->i_dno, name, len, &dno, &qbh); if (!de) @@ -397,7 +381,6 @@ again: if (de->directory) goto out1; - fno = de->fnode; r = hpfs_remove_dirent(dir, dno, de, &qbh, 1); switch (r) { case 1: @@ -410,8 +393,6 @@ again: if (rep++) break; - mutex_unlock(&hpfs_i(dir)->i_mutex); - mutex_unlock(&hpfs_i(inode)->i_parent_mutex); dentry_unhash(dentry); if (!d_unhashed(dentry)) { dput(dentry); @@ -445,8 +426,6 @@ again: out1: hpfs_brelse4(&qbh); out: - mutex_unlock(&hpfs_i(dir)->i_mutex); - mutex_unlock(&hpfs_i(inode)->i_parent_mutex); hpfs_unlock(dir->i_sb); return err; } @@ -459,15 +438,12 @@ static int hpfs_rmdir(struct inode *dir, struct dentry *dentry) struct hpfs_dirent *de; struct inode *inode = dentry->d_inode; dnode_secno dno; - fnode_secno fno; int n_items = 0; int err; int r; hpfs_adjust_length(name, &len); hpfs_lock(dir->i_sb); - mutex_lock(&hpfs_i(inode)->i_parent_mutex); - mutex_lock(&hpfs_i(dir)->i_mutex); err = -ENOENT; de = map_dirent(dir, hpfs_i(dir)->i_dno, name, len, &dno, &qbh); if (!de) @@ -486,7 +462,6 @@ static int hpfs_rmdir(struct inode *dir, struct dentry *dentry) if (n_items) goto out1; - fno = de->fnode; r = hpfs_remove_dirent(dir, dno, de, &qbh, 1); switch (r) { case 1: @@ -505,8 +480,6 @@ static int hpfs_rmdir(struct inode *dir, struct dentry *dentry) out1: hpfs_brelse4(&qbh); out: - mutex_unlock(&hpfs_i(dir)->i_mutex); - mutex_unlock(&hpfs_i(inode)->i_parent_mutex); hpfs_unlock(dir->i_sb); return err; } @@ -568,12 +541,6 @@ static int hpfs_rename(struct inode *old_dir, struct dentry *old_dentry, hpfs_lock(i->i_sb); /* 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 */ 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, 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, 1))) { - hpfs_unlock_creation(i->i_sb); + if ((r = hpfs_add_dirent(new_dir, new_name, new_len, &de))) { if (r == -1) hpfs_error(new_dir->i_sb, "hpfs_rename: dirent already exists!"); err = r == 1 ? -ENOSPC : -EFSERROR; if (new_dir != old_dir) hpfs_brelse4(&qbh); @@ -621,20 +586,17 @@ static int hpfs_rename(struct inode *old_dir, struct dentry *old_dentry, if (new_dir == old_dir) 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"); err = -ENOENT; goto end1; } 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"); err = r == 2 ? -ENOSPC : -EFSERROR; goto end1; } - hpfs_unlock_creation(i->i_sb); - + end: hpfs_i(i)->i_parent_dir = new_dir->i_ino; if (S_ISDIR(i->i_mode)) { @@ -642,22 +604,14 @@ static int hpfs_rename(struct inode *old_dir, struct dentry *old_dentry, drop_nlink(old_dir); } 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; memcpy(fnode->name, new_name, new_len>15?15:new_len); if (new_len < 15) memset(&fnode->name[new_len], 0, 15 - new_len); mark_buffer_dirty(bh); brelse(bh); } - hpfs_i(i)->i_conv = hpfs_sb(i->i_sb)->sb_conv; - hpfs_decide_conv(i, new_name, new_len); 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); return err; } diff --git a/fs/hpfs/super.c b/fs/hpfs/super.c index c89b408..98580a3 100644 --- a/fs/hpfs/super.c +++ b/fs/hpfs/super.c @@ -18,15 +18,16 @@ /* 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 hpfs_spare_block *sb; if ((sb = hpfs_map_sector(s, 17, &bh, 0))) { sb->dirty = 1; sb->old_wrote = 0; mark_buffer_dirty(bh); + sync_dirty_buffer(bh); brelse(bh); } } @@ -40,10 +41,12 @@ static void unmark_dirty(struct super_block *s) struct buffer_head *bh; struct hpfs_spare_block *sb; if (s->s_flags & MS_RDONLY) return; + sync_blockdev(s->s_bdev); if ((sb = hpfs_map_sector(s, 17, &bh, 0))) { 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; mark_buffer_dirty(bh); + sync_dirty_buffer(bh); brelse(bh); } } @@ -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_err == 2) { printk("; crashing the system because you wanted it\n"); - mark_dirty(s); + mark_dirty(s, 0); panic("HPFS panic"); } else if (hpfs_sb(s)->sb_err == 1) { if (s->s_flags & MS_RDONLY) printk("; already mounted read-only\n"); else { printk("; remounting read-only\n"); - mark_dirty(s); + mark_dirty(s, 0); 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"); @@ -102,9 +105,12 @@ static void hpfs_put_super(struct super_block *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_bmp_dir); - unmark_dirty(s); s->s_fs_info = NULL; kfree(sbi); } @@ -129,7 +135,7 @@ static unsigned count_bitmaps(struct super_block *s) n_bands = (hpfs_sb(s)->sb_fs_size + 0x3fff) >> 14; count = 0; 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; } @@ -188,8 +194,6 @@ static void init_once(void *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); } @@ -218,7 +222,6 @@ static void destroy_inodecache(void) enum { 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_err_cont, Opt_err_ro, Opt_err_panic, Opt_eas_no, Opt_eas_ro, Opt_eas_rw, @@ -233,9 +236,6 @@ static const match_table_t tokens = { {Opt_umask, "umask=%o"}, {Opt_case_lower, "case=lower"}, {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_normal, "check=normal"}, {Opt_check_strict, "check=strict"}, @@ -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, - int *lowercase, int *conv, int *eas, int *chk, int *errs, + int *lowercase, int *eas, int *chk, int *errs, int *chkdsk, int *timeshift) { char *p; @@ -295,15 +295,6 @@ static int parse_opts(char *opts, uid_t *uid, gid_t *gid, umode_t *umask, case Opt_case_asis: *lowercase = 0; 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: *chk = 0; break; @@ -370,9 +361,6 @@ HPFS filesystem options:\n\ umask=xxx set mode of files that don't have mode specified in eas\n\ case=lower lowercase all files\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=normal do some checks - it should not crash (default)\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) uid_t uid; gid_t gid; umode_t umask; - int lowercase, conv, eas, chk, errs, chkdsk, timeshift; + int lowercase, eas, chk, errs, chkdsk, timeshift; int o; struct hpfs_sb_info *sbi = hpfs_sb(s); char *new_opts = kstrdup(data, GFP_KERNEL); @@ -405,11 +393,11 @@ static int hpfs_remount_fs(struct super_block *s, int *flags, char *data) lock_super(s); uid = sbi->sb_uid; gid = sbi->sb_gid; 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; 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, ×hift))) { printk("HPFS: bad mount options.\n"); goto out_err; @@ -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_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_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); @@ -471,7 +459,7 @@ static int hpfs_fill_super(struct super_block *s, void *options, int silent) uid_t uid; gid_t gid; umode_t umask; - int lowercase, conv, eas, chk, errs, chkdsk, timeshift; + int lowercase, eas, chk, errs, chkdsk, timeshift; dnode_secno root_dno; struct hpfs_dirent *de = NULL; @@ -479,11 +467,6 @@ static int hpfs_fill_super(struct super_block *s, void *options, int silent) int o; - if (num_possible_cpus() > 1) { - printk(KERN_ERR "HPFS is not SMP safe\n"); - return -EINVAL; - } - save_mount_options(s, options); sbi = kzalloc(sizeof(*sbi), GFP_KERNEL); @@ -495,20 +478,20 @@ static int hpfs_fill_super(struct super_block *s, void *options, int silent) sbi->sb_bmp_dir = NULL; sbi->sb_cp_table = NULL; - mutex_init(&sbi->hpfs_creation_de); + mutex_init(&sbi->hpfs_mutex); + hpfs_lock(s); uid = current_uid(); gid = current_gid(); umask = current_umask(); lowercase = 0; - conv = CONV_BINARY; eas = 2; chk = 1; errs = 1; chkdsk = 1; 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, ×hift))) { printk("HPFS: bad mount options.\n"); goto bail0; @@ -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; /* Check magics */ - if (/*bootblock->magic != BB_MAGIC - ||*/ superblock->magic != SB_MAGIC - || spareblock->magic != SP_MAGIC) { + if (/*le16_to_cpu(bootblock->magic) != BB_MAGIC + ||*/ le32_to_cpu(superblock->magic) != SB_MAGIC + || le32_to_cpu(spareblock->magic) != SP_MAGIC) { if (!silent) printk("HPFS: Bad magic ... probably not HPFS\n"); goto bail4; } @@ -549,19 +532,18 @@ static int hpfs_fill_super(struct super_block *s, void *options, int silent) s->s_op = &hpfs_sops; s->s_d_op = &hpfs_dentry_operations; - sbi->sb_root = superblock->root; - sbi->sb_fs_size = superblock->n_sectors; - sbi->sb_bitmaps = superblock->bitmaps; - sbi->sb_dirband_start = superblock->dir_band_start; - sbi->sb_dirband_size = superblock->n_dir_band; - sbi->sb_dmap = superblock->dir_band_bitmap; + sbi->sb_root = le32_to_cpu(superblock->root); + sbi->sb_fs_size = le32_to_cpu(superblock->n_sectors); + sbi->sb_bitmaps = le32_to_cpu(superblock->bitmaps); + sbi->sb_dirband_start = le32_to_cpu(superblock->dir_band_start); + sbi->sb_dirband_size = le32_to_cpu(superblock->n_dir_band); + sbi->sb_dmap = le32_to_cpu(superblock->dir_band_bitmap); sbi->sb_uid = uid; sbi->sb_gid = gid; sbi->sb_mode = 0777 & ~umask; sbi->sb_n_free = -1; sbi->sb_n_free_dnodes = -1; sbi->sb_lowercase = lowercase; - sbi->sb_conv = conv; sbi->sb_eas = eas; sbi->sb_chk = chk; sbi->sb_chkdsk = chkdsk; @@ -573,7 +555,7 @@ static int hpfs_fill_super(struct super_block *s, void *options, int silent) sbi->sb_max_fwd_alloc = 0xffffff; /* 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; /* Check for general fs errors*/ @@ -591,20 +573,20 @@ static int hpfs_fill_super(struct super_block *s, void *options, int silent) 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) { printk("HPFS: Hotfixes not supported here, try chkdsk\n"); - mark_dirty(s); + mark_dirty(s, 0); goto bail4; } 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"); 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) { printk("HPFS: Spare dnodes used, try chkdsk\n"); - mark_dirty(s); + mark_dirty(s, 0); goto bail4; } 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) } if (chk) { unsigned a; - if (superblock->dir_band_end - superblock->dir_band_start + 1 != superblock->n_dir_band || - superblock->dir_band_end < superblock->dir_band_start || superblock->n_dir_band > 0x4000) { + if (le32_to_cpu(superblock->dir_band_end) - le32_to_cpu(superblock->dir_band_start) + 1 != le32_to_cpu(superblock->n_dir_band) || + 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", - 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; } a = sbi->sb_dirband_size; sbi->sb_dirband_size = 0; - if (hpfs_chk_sectors(s, superblock->dir_band_start, superblock->n_dir_band, "dir_band") || - hpfs_chk_sectors(s, superblock->dir_band_bitmap, 4, "dir_band_bitmap") || - hpfs_chk_sectors(s, superblock->bitmaps, 4, "bitmaps")) { - mark_dirty(s); + 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, le32_to_cpu(superblock->dir_band_bitmap), 4, "dir_band_bitmap") || + hpfs_chk_sectors(s, le32_to_cpu(superblock->bitmaps), 4, "bitmaps")) { + mark_dirty(s, 0); goto bail4; } sbi->sb_dirband_size = a; } else printk("HPFS: You really don't want any checks? You are crazy...\n"); /* Load code page table */ - if (spareblock->n_code_pages) - if (!(sbi->sb_cp_table = hpfs_load_code_page(s, spareblock->code_page_dir))) + if (le32_to_cpu(spareblock->n_code_pages)) + 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"); brelse(bh2); @@ -660,13 +642,13 @@ static int hpfs_fill_super(struct super_block *s, void *options, int silent) if (!de) hpfs_error(s, "unable to find root dir"); 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_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_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; - 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; if (root->i_size == -1) root->i_size = 2048; @@ -674,6 +656,7 @@ static int hpfs_fill_super(struct super_block *s, void *options, int silent) root->i_blocks = 5; hpfs_brelse4(&qbh); } + hpfs_unlock(s); return 0; bail4: brelse(bh2); @@ -681,6 +664,7 @@ bail3: brelse(bh1); bail2: brelse(bh0); bail1: bail0: + hpfs_unlock(s); kfree(sbi->sb_bmp_dir); kfree(sbi->sb_cp_table); s->s_fs_info = NULL; |