Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 824b005c authored by Linus Torvalds's avatar Linus Torvalds
Browse files

Merge branch 'hpfs' (patches from Mikulas)

Merge hpfs upddate from Mikulas Patocka.

* emailed patches from Mikulas Patocka <mikulas@twibright.com>:
  hpfs: update ctime and mtime on directory modification
  hpfs: support hotfixes
parents dd5cdb48 f49a26e7
Loading
Loading
Loading
Loading
+33 −6
Original line number Diff line number Diff line
@@ -10,6 +10,30 @@
#include <linux/blkdev.h>
#include "hpfs_fn.h"

secno hpfs_search_hotfix_map(struct super_block *s, secno sec)
{
	unsigned i;
	struct hpfs_sb_info *sbi = hpfs_sb(s);
	for (i = 0; unlikely(i < sbi->n_hotfixes); i++) {
		if (sbi->hotfix_from[i] == sec) {
			return sbi->hotfix_to[i];
		}
	}
	return sec;
}

unsigned hpfs_search_hotfix_map_for_range(struct super_block *s, secno sec, unsigned n)
{
	unsigned i;
	struct hpfs_sb_info *sbi = hpfs_sb(s);
	for (i = 0; unlikely(i < sbi->n_hotfixes); i++) {
		if (sbi->hotfix_from[i] >= sec && sbi->hotfix_from[i] < sec + n) {
			n = sbi->hotfix_from[i] - sec;
		}
	}
	return n;
}

void hpfs_prefetch_sectors(struct super_block *s, unsigned secno, int n)
{
	struct buffer_head *bh;
@@ -18,6 +42,9 @@ void hpfs_prefetch_sectors(struct super_block *s, unsigned secno, int n)
	if (n <= 0 || unlikely(secno >= hpfs_sb(s)->sb_fs_size))
		return;

	if (unlikely(hpfs_search_hotfix_map_for_range(s, secno, n) != n))
		return;

	bh = sb_find_get_block(s, secno);
	if (bh) {
		if (buffer_uptodate(bh)) {
@@ -51,7 +78,7 @@ void *hpfs_map_sector(struct super_block *s, unsigned secno, struct buffer_head

	cond_resched();

	*bhp = bh = sb_bread(s, secno);
	*bhp = bh = sb_bread(s, hpfs_search_hotfix_map(s, secno));
	if (bh != NULL)
		return bh->b_data;
	else {
@@ -71,7 +98,7 @@ void *hpfs_get_sector(struct super_block *s, unsigned secno, struct buffer_head

	cond_resched();

	if ((*bhp = bh = sb_getblk(s, secno)) != NULL) {
	if ((*bhp = bh = sb_getblk(s, hpfs_search_hotfix_map(s, secno))) != NULL) {
		if (!buffer_uptodate(bh)) wait_on_buffer(bh);
		set_buffer_uptodate(bh);
		return bh->b_data;
@@ -99,10 +126,10 @@ void *hpfs_map_4sectors(struct super_block *s, unsigned secno, struct quad_buffe

	hpfs_prefetch_sectors(s, secno, 4 + ahead);

	if (!(qbh->bh[0] = sb_bread(s, secno + 0))) goto bail0;
	if (!(qbh->bh[1] = sb_bread(s, secno + 1))) goto bail1;
	if (!(qbh->bh[2] = sb_bread(s, secno + 2))) goto bail2;
	if (!(qbh->bh[3] = sb_bread(s, secno + 3))) goto bail3;
	if (!hpfs_map_sector(s, secno + 0, &qbh->bh[0], 0)) goto bail0;
	if (!hpfs_map_sector(s, secno + 1, &qbh->bh[1], 0)) goto bail1;
	if (!hpfs_map_sector(s, secno + 2, &qbh->bh[2], 0)) goto bail2;
	if (!hpfs_map_sector(s, secno + 3, &qbh->bh[3], 0)) goto bail3;

	if (likely(qbh->bh[1]->b_data == qbh->bh[0]->b_data + 1 * 512) &&
	    likely(qbh->bh[2]->b_data == qbh->bh[0]->b_data + 2 * 512) &&
+7 −2
Original line number Diff line number Diff line
@@ -83,6 +83,11 @@ static int hpfs_get_block(struct inode *inode, sector_t iblock, struct buffer_he
	if (s) {
		if (bh_result->b_size >> 9 < n_secs)
			n_secs = bh_result->b_size >> 9;
		n_secs = hpfs_search_hotfix_map_for_range(inode->i_sb, s, n_secs);
		if (unlikely(!n_secs)) {
			s = hpfs_search_hotfix_map(inode->i_sb, s);
			n_secs = 1;
		}
		map_bh(bh_result, inode->i_sb, s);
		bh_result->b_size = n_secs << 9;
		goto ret_0;
@@ -101,7 +106,7 @@ static int hpfs_get_block(struct inode *inode, sector_t iblock, struct buffer_he
	inode->i_blocks++;
	hpfs_i(inode)->mmu_private += 512;
	set_buffer_new(bh_result);
	map_bh(bh_result, inode->i_sb, s);
	map_bh(bh_result, inode->i_sb, hpfs_search_hotfix_map(inode->i_sb, s));
	ret_0:
	r = 0;
	ret_r:
+7 −0
Original line number Diff line number Diff line
@@ -88,6 +88,10 @@ struct hpfs_sb_info {
	unsigned sb_max_fwd_alloc;	/* max forwad allocation */
	int sb_timeshift;
	struct rcu_head rcu;

	unsigned n_hotfixes;
	secno hotfix_from[256];
	secno hotfix_to[256];
};

/* Four 512-byte buffers and the 2k block obtained by concatenating them */
@@ -217,6 +221,8 @@ void hpfs_remove_fnode(struct super_block *, fnode_secno fno);

/* buffer.c */

secno hpfs_search_hotfix_map(struct super_block *s, secno sec);
unsigned hpfs_search_hotfix_map_for_range(struct super_block *s, secno sec, unsigned n);
void hpfs_prefetch_sectors(struct super_block *, unsigned, int);
void *hpfs_map_sector(struct super_block *, unsigned, struct buffer_head **, int);
void *hpfs_get_sector(struct super_block *, unsigned, struct buffer_head **);
@@ -285,6 +291,7 @@ __le32 *hpfs_map_bitmap(struct super_block *, unsigned, struct quad_buffer_head
void hpfs_prefetch_bitmap(struct super_block *, unsigned);
unsigned char *hpfs_load_code_page(struct super_block *, secno);
__le32 *hpfs_load_bitmap_directory(struct super_block *, secno bmp);
void hpfs_load_hotfix_map(struct super_block *s, struct hpfs_spare_block *spareblock);
struct fnode *hpfs_map_fnode(struct super_block *s, ino_t, struct buffer_head **);
struct anode *hpfs_map_anode(struct super_block *s, anode_secno, struct buffer_head **);
struct dnode *hpfs_map_dnode(struct super_block *s, dnode_secno, struct quad_buffer_head *);
+26 −0
Original line number Diff line number Diff line
@@ -130,6 +130,32 @@ __le32 *hpfs_load_bitmap_directory(struct super_block *s, secno bmp)
	return b;
}

void hpfs_load_hotfix_map(struct super_block *s, struct hpfs_spare_block *spareblock)
{
	struct quad_buffer_head qbh;
	u32 *directory;
	u32 n_hotfixes, n_used_hotfixes;
	unsigned i;

	n_hotfixes = le32_to_cpu(spareblock->n_spares);
	n_used_hotfixes = le32_to_cpu(spareblock->n_spares_used);

	if (n_hotfixes > 256 || n_used_hotfixes > n_hotfixes) {
		hpfs_error(s, "invalid number of hotfixes: %u, used: %u", n_hotfixes, n_used_hotfixes);
		return;
	}
	if (!(directory = hpfs_map_4sectors(s, le32_to_cpu(spareblock->hotfix_map), &qbh, 0))) {
		hpfs_error(s, "can't load hotfix map");
		return;
	}
	for (i = 0; i < n_used_hotfixes; i++) {
		hpfs_sb(s)->hotfix_from[i] = le32_to_cpu(directory[i]);
		hpfs_sb(s)->hotfix_to[i] = le32_to_cpu(directory[n_hotfixes + i]);
	}
	hpfs_sb(s)->n_hotfixes = n_used_hotfixes;
	hpfs_brelse4(&qbh);
}

/*
 * Load fnode to memory
 */
+24 −1
Original line number Diff line number Diff line
@@ -8,6 +8,17 @@
#include <linux/sched.h>
#include "hpfs_fn.h"

static void hpfs_update_directory_times(struct inode *dir)
{
	time_t t = get_seconds();
	if (t == dir->i_mtime.tv_sec &&
	    t == dir->i_ctime.tv_sec)
		return;
	dir->i_mtime.tv_sec = dir->i_ctime.tv_sec = t;
	dir->i_mtime.tv_nsec = dir->i_ctime.tv_nsec = 0;
	hpfs_write_inode_nolock(dir);
}

static int hpfs_mkdir(struct inode *dir, struct dentry *dentry, umode_t mode)
{
	const unsigned char *name = dentry->d_name.name;
@@ -99,6 +110,7 @@ static int hpfs_mkdir(struct inode *dir, struct dentry *dentry, umode_t mode)
		result->i_mode = mode | S_IFDIR;
		hpfs_write_inode_nolock(result);
	}
	hpfs_update_directory_times(dir);
	d_instantiate(dentry, result);
	hpfs_unlock(dir->i_sb);
	return 0;
@@ -187,6 +199,7 @@ static int hpfs_create(struct inode *dir, struct dentry *dentry, umode_t mode, b
		result->i_mode = mode | S_IFREG;
		hpfs_write_inode_nolock(result);
	}
	hpfs_update_directory_times(dir);
	d_instantiate(dentry, result);
	hpfs_unlock(dir->i_sb);
	return 0;
@@ -262,6 +275,7 @@ static int hpfs_mknod(struct inode *dir, struct dentry *dentry, umode_t mode, de
	insert_inode_hash(result);

	hpfs_write_inode_nolock(result);
	hpfs_update_directory_times(dir);
	d_instantiate(dentry, result);
	brelse(bh);
	hpfs_unlock(dir->i_sb);
@@ -340,6 +354,7 @@ static int hpfs_symlink(struct inode *dir, struct dentry *dentry, const char *sy
	insert_inode_hash(result);

	hpfs_write_inode_nolock(result);
	hpfs_update_directory_times(dir);
	d_instantiate(dentry, result);
	hpfs_unlock(dir->i_sb);
	return 0;
@@ -423,6 +438,8 @@ static int hpfs_unlink(struct inode *dir, struct dentry *dentry)
out1:
	hpfs_brelse4(&qbh);
out:
	if (!err)
		hpfs_update_directory_times(dir);
	hpfs_unlock(dir->i_sb);
	return err;
}
@@ -477,6 +494,8 @@ static int hpfs_rmdir(struct inode *dir, struct dentry *dentry)
out1:
	hpfs_brelse4(&qbh);
out:
	if (!err)
		hpfs_update_directory_times(dir);
	hpfs_unlock(dir->i_sb);
	return err;
}
@@ -610,6 +629,10 @@ static int hpfs_rename(struct inode *old_dir, struct dentry *old_dentry,
		brelse(bh);
	}
end1:
	if (!err) {
		hpfs_update_directory_times(old_dir);
		hpfs_update_directory_times(new_dir);
	}
	hpfs_unlock(i->i_sb);
	return err;
}
Loading