xref: /linux/fs/jfs/inode.c (revision 1da177e4c3f41524e886b7f1b8a0c1fc7321cac2)
1*1da177e4SLinus Torvalds /*
2*1da177e4SLinus Torvalds  *   Copyright (C) International Business Machines Corp., 2000-2004
3*1da177e4SLinus Torvalds  *   Portions Copyright (C) Christoph Hellwig, 2001-2002
4*1da177e4SLinus Torvalds  *
5*1da177e4SLinus Torvalds  *   This program is free software;  you can redistribute it and/or modify
6*1da177e4SLinus Torvalds  *   it under the terms of the GNU General Public License as published by
7*1da177e4SLinus Torvalds  *   the Free Software Foundation; either version 2 of the License, or
8*1da177e4SLinus Torvalds  *   (at your option) any later version.
9*1da177e4SLinus Torvalds  *
10*1da177e4SLinus Torvalds  *   This program is distributed in the hope that it will be useful,
11*1da177e4SLinus Torvalds  *   but WITHOUT ANY WARRANTY;  without even the implied warranty of
12*1da177e4SLinus Torvalds  *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See
13*1da177e4SLinus Torvalds  *   the GNU General Public License for more details.
14*1da177e4SLinus Torvalds  *
15*1da177e4SLinus Torvalds  *   You should have received a copy of the GNU General Public License
16*1da177e4SLinus Torvalds  *   along with this program;  if not, write to the Free Software
17*1da177e4SLinus Torvalds  *   Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
18*1da177e4SLinus Torvalds  */
19*1da177e4SLinus Torvalds 
20*1da177e4SLinus Torvalds #include <linux/fs.h>
21*1da177e4SLinus Torvalds #include <linux/mpage.h>
22*1da177e4SLinus Torvalds #include <linux/buffer_head.h>
23*1da177e4SLinus Torvalds #include <linux/pagemap.h>
24*1da177e4SLinus Torvalds #include <linux/quotaops.h>
25*1da177e4SLinus Torvalds #include "jfs_incore.h"
26*1da177e4SLinus Torvalds #include "jfs_filsys.h"
27*1da177e4SLinus Torvalds #include "jfs_imap.h"
28*1da177e4SLinus Torvalds #include "jfs_extent.h"
29*1da177e4SLinus Torvalds #include "jfs_unicode.h"
30*1da177e4SLinus Torvalds #include "jfs_debug.h"
31*1da177e4SLinus Torvalds 
32*1da177e4SLinus Torvalds 
33*1da177e4SLinus Torvalds extern struct inode_operations jfs_dir_inode_operations;
34*1da177e4SLinus Torvalds extern struct inode_operations jfs_file_inode_operations;
35*1da177e4SLinus Torvalds extern struct inode_operations jfs_symlink_inode_operations;
36*1da177e4SLinus Torvalds extern struct file_operations jfs_dir_operations;
37*1da177e4SLinus Torvalds extern struct file_operations jfs_file_operations;
38*1da177e4SLinus Torvalds struct address_space_operations jfs_aops;
39*1da177e4SLinus Torvalds extern int freeZeroLink(struct inode *);
40*1da177e4SLinus Torvalds 
41*1da177e4SLinus Torvalds void jfs_read_inode(struct inode *inode)
42*1da177e4SLinus Torvalds {
43*1da177e4SLinus Torvalds 	if (diRead(inode)) {
44*1da177e4SLinus Torvalds 		make_bad_inode(inode);
45*1da177e4SLinus Torvalds 		return;
46*1da177e4SLinus Torvalds 	}
47*1da177e4SLinus Torvalds 
48*1da177e4SLinus Torvalds 	if (S_ISREG(inode->i_mode)) {
49*1da177e4SLinus Torvalds 		inode->i_op = &jfs_file_inode_operations;
50*1da177e4SLinus Torvalds 		inode->i_fop = &jfs_file_operations;
51*1da177e4SLinus Torvalds 		inode->i_mapping->a_ops = &jfs_aops;
52*1da177e4SLinus Torvalds 	} else if (S_ISDIR(inode->i_mode)) {
53*1da177e4SLinus Torvalds 		inode->i_op = &jfs_dir_inode_operations;
54*1da177e4SLinus Torvalds 		inode->i_fop = &jfs_dir_operations;
55*1da177e4SLinus Torvalds 	} else if (S_ISLNK(inode->i_mode)) {
56*1da177e4SLinus Torvalds 		if (inode->i_size >= IDATASIZE) {
57*1da177e4SLinus Torvalds 			inode->i_op = &page_symlink_inode_operations;
58*1da177e4SLinus Torvalds 			inode->i_mapping->a_ops = &jfs_aops;
59*1da177e4SLinus Torvalds 		} else
60*1da177e4SLinus Torvalds 			inode->i_op = &jfs_symlink_inode_operations;
61*1da177e4SLinus Torvalds 	} else {
62*1da177e4SLinus Torvalds 		inode->i_op = &jfs_file_inode_operations;
63*1da177e4SLinus Torvalds 		init_special_inode(inode, inode->i_mode, inode->i_rdev);
64*1da177e4SLinus Torvalds 	}
65*1da177e4SLinus Torvalds }
66*1da177e4SLinus Torvalds 
67*1da177e4SLinus Torvalds /*
68*1da177e4SLinus Torvalds  * Workhorse of both fsync & write_inode
69*1da177e4SLinus Torvalds  */
70*1da177e4SLinus Torvalds int jfs_commit_inode(struct inode *inode, int wait)
71*1da177e4SLinus Torvalds {
72*1da177e4SLinus Torvalds 	int rc = 0;
73*1da177e4SLinus Torvalds 	tid_t tid;
74*1da177e4SLinus Torvalds 	static int noisy = 5;
75*1da177e4SLinus Torvalds 
76*1da177e4SLinus Torvalds 	jfs_info("In jfs_commit_inode, inode = 0x%p", inode);
77*1da177e4SLinus Torvalds 
78*1da177e4SLinus Torvalds 	/*
79*1da177e4SLinus Torvalds 	 * Don't commit if inode has been committed since last being
80*1da177e4SLinus Torvalds 	 * marked dirty, or if it has been deleted.
81*1da177e4SLinus Torvalds 	 */
82*1da177e4SLinus Torvalds 	if (inode->i_nlink == 0 || !test_cflag(COMMIT_Dirty, inode))
83*1da177e4SLinus Torvalds 		return 0;
84*1da177e4SLinus Torvalds 
85*1da177e4SLinus Torvalds 	if (isReadOnly(inode)) {
86*1da177e4SLinus Torvalds 		/* kernel allows writes to devices on read-only
87*1da177e4SLinus Torvalds 		 * partitions and may think inode is dirty
88*1da177e4SLinus Torvalds 		 */
89*1da177e4SLinus Torvalds 		if (!special_file(inode->i_mode) && noisy) {
90*1da177e4SLinus Torvalds 			jfs_err("jfs_commit_inode(0x%p) called on "
91*1da177e4SLinus Torvalds 				   "read-only volume", inode);
92*1da177e4SLinus Torvalds 			jfs_err("Is remount racy?");
93*1da177e4SLinus Torvalds 			noisy--;
94*1da177e4SLinus Torvalds 		}
95*1da177e4SLinus Torvalds 		return 0;
96*1da177e4SLinus Torvalds 	}
97*1da177e4SLinus Torvalds 
98*1da177e4SLinus Torvalds 	tid = txBegin(inode->i_sb, COMMIT_INODE);
99*1da177e4SLinus Torvalds 	down(&JFS_IP(inode)->commit_sem);
100*1da177e4SLinus Torvalds 
101*1da177e4SLinus Torvalds 	/*
102*1da177e4SLinus Torvalds 	 * Retest inode state after taking commit_sem
103*1da177e4SLinus Torvalds 	 */
104*1da177e4SLinus Torvalds 	if (inode->i_nlink && test_cflag(COMMIT_Dirty, inode))
105*1da177e4SLinus Torvalds 		rc = txCommit(tid, 1, &inode, wait ? COMMIT_SYNC : 0);
106*1da177e4SLinus Torvalds 
107*1da177e4SLinus Torvalds 	txEnd(tid);
108*1da177e4SLinus Torvalds 	up(&JFS_IP(inode)->commit_sem);
109*1da177e4SLinus Torvalds 	return rc;
110*1da177e4SLinus Torvalds }
111*1da177e4SLinus Torvalds 
112*1da177e4SLinus Torvalds int jfs_write_inode(struct inode *inode, int wait)
113*1da177e4SLinus Torvalds {
114*1da177e4SLinus Torvalds 	if (test_cflag(COMMIT_Nolink, inode))
115*1da177e4SLinus Torvalds 		return 0;
116*1da177e4SLinus Torvalds 	/*
117*1da177e4SLinus Torvalds 	 * If COMMIT_DIRTY is not set, the inode isn't really dirty.
118*1da177e4SLinus Torvalds 	 * It has been committed since the last change, but was still
119*1da177e4SLinus Torvalds 	 * on the dirty inode list.
120*1da177e4SLinus Torvalds 	 */
121*1da177e4SLinus Torvalds 	 if (!test_cflag(COMMIT_Dirty, inode)) {
122*1da177e4SLinus Torvalds 		/* Make sure committed changes hit the disk */
123*1da177e4SLinus Torvalds 		jfs_flush_journal(JFS_SBI(inode->i_sb)->log, wait);
124*1da177e4SLinus Torvalds 		return 0;
125*1da177e4SLinus Torvalds 	 }
126*1da177e4SLinus Torvalds 
127*1da177e4SLinus Torvalds 	if (jfs_commit_inode(inode, wait)) {
128*1da177e4SLinus Torvalds 		jfs_err("jfs_write_inode: jfs_commit_inode failed!");
129*1da177e4SLinus Torvalds 		return -EIO;
130*1da177e4SLinus Torvalds 	} else
131*1da177e4SLinus Torvalds 		return 0;
132*1da177e4SLinus Torvalds }
133*1da177e4SLinus Torvalds 
134*1da177e4SLinus Torvalds void jfs_delete_inode(struct inode *inode)
135*1da177e4SLinus Torvalds {
136*1da177e4SLinus Torvalds 	jfs_info("In jfs_delete_inode, inode = 0x%p", inode);
137*1da177e4SLinus Torvalds 
138*1da177e4SLinus Torvalds 	if (test_cflag(COMMIT_Freewmap, inode))
139*1da177e4SLinus Torvalds 		freeZeroLink(inode);
140*1da177e4SLinus Torvalds 
141*1da177e4SLinus Torvalds 	diFree(inode);
142*1da177e4SLinus Torvalds 
143*1da177e4SLinus Torvalds 	/*
144*1da177e4SLinus Torvalds 	 * Free the inode from the quota allocation.
145*1da177e4SLinus Torvalds 	 */
146*1da177e4SLinus Torvalds 	DQUOT_INIT(inode);
147*1da177e4SLinus Torvalds 	DQUOT_FREE_INODE(inode);
148*1da177e4SLinus Torvalds 	DQUOT_DROP(inode);
149*1da177e4SLinus Torvalds 
150*1da177e4SLinus Torvalds 	clear_inode(inode);
151*1da177e4SLinus Torvalds }
152*1da177e4SLinus Torvalds 
153*1da177e4SLinus Torvalds void jfs_dirty_inode(struct inode *inode)
154*1da177e4SLinus Torvalds {
155*1da177e4SLinus Torvalds 	static int noisy = 5;
156*1da177e4SLinus Torvalds 
157*1da177e4SLinus Torvalds 	if (isReadOnly(inode)) {
158*1da177e4SLinus Torvalds 		if (!special_file(inode->i_mode) && noisy) {
159*1da177e4SLinus Torvalds 			/* kernel allows writes to devices on read-only
160*1da177e4SLinus Torvalds 			 * partitions and may try to mark inode dirty
161*1da177e4SLinus Torvalds 			 */
162*1da177e4SLinus Torvalds 			jfs_err("jfs_dirty_inode called on read-only volume");
163*1da177e4SLinus Torvalds 			jfs_err("Is remount racy?");
164*1da177e4SLinus Torvalds 			noisy--;
165*1da177e4SLinus Torvalds 		}
166*1da177e4SLinus Torvalds 		return;
167*1da177e4SLinus Torvalds 	}
168*1da177e4SLinus Torvalds 
169*1da177e4SLinus Torvalds 	set_cflag(COMMIT_Dirty, inode);
170*1da177e4SLinus Torvalds }
171*1da177e4SLinus Torvalds 
172*1da177e4SLinus Torvalds static int
173*1da177e4SLinus Torvalds jfs_get_blocks(struct inode *ip, sector_t lblock, unsigned long max_blocks,
174*1da177e4SLinus Torvalds 			struct buffer_head *bh_result, int create)
175*1da177e4SLinus Torvalds {
176*1da177e4SLinus Torvalds 	s64 lblock64 = lblock;
177*1da177e4SLinus Torvalds 	int rc = 0;
178*1da177e4SLinus Torvalds 	int take_locks;
179*1da177e4SLinus Torvalds 	xad_t xad;
180*1da177e4SLinus Torvalds 	s64 xaddr;
181*1da177e4SLinus Torvalds 	int xflag;
182*1da177e4SLinus Torvalds 	s32 xlen;
183*1da177e4SLinus Torvalds 
184*1da177e4SLinus Torvalds 	/*
185*1da177e4SLinus Torvalds 	 * If this is a special inode (imap, dmap)
186*1da177e4SLinus Torvalds 	 * the lock should already be taken
187*1da177e4SLinus Torvalds 	 */
188*1da177e4SLinus Torvalds 	take_locks = (JFS_IP(ip)->fileset != AGGREGATE_I);
189*1da177e4SLinus Torvalds 
190*1da177e4SLinus Torvalds 	/*
191*1da177e4SLinus Torvalds 	 * Take appropriate lock on inode
192*1da177e4SLinus Torvalds 	 */
193*1da177e4SLinus Torvalds 	if (take_locks) {
194*1da177e4SLinus Torvalds 		if (create)
195*1da177e4SLinus Torvalds 			IWRITE_LOCK(ip);
196*1da177e4SLinus Torvalds 		else
197*1da177e4SLinus Torvalds 			IREAD_LOCK(ip);
198*1da177e4SLinus Torvalds 	}
199*1da177e4SLinus Torvalds 
200*1da177e4SLinus Torvalds 	if (((lblock64 << ip->i_sb->s_blocksize_bits) < ip->i_size) &&
201*1da177e4SLinus Torvalds 	    (xtLookup(ip, lblock64, max_blocks, &xflag, &xaddr, &xlen, 0)
202*1da177e4SLinus Torvalds 	     == 0) && xlen) {
203*1da177e4SLinus Torvalds 		if (xflag & XAD_NOTRECORDED) {
204*1da177e4SLinus Torvalds 			if (!create)
205*1da177e4SLinus Torvalds 				/*
206*1da177e4SLinus Torvalds 				 * Allocated but not recorded, read treats
207*1da177e4SLinus Torvalds 				 * this as a hole
208*1da177e4SLinus Torvalds 				 */
209*1da177e4SLinus Torvalds 				goto unlock;
210*1da177e4SLinus Torvalds #ifdef _JFS_4K
211*1da177e4SLinus Torvalds 			XADoffset(&xad, lblock64);
212*1da177e4SLinus Torvalds 			XADlength(&xad, xlen);
213*1da177e4SLinus Torvalds 			XADaddress(&xad, xaddr);
214*1da177e4SLinus Torvalds #else				/* _JFS_4K */
215*1da177e4SLinus Torvalds 			/*
216*1da177e4SLinus Torvalds 			 * As long as block size = 4K, this isn't a problem.
217*1da177e4SLinus Torvalds 			 * We should mark the whole page not ABNR, but how
218*1da177e4SLinus Torvalds 			 * will we know to mark the other blocks BH_New?
219*1da177e4SLinus Torvalds 			 */
220*1da177e4SLinus Torvalds 			BUG();
221*1da177e4SLinus Torvalds #endif				/* _JFS_4K */
222*1da177e4SLinus Torvalds 			rc = extRecord(ip, &xad);
223*1da177e4SLinus Torvalds 			if (rc)
224*1da177e4SLinus Torvalds 				goto unlock;
225*1da177e4SLinus Torvalds 			set_buffer_new(bh_result);
226*1da177e4SLinus Torvalds 		}
227*1da177e4SLinus Torvalds 
228*1da177e4SLinus Torvalds 		map_bh(bh_result, ip->i_sb, xaddr);
229*1da177e4SLinus Torvalds 		bh_result->b_size = xlen << ip->i_blkbits;
230*1da177e4SLinus Torvalds 		goto unlock;
231*1da177e4SLinus Torvalds 	}
232*1da177e4SLinus Torvalds 	if (!create)
233*1da177e4SLinus Torvalds 		goto unlock;
234*1da177e4SLinus Torvalds 
235*1da177e4SLinus Torvalds 	/*
236*1da177e4SLinus Torvalds 	 * Allocate a new block
237*1da177e4SLinus Torvalds 	 */
238*1da177e4SLinus Torvalds #ifdef _JFS_4K
239*1da177e4SLinus Torvalds 	if ((rc = extHint(ip, lblock64 << ip->i_sb->s_blocksize_bits, &xad)))
240*1da177e4SLinus Torvalds 		goto unlock;
241*1da177e4SLinus Torvalds 	rc = extAlloc(ip, max_blocks, lblock64, &xad, FALSE);
242*1da177e4SLinus Torvalds 	if (rc)
243*1da177e4SLinus Torvalds 		goto unlock;
244*1da177e4SLinus Torvalds 
245*1da177e4SLinus Torvalds 	set_buffer_new(bh_result);
246*1da177e4SLinus Torvalds 	map_bh(bh_result, ip->i_sb, addressXAD(&xad));
247*1da177e4SLinus Torvalds 	bh_result->b_size = lengthXAD(&xad) << ip->i_blkbits;
248*1da177e4SLinus Torvalds 
249*1da177e4SLinus Torvalds #else				/* _JFS_4K */
250*1da177e4SLinus Torvalds 	/*
251*1da177e4SLinus Torvalds 	 * We need to do whatever it takes to keep all but the last buffers
252*1da177e4SLinus Torvalds 	 * in 4K pages - see jfs_write.c
253*1da177e4SLinus Torvalds 	 */
254*1da177e4SLinus Torvalds 	BUG();
255*1da177e4SLinus Torvalds #endif				/* _JFS_4K */
256*1da177e4SLinus Torvalds 
257*1da177e4SLinus Torvalds       unlock:
258*1da177e4SLinus Torvalds 	/*
259*1da177e4SLinus Torvalds 	 * Release lock on inode
260*1da177e4SLinus Torvalds 	 */
261*1da177e4SLinus Torvalds 	if (take_locks) {
262*1da177e4SLinus Torvalds 		if (create)
263*1da177e4SLinus Torvalds 			IWRITE_UNLOCK(ip);
264*1da177e4SLinus Torvalds 		else
265*1da177e4SLinus Torvalds 			IREAD_UNLOCK(ip);
266*1da177e4SLinus Torvalds 	}
267*1da177e4SLinus Torvalds 	return rc;
268*1da177e4SLinus Torvalds }
269*1da177e4SLinus Torvalds 
270*1da177e4SLinus Torvalds static int jfs_get_block(struct inode *ip, sector_t lblock,
271*1da177e4SLinus Torvalds 			 struct buffer_head *bh_result, int create)
272*1da177e4SLinus Torvalds {
273*1da177e4SLinus Torvalds 	return jfs_get_blocks(ip, lblock, 1, bh_result, create);
274*1da177e4SLinus Torvalds }
275*1da177e4SLinus Torvalds 
276*1da177e4SLinus Torvalds static int jfs_writepage(struct page *page, struct writeback_control *wbc)
277*1da177e4SLinus Torvalds {
278*1da177e4SLinus Torvalds 	return nobh_writepage(page, jfs_get_block, wbc);
279*1da177e4SLinus Torvalds }
280*1da177e4SLinus Torvalds 
281*1da177e4SLinus Torvalds static int jfs_writepages(struct address_space *mapping,
282*1da177e4SLinus Torvalds 			struct writeback_control *wbc)
283*1da177e4SLinus Torvalds {
284*1da177e4SLinus Torvalds 	return mpage_writepages(mapping, wbc, jfs_get_block);
285*1da177e4SLinus Torvalds }
286*1da177e4SLinus Torvalds 
287*1da177e4SLinus Torvalds static int jfs_readpage(struct file *file, struct page *page)
288*1da177e4SLinus Torvalds {
289*1da177e4SLinus Torvalds 	return mpage_readpage(page, jfs_get_block);
290*1da177e4SLinus Torvalds }
291*1da177e4SLinus Torvalds 
292*1da177e4SLinus Torvalds static int jfs_readpages(struct file *file, struct address_space *mapping,
293*1da177e4SLinus Torvalds 		struct list_head *pages, unsigned nr_pages)
294*1da177e4SLinus Torvalds {
295*1da177e4SLinus Torvalds 	return mpage_readpages(mapping, pages, nr_pages, jfs_get_block);
296*1da177e4SLinus Torvalds }
297*1da177e4SLinus Torvalds 
298*1da177e4SLinus Torvalds static int jfs_prepare_write(struct file *file,
299*1da177e4SLinus Torvalds 			     struct page *page, unsigned from, unsigned to)
300*1da177e4SLinus Torvalds {
301*1da177e4SLinus Torvalds 	return nobh_prepare_write(page, from, to, jfs_get_block);
302*1da177e4SLinus Torvalds }
303*1da177e4SLinus Torvalds 
304*1da177e4SLinus Torvalds static sector_t jfs_bmap(struct address_space *mapping, sector_t block)
305*1da177e4SLinus Torvalds {
306*1da177e4SLinus Torvalds 	return generic_block_bmap(mapping, block, jfs_get_block);
307*1da177e4SLinus Torvalds }
308*1da177e4SLinus Torvalds 
309*1da177e4SLinus Torvalds static ssize_t jfs_direct_IO(int rw, struct kiocb *iocb,
310*1da177e4SLinus Torvalds 	const struct iovec *iov, loff_t offset, unsigned long nr_segs)
311*1da177e4SLinus Torvalds {
312*1da177e4SLinus Torvalds 	struct file *file = iocb->ki_filp;
313*1da177e4SLinus Torvalds 	struct inode *inode = file->f_mapping->host;
314*1da177e4SLinus Torvalds 
315*1da177e4SLinus Torvalds 	return blockdev_direct_IO(rw, iocb, inode, inode->i_sb->s_bdev, iov,
316*1da177e4SLinus Torvalds 				offset, nr_segs, jfs_get_blocks, NULL);
317*1da177e4SLinus Torvalds }
318*1da177e4SLinus Torvalds 
319*1da177e4SLinus Torvalds struct address_space_operations jfs_aops = {
320*1da177e4SLinus Torvalds 	.readpage	= jfs_readpage,
321*1da177e4SLinus Torvalds 	.readpages	= jfs_readpages,
322*1da177e4SLinus Torvalds 	.writepage	= jfs_writepage,
323*1da177e4SLinus Torvalds 	.writepages	= jfs_writepages,
324*1da177e4SLinus Torvalds 	.sync_page	= block_sync_page,
325*1da177e4SLinus Torvalds 	.prepare_write	= jfs_prepare_write,
326*1da177e4SLinus Torvalds 	.commit_write	= nobh_commit_write,
327*1da177e4SLinus Torvalds 	.bmap		= jfs_bmap,
328*1da177e4SLinus Torvalds 	.direct_IO	= jfs_direct_IO,
329*1da177e4SLinus Torvalds };
330*1da177e4SLinus Torvalds 
331*1da177e4SLinus Torvalds /*
332*1da177e4SLinus Torvalds  * Guts of jfs_truncate.  Called with locks already held.  Can be called
333*1da177e4SLinus Torvalds  * with directory for truncating directory index table.
334*1da177e4SLinus Torvalds  */
335*1da177e4SLinus Torvalds void jfs_truncate_nolock(struct inode *ip, loff_t length)
336*1da177e4SLinus Torvalds {
337*1da177e4SLinus Torvalds 	loff_t newsize;
338*1da177e4SLinus Torvalds 	tid_t tid;
339*1da177e4SLinus Torvalds 
340*1da177e4SLinus Torvalds 	ASSERT(length >= 0);
341*1da177e4SLinus Torvalds 
342*1da177e4SLinus Torvalds 	if (test_cflag(COMMIT_Nolink, ip)) {
343*1da177e4SLinus Torvalds 		xtTruncate(0, ip, length, COMMIT_WMAP);
344*1da177e4SLinus Torvalds 		return;
345*1da177e4SLinus Torvalds 	}
346*1da177e4SLinus Torvalds 
347*1da177e4SLinus Torvalds 	do {
348*1da177e4SLinus Torvalds 		tid = txBegin(ip->i_sb, 0);
349*1da177e4SLinus Torvalds 
350*1da177e4SLinus Torvalds 		/*
351*1da177e4SLinus Torvalds 		 * The commit_sem cannot be taken before txBegin.
352*1da177e4SLinus Torvalds 		 * txBegin may block and there is a chance the inode
353*1da177e4SLinus Torvalds 		 * could be marked dirty and need to be committed
354*1da177e4SLinus Torvalds 		 * before txBegin unblocks
355*1da177e4SLinus Torvalds 		 */
356*1da177e4SLinus Torvalds 		down(&JFS_IP(ip)->commit_sem);
357*1da177e4SLinus Torvalds 
358*1da177e4SLinus Torvalds 		newsize = xtTruncate(tid, ip, length,
359*1da177e4SLinus Torvalds 				     COMMIT_TRUNCATE | COMMIT_PWMAP);
360*1da177e4SLinus Torvalds 		if (newsize < 0) {
361*1da177e4SLinus Torvalds 			txEnd(tid);
362*1da177e4SLinus Torvalds 			up(&JFS_IP(ip)->commit_sem);
363*1da177e4SLinus Torvalds 			break;
364*1da177e4SLinus Torvalds 		}
365*1da177e4SLinus Torvalds 
366*1da177e4SLinus Torvalds 		ip->i_mtime = ip->i_ctime = CURRENT_TIME;
367*1da177e4SLinus Torvalds 		mark_inode_dirty(ip);
368*1da177e4SLinus Torvalds 
369*1da177e4SLinus Torvalds 		txCommit(tid, 1, &ip, 0);
370*1da177e4SLinus Torvalds 		txEnd(tid);
371*1da177e4SLinus Torvalds 		up(&JFS_IP(ip)->commit_sem);
372*1da177e4SLinus Torvalds 	} while (newsize > length);	/* Truncate isn't always atomic */
373*1da177e4SLinus Torvalds }
374*1da177e4SLinus Torvalds 
375*1da177e4SLinus Torvalds void jfs_truncate(struct inode *ip)
376*1da177e4SLinus Torvalds {
377*1da177e4SLinus Torvalds 	jfs_info("jfs_truncate: size = 0x%lx", (ulong) ip->i_size);
378*1da177e4SLinus Torvalds 
379*1da177e4SLinus Torvalds 	nobh_truncate_page(ip->i_mapping, ip->i_size);
380*1da177e4SLinus Torvalds 
381*1da177e4SLinus Torvalds 	IWRITE_LOCK(ip);
382*1da177e4SLinus Torvalds 	jfs_truncate_nolock(ip, ip->i_size);
383*1da177e4SLinus Torvalds 	IWRITE_UNLOCK(ip);
384*1da177e4SLinus Torvalds }
385