Skip to content

Commit

Permalink
---
Browse files Browse the repository at this point in the history
yaml
---
r: 18174
b: refs/heads/master
c: 1defeac
h: refs/heads/master
v: v3
  • Loading branch information
Christoph Hellwig authored and Nathan Scott committed Jan 11, 2006
1 parent e6d8640 commit 87e58c8
Show file tree
Hide file tree
Showing 2 changed files with 54 additions and 84 deletions.
2 changes: 1 addition & 1 deletion [refs]
Original file line number Diff line number Diff line change
@@ -1,2 +1,2 @@
---
refs/heads/master: 10ce444428c2329eb2aaf84850b5c7c09cecc58c
refs/heads/master: 1defeac9d4fffa3eabc4fba887e8ff5b1da7f361
136 changes: 53 additions & 83 deletions trunk/fs/xfs/linux-2.6/xfs_aops.c
Original file line number Diff line number Diff line change
Expand Up @@ -228,29 +228,13 @@ xfs_map_blocks(
return -error;
}

/*
* Finds the corresponding mapping in block @map array of the
* given @offset within a @page.
*/
STATIC xfs_iomap_t *
xfs_offset_to_map(
struct page *page,
STATIC inline int
xfs_iomap_valid(
xfs_iomap_t *iomapp,
unsigned long offset)
loff_t offset)
{
xfs_off_t full_offset; /* offset from start of file */

ASSERT(offset < PAGE_CACHE_SIZE);

full_offset = page->index; /* NB: using 64bit number */
full_offset <<= PAGE_CACHE_SHIFT; /* offset from file start */
full_offset += offset; /* offset from page start */

if (full_offset < iomapp->iomap_offset)
return NULL;
if (iomapp->iomap_offset + (iomapp->iomap_bsize -1) >= full_offset)
return iomapp;
return NULL;
return offset >= iomapp->iomap_offset &&
offset < iomapp->iomap_offset + iomapp->iomap_bsize;
}

/*
Expand Down Expand Up @@ -461,31 +445,23 @@ xfs_add_to_ioend(

STATIC void
xfs_map_at_offset(
struct page *page,
struct buffer_head *bh,
unsigned long offset,
loff_t offset,
int block_bits,
xfs_iomap_t *iomapp,
xfs_ioend_t *ioend)
xfs_iomap_t *iomapp)
{
xfs_daddr_t bn;
xfs_off_t delta;
int sector_shift;

ASSERT(!(iomapp->iomap_flags & IOMAP_HOLE));
ASSERT(!(iomapp->iomap_flags & IOMAP_DELAY));
ASSERT(iomapp->iomap_bn != IOMAP_DADDR_NULL);

delta = page->index;
delta <<= PAGE_CACHE_SHIFT;
delta += offset;
delta -= iomapp->iomap_offset;
delta >>= block_bits;

sector_shift = block_bits - BBSHIFT;
bn = iomapp->iomap_bn >> sector_shift;
bn += delta;
BUG_ON(!bn && !(iomapp->iomap_flags & IOMAP_REALTIME));
bn = (iomapp->iomap_bn >> sector_shift) +
((offset - iomapp->iomap_offset) >> block_bits);

ASSERT(bn || (iomapp->iomap_flags & IOMAP_REALTIME));
ASSERT((bn << sector_shift) >= iomapp->iomap_bn);

lock_buffer(bh);
Expand Down Expand Up @@ -569,8 +545,10 @@ xfs_probe_unmapped_cluster(
if (tindex == tlast) {
pg_offset =
i_size_read(inode) & (PAGE_CACHE_SIZE - 1);
if (!pg_offset)
if (!pg_offset) {
done = 1;
break;
}
} else
pg_offset = PAGE_CACHE_SIZE;

Expand All @@ -585,6 +563,7 @@ xfs_probe_unmapped_cluster(
}

total += len;
tindex++;
}

pagevec_release(&pvec);
Expand Down Expand Up @@ -638,19 +617,19 @@ xfs_convert_page(
struct inode *inode,
struct page *page,
loff_t tindex,
xfs_iomap_t *iomapp,
xfs_iomap_t *mp,
xfs_ioend_t **ioendp,
struct writeback_control *wbc,
int startio,
int all_bh)
{
struct buffer_head *bh, *head;
xfs_iomap_t *mp = iomapp, *tmp;
unsigned long p_offset, end_offset;
unsigned int type;
int bbits = inode->i_blkbits;
int len, page_dirty;
int count = 0, done = 0, uptodate = 1;
xfs_off_t f_offset = page_offset(page);

if (page->index != tindex)
goto fail;
Expand Down Expand Up @@ -703,15 +682,15 @@ xfs_convert_page(
}
continue;
}
tmp = xfs_offset_to_map(page, mp, p_offset);
if (!tmp) {

if (!xfs_iomap_valid(mp, f_offset + p_offset)) {
done = 1;
continue;
}
ASSERT(!(tmp->iomap_flags & IOMAP_HOLE));
ASSERT(!(tmp->iomap_flags & IOMAP_DELAY));
ASSERT(!(mp->iomap_flags & IOMAP_HOLE));
ASSERT(!(mp->iomap_flags & IOMAP_DELAY));

xfs_map_at_offset(page, bh, p_offset, bbits, tmp, *ioendp);
xfs_map_at_offset(bh, f_offset + p_offset, bbits, mp);
if (startio) {
xfs_add_to_ioend(inode, bh, p_offset,
type, ioendp, done);
Expand Down Expand Up @@ -805,15 +784,14 @@ xfs_page_state_convert(
int unmapped) /* also implies page uptodate */
{
struct buffer_head *bh, *head;
xfs_iomap_t *iomp, iomap;
xfs_iomap_t iomap;
xfs_ioend_t *ioend = NULL, *iohead = NULL;
loff_t offset;
unsigned long p_offset = 0;
unsigned int type;
__uint64_t end_offset;
pgoff_t end_index, last_index, tlast;
int flags, len, err, done = 1;
int uptodate = 1;
int flags, len, err, iomap_valid = 0, uptodate = 1;
int page_dirty, count = 0, trylock_flag = 0;

/* wait for other IO threads? */
Expand Down Expand Up @@ -854,11 +832,9 @@ xfs_page_state_convert(
p_offset = p_offset ? roundup(p_offset, len) : PAGE_CACHE_SIZE;
page_dirty = p_offset / len;

iomp = NULL;
bh = head = page_buffers(page);
offset = page_offset(page);

/* TODO: fix up "done" variable and iomap pointer (boolean) */
/* TODO: cleanup count and page_dirty */

do {
Expand All @@ -867,14 +843,16 @@ xfs_page_state_convert(
if (!buffer_uptodate(bh))
uptodate = 0;
if (!(PageUptodate(page) || buffer_uptodate(bh)) && !startio) {
done = 1;
/*
* the iomap is actually still valid, but the ioend
* isn't. shouldn't happen too often.
*/
iomap_valid = 0;
continue;
}

if (iomp) {
iomp = xfs_offset_to_map(page, &iomap, p_offset);
done = (iomp == NULL);
}
if (iomap_valid)
iomap_valid = xfs_iomap_valid(&iomap, offset);

/*
* First case, map an unwritten extent and prepare for
Expand All @@ -894,31 +872,27 @@ xfs_page_state_convert(
flags |= trylock_flag;
}

if (!iomp) {
done = 1;
if (!iomap_valid) {
err = xfs_map_blocks(inode, offset, len, &iomap,
flags);
if (err)
goto error;
iomp = xfs_offset_to_map(page, &iomap,
p_offset);
done = (iomp == NULL);
iomap_valid = xfs_iomap_valid(&iomap, offset);
}
if (iomp) {
xfs_map_at_offset(page, bh, p_offset,
inode->i_blkbits, iomp, ioend);
if (iomap_valid) {
xfs_map_at_offset(bh, offset,
inode->i_blkbits, &iomap);
if (startio) {
xfs_add_to_ioend(inode, bh, p_offset,
type, &ioend, done);
type, &ioend,
!iomap_valid);
} else {
set_buffer_dirty(bh);
unlock_buffer(bh);
mark_buffer_dirty(bh);
}
page_dirty--;
count++;
} else {
done = 1;
}
} else if ((buffer_uptodate(bh) || PageUptodate(page)) &&
(unmapped || startio)) {
Expand All @@ -931,53 +905,49 @@ xfs_page_state_convert(
* was found, and we are in a path where we
* need to write the whole page out.
*/
if (!iomp) {
if (!iomap_valid) {
int size;

size = xfs_probe_unmapped_cluster(
inode, page, bh, head);
err = xfs_map_blocks(inode, offset,
size, &iomap,
BMAPI_WRITE|BMAPI_MMAP);
if (err) {
if (err)
goto error;
}
iomp = xfs_offset_to_map(page, &iomap,
p_offset);
done = (iomp == NULL);
iomap_valid = xfs_iomap_valid(&iomap,
offset);
}
if (iomp) {
xfs_map_at_offset(page, bh, p_offset,
inode->i_blkbits, iomp,
ioend);
if (iomap_valid) {
xfs_map_at_offset(bh, offset,
inode->i_blkbits,
&iomap);
if (startio) {
xfs_add_to_ioend(inode,
bh, p_offset, type,
&ioend, done);
&ioend, !iomap_valid);
} else {
set_buffer_dirty(bh);
unlock_buffer(bh);
mark_buffer_dirty(bh);
}
page_dirty--;
count++;
} else {
done = 1;
}
} else if (startio) {
if (buffer_uptodate(bh) &&
!test_and_set_bit(BH_Lock, &bh->b_state)) {
ASSERT(buffer_mapped(bh));
xfs_add_to_ioend(inode,
bh, p_offset, type,
&ioend, done);
&ioend, !iomap_valid);
page_dirty--;
count++;
} else {
done = 1;
iomap_valid = 0;
}
} else {
done = 1;
iomap_valid = 0;
}
}

Expand All @@ -992,11 +962,11 @@ xfs_page_state_convert(
if (startio)
xfs_start_page_writeback(page, wbc, 1, count);

if (ioend && iomp && !done) {
offset = (iomp->iomap_offset + iomp->iomap_bsize - 1) >>
if (ioend && iomap_valid) {
offset = (iomap.iomap_offset + iomap.iomap_bsize - 1) >>
PAGE_CACHE_SHIFT;
tlast = min_t(pgoff_t, offset, last_index);
xfs_cluster_write(inode, page->index + 1, iomp, &ioend,
xfs_cluster_write(inode, page->index + 1, &iomap, &ioend,
wbc, startio, unmapped, tlast);
}

Expand Down

0 comments on commit 87e58c8

Please sign in to comment.