Commit df34d04a authored by Linus Torvalds's avatar Linus Torvalds

Merge tag 'befs-v4.9-rc1' of git://github.com/luisbg/linux-befs

Pull befs fixes from Luis de Bethencourt:
 "I recently took maintainership of the befs file system [0]. This is
  the first time I send you a git pull request, so please let me know if
  all the below is OK.

  Salah Triki and myself have been cleaning the code and fixing a few
  small bugs.

  Sorry I couldn't send this sooner in the merge window, I was waiting
  to have my GPG key signed by kernel members at ELCE in Berlin a few
  days ago."

[0] https://lkml.org/lkml/2016/7/27/502

* tag 'befs-v4.9-rc1' of git://github.com/luisbg/linux-befs: (39 commits)
  befs: befs: fix style issues in datastream.c
  befs: improve documentation in datastream.c
  befs: fix typos in datastream.c
  befs: fix typos in btree.c
  befs: fix style issues in super.c
  befs: fix comment style
  befs: add check for ag_shift in superblock
  befs: dump inode_size superblock information
  befs: remove unnecessary initialization
  befs: fix typo in befs_sb_info
  befs: add flags field to validate superblock state
  befs: fix typo in befs_find_key
  befs: remove unused BEFS_BT_PARMATCH
  fs: befs: remove ret variable
  fs: befs: remove in vain variable assignment
  fs: befs: remove unnecessary *befs_sb variable
  fs: befs: remove useless initialization to zero
  fs: befs: remove in vain variable assignment
  fs: befs: Insert NULL inode to dentry
  fs: befs: Remove useless calls to brelse in befs_find_brun_dblindirect
  ...
parents 9ffc6694 a17e7d20
...@@ -43,7 +43,10 @@ struct befs_sb_info { ...@@ -43,7 +43,10 @@ struct befs_sb_info {
u32 ag_shift; u32 ag_shift;
u32 num_ags; u32 num_ags;
/* jornal log entry */ /* State of the superblock */
u32 flags;
/* Journal log entry */
befs_block_run log_blocks; befs_block_run log_blocks;
befs_off_t log_start; befs_off_t log_start;
befs_off_t log_end; befs_off_t log_end;
...@@ -79,7 +82,7 @@ enum befs_err { ...@@ -79,7 +82,7 @@ enum befs_err {
BEFS_BT_END, BEFS_BT_END,
BEFS_BT_EMPTY, BEFS_BT_EMPTY,
BEFS_BT_MATCH, BEFS_BT_MATCH,
BEFS_BT_PARMATCH, BEFS_BT_OVERFLOW,
BEFS_BT_NOT_FOUND BEFS_BT_NOT_FOUND
}; };
...@@ -140,18 +143,6 @@ befs_iaddrs_per_block(struct super_block *sb) ...@@ -140,18 +143,6 @@ befs_iaddrs_per_block(struct super_block *sb)
return BEFS_SB(sb)->block_size / sizeof (befs_disk_inode_addr); return BEFS_SB(sb)->block_size / sizeof (befs_disk_inode_addr);
} }
static inline int
befs_iaddr_is_empty(const befs_inode_addr *iaddr)
{
return (!iaddr->allocation_group) && (!iaddr->start) && (!iaddr->len);
}
static inline size_t
befs_brun_size(struct super_block *sb, befs_block_run run)
{
return BEFS_SB(sb)->block_size * run.len;
}
#include "endian.h" #include "endian.h"
#endif /* _LINUX_BEFS_H */ #endif /* _LINUX_BEFS_H */
...@@ -85,7 +85,7 @@ struct befs_btree_node { ...@@ -85,7 +85,7 @@ struct befs_btree_node {
}; };
/* local constants */ /* local constants */
static const befs_off_t befs_bt_inval = 0xffffffffffffffffULL; static const befs_off_t BEFS_BT_INVAL = 0xffffffffffffffffULL;
/* local functions */ /* local functions */
static int befs_btree_seekleaf(struct super_block *sb, const befs_data_stream *ds, static int befs_btree_seekleaf(struct super_block *sb, const befs_data_stream *ds,
...@@ -156,8 +156,6 @@ befs_bt_read_super(struct super_block *sb, const befs_data_stream *ds, ...@@ -156,8 +156,6 @@ befs_bt_read_super(struct super_block *sb, const befs_data_stream *ds,
sup->max_depth = fs32_to_cpu(sb, od_sup->max_depth); sup->max_depth = fs32_to_cpu(sb, od_sup->max_depth);
sup->data_type = fs32_to_cpu(sb, od_sup->data_type); sup->data_type = fs32_to_cpu(sb, od_sup->data_type);
sup->root_node_ptr = fs64_to_cpu(sb, od_sup->root_node_ptr); sup->root_node_ptr = fs64_to_cpu(sb, od_sup->root_node_ptr);
sup->free_node_ptr = fs64_to_cpu(sb, od_sup->free_node_ptr);
sup->max_size = fs64_to_cpu(sb, od_sup->max_size);
brelse(bh); brelse(bh);
if (sup->magic != BEFS_BTREE_MAGIC) { if (sup->magic != BEFS_BTREE_MAGIC) {
...@@ -183,8 +181,8 @@ befs_bt_read_super(struct super_block *sb, const befs_data_stream *ds, ...@@ -183,8 +181,8 @@ befs_bt_read_super(struct super_block *sb, const befs_data_stream *ds,
* Calls befs_read_datastream to read in the indicated btree node and * Calls befs_read_datastream to read in the indicated btree node and
* makes sure its header fields are in cpu byteorder, byteswapping if * makes sure its header fields are in cpu byteorder, byteswapping if
* necessary. * necessary.
* Note: node->bh must be NULL when this function called first * Note: node->bh must be NULL when this function is called the first time.
* time. Don't forget brelse(node->bh) after last call. * Don't forget brelse(node->bh) after last call.
* *
* On success, returns BEFS_OK and *@node contains the btree node that * On success, returns BEFS_OK and *@node contains the btree node that
* starts at @node_off, with the node->head fields in cpu byte order. * starts at @node_off, with the node->head fields in cpu byte order.
...@@ -244,7 +242,7 @@ befs_bt_read_node(struct super_block *sb, const befs_data_stream *ds, ...@@ -244,7 +242,7 @@ befs_bt_read_node(struct super_block *sb, const befs_data_stream *ds,
* Read the superblock and rootnode of the b+tree. * Read the superblock and rootnode of the b+tree.
* Drill down through the interior nodes using befs_find_key(). * Drill down through the interior nodes using befs_find_key().
* Once at the correct leaf node, use befs_find_key() again to get the * Once at the correct leaf node, use befs_find_key() again to get the
* actuall value stored with the key. * actual value stored with the key.
*/ */
int int
befs_btree_find(struct super_block *sb, const befs_data_stream *ds, befs_btree_find(struct super_block *sb, const befs_data_stream *ds,
...@@ -283,9 +281,9 @@ befs_btree_find(struct super_block *sb, const befs_data_stream *ds, ...@@ -283,9 +281,9 @@ befs_btree_find(struct super_block *sb, const befs_data_stream *ds,
while (!befs_leafnode(this_node)) { while (!befs_leafnode(this_node)) {
res = befs_find_key(sb, this_node, key, &node_off); res = befs_find_key(sb, this_node, key, &node_off);
if (res == BEFS_BT_NOT_FOUND) /* if no key set, try the overflow node */
if (res == BEFS_BT_OVERFLOW)
node_off = this_node->head.overflow; node_off = this_node->head.overflow;
/* if no match, go to overflow node */
if (befs_bt_read_node(sb, ds, this_node, node_off) != BEFS_OK) { if (befs_bt_read_node(sb, ds, this_node, node_off) != BEFS_OK) {
befs_error(sb, "befs_btree_find() failed to read " befs_error(sb, "befs_btree_find() failed to read "
"node at %llu", node_off); "node at %llu", node_off);
...@@ -293,15 +291,15 @@ befs_btree_find(struct super_block *sb, const befs_data_stream *ds, ...@@ -293,15 +291,15 @@ befs_btree_find(struct super_block *sb, const befs_data_stream *ds,
} }
} }
/* at the correct leaf node now */ /* at a leaf node now, check if it is correct */
res = befs_find_key(sb, this_node, key, value); res = befs_find_key(sb, this_node, key, value);
brelse(this_node->bh); brelse(this_node->bh);
kfree(this_node); kfree(this_node);
if (res != BEFS_BT_MATCH) { if (res != BEFS_BT_MATCH) {
befs_debug(sb, "<--- %s Key %s not found", __func__, key); befs_error(sb, "<--- %s Key %s not found", __func__, key);
befs_debug(sb, "<--- %s ERROR", __func__);
*value = 0; *value = 0;
return BEFS_BT_NOT_FOUND; return BEFS_BT_NOT_FOUND;
} }
...@@ -324,16 +322,12 @@ befs_btree_find(struct super_block *sb, const befs_data_stream *ds, ...@@ -324,16 +322,12 @@ befs_btree_find(struct super_block *sb, const befs_data_stream *ds,
* @findkey: Keystring to search for * @findkey: Keystring to search for
* @value: If key is found, the value stored with the key is put here * @value: If key is found, the value stored with the key is put here
* *
* finds exact match if one exists, and returns BEFS_BT_MATCH * Finds exact match if one exists, and returns BEFS_BT_MATCH.
* If no exact match, finds first key in node that is greater * If there is no match and node's value array is too small for key, return
* (alphabetically) than the search key and returns BEFS_BT_PARMATCH * BEFS_BT_OVERFLOW.
* (for partial match, I guess). Can you think of something better to * If no match and node should countain this key, return BEFS_BT_NOT_FOUND.
* call it?
*
* If no key was a match or greater than the search key, return
* BEFS_BT_NOT_FOUND.
* *
* Use binary search instead of a linear. * Uses binary search instead of a linear.
*/ */
static int static int
befs_find_key(struct super_block *sb, struct befs_btree_node *node, befs_find_key(struct super_block *sb, struct befs_btree_node *node,
...@@ -348,18 +342,16 @@ befs_find_key(struct super_block *sb, struct befs_btree_node *node, ...@@ -348,18 +342,16 @@ befs_find_key(struct super_block *sb, struct befs_btree_node *node,
befs_debug(sb, "---> %s %s", __func__, findkey); befs_debug(sb, "---> %s %s", __func__, findkey);
*value = 0;
findkey_len = strlen(findkey); findkey_len = strlen(findkey);
/* if node can not contain key, just skeep this node */ /* if node can not contain key, just skip this node */
last = node->head.all_key_count - 1; last = node->head.all_key_count - 1;
thiskey = befs_bt_get_key(sb, node, last, &keylen); thiskey = befs_bt_get_key(sb, node, last, &keylen);
eq = befs_compare_strings(thiskey, keylen, findkey, findkey_len); eq = befs_compare_strings(thiskey, keylen, findkey, findkey_len);
if (eq < 0) { if (eq < 0) {
befs_debug(sb, "<--- %s %s not found", __func__, findkey); befs_debug(sb, "<--- node can't contain %s", findkey);
return BEFS_BT_NOT_FOUND; return BEFS_BT_OVERFLOW;
} }
valarray = befs_bt_valarray(node); valarray = befs_bt_valarray(node);
...@@ -387,12 +379,15 @@ befs_find_key(struct super_block *sb, struct befs_btree_node *node, ...@@ -387,12 +379,15 @@ befs_find_key(struct super_block *sb, struct befs_btree_node *node,
else else
first = mid + 1; first = mid + 1;
} }
/* return an existing value so caller can arrive to a leaf node */
if (eq < 0) if (eq < 0)
*value = fs64_to_cpu(sb, valarray[mid + 1]); *value = fs64_to_cpu(sb, valarray[mid + 1]);
else else
*value = fs64_to_cpu(sb, valarray[mid]); *value = fs64_to_cpu(sb, valarray[mid]);
befs_debug(sb, "<--- %s found %s at %d", __func__, thiskey, mid); befs_error(sb, "<--- %s %s not found", __func__, findkey);
return BEFS_BT_PARMATCH; befs_debug(sb, "<--- %s ERROR", __func__);
return BEFS_BT_NOT_FOUND;
} }
/** /**
...@@ -405,7 +400,7 @@ befs_find_key(struct super_block *sb, struct befs_btree_node *node, ...@@ -405,7 +400,7 @@ befs_find_key(struct super_block *sb, struct befs_btree_node *node,
* @keysize: Length of the returned key * @keysize: Length of the returned key
* @value: Value stored with the returned key * @value: Value stored with the returned key
* *
* Heres how it works: Key_no is the index of the key/value pair to * Here's how it works: Key_no is the index of the key/value pair to
* return in keybuf/value. * return in keybuf/value.
* Bufsize is the size of keybuf (BEFS_NAME_LEN+1 is a good size). Keysize is * Bufsize is the size of keybuf (BEFS_NAME_LEN+1 is a good size). Keysize is
* the number of characters in the key (just a convenience). * the number of characters in the key (just a convenience).
...@@ -422,7 +417,7 @@ befs_btree_read(struct super_block *sb, const befs_data_stream *ds, ...@@ -422,7 +417,7 @@ befs_btree_read(struct super_block *sb, const befs_data_stream *ds,
{ {
struct befs_btree_node *this_node; struct befs_btree_node *this_node;
befs_btree_super bt_super; befs_btree_super bt_super;
befs_off_t node_off = 0; befs_off_t node_off;
int cur_key; int cur_key;
fs64 *valarray; fs64 *valarray;
char *keystart; char *keystart;
...@@ -467,7 +462,7 @@ befs_btree_read(struct super_block *sb, const befs_data_stream *ds, ...@@ -467,7 +462,7 @@ befs_btree_read(struct super_block *sb, const befs_data_stream *ds,
while (key_sum + this_node->head.all_key_count <= key_no) { while (key_sum + this_node->head.all_key_count <= key_no) {
/* no more nodes to look in: key_no is too large */ /* no more nodes to look in: key_no is too large */
if (this_node->head.right == befs_bt_inval) { if (this_node->head.right == BEFS_BT_INVAL) {
*keysize = 0; *keysize = 0;
*value = 0; *value = 0;
befs_debug(sb, befs_debug(sb,
...@@ -541,7 +536,6 @@ befs_btree_read(struct super_block *sb, const befs_data_stream *ds, ...@@ -541,7 +536,6 @@ befs_btree_read(struct super_block *sb, const befs_data_stream *ds,
* @node_off: Pointer to offset of current node within datastream. Modified * @node_off: Pointer to offset of current node within datastream. Modified
* by the function. * by the function.
* *
*
* Helper function for btree traverse. Moves the current position to the * Helper function for btree traverse. Moves the current position to the
* start of the first leaf node. * start of the first leaf node.
* *
...@@ -608,7 +602,7 @@ static int ...@@ -608,7 +602,7 @@ static int
befs_leafnode(struct befs_btree_node *node) befs_leafnode(struct befs_btree_node *node)
{ {
/* all interior nodes (and only interior nodes) have an overflow node */ /* all interior nodes (and only interior nodes) have an overflow node */
if (node->head.overflow == befs_bt_inval) if (node->head.overflow == BEFS_BT_INVAL)
return 1; return 1;
else else
return 0; return 0;
...@@ -715,7 +709,7 @@ befs_bt_get_key(struct super_block *sb, struct befs_btree_node *node, ...@@ -715,7 +709,7 @@ befs_bt_get_key(struct super_block *sb, struct befs_btree_node *node,
* *
* Returns 0 if @key1 and @key2 are equal. * Returns 0 if @key1 and @key2 are equal.
* Returns >0 if @key1 is greater. * Returns >0 if @key1 is greater.
* Returns <0 if @key2 is greater.. * Returns <0 if @key2 is greater.
*/ */
static int static int
befs_compare_strings(const void *key1, int keylen1, befs_compare_strings(const void *key1, int keylen1,
......
This diff is collapsed.
...@@ -169,6 +169,7 @@ befs_dump_super_block(const struct super_block *sb, befs_super_block * sup) ...@@ -169,6 +169,7 @@ befs_dump_super_block(const struct super_block *sb, befs_super_block * sup)
befs_debug(sb, " num_blocks %llu", fs64_to_cpu(sb, sup->num_blocks)); befs_debug(sb, " num_blocks %llu", fs64_to_cpu(sb, sup->num_blocks));
befs_debug(sb, " used_blocks %llu", fs64_to_cpu(sb, sup->used_blocks)); befs_debug(sb, " used_blocks %llu", fs64_to_cpu(sb, sup->used_blocks));
befs_debug(sb, " inode_size %u", fs32_to_cpu(sb, sup->inode_size));
befs_debug(sb, " magic2 %08x", fs32_to_cpu(sb, sup->magic2)); befs_debug(sb, " magic2 %08x", fs32_to_cpu(sb, sup->magic2));
befs_debug(sb, " blocks_per_ag %u", befs_debug(sb, " blocks_per_ag %u",
......
...@@ -27,7 +27,7 @@ struct buffer_head * ...@@ -27,7 +27,7 @@ struct buffer_head *
befs_bread_iaddr(struct super_block *sb, befs_inode_addr iaddr) befs_bread_iaddr(struct super_block *sb, befs_inode_addr iaddr)
{ {
struct buffer_head *bh; struct buffer_head *bh;
befs_blocknr_t block = 0; befs_blocknr_t block;
struct befs_sb_info *befs_sb = BEFS_SB(sb); struct befs_sb_info *befs_sb = BEFS_SB(sb);
befs_debug(sb, "---> Enter %s " befs_debug(sb, "---> Enter %s "
...@@ -59,27 +59,3 @@ befs_bread_iaddr(struct super_block *sb, befs_inode_addr iaddr) ...@@ -59,27 +59,3 @@ befs_bread_iaddr(struct super_block *sb, befs_inode_addr iaddr)
befs_debug(sb, "<--- %s ERROR", __func__); befs_debug(sb, "<--- %s ERROR", __func__);
return NULL; return NULL;
} }
struct buffer_head *
befs_bread(struct super_block *sb, befs_blocknr_t block)
{
struct buffer_head *bh;
befs_debug(sb, "---> Enter %s %lu", __func__, (unsigned long)block);
bh = sb_bread(sb, block);
if (bh == NULL) {
befs_error(sb, "Failed to read block %lu",
(unsigned long)block);
goto error;
}
befs_debug(sb, "<--- %s", __func__);
return bh;
error:
befs_debug(sb, "<--- %s ERROR", __func__);
return NULL;
}
...@@ -5,5 +5,3 @@ ...@@ -5,5 +5,3 @@
struct buffer_head *befs_bread_iaddr(struct super_block *sb, struct buffer_head *befs_bread_iaddr(struct super_block *sb,
befs_inode_addr iaddr); befs_inode_addr iaddr);
struct buffer_head *befs_bread(struct super_block *sb, befs_blocknr_t block);
...@@ -120,7 +120,7 @@ befs_get_block(struct inode *inode, sector_t block, ...@@ -120,7 +120,7 @@ befs_get_block(struct inode *inode, sector_t block,
struct super_block *sb = inode->i_sb; struct super_block *sb = inode->i_sb;
befs_data_stream *ds = &BEFS_I(inode)->i_data.ds; befs_data_stream *ds = &BEFS_I(inode)->i_data.ds;
befs_block_run run = BAD_IADDR; befs_block_run run = BAD_IADDR;
int res = 0; int res;
ulong disk_off; ulong disk_off;
befs_debug(sb, "---> befs_get_block() for inode %lu, block %ld", befs_debug(sb, "---> befs_get_block() for inode %lu, block %ld",
...@@ -179,15 +179,16 @@ befs_lookup(struct inode *dir, struct dentry *dentry, unsigned int flags) ...@@ -179,15 +179,16 @@ befs_lookup(struct inode *dir, struct dentry *dentry, unsigned int flags)
kfree(utfname); kfree(utfname);
} else { } else {
ret = befs_btree_find(sb, ds, dentry->d_name.name, &offset); ret = befs_btree_find(sb, ds, name, &offset);
} }
if (ret == BEFS_BT_NOT_FOUND) { if (ret == BEFS_BT_NOT_FOUND) {
befs_debug(sb, "<--- %s %pd not found", __func__, dentry); befs_debug(sb, "<--- %s %pd not found", __func__, dentry);
d_add(dentry, NULL);
return ERR_PTR(-ENOENT); return ERR_PTR(-ENOENT);
} else if (ret != BEFS_OK || offset == 0) { } else if (ret != BEFS_OK || offset == 0) {
befs_warning(sb, "<--- %s Error", __func__); befs_error(sb, "<--- %s Error", __func__);
return ERR_PTR(-ENODATA); return ERR_PTR(-ENODATA);
} }
...@@ -211,56 +212,55 @@ befs_readdir(struct file *file, struct dir_context *ctx) ...@@ -211,56 +212,55 @@ befs_readdir(struct file *file, struct dir_context *ctx)
befs_off_t value; befs_off_t value;
int result; int result;
size_t keysize; size_t keysize;
unsigned char d_type;
char keybuf[BEFS_NAME_LEN + 1]; char keybuf[BEFS_NAME_LEN + 1];
befs_debug(sb, "---> %s name %pD, inode %ld, ctx->pos %lld", befs_debug(sb, "---> %s name %pD, inode %ld, ctx->pos %lld",
__func__, file, inode->i_ino, ctx->pos); __func__, file, inode->i_ino, ctx->pos);
more: while (1) {
result = befs_btree_read(sb, ds, ctx->pos, BEFS_NAME_LEN + 1, result = befs_btree_read(sb, ds, ctx->pos, BEFS_NAME_LEN + 1,
keybuf, &keysize, &value); keybuf, &keysize, &value);
if (result == BEFS_ERR) { if (result == BEFS_ERR) {
befs_debug(sb, "<--- %s ERROR", __func__); befs_debug(sb, "<--- %s ERROR", __func__);
befs_error(sb, "IO error reading %pD (inode %lu)", befs_error(sb, "IO error reading %pD (inode %lu)",
file, inode->i_ino); file, inode->i_ino);
return -EIO; return -EIO;
} else if (result == BEFS_BT_END) {
befs_debug(sb, "<--- %s END", __func__);
return 0;
} else if (result == BEFS_BT_EMPTY) {
befs_debug(sb, "<--- %s Empty directory", __func__);
return 0;
}
d_type = DT_UNKNOWN; } else if (result == BEFS_BT_END) {
befs_debug(sb, "<--- %s END", __func__);
return 0;
/* Convert to NLS */ } else if (result == BEFS_BT_EMPTY) {
if (BEFS_SB(sb)->nls) { befs_debug(sb, "<--- %s Empty directory", __func__);
char *nlsname; return 0;
int nlsnamelen;
result =
befs_utf2nls(sb, keybuf, keysize, &nlsname, &nlsnamelen);
if (result < 0) {
befs_debug(sb, "<--- %s ERROR", __func__);
return result;
} }
if (!dir_emit(ctx, nlsname, nlsnamelen,
(ino_t) value, d_type)) { /* Convert to NLS */
if (BEFS_SB(sb)->nls) {
char *nlsname;
int nlsnamelen;
result =
befs_utf2nls(sb, keybuf, keysize, &nlsname,
&nlsnamelen);
if (result < 0) {
befs_debug(sb, "<--- %s ERROR", __func__);
return result;
}
if (!dir_emit(ctx, nlsname, nlsnamelen,
(ino_t) value, DT_UNKNOWN)) {
kfree(nlsname);
return 0;
}
kfree(nlsname); kfree(nlsname);
return 0; } else {
if (!dir_emit(ctx, keybuf, keysize,
(ino_t) value, DT_UNKNOWN))
return 0;
} }
kfree(nlsname); ctx->pos++;
} else {
if (!dir_emit(ctx, keybuf, keysize,
(ino_t) value, d_type))
return 0;
} }
ctx->pos++;
goto more;
} }
static struct inode * static struct inode *
...@@ -299,7 +299,6 @@ static struct inode *befs_iget(struct super_block *sb, unsigned long ino) ...@@ -299,7 +299,6 @@ static struct inode *befs_iget(struct super_block *sb, unsigned long ino)
struct befs_sb_info *befs_sb = BEFS_SB(sb); struct befs_sb_info *befs_sb = BEFS_SB(sb);
struct befs_inode_info *befs_ino; struct befs_inode_info *befs_ino;
struct inode *inode; struct inode *inode;
long ret = -EIO;
befs_debug(sb, "---> %s inode = %lu", __func__, ino); befs_debug(sb, "---> %s inode = %lu", __func__, ino);
...@@ -318,7 +317,7 @@ static struct inode *befs_iget(struct super_block *sb, unsigned long ino) ...@@ -318,7 +317,7 @@ static struct inode *befs_iget(struct super_block *sb, unsigned long ino)
befs_ino->i_inode_num.allocation_group, befs_ino->i_inode_num.allocation_group,
befs_ino->i_inode_num.start, befs_ino->i_inode_num.len); befs_ino->i_inode_num.start, befs_ino->i_inode_num.len);
bh = befs_bread(sb, inode->i_ino); bh = sb_bread(sb, inode->i_ino);
if (!bh) { if (!bh) {
befs_error(sb, "unable to read inode block - " befs_error(sb, "unable to read inode block - "
"inode = %lu", inode->i_ino); "inode = %lu", inode->i_ino);
...@@ -421,7 +420,7 @@ static struct inode *befs_iget(struct super_block *sb, unsigned long ino) ...@@ -421,7 +420,7 @@ static struct inode *befs_iget(struct super_block *sb, unsigned long ino)
unacquire_none: unacquire_none:
iget_failed(inode); iget_failed(inode);
befs_debug(sb, "<--- %s - Bad inode", __func__); befs_debug(sb, "<--- %s - Bad inode", __func__);
return ERR_PTR(ret); return ERR_PTR(-EIO);
} }
/* Initialize the inode cache. Called at fs setup. /* Initialize the inode cache. Called at fs setup.
...@@ -436,10 +435,9 @@ befs_init_inodecache(void) ...@@ -436,10 +435,9 @@ befs_init_inodecache(void)
0, (SLAB_RECLAIM_ACCOUNT| 0, (SLAB_RECLAIM_ACCOUNT|
SLAB_MEM_SPREAD|SLAB_ACCOUNT), SLAB_MEM_SPREAD|SLAB_ACCOUNT),
init_once); init_once);
if (befs_inode_cachep == NULL) { if (befs_inode_cachep == NULL)
pr_err("%s: Couldn't initialize inode slabcache\n", __func__);
return -ENOMEM; return -ENOMEM;
}
return 0; return 0;
} }
...@@ -524,8 +522,6 @@ befs_utf2nls(struct super_block *sb, const char *in, ...@@ -524,8 +522,6 @@ befs_utf2nls(struct super_block *sb, const char *in,
*out = result = kmalloc(maxlen, GFP_NOFS); *out = result = kmalloc(maxlen, GFP_NOFS);
if (!*out) { if (!*out) {
befs_error(sb, "%s cannot allocate memory", __func__);
*out_len = 0;
return -ENOMEM; return -ENOMEM;
} }
...@@ -604,7 +600,6 @@ befs_nls2utf(struct super_block *sb, const char *in, ...@@ -604,7 +600,6 @@ befs_nls2utf(struct super_block *sb, const char *in,
*out = result = kmalloc(maxlen, GFP_NOFS); *out = result = kmalloc(maxlen, GFP_NOFS);
if (!*out) { if (!*out) {
befs_error(sb, "%s cannot allocate memory", __func__);
*out_len = 0; *out_len = 0;
return -ENOMEM; return -ENOMEM;
} }
...@@ -637,10 +632,6 @@ befs_nls2utf(struct super_block *sb, const char *in, ...@@ -637,10 +632,6 @@ befs_nls2utf(struct super_block *sb, const char *in,
return -EILSEQ; return -EILSEQ;
} }
/**
* Use the
*
*/
enum { enum {
Opt_uid, Opt_gid, Opt_charset, Opt_debug, Opt_err, Opt_uid, Opt_gid, Opt_charset, Opt_debug, Opt_err,
}; };
...@@ -760,19 +751,19 @@ befs_fill_super(struct super_block *sb, void *data, int silent) ...@@ -760,19 +751,19 @@ befs_fill_super(struct super_block *sb, void *data, int silent)
long ret = -EINVAL; long ret = -EINVAL;
const unsigned long sb_block = 0; const unsigned long sb_block = 0;
const off_t x86_sb_off = 512; const off_t x86_sb_off = 512;
int blocksize;
save_mount_options(sb, data); save_mount_options(sb, data);
sb->s_fs_info = kzalloc(sizeof(*befs_sb), GFP_KERNEL); sb->s_fs_info = kzalloc(sizeof(*befs_sb), GFP_KERNEL);
if (sb->s_fs_info == NULL) { if (sb->s_fs_info == NULL)
pr_err("(%s): Unable to allocate memory for private "
"portion of superblock. Bailing.\n", sb->s_id);
goto unacquire_none; goto unacquire_none;
}
befs_sb = BEFS_SB(sb); befs_sb = BEFS_SB(sb);
if (!parse_options((char *) data, &befs_sb->mount_opts)) { if (!parse_options((char *) data, &befs_sb->mount_opts)) {
befs_error(sb, "cannot parse mount options"); if (!silent)
befs_error(sb, "cannot parse mount options");
goto unacquire_priv_sbp; goto unacquire_priv_sbp;
} }
...@@ -793,10 +784,16 @@ befs_fill_super(struct super_block *sb, void *data, int silent) ...@@ -793,10 +784,16 @@ befs_fill_super(struct super_block *sb, void *data, int silent)
* least 1k to get the second 512 bytes of the volume. * least 1k to get the second 512 bytes of the volume.
* -WD 10-26-01 * -WD 10-26-01
*/ */
sb_min_blocksize(sb, 1024); blocksize = sb_min_blocksize(sb, 1024);
if (!blocksize) {
if (!silent)
befs_error(sb, "unable to set blocksize");
goto unacquire_priv_sbp;
}
if (!(bh = sb_bread(sb, sb_block))) { if (!(bh = sb_bread(sb, sb_block))) {
befs_error(sb, "unable to read superblock"); if (!silent)
befs_error(sb, "unable to read superblock");
goto unacquire_priv_sbp; goto unacquire_priv_sbp;
} }
...@@ -820,9 +817,9 @@ befs_fill_super(struct super_block *sb, void *data, int silent) ...@@ -820,9 +817,9 @@ befs_fill_super(struct super_block *sb, void *data, int silent)
brelse(bh); brelse(bh);
if( befs_sb->num_blocks > ~((sector_t)0) ) { if( befs_sb->num_blocks > ~((sector_t)0) ) {
befs_error(sb, "blocks count: %llu " if (!silent)
"is larger than the host can use", befs_error(sb, "blocks count: %llu is larger than the host can use",
befs_sb->num_blocks); befs_sb->num_blocks);
goto unacquire_priv_sbp; goto unacquire_priv_sbp;
} }
...@@ -841,7 +838,8 @@ befs_fill_super(struct super_block *sb, void *data, int silent) ...@@ -841,7 +838,8 @@ befs_fill_super(struct super_block *sb, void *data, int silent)
} }
sb->s_root = d_make_root(root); sb->s_root = d_make_root(root);
if (!sb->s_root) { if (!sb->s_root) {
befs_error(sb, "get root inode failed"); if (!silent)
befs_error(sb, "get root inode failed");
goto unacquire_priv_sbp; goto unacquire_priv_sbp;
} }
...@@ -870,9 +868,9 @@ befs_fill_super(struct super_block *sb, void *data, int silent) ...@@ -870,9 +868,9 @@ befs_fill_super(struct super_block *sb, void *data, int silent)
unacquire_priv_sbp: unacquire_priv_sbp:
kfree(befs_sb->mount_opts.iocharset); kfree(befs_sb->mount_opts.iocharset);
kfree(sb->s_fs_info); kfree(sb->s_fs_info);
sb->s_fs_info = NULL;
unacquire_none: unacquire_none:
sb->s_fs_info = NULL;
return ret; return ret;
} }
......
...@@ -13,24 +13,20 @@ ...@@ -13,24 +13,20 @@
#include "befs.h" #include "befs.h"
#include "super.h" #include "super.h"
/** /*
* load_befs_sb -- Read from disk and properly byteswap all the fields * befs_load_sb -- Read from disk and properly byteswap all the fields
* of the befs superblock * of the befs superblock
*
*
*
*
*/ */
int int
befs_load_sb(struct super_block *sb, befs_super_block * disk_sb) befs_load_sb(struct super_block *sb, befs_super_block *disk_sb)
{ {
struct befs_sb_info *befs_sb = BEFS_SB(sb); struct befs_sb_info *befs_sb = BEFS_SB(sb);
/* Check the byte order of the filesystem */ /* Check the byte order of the filesystem */
if (disk_sb->fs_byte_order == BEFS_BYTEORDER_NATIVE_LE) if (disk_sb->fs_byte_order == BEFS_BYTEORDER_NATIVE_LE)
befs_sb->byte_order = BEFS_BYTESEX_LE; befs_sb->byte_order = BEFS_BYTESEX_LE;
else if (disk_sb->fs_byte_order == BEFS_BYTEORDER_NATIVE_BE) else if (disk_sb->fs_byte_order == BEFS_BYTEORDER_NATIVE_BE)
befs_sb->byte_order = BEFS_BYTESEX_BE; befs_sb->byte_order = BEFS_BYTESEX_BE;
befs_sb->magic1 = fs32_to_cpu(sb, disk_sb->magic1); befs_sb->magic1 = fs32_to_cpu(sb, disk_sb->magic1);
befs_sb->magic2 = fs32_to_cpu(sb, disk_sb->magic2); befs_sb->magic2 = fs32_to_cpu(sb, disk_sb->magic2);
...@@ -45,6 +41,8 @@ befs_load_sb(struct super_block *sb, befs_super_block * disk_sb) ...@@ -45,6 +41,8 @@ befs_load_sb(struct super_block *sb, befs_super_block * disk_sb)
befs_sb->ag_shift = fs32_to_cpu(sb, disk_sb->ag_shift); befs_sb->ag_shift = fs32_to_cpu(sb, disk_sb->ag_shift);
befs_sb->num_ags = fs32_to_cpu(sb, disk_sb->num_ags); befs_sb->num_ags = fs32_to_cpu(sb, disk_sb->num_ags);
befs_sb->flags = fs32_to_cpu(sb, disk_sb->flags);
befs_sb->log_blocks = fsrun_to_cpu(sb, disk_sb->log_blocks); befs_sb->log_blocks = fsrun_to_cpu(sb, disk_sb->log_blocks);
befs_sb->log_start = fs64_to_cpu(sb, disk_sb->log_start); befs_sb->log_start = fs64_to_cpu(sb, disk_sb->log_start);
befs_sb->log_end = fs64_to_cpu(sb, disk_sb->log_end); befs_sb->log_end = fs64_to_cpu(sb, disk_sb->log_end);
...@@ -84,15 +82,15 @@ befs_check_sb(struct super_block *sb) ...@@ -84,15 +82,15 @@ befs_check_sb(struct super_block *sb)
} }
if (befs_sb->block_size > PAGE_SIZE) { if (befs_sb->block_size > PAGE_SIZE) {
befs_error(sb, "blocksize(%u) cannot be larger" befs_error(sb, "blocksize(%u) cannot be larger "
"than system pagesize(%lu)", befs_sb->block_size, "than system pagesize(%lu)", befs_sb->block_size,
PAGE_SIZE); PAGE_SIZE);
return BEFS_ERR; return BEFS_ERR;
} }
/* /*
* block_shift and block_size encode the same information * block_shift and block_size encode the same information
* in different ways as a consistency check. * in different ways as a consistency check.
*/ */
if ((1 << befs_sb->block_shift) != befs_sb->block_size) { if ((1 << befs_sb->block_shift) != befs_sb->block_size) {
...@@ -101,10 +99,18 @@ befs_check_sb(struct super_block *sb) ...@@ -101,10 +99,18 @@ befs_check_sb(struct super_block *sb)
return BEFS_ERR; return BEFS_ERR;
} }
if (befs_sb->log_start != befs_sb->log_end) {
/* ag_shift also encodes the same information as blocks_per_ag in a
* different way, non-fatal consistency check
*/
if ((1 << befs_sb->ag_shift) != befs_sb->blocks_per_ag)
befs_error(sb, "ag_shift disagrees with blocks_per_ag.");
if (befs_sb->log_start != befs_sb->log_end ||
befs_sb->flags == BEFS_DIRTY) {
befs_error(sb, "Filesystem not clean! There are blocks in the " befs_error(sb, "Filesystem not clean! There are blocks in the "
"journal. You must boot into BeOS and mount this volume " "journal. You must boot into BeOS and mount this "
"to make it clean."); "volume to make it clean.");
return BEFS_ERR; return BEFS_ERR;
} }
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment