Commit 7d23ce36 authored by Mikulas Patocka's avatar Mikulas Patocka Committed by Linus Torvalds
Browse files

HPFS: Remove remaining locks



Remove remaining locks

Because of a new global per-fs lock, no other locks are needed

Signed-off-by: default avatarMikulas Patocka <mikulas@artax.karlin.mff.cuni.cz>
Signed-off-by: default avatarLinus Torvalds <torvalds@linux-foundation.org>
parent 7dd29d8d
Loading
Loading
Loading
Loading
+11 −39
Original line number Diff line number Diff line
@@ -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
@@ -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 {
@@ -143,7 +140,6 @@ static secno alloc_in_bmp(struct super_block *s, secno near, unsigned n, unsigne
	b:
	hpfs_brelse4(&qbh);
	uls:
	unlock_super(s);
	return ret;
}

@@ -155,7 +151,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 +163,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 +209,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,43 +230,29 @@ 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);
	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));
		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)
@@ -286,26 +266,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)) {
		hpfs_error(s, "sector %08x not allocated", sec);
		hpfs_brelse4(&qbh);
		unlock_super(s);
		return;
	}
	bmp[(sec & 0x3fff) >> 5] |= 1 << (sec & 0x1f);
	if (!--n) {
		hpfs_mark_4buffers_dirty(&qbh);
		hpfs_brelse4(&qbh);
		unlock_super(s);
		return;
	}	
	if (!(++sec & 0x3fff)) {
@@ -381,29 +357,25 @@ void hpfs_free_dnode(struct super_block *s, dnode_secno dno)
		struct quad_buffer_head qbh;
		unsigned *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);
		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);
@@ -424,7 +396,7 @@ 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;
@@ -441,7 +413,7 @@ 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;
+1 −1
Original line number Diff line number Diff line
@@ -115,7 +115,7 @@ 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;
	}
+0 −16
Original line number Diff line number Diff line
@@ -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,
+25 −32
Original line number Diff line number Diff line
@@ -145,9 +145,10 @@ static void set_last_pointer(struct super_block *s, struct dnode *d, dnode_secno
		}
	}
	if (ptr) {
		if ((d->first_free += 4) > 2048) {
		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", d->self);
			d->first_free -= 4;
			d->first_free = cpu_to_le32(le32_to_cpu(d->first_free) - 4);
			return;
		}
		de->length = 36;
@@ -184,7 +185,7 @@ struct hpfs_dirent *hpfs_add_de(struct super_block *s, struct dnode *d,
	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;
}

@@ -197,8 +198,8 @@ static void hpfs_delete_de(struct super_block *s, struct dnode *d,
		hpfs_error(s, "attempt to delete last dirent in dnode %08x", 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) - 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)
@@ -262,7 +263,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 +287,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, d->up, &adno, &qbh1))) {
		hpfs_error(i->i_sb, "unable to alloc dnode - dnode tree will be corrupted");
		hpfs_brelse4(&qbh);
		kfree(nd);
@@ -313,9 +314,9 @@ 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) {
@@ -326,7 +327,7 @@ static int hpfs_add_to_dnode(struct inode *i, dnode_secno dno,
		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, d->up, &rdno, &qbh2))) {
		hpfs_error(i->i_sb, "unable to alloc dnode - dnode tree will be corrupted");
		hpfs_brelse4(&qbh);
		hpfs_brelse4(&qbh1);
@@ -373,7 +374,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 +404,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 +411,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;
}

@@ -474,7 +473,7 @@ static secno move_to_top(struct inode *i, dnode_secno from, dnode_secno to)
			hpfs_brelse4(&qbh);
			return 0;
		}
		dnode->first_free -= 4;
		dnode->first_free = cpu_to_le32(le32_to_cpu(dnode->first_free) - 4);
		de->length -= 4;
		de->down = 0;
		hpfs_mark_4buffers_dirty(&qbh);
@@ -517,8 +516,8 @@ 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;
@@ -571,9 +570,9 @@ static void delete_empty_dnode(struct inode *i, dnode_secno dno)
		if (!down) {
			de->down = 0;
			de->length -= 4;
			dnode->first_free -= 4;
			dnode->first_free = cpu_to_le32(le32_to_cpu(dnode->first_free) - 4);
			memmove(de_next_de(de), (char *)de_next_de(de) + 4,
				(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;
@@ -585,7 +584,7 @@ static void delete_empty_dnode(struct inode *i, dnode_secno dno)
			}
		}
	} 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;
	}

@@ -635,7 +634,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");
@@ -649,12 +648,12 @@ static void delete_empty_dnode(struct inode *i, dnode_secno dno)
				}
				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->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;
		} else goto endm;
@@ -670,7 +669,7 @@ static void delete_empty_dnode(struct inode *i, dnode_secno dno)
		if (!de_prev->down) {
			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;
		hpfs_mark_4buffers_dirty(&qbh);
@@ -701,7 +700,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 +708,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 +722,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;
}

+3 −3
Original line number Diff line number Diff line
@@ -266,7 +266,7 @@ void hpfs_set_ea(struct inode *inode, struct fnode *fnode, const char *key,
		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;
@@ -284,7 +284,7 @@ void hpfs_set_ea(struct inode *inode, struct fnode *fnode, const char *key,
	if (pos >= 30000) goto bail;
	while (((pos + 511) >> 9) > len) {
		if (!len) {
			if (!(fnode->ea_secno = hpfs_alloc_sector(s, fno, 1, 0, 1)))
			if (!(fnode->ea_secno = hpfs_alloc_sector(s, fno, 1, 0)))
				goto bail;
			fnode->ea_anode = 0;
			len++;
@@ -312,7 +312,7 @@ void hpfs_set_ea(struct inode *inode, struct fnode *fnode, const char *key,
				fnode->ea_secno = 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;
Loading