aboutsummaryrefslogtreecommitdiff
path: root/fs
diff options
context:
space:
mode:
Diffstat (limited to 'fs')
-rw-r--r--fs/afs/internal.h2
-rw-r--r--fs/ext4/balloc.c6
-rw-r--r--fs/ext4/extents.c148
-rw-r--r--fs/ext4/inode.c4
-rw-r--r--fs/ext4/namei.c4
-rw-r--r--fs/ext4/super.c2
-rw-r--r--fs/ioctl.c14
-rw-r--r--fs/jffs2/readinode.c22
-rw-r--r--fs/jffs2/super.c194
-rw-r--r--fs/jffs2/xattr.c6
-rw-r--r--fs/ntfs/inode.c2
-rw-r--r--fs/udf/inode.c12
-rw-r--r--fs/udf/super.c2
13 files changed, 171 insertions, 247 deletions
diff --git a/fs/afs/internal.h b/fs/afs/internal.h
index 2dac3ad2c44..2c55dd94a1d 100644
--- a/fs/afs/internal.h
+++ b/fs/afs/internal.h
@@ -17,6 +17,8 @@
#include <linux/rxrpc.h>
#include <linux/key.h>
#include <linux/workqueue.h>
+#include <linux/sched.h>
+
#include "afs.h"
#include "afs_vl.h"
diff --git a/fs/ext4/balloc.c b/fs/ext4/balloc.c
index 8a23483ca8d..3b64bb16c72 100644
--- a/fs/ext4/balloc.c
+++ b/fs/ext4/balloc.c
@@ -30,15 +30,15 @@
void ext4_get_group_no_and_offset(struct super_block *sb, ext4_fsblk_t blocknr,
unsigned long *blockgrpp, ext4_grpblk_t *offsetp)
{
- struct ext4_super_block *es = EXT4_SB(sb)->s_es;
+ struct ext4_super_block *es = EXT4_SB(sb)->s_es;
ext4_grpblk_t offset;
- blocknr = blocknr - le32_to_cpu(es->s_first_data_block);
+ blocknr = blocknr - le32_to_cpu(es->s_first_data_block);
offset = do_div(blocknr, EXT4_BLOCKS_PER_GROUP(sb));
if (offsetp)
*offsetp = offset;
if (blockgrpp)
- *blockgrpp = blocknr;
+ *blockgrpp = blocknr;
}
diff --git a/fs/ext4/extents.c b/fs/ext4/extents.c
index a0f0c04e79b..b9ce2412907 100644
--- a/fs/ext4/extents.c
+++ b/fs/ext4/extents.c
@@ -374,7 +374,7 @@ ext4_ext_binsearch_idx(struct inode *inode, struct ext4_ext_path *path, int bloc
le32_to_cpu(ix[-1].ei_block));
}
BUG_ON(k && le32_to_cpu(ix->ei_block)
- <= le32_to_cpu(ix[-1].ei_block));
+ <= le32_to_cpu(ix[-1].ei_block));
if (block < le32_to_cpu(ix->ei_block))
break;
chix = ix;
@@ -423,8 +423,8 @@ ext4_ext_binsearch(struct inode *inode, struct ext4_ext_path *path, int block)
path->p_ext = l - 1;
ext_debug(" -> %d:%llu:%d ",
- le32_to_cpu(path->p_ext->ee_block),
- ext_pblock(path->p_ext),
+ le32_to_cpu(path->p_ext->ee_block),
+ ext_pblock(path->p_ext),
le16_to_cpu(path->p_ext->ee_len));
#ifdef CHECK_BINSEARCH
@@ -435,7 +435,7 @@ ext4_ext_binsearch(struct inode *inode, struct ext4_ext_path *path, int block)
chex = ex = EXT_FIRST_EXTENT(eh);
for (k = 0; k < le16_to_cpu(eh->eh_entries); k++, ex++) {
BUG_ON(k && le32_to_cpu(ex->ee_block)
- <= le32_to_cpu(ex[-1].ee_block));
+ <= le32_to_cpu(ex[-1].ee_block));
if (block < le32_to_cpu(ex->ee_block))
break;
chex = ex;
@@ -577,7 +577,7 @@ static int ext4_ext_insert_index(handle_t *handle, struct inode *inode,
curp->p_hdr->eh_entries = cpu_to_le16(le16_to_cpu(curp->p_hdr->eh_entries)+1);
BUG_ON(le16_to_cpu(curp->p_hdr->eh_entries)
- > le16_to_cpu(curp->p_hdr->eh_max));
+ > le16_to_cpu(curp->p_hdr->eh_max));
BUG_ON(ix > EXT_LAST_INDEX(curp->p_hdr));
err = ext4_ext_dirty(handle, inode, curp);
@@ -621,12 +621,12 @@ static int ext4_ext_split(handle_t *handle, struct inode *inode,
border = path[depth].p_ext[1].ee_block;
ext_debug("leaf will be split."
" next leaf starts at %d\n",
- le32_to_cpu(border));
+ le32_to_cpu(border));
} else {
border = newext->ee_block;
ext_debug("leaf will be added."
" next leaf starts at %d\n",
- le32_to_cpu(border));
+ le32_to_cpu(border));
}
/*
@@ -684,9 +684,9 @@ static int ext4_ext_split(handle_t *handle, struct inode *inode,
while (path[depth].p_ext <=
EXT_MAX_EXTENT(path[depth].p_hdr)) {
ext_debug("move %d:%llu:%d in new leaf %llu\n",
- le32_to_cpu(path[depth].p_ext->ee_block),
- ext_pblock(path[depth].p_ext),
- le16_to_cpu(path[depth].p_ext->ee_len),
+ le32_to_cpu(path[depth].p_ext->ee_block),
+ ext_pblock(path[depth].p_ext),
+ le16_to_cpu(path[depth].p_ext->ee_len),
newblock);
/*memmove(ex++, path[depth].p_ext++,
sizeof(struct ext4_extent));
@@ -765,9 +765,9 @@ static int ext4_ext_split(handle_t *handle, struct inode *inode,
EXT_LAST_INDEX(path[i].p_hdr));
while (path[i].p_idx <= EXT_MAX_INDEX(path[i].p_hdr)) {
ext_debug("%d: move %d:%d in new index %llu\n", i,
- le32_to_cpu(path[i].p_idx->ei_block),
- idx_pblock(path[i].p_idx),
- newblock);
+ le32_to_cpu(path[i].p_idx->ei_block),
+ idx_pblock(path[i].p_idx),
+ newblock);
/*memmove(++fidx, path[i].p_idx++,
sizeof(struct ext4_extent_idx));
neh->eh_entries++;
@@ -1128,6 +1128,55 @@ ext4_can_extents_be_merged(struct inode *inode, struct ext4_extent *ex1,
}
/*
+ * check if a portion of the "newext" extent overlaps with an
+ * existing extent.
+ *
+ * If there is an overlap discovered, it updates the length of the newext
+ * such that there will be no overlap, and then returns 1.
+ * If there is no overlap found, it returns 0.
+ */
+unsigned int ext4_ext_check_overlap(struct inode *inode,
+ struct ext4_extent *newext,
+ struct ext4_ext_path *path)
+{
+ unsigned long b1, b2;
+ unsigned int depth, len1;
+ unsigned int ret = 0;
+
+ b1 = le32_to_cpu(newext->ee_block);
+ len1 = le16_to_cpu(newext->ee_len);
+ depth = ext_depth(inode);
+ if (!path[depth].p_ext)
+ goto out;
+ b2 = le32_to_cpu(path[depth].p_ext->ee_block);
+
+ /*
+ * get the next allocated block if the extent in the path
+ * is before the requested block(s)
+ */
+ if (b2 < b1) {
+ b2 = ext4_ext_next_allocated_block(path);
+ if (b2 == EXT_MAX_BLOCK)
+ goto out;
+ }
+
+ /* check for wrap through zero */
+ if (b1 + len1 < b1) {
+ len1 = EXT_MAX_BLOCK - b1;
+ newext->ee_len = cpu_to_le16(len1);
+ ret = 1;
+ }
+
+ /* check for overlap */
+ if (b1 + len1 > b2) {
+ newext->ee_len = cpu_to_le16(b2 - b1);
+ ret = 1;
+ }
+out:
+ return ret;
+}
+
+/*
* ext4_ext_insert_extent:
* tries to merge requsted extent into the existing extent or
* inserts requested extent as new one into the tree,
@@ -1212,12 +1261,12 @@ has_space:
if (!nearex) {
/* there is no extent in this leaf, create first one */
ext_debug("first extent in the leaf: %d:%llu:%d\n",
- le32_to_cpu(newext->ee_block),
- ext_pblock(newext),
- le16_to_cpu(newext->ee_len));
+ le32_to_cpu(newext->ee_block),
+ ext_pblock(newext),
+ le16_to_cpu(newext->ee_len));
path[depth].p_ext = EXT_FIRST_EXTENT(eh);
} else if (le32_to_cpu(newext->ee_block)
- > le32_to_cpu(nearex->ee_block)) {
+ > le32_to_cpu(nearex->ee_block)) {
/* BUG_ON(newext->ee_block == nearex->ee_block); */
if (nearex != EXT_LAST_EXTENT(eh)) {
len = EXT_MAX_EXTENT(eh) - nearex;
@@ -1225,9 +1274,9 @@ has_space:
len = len < 0 ? 0 : len;
ext_debug("insert %d:%llu:%d after: nearest 0x%p, "
"move %d from 0x%p to 0x%p\n",
- le32_to_cpu(newext->ee_block),
- ext_pblock(newext),
- le16_to_cpu(newext->ee_len),
+ le32_to_cpu(newext->ee_block),
+ ext_pblock(newext),
+ le16_to_cpu(newext->ee_len),
nearex, len, nearex + 1, nearex + 2);
memmove(nearex + 2, nearex + 1, len);
}
@@ -1358,9 +1407,9 @@ int ext4_ext_walk_space(struct inode *inode, unsigned long block,
cbex.ec_start = 0;
cbex.ec_type = EXT4_EXT_CACHE_GAP;
} else {
- cbex.ec_block = le32_to_cpu(ex->ee_block);
- cbex.ec_len = le16_to_cpu(ex->ee_len);
- cbex.ec_start = ext_pblock(ex);
+ cbex.ec_block = le32_to_cpu(ex->ee_block);
+ cbex.ec_len = le16_to_cpu(ex->ee_len);
+ cbex.ec_start = ext_pblock(ex);
cbex.ec_type = EXT4_EXT_CACHE_EXTENT;
}
@@ -1431,16 +1480,16 @@ ext4_ext_put_gap_in_cache(struct inode *inode, struct ext4_ext_path *path,
len = le32_to_cpu(ex->ee_block) - block;
ext_debug("cache gap(before): %lu [%lu:%lu]",
(unsigned long) block,
- (unsigned long) le32_to_cpu(ex->ee_block),
- (unsigned long) le16_to_cpu(ex->ee_len));
+ (unsigned long) le32_to_cpu(ex->ee_block),
+ (unsigned long) le16_to_cpu(ex->ee_len));
} else if (block >= le32_to_cpu(ex->ee_block)
- + le16_to_cpu(ex->ee_len)) {
- lblock = le32_to_cpu(ex->ee_block)
- + le16_to_cpu(ex->ee_len);
+ + le16_to_cpu(ex->ee_len)) {
+ lblock = le32_to_cpu(ex->ee_block)
+ + le16_to_cpu(ex->ee_len);
len = ext4_ext_next_allocated_block(path);
ext_debug("cache gap(after): [%lu:%lu] %lu",
- (unsigned long) le32_to_cpu(ex->ee_block),
- (unsigned long) le16_to_cpu(ex->ee_len),
+ (unsigned long) le32_to_cpu(ex->ee_block),
+ (unsigned long) le16_to_cpu(ex->ee_len),
(unsigned long) block);
BUG_ON(len == lblock);
len = len - lblock;
@@ -1468,9 +1517,9 @@ ext4_ext_in_cache(struct inode *inode, unsigned long block,
BUG_ON(cex->ec_type != EXT4_EXT_CACHE_GAP &&
cex->ec_type != EXT4_EXT_CACHE_EXTENT);
if (block >= cex->ec_block && block < cex->ec_block + cex->ec_len) {
- ex->ee_block = cpu_to_le32(cex->ec_block);
+ ex->ee_block = cpu_to_le32(cex->ec_block);
ext4_ext_store_pblock(ex, cex->ec_start);
- ex->ee_len = cpu_to_le16(cex->ec_len);
+ ex->ee_len = cpu_to_le16(cex->ec_len);
ext_debug("%lu cached by %lu:%lu:%llu\n",
(unsigned long) block,
(unsigned long) cex->ec_block,
@@ -1956,9 +2005,9 @@ int ext4_ext_get_blocks(handle_t *handle, struct inode *inode,
/* we should allocate requested block */
} else if (goal == EXT4_EXT_CACHE_EXTENT) {
/* block is already allocated */
- newblock = iblock
- - le32_to_cpu(newex.ee_block)
- + ext_pblock(&newex);
+ newblock = iblock
+ - le32_to_cpu(newex.ee_block)
+ + ext_pblock(&newex);
/* number of remaining blocks in the extent */
allocated = le16_to_cpu(newex.ee_len) -
(iblock - le32_to_cpu(newex.ee_block));
@@ -1987,7 +2036,7 @@ int ext4_ext_get_blocks(handle_t *handle, struct inode *inode,
ex = path[depth].p_ext;
if (ex) {
- unsigned long ee_block = le32_to_cpu(ex->ee_block);
+ unsigned long ee_block = le32_to_cpu(ex->ee_block);
ext4_fsblk_t ee_start = ext_pblock(ex);
unsigned short ee_len = le16_to_cpu(ex->ee_len);
@@ -2000,7 +2049,7 @@ int ext4_ext_get_blocks(handle_t *handle, struct inode *inode,
if (ee_len > EXT_MAX_LEN)
goto out2;
/* if found extent covers block, simply return it */
- if (iblock >= ee_block && iblock < ee_block + ee_len) {
+ if (iblock >= ee_block && iblock < ee_block + ee_len) {
newblock = iblock - ee_block + ee_start;
/* number of remaining blocks in the extent */
allocated = ee_len - (iblock - ee_block);
@@ -2031,7 +2080,15 @@ int ext4_ext_get_blocks(handle_t *handle, struct inode *inode,
/* allocate new block */
goal = ext4_ext_find_goal(inode, path, iblock);
- allocated = max_blocks;
+
+ /* Check if we can really insert (iblock)::(iblock+max_blocks) extent */
+ newex.ee_block = cpu_to_le32(iblock);
+ newex.ee_len = cpu_to_le16(max_blocks);
+ err = ext4_ext_check_overlap(inode, &newex, path);
+ if (err)
+ allocated = le16_to_cpu(newex.ee_len);
+ else
+ allocated = max_blocks;
newblock = ext4_new_blocks(handle, inode, goal, &allocated, &err);
if (!newblock)
goto out2;
@@ -2039,12 +2096,15 @@ int ext4_ext_get_blocks(handle_t *handle, struct inode *inode,
goal, newblock, allocated);
/* try to insert new extent into found leaf and return */
- newex.ee_block = cpu_to_le32(iblock);
ext4_ext_store_pblock(&newex, newblock);
newex.ee_len = cpu_to_le16(allocated);
err = ext4_ext_insert_extent(handle, inode, path, &newex);
- if (err)
+ if (err) {
+ /* free data blocks we just allocated */
+ ext4_free_blocks(handle, inode, ext_pblock(&newex),
+ le16_to_cpu(newex.ee_len));
goto out2;
+ }
if (extend_disksize && inode->i_size > EXT4_I(inode)->i_disksize)
EXT4_I(inode)->i_disksize = inode->i_size;
@@ -2157,11 +2217,3 @@ int ext4_ext_writepage_trans_blocks(struct inode *inode, int num)
return needed;
}
-
-EXPORT_SYMBOL(ext4_mark_inode_dirty);
-EXPORT_SYMBOL(ext4_ext_invalidate_cache);
-EXPORT_SYMBOL(ext4_ext_insert_extent);
-EXPORT_SYMBOL(ext4_ext_walk_space);
-EXPORT_SYMBOL(ext4_ext_find_goal);
-EXPORT_SYMBOL(ext4_ext_calc_credits_for_insert);
-
diff --git a/fs/ext4/inode.c b/fs/ext4/inode.c
index b34182b6ee4..0bcf62a750f 100644
--- a/fs/ext4/inode.c
+++ b/fs/ext4/inode.c
@@ -255,8 +255,8 @@ static int verify_chain(Indirect *from, Indirect *to)
* @inode: inode in question (we are only interested in its superblock)
* @i_block: block number to be parsed
* @offsets: array to store the offsets in
- * @boundary: set this non-zero if the referred-to block is likely to be
- * followed (on disk) by an indirect block.
+ * @boundary: set this non-zero if the referred-to block is likely to be
+ * followed (on disk) by an indirect block.
*
* To store the locations of file's data ext4 uses a data structure common
* for UNIX filesystems - tree of pointers anchored in the inode, with
diff --git a/fs/ext4/namei.c b/fs/ext4/namei.c
index 4ec57be5baf..2811e5720ad 100644
--- a/fs/ext4/namei.c
+++ b/fs/ext4/namei.c
@@ -46,7 +46,7 @@
*/
#define NAMEI_RA_CHUNKS 2
#define NAMEI_RA_BLOCKS 4
-#define NAMEI_RA_SIZE (NAMEI_RA_CHUNKS * NAMEI_RA_BLOCKS)
+#define NAMEI_RA_SIZE (NAMEI_RA_CHUNKS * NAMEI_RA_BLOCKS)
#define NAMEI_RA_INDEX(c,b) (((c) * NAMEI_RA_BLOCKS) + (b))
static struct buffer_head *ext4_append(handle_t *handle,
@@ -241,7 +241,7 @@ static inline unsigned dx_node_limit (struct inode *dir)
static void dx_show_index (char * label, struct dx_entry *entries)
{
int i, n = dx_get_count (entries);
- printk("%s index ", label);
+ printk("%s index ", label);
for (i = 0; i < n; i++) {
printk("%x->%u ", i? dx_get_hash(entries + i) :
0, dx_get_block(entries + i));
diff --git a/fs/ext4/super.c b/fs/ext4/super.c
index cb9afdd0e26..175b68c6096 100644
--- a/fs/ext4/super.c
+++ b/fs/ext4/super.c
@@ -1985,7 +1985,7 @@ static journal_t *ext4_get_dev_journal(struct super_block *sb,
if (bd_claim(bdev, sb)) {
printk(KERN_ERR
- "EXT4: failed to claim external journal device.\n");
+ "EXT4: failed to claim external journal device.\n");
blkdev_put(bdev);
return NULL;
}
diff --git a/fs/ioctl.c b/fs/ioctl.c
index 479c1038ed4..8c90cbc903f 100644
--- a/fs/ioctl.c
+++ b/fs/ioctl.c
@@ -12,6 +12,7 @@
#include <linux/fs.h>
#include <linux/security.h>
#include <linux/module.h>
+#include <linux/kallsyms.h>
#include <asm/uaccess.h>
#include <asm/ioctls.h>
@@ -20,6 +21,7 @@ static long do_ioctl(struct file *filp, unsigned int cmd,
unsigned long arg)
{
int error = -ENOTTY;
+ void *f;
if (!filp->f_op)
goto out;
@@ -29,10 +31,16 @@ static long do_ioctl(struct file *filp, unsigned int cmd,
if (error == -ENOIOCTLCMD)
error = -EINVAL;
goto out;
- } else if (filp->f_op->ioctl) {
+ } else if ((f = filp->f_op->ioctl)) {
lock_kernel();
- error = filp->f_op->ioctl(filp->f_path.dentry->d_inode,
- filp, cmd, arg);
+ if (!filp->f_op->ioctl) {
+ printk("%s: ioctl %p disappeared\n", __FUNCTION__, f);
+ print_symbol("symbol: %s\n", (unsigned long)f);
+ dump_stack();
+ } else {
+ error = filp->f_op->ioctl(filp->f_path.dentry->d_inode,
+ filp, cmd, arg);
+ }
unlock_kernel();
}
diff --git a/fs/jffs2/readinode.c b/fs/jffs2/readinode.c
index 4884d5edfe6..12e83f67eee 100644
--- a/fs/jffs2/readinode.c
+++ b/fs/jffs2/readinode.c
@@ -229,9 +229,16 @@ static int jffs2_add_tn_to_tree(struct jffs2_sb_info *c,
check anyway. */
if (!tn->fn->size) {
if (rii->mdata_tn) {
- /* We had a candidate mdata node already */
- dbg_readinode("kill old mdata with ver %d\n", rii->mdata_tn->version);
- jffs2_kill_tn(c, rii->mdata_tn);
+ if (rii->mdata_tn->version < tn->version) {
+ /* We had a candidate mdata node already */
+ dbg_readinode("kill old mdata with ver %d\n", rii->mdata_tn->version);
+ jffs2_kill_tn(c, rii->mdata_tn);
+ } else {
+ dbg_readinode("kill new mdata with ver %d (older than existing %d\n",
+ tn->version, rii->mdata_tn->version);
+ jffs2_kill_tn(c, tn);
+ return 0;
+ }
}
rii->mdata_tn = tn;
dbg_readinode("keep new mdata with ver %d\n", tn->version);
@@ -1044,7 +1051,8 @@ static int jffs2_get_inode_nodes(struct jffs2_sb_info *c, struct jffs2_inode_inf
case JFFS2_NODETYPE_DIRENT:
- if (JFFS2_MIN_NODE_HEADER < sizeof(struct jffs2_raw_dirent)) {
+ if (JFFS2_MIN_NODE_HEADER < sizeof(struct jffs2_raw_dirent) &&
+ len < sizeof(struct jffs2_raw_dirent)) {
err = read_more(c, ref, sizeof(struct jffs2_raw_dirent), &len, buf);
if (unlikely(err))
goto free_out;
@@ -1058,7 +1066,8 @@ static int jffs2_get_inode_nodes(struct jffs2_sb_info *c, struct jffs2_inode_inf
case JFFS2_NODETYPE_INODE:
- if (JFFS2_MIN_NODE_HEADER < sizeof(struct jffs2_raw_inode)) {
+ if (JFFS2_MIN_NODE_HEADER < sizeof(struct jffs2_raw_inode) &&
+ len < sizeof(struct jffs2_raw_inode)) {
err = read_more(c, ref, sizeof(struct jffs2_raw_inode), &len, buf);
if (unlikely(err))
goto free_out;
@@ -1071,7 +1080,8 @@ static int jffs2_get_inode_nodes(struct jffs2_sb_info *c, struct jffs2_inode_inf
break;
default:
- if (JFFS2_MIN_NODE_HEADER < sizeof(struct jffs2_unknown_node)) {
+ if (JFFS2_MIN_NODE_HEADER < sizeof(struct jffs2_unknown_node) &&
+ len < sizeof(struct jffs2_unknown_node)) {
err = read_more(c, ref, sizeof(struct jffs2_unknown_node), &len, buf);
if (unlikely(err))
goto free_out;
diff --git a/fs/jffs2/super.c b/fs/jffs2/super.c
index 6488af43bc9..e220d3bd610 100644
--- a/fs/jffs2/super.c
+++ b/fs/jffs2/super.c
@@ -19,7 +19,7 @@
#include <linux/mount.h>
#include <linux/jffs2.h>
#include <linux/pagemap.h>
-#include <linux/mtd/mtd.h>
+#include <linux/mtd/super.h>
#include <linux/ctype.h>
#include <linux/namei.h>
#include "compr.h"
@@ -75,69 +75,27 @@ static const struct super_operations jffs2_super_operations =
.sync_fs = jffs2_sync_fs,
};
-static int jffs2_sb_compare(struct super_block *sb, void *data)
-{
- struct jffs2_sb_info *p = data;
- struct jffs2_sb_info *c = JFFS2_SB_INFO(sb);
-
- /* The superblocks are considered to be equivalent if the underlying MTD
- device is the same one */
- if (c->mtd == p->mtd) {
- D1(printk(KERN_DEBUG "jffs2_sb_compare: match on device %d (\"%s\")\n", p->mtd->index, p->mtd->name));
- return 1;
- } else {
- D1(printk(KERN_DEBUG "jffs2_sb_compare: No match, device %d (\"%s\"), device %d (\"%s\")\n",
- c->mtd->index, c->mtd->name, p->mtd->index, p->mtd->name));
- return 0;
- }
-}
-
-static int jffs2_sb_set(struct super_block *sb, void *data)
-{
- struct jffs2_sb_info *p = data;
-
- /* For persistence of NFS exports etc. we use the same s_dev
- each time we mount the device, don't just use an anonymous
- device */
- sb->s_fs_info = p;
- p->os_priv = sb;
- sb->s_dev = MKDEV(MTD_BLOCK_MAJOR, p->mtd->index);
-
- return 0;
-}
-
-static int jffs2_get_sb_mtd(struct file_system_type *fs_type,
- int flags, const char *dev_name,
- void *data, struct mtd_info *mtd,
- struct vfsmount *mnt)
+/*
+ * fill in the superblock
+ */
+static int jffs2_fill_super(struct super_block *sb, void *data, int silent)
{
- struct super_block *sb;
struct jffs2_sb_info *c;
- int ret;
+
+ D1(printk(KERN_DEBUG "jffs2_get_sb_mtd():"
+ " New superblock for device %d (\"%s\")\n",
+ sb->s_mtd->index, sb->s_mtd->name));
c = kzalloc(sizeof(*c), GFP_KERNEL);
if (!c)
return -ENOMEM;
- c->mtd = mtd;
-
- sb = sget(fs_type, jffs2_sb_compare, jffs2_sb_set, c);
-
- if (IS_ERR(sb))
- goto out_error;
-
- if (sb->s_root) {
- /* New mountpoint for JFFS2 which is already mounted */
- D1(printk(KERN_DEBUG "jffs2_get_sb_mtd(): Device %d (\"%s\") is already mounted\n",
- mtd->index, mtd->name));
- ret = simple_set_mnt(mnt, sb);
- goto out_put;
- }
- D1(printk(KERN_DEBUG "jffs2_get_sb_mtd(): New superblock for device %d (\"%s\")\n",
- mtd->index, mtd->name));
+ c->mtd = sb->s_mtd;
+ c->os_priv = sb;
+ sb->s_fs_info = c;
- /* Initialize JFFS2 superblock locks, the further initialization will be
- * done later */
+ /* Initialize JFFS2 superblock locks, the further initialization will
+ * be done later */
init_MUTEX(&c->alloc_sem);
init_MUTEX(&c->erase_free_sem);
init_waitqueue_head(&c->erase_wait);
@@ -146,133 +104,20 @@ static int jffs2_get_sb_mtd(struct file_system_type *fs_type,
spin_lock_init(&c->inocache_lock);
sb->s_op = &jffs2_super_operations;
- sb->s_flags = flags | MS_NOATIME;
+ sb->s_flags = sb->s_flags | MS_NOATIME;
sb->s_xattr = jffs2_xattr_handlers;
#ifdef CONFIG_JFFS2_FS_POSIX_ACL
sb->s_flags |= MS_POSIXACL;
#endif
- ret = jffs2_do_fill_super(sb, data, flags & MS_SILENT ? 1 : 0);
-
- if (ret) {
- /* Failure case... */
- up_write(&sb->s_umount);
- deactivate_super(sb);
- return ret;
- }
-
- sb->s_flags |= MS_ACTIVE;
- return simple_set_mnt(mnt, sb);
-
-out_error:
- ret = PTR_ERR(sb);
- out_put:
- kfree(c);
- put_mtd_device(mtd);
-
- return ret;
-}
-
-static int jffs2_get_sb_mtdnr(struct file_system_type *fs_type,
- int flags, const char *dev_name,
- void *data, int mtdnr,
- struct vfsmount *mnt)
-{
- struct mtd_info *mtd;
-
- mtd = get_mtd_device(NULL, mtdnr);
- if (IS_ERR(mtd)) {
- D1(printk(KERN_DEBUG "jffs2: MTD device #%u doesn't appear to exist\n", mtdnr));
- return PTR_ERR(mtd);
- }
-
- return jffs2_get_sb_mtd(fs_type, flags, dev_name, data, mtd, mnt);
+ return jffs2_do_fill_super(sb, data, silent);
}
static int jffs2_get_sb(struct file_system_type *fs_type,
int flags, const char *dev_name,
void *data, struct vfsmount *mnt)
{
- int err;
- struct nameidata nd;
- int mtdnr;
-
- if (!dev_name)
- return -EINVAL;
-
- D1(printk(KERN_DEBUG "jffs2_get_sb(): dev_name \"%s\"\n", dev_name));
-
- /* The preferred way of mounting in future; especially when
- CONFIG_BLK_DEV is implemented - we specify the underlying
- MTD device by number or by name, so that we don't require
- block device support to be present in the kernel. */
-
- /* FIXME: How to do the root fs this way? */
-
- if (dev_name[0] == 'm' && dev_name[1] == 't' && dev_name[2] == 'd') {
- /* Probably mounting without the blkdev crap */
- if (dev_name[3] == ':') {
- struct mtd_info *mtd;
-
- /* Mount by MTD device name */
- D1(printk(KERN_DEBUG "jffs2_get_sb(): mtd:%%s, name \"%s\"\n", dev_name+4));
- for (mtdnr = 0; mtdnr < MAX_MTD_DEVICES; mtdnr++) {
- mtd = get_mtd_device(NULL, mtdnr);
- if (!IS_ERR(mtd)) {
- if (!strcmp(mtd->name, dev_name+4))
- return jffs2_get_sb_mtd(fs_type, flags, dev_name, data, mtd, mnt);
- put_mtd_device(mtd);
- }
- }
- printk(KERN_NOTICE "jffs2_get_sb(): MTD device with name \"%s\" not found.\n", dev_name+4);
- } else if (isdigit(dev_name[3])) {
- /* Mount by MTD device number name */
- char *endptr;
-
- mtdnr = simple_strtoul(dev_name+3, &endptr, 0);
- if (!*endptr) {
- /* It was a valid number */
- D1(printk(KERN_DEBUG "jffs2_get_sb(): mtd%%d, mtdnr %d\n", mtdnr));
- return jffs2_get_sb_mtdnr(fs_type, flags, dev_name, data, mtdnr, mnt);
- }
- }
- }
-
- /* Try the old way - the hack where we allowed users to mount
- /dev/mtdblock$(n) but didn't actually _use_ the blkdev */
-
- err = path_lookup(dev_name, LOOKUP_FOLLOW, &nd);
-
- D1(printk(KERN_DEBUG "jffs2_get_sb(): path_lookup() returned %d, inode %p\n",
- err, nd.dentry->d_inode));
-
- if (err)
- return err;
-
- err = -EINVAL;
-
- if (!S_ISBLK(nd.dentry->d_inode->i_mode))
- goto out;
-
- if (nd.mnt->mnt_flags & MNT_NODEV) {
- err = -EACCES;
- goto out;
- }
-
- if (imajor(nd.dentry->d_inode) != MTD_BLOCK_MAJOR) {
- if (!(flags & MS_SILENT))
- printk(KERN_NOTICE "Attempt to mount non-MTD device \"%s\" as JFFS2\n",
- dev_name);
- goto out;
- }
-
- mtdnr = iminor(nd.dentry->d_inode);
- path_release(&nd);
-
- return jffs2_get_sb_mtdnr(fs_type, flags, dev_name, data, mtdnr, mnt);
-
-out:
- path_release(&nd);
- return err;
+ return get_sb_mtd(fs_type, flags, dev_name, data, jffs2_fill_super,
+ mnt);
}
static void jffs2_put_super (struct super_block *sb)
@@ -307,8 +152,7 @@ static void jffs2_kill_sb(struct super_block *sb)
struct jffs2_sb_info *c = JFFS2_SB_INFO(sb);
if (!(sb->s_flags & MS_RDONLY))
jffs2_stop_garbage_collect_thread(c);
- generic_shutdown_super(sb);
- put_mtd_device(c->mtd);
+ kill_mtd_super(sb);
kfree(c);
}
diff --git a/fs/jffs2/xattr.c b/fs/jffs2/xattr.c
index 78fc08893a6..e48665984cb 100644
--- a/fs/jffs2/xattr.c
+++ b/fs/jffs2/xattr.c
@@ -754,6 +754,10 @@ void jffs2_clear_xattr_subsystem(struct jffs2_sb_info *c)
list_del(&xd->xindex);
jffs2_free_xattr_datum(xd);
}
+ list_for_each_entry_safe(xd, _xd, &c->xattr_unchecked, xindex) {
+ list_del(&xd->xindex);
+ jffs2_free_xattr_datum(xd);
+ }
}
#define XREF_TMPHASH_SIZE (128)
@@ -825,7 +829,7 @@ void jffs2_build_xattr_subsystem(struct jffs2_sb_info *c)
ref->xd and ref->ic are not valid yet. */
xd = jffs2_find_xattr_datum(c, ref->xid);
ic = jffs2_get_ino_cache(c, ref->ino);
- if (!xd || !ic) {
+ if (!xd || !ic || !ic->nlink) {
dbg_xattr("xref(ino=%u, xid=%u, xseqno=%u) is orphan.\n",
ref->ino, ref->xid, ref->xseqno);
ref->xseqno |= XREF_DELETE_MARKER;
diff --git a/fs/ntfs/inode.c b/fs/ntfs/inode.c
index 074791ce4ab..b532a730cec 100644
--- a/fs/ntfs/inode.c
+++ b/fs/ntfs/inode.c
@@ -140,7 +140,7 @@ static int ntfs_init_locked_inode(struct inode *vi, ntfs_attr *na)
if (!ni->name)
return -ENOMEM;
memcpy(ni->name, na->name, i);
- ni->name[i] = 0;
+ ni->name[na->name_len] = 0;
}
return 0;
}
diff --git a/fs/udf/inode.c b/fs/udf/inode.c
index c8461551e10..1f0129405cf 100644
--- a/fs/udf/inode.c
+++ b/fs/udf/inode.c
@@ -460,8 +460,8 @@ static struct buffer_head * inode_getblk(struct inode * inode, sector_t block,
kernel_long_ad laarr[EXTENT_MERGE_SIZE];
struct extent_position prev_epos, cur_epos, next_epos;
int count = 0, startnum = 0, endnum = 0;
- uint32_t elen = 0;
- kernel_lb_addr eloc;
+ uint32_t elen = 0, tmpelen;
+ kernel_lb_addr eloc, tmpeloc;
int c = 1;
loff_t lbcount = 0, b_off = 0;
uint32_t newblocknum, newblock;
@@ -520,8 +520,12 @@ static struct buffer_head * inode_getblk(struct inode * inode, sector_t block,
b_off -= lbcount;
offset = b_off >> inode->i_sb->s_blocksize_bits;
- /* Move into indirect extent if we are at a pointer to it */
- udf_next_aext(inode, &prev_epos, &eloc, &elen, 0);
+ /*
+ * Move prev_epos and cur_epos into indirect extent if we are at
+ * the pointer to it
+ */
+ udf_next_aext(inode, &prev_epos, &tmpeloc, &tmpelen, 0);
+ udf_next_aext(inode, &cur_epos, &tmpeloc, &tmpelen, 0);
/* if the extent is allocated and recorded, return the block
if the extent is not a multiple of the blocksize, round up */
diff --git a/fs/udf/super.c b/fs/udf/super.c
index 3a743d854c1..6658afb41cc 100644
--- a/fs/udf/super.c
+++ b/fs/udf/super.c
@@ -1351,7 +1351,7 @@ udf_load_partition(struct super_block *sb, kernel_lb_addr *fileset)
for (i=0; i<UDF_SB_NUMPARTS(sb); i++)
{
- switch UDF_SB_PARTTYPE(sb, i)
+ switch (UDF_SB_PARTTYPE(sb, i))
{
case UDF_VIRTUAL_MAP15:
case UDF_VIRTUAL_MAP20: