From aba344fdfed81b2c03d6114c54cfd73a486aa10b Mon Sep 17 00:00:00 2001 From: Ralf Baechle Date: Mon, 5 Jul 1999 23:09:37 +0000 Subject: Merge with Linux 2.3.9. --- fs/ufs/dir.c | 10 +- fs/ufs/file.c | 58 +++----- fs/ufs/inode.c | 400 ++++++++++++++++++++++++++++-------------------------- fs/ufs/super.c | 23 +++- fs/ufs/symlink.c | 6 +- fs/ufs/truncate.c | 2 +- fs/ufs/util.c | 4 +- 7 files changed, 252 insertions(+), 251 deletions(-) (limited to 'fs/ufs') diff --git a/fs/ufs/dir.c b/fs/ufs/dir.c index 6a79c4a5e..b93d04f0b 100644 --- a/fs/ufs/dir.c +++ b/fs/ufs/dir.c @@ -55,10 +55,8 @@ ufs_readdir (struct file * filp, void * dirent, filldir_t filldir) while (!error && !stored && filp->f_pos < inode->i_size) { lblk = (filp->f_pos) >> sb->s_blocksize_bits; - /* XXX - ufs_bmap() call needs error checking */ - blk = ufs_bmap(inode, lblk); - bh = bread (sb->s_dev, blk, sb->s_blocksize); - if (!bh) { + blk = ufs_frag_map(inode, lblk); + if (!blk || !(bh = bread (sb->s_dev, blk, sb->s_blocksize))) { /* XXX - error - skip to the next block */ printk("ufs_readdir: " "dir inode %lu has a hole at offset %lu\n", @@ -209,10 +207,12 @@ struct inode_operations ufs_dir_inode_operations = { ufs_rename, /* rename */ NULL, /* readlink */ NULL, /* follow_link */ + NULL, /* get_block */ NULL, /* readpage */ NULL, /* writepage */ - NULL, /* bmap */ + NULL, /* flushpage */ NULL, /* truncate */ ufs_permission, /* permission */ NULL, /* smap */ + NULL /* revalidate */ }; diff --git a/fs/ufs/file.c b/fs/ufs/file.c index 9e027cfc3..33d68ba5d 100644 --- a/fs/ufs/file.c +++ b/fs/ufs/file.c @@ -87,49 +87,23 @@ static inline void remove_suid(struct inode *inode) } } -static int ufs_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/512]; - int i, err, created; - struct buffer_head *bh; - - i = PAGE_SIZE >> inode->i_sb->s_blocksize_bits; - block = page->offset >> inode->i_sb->s_blocksize_bits; - p = nr; - bh = page->buffers; - do { - if (bh && bh->b_blocknr) - *p = bh->b_blocknr; - else - *p = ufs_getfrag_block(inode, block, 1, &err, &created); - if (!*p) - return -EIO; - i--; - block++; - p++; - if (bh) - bh = bh->b_this_page; - } while (i > 0); - - brw_page(WRITE, page, inode->i_dev, nr, inode->i_sb->s_blocksize, 1); - return 0; -} - -static long ufs_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, ufs_getfrag_block); -} - /* * Write to a file (through the page cache). */ static ssize_t ufs_file_write(struct file *file, const char *buf, size_t count, loff_t *ppos) { - return generic_file_write(file, buf, count, ppos, ufs_write_one_page); + ssize_t retval; + + retval = generic_file_write(file, buf, count, + ppos, block_write_partial_page); + if (retval > 0) { + struct inode *inode = file->f_dentry->d_inode; + remove_suid(inode); + inode->i_ctime = inode->i_mtime = CURRENT_TIME; + mark_inode_dirty(inode); + } + return retval; } /* @@ -176,12 +150,12 @@ struct inode_operations ufs_file_inode_operations = { NULL, /* rename */ NULL, /* readlink */ NULL, /* follow_link */ - generic_readpage, /* readpage */ - ufs_writepage, /* writepage */ - ufs_bmap, /* bmap */ + ufs_getfrag_block, /* get_block */ + block_read_full_page, /* readpage */ + block_write_full_page, /* writepage */ + block_flushpage, /* flushpage */ ufs_truncate, /* truncate */ NULL, /* permission */ NULL, /* smap */ - NULL, /* revalidate */ - block_flushpage, /* flushpage */ + NULL /* revalidate */ }; diff --git a/fs/ufs/inode.c b/fs/ufs/inode.c index 636b0aabd..3d9c8f602 100644 --- a/fs/ufs/inode.c +++ b/fs/ufs/inode.c @@ -36,6 +36,7 @@ #include #include #include +#include #include "swab.h" #include "util.h" @@ -82,10 +83,10 @@ static void ufs_print_inode(struct inode * inode) #define ufs_inode_bmap(inode, nr) \ (SWAB32((inode)->u.ufs_i.i_u1.i_data[(nr) >> uspi->s_fpbshift]) + ((nr) & uspi->s_fpbmask)) -static inline unsigned ufs_block_bmap (struct buffer_head * bh, unsigned nr, +static inline unsigned int ufs_block_bmap (struct buffer_head * bh, unsigned nr, struct ufs_sb_private_info * uspi, unsigned swab) { - unsigned tmp; + unsigned int tmp; UFSD(("ENTER, nr %u\n", nr)) if (!bh) @@ -96,86 +97,90 @@ static inline unsigned ufs_block_bmap (struct buffer_head * bh, unsigned nr, return tmp; } -int ufs_bmap (struct inode * inode, int fragment) +int ufs_frag_map(struct inode *inode, int frag) { - struct super_block * sb; - struct ufs_sb_private_info * uspi; - unsigned tmp; - unsigned swab; + struct super_block *sb; + struct ufs_sb_private_info *uspi; + unsigned int swab; + int i, ret; + + ret = 0; + lock_kernel(); sb = inode->i_sb; uspi = sb->u.ufs_sb.s_uspi; swab = sb->u.ufs_sb.s_swab; - - UFSD(("ENTER, ino %lu, fragment %u\n", inode->i_ino, fragment)) - - if (fragment >= ((UFS_NDADDR + uspi->s_apb + uspi->s_2apb + uspi->s_3apb) << uspi->s_fpbshift)) { - ufs_warning (sb, "ufs_bmap", "block > big"); - return 0; + if (frag < 0) { + ufs_warning(sb, "ufs_frag_map", "frag < 0"); + goto out; } - - /* - * direct fragment - */ - if (fragment < UFS_NDIR_FRAGMENT) - return (uspi->s_sbbase + ufs_inode_bmap (inode, fragment)); - - /* - * indirect fragment - */ - fragment -= UFS_NDIR_FRAGMENT; - if (fragment < (1 << (uspi->s_apbshift + uspi->s_fpbshift))) { - tmp = ufs_inode_bmap (inode, - UFS_IND_FRAGMENT + (fragment >> uspi->s_apbshift)); - if (!tmp) - return 0; - return (uspi->s_sbbase + - ufs_block_bmap (bread (sb->s_dev, uspi->s_sbbase + tmp, sb->s_blocksize), - fragment & uspi->s_apbmask, uspi, swab)); + if (frag >= + ((UFS_NDADDR + uspi->s_apb + uspi->s_2apb + uspi->s_3apb) + << uspi->s_fpbshift)) { + ufs_warning(sb, "ufs_frag_map", "frag > big"); + goto out; } - /* - * dindirect fragment - */ - fragment -= 1 << (uspi->s_apbshift + uspi->s_fpbshift); - if (fragment < (1 << (uspi->s_2apbshift + uspi->s_fpbshift))) { - tmp = ufs_inode_bmap (inode, - UFS_DIND_FRAGMENT + (fragment >> uspi->s_2apbshift)); - if (!tmp) - return 0; - tmp = ufs_block_bmap (bread (sb->s_dev, uspi->s_sbbase + tmp, sb->s_blocksize), - (fragment >> uspi->s_apbshift) & uspi->s_apbmask, uspi, swab); - if (!tmp) - return 0; - return (uspi->s_sbbase + - ufs_block_bmap (bread (sb->s_dev, uspi->s_sbbase + tmp, sb->s_blocksize), - fragment & uspi->s_apbmask, uspi, swab)); + if (frag < UFS_NDIR_FRAGMENT) { + ret = uspi->s_sbbase + ufs_inode_bmap(inode, frag); + goto out; } - /* - * tindirect fragment - */ - fragment -= 1 << (uspi->s_2apbshift + uspi->s_fpbshift); - tmp = ufs_inode_bmap (inode, - UFS_TIND_FRAGMENT + (fragment >> uspi->s_3apbshift)); - if (!tmp) - return 0; - tmp = ufs_block_bmap (bread (sb->s_dev, uspi->s_sbbase + tmp, sb->s_blocksize), - (fragment >> uspi->s_2apbshift) & uspi->s_apbmask, uspi, swab); - if (!tmp) - return 0; - tmp = ufs_block_bmap (bread (sb->s_dev, uspi->s_sbbase + tmp, sb->s_blocksize), - (fragment >> uspi->s_apbshift) & uspi->s_apbmask, uspi, swab); - if (!tmp) - return 0; - return (uspi->s_sbbase + - ufs_block_bmap (bread (sb->s_dev, uspi->s_sbbase + tmp, sb->s_blocksize), - fragment & uspi->s_apbmask, uspi, swab)); + frag -= UFS_NDIR_FRAGMENT; + if (frag < (1 << (uspi->s_apbshift + uspi->s_fpbshift))) { + i = ufs_inode_bmap(inode, + UFS_IND_FRAGMENT + (frag >> uspi->s_apbshift)); + if (!i) + goto out; + ret = (uspi->s_sbbase + + ufs_block_bmap(bread(sb->s_dev, uspi->s_sbbase + i, + sb->s_blocksize), + frag & uspi->s_apbmask, uspi, swab)); + } + frag -= 1 << (uspi->s_apbshift + uspi->s_fpbshift); + if (frag < (1 << (uspi->s_2apbshift + uspi->s_fpbshift))) { + i = ufs_inode_bmap (inode, + UFS_DIND_FRAGMENT + (frag >> uspi->s_2apbshift)); + if (!i) + goto out; + i = ufs_block_bmap(bread(sb->s_dev, uspi->s_sbbase + i, + sb->s_blocksize), + (frag >> uspi->s_apbshift) & uspi->s_apbmask, + uspi, swab); + if (!i) + goto out; + ret = (uspi->s_sbbase + + ufs_block_bmap(bread(sb->s_dev, uspi->s_sbbase + i, + sb->s_blocksize), + (frag & uspi->s_apbmask), uspi, swab)); + goto out; + } + frag -= 1 << (uspi->s_2apbshift + uspi->s_fpbshift); + i = ufs_inode_bmap(inode, + UFS_TIND_FRAGMENT + (frag >> uspi->s_3apbshift)); + if (!i) + goto out; + i = ufs_block_bmap(bread(sb->s_dev, uspi->s_sbbase + i, sb->s_blocksize), + (frag >> uspi->s_2apbshift) & uspi->s_apbmask, + uspi, swab); + if (!i) + goto out; + i = ufs_block_bmap(bread(sb->s_dev, uspi->s_sbbase + i, sb->s_blocksize), + (frag >> uspi->s_apbshift) & uspi->s_apbmask, + uspi, swab); + if (!i) + goto out; + ret = (uspi->s_sbbase + + ufs_block_bmap(bread(sb->s_dev, uspi->s_sbbase + i, sb->s_blocksize), + (frag & uspi->s_apbmask), uspi, swab)); +out: + unlock_kernel(); + return ret; } -static struct buffer_head * ufs_inode_getfrag (struct inode * inode, - unsigned fragment, unsigned new_fragment, int create, - unsigned required, int *err, int metadata, int *phys_block, int *created) +static struct buffer_head * ufs_inode_getfrag (struct inode *inode, + unsigned int fragment, unsigned int new_fragment, + unsigned int required, int *err, int metadata, long *phys, int *new) { struct super_block * sb; struct ufs_sb_private_info * uspi; @@ -184,7 +189,7 @@ static struct buffer_head * ufs_inode_getfrag (struct inode * inode, unsigned block, blockoff, lastfrag, lastblock, lastblockoff; unsigned tmp, goal; u32 * p, * p2; - unsigned swab; + unsigned int swab; UFSD(("ENTER, ino %lu, fragment %u, new_fragment %u, required %u\n", inode->i_ino, fragment, new_fragment, required)) @@ -206,18 +211,17 @@ repeat: sb->s_blocksize); if (tmp == SWAB32(*p)) { UFSD(("EXIT, result %u\n", tmp + blockoff)) - return result; + return result; } brelse (result); goto repeat; } else { - *phys_block = tmp; + *phys = tmp; return NULL; } } *err = -EFBIG; - if (!create) - return NULL; + limit = current->rlim[RLIMIT_FSIZE].rlim_cur; if (limit < RLIM_INFINITY) { limit >>= sb->s_blocksize_bits; @@ -226,6 +230,7 @@ repeat: return NULL; } } + lastblock = ufs_fragstoblks (lastfrag); lastblockoff = ufs_fragnum (lastfrag); /* @@ -270,10 +275,10 @@ repeat: } if (!tmp) { if ((!blockoff && SWAB32(*p)) || - (blockoff && lastfrag != inode->u.ufs_i.i_lastfrag)) + (blockoff && lastfrag != inode->u.ufs_i.i_lastfrag)) goto repeat; - else - return NULL; + *err = -ENOSPC; + return NULL; } /* The nullification of framgents done in ufs/balloc.c is @@ -283,10 +288,10 @@ repeat: if (metadata) { result = getblk (inode->i_dev, tmp + blockoff, sb->s_blocksize); } else { - *phys_block = tmp; + *phys = tmp; result = NULL; *err = 0; - *created = 1; + *new = 1; } inode->i_ctime = CURRENT_TIME; @@ -297,16 +302,16 @@ repeat: return result; } -static struct buffer_head * ufs_block_getfrag (struct inode * inode, - struct buffer_head * bh, unsigned fragment, unsigned new_fragment, - int create, unsigned blocksize, int * err, int metadata, int *phys_block, int *created) +static struct buffer_head * ufs_block_getfrag (struct inode *inode, + struct buffer_head *bh, unsigned int fragment, unsigned int new_fragment, + unsigned int blocksize, int * err, int metadata, long *phys, int *new) { struct super_block * sb; struct ufs_sb_private_info * uspi; struct buffer_head * result; unsigned tmp, goal, block, blockoff; u32 * p; - unsigned swab; + unsigned int swab; sb = inode->i_sb; swab = sb->u.ufs_sb.s_swab; @@ -316,15 +321,14 @@ static struct buffer_head * ufs_block_getfrag (struct inode * inode, UFSD(("ENTER, ino %lu, fragment %u, new_fragment %u\n", inode->i_ino, fragment, new_fragment)) + 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 = (u32 *) bh->b_data + block; @@ -334,24 +338,18 @@ repeat: if (metadata) { result = getblk (bh->b_dev, uspi->s_sbbase + tmp + blockoff, sb->s_blocksize); - if (tmp == SWAB32(*p)) { - brelse (bh); - UFSD(("EXIT, result %u\n", tmp + blockoff)) - return result; - } + if (tmp == SWAB32(*p)) + goto out; brelse (result); goto repeat; } else { - *phys_block = tmp; - brelse (bh); - return NULL; + *phys = tmp; + goto out; } } *err = -EFBIG; - if (!create) { - brelse (bh); - return NULL; - } else { + + { unsigned long limit = current->rlim[RLIMIT_FSIZE].rlim_cur; if (limit < RLIM_INFINITY) { limit >>= sb->s_blocksize_bits; @@ -368,12 +366,9 @@ repeat: goal = bh->b_blocknr + uspi->s_fpb; tmp = ufs_new_fragments (inode, p, ufs_blknum(new_fragment), goal, uspi->s_fpb, err); if (!tmp) { - if (SWAB32(*p)) { + if (SWAB32(*p)) goto repeat; - } else { - brelse (bh); - return NULL; - } + goto out; } /* The nullification of framgents done in ufs/balloc.c is @@ -383,10 +378,8 @@ repeat: if (metadata) { result = getblk (bh->b_dev, tmp + blockoff, sb->s_blocksize); } else { - *phys_block = tmp; - result = NULL; - *err = 0; - *created = 1; + *phys = tmp; + *new = 1; } mark_buffer_dirty(bh, 1); @@ -396,122 +389,137 @@ repeat: } inode->i_ctime = CURRENT_TIME; mark_inode_dirty(inode); +out: brelse (bh); UFSD(("EXIT, result %u\n", tmp + blockoff)) return result; } -int ufs_getfrag_block (struct inode * inode, long fragment, - int create, int * err, int *created) +int ufs_getfrag_block (struct inode *inode, long fragment, struct buffer_head *bh_result, int create) { struct super_block * sb; struct ufs_sb_private_info * uspi; - struct buffer_head * bh, * tmp; - unsigned f; - unsigned swab; - int phys_block; + struct buffer_head * bh; + unsigned int swab; + int ret, err, new; + unsigned long ptr, phys; sb = inode->i_sb; uspi = sb->u.ufs_sb.s_uspi; swab = sb->u.ufs_sb.s_swab; - *err = -EIO; - UFSD(("ENTER, ino %lu, fragment %u\n", inode->i_ino, fragment)) - if (fragment < 0) { - ufs_warning (sb, "ufs_getblk", "block < 0"); - return 0; - } - if (fragment > ((UFS_NDADDR + uspi->s_apb + uspi->s_2apb + uspi->s_3apb) << uspi->s_fpbshift)) { - ufs_warning (sb, "ufs_getblk", "block > big"); + if (!create) { + phys = ufs_frag_map(inode, fragment); + if (phys) { + bh_result->b_dev = inode->i_dev; + bh_result->b_blocknr = phys; + bh_result->b_state |= (1UL << BH_Mapped); + } return 0; } - *err = -ENOSPC; - f = fragment; - *created = 0; + err = -EIO; + new = 0; + ret = 0; + bh = NULL; + + lock_kernel(); + + UFSD(("ENTER, ino %lu, fragment %u\n", inode->i_ino, fragment)) + if (fragment < 0) + goto abort_negative; + if (fragment > + ((UFS_NDADDR + uspi->s_apb + uspi->s_2apb + uspi->s_3apb) + << uspi->s_fpbshift)) + goto abort_too_big; + + err = 0; + ptr = fragment; /* - * Direct fragment - */ - if (fragment < UFS_NDIR_FRAGMENT) { - tmp = ufs_inode_getfrag (inode, fragment, fragment, create, 1, - err, 0, &phys_block, created); - goto out; - } - /* - * Indirect fragment - */ - fragment -= UFS_NDIR_FRAGMENT; - if (fragment < (1 << (uspi->s_apbshift + uspi->s_fpbshift))) { - bh = ufs_inode_getfrag (inode, - UFS_IND_FRAGMENT + (fragment >> uspi->s_apbshift), - f, create, uspi->s_fpb, err, 1, NULL, NULL); - tmp = ufs_block_getfrag (inode, bh, - fragment & uspi->s_apbmask, - f, create, sb->s_blocksize, - err, 0, &phys_block, created); - goto out; - } - /* - * Dindirect fragment + * ok, these macros clean the logic up a bit and make + * it much more readable: */ - fragment -= 1 << (uspi->s_apbshift + uspi->s_fpbshift); - if ( fragment < (1 << (uspi->s_2apbshift + uspi->s_fpbshift))) { - bh = ufs_inode_getfrag (inode, - UFS_DIND_FRAGMENT + (fragment >> uspi->s_2apbshift), - f, create, uspi->s_fpb, err, - 1, NULL, NULL); - bh = ufs_block_getfrag (inode, bh, - (fragment >> uspi->s_apbshift) & uspi->s_apbmask, - f, create, sb->s_blocksize, err, - 1, NULL, NULL); - tmp = ufs_block_getfrag (inode, bh, - fragment & uspi->s_apbmask, - f, create, sb->s_blocksize, err, - 0, &phys_block, created); +#define GET_INODE_DATABLOCK(x) \ + ufs_inode_getfrag(inode, x, fragment, 1, &err, 0, &phys, &new) +#define GET_INODE_PTR(x) \ + ufs_inode_getfrag(inode, x, fragment, uspi->s_fpb, &err, 1, NULL, NULL) +#define GET_INDIRECT_DATABLOCK(x) \ + ufs_block_getfrag(inode, bh, x, fragment, sb->s_blocksize, \ + &err, 0, &phys, &new); +#define GET_INDIRECT_PTR(x) \ + ufs_block_getfrag(inode, bh, x, fragment, sb->s_blocksize, \ + &err, 1, NULL, NULL); + + if (ptr < UFS_NDIR_FRAGMENT) { + bh = GET_INODE_DATABLOCK(ptr); goto out; } - /* - * Tindirect fragment - */ - fragment -= 1 << (uspi->s_2apbshift + uspi->s_fpbshift); - bh = ufs_inode_getfrag (inode, - UFS_TIND_FRAGMENT + (fragment >> uspi->s_3apbshift), - f, create, uspi->s_fpb, err, 1, NULL, NULL); - bh = ufs_block_getfrag (inode, bh, - (fragment >> uspi->s_2apbshift) & uspi->s_apbmask, - f, create, sb->s_blocksize, err, 1, NULL, NULL); - bh = ufs_block_getfrag (inode, bh, - (fragment >> uspi->s_apbshift) & uspi->s_apbmask, - f, create, sb->s_blocksize, err, 1, NULL, NULL); - tmp = ufs_block_getfrag (inode, bh, - fragment & uspi->s_apbmask, - f, create, sb->s_blocksize, err, 0, &phys_block, created); + ptr -= UFS_NDIR_FRAGMENT; + if (ptr < (1 << (uspi->s_apbshift + uspi->s_fpbshift))) { + bh = GET_INODE_PTR(UFS_IND_FRAGMENT + (ptr >> uspi->s_apbshift)); + goto get_indirect; + } + ptr -= 1 << (uspi->s_apbshift + uspi->s_fpbshift); + if (ptr < (1 << (uspi->s_2apbshift + uspi->s_fpbshift))) { + bh = GET_INODE_PTR(UFS_DIND_FRAGMENT + (ptr >> uspi->s_2apbshift)); + goto get_double; + } + ptr -= 1 << (uspi->s_2apbshift + uspi->s_fpbshift); + bh = GET_INODE_PTR(UFS_TIND_FRAGMENT + (ptr >> uspi->s_3apbshift)); + bh = GET_INDIRECT_PTR((ptr >> uspi->s_2apbshift) & uspi->s_apbmask); +get_double: + bh = GET_INDIRECT_PTR((ptr >> uspi->s_apbshift) & uspi->s_apbmask); +get_indirect: + bh = GET_INDIRECT_DATABLOCK(ptr & uspi->s_apbmask); + +#undef GET_INODE_DATABLOCK +#undef GET_INODE_PTR +#undef GET_INDIRECT_DATABLOCK +#undef GET_INDIRECT_PTR out: - if (!phys_block) - return 0; - if (*err) - return 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: + ufs_warning(sb, "ufs_get_block", "block < 0"); + goto abort; + +abort_too_big: + ufs_warning(sb, "ufs_get_block", "block > big"); + goto abort; } struct buffer_head *ufs_getfrag(struct inode *inode, unsigned int fragment, int create, int *err) { - struct buffer_head *tmp = NULL; - int phys_block, created; - - phys_block = ufs_getfrag_block(inode, fragment, create, err, &created); - if (phys_block) { - tmp = getblk(inode->i_dev, phys_block, inode->i_sb->s_blocksize); - if (created) { - memset(tmp->b_data, 0, inode->i_sb->s_blocksize); - 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 = ufs_getfrag_block(inode, fragment, &dummy, create); + *err = error; + if (!error && buffer_mapped(&dummy)) { + struct buffer_head *bh; + bh = getblk(dummy.b_dev, dummy.b_blocknr, inode->i_sb->s_blocksize); + if (buffer_new(&dummy)) { + memset(bh->b_data, 0, inode->i_sb->s_blocksize); + mark_buffer_uptodate(bh, 1); + mark_buffer_dirty(bh, 1); } + return bh; } - return tmp; + return NULL; } struct buffer_head * ufs_bread (struct inode * inode, unsigned fragment, diff --git a/fs/ufs/super.c b/fs/ufs/super.c index db3f11f23..12937adcf 100644 --- a/fs/ufs/super.c +++ b/fs/ufs/super.c @@ -271,6 +271,8 @@ static int ufs_parse_options (char * options, unsigned * mount_options) ufs_set_opt (*mount_options, UFSTYPE_44BSD); else if (!strcmp (value, "nextstep")) ufs_set_opt (*mount_options, UFSTYPE_NEXTSTEP); + else if (!strcmp (value, "nextstep-cd")) + ufs_set_opt (*mount_options, UFSTYPE_NEXTSTEP_CD); else if (!strcmp (value, "openstep")) ufs_set_opt (*mount_options, UFSTYPE_OPENSTEP); else if (!strcmp (value, "sunx86")) @@ -465,7 +467,7 @@ struct super_block * ufs_read_super (struct super_block * sb, void * data, } if (!(sb->u.ufs_sb.s_mount_opt & UFS_MOUNT_UFSTYPE)) { printk("You didn't specify the type of your ufs filesystem\n\n" - " mount -t ufs -o ufstype=sun|sunx86|44bsd|old|nextstep|openstep ....\n\n" + " mount -t ufs -o ufstype=sun|sunx86|44bsd|old|nextstep|netxstep-cd|openstep ...\n\n" ">>>WARNING<<< Wrong ufstype may corrupt your filesystem, " "default is ufstype=old\n"); ufs_set_opt (sb->u.ufs_sb.s_mount_opt, UFSTYPE_OLD); @@ -535,6 +537,20 @@ struct super_block * ufs_read_super (struct super_block * sb, void * data, } break; + case UFS_MOUNT_UFSTYPE_NEXTSTEP_CD: + UFSD(("ufstype=nextstep-cd\n")) + uspi->s_fsize = block_size = 2048; + uspi->s_fmask = ~(2048 - 1); + uspi->s_fshift = 11; + uspi->s_sbsize = super_block_size = 2048; + uspi->s_sbbase = 0; + flags |= UFS_DE_OLD | UFS_UID_OLD | UFS_ST_OLD | UFS_CG_OLD; + if (!(sb->s_flags & MS_RDONLY)) { + printk(KERN_INFO "ufstype=nextstep-cd is supported read-only\n"); + sb->s_flags |= MS_RDONLY; + } + break; + case UFS_MOUNT_UFSTYPE_OPENSTEP: UFSD(("ufstype=openstep\n")) uspi->s_fsize = block_size = 1024; @@ -592,6 +608,7 @@ again: #endif if ((((sb->u.ufs_sb.s_mount_opt & UFS_MOUNT_UFSTYPE) == UFS_MOUNT_UFSTYPE_NEXTSTEP) + || ((sb->u.ufs_sb.s_mount_opt & UFS_MOUNT_UFSTYPE) == UFS_MOUNT_UFSTYPE_NEXTSTEP_CD) || ((sb->u.ufs_sb.s_mount_opt & UFS_MOUNT_UFSTYPE) == UFS_MOUNT_UFSTYPE_OPENSTEP)) && uspi->s_sbbase < 256) { ubh_brelse_uspi(uspi); @@ -616,8 +633,8 @@ magic_found: printk("ufs_read_super: fs_bsize %u != {4096, 8192}\n", uspi->s_bsize); goto failed; } - if (uspi->s_fsize != 512 && uspi->s_fsize != 1024) { - printk("ufs_read_super: fs_fsize %u != {512, 1024}\n", uspi->s_fsize); + if (uspi->s_fsize != 512 && uspi->s_fsize != 1024 && uspi->s_fsize != 2048) { + printk("ufs_read_super: fs_fsize %u != {512, 1024, 2048}\n", uspi->s_fsize); goto failed; } if (uspi->s_fsize != block_size || uspi->s_sbsize != super_block_size) { diff --git a/fs/ufs/symlink.c b/fs/ufs/symlink.c index 39b54e05d..3df5c40a6 100644 --- a/fs/ufs/symlink.c +++ b/fs/ufs/symlink.c @@ -129,10 +129,12 @@ struct inode_operations ufs_symlink_inode_operations = { NULL, /* rename */ ufs_readlink, /* readlink */ ufs_follow_link, /* follow_link */ + NULL, /* get_block */ NULL, /* readpage */ NULL, /* writepage */ - NULL, /* bmap */ + NULL, /* flushpage */ NULL, /* truncate */ NULL, /* permission */ - NULL /* smap */ + NULL, /* smap */ + NULL /* revalidate */ }; diff --git a/fs/ufs/truncate.c b/fs/ufs/truncate.c index 4649a4253..b7214fc49 100644 --- a/fs/ufs/truncate.c +++ b/fs/ufs/truncate.c @@ -63,7 +63,7 @@ #define DIRECT_FRAGMENT howmany (inode->i_size, uspi->s_fsize) #define DATA_BUFFER_USED(bh) \ - ((bh->b_count > 1) || buffer_locked(bh)) + (atomic_read(&bh->b_count) || buffer_locked(bh)) static int ufs_trunc_direct (struct inode * inode) { diff --git a/fs/ufs/util.c b/fs/ufs/util.c index 11978a752..e6d5f3a5b 100644 --- a/fs/ufs/util.c +++ b/fs/ufs/util.c @@ -137,8 +137,8 @@ unsigned ubh_max_bcount (struct ufs_buffer_head * ubh) if (!ubh) return 0; for ( i = 0; i < ubh->count; i++ ) - if ( ubh->bh[i]->b_count > max ) - max = ubh->bh[i]->b_count; + if ( atomic_read(&ubh->bh[i]->b_count) > max ) + max = atomic_read(&ubh->bh[i]->b_count); return max; } -- cgit v1.2.3