Skip to content

Commit

Permalink
---
Browse files Browse the repository at this point in the history
yaml
---
r: 7756
b: refs/heads/master
c: 9529d46
h: refs/heads/master
v: v3
  • Loading branch information
Anton Altaparmakov committed Sep 8, 2005
1 parent ac5c945 commit 1b988a2
Show file tree
Hide file tree
Showing 3 changed files with 54 additions and 19 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: 06d0e3cf3d527f927681773c6ffbe697ccc5db7f
refs/heads/master: 9529d461d0992959026264b8fc002ac01d226708
3 changes: 3 additions & 0 deletions trunk/fs/ntfs/ChangeLog
Original file line number Diff line number Diff line change
Expand Up @@ -40,6 +40,9 @@ ToDo/Notes:
- Add fs/ntfs/malloc.h::ntfs_malloc_nofs_nofail() which is analogous to
ntfs_malloc_nofs() but it performs allocations with __GFP_NOFAIL and
hence cannot fail.
- Use ntfs_malloc_nofs_nofail() in the two critical regions in
fs/ntfs/runlist.c::ntfs_runlists_merge(). This means we no longer
need to panic() if the allocation fails as it now cannot fail.

2.1.23 - Implement extension of resident files and make writing safe as well as
many bug fixes, cleanups, and enhancements...
Expand Down
68 changes: 50 additions & 18 deletions trunk/fs/ntfs/runlist.c
Original file line number Diff line number Diff line change
Expand Up @@ -35,7 +35,7 @@ static inline void ntfs_rl_mm(runlist_element *base, int dst, int src,
int size)
{
if (likely((dst != src) && (size > 0)))
memmove(base + dst, base + src, size * sizeof (*base));
memmove(base + dst, base + src, size * sizeof(*base));
}

/**
Expand Down Expand Up @@ -94,6 +94,51 @@ static inline runlist_element *ntfs_rl_realloc(runlist_element *rl,
return new_rl;
}

/**
* ntfs_rl_realloc_nofail - Reallocate memory for runlists
* @rl: original runlist
* @old_size: number of runlist elements in the original runlist @rl
* @new_size: number of runlist elements we need space for
*
* As the runlists grow, more memory will be required. To prevent the
* kernel having to allocate and reallocate large numbers of small bits of
* memory, this function returns an entire page of memory.
*
* This function guarantees that the allocation will succeed. It will sleep
* for as long as it takes to complete the allocation.
*
* It is up to the caller to serialize access to the runlist @rl.
*
* N.B. If the new allocation doesn't require a different number of pages in
* memory, the function will return the original pointer.
*
* On success, return a pointer to the newly allocated, or recycled, memory.
* On error, return -errno. The following error codes are defined:
* -ENOMEM - Not enough memory to allocate runlist array.
* -EINVAL - Invalid parameters were passed in.
*/
static inline runlist_element *ntfs_rl_realloc_nofail(runlist_element *rl,
int old_size, int new_size)
{
runlist_element *new_rl;

old_size = PAGE_ALIGN(old_size * sizeof(*rl));
new_size = PAGE_ALIGN(new_size * sizeof(*rl));
if (old_size == new_size)
return rl;

new_rl = ntfs_malloc_nofs_nofail(new_size);
BUG_ON(!new_rl);

if (likely(rl != NULL)) {
if (unlikely(old_size > new_size))
old_size = new_size;
memcpy(new_rl, rl, old_size);
ntfs_free(rl);
}
return new_rl;
}

/**
* ntfs_are_rl_mergeable - test if two runlists can be joined together
* @dst: original runlist
Expand Down Expand Up @@ -621,11 +666,8 @@ runlist_element *ntfs_runlists_merge(runlist_element *drl,
if (drl[ds].lcn != LCN_RL_NOT_MAPPED) {
/* Add an unmapped runlist element. */
if (!slots) {
/* FIXME/TODO: We need to have the
* extra memory already! (AIA) */
drl = ntfs_rl_realloc(drl, ds, ds + 2);
if (!drl)
goto critical_error;
drl = ntfs_rl_realloc_nofail(drl, ds,
ds + 2);
slots = 2;
}
ds++;
Expand All @@ -640,13 +682,8 @@ runlist_element *ntfs_runlists_merge(runlist_element *drl,
drl[ds].length = marker_vcn - drl[ds].vcn;
/* Finally add the ENOENT terminator. */
ds++;
if (!slots) {
/* FIXME/TODO: We need to have the extra
* memory already! (AIA) */
drl = ntfs_rl_realloc(drl, ds, ds + 1);
if (!drl)
goto critical_error;
}
if (!slots)
drl = ntfs_rl_realloc_nofail(drl, ds, ds + 1);
drl[ds].vcn = marker_vcn;
drl[ds].lcn = LCN_ENOENT;
drl[ds].length = (s64)0;
Expand All @@ -659,11 +696,6 @@ runlist_element *ntfs_runlists_merge(runlist_element *drl,
ntfs_debug("Merged runlist:");
ntfs_debug_dump_runlist(drl);
return drl;

critical_error:
/* Critical error! We cannot afford to fail here. */
ntfs_error(NULL, "Critical error! Not enough memory.");
panic("NTFS: Cannot continue.");
}

/**
Expand Down

0 comments on commit 1b988a2

Please sign in to comment.