diff options
Diffstat (limited to 'fs')
-rw-r--r-- | fs/9p/conv.c | 28 | ||||
-rw-r--r-- | fs/9p/mux.c | 15 | ||||
-rw-r--r-- | fs/9p/vfs_inode.c | 6 | ||||
-rw-r--r-- | fs/buffer.c | 4 | ||||
-rw-r--r-- | fs/dcache.c | 2 | ||||
-rw-r--r-- | fs/direct-io.c | 9 | ||||
-rw-r--r-- | fs/ext2/acl.c | 2 | ||||
-rw-r--r-- | fs/ext2/ialloc.c | 2 | ||||
-rw-r--r-- | fs/ext2/super.c | 5 | ||||
-rw-r--r-- | fs/ext3/acl.c | 2 | ||||
-rw-r--r-- | fs/fat/file.c | 50 | ||||
-rw-r--r-- | fs/fat/misc.c | 14 | ||||
-rw-r--r-- | fs/fcntl.c | 7 | ||||
-rw-r--r-- | fs/jffs/intrep.c | 2 | ||||
-rw-r--r-- | fs/libfs.c | 1 | ||||
-rw-r--r-- | fs/proc/proc_misc.c | 2 | ||||
-rw-r--r-- | fs/quota_v2.c | 2 | ||||
-rw-r--r-- | fs/reiserfs/super.c | 2 | ||||
-rw-r--r-- | fs/udf/balloc.c | 7 | ||||
-rw-r--r-- | fs/udf/namei.c | 4 | ||||
-rw-r--r-- | fs/ufs/inode.c | 2 | ||||
-rw-r--r-- | fs/ufs/super.c | 10 | ||||
-rw-r--r-- | fs/ufs/truncate.c | 72 |
23 files changed, 116 insertions, 134 deletions
diff --git a/fs/9p/conv.c b/fs/9p/conv.c index 32a9f99154e..bf1f1006796 100644 --- a/fs/9p/conv.c +++ b/fs/9p/conv.c @@ -116,13 +116,19 @@ static void buf_put_int64(struct cbuf *buf, u64 val) } } -static void buf_put_stringn(struct cbuf *buf, const char *s, u16 slen) +static char *buf_put_stringn(struct cbuf *buf, const char *s, u16 slen) { + char *ret; + + ret = NULL; if (buf_check_size(buf, slen + 2)) { buf_put_int16(buf, slen); + ret = buf->p; memcpy(buf->p, s, slen); buf->p += slen; } + + return ret; } static inline void buf_put_string(struct cbuf *buf, const char *s) @@ -430,15 +436,19 @@ static inline void v9fs_put_int64(struct cbuf *bufp, u64 val, u64 * p) static void v9fs_put_str(struct cbuf *bufp, char *data, struct v9fs_str *str) { - if (data) { - str->len = strlen(data); - str->str = bufp->p; - } else { - str->len = 0; - str->str = NULL; - } + int len; + char *s; + + if (data) + len = strlen(data); + else + len = 0; - buf_put_stringn(bufp, data, str->len); + s = buf_put_stringn(bufp, data, len); + if (str) { + str->len = len; + str->str = s; + } } static int diff --git a/fs/9p/mux.c b/fs/9p/mux.c index 945cb368d45..ea1134eb47c 100644 --- a/fs/9p/mux.c +++ b/fs/9p/mux.c @@ -471,10 +471,13 @@ static void v9fs_write_work(void *a) } spin_lock(&m->lock); - req = - list_entry(m->unsent_req_list.next, struct v9fs_req, +again: + req = list_entry(m->unsent_req_list.next, struct v9fs_req, req_list); list_move_tail(&req->req_list, &m->req_list); + if (req->err == ERREQFLUSH) + goto again; + m->wbuf = req->tcall->sdata; m->wsize = req->tcall->size; m->wpos = 0; @@ -525,7 +528,7 @@ static void process_request(struct v9fs_mux_data *m, struct v9fs_req *req) struct v9fs_str *ename; tag = req->tag; - if (req->rcall->id == RERROR && !req->err) { + if (!req->err && req->rcall->id == RERROR) { ecode = req->rcall->params.rerror.errno; ename = &req->rcall->params.rerror.error; @@ -551,7 +554,10 @@ static void process_request(struct v9fs_mux_data *m, struct v9fs_req *req) req->err = -EIO; } - if (req->cb && req->err != ERREQFLUSH) { + if (req->err == ERREQFLUSH) + return; + + if (req->cb) { dprintk(DEBUG_MUX, "calling callback tcall %p rcall %p\n", req->tcall, req->rcall); @@ -812,6 +818,7 @@ v9fs_mux_rpc_cb(void *a, struct v9fs_fcall *tc, struct v9fs_fcall *rc, int err) struct v9fs_mux_rpc *r; if (err == ERREQFLUSH) { + kfree(rc); dprintk(DEBUG_MUX, "err req flush\n"); return; } diff --git a/fs/9p/vfs_inode.c b/fs/9p/vfs_inode.c index 91f552454c7..63e5b0398e8 100644 --- a/fs/9p/vfs_inode.c +++ b/fs/9p/vfs_inode.c @@ -886,8 +886,8 @@ static int v9fs_readlink(struct dentry *dentry, char *buffer, int buflen) } /* copy extension buffer into buffer */ - if (fcall->params.rstat.stat.extension.len < buflen) - buflen = fcall->params.rstat.stat.extension.len; + if (fcall->params.rstat.stat.extension.len+1 < buflen) + buflen = fcall->params.rstat.stat.extension.len + 1; memcpy(buffer, fcall->params.rstat.stat.extension.str, buflen - 1); buffer[buflen-1] = 0; @@ -951,7 +951,7 @@ static void *v9fs_vfs_follow_link(struct dentry *dentry, struct nameidata *nd) if (!link) link = ERR_PTR(-ENOMEM); else { - len = v9fs_readlink(dentry, link, strlen(link)); + len = v9fs_readlink(dentry, link, PATH_MAX); if (len < 0) { __putname(link); diff --git a/fs/buffer.c b/fs/buffer.c index 5e4a90ee103..62cfd17dc5f 100644 --- a/fs/buffer.c +++ b/fs/buffer.c @@ -2867,22 +2867,22 @@ void ll_rw_block(int rw, int nr, struct buffer_head *bhs[]) else if (test_set_buffer_locked(bh)) continue; - get_bh(bh); if (rw == WRITE || rw == SWRITE) { if (test_clear_buffer_dirty(bh)) { bh->b_end_io = end_buffer_write_sync; + get_bh(bh); submit_bh(WRITE, bh); continue; } } else { if (!buffer_uptodate(bh)) { bh->b_end_io = end_buffer_read_sync; + get_bh(bh); submit_bh(rw, bh); continue; } } unlock_buffer(bh); - put_bh(bh); } } diff --git a/fs/dcache.c b/fs/dcache.c index 86bdb93789c..a173bba3266 100644 --- a/fs/dcache.c +++ b/fs/dcache.c @@ -743,7 +743,9 @@ struct dentry *d_alloc(struct dentry * parent, const struct qstr *name) dentry->d_op = NULL; dentry->d_fsdata = NULL; dentry->d_mounted = 0; +#ifdef CONFIG_PROFILING dentry->d_cookie = NULL; +#endif INIT_HLIST_NODE(&dentry->d_hash); INIT_LIST_HEAD(&dentry->d_lru); INIT_LIST_HEAD(&dentry->d_subdirs); diff --git a/fs/direct-io.c b/fs/direct-io.c index 30dbbd1df51..848044af7e1 100644 --- a/fs/direct-io.c +++ b/fs/direct-io.c @@ -857,6 +857,7 @@ do_holes: /* Handle holes */ if (!buffer_mapped(map_bh)) { char *kaddr; + loff_t i_size_aligned; /* AKPM: eargh, -ENOTBLK is a hack */ if (dio->rw == WRITE) { @@ -864,8 +865,14 @@ do_holes: return -ENOTBLK; } + /* + * Be sure to account for a partial block as the + * last block in the file + */ + i_size_aligned = ALIGN(i_size_read(dio->inode), + 1 << blkbits); if (dio->block_in_file >= - i_size_read(dio->inode)>>blkbits) { + i_size_aligned >> blkbits) { /* We hit eof */ page_cache_release(page); goto out; diff --git a/fs/ext2/acl.c b/fs/ext2/acl.c index 35acc43b897..da52b4a5db6 100644 --- a/fs/ext2/acl.c +++ b/fs/ext2/acl.c @@ -220,7 +220,7 @@ ext2_set_acl(struct inode *inode, int type, struct posix_acl *acl) struct ext2_inode_info *ei = EXT2_I(inode); int name_index; void *value = NULL; - size_t size; + size_t size = 0; int error; if (S_ISLNK(inode->i_mode)) diff --git a/fs/ext2/ialloc.c b/fs/ext2/ialloc.c index 74714af4ae6..e52765219e1 100644 --- a/fs/ext2/ialloc.c +++ b/fs/ext2/ialloc.c @@ -605,7 +605,7 @@ got: insert_inode_hash(inode); if (DQUOT_ALLOC_INODE(inode)) { - err = -ENOSPC; + err = -EDQUOT; goto fail_drop; } diff --git a/fs/ext2/super.c b/fs/ext2/super.c index 8d6819846fc..cb6f9bd658d 100644 --- a/fs/ext2/super.c +++ b/fs/ext2/super.c @@ -221,6 +221,11 @@ static int ext2_show_options(struct seq_file *seq, struct vfsmount *vfs) seq_puts(seq, ",grpquota"); #endif +#if defined(CONFIG_EXT2_FS_XIP) + if (sbi->s_mount_opt & EXT2_MOUNT_XIP) + seq_puts(seq, ",xip"); +#endif + return 0; } diff --git a/fs/ext3/acl.c b/fs/ext3/acl.c index 47a9da2dfb4..0d21d558b87 100644 --- a/fs/ext3/acl.c +++ b/fs/ext3/acl.c @@ -226,7 +226,7 @@ ext3_set_acl(handle_t *handle, struct inode *inode, int type, struct ext3_inode_info *ei = EXT3_I(inode); int name_index; void *value = NULL; - size_t size; + size_t size = 0; int error; if (S_ISLNK(inode->i_mode)) diff --git a/fs/fat/file.c b/fs/fat/file.c index e99c5a73b39..88aa1ae13f9 100644 --- a/fs/fat/file.c +++ b/fs/fat/file.c @@ -210,10 +210,30 @@ static int fat_free(struct inode *inode, int skip) if (MSDOS_I(inode)->i_start == 0) return 0; - /* - * Write a new EOF, and get the remaining cluster chain for freeing. - */ + fat_cache_inval_inode(inode); + wait = IS_DIRSYNC(inode); + i_start = free_start = MSDOS_I(inode)->i_start; + i_logstart = MSDOS_I(inode)->i_logstart; + + /* First, we write the new file size. */ + if (!skip) { + MSDOS_I(inode)->i_start = 0; + MSDOS_I(inode)->i_logstart = 0; + } + MSDOS_I(inode)->i_attrs |= ATTR_ARCH; + inode->i_ctime = inode->i_mtime = CURRENT_TIME_SEC; + if (wait) { + err = fat_sync_inode(inode); + if (err) { + MSDOS_I(inode)->i_start = i_start; + MSDOS_I(inode)->i_logstart = i_logstart; + return err; + } + } else + mark_inode_dirty(inode); + + /* Write a new EOF, and get the remaining cluster chain for freeing. */ if (skip) { struct fat_entry fatent; int ret, fclus, dclus; @@ -244,35 +264,11 @@ static int fat_free(struct inode *inode, int skip) return ret; free_start = ret; - i_start = i_logstart = 0; - fat_cache_inval_inode(inode); - } else { - fat_cache_inval_inode(inode); - - i_start = free_start = MSDOS_I(inode)->i_start; - i_logstart = MSDOS_I(inode)->i_logstart; - MSDOS_I(inode)->i_start = 0; - MSDOS_I(inode)->i_logstart = 0; } - MSDOS_I(inode)->i_attrs |= ATTR_ARCH; - inode->i_ctime = inode->i_mtime = CURRENT_TIME_SEC; - if (wait) { - err = fat_sync_inode(inode); - if (err) - goto error; - } else - mark_inode_dirty(inode); inode->i_blocks = skip << (MSDOS_SB(sb)->cluster_bits - 9); /* Freeing the remained cluster chain */ return fat_free_clusters(inode, free_start); - -error: - if (i_start) { - MSDOS_I(inode)->i_start = i_start; - MSDOS_I(inode)->i_logstart = i_logstart; - } - return err; } void fat_truncate(struct inode *inode) diff --git a/fs/fat/misc.c b/fs/fat/misc.c index 32fb0a3f1da..944652e9dde 100644 --- a/fs/fat/misc.c +++ b/fs/fat/misc.c @@ -196,19 +196,9 @@ EXPORT_SYMBOL_GPL(fat_date_unix2dos); int fat_sync_bhs(struct buffer_head **bhs, int nr_bhs) { - int i, e, err = 0; + int i, err = 0; - for (i = 0; i < nr_bhs; i++) { - lock_buffer(bhs[i]); - if (test_clear_buffer_dirty(bhs[i])) { - get_bh(bhs[i]); - bhs[i]->b_end_io = end_buffer_write_sync; - e = submit_bh(WRITE, bhs[i]); - if (!err && e) - err = e; - } else - unlock_buffer(bhs[i]); - } + ll_rw_block(SWRITE, nr_bhs, bhs); for (i = 0; i < nr_bhs; i++) { wait_on_buffer(bhs[i]); if (buffer_eopnotsupp(bhs[i])) { diff --git a/fs/fcntl.c b/fs/fcntl.c index 5f96786d1c7..dc4a7007f4e 100644 --- a/fs/fcntl.c +++ b/fs/fcntl.c @@ -208,8 +208,11 @@ static int setfl(int fd, struct file * filp, unsigned long arg) struct inode * inode = filp->f_dentry->d_inode; int error = 0; - /* O_APPEND cannot be cleared if the file is marked as append-only */ - if (!(arg & O_APPEND) && IS_APPEND(inode)) + /* + * O_APPEND cannot be cleared if the file is marked as append-only + * and the file is open for write. + */ + if (((arg ^ filp->f_flags) & O_APPEND) && IS_APPEND(inode)) return -EPERM; /* O_NOATIME can only be set by the owner or superuser */ diff --git a/fs/jffs/intrep.c b/fs/jffs/intrep.c index b2e95421d93..ce7b54b0b2b 100644 --- a/fs/jffs/intrep.c +++ b/fs/jffs/intrep.c @@ -1965,7 +1965,7 @@ retry: iovec_cnt++; if (JFFS_GET_PAD_BYTES(raw_inode->nsize)) { - static char allff[3]={255,255,255}; + static unsigned char allff[3]={255,255,255}; /* Add some extra padding if necessary */ node_iovec[iovec_cnt].iov_base = allff; node_iovec[iovec_cnt].iov_len = diff --git a/fs/libfs.c b/fs/libfs.c index 63c020e6589..71fd08fa410 100644 --- a/fs/libfs.c +++ b/fs/libfs.c @@ -388,6 +388,7 @@ int simple_fill_super(struct super_block *s, int magic, struct tree_descr *files inode->i_atime = inode->i_mtime = inode->i_ctime = CURRENT_TIME; inode->i_op = &simple_dir_inode_operations; inode->i_fop = &simple_dir_operations; + inode->i_nlink = 2; root = d_alloc_root(inode); if (!root) { iput(inode); diff --git a/fs/proc/proc_misc.c b/fs/proc/proc_misc.c index 8f8014285a3..1d24fead51a 100644 --- a/fs/proc/proc_misc.c +++ b/fs/proc/proc_misc.c @@ -548,7 +548,7 @@ static int show_stat(struct seq_file *p, void *v) } seq_printf(p, "intr %llu", (unsigned long long)sum); -#if !defined(CONFIG_PPC64) && !defined(CONFIG_ALPHA) +#if !defined(CONFIG_PPC64) && !defined(CONFIG_ALPHA) && !defined(CONFIG_IA64) for (i = 0; i < NR_IRQS; i++) seq_printf(p, " %u", kstat_irqs(i)); #endif diff --git a/fs/quota_v2.c b/fs/quota_v2.c index a4ef91bb4f3..b4199ec3ece 100644 --- a/fs/quota_v2.c +++ b/fs/quota_v2.c @@ -35,7 +35,7 @@ static int v2_check_quota_file(struct super_block *sb, int type) size = sb->s_op->quota_read(sb, type, (char *)&dqhead, sizeof(struct v2_disk_dqheader), 0); if (size != sizeof(struct v2_disk_dqheader)) { - printk("quota_v2: failed read expected=%d got=%d\n", + printk("quota_v2: failed read expected=%zd got=%zd\n", sizeof(struct v2_disk_dqheader), size); return 0; } diff --git a/fs/reiserfs/super.c b/fs/reiserfs/super.c index 77891de0e02..ef5e5414e7a 100644 --- a/fs/reiserfs/super.c +++ b/fs/reiserfs/super.c @@ -1125,7 +1125,7 @@ static void handle_attrs(struct super_block *s) REISERFS_SB(s)->s_mount_opt &= ~(1 << REISERFS_ATTRS); } } else if (le32_to_cpu(rs->s_flags) & reiserfs_attrs_cleared) { - REISERFS_SB(s)->s_mount_opt |= REISERFS_ATTRS; + REISERFS_SB(s)->s_mount_opt |= (1 << REISERFS_ATTRS); } } diff --git a/fs/udf/balloc.c b/fs/udf/balloc.c index 4fae57d9d11..201049ac8a9 100644 --- a/fs/udf/balloc.c +++ b/fs/udf/balloc.c @@ -579,10 +579,9 @@ static void udf_table_free_blocks(struct super_block * sb, { loffset = nextoffset; aed->lengthAllocDescs = cpu_to_le32(adsize); - if (obh) - sptr = UDF_I_DATA(inode) + nextoffset - udf_file_entry_alloc_offset(inode) + UDF_I_LENEATTR(inode) - adsize; - else - sptr = obh->b_data + nextoffset - adsize; + sptr = UDF_I_DATA(inode) + nextoffset - + udf_file_entry_alloc_offset(inode) + + UDF_I_LENEATTR(inode) - adsize; dptr = nbh->b_data + sizeof(struct allocExtDesc); memcpy(dptr, sptr, adsize); nextoffset = sizeof(struct allocExtDesc) + adsize; diff --git a/fs/udf/namei.c b/fs/udf/namei.c index ca732e79c48..ab9a7629d23 100644 --- a/fs/udf/namei.c +++ b/fs/udf/namei.c @@ -296,7 +296,7 @@ static struct dentry * udf_lookup(struct inode *dir, struct dentry *dentry, struct nameidata *nd) { struct inode *inode = NULL; - struct fileIdentDesc cfi, *fi; + struct fileIdentDesc cfi; struct udf_fileident_bh fibh; if (dentry->d_name.len > UDF_NAME_LEN-2) @@ -318,7 +318,7 @@ udf_lookup(struct inode *dir, struct dentry *dentry, struct nameidata *nd) else #endif /* UDF_RECOVERY */ - if ((fi = udf_find_entry(dir, dentry, &fibh, &cfi))) + if (udf_find_entry(dir, dentry, &fibh, &cfi)) { if (fibh.sbh != fibh.ebh) udf_release_data(fibh.ebh); diff --git a/fs/ufs/inode.c b/fs/ufs/inode.c index e0c04e36a05..3c3f62ce2ad 100644 --- a/fs/ufs/inode.c +++ b/fs/ufs/inode.c @@ -376,7 +376,7 @@ out: * This function gets the block which contains the fragment. */ -static int ufs_getfrag_block (struct inode *inode, sector_t fragment, struct buffer_head *bh_result, int create) +int ufs_getfrag_block (struct inode *inode, sector_t fragment, struct buffer_head *bh_result, int create) { struct super_block * sb = inode->i_sb; struct ufs_sb_private_info * uspi = UFS_SB(sb)->s_uspi; diff --git a/fs/ufs/super.c b/fs/ufs/super.c index d4aacee593f..e9055ef7f5a 100644 --- a/fs/ufs/super.c +++ b/fs/ufs/super.c @@ -388,7 +388,8 @@ static int ufs_parse_options (char * options, unsigned * mount_options) /* * Read on-disk structures associated with cylinder groups */ -static int ufs_read_cylinder_structures (struct super_block *sb) { +static int ufs_read_cylinder_structures (struct super_block *sb) +{ struct ufs_sb_info * sbi = UFS_SB(sb); struct ufs_sb_private_info * uspi; struct ufs_super_block *usb; @@ -415,6 +416,7 @@ static int ufs_read_cylinder_structures (struct super_block *sb) { base = space = kmalloc(size, GFP_KERNEL); if (!base) goto failed; + sbi->s_csp = (struct ufs_csum *)space; for (i = 0; i < blks; i += uspi->s_fpb) { size = uspi->s_bsize; if (i + uspi->s_fpb > blks) @@ -430,7 +432,6 @@ static int ufs_read_cylinder_structures (struct super_block *sb) { goto failed; ubh_ubhcpymem (space, ubh, size); - sbi->s_csp[ufs_fragstoblks(i)]=(struct ufs_csum *)space; space += size; ubh_brelse (ubh); @@ -486,7 +487,8 @@ failed: * Put on-disk structures associated with cylinder groups and * write them back to disk */ -static void ufs_put_cylinder_structures (struct super_block *sb) { +static void ufs_put_cylinder_structures (struct super_block *sb) +{ struct ufs_sb_info * sbi = UFS_SB(sb); struct ufs_sb_private_info * uspi; struct ufs_buffer_head * ubh; @@ -499,7 +501,7 @@ static void ufs_put_cylinder_structures (struct super_block *sb) { size = uspi->s_cssize; blks = (size + uspi->s_fsize - 1) >> uspi->s_fshift; - base = space = (char*) sbi->s_csp[0]; + base = space = (char*) sbi->s_csp; for (i = 0; i < blks; i += uspi->s_fpb) { size = uspi->s_bsize; if (i + uspi->s_fpb > blks) diff --git a/fs/ufs/truncate.c b/fs/ufs/truncate.c index 61d2e35012a..02e86291ef8 100644 --- a/fs/ufs/truncate.c +++ b/fs/ufs/truncate.c @@ -29,6 +29,11 @@ * Idea from Pierre del Perugia <delperug@gla.ecoledoc.ibp.fr> */ +/* + * Modified to avoid infinite loop on 2006 by + * Evgeniy Dushistov <dushistov@mail.ru> + */ + #include <linux/errno.h> #include <linux/fs.h> #include <linux/ufs_fs.h> @@ -65,19 +70,16 @@ #define DIRECT_BLOCK ((inode->i_size + uspi->s_bsize - 1) >> uspi->s_bshift) #define DIRECT_FRAGMENT ((inode->i_size + uspi->s_fsize - 1) >> uspi->s_fshift) -#define DATA_BUFFER_USED(bh) \ - (atomic_read(&bh->b_count)>1 || buffer_locked(bh)) static int ufs_trunc_direct (struct inode * inode) { struct ufs_inode_info *ufsi = UFS_I(inode); struct super_block * sb; struct ufs_sb_private_info * uspi; - struct buffer_head * bh; __fs32 * p; unsigned frag1, frag2, frag3, frag4, block1, block2; unsigned frag_to_free, free_count; - unsigned i, j, tmp; + unsigned i, tmp; int retry; UFSD(("ENTER\n")) @@ -117,15 +119,7 @@ static int ufs_trunc_direct (struct inode * inode) ufs_panic (sb, "ufs_trunc_direct", "internal error"); frag1 = ufs_fragnum (frag1); frag2 = ufs_fragnum (frag2); - for (j = frag1; j < frag2; j++) { - bh = sb_find_get_block (sb, tmp + j); - if ((bh && DATA_BUFFER_USED(bh)) || tmp != fs32_to_cpu(sb, *p)) { - retry = 1; - brelse (bh); - goto next1; - } - bforget (bh); - } + inode->i_blocks -= (frag2-frag1) << uspi->s_nspfshift; mark_inode_dirty(inode); ufs_free_fragments (inode, tmp + frag1, frag2 - frag1); @@ -140,15 +134,7 @@ next1: tmp = fs32_to_cpu(sb, *p); if (!tmp) continue; - for (j = 0; j < uspi->s_fpb; j++) { - bh = sb_find_get_block(sb, tmp + j); - if ((bh && DATA_BUFFER_USED(bh)) || tmp != fs32_to_cpu(sb, *p)) { - retry = 1; - brelse (bh); - goto next2; - } - bforget (bh); - } + *p = 0; inode->i_blocks -= uspi->s_nspb; mark_inode_dirty(inode); @@ -162,7 +148,6 @@ next1: frag_to_free = tmp; free_count = uspi->s_fpb; } -next2:; } if (free_count > 0) @@ -179,15 +164,7 @@ next2:; if (!tmp ) ufs_panic(sb, "ufs_truncate_direct", "internal error"); frag4 = ufs_fragnum (frag4); - for (j = 0; j < frag4; j++) { - bh = sb_find_get_block (sb, tmp + j); - if ((bh && DATA_BUFFER_USED(bh)) || tmp != fs32_to_cpu(sb, *p)) { - retry = 1; - brelse (bh); - goto next1; - } - bforget (bh); - } + *p = 0; inode->i_blocks -= frag4 << uspi->s_nspfshift; mark_inode_dirty(inode); @@ -204,9 +181,8 @@ static int ufs_trunc_indirect (struct inode * inode, unsigned offset, __fs32 *p) struct super_block * sb; struct ufs_sb_private_info * uspi; struct ufs_buffer_head * ind_ubh; - struct buffer_head * bh; __fs32 * ind; - unsigned indirect_block, i, j, tmp; + unsigned indirect_block, i, tmp; unsigned frag_to_free, free_count; int retry; @@ -238,15 +214,7 @@ static int ufs_trunc_indirect (struct inode * inode, unsigned offset, __fs32 *p) tmp = fs32_to_cpu(sb, *ind); if (!tmp) continue; - for (j = 0; j < uspi->s_fpb; j++) { - bh = sb_find_get_block(sb, tmp + j); - if ((bh && DATA_BUFFER_USED(bh)) || tmp != fs32_to_cpu(sb, *ind)) { - retry = 1; - brelse (bh); - goto next; - } - bforget (bh); - } + *ind = 0; ubh_mark_buffer_dirty(ind_ubh); if (free_count == 0) { @@ -261,7 +229,6 @@ static int ufs_trunc_indirect (struct inode * inode, unsigned offset, __fs32 *p) } inode->i_blocks -= uspi->s_nspb; mark_inode_dirty(inode); -next:; } if (free_count > 0) { @@ -430,9 +397,7 @@ void ufs_truncate (struct inode * inode) struct ufs_inode_info *ufsi = UFS_I(inode); struct super_block * sb; struct ufs_sb_private_info * uspi; - struct buffer_head * bh; - unsigned offset; - int err, retry; + int retry; UFSD(("ENTER\n")) sb = inode->i_sb; @@ -442,6 +407,9 @@ void ufs_truncate (struct inode * inode) return; if (IS_APPEND(inode) || IS_IMMUTABLE(inode)) return; + + block_truncate_page(inode->i_mapping, inode->i_size, ufs_getfrag_block); + lock_kernel(); while (1) { retry = ufs_trunc_direct(inode); @@ -457,15 +425,7 @@ void ufs_truncate (struct inode * inode) blk_run_address_space(inode->i_mapping); yield(); } - offset = inode->i_size & uspi->s_fshift; - if (offset) { - bh = ufs_bread (inode, inode->i_size >> uspi->s_fshift, 0, &err); - if (bh) { - memset (bh->b_data + offset, 0, uspi->s_fsize - offset); - mark_buffer_dirty (bh); - brelse (bh); - } - } + inode->i_mtime = inode->i_ctime = CURRENT_TIME_SEC; ufsi->i_lastfrag = DIRECT_FRAGMENT; unlock_kernel(); |