diff options
author | Ralf Baechle <ralf@linux-mips.org> | 1999-07-05 23:09:37 +0000 |
---|---|---|
committer | Ralf Baechle <ralf@linux-mips.org> | 1999-07-05 23:09:37 +0000 |
commit | aba344fdfed81b2c03d6114c54cfd73a486aa10b (patch) | |
tree | d032d8430bf1234c3ecc6f6330d6de6e887e5963 /fs/minix | |
parent | 40c138bfc6d37dbff5339f84575db1e3cec6e34e (diff) |
Merge with Linux 2.3.9.
Diffstat (limited to 'fs/minix')
-rw-r--r-- | fs/minix/dir.c | 7 | ||||
-rw-r--r-- | fs/minix/file.c | 53 | ||||
-rw-r--r-- | fs/minix/fsync.c | 4 | ||||
-rw-r--r-- | fs/minix/inode.c | 567 | ||||
-rw-r--r-- | fs/minix/symlink.c | 7 | ||||
-rw-r--r-- | fs/minix/truncate.c | 12 |
6 files changed, 391 insertions, 259 deletions
diff --git a/fs/minix/dir.c b/fs/minix/dir.c index 187925903..a44d5d69d 100644 --- a/fs/minix/dir.c +++ b/fs/minix/dir.c @@ -52,11 +52,14 @@ struct inode_operations minix_dir_inode_operations = { minix_rename, /* rename */ NULL, /* readlink */ NULL, /* follow_link */ + NULL, /* get_block */ NULL, /* readpage */ NULL, /* writepage */ - NULL, /* bmap */ + NULL, /* flushpage */ NULL, /* truncate */ - NULL /* permission */ + NULL, /* permission */ + NULL, /* smap */ + NULL /* revalidate */ }; static int minix_readdir(struct file * filp, diff --git a/fs/minix/file.c b/fs/minix/file.c index d6b7ecb17..14d478bde 100644 --- a/fs/minix/file.c +++ b/fs/minix/file.c @@ -27,50 +27,14 @@ #include <linux/fs.h> #include <linux/minix_fs.h> -static int minix_writepage(struct file *file, struct page *page) -{ - struct dentry *dentry = file->f_dentry; - struct inode *inode = dentry->d_inode; - unsigned long block; - int *p, nr[PAGE_SIZE/BLOCK_SIZE]; - int i, err, created; - struct buffer_head *bh; - - i = PAGE_SIZE / BLOCK_SIZE; - block = page->offset / BLOCK_SIZE; - p = nr; - bh = page->buffers; - do { - if (bh && bh->b_blocknr) - *p = bh->b_blocknr; - else - *p = minix_getblk_block(inode, block, 1, &err, &created); - if (!*p) - return -EIO; - i--; - block++; - p++; - if (bh) - bh = bh->b_this_page; - } while(i > 0); - - /* IO start */ - brw_page(WRITE, page, inode->i_dev, nr, BLOCK_SIZE, 1); - return 0; -} - -static long minix_write_one_page(struct file *file, struct page *page, unsigned long offset, unsigned long bytes, const char *buf) -{ - return block_write_one_page(file, page, offset, bytes, buf, minix_getblk_block); -} - /* * Write to a file (through the page cache). */ static ssize_t minix_file_write(struct file *file, const char *buf, size_t count, loff_t *ppos) { - return generic_file_write(file, buf, count, ppos, minix_write_one_page); + return generic_file_write(file, buf, count, + ppos, block_write_partial_page); } /* @@ -88,7 +52,10 @@ static struct file_operations minix_file_operations = { NULL, /* no special open is needed */ NULL, /* flush */ NULL, /* release */ - minix_sync_file /* fsync */ + minix_sync_file, /* fsync */ + NULL, /* fasync */ + NULL, /* check_media_change */ + NULL /* revalidate */ }; struct inode_operations minix_file_inode_operations = { @@ -104,12 +71,12 @@ struct inode_operations minix_file_inode_operations = { NULL, /* rename */ NULL, /* readlink */ NULL, /* follow_link */ - generic_readpage, /* readpage */ - minix_writepage, /* writepage */ - minix_bmap, /* bmap */ + minix_get_block, /* get_block */ + block_read_full_page, /* readpage */ + block_write_full_page, /* writepage */ + block_flushpage, /* flushpage */ minix_truncate, /* truncate */ NULL, /* permission */ NULL, /* smap */ NULL, /* revalidate */ - block_flushpage, /* flushpage */ }; diff --git a/fs/minix/fsync.c b/fs/minix/fsync.c index ef3d15db9..2fcdddf15 100644 --- a/fs/minix/fsync.c +++ b/fs/minix/fsync.c @@ -53,7 +53,7 @@ static int V1_sync_block (struct inode * inode, unsigned short * block, int wait return 0; } ll_rw_block(WRITE, 1, &bh); - bh->b_count--; + atomic_dec(&bh->b_count); return 0; } @@ -190,7 +190,7 @@ static int V2_sync_block (struct inode * inode, unsigned long * block, int wait) return 0; } ll_rw_block(WRITE, 1, &bh); - bh->b_count--; + atomic_dec(&bh->b_count); return 0; } diff --git a/fs/minix/inode.c b/fs/minix/inode.c index 088de42dc..e5352090d 100644 --- a/fs/minix/inode.c +++ b/fs/minix/inode.c @@ -19,6 +19,7 @@ #include <linux/stat.h> #include <linux/locks.h> #include <linux/init.h> +#include <linux/smp_lock.h> #include <asm/system.h> #include <asm/uaccess.h> @@ -361,112 +362,127 @@ static int V1_block_bmap(struct buffer_head * bh, int nr) return tmp; } -static int V1_minix_bmap(struct inode * inode,int block) +static int V1_minix_block_map(struct inode * inode, long block) { - int i; + int i, ret; - if (block<0) { + ret = 0; + lock_kernel(); + if (block < 0) { printk("minix_bmap: block<0"); - return 0; + goto out; } if (block >= (inode->i_sb->u.minix_sb.s_max_size/BLOCK_SIZE)) { printk("minix_bmap: block>big"); - return 0; + goto out; + } + if (block < 7) { + ret = V1_inode_bmap(inode,block); + goto out; } - if (block < 7) - return V1_inode_bmap(inode,block); block -= 7; if (block < 512) { i = V1_inode_bmap(inode,7); if (!i) - return 0; - return V1_block_bmap(bread(inode->i_dev,i,BLOCK_SIZE),block); + goto out; + ret = V1_block_bmap(bread(inode->i_dev, i, + BLOCK_SIZE), block); + goto out; } block -= 512; i = V1_inode_bmap(inode,8); if (!i) - return 0; + goto out; i = V1_block_bmap(bread(inode->i_dev,i,BLOCK_SIZE),block>>9); if (!i) - return 0; - return V1_block_bmap(bread(inode->i_dev,i,BLOCK_SIZE),block & 511); + goto out; + ret = V1_block_bmap(bread(inode->i_dev, i, BLOCK_SIZE), + block & 511); +out: + unlock_kernel(); + return ret; } /* * The minix V2 fs bmap functions. */ -#define V2_inode_bmap(inode,nr) (((unsigned long *)(inode)->u.minix_i.u.i2_data)[(nr)]) +#define V2_inode_bmap(inode,nr) (((unsigned int *)(inode)->u.minix_i.u.i2_data)[(nr)]) static int V2_block_bmap(struct buffer_head * bh, int nr) { int tmp; if (!bh) return 0; - tmp = ((unsigned long *) bh->b_data)[nr]; + tmp = ((unsigned int *) bh->b_data)[nr]; brelse(bh); return tmp; } -static int V2_minix_bmap(struct inode * inode, int block) +static int V2_minix_block_map(struct inode * inode, int block) { - int i; + int i, ret; - if (block<0) { + ret = 0; + lock_kernel(); + if (block < 0) { printk("minix_bmap: block<0"); - return 0; + goto out; } if (block >= (inode->i_sb->u.minix_sb.s_max_size/BLOCK_SIZE)) { printk("minix_bmap: block>big"); - return 0; + goto out; + } + if (block < 7) { + ret = V2_inode_bmap(inode,block); + goto out; } - if (block < 7) - return V2_inode_bmap(inode,block); block -= 7; if (block < 256) { - i = V2_inode_bmap(inode,7); + i = V2_inode_bmap(inode, 7); if (!i) - return 0; - return V2_block_bmap(bread(inode->i_dev,i,BLOCK_SIZE),block); + goto out; + ret = V2_block_bmap(bread(inode->i_dev, i, + BLOCK_SIZE), block); + goto out; } block -= 256; - if (block < 256*256) { - i = V2_inode_bmap(inode,8); + if (block < (256 * 256)) { + i = V2_inode_bmap(inode, 8); if (!i) - return 0; - i = V2_block_bmap(bread(inode->i_dev,i,BLOCK_SIZE),block >> 8); + goto out; + i = V2_block_bmap(bread(inode->i_dev, i, BLOCK_SIZE), + block >> 8); if (!i) - return 0; - return V2_block_bmap(bread(inode->i_dev,i,BLOCK_SIZE),block & 255); + goto out; + ret = V2_block_bmap(bread(inode->i_dev, i, BLOCK_SIZE), + block & 255); + goto out; } - block -= 256*256; - i = V2_inode_bmap(inode,9); + block -= (256 * 256); + i = V2_inode_bmap(inode, 9); if (!i) - return 0; - i = V2_block_bmap(bread(inode->i_dev,i,BLOCK_SIZE),block >> 16); + goto out; + i = V2_block_bmap(bread(inode->i_dev, i, BLOCK_SIZE), + block >> 16); if (!i) - return 0; - i = V2_block_bmap(bread(inode->i_dev,i,BLOCK_SIZE),(block >> 8) & 255); + goto out; + i = V2_block_bmap(bread(inode->i_dev, i, BLOCK_SIZE), + (block >> 8) & 255); if (!i) - return 0; - return V2_block_bmap(bread(inode->i_dev,i,BLOCK_SIZE),block & 255); -} - -/* - * The global minix fs bmap function. - */ -int minix_bmap(struct inode * inode, int block) -{ - if (INODE_VERSION(inode) == MINIX_V1) - return V1_minix_bmap(inode, block); - else - return V2_minix_bmap(inode, block); + goto out; + ret = V2_block_bmap(bread(inode->i_dev, i, BLOCK_SIZE), + block & 255); +out: + unlock_kernel(); + return ret; } /* * The minix V1 fs getblk functions. */ -static struct buffer_head * V1_inode_getblk(struct inode * inode, int nr, int create, - int metadata, int *phys_block, int *created) +static struct buffer_head * V1_inode_getblk(struct inode * inode, int nr, + int new_block, int *err, + int metadata, int *phys, int *new) { int tmp; unsigned short *p; @@ -483,15 +499,30 @@ repeat: brelse(result); goto repeat; } else { - *phys_block = tmp; + *phys = tmp; return NULL; } } - if (!create) - return NULL; + *err = -EFBIG; + + /* Check file limits.. */ + { + unsigned long limit = current->rlim[RLIMIT_FSIZE].rlim_cur; + if (limit < RLIM_INFINITY) { + limit >>= BLOCK_SIZE_BITS; + if (new_block >= limit) { + send_sig(SIGXFSZ, current, 0); + *err = -EFBIG; + return NULL; + } + } + } + tmp = minix_new_block(inode->i_sb); - if (!tmp) + if (!tmp) { + *err = -ENOSPC; return NULL; + } if (metadata) { result = getblk(inode->i_dev, tmp, BLOCK_SIZE); if (*p) { @@ -504,12 +535,18 @@ repeat: mark_buffer_dirty(result, 1); } else { if (*p) { + /* + * Nobody is allowed to change block allocation + * state from under us: + */ + BUG(); minix_free_block(inode->i_sb, tmp); goto repeat; } - *phys_block = tmp; + *phys = tmp; result = NULL; - *created = 1; + *err = 0; + *new = 1; } *p = tmp; @@ -519,22 +556,22 @@ repeat: } static struct buffer_head * V1_block_getblk(struct inode * inode, - struct buffer_head * bh, int nr, int create, - int metadata, int *phys_block, int *created) + struct buffer_head * bh, int nr, int new_block, int *err, + int metadata, int *phys, int *new) { int tmp; unsigned short *p; struct buffer_head * result; + unsigned long limit; + result = NULL; if (!bh) - return NULL; + goto out; if (!buffer_uptodate(bh)) { ll_rw_block(READ, 1, &bh); wait_on_buffer(bh); - if (!buffer_uptodate(bh)) { - brelse(bh); - return NULL; - } + if (!buffer_uptodate(bh)) + goto out; } p = nr + (unsigned short *) bh->b_data; repeat: @@ -542,27 +579,29 @@ repeat: if (tmp) { if (metadata) { result = getblk(bh->b_dev, tmp, BLOCK_SIZE); - if (tmp == *p) { - brelse(bh); - return result; - } + if (tmp == *p) + goto out; brelse(result); goto repeat; } else { - *phys_block = tmp; - brelse(bh); - return NULL; + *phys = tmp; + goto out; } } - if (!create) { - brelse(bh); - return NULL; + *err = -EFBIG; + + limit = current->rlim[RLIMIT_FSIZE].rlim_cur; + if (limit < RLIM_INFINITY) { + limit >>= BLOCK_SIZE_BITS; + if (new_block >= limit) { + send_sig(SIGXFSZ, current, 0); + goto out; + } } + tmp = minix_new_block(inode->i_sb); - if (!tmp) { - brelse(bh); - return NULL; - } + if (!tmp) + goto out; if (metadata) { result = getblk(bh->b_dev, tmp, BLOCK_SIZE); if (*p) { @@ -574,69 +613,118 @@ repeat: mark_buffer_uptodate(result, 1); mark_buffer_dirty(result, 1); } else { - if (*p) { - minix_free_block(inode->i_sb, tmp); - goto repeat; - } - *phys_block = tmp; - result = NULL; - *created = 1; + *phys = tmp; + *new = 1; + } + if (*p) { + minix_free_block(inode->i_sb, tmp); + brelse(result); + goto repeat; } *p = tmp; mark_buffer_dirty(bh, 1); + *err = 0; +out: brelse(bh); return result; } -int V1_getblk_block(struct inode * inode, long block, int create, int *err, int *created) +static int V1_get_block(struct inode * inode, long block, + struct buffer_head *bh_result, int create) { - struct buffer_head *bh, *tmp; - int phys_block; + int ret, err, new, phys, ptr; + struct buffer_head *bh; - *err = -EIO; - if (block < 0) { - printk("minix_getblk: block<0"); - return 0; - } - if (block >= inode->i_sb->u.minix_sb.s_max_size/BLOCK_SIZE) { - printk("minix_getblk: block>big"); + if (!create) { + phys = V1_minix_block_map(inode, block); + if (phys) { + bh_result->b_dev = inode->i_dev; + bh_result->b_blocknr = phys; + bh_result->b_state |= (1UL << BH_Mapped); + } return 0; } - *created = 0; - if (block < 7) { - tmp = V1_inode_getblk(inode, block, create, - 0, &phys_block, created); + + err = -EIO; + new = 0; + ret = 0; + bh = NULL; + + lock_kernel(); + if (block < 0) + goto abort_negative; + if (block >= inode->i_sb->u.minix_sb.s_max_size/BLOCK_SIZE) + goto abort_too_big; + + err = 0; + ptr = block; + /* + * ok, these macros clean the logic up a bit and make + * it much more readable: + */ +#define GET_INODE_DATABLOCK(x) \ + V1_inode_getblk(inode, x, block, &err, 0, &phys, &new) +#define GET_INODE_PTR(x) \ + V1_inode_getblk(inode, x, block, &err, 1, NULL, NULL) +#define GET_INDIRECT_DATABLOCK(x) \ + V1_block_getblk(inode, bh, x, block, &err, 0, &phys, &new) +#define GET_INDIRECT_PTR(x) \ + V1_block_getblk(inode, bh, x, block, &err, 1, NULL, NULL) + + if (ptr < 7) { + bh = GET_INODE_DATABLOCK(ptr); goto out; } - block -= 7; - if (block < 512) { - bh = V1_inode_getblk(inode, 7, create, 1, NULL, NULL); - tmp = V1_block_getblk(inode, bh, block, create, - 0, &phys_block, created); - goto out; + ptr -= 7; + if (ptr < 512) { + bh = GET_INODE_PTR(7); + goto get_indirect; } - block -= 512; - bh = V1_inode_getblk(inode, 8, create, 1, NULL, NULL); - bh = V1_block_getblk(inode, bh, (block>>9) & 511, create, 1, NULL, NULL); - tmp = V1_block_getblk(inode, bh, block & 511, create, 0, &phys_block, created); + ptr -= 512; + bh = GET_INODE_PTR(8); + bh = GET_INDIRECT_PTR((ptr >> 9) & 511); +get_indirect: + bh = GET_INDIRECT_DATABLOCK(ptr & 511); + +#undef GET_INODE_DATABLOCK +#undef GET_INODE_PTR +#undef GET_INDIRECT_DATABLOCK +#undef GET_INDIRECT_PTR out: - *err = 0; - return phys_block; + if (err) + goto abort; + bh_result->b_dev = inode->i_dev; + bh_result->b_blocknr = phys; + bh_result->b_state |= (1UL << BH_Mapped); + if (new) + bh_result->b_state |= (1UL << BH_New); +abort: + unlock_kernel(); + return err; + +abort_negative: + printk("minix_getblk: block<0"); + goto abort; + +abort_too_big: + printk("minix_getblk: block>big"); + goto abort; } /* * The minix V2 fs getblk functions. */ -static struct buffer_head * V2_inode_getblk(struct inode * inode, int nr, int create, - int metadata, int *phys_block, int *created) +static struct buffer_head * V2_inode_getblk(struct inode * inode, int nr, + int new_block, int *err, + int metadata, int *phys, int *new) { int tmp; - unsigned long *p; + unsigned int *p; struct buffer_head * result; - p = (unsigned long *) inode->u.minix_i.u.i2_data + nr; + p = (unsigned int *) inode->u.minix_i.u.i2_data + nr; repeat: tmp = *p; if (tmp) { @@ -647,15 +735,30 @@ repeat: brelse(result); goto repeat; } else { - *phys_block = tmp; + *phys = tmp; return NULL; } } - if (!create) - return NULL; + *err = -EFBIG; + + /* Check file limits.. */ + { + unsigned long limit = current->rlim[RLIMIT_FSIZE].rlim_cur; + if (limit < RLIM_INFINITY) { + limit >>= BLOCK_SIZE_BITS; + if (new_block >= limit) { + send_sig(SIGXFSZ, current, 0); + *err = -EFBIG; + return NULL; + } + } + } + tmp = minix_new_block(inode->i_sb); - if (!tmp) + if (!tmp) { + *err = -ENOSPC; return NULL; + } if (metadata) { result = getblk(inode->i_dev, tmp, BLOCK_SIZE); if (*p) { @@ -668,12 +771,18 @@ repeat: mark_buffer_dirty(result, 1); } else { if (*p) { + /* + * Nobody is allowed to change block allocation + * state from under us: + */ + BUG(); minix_free_block(inode->i_sb, tmp); goto repeat; } - *phys_block = tmp; + *phys = tmp; result = NULL; - *created = 1; + *err = 0; + *new = 1; } *p = tmp; @@ -683,50 +792,52 @@ repeat: } static struct buffer_head * V2_block_getblk(struct inode * inode, - struct buffer_head * bh, int nr, int create, - int metadata, int *phys_block, int *created) + struct buffer_head * bh, int nr, int new_block, int *err, + int metadata, int *phys, int *new) { int tmp; - unsigned long *p; + unsigned int *p; struct buffer_head * result; + unsigned long limit; + result = NULL; if (!bh) - return NULL; + goto out; if (!buffer_uptodate(bh)) { ll_rw_block(READ, 1, &bh); wait_on_buffer(bh); - if (!buffer_uptodate(bh)) { - brelse(bh); - return NULL; - } + if (!buffer_uptodate(bh)) + goto out; } - p = nr + (unsigned long *) bh->b_data; + p = nr + (unsigned int *) bh->b_data; repeat: tmp = *p; if (tmp) { if (metadata) { result = getblk(bh->b_dev, tmp, BLOCK_SIZE); - if (tmp == *p) { - brelse(bh); - return result; - } + if (tmp == *p) + goto out; brelse(result); goto repeat; } else { - *phys_block = tmp; - brelse(bh); - return NULL; + *phys = tmp; + goto out; } } - if (!create) { - brelse(bh); - return NULL; + *err = -EFBIG; + + limit = current->rlim[RLIMIT_FSIZE].rlim_cur; + if (limit < RLIM_INFINITY) { + limit >>= BLOCK_SIZE_BITS; + if (new_block >= limit) { + send_sig(SIGXFSZ, current, 0); + goto out; + } } + tmp = minix_new_block(inode->i_sb); - if (!tmp) { - brelse(bh); - return NULL; - } + if (!tmp) + goto out; if (metadata) { result = getblk(bh->b_dev, tmp, BLOCK_SIZE); if (*p) { @@ -738,103 +849,151 @@ repeat: mark_buffer_uptodate(result, 1); mark_buffer_dirty(result, 1); } else { - if (*p) { - minix_free_block(inode->i_sb, tmp); - goto repeat; - } - *phys_block = tmp; - result = NULL; - *created = 1; + *phys = tmp; + *new = 1; + } + if (*p) { + minix_free_block(inode->i_sb, tmp); + brelse(result); + goto repeat; } *p = tmp; mark_buffer_dirty(bh, 1); + *err = 0; +out: brelse(bh); return result; } -int V2_getblk_block(struct inode * inode, int block, int create, int *err, int *created) +static int V2_get_block(struct inode * inode, long block, + struct buffer_head *bh_result, int create) { - struct buffer_head * bh, *tmp; - int phys_block; + int ret, err, new, phys, ptr; + struct buffer_head * bh; - *err = -EIO; - if (block < 0) { - printk("minix_getblk: block<0"); - return 0; - } - if (block >= inode->i_sb->u.minix_sb.s_max_size/BLOCK_SIZE) { - printk("minix_getblk: block>big"); + if (!create) { + phys = V2_minix_block_map(inode, block); + if (phys) { + bh_result->b_dev = inode->i_dev; + bh_result->b_blocknr = phys; + bh_result->b_state |= (1UL << BH_Mapped); + } return 0; } - *created = 0; - if (block < 7) { - tmp = V2_inode_getblk(inode, block, create, - 0, &phys_block, created); + + err = -EIO; + new = 0; + ret = 0; + bh = NULL; + + lock_kernel(); + if (block < 0) + goto abort_negative; + if (block >= inode->i_sb->u.minix_sb.s_max_size/BLOCK_SIZE) + goto abort_too_big; + + err = 0; + ptr = block; + /* + * ok, these macros clean the logic up a bit and make + * it much more readable: + */ +#define GET_INODE_DATABLOCK(x) \ + V2_inode_getblk(inode, x, block, &err, 0, &phys, &new) +#define GET_INODE_PTR(x) \ + V2_inode_getblk(inode, x, block, &err, 1, NULL, NULL) +#define GET_INDIRECT_DATABLOCK(x) \ + V2_block_getblk(inode, bh, x, block, &err, 0, &phys, &new) +#define GET_INDIRECT_PTR(x) \ + V2_block_getblk(inode, bh, x, block, &err, 1, NULL, NULL) + + if (ptr < 7) { + bh = GET_INODE_DATABLOCK(ptr); goto out; } - block -= 7; - if (block < 256) { - bh = V2_inode_getblk(inode, 7, create, 1, NULL, NULL); - tmp = V2_block_getblk(inode, bh, block, create, - 0, &phys_block, created); - goto out; + ptr -= 7; + if (ptr < 256) { + bh = GET_INODE_PTR(7); + goto get_indirect; } - block -= 256; - if (block < 256*256) { - bh = V2_inode_getblk(inode, 8, create, 1, NULL, NULL); - bh = V2_block_getblk(inode, bh, (block>>8) & 255, create, - 1, NULL, NULL); - tmp = V2_block_getblk(inode, bh, block & 255, create, - 0, &phys_block, created); - goto out; + ptr -= 256; + if (ptr < 256*256) { + bh = GET_INODE_PTR(8); + goto get_double; } - block -= 256*256; - bh = V2_inode_getblk(inode, 9, create, 1, NULL, NULL); - bh = V2_block_getblk(inode, bh, (block >> 16) & 255, create, 1, NULL, NULL); - bh = V2_block_getblk(inode, bh, (block >> 8) & 255, create, 1, NULL, NULL); - tmp = V2_block_getblk(inode, bh, block & 255, create, 0, &phys_block, created); + ptr -= 256*256; + bh = GET_INODE_PTR(9); + bh = GET_INDIRECT_PTR((ptr >> 16) & 255); +get_double: + bh = GET_INDIRECT_PTR((ptr >> 8) & 255); +get_indirect: + bh = GET_INDIRECT_DATABLOCK(ptr & 255); + +#undef GET_INODE_DATABLOCK +#undef GET_INODE_PTR +#undef GET_INDIRECT_DATABLOCK +#undef GET_INDIRECT_PTR out: - *err = 0; - return phys_block; + if (err) + goto abort; + bh_result->b_dev = inode->i_dev; + bh_result->b_blocknr = phys; + bh_result->b_state |= (1UL << BH_Mapped); + if (new) + bh_result->b_state |= (1UL << BH_New); +abort: + unlock_kernel(); + return err; + +abort_negative: + printk("minix_getblk: block<0"); + goto abort; + +abort_too_big: + printk("minix_getblk: block>big"); + goto abort; } -int minix_getblk_block (struct inode *inode, long block, - int create, int *err, int *created) +int minix_get_block(struct inode *inode, long block, + struct buffer_head *bh_result, int create) { if (INODE_VERSION(inode) == MINIX_V1) - return V1_getblk_block(inode, block, create, err, created); + return V1_get_block(inode, block, bh_result, create); else - return V2_getblk_block(inode, block, create, err, created); + return V2_get_block(inode, block, bh_result, create); } /* * the global minix fs getblk function. */ -struct buffer_head *minix_getblk (struct inode *inode, int block, int create) +struct buffer_head *minix_getblk(struct inode *inode, int block, int create) { - struct buffer_head *tmp = NULL; - int phys_block; - int err, created; - - phys_block = minix_getblk_block(inode, block, create, &err, &created); - if (phys_block) { - tmp = getblk(inode->i_dev, phys_block, BLOCK_SIZE); - if (created) { - memset(tmp->b_data, 0, BLOCK_SIZE); - mark_buffer_uptodate(tmp, 1); - mark_buffer_dirty(tmp, 1); + struct buffer_head dummy; + int error; + + dummy.b_state = 0; + dummy.b_blocknr = -1000; + error = minix_get_block(inode, block, &dummy, create); + if (!error && buffer_mapped(&dummy)) { + struct buffer_head *bh; + bh = getblk(dummy.b_dev, dummy.b_blocknr, BLOCK_SIZE); + if (buffer_new(&dummy)) { + memset(bh->b_data, 0, BLOCK_SIZE); + mark_buffer_uptodate(bh, 1); + mark_buffer_dirty(bh, 1); } + return bh; } - return tmp; + return NULL; } struct buffer_head * minix_bread(struct inode * inode, int block, int create) { struct buffer_head * bh; - bh = minix_getblk(inode,block,create); + bh = minix_getblk(inode, block, create); if (!bh || buffer_uptodate(bh)) return bh; ll_rw_block(READ, 1, &bh); diff --git a/fs/minix/symlink.c b/fs/minix/symlink.c index 4f3661105..3a8951b09 100644 --- a/fs/minix/symlink.c +++ b/fs/minix/symlink.c @@ -33,11 +33,14 @@ struct inode_operations minix_symlink_inode_operations = { NULL, /* rename */ minix_readlink, /* readlink */ minix_follow_link, /* follow_link */ + NULL, /* get_block */ NULL, /* readpage */ NULL, /* writepage */ - NULL, /* bmap */ + NULL, /* flushpage */ NULL, /* truncate */ - NULL /* permission */ + NULL, /* permission */ + NULL, /* smap */ + NULL /* revalidate */ }; static struct dentry * minix_follow_link(struct dentry * dentry, diff --git a/fs/minix/truncate.c b/fs/minix/truncate.c index 4718e092e..6724d0064 100644 --- a/fs/minix/truncate.c +++ b/fs/minix/truncate.c @@ -33,7 +33,7 @@ */ #define DATA_BUFFER_USED(bh) \ - ((bh->b_count > 1) || buffer_locked(bh)) + (atomic_read(&bh->b_count) || buffer_locked(bh)) /* * The functions for minix V1 fs truncation. @@ -121,7 +121,7 @@ repeat: if (*(ind++)) break; if (i >= 512) { - if (ind_bh->b_count != 1) + if (atomic_read(&ind_bh->b_count) != 1) retry = 1; else { tmp = *p; @@ -166,7 +166,7 @@ repeat: if (*(dind++)) break; if (i >= 512) { - if (dind_bh->b_count != 1) + if (atomic_read(&dind_bh->b_count) != 1) retry = 1; else { tmp = *p; @@ -285,7 +285,7 @@ repeat: if (*(ind++)) break; if (i >= 256) { - if (ind_bh->b_count != 1) + if (atomic_read(&ind_bh->b_count) != 1) retry = 1; else { tmp = *p; @@ -330,7 +330,7 @@ repeat: if (*(dind++)) break; if (i >= 256) { - if (dind_bh->b_count != 1) + if (atomic_read(&dind_bh->b_count) != 1) retry = 1; else { tmp = *p; @@ -376,7 +376,7 @@ repeat: if (*(tind++)) break; if (i >= 256) { - if (tind_bh->b_count != 1) + if (atomic_read(&tind_bh->b_count) != 1) retry = 1; else { tmp = *p; |