Skip to content

Commit

Permalink
---
Browse files Browse the repository at this point in the history
yaml
---
r: 109729
b: refs/heads/master
c: 3d6e48f
h: refs/heads/master
i:
  109727: e8184dd
v: v3
  • Loading branch information
Jarod Wilson authored and Martin Schwidefsky committed Sep 9, 2008
1 parent c42db38 commit 66d6016
Show file tree
Hide file tree
Showing 24 changed files with 195 additions and 286 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: 0b1fc335d2f2c1206ac4048e5f6d8971f2aae6be
refs/heads/master: 3d6e48f43340343d97839eadb1ab7b6a3ea98797
15 changes: 11 additions & 4 deletions trunk/Documentation/filesystems/Locking
Original file line number Diff line number Diff line change
Expand Up @@ -144,8 +144,8 @@ prototypes:
void (*kill_sb) (struct super_block *);
locking rules:
may block BKL
get_sb yes no
kill_sb yes no
get_sb yes yes
kill_sb yes yes

->get_sb() returns error or 0 with locked superblock attached to the vfsmount
(exclusive on ->s_umount).
Expand Down Expand Up @@ -409,12 +409,12 @@ ioctl: yes (see below)
unlocked_ioctl: no (see below)
compat_ioctl: no
mmap: no
open: no
open: maybe (see below)
flush: no
release: no
fsync: no (see below)
aio_fsync: no
fasync: no
fasync: yes (see below)
lock: yes
readv: no
writev: no
Expand All @@ -431,6 +431,13 @@ For many filesystems, it is probably safe to acquire the inode
semaphore. Note some filesystems (i.e. remote ones) provide no
protection for i_size so you will need to use the BKL.

->open() locking is in-transit: big lock partially moved into the methods.
The only exception is ->open() in the instances of file_operations that never
end up in ->i_fop/->proc_fops, i.e. ones that belong to character devices
(chrdev_open() takes lock before replacing ->f_op and calling the secondary
method. As soon as we fix the handling of module reference counters all
instances of ->open() will be called without the BKL.

Note: ext2_release() was *the* source of contention on fs-intensive
loads and dropping BKL on ->release() helps to get rid of that (we still
grab BKL for cases when we close a file that had been opened r/w, but that
Expand Down
4 changes: 1 addition & 3 deletions trunk/MAINTAINERS
Original file line number Diff line number Diff line change
Expand Up @@ -750,13 +750,11 @@ P: Ville Syrjala
M: syrjala@sci.fi
S: Maintained

ATLX ETHERNET DRIVERS
ATL1 ETHERNET DRIVER
P: Jay Cliburn
M: jcliburn@gmail.com
P: Chris Snook
M: csnook@redhat.com
P: Jie Yang
M: jie.yang@atheros.com
L: atl1-devel@lists.sourceforge.net
W: http://sourceforge.net/projects/atl1
W: http://atl1.sourceforge.net
Expand Down
3 changes: 0 additions & 3 deletions trunk/arch/ia64/include/asm/sections.h
Original file line number Diff line number Diff line change
Expand Up @@ -21,8 +21,5 @@ extern char __start_gate_brl_fsys_bubble_down_patchlist[], __end_gate_brl_fsys_b
extern char __start_unwind[], __end_unwind[];
extern char __start_ivt_text[], __end_ivt_text[];

#undef dereference_function_descriptor
void *dereference_function_descriptor(void *);

#endif /* _ASM_IA64_SECTIONS_H */

12 changes: 0 additions & 12 deletions trunk/arch/ia64/kernel/module.c
Original file line number Diff line number Diff line change
Expand Up @@ -31,11 +31,9 @@
#include <linux/elf.h>
#include <linux/moduleloader.h>
#include <linux/string.h>
#include <linux/uaccess.h>
#include <linux/vmalloc.h>

#include <asm/patch.h>
#include <asm/sections.h>
#include <asm/unaligned.h>

#define ARCH_MODULE_DEBUG 0
Expand Down Expand Up @@ -943,13 +941,3 @@ module_arch_cleanup (struct module *mod)
if (mod->arch.core_unw_table)
unw_remove_unwind_table(mod->arch.core_unw_table);
}

void *dereference_function_descriptor(void *ptr)
{
struct fdesc *desc = ptr;
void *p;

if (!probe_kernel_address(&desc->ip, p))
ptr = p;
return ptr;
}
2 changes: 1 addition & 1 deletion trunk/arch/mips/sgi-ip22/ip22-platform.c
Original file line number Diff line number Diff line change
Expand Up @@ -150,7 +150,7 @@ static int __init sgiseeq_devinit(void)
return res;

/* Second HPC is missing? */
if (ip22_is_fullhouse() ||
if (!ip22_is_fullhouse() ||
get_dbe(tmp, (unsigned int *)&hpc3c1->pbdma[1]))
return 0;

Expand Down
14 changes: 0 additions & 14 deletions trunk/arch/parisc/kernel/module.c
Original file line number Diff line number Diff line change
Expand Up @@ -47,9 +47,7 @@
#include <linux/string.h>
#include <linux/kernel.h>
#include <linux/bug.h>
#include <linux/uaccess.h>

#include <asm/sections.h>
#include <asm/unwind.h>

#if 0
Expand Down Expand Up @@ -862,15 +860,3 @@ void module_arch_cleanup(struct module *mod)
deregister_unwind_table(mod);
module_bug_cleanup(mod);
}

#ifdef CONFIG_64BIT
void *dereference_function_descriptor(void *ptr)
{
Elf64_Fdesc *desc = ptr;
void *p;

if (!probe_kernel_address(&desc->addr, p))
ptr = p;
return ptr;
}
#endif
3 changes: 0 additions & 3 deletions trunk/arch/powerpc/include/asm/sections.h
Original file line number Diff line number Diff line change
Expand Up @@ -16,9 +16,6 @@ static inline int in_kernel_text(unsigned long addr)
return 0;
}

#undef dereference_function_descriptor
void *dereference_function_descriptor(void *);

#endif

#endif /* __KERNEL__ */
Expand Down
13 changes: 1 addition & 12 deletions trunk/arch/powerpc/kernel/module_64.c
Original file line number Diff line number Diff line change
Expand Up @@ -21,9 +21,8 @@
#include <linux/err.h>
#include <linux/vmalloc.h>
#include <linux/bug.h>
#include <linux/uaccess.h>
#include <asm/module.h>
#include <asm/sections.h>
#include <asm/uaccess.h>
#include <asm/firmware.h>
#include <asm/code-patching.h>
#include <linux/sort.h>
Expand Down Expand Up @@ -452,13 +451,3 @@ int apply_relocate_add(Elf64_Shdr *sechdrs,

return 0;
}

void *dereference_function_descriptor(void *ptr)
{
struct ppc64_opd_entry *desc = ptr;
void *p;

if (!probe_kernel_address(&desc->funcaddr, p))
ptr = p;
return ptr;
}
1 change: 1 addition & 0 deletions trunk/arch/s390/kernel/compat_ptrace.h
Original file line number Diff line number Diff line change
Expand Up @@ -42,6 +42,7 @@ struct user_regs_struct32
u32 gprs[NUM_GPRS];
u32 acrs[NUM_ACRS];
u32 orig_gpr2;
/* nb: there's a 4-byte hole here */
s390_fp_regs fp_regs;
/*
* These per registers are in here so that gdb can modify them
Expand Down
28 changes: 28 additions & 0 deletions trunk/arch/s390/kernel/ptrace.c
Original file line number Diff line number Diff line change
Expand Up @@ -170,6 +170,13 @@ static unsigned long __peek_user(struct task_struct *child, addr_t addr)
*/
tmp = (addr_t) task_pt_regs(child)->orig_gpr2;

} else if (addr < (addr_t) &dummy->regs.fp_regs) {
/*
* prevent reads of padding hole between
* orig_gpr2 and fp_regs on s390.
*/
tmp = 0;

} else if (addr < (addr_t) (&dummy->regs.fp_regs + 1)) {
/*
* floating point regs. are stored in the thread structure
Expand Down Expand Up @@ -270,6 +277,13 @@ static int __poke_user(struct task_struct *child, addr_t addr, addr_t data)
*/
task_pt_regs(child)->orig_gpr2 = data;

} else if (addr < (addr_t) &dummy->regs.fp_regs) {
/*
* prevent writes of padding hole between
* orig_gpr2 and fp_regs on s390.
*/
return 0;

} else if (addr < (addr_t) (&dummy->regs.fp_regs + 1)) {
/*
* floating point regs. are stored in the thread structure
Expand Down Expand Up @@ -428,6 +442,13 @@ static u32 __peek_user_compat(struct task_struct *child, addr_t addr)
*/
tmp = *(__u32*)((addr_t) &task_pt_regs(child)->orig_gpr2 + 4);

} else if (addr < (addr_t) &dummy32->regs.fp_regs) {
/*
* prevent reads of padding hole between
* orig_gpr2 and fp_regs on s390.
*/
tmp = 0;

} else if (addr < (addr_t) (&dummy32->regs.fp_regs + 1)) {
/*
* floating point regs. are stored in the thread structure
Expand Down Expand Up @@ -514,6 +535,13 @@ static int __poke_user_compat(struct task_struct *child,
*/
*(__u32*)((addr_t) &task_pt_regs(child)->orig_gpr2 + 4) = tmp;

} else if (addr < (addr_t) &dummy32->regs.fp_regs) {
/*
* prevent writess of padding hole between
* orig_gpr2 and fp_regs on s390.
*/
return 0;

} else if (addr < (addr_t) (&dummy32->regs.fp_regs + 1)) {
/*
* floating point regs. are stored in the thread structure
Expand Down
114 changes: 27 additions & 87 deletions trunk/fs/ubifs/budget.c
Original file line number Diff line number Diff line change
Expand Up @@ -302,6 +302,18 @@ long long ubifs_calc_available(const struct ubifs_info *c, int min_idx_lebs)
int subtract_lebs;
long long available;

/*
* Force the amount available to the total size reported if the used
* space is zero.
*/
if (c->lst.total_used <= UBIFS_INO_NODE_SZ &&
c->budg_data_growth + c->budg_dd_growth == 0) {
/* Do the same calculation as for c->block_cnt */
available = c->main_lebs - 2;
available *= c->leb_size - c->dark_wm;
return available;
}

available = c->main_bytes - c->lst.total_used;

/*
Expand Down Expand Up @@ -702,106 +714,34 @@ void ubifs_release_dirty_inode_budget(struct ubifs_info *c,
}

/**
* ubifs_reported_space - calculate reported free space.
* @c: the UBIFS file-system description object
* @free: amount of free space
*
* This function calculates amount of free space which will be reported to
* user-space. User-space application tend to expect that if the file-system
* (e.g., via the 'statfs()' call) reports that it has N bytes available, they
* are able to write a file of size N. UBIFS attaches node headers to each data
* node and it has to write indexind nodes as well. This introduces additional
* overhead, and UBIFS it has to report sligtly less free space to meet the
* above expectetion.
*
* This function assumes free space is made up of uncompressed data nodes and
* full index nodes (one per data node, tripled because we always allow enough
* space to write the index thrice).
*
* Note, the calculation is pessimistic, which means that most of the time
* UBIFS reports less space than it actually has.
*/
long long ubifs_reported_space(const struct ubifs_info *c, uint64_t free)
{
int divisor, factor, f;

/*
* Reported space size is @free * X, where X is UBIFS block size
* divided by UBIFS block size + all overhead one data block
* introduces. The overhead is the node header + indexing overhead.
*
* Indexing overhead calculations are based on the following formula:
* I = N/(f - 1) + 1, where I - number of indexing nodes, N - number
* of data nodes, f - fanout. Because effective UBIFS fanout is twice
* as less than maximum fanout, we assume that each data node
* introduces 3 * @c->max_idx_node_sz / (@c->fanout/2 - 1) bytes.
* Note, the multiplier 3 is because UBIFS reseves thrice as more space
* for the index.
*/
f = c->fanout > 3 ? c->fanout >> 1 : 2;
factor = UBIFS_BLOCK_SIZE;
divisor = UBIFS_MAX_DATA_NODE_SZ;
divisor += (c->max_idx_node_sz * 3) / (f - 1);
free *= factor;
do_div(free, divisor);
return free;
}

/**
* ubifs_get_free_space - return amount of free space.
* ubifs_budg_get_free_space - return amount of free space.
* @c: UBIFS file-system description object
*
* This function calculates amount of free space to report to user-space.
*
* Because UBIFS may introduce substantial overhead (the index, node headers,
* alighment, wastage at the end of eraseblocks, etc), it cannot report real
* amount of free flash space it has (well, because not all dirty space is
* reclamable, UBIFS does not actually know the real amount). If UBIFS did so,
* it would bread user expectetion about what free space is. Users seem to
* accustomed to assume that if the file-system reports N bytes of free space,
* they would be able to fit a file of N bytes to the FS. This almost works for
* traditional file-systems, because they have way less overhead than UBIFS.
* So, to keep users happy, UBIFS tries to take the overhead into account.
* This function returns amount of free space on the file-system.
*/
long long ubifs_get_free_space(struct ubifs_info *c)
long long ubifs_budg_get_free_space(struct ubifs_info *c)
{
int min_idx_lebs, rsvd_idx_lebs, lebs;
int min_idx_lebs, rsvd_idx_lebs;
long long available, outstanding, free;

/* Do exactly the same calculations as in 'do_budget_space()' */
spin_lock(&c->space_lock);
min_idx_lebs = ubifs_calc_min_idx_lebs(c);
outstanding = c->budg_data_growth + c->budg_dd_growth;

/*
* Force the amount available to the total size reported if the used
* space is zero.
*/
if (c->lst.total_used <= UBIFS_INO_NODE_SZ && !outstanding) {
spin_unlock(&c->space_lock);
return (long long)c->block_cnt << UBIFS_BLOCK_SHIFT;
}

available = ubifs_calc_available(c, min_idx_lebs);

/*
* When reporting free space to user-space, UBIFS guarantees that it is
* possible to write a file of free space size. This means that for
* empty LEBs we may use more precise calculations than
* 'ubifs_calc_available()' is using. Namely, we know that in empty
* LEBs we would waste only @c->leb_overhead bytes, not @c->dark_wm.
* Thus, amend the available space.
*
* Note, the calculations below are similar to what we have in
* 'do_budget_space()', so refer there for comments.
*/
if (min_idx_lebs > c->lst.idx_lebs)
rsvd_idx_lebs = min_idx_lebs - c->lst.idx_lebs;
else
rsvd_idx_lebs = 0;
lebs = c->lst.empty_lebs + c->freeable_cnt + c->idx_gc_cnt -
c->lst.taken_empty_lebs;
lebs -= rsvd_idx_lebs;
available += lebs * (c->dark_wm - c->leb_overhead);

if (rsvd_idx_lebs > c->lst.empty_lebs + c->freeable_cnt + c->idx_gc_cnt
- c->lst.taken_empty_lebs) {
spin_unlock(&c->space_lock);
return 0;
}

available = ubifs_calc_available(c, min_idx_lebs);
outstanding = c->budg_data_growth + c->budg_dd_growth;
c->min_idx_lebs = min_idx_lebs;
spin_unlock(&c->space_lock);

if (available > outstanding)
Expand Down
1 change: 1 addition & 0 deletions trunk/fs/ubifs/dir.c
Original file line number Diff line number Diff line change
Expand Up @@ -587,6 +587,7 @@ static int ubifs_unlink(struct inode *dir, struct dentry *dentry)
if (err) {
if (err != -ENOSPC)
return err;
err = 0;
budgeted = 0;
}

Expand Down
Loading

0 comments on commit 66d6016

Please sign in to comment.