Skip to content

Commit 30460e1

Browse files
cmaiolinoAl Viro
authored andcommitted
fs: Enable bmap() function to properly return errors
By now, bmap() will either return the physical block number related to the requested file offset or 0 in case of error or the requested offset maps into a hole. This patch makes the needed changes to enable bmap() to proper return errors, using the return value as an error return, and now, a pointer must be passed to bmap() to be filled with the mapped physical block. It will change the behavior of bmap() on return: - negative value in case of error - zero on success or map fell into a hole In case of a hole, the *block will be zero too Since this is a prep patch, by now, the only error return is -EINVAL if ->bmap doesn't exist. Reviewed-by: Christoph Hellwig <[email protected]> Signed-off-by: Carlos Maiolino <[email protected]> Signed-off-by: Al Viro <[email protected]>
1 parent c79f46a commit 30460e1

File tree

6 files changed

+70
-36
lines changed

6 files changed

+70
-36
lines changed

drivers/md/md-bitmap.c

Lines changed: 10 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -364,7 +364,7 @@ static int read_page(struct file *file, unsigned long index,
364364
int ret = 0;
365365
struct inode *inode = file_inode(file);
366366
struct buffer_head *bh;
367-
sector_t block;
367+
sector_t block, blk_cur;
368368

369369
pr_debug("read bitmap file (%dB @ %llu)\n", (int)PAGE_SIZE,
370370
(unsigned long long)index << PAGE_SHIFT);
@@ -375,17 +375,21 @@ static int read_page(struct file *file, unsigned long index,
375375
goto out;
376376
}
377377
attach_page_buffers(page, bh);
378-
block = index << (PAGE_SHIFT - inode->i_blkbits);
378+
blk_cur = index << (PAGE_SHIFT - inode->i_blkbits);
379379
while (bh) {
380+
block = blk_cur;
381+
380382
if (count == 0)
381383
bh->b_blocknr = 0;
382384
else {
383-
bh->b_blocknr = bmap(inode, block);
384-
if (bh->b_blocknr == 0) {
385-
/* Cannot use this file! */
385+
ret = bmap(inode, &block);
386+
if (ret || !block) {
386387
ret = -EINVAL;
388+
bh->b_blocknr = 0;
387389
goto out;
388390
}
391+
392+
bh->b_blocknr = block;
389393
bh->b_bdev = inode->i_sb->s_bdev;
390394
if (count < (1<<inode->i_blkbits))
391395
count = 0;
@@ -399,7 +403,7 @@ static int read_page(struct file *file, unsigned long index,
399403
set_buffer_mapped(bh);
400404
submit_bh(REQ_OP_READ, 0, bh);
401405
}
402-
block++;
406+
blk_cur++;
403407
bh = bh->b_this_page;
404408
}
405409
page->index = index;

fs/f2fs/data.c

Lines changed: 11 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -3170,12 +3170,16 @@ static int check_swap_activate(struct file *swap_file, unsigned int max)
31703170
while ((probe_block + blocks_per_page) <= last_block && page_no < max) {
31713171
unsigned block_in_page;
31723172
sector_t first_block;
3173+
sector_t block = 0;
3174+
int err = 0;
31733175

31743176
cond_resched();
31753177

3176-
first_block = bmap(inode, probe_block);
3177-
if (first_block == 0)
3178+
block = probe_block;
3179+
err = bmap(inode, &block);
3180+
if (err || !block)
31783181
goto bad_bmap;
3182+
first_block = block;
31793183

31803184
/*
31813185
* It must be PAGE_SIZE aligned on-disk
@@ -3187,11 +3191,13 @@ static int check_swap_activate(struct file *swap_file, unsigned int max)
31873191

31883192
for (block_in_page = 1; block_in_page < blocks_per_page;
31893193
block_in_page++) {
3190-
sector_t block;
31913194

3192-
block = bmap(inode, probe_block + block_in_page);
3193-
if (block == 0)
3195+
block = probe_block + block_in_page;
3196+
err = bmap(inode, &block);
3197+
3198+
if (err || !block)
31943199
goto bad_bmap;
3200+
31953201
if (block != first_block + block_in_page) {
31963202
/* Discontiguity */
31973203
probe_block++;

fs/inode.c

Lines changed: 19 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -1598,25 +1598,31 @@ void iput(struct inode *inode)
15981598
}
15991599
EXPORT_SYMBOL(iput);
16001600

1601+
#ifdef CONFIG_BLOCK
16011602
/**
16021603
* bmap - find a block number in a file
1603-
* @inode: inode of file
1604-
* @block: block to find
1605-
*
1606-
* Returns the block number on the device holding the inode that
1607-
* is the disk block number for the block of the file requested.
1608-
* That is, asked for block 4 of inode 1 the function will return the
1609-
* disk block relative to the disk start that holds that block of the
1610-
* file.
1604+
* @inode: inode owning the block number being requested
1605+
* @block: pointer containing the block to find
1606+
*
1607+
* Replaces the value in *block with the block number on the device holding
1608+
* corresponding to the requested block number in the file.
1609+
* That is, asked for block 4 of inode 1 the function will replace the
1610+
* 4 in *block, with disk block relative to the disk start that holds that
1611+
* block of the file.
1612+
*
1613+
* Returns -EINVAL in case of error, 0 otherwise. If mapping falls into a
1614+
* hole, returns 0 and *block is also set to 0.
16111615
*/
1612-
sector_t bmap(struct inode *inode, sector_t block)
1616+
int bmap(struct inode *inode, sector_t *block)
16131617
{
1614-
sector_t res = 0;
1615-
if (inode->i_mapping->a_ops->bmap)
1616-
res = inode->i_mapping->a_ops->bmap(inode->i_mapping, block);
1617-
return res;
1618+
if (!inode->i_mapping->a_ops->bmap)
1619+
return -EINVAL;
1620+
1621+
*block = inode->i_mapping->a_ops->bmap(inode->i_mapping, *block);
1622+
return 0;
16181623
}
16191624
EXPORT_SYMBOL(bmap);
1625+
#endif
16201626

16211627
/*
16221628
* With relative atime, only update atime if the previous atime is

fs/jbd2/journal.c

Lines changed: 15 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -795,18 +795,23 @@ int jbd2_journal_bmap(journal_t *journal, unsigned long blocknr,
795795
{
796796
int err = 0;
797797
unsigned long long ret;
798+
sector_t block = 0;
798799

799800
if (journal->j_inode) {
800-
ret = bmap(journal->j_inode, blocknr);
801-
if (ret)
802-
*retp = ret;
803-
else {
801+
block = blocknr;
802+
ret = bmap(journal->j_inode, &block);
803+
804+
if (ret || !block) {
804805
printk(KERN_ALERT "%s: journal block not found "
805806
"at offset %lu on %s\n",
806807
__func__, blocknr, journal->j_devname);
807808
err = -EIO;
808809
__journal_abort_soft(journal, err);
810+
811+
} else {
812+
*retp = block;
809813
}
814+
810815
} else {
811816
*retp = blocknr; /* +journal->j_blk_offset */
812817
}
@@ -1244,11 +1249,14 @@ journal_t *jbd2_journal_init_dev(struct block_device *bdev,
12441249
journal_t *jbd2_journal_init_inode(struct inode *inode)
12451250
{
12461251
journal_t *journal;
1252+
sector_t blocknr;
12471253
char *p;
1248-
unsigned long long blocknr;
1254+
int err = 0;
1255+
1256+
blocknr = 0;
1257+
err = bmap(inode, &blocknr);
12491258

1250-
blocknr = bmap(inode, 0);
1251-
if (!blocknr) {
1259+
if (err || !blocknr) {
12521260
pr_err("%s: Cannot locate journal superblock\n",
12531261
__func__);
12541262
return NULL;

include/linux/fs.h

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2865,9 +2865,16 @@ static inline ssize_t generic_write_sync(struct kiocb *iocb, ssize_t count)
28652865

28662866
extern void emergency_sync(void);
28672867
extern void emergency_remount(void);
2868+
28682869
#ifdef CONFIG_BLOCK
2869-
extern sector_t bmap(struct inode *, sector_t);
2870+
extern int bmap(struct inode *inode, sector_t *block);
2871+
#else
2872+
static inline int bmap(struct inode *inode, sector_t *block)
2873+
{
2874+
return -EINVAL;
2875+
}
28702876
#endif
2877+
28712878
extern int notify_change(struct dentry *, struct iattr *, struct inode **);
28722879
extern int inode_permission(struct inode *, int);
28732880
extern int generic_permission(struct inode *, int);

mm/page_io.c

Lines changed: 7 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -177,8 +177,9 @@ int generic_swapfile_activate(struct swap_info_struct *sis,
177177

178178
cond_resched();
179179

180-
first_block = bmap(inode, probe_block);
181-
if (first_block == 0)
180+
first_block = probe_block;
181+
ret = bmap(inode, &first_block);
182+
if (ret || !first_block)
182183
goto bad_bmap;
183184

184185
/*
@@ -193,9 +194,11 @@ int generic_swapfile_activate(struct swap_info_struct *sis,
193194
block_in_page++) {
194195
sector_t block;
195196

196-
block = bmap(inode, probe_block + block_in_page);
197-
if (block == 0)
197+
block = probe_block + block_in_page;
198+
ret = bmap(inode, &block);
199+
if (ret || !block)
198200
goto bad_bmap;
201+
199202
if (block != first_block + block_in_page) {
200203
/* Discontiguity */
201204
probe_block++;

0 commit comments

Comments
 (0)