aboutsummaryrefslogtreecommitdiffstats
path: root/fs/jffs2/nodemgmt.c
diff options
context:
space:
mode:
Diffstat (limited to 'fs/jffs2/nodemgmt.c')
-rw-r--r--fs/jffs2/nodemgmt.c42
1 files changed, 42 insertions, 0 deletions
diff --git a/fs/jffs2/nodemgmt.c b/fs/jffs2/nodemgmt.c
index 6784d1e7a7eb..0c96eb52c797 100644
--- a/fs/jffs2/nodemgmt.c
+++ b/fs/jffs2/nodemgmt.c
@@ -18,6 +18,37 @@
18#include "nodelist.h" 18#include "nodelist.h"
19#include "debug.h" 19#include "debug.h"
20 20
21/*
22 * Check whether the user is allowed to write.
23 */
24static int jffs2_rp_can_write(struct jffs2_sb_info *c)
25{
26 uint32_t avail;
27 struct jffs2_mount_opts *opts = &c->mount_opts;
28
29 avail = c->dirty_size + c->free_size + c->unchecked_size +
30 c->erasing_size - c->resv_blocks_write * c->sector_size
31 - c->nospc_dirty_size;
32
33 if (avail < 2 * opts->rp_size)
34 jffs2_dbg(1, "rpsize %u, dirty_size %u, free_size %u, "
35 "erasing_size %u, unchecked_size %u, "
36 "nr_erasing_blocks %u, avail %u, resrv %u\n",
37 opts->rp_size, c->dirty_size, c->free_size,
38 c->erasing_size, c->unchecked_size,
39 c->nr_erasing_blocks, avail, c->nospc_dirty_size);
40
41 if (avail > opts->rp_size)
42 return 1;
43
44 /* Always allow root */
45 if (capable(CAP_SYS_RESOURCE))
46 return 1;
47
48 jffs2_dbg(1, "forbid writing\n");
49 return 0;
50}
51
21/** 52/**
22 * jffs2_reserve_space - request physical space to write nodes to flash 53 * jffs2_reserve_space - request physical space to write nodes to flash
23 * @c: superblock info 54 * @c: superblock info
@@ -55,6 +86,15 @@ int jffs2_reserve_space(struct jffs2_sb_info *c, uint32_t minsize,
55 86
56 spin_lock(&c->erase_completion_lock); 87 spin_lock(&c->erase_completion_lock);
57 88
89 /*
90 * Check if the free space is greater then size of the reserved pool.
91 * If not, only allow root to proceed with writing.
92 */
93 if (prio != ALLOC_DELETION && !jffs2_rp_can_write(c)) {
94 ret = -ENOSPC;
95 goto out;
96 }
97
58 /* this needs a little more thought (true <tglx> :)) */ 98 /* this needs a little more thought (true <tglx> :)) */
59 while(ret == -EAGAIN) { 99 while(ret == -EAGAIN) {
60 while(c->nr_free_blocks + c->nr_erasing_blocks < blocksneeded) { 100 while(c->nr_free_blocks + c->nr_erasing_blocks < blocksneeded) {
@@ -158,6 +198,8 @@ int jffs2_reserve_space(struct jffs2_sb_info *c, uint32_t minsize,
158 jffs2_dbg(1, "%s(): ret is %d\n", __func__, ret); 198 jffs2_dbg(1, "%s(): ret is %d\n", __func__, ret);
159 } 199 }
160 } 200 }
201
202out:
161 spin_unlock(&c->erase_completion_lock); 203 spin_unlock(&c->erase_completion_lock);
162 if (!ret) 204 if (!ret)
163 ret = jffs2_prealloc_raw_node_refs(c, c->nextblock, 1); 205 ret = jffs2_prealloc_raw_node_refs(c, c->nextblock, 1);