xref: /openbmc/linux/fs/udf/inode.c (revision 1da177e4c3f41524e886b7f1b8a0c1fc7321cac2)
1*1da177e4SLinus Torvalds /*
2*1da177e4SLinus Torvalds  * inode.c
3*1da177e4SLinus Torvalds  *
4*1da177e4SLinus Torvalds  * PURPOSE
5*1da177e4SLinus Torvalds  *  Inode handling routines for the OSTA-UDF(tm) filesystem.
6*1da177e4SLinus Torvalds  *
7*1da177e4SLinus Torvalds  * CONTACTS
8*1da177e4SLinus Torvalds  *  E-mail regarding any portion of the Linux UDF file system should be
9*1da177e4SLinus Torvalds  *  directed to the development team mailing list (run by majordomo):
10*1da177e4SLinus Torvalds  *    linux_udf@hpesjro.fc.hp.com
11*1da177e4SLinus Torvalds  *
12*1da177e4SLinus Torvalds  * COPYRIGHT
13*1da177e4SLinus Torvalds  *  This file is distributed under the terms of the GNU General Public
14*1da177e4SLinus Torvalds  *  License (GPL). Copies of the GPL can be obtained from:
15*1da177e4SLinus Torvalds  *    ftp://prep.ai.mit.edu/pub/gnu/GPL
16*1da177e4SLinus Torvalds  *  Each contributing author retains all rights to their own work.
17*1da177e4SLinus Torvalds  *
18*1da177e4SLinus Torvalds  *  (C) 1998 Dave Boynton
19*1da177e4SLinus Torvalds  *  (C) 1998-2004 Ben Fennema
20*1da177e4SLinus Torvalds  *  (C) 1999-2000 Stelias Computing Inc
21*1da177e4SLinus Torvalds  *
22*1da177e4SLinus Torvalds  * HISTORY
23*1da177e4SLinus Torvalds  *
24*1da177e4SLinus Torvalds  *  10/04/98 dgb  Added rudimentary directory functions
25*1da177e4SLinus Torvalds  *  10/07/98      Fully working udf_block_map! It works!
26*1da177e4SLinus Torvalds  *  11/25/98      bmap altered to better support extents
27*1da177e4SLinus Torvalds  *  12/06/98 blf  partition support in udf_iget, udf_block_map and udf_read_inode
28*1da177e4SLinus Torvalds  *  12/12/98      rewrote udf_block_map to handle next extents and descs across
29*1da177e4SLinus Torvalds  *                block boundaries (which is not actually allowed)
30*1da177e4SLinus Torvalds  *  12/20/98      added support for strategy 4096
31*1da177e4SLinus Torvalds  *  03/07/99      rewrote udf_block_map (again)
32*1da177e4SLinus Torvalds  *                New funcs, inode_bmap, udf_next_aext
33*1da177e4SLinus Torvalds  *  04/19/99      Support for writing device EA's for major/minor #
34*1da177e4SLinus Torvalds  */
35*1da177e4SLinus Torvalds 
36*1da177e4SLinus Torvalds #include "udfdecl.h"
37*1da177e4SLinus Torvalds #include <linux/mm.h>
38*1da177e4SLinus Torvalds #include <linux/smp_lock.h>
39*1da177e4SLinus Torvalds #include <linux/module.h>
40*1da177e4SLinus Torvalds #include <linux/pagemap.h>
41*1da177e4SLinus Torvalds #include <linux/buffer_head.h>
42*1da177e4SLinus Torvalds #include <linux/writeback.h>
43*1da177e4SLinus Torvalds #include <linux/slab.h>
44*1da177e4SLinus Torvalds 
45*1da177e4SLinus Torvalds #include "udf_i.h"
46*1da177e4SLinus Torvalds #include "udf_sb.h"
47*1da177e4SLinus Torvalds 
48*1da177e4SLinus Torvalds MODULE_AUTHOR("Ben Fennema");
49*1da177e4SLinus Torvalds MODULE_DESCRIPTION("Universal Disk Format Filesystem");
50*1da177e4SLinus Torvalds MODULE_LICENSE("GPL");
51*1da177e4SLinus Torvalds 
52*1da177e4SLinus Torvalds #define EXTENT_MERGE_SIZE 5
53*1da177e4SLinus Torvalds 
54*1da177e4SLinus Torvalds static mode_t udf_convert_permissions(struct fileEntry *);
55*1da177e4SLinus Torvalds static int udf_update_inode(struct inode *, int);
56*1da177e4SLinus Torvalds static void udf_fill_inode(struct inode *, struct buffer_head *);
57*1da177e4SLinus Torvalds static struct buffer_head *inode_getblk(struct inode *, long, int *,
58*1da177e4SLinus Torvalds 	long *, int *);
59*1da177e4SLinus Torvalds static int8_t udf_insert_aext(struct inode *, kernel_lb_addr, int,
60*1da177e4SLinus Torvalds 	kernel_lb_addr, uint32_t, struct buffer_head *);
61*1da177e4SLinus Torvalds static void udf_split_extents(struct inode *, int *, int, int,
62*1da177e4SLinus Torvalds 	kernel_long_ad [EXTENT_MERGE_SIZE], int *);
63*1da177e4SLinus Torvalds static void udf_prealloc_extents(struct inode *, int, int,
64*1da177e4SLinus Torvalds 	 kernel_long_ad [EXTENT_MERGE_SIZE], int *);
65*1da177e4SLinus Torvalds static void udf_merge_extents(struct inode *,
66*1da177e4SLinus Torvalds 	 kernel_long_ad [EXTENT_MERGE_SIZE], int *);
67*1da177e4SLinus Torvalds static void udf_update_extents(struct inode *,
68*1da177e4SLinus Torvalds 	kernel_long_ad [EXTENT_MERGE_SIZE], int, int,
69*1da177e4SLinus Torvalds 	kernel_lb_addr, uint32_t, struct buffer_head **);
70*1da177e4SLinus Torvalds static int udf_get_block(struct inode *, sector_t, struct buffer_head *, int);
71*1da177e4SLinus Torvalds 
72*1da177e4SLinus Torvalds /*
73*1da177e4SLinus Torvalds  * udf_delete_inode
74*1da177e4SLinus Torvalds  *
75*1da177e4SLinus Torvalds  * PURPOSE
76*1da177e4SLinus Torvalds  *	Clean-up before the specified inode is destroyed.
77*1da177e4SLinus Torvalds  *
78*1da177e4SLinus Torvalds  * DESCRIPTION
79*1da177e4SLinus Torvalds  *	This routine is called when the kernel destroys an inode structure
80*1da177e4SLinus Torvalds  *	ie. when iput() finds i_count == 0.
81*1da177e4SLinus Torvalds  *
82*1da177e4SLinus Torvalds  * HISTORY
83*1da177e4SLinus Torvalds  *	July 1, 1997 - Andrew E. Mileski
84*1da177e4SLinus Torvalds  *	Written, tested, and released.
85*1da177e4SLinus Torvalds  *
86*1da177e4SLinus Torvalds  *  Called at the last iput() if i_nlink is zero.
87*1da177e4SLinus Torvalds  */
88*1da177e4SLinus Torvalds void udf_delete_inode(struct inode * inode)
89*1da177e4SLinus Torvalds {
90*1da177e4SLinus Torvalds 	if (is_bad_inode(inode))
91*1da177e4SLinus Torvalds 		goto no_delete;
92*1da177e4SLinus Torvalds 
93*1da177e4SLinus Torvalds 	inode->i_size = 0;
94*1da177e4SLinus Torvalds 	udf_truncate(inode);
95*1da177e4SLinus Torvalds 	lock_kernel();
96*1da177e4SLinus Torvalds 
97*1da177e4SLinus Torvalds 	udf_update_inode(inode, IS_SYNC(inode));
98*1da177e4SLinus Torvalds 	udf_free_inode(inode);
99*1da177e4SLinus Torvalds 
100*1da177e4SLinus Torvalds 	unlock_kernel();
101*1da177e4SLinus Torvalds 	return;
102*1da177e4SLinus Torvalds no_delete:
103*1da177e4SLinus Torvalds 	clear_inode(inode);
104*1da177e4SLinus Torvalds }
105*1da177e4SLinus Torvalds 
106*1da177e4SLinus Torvalds void udf_clear_inode(struct inode *inode)
107*1da177e4SLinus Torvalds {
108*1da177e4SLinus Torvalds 	if (!(inode->i_sb->s_flags & MS_RDONLY)) {
109*1da177e4SLinus Torvalds 		lock_kernel();
110*1da177e4SLinus Torvalds 		udf_discard_prealloc(inode);
111*1da177e4SLinus Torvalds 		unlock_kernel();
112*1da177e4SLinus Torvalds 	}
113*1da177e4SLinus Torvalds 
114*1da177e4SLinus Torvalds 	kfree(UDF_I_DATA(inode));
115*1da177e4SLinus Torvalds 	UDF_I_DATA(inode) = NULL;
116*1da177e4SLinus Torvalds }
117*1da177e4SLinus Torvalds 
118*1da177e4SLinus Torvalds static int udf_writepage(struct page *page, struct writeback_control *wbc)
119*1da177e4SLinus Torvalds {
120*1da177e4SLinus Torvalds 	return block_write_full_page(page, udf_get_block, wbc);
121*1da177e4SLinus Torvalds }
122*1da177e4SLinus Torvalds 
123*1da177e4SLinus Torvalds static int udf_readpage(struct file *file, struct page *page)
124*1da177e4SLinus Torvalds {
125*1da177e4SLinus Torvalds 	return block_read_full_page(page, udf_get_block);
126*1da177e4SLinus Torvalds }
127*1da177e4SLinus Torvalds 
128*1da177e4SLinus Torvalds static int udf_prepare_write(struct file *file, struct page *page, unsigned from, unsigned to)
129*1da177e4SLinus Torvalds {
130*1da177e4SLinus Torvalds 	return block_prepare_write(page, from, to, udf_get_block);
131*1da177e4SLinus Torvalds }
132*1da177e4SLinus Torvalds 
133*1da177e4SLinus Torvalds static sector_t udf_bmap(struct address_space *mapping, sector_t block)
134*1da177e4SLinus Torvalds {
135*1da177e4SLinus Torvalds 	return generic_block_bmap(mapping,block,udf_get_block);
136*1da177e4SLinus Torvalds }
137*1da177e4SLinus Torvalds 
138*1da177e4SLinus Torvalds struct address_space_operations udf_aops = {
139*1da177e4SLinus Torvalds 	.readpage		= udf_readpage,
140*1da177e4SLinus Torvalds 	.writepage		= udf_writepage,
141*1da177e4SLinus Torvalds 	.sync_page		= block_sync_page,
142*1da177e4SLinus Torvalds 	.prepare_write		= udf_prepare_write,
143*1da177e4SLinus Torvalds 	.commit_write		= generic_commit_write,
144*1da177e4SLinus Torvalds 	.bmap			= udf_bmap,
145*1da177e4SLinus Torvalds };
146*1da177e4SLinus Torvalds 
147*1da177e4SLinus Torvalds void udf_expand_file_adinicb(struct inode * inode, int newsize, int * err)
148*1da177e4SLinus Torvalds {
149*1da177e4SLinus Torvalds 	struct page *page;
150*1da177e4SLinus Torvalds 	char *kaddr;
151*1da177e4SLinus Torvalds 	struct writeback_control udf_wbc = {
152*1da177e4SLinus Torvalds 		.sync_mode = WB_SYNC_NONE,
153*1da177e4SLinus Torvalds 		.nr_to_write = 1,
154*1da177e4SLinus Torvalds 	};
155*1da177e4SLinus Torvalds 
156*1da177e4SLinus Torvalds 	/* from now on we have normal address_space methods */
157*1da177e4SLinus Torvalds 	inode->i_data.a_ops = &udf_aops;
158*1da177e4SLinus Torvalds 
159*1da177e4SLinus Torvalds 	if (!UDF_I_LENALLOC(inode))
160*1da177e4SLinus Torvalds 	{
161*1da177e4SLinus Torvalds 		if (UDF_QUERY_FLAG(inode->i_sb, UDF_FLAG_USE_SHORT_AD))
162*1da177e4SLinus Torvalds 			UDF_I_ALLOCTYPE(inode) = ICBTAG_FLAG_AD_SHORT;
163*1da177e4SLinus Torvalds 		else
164*1da177e4SLinus Torvalds 			UDF_I_ALLOCTYPE(inode) = ICBTAG_FLAG_AD_LONG;
165*1da177e4SLinus Torvalds 		mark_inode_dirty(inode);
166*1da177e4SLinus Torvalds 		return;
167*1da177e4SLinus Torvalds 	}
168*1da177e4SLinus Torvalds 
169*1da177e4SLinus Torvalds 	page = grab_cache_page(inode->i_mapping, 0);
170*1da177e4SLinus Torvalds 	if (!PageLocked(page))
171*1da177e4SLinus Torvalds 		PAGE_BUG(page);
172*1da177e4SLinus Torvalds 	if (!PageUptodate(page))
173*1da177e4SLinus Torvalds 	{
174*1da177e4SLinus Torvalds 		kaddr = kmap(page);
175*1da177e4SLinus Torvalds 		memset(kaddr + UDF_I_LENALLOC(inode), 0x00,
176*1da177e4SLinus Torvalds 			PAGE_CACHE_SIZE - UDF_I_LENALLOC(inode));
177*1da177e4SLinus Torvalds 		memcpy(kaddr, UDF_I_DATA(inode) + UDF_I_LENEATTR(inode),
178*1da177e4SLinus Torvalds 			UDF_I_LENALLOC(inode));
179*1da177e4SLinus Torvalds 		flush_dcache_page(page);
180*1da177e4SLinus Torvalds 		SetPageUptodate(page);
181*1da177e4SLinus Torvalds 		kunmap(page);
182*1da177e4SLinus Torvalds 	}
183*1da177e4SLinus Torvalds 	memset(UDF_I_DATA(inode) + UDF_I_LENEATTR(inode), 0x00,
184*1da177e4SLinus Torvalds 		UDF_I_LENALLOC(inode));
185*1da177e4SLinus Torvalds 	UDF_I_LENALLOC(inode) = 0;
186*1da177e4SLinus Torvalds 	if (UDF_QUERY_FLAG(inode->i_sb, UDF_FLAG_USE_SHORT_AD))
187*1da177e4SLinus Torvalds 		UDF_I_ALLOCTYPE(inode) = ICBTAG_FLAG_AD_SHORT;
188*1da177e4SLinus Torvalds 	else
189*1da177e4SLinus Torvalds 		UDF_I_ALLOCTYPE(inode) = ICBTAG_FLAG_AD_LONG;
190*1da177e4SLinus Torvalds 
191*1da177e4SLinus Torvalds 	inode->i_data.a_ops->writepage(page, &udf_wbc);
192*1da177e4SLinus Torvalds 	page_cache_release(page);
193*1da177e4SLinus Torvalds 
194*1da177e4SLinus Torvalds 	mark_inode_dirty(inode);
195*1da177e4SLinus Torvalds }
196*1da177e4SLinus Torvalds 
197*1da177e4SLinus Torvalds struct buffer_head * udf_expand_dir_adinicb(struct inode *inode, int *block, int *err)
198*1da177e4SLinus Torvalds {
199*1da177e4SLinus Torvalds 	int newblock;
200*1da177e4SLinus Torvalds 	struct buffer_head *sbh = NULL, *dbh = NULL;
201*1da177e4SLinus Torvalds 	kernel_lb_addr bloc, eloc;
202*1da177e4SLinus Torvalds 	uint32_t elen, extoffset;
203*1da177e4SLinus Torvalds 	uint8_t alloctype;
204*1da177e4SLinus Torvalds 
205*1da177e4SLinus Torvalds 	struct udf_fileident_bh sfibh, dfibh;
206*1da177e4SLinus Torvalds 	loff_t f_pos = udf_ext0_offset(inode) >> 2;
207*1da177e4SLinus Torvalds 	int size = (udf_ext0_offset(inode) + inode->i_size) >> 2;
208*1da177e4SLinus Torvalds 	struct fileIdentDesc cfi, *sfi, *dfi;
209*1da177e4SLinus Torvalds 
210*1da177e4SLinus Torvalds 	if (UDF_QUERY_FLAG(inode->i_sb, UDF_FLAG_USE_SHORT_AD))
211*1da177e4SLinus Torvalds 		alloctype = ICBTAG_FLAG_AD_SHORT;
212*1da177e4SLinus Torvalds 	else
213*1da177e4SLinus Torvalds 		alloctype = ICBTAG_FLAG_AD_LONG;
214*1da177e4SLinus Torvalds 
215*1da177e4SLinus Torvalds 	if (!inode->i_size)
216*1da177e4SLinus Torvalds 	{
217*1da177e4SLinus Torvalds 		UDF_I_ALLOCTYPE(inode) = alloctype;
218*1da177e4SLinus Torvalds 		mark_inode_dirty(inode);
219*1da177e4SLinus Torvalds 		return NULL;
220*1da177e4SLinus Torvalds 	}
221*1da177e4SLinus Torvalds 
222*1da177e4SLinus Torvalds 	/* alloc block, and copy data to it */
223*1da177e4SLinus Torvalds 	*block = udf_new_block(inode->i_sb, inode,
224*1da177e4SLinus Torvalds 		UDF_I_LOCATION(inode).partitionReferenceNum,
225*1da177e4SLinus Torvalds 		UDF_I_LOCATION(inode).logicalBlockNum, err);
226*1da177e4SLinus Torvalds 
227*1da177e4SLinus Torvalds 	if (!(*block))
228*1da177e4SLinus Torvalds 		return NULL;
229*1da177e4SLinus Torvalds 	newblock = udf_get_pblock(inode->i_sb, *block,
230*1da177e4SLinus Torvalds 		UDF_I_LOCATION(inode).partitionReferenceNum, 0);
231*1da177e4SLinus Torvalds 	if (!newblock)
232*1da177e4SLinus Torvalds 		return NULL;
233*1da177e4SLinus Torvalds 	dbh = udf_tgetblk(inode->i_sb, newblock);
234*1da177e4SLinus Torvalds 	if (!dbh)
235*1da177e4SLinus Torvalds 		return NULL;
236*1da177e4SLinus Torvalds 	lock_buffer(dbh);
237*1da177e4SLinus Torvalds 	memset(dbh->b_data, 0x00, inode->i_sb->s_blocksize);
238*1da177e4SLinus Torvalds 	set_buffer_uptodate(dbh);
239*1da177e4SLinus Torvalds 	unlock_buffer(dbh);
240*1da177e4SLinus Torvalds 	mark_buffer_dirty_inode(dbh, inode);
241*1da177e4SLinus Torvalds 
242*1da177e4SLinus Torvalds 	sfibh.soffset = sfibh.eoffset = (f_pos & ((inode->i_sb->s_blocksize - 1) >> 2)) << 2;
243*1da177e4SLinus Torvalds 	sbh = sfibh.sbh = sfibh.ebh = NULL;
244*1da177e4SLinus Torvalds 	dfibh.soffset = dfibh.eoffset = 0;
245*1da177e4SLinus Torvalds 	dfibh.sbh = dfibh.ebh = dbh;
246*1da177e4SLinus Torvalds 	while ( (f_pos < size) )
247*1da177e4SLinus Torvalds 	{
248*1da177e4SLinus Torvalds 		UDF_I_ALLOCTYPE(inode) = ICBTAG_FLAG_AD_IN_ICB;
249*1da177e4SLinus Torvalds 		sfi = udf_fileident_read(inode, &f_pos, &sfibh, &cfi, NULL, NULL, NULL, NULL, NULL, NULL);
250*1da177e4SLinus Torvalds 		if (!sfi)
251*1da177e4SLinus Torvalds 		{
252*1da177e4SLinus Torvalds 			udf_release_data(dbh);
253*1da177e4SLinus Torvalds 			return NULL;
254*1da177e4SLinus Torvalds 		}
255*1da177e4SLinus Torvalds 		UDF_I_ALLOCTYPE(inode) = alloctype;
256*1da177e4SLinus Torvalds 		sfi->descTag.tagLocation = cpu_to_le32(*block);
257*1da177e4SLinus Torvalds 		dfibh.soffset = dfibh.eoffset;
258*1da177e4SLinus Torvalds 		dfibh.eoffset += (sfibh.eoffset - sfibh.soffset);
259*1da177e4SLinus Torvalds 		dfi = (struct fileIdentDesc *)(dbh->b_data + dfibh.soffset);
260*1da177e4SLinus Torvalds 		if (udf_write_fi(inode, sfi, dfi, &dfibh, sfi->impUse,
261*1da177e4SLinus Torvalds 			sfi->fileIdent + le16_to_cpu(sfi->lengthOfImpUse)))
262*1da177e4SLinus Torvalds 		{
263*1da177e4SLinus Torvalds 			UDF_I_ALLOCTYPE(inode) = ICBTAG_FLAG_AD_IN_ICB;
264*1da177e4SLinus Torvalds 			udf_release_data(dbh);
265*1da177e4SLinus Torvalds 			return NULL;
266*1da177e4SLinus Torvalds 		}
267*1da177e4SLinus Torvalds 	}
268*1da177e4SLinus Torvalds 	mark_buffer_dirty_inode(dbh, inode);
269*1da177e4SLinus Torvalds 
270*1da177e4SLinus Torvalds 	memset(UDF_I_DATA(inode) + UDF_I_LENEATTR(inode), 0, UDF_I_LENALLOC(inode));
271*1da177e4SLinus Torvalds 	UDF_I_LENALLOC(inode) = 0;
272*1da177e4SLinus Torvalds 	bloc = UDF_I_LOCATION(inode);
273*1da177e4SLinus Torvalds 	eloc.logicalBlockNum = *block;
274*1da177e4SLinus Torvalds 	eloc.partitionReferenceNum = UDF_I_LOCATION(inode).partitionReferenceNum;
275*1da177e4SLinus Torvalds 	elen = inode->i_size;
276*1da177e4SLinus Torvalds 	UDF_I_LENEXTENTS(inode) = elen;
277*1da177e4SLinus Torvalds 	extoffset = udf_file_entry_alloc_offset(inode);
278*1da177e4SLinus Torvalds 	udf_add_aext(inode, &bloc, &extoffset, eloc, elen, &sbh, 0);
279*1da177e4SLinus Torvalds 	/* UniqueID stuff */
280*1da177e4SLinus Torvalds 
281*1da177e4SLinus Torvalds 	udf_release_data(sbh);
282*1da177e4SLinus Torvalds 	mark_inode_dirty(inode);
283*1da177e4SLinus Torvalds 	return dbh;
284*1da177e4SLinus Torvalds }
285*1da177e4SLinus Torvalds 
286*1da177e4SLinus Torvalds static int udf_get_block(struct inode *inode, sector_t block, struct buffer_head *bh_result, int create)
287*1da177e4SLinus Torvalds {
288*1da177e4SLinus Torvalds 	int err, new;
289*1da177e4SLinus Torvalds 	struct buffer_head *bh;
290*1da177e4SLinus Torvalds 	unsigned long phys;
291*1da177e4SLinus Torvalds 
292*1da177e4SLinus Torvalds 	if (!create)
293*1da177e4SLinus Torvalds 	{
294*1da177e4SLinus Torvalds 		phys = udf_block_map(inode, block);
295*1da177e4SLinus Torvalds 		if (phys)
296*1da177e4SLinus Torvalds 			map_bh(bh_result, inode->i_sb, phys);
297*1da177e4SLinus Torvalds 		return 0;
298*1da177e4SLinus Torvalds 	}
299*1da177e4SLinus Torvalds 
300*1da177e4SLinus Torvalds 	err = -EIO;
301*1da177e4SLinus Torvalds 	new = 0;
302*1da177e4SLinus Torvalds 	bh = NULL;
303*1da177e4SLinus Torvalds 
304*1da177e4SLinus Torvalds 	lock_kernel();
305*1da177e4SLinus Torvalds 
306*1da177e4SLinus Torvalds 	if (block < 0)
307*1da177e4SLinus Torvalds 		goto abort_negative;
308*1da177e4SLinus Torvalds 
309*1da177e4SLinus Torvalds 	if (block == UDF_I_NEXT_ALLOC_BLOCK(inode) + 1)
310*1da177e4SLinus Torvalds 	{
311*1da177e4SLinus Torvalds 		UDF_I_NEXT_ALLOC_BLOCK(inode) ++;
312*1da177e4SLinus Torvalds 		UDF_I_NEXT_ALLOC_GOAL(inode) ++;
313*1da177e4SLinus Torvalds 	}
314*1da177e4SLinus Torvalds 
315*1da177e4SLinus Torvalds 	err = 0;
316*1da177e4SLinus Torvalds 
317*1da177e4SLinus Torvalds 	bh = inode_getblk(inode, block, &err, &phys, &new);
318*1da177e4SLinus Torvalds 	if (bh)
319*1da177e4SLinus Torvalds 		BUG();
320*1da177e4SLinus Torvalds 	if (err)
321*1da177e4SLinus Torvalds 		goto abort;
322*1da177e4SLinus Torvalds 	if (!phys)
323*1da177e4SLinus Torvalds 		BUG();
324*1da177e4SLinus Torvalds 
325*1da177e4SLinus Torvalds 	if (new)
326*1da177e4SLinus Torvalds 		set_buffer_new(bh_result);
327*1da177e4SLinus Torvalds 	map_bh(bh_result, inode->i_sb, phys);
328*1da177e4SLinus Torvalds abort:
329*1da177e4SLinus Torvalds 	unlock_kernel();
330*1da177e4SLinus Torvalds 	return err;
331*1da177e4SLinus Torvalds 
332*1da177e4SLinus Torvalds abort_negative:
333*1da177e4SLinus Torvalds 	udf_warning(inode->i_sb, "udf_get_block", "block < 0");
334*1da177e4SLinus Torvalds 	goto abort;
335*1da177e4SLinus Torvalds }
336*1da177e4SLinus Torvalds 
337*1da177e4SLinus Torvalds static struct buffer_head *
338*1da177e4SLinus Torvalds udf_getblk(struct inode *inode, long block, int create, int *err)
339*1da177e4SLinus Torvalds {
340*1da177e4SLinus Torvalds 	struct buffer_head dummy;
341*1da177e4SLinus Torvalds 
342*1da177e4SLinus Torvalds 	dummy.b_state = 0;
343*1da177e4SLinus Torvalds 	dummy.b_blocknr = -1000;
344*1da177e4SLinus Torvalds 	*err = udf_get_block(inode, block, &dummy, create);
345*1da177e4SLinus Torvalds 	if (!*err && buffer_mapped(&dummy))
346*1da177e4SLinus Torvalds 	{
347*1da177e4SLinus Torvalds 		struct buffer_head *bh;
348*1da177e4SLinus Torvalds 		bh = sb_getblk(inode->i_sb, dummy.b_blocknr);
349*1da177e4SLinus Torvalds 		if (buffer_new(&dummy))
350*1da177e4SLinus Torvalds 		{
351*1da177e4SLinus Torvalds 			lock_buffer(bh);
352*1da177e4SLinus Torvalds 			memset(bh->b_data, 0x00, inode->i_sb->s_blocksize);
353*1da177e4SLinus Torvalds 			set_buffer_uptodate(bh);
354*1da177e4SLinus Torvalds 			unlock_buffer(bh);
355*1da177e4SLinus Torvalds 			mark_buffer_dirty_inode(bh, inode);
356*1da177e4SLinus Torvalds 		}
357*1da177e4SLinus Torvalds 		return bh;
358*1da177e4SLinus Torvalds 	}
359*1da177e4SLinus Torvalds 	return NULL;
360*1da177e4SLinus Torvalds }
361*1da177e4SLinus Torvalds 
362*1da177e4SLinus Torvalds static struct buffer_head * inode_getblk(struct inode * inode, long block,
363*1da177e4SLinus Torvalds 	int *err, long *phys, int *new)
364*1da177e4SLinus Torvalds {
365*1da177e4SLinus Torvalds 	struct buffer_head *pbh = NULL, *cbh = NULL, *nbh = NULL, *result = NULL;
366*1da177e4SLinus Torvalds 	kernel_long_ad laarr[EXTENT_MERGE_SIZE];
367*1da177e4SLinus Torvalds 	uint32_t pextoffset = 0, cextoffset = 0, nextoffset = 0;
368*1da177e4SLinus Torvalds 	int count = 0, startnum = 0, endnum = 0;
369*1da177e4SLinus Torvalds 	uint32_t elen = 0;
370*1da177e4SLinus Torvalds 	kernel_lb_addr eloc, pbloc, cbloc, nbloc;
371*1da177e4SLinus Torvalds 	int c = 1;
372*1da177e4SLinus Torvalds 	uint64_t lbcount = 0, b_off = 0;
373*1da177e4SLinus Torvalds 	uint32_t newblocknum, newblock, offset = 0;
374*1da177e4SLinus Torvalds 	int8_t etype;
375*1da177e4SLinus Torvalds 	int goal = 0, pgoal = UDF_I_LOCATION(inode).logicalBlockNum;
376*1da177e4SLinus Torvalds 	char lastblock = 0;
377*1da177e4SLinus Torvalds 
378*1da177e4SLinus Torvalds 	pextoffset = cextoffset = nextoffset = udf_file_entry_alloc_offset(inode);
379*1da177e4SLinus Torvalds 	b_off = (uint64_t)block << inode->i_sb->s_blocksize_bits;
380*1da177e4SLinus Torvalds 	pbloc = cbloc = nbloc = UDF_I_LOCATION(inode);
381*1da177e4SLinus Torvalds 
382*1da177e4SLinus Torvalds 	/* find the extent which contains the block we are looking for.
383*1da177e4SLinus Torvalds        alternate between laarr[0] and laarr[1] for locations of the
384*1da177e4SLinus Torvalds        current extent, and the previous extent */
385*1da177e4SLinus Torvalds 	do
386*1da177e4SLinus Torvalds 	{
387*1da177e4SLinus Torvalds 		if (pbh != cbh)
388*1da177e4SLinus Torvalds 		{
389*1da177e4SLinus Torvalds 			udf_release_data(pbh);
390*1da177e4SLinus Torvalds 			atomic_inc(&cbh->b_count);
391*1da177e4SLinus Torvalds 			pbh = cbh;
392*1da177e4SLinus Torvalds 		}
393*1da177e4SLinus Torvalds 		if (cbh != nbh)
394*1da177e4SLinus Torvalds 		{
395*1da177e4SLinus Torvalds 			udf_release_data(cbh);
396*1da177e4SLinus Torvalds 			atomic_inc(&nbh->b_count);
397*1da177e4SLinus Torvalds 			cbh = nbh;
398*1da177e4SLinus Torvalds 		}
399*1da177e4SLinus Torvalds 
400*1da177e4SLinus Torvalds 		lbcount += elen;
401*1da177e4SLinus Torvalds 
402*1da177e4SLinus Torvalds 		pbloc = cbloc;
403*1da177e4SLinus Torvalds 		cbloc = nbloc;
404*1da177e4SLinus Torvalds 
405*1da177e4SLinus Torvalds 		pextoffset = cextoffset;
406*1da177e4SLinus Torvalds 		cextoffset = nextoffset;
407*1da177e4SLinus Torvalds 
408*1da177e4SLinus Torvalds 		if ((etype = udf_next_aext(inode, &nbloc, &nextoffset, &eloc, &elen, &nbh, 1)) == -1)
409*1da177e4SLinus Torvalds 			break;
410*1da177e4SLinus Torvalds 
411*1da177e4SLinus Torvalds 		c = !c;
412*1da177e4SLinus Torvalds 
413*1da177e4SLinus Torvalds 		laarr[c].extLength = (etype << 30) | elen;
414*1da177e4SLinus Torvalds 		laarr[c].extLocation = eloc;
415*1da177e4SLinus Torvalds 
416*1da177e4SLinus Torvalds 		if (etype != (EXT_NOT_RECORDED_NOT_ALLOCATED >> 30))
417*1da177e4SLinus Torvalds 			pgoal = eloc.logicalBlockNum +
418*1da177e4SLinus Torvalds 				((elen + inode->i_sb->s_blocksize - 1) >>
419*1da177e4SLinus Torvalds 				inode->i_sb->s_blocksize_bits);
420*1da177e4SLinus Torvalds 
421*1da177e4SLinus Torvalds 		count ++;
422*1da177e4SLinus Torvalds 	} while (lbcount + elen <= b_off);
423*1da177e4SLinus Torvalds 
424*1da177e4SLinus Torvalds 	b_off -= lbcount;
425*1da177e4SLinus Torvalds 	offset = b_off >> inode->i_sb->s_blocksize_bits;
426*1da177e4SLinus Torvalds 
427*1da177e4SLinus Torvalds 	/* if the extent is allocated and recorded, return the block
428*1da177e4SLinus Torvalds        if the extent is not a multiple of the blocksize, round up */
429*1da177e4SLinus Torvalds 
430*1da177e4SLinus Torvalds 	if (etype == (EXT_RECORDED_ALLOCATED >> 30))
431*1da177e4SLinus Torvalds 	{
432*1da177e4SLinus Torvalds 		if (elen & (inode->i_sb->s_blocksize - 1))
433*1da177e4SLinus Torvalds 		{
434*1da177e4SLinus Torvalds 			elen = EXT_RECORDED_ALLOCATED |
435*1da177e4SLinus Torvalds 				((elen + inode->i_sb->s_blocksize - 1) &
436*1da177e4SLinus Torvalds 				~(inode->i_sb->s_blocksize - 1));
437*1da177e4SLinus Torvalds 			etype = udf_write_aext(inode, nbloc, &cextoffset, eloc, elen, nbh, 1);
438*1da177e4SLinus Torvalds 		}
439*1da177e4SLinus Torvalds 		udf_release_data(pbh);
440*1da177e4SLinus Torvalds 		udf_release_data(cbh);
441*1da177e4SLinus Torvalds 		udf_release_data(nbh);
442*1da177e4SLinus Torvalds 		newblock = udf_get_lb_pblock(inode->i_sb, eloc, offset);
443*1da177e4SLinus Torvalds 		*phys = newblock;
444*1da177e4SLinus Torvalds 		return NULL;
445*1da177e4SLinus Torvalds 	}
446*1da177e4SLinus Torvalds 
447*1da177e4SLinus Torvalds 	if (etype == -1)
448*1da177e4SLinus Torvalds 	{
449*1da177e4SLinus Torvalds 		endnum = startnum = ((count > 1) ? 1 : count);
450*1da177e4SLinus Torvalds 		if (laarr[c].extLength & (inode->i_sb->s_blocksize - 1))
451*1da177e4SLinus Torvalds 		{
452*1da177e4SLinus Torvalds 			laarr[c].extLength =
453*1da177e4SLinus Torvalds 				(laarr[c].extLength & UDF_EXTENT_FLAG_MASK) |
454*1da177e4SLinus Torvalds 				(((laarr[c].extLength & UDF_EXTENT_LENGTH_MASK) +
455*1da177e4SLinus Torvalds 					inode->i_sb->s_blocksize - 1) &
456*1da177e4SLinus Torvalds 				~(inode->i_sb->s_blocksize - 1));
457*1da177e4SLinus Torvalds 			UDF_I_LENEXTENTS(inode) =
458*1da177e4SLinus Torvalds 				(UDF_I_LENEXTENTS(inode) + inode->i_sb->s_blocksize - 1) &
459*1da177e4SLinus Torvalds 					~(inode->i_sb->s_blocksize - 1);
460*1da177e4SLinus Torvalds 		}
461*1da177e4SLinus Torvalds 		c = !c;
462*1da177e4SLinus Torvalds 		laarr[c].extLength = EXT_NOT_RECORDED_NOT_ALLOCATED |
463*1da177e4SLinus Torvalds 			((offset + 1) << inode->i_sb->s_blocksize_bits);
464*1da177e4SLinus Torvalds 		memset(&laarr[c].extLocation, 0x00, sizeof(kernel_lb_addr));
465*1da177e4SLinus Torvalds 		count ++;
466*1da177e4SLinus Torvalds 		endnum ++;
467*1da177e4SLinus Torvalds 		lastblock = 1;
468*1da177e4SLinus Torvalds 	}
469*1da177e4SLinus Torvalds 	else
470*1da177e4SLinus Torvalds 		endnum = startnum = ((count > 2) ? 2 : count);
471*1da177e4SLinus Torvalds 
472*1da177e4SLinus Torvalds 	/* if the current extent is in position 0, swap it with the previous */
473*1da177e4SLinus Torvalds 	if (!c && count != 1)
474*1da177e4SLinus Torvalds 	{
475*1da177e4SLinus Torvalds 		laarr[2] = laarr[0];
476*1da177e4SLinus Torvalds 		laarr[0] = laarr[1];
477*1da177e4SLinus Torvalds 		laarr[1] = laarr[2];
478*1da177e4SLinus Torvalds 		c = 1;
479*1da177e4SLinus Torvalds 	}
480*1da177e4SLinus Torvalds 
481*1da177e4SLinus Torvalds 	/* if the current block is located in a extent, read the next extent */
482*1da177e4SLinus Torvalds 	if (etype != -1)
483*1da177e4SLinus Torvalds 	{
484*1da177e4SLinus Torvalds 		if ((etype = udf_next_aext(inode, &nbloc, &nextoffset, &eloc, &elen, &nbh, 0)) != -1)
485*1da177e4SLinus Torvalds 		{
486*1da177e4SLinus Torvalds 			laarr[c+1].extLength = (etype << 30) | elen;
487*1da177e4SLinus Torvalds 			laarr[c+1].extLocation = eloc;
488*1da177e4SLinus Torvalds 			count ++;
489*1da177e4SLinus Torvalds 			startnum ++;
490*1da177e4SLinus Torvalds 			endnum ++;
491*1da177e4SLinus Torvalds 		}
492*1da177e4SLinus Torvalds 		else
493*1da177e4SLinus Torvalds 			lastblock = 1;
494*1da177e4SLinus Torvalds 	}
495*1da177e4SLinus Torvalds 	udf_release_data(cbh);
496*1da177e4SLinus Torvalds 	udf_release_data(nbh);
497*1da177e4SLinus Torvalds 
498*1da177e4SLinus Torvalds 	/* if the current extent is not recorded but allocated, get the
499*1da177e4SLinus Torvalds 		block in the extent corresponding to the requested block */
500*1da177e4SLinus Torvalds 	if ((laarr[c].extLength >> 30) == (EXT_NOT_RECORDED_ALLOCATED >> 30))
501*1da177e4SLinus Torvalds 		newblocknum = laarr[c].extLocation.logicalBlockNum + offset;
502*1da177e4SLinus Torvalds 	else /* otherwise, allocate a new block */
503*1da177e4SLinus Torvalds 	{
504*1da177e4SLinus Torvalds 		if (UDF_I_NEXT_ALLOC_BLOCK(inode) == block)
505*1da177e4SLinus Torvalds 			goal = UDF_I_NEXT_ALLOC_GOAL(inode);
506*1da177e4SLinus Torvalds 
507*1da177e4SLinus Torvalds 		if (!goal)
508*1da177e4SLinus Torvalds 		{
509*1da177e4SLinus Torvalds 			if (!(goal = pgoal))
510*1da177e4SLinus Torvalds 				goal = UDF_I_LOCATION(inode).logicalBlockNum + 1;
511*1da177e4SLinus Torvalds 		}
512*1da177e4SLinus Torvalds 
513*1da177e4SLinus Torvalds 		if (!(newblocknum = udf_new_block(inode->i_sb, inode,
514*1da177e4SLinus Torvalds 			UDF_I_LOCATION(inode).partitionReferenceNum, goal, err)))
515*1da177e4SLinus Torvalds 		{
516*1da177e4SLinus Torvalds 			udf_release_data(pbh);
517*1da177e4SLinus Torvalds 			*err = -ENOSPC;
518*1da177e4SLinus Torvalds 			return NULL;
519*1da177e4SLinus Torvalds 		}
520*1da177e4SLinus Torvalds 		UDF_I_LENEXTENTS(inode) += inode->i_sb->s_blocksize;
521*1da177e4SLinus Torvalds 	}
522*1da177e4SLinus Torvalds 
523*1da177e4SLinus Torvalds 	/* if the extent the requsted block is located in contains multiple blocks,
524*1da177e4SLinus Torvalds        split the extent into at most three extents. blocks prior to requested
525*1da177e4SLinus Torvalds        block, requested block, and blocks after requested block */
526*1da177e4SLinus Torvalds 	udf_split_extents(inode, &c, offset, newblocknum, laarr, &endnum);
527*1da177e4SLinus Torvalds 
528*1da177e4SLinus Torvalds #ifdef UDF_PREALLOCATE
529*1da177e4SLinus Torvalds 	/* preallocate blocks */
530*1da177e4SLinus Torvalds 	udf_prealloc_extents(inode, c, lastblock, laarr, &endnum);
531*1da177e4SLinus Torvalds #endif
532*1da177e4SLinus Torvalds 
533*1da177e4SLinus Torvalds 	/* merge any continuous blocks in laarr */
534*1da177e4SLinus Torvalds 	udf_merge_extents(inode, laarr, &endnum);
535*1da177e4SLinus Torvalds 
536*1da177e4SLinus Torvalds 	/* write back the new extents, inserting new extents if the new number
537*1da177e4SLinus Torvalds        of extents is greater than the old number, and deleting extents if
538*1da177e4SLinus Torvalds        the new number of extents is less than the old number */
539*1da177e4SLinus Torvalds 	udf_update_extents(inode, laarr, startnum, endnum, pbloc, pextoffset, &pbh);
540*1da177e4SLinus Torvalds 
541*1da177e4SLinus Torvalds 	udf_release_data(pbh);
542*1da177e4SLinus Torvalds 
543*1da177e4SLinus Torvalds 	if (!(newblock = udf_get_pblock(inode->i_sb, newblocknum,
544*1da177e4SLinus Torvalds 		UDF_I_LOCATION(inode).partitionReferenceNum, 0)))
545*1da177e4SLinus Torvalds 	{
546*1da177e4SLinus Torvalds 		return NULL;
547*1da177e4SLinus Torvalds 	}
548*1da177e4SLinus Torvalds 	*phys = newblock;
549*1da177e4SLinus Torvalds 	*err = 0;
550*1da177e4SLinus Torvalds 	*new = 1;
551*1da177e4SLinus Torvalds 	UDF_I_NEXT_ALLOC_BLOCK(inode) = block;
552*1da177e4SLinus Torvalds 	UDF_I_NEXT_ALLOC_GOAL(inode) = newblocknum;
553*1da177e4SLinus Torvalds 	inode->i_ctime = current_fs_time(inode->i_sb);
554*1da177e4SLinus Torvalds 
555*1da177e4SLinus Torvalds 	if (IS_SYNC(inode))
556*1da177e4SLinus Torvalds 		udf_sync_inode(inode);
557*1da177e4SLinus Torvalds 	else
558*1da177e4SLinus Torvalds 		mark_inode_dirty(inode);
559*1da177e4SLinus Torvalds 	return result;
560*1da177e4SLinus Torvalds }
561*1da177e4SLinus Torvalds 
562*1da177e4SLinus Torvalds static void udf_split_extents(struct inode *inode, int *c, int offset, int newblocknum,
563*1da177e4SLinus Torvalds 	kernel_long_ad laarr[EXTENT_MERGE_SIZE], int *endnum)
564*1da177e4SLinus Torvalds {
565*1da177e4SLinus Torvalds 	if ((laarr[*c].extLength >> 30) == (EXT_NOT_RECORDED_ALLOCATED >> 30) ||
566*1da177e4SLinus Torvalds 		(laarr[*c].extLength >> 30) == (EXT_NOT_RECORDED_NOT_ALLOCATED >> 30))
567*1da177e4SLinus Torvalds 	{
568*1da177e4SLinus Torvalds 		int curr = *c;
569*1da177e4SLinus Torvalds 		int blen = ((laarr[curr].extLength & UDF_EXTENT_LENGTH_MASK) +
570*1da177e4SLinus Torvalds 			inode->i_sb->s_blocksize - 1) >> inode->i_sb->s_blocksize_bits;
571*1da177e4SLinus Torvalds 		int8_t etype = (laarr[curr].extLength >> 30);
572*1da177e4SLinus Torvalds 
573*1da177e4SLinus Torvalds 		if (blen == 1)
574*1da177e4SLinus Torvalds 			;
575*1da177e4SLinus Torvalds 		else if (!offset || blen == offset + 1)
576*1da177e4SLinus Torvalds 		{
577*1da177e4SLinus Torvalds 			laarr[curr+2] = laarr[curr+1];
578*1da177e4SLinus Torvalds 			laarr[curr+1] = laarr[curr];
579*1da177e4SLinus Torvalds 		}
580*1da177e4SLinus Torvalds 		else
581*1da177e4SLinus Torvalds 		{
582*1da177e4SLinus Torvalds 			laarr[curr+3] = laarr[curr+1];
583*1da177e4SLinus Torvalds 			laarr[curr+2] = laarr[curr+1] = laarr[curr];
584*1da177e4SLinus Torvalds 		}
585*1da177e4SLinus Torvalds 
586*1da177e4SLinus Torvalds 		if (offset)
587*1da177e4SLinus Torvalds 		{
588*1da177e4SLinus Torvalds 			if (etype == (EXT_NOT_RECORDED_ALLOCATED >> 30))
589*1da177e4SLinus Torvalds 			{
590*1da177e4SLinus Torvalds 				udf_free_blocks(inode->i_sb, inode, laarr[curr].extLocation, 0, offset);
591*1da177e4SLinus Torvalds 				laarr[curr].extLength = EXT_NOT_RECORDED_NOT_ALLOCATED |
592*1da177e4SLinus Torvalds 					(offset << inode->i_sb->s_blocksize_bits);
593*1da177e4SLinus Torvalds 				laarr[curr].extLocation.logicalBlockNum = 0;
594*1da177e4SLinus Torvalds 				laarr[curr].extLocation.partitionReferenceNum = 0;
595*1da177e4SLinus Torvalds 			}
596*1da177e4SLinus Torvalds 			else
597*1da177e4SLinus Torvalds 				laarr[curr].extLength = (etype << 30) |
598*1da177e4SLinus Torvalds 					(offset << inode->i_sb->s_blocksize_bits);
599*1da177e4SLinus Torvalds 			curr ++;
600*1da177e4SLinus Torvalds 			(*c) ++;
601*1da177e4SLinus Torvalds 			(*endnum) ++;
602*1da177e4SLinus Torvalds 		}
603*1da177e4SLinus Torvalds 
604*1da177e4SLinus Torvalds 		laarr[curr].extLocation.logicalBlockNum = newblocknum;
605*1da177e4SLinus Torvalds 		if (etype == (EXT_NOT_RECORDED_NOT_ALLOCATED >> 30))
606*1da177e4SLinus Torvalds 			laarr[curr].extLocation.partitionReferenceNum =
607*1da177e4SLinus Torvalds 				UDF_I_LOCATION(inode).partitionReferenceNum;
608*1da177e4SLinus Torvalds 		laarr[curr].extLength = EXT_RECORDED_ALLOCATED |
609*1da177e4SLinus Torvalds 			inode->i_sb->s_blocksize;
610*1da177e4SLinus Torvalds 		curr ++;
611*1da177e4SLinus Torvalds 
612*1da177e4SLinus Torvalds 		if (blen != offset + 1)
613*1da177e4SLinus Torvalds 		{
614*1da177e4SLinus Torvalds 			if (etype == (EXT_NOT_RECORDED_ALLOCATED >> 30))
615*1da177e4SLinus Torvalds 				laarr[curr].extLocation.logicalBlockNum += (offset + 1);
616*1da177e4SLinus Torvalds 			laarr[curr].extLength = (etype << 30) |
617*1da177e4SLinus Torvalds 				((blen - (offset + 1)) << inode->i_sb->s_blocksize_bits);
618*1da177e4SLinus Torvalds 			curr ++;
619*1da177e4SLinus Torvalds 			(*endnum) ++;
620*1da177e4SLinus Torvalds 		}
621*1da177e4SLinus Torvalds 	}
622*1da177e4SLinus Torvalds }
623*1da177e4SLinus Torvalds 
624*1da177e4SLinus Torvalds static void udf_prealloc_extents(struct inode *inode, int c, int lastblock,
625*1da177e4SLinus Torvalds 	 kernel_long_ad laarr[EXTENT_MERGE_SIZE], int *endnum)
626*1da177e4SLinus Torvalds {
627*1da177e4SLinus Torvalds 	int start, length = 0, currlength = 0, i;
628*1da177e4SLinus Torvalds 
629*1da177e4SLinus Torvalds 	if (*endnum >= (c+1))
630*1da177e4SLinus Torvalds 	{
631*1da177e4SLinus Torvalds 		if (!lastblock)
632*1da177e4SLinus Torvalds 			return;
633*1da177e4SLinus Torvalds 		else
634*1da177e4SLinus Torvalds 			start = c;
635*1da177e4SLinus Torvalds 	}
636*1da177e4SLinus Torvalds 	else
637*1da177e4SLinus Torvalds 	{
638*1da177e4SLinus Torvalds 		if ((laarr[c+1].extLength >> 30) == (EXT_NOT_RECORDED_ALLOCATED >> 30))
639*1da177e4SLinus Torvalds 		{
640*1da177e4SLinus Torvalds 			start = c+1;
641*1da177e4SLinus Torvalds 			length = currlength = (((laarr[c+1].extLength & UDF_EXTENT_LENGTH_MASK) +
642*1da177e4SLinus Torvalds 				inode->i_sb->s_blocksize - 1) >> inode->i_sb->s_blocksize_bits);
643*1da177e4SLinus Torvalds 		}
644*1da177e4SLinus Torvalds 		else
645*1da177e4SLinus Torvalds 			start = c;
646*1da177e4SLinus Torvalds 	}
647*1da177e4SLinus Torvalds 
648*1da177e4SLinus Torvalds 	for (i=start+1; i<=*endnum; i++)
649*1da177e4SLinus Torvalds 	{
650*1da177e4SLinus Torvalds 		if (i == *endnum)
651*1da177e4SLinus Torvalds 		{
652*1da177e4SLinus Torvalds 			if (lastblock)
653*1da177e4SLinus Torvalds 				length += UDF_DEFAULT_PREALLOC_BLOCKS;
654*1da177e4SLinus Torvalds 		}
655*1da177e4SLinus Torvalds 		else if ((laarr[i].extLength >> 30) == (EXT_NOT_RECORDED_NOT_ALLOCATED >> 30))
656*1da177e4SLinus Torvalds 			length += (((laarr[i].extLength & UDF_EXTENT_LENGTH_MASK) +
657*1da177e4SLinus Torvalds 				inode->i_sb->s_blocksize - 1) >> inode->i_sb->s_blocksize_bits);
658*1da177e4SLinus Torvalds 		else
659*1da177e4SLinus Torvalds 			break;
660*1da177e4SLinus Torvalds 	}
661*1da177e4SLinus Torvalds 
662*1da177e4SLinus Torvalds 	if (length)
663*1da177e4SLinus Torvalds 	{
664*1da177e4SLinus Torvalds 		int next = laarr[start].extLocation.logicalBlockNum +
665*1da177e4SLinus Torvalds 			(((laarr[start].extLength & UDF_EXTENT_LENGTH_MASK) +
666*1da177e4SLinus Torvalds 			inode->i_sb->s_blocksize - 1) >> inode->i_sb->s_blocksize_bits);
667*1da177e4SLinus Torvalds 		int numalloc = udf_prealloc_blocks(inode->i_sb, inode,
668*1da177e4SLinus Torvalds 			laarr[start].extLocation.partitionReferenceNum,
669*1da177e4SLinus Torvalds 			next, (UDF_DEFAULT_PREALLOC_BLOCKS > length ? length :
670*1da177e4SLinus Torvalds 				UDF_DEFAULT_PREALLOC_BLOCKS) - currlength);
671*1da177e4SLinus Torvalds 
672*1da177e4SLinus Torvalds 		if (numalloc)
673*1da177e4SLinus Torvalds 		{
674*1da177e4SLinus Torvalds 			if (start == (c+1))
675*1da177e4SLinus Torvalds 				laarr[start].extLength +=
676*1da177e4SLinus Torvalds 					(numalloc << inode->i_sb->s_blocksize_bits);
677*1da177e4SLinus Torvalds 			else
678*1da177e4SLinus Torvalds 			{
679*1da177e4SLinus Torvalds 				memmove(&laarr[c+2], &laarr[c+1],
680*1da177e4SLinus Torvalds 					sizeof(long_ad) * (*endnum - (c+1)));
681*1da177e4SLinus Torvalds 				(*endnum) ++;
682*1da177e4SLinus Torvalds 				laarr[c+1].extLocation.logicalBlockNum = next;
683*1da177e4SLinus Torvalds 				laarr[c+1].extLocation.partitionReferenceNum =
684*1da177e4SLinus Torvalds 					laarr[c].extLocation.partitionReferenceNum;
685*1da177e4SLinus Torvalds 				laarr[c+1].extLength = EXT_NOT_RECORDED_ALLOCATED |
686*1da177e4SLinus Torvalds 					(numalloc << inode->i_sb->s_blocksize_bits);
687*1da177e4SLinus Torvalds 				start = c+1;
688*1da177e4SLinus Torvalds 			}
689*1da177e4SLinus Torvalds 
690*1da177e4SLinus Torvalds 			for (i=start+1; numalloc && i<*endnum; i++)
691*1da177e4SLinus Torvalds 			{
692*1da177e4SLinus Torvalds 				int elen = ((laarr[i].extLength & UDF_EXTENT_LENGTH_MASK) +
693*1da177e4SLinus Torvalds 					inode->i_sb->s_blocksize - 1) >> inode->i_sb->s_blocksize_bits;
694*1da177e4SLinus Torvalds 
695*1da177e4SLinus Torvalds 				if (elen > numalloc)
696*1da177e4SLinus Torvalds 				{
697*1da177e4SLinus Torvalds 					laarr[i].extLength -=
698*1da177e4SLinus Torvalds 						(numalloc << inode->i_sb->s_blocksize_bits);
699*1da177e4SLinus Torvalds 					numalloc = 0;
700*1da177e4SLinus Torvalds 				}
701*1da177e4SLinus Torvalds 				else
702*1da177e4SLinus Torvalds 				{
703*1da177e4SLinus Torvalds 					numalloc -= elen;
704*1da177e4SLinus Torvalds 					if (*endnum > (i+1))
705*1da177e4SLinus Torvalds 						memmove(&laarr[i], &laarr[i+1],
706*1da177e4SLinus Torvalds 							sizeof(long_ad) * (*endnum - (i+1)));
707*1da177e4SLinus Torvalds 					i --;
708*1da177e4SLinus Torvalds 					(*endnum) --;
709*1da177e4SLinus Torvalds 				}
710*1da177e4SLinus Torvalds 			}
711*1da177e4SLinus Torvalds 			UDF_I_LENEXTENTS(inode) += numalloc << inode->i_sb->s_blocksize_bits;
712*1da177e4SLinus Torvalds 		}
713*1da177e4SLinus Torvalds 	}
714*1da177e4SLinus Torvalds }
715*1da177e4SLinus Torvalds 
716*1da177e4SLinus Torvalds static void udf_merge_extents(struct inode *inode,
717*1da177e4SLinus Torvalds 	 kernel_long_ad laarr[EXTENT_MERGE_SIZE], int *endnum)
718*1da177e4SLinus Torvalds {
719*1da177e4SLinus Torvalds 	int i;
720*1da177e4SLinus Torvalds 
721*1da177e4SLinus Torvalds 	for (i=0; i<(*endnum-1); i++)
722*1da177e4SLinus Torvalds 	{
723*1da177e4SLinus Torvalds 		if ((laarr[i].extLength >> 30) == (laarr[i+1].extLength >> 30))
724*1da177e4SLinus Torvalds 		{
725*1da177e4SLinus Torvalds 			if (((laarr[i].extLength >> 30) == (EXT_NOT_RECORDED_NOT_ALLOCATED >> 30)) ||
726*1da177e4SLinus Torvalds 				((laarr[i+1].extLocation.logicalBlockNum - laarr[i].extLocation.logicalBlockNum) ==
727*1da177e4SLinus Torvalds 				(((laarr[i].extLength & UDF_EXTENT_LENGTH_MASK) +
728*1da177e4SLinus Torvalds 				inode->i_sb->s_blocksize - 1) >> inode->i_sb->s_blocksize_bits)))
729*1da177e4SLinus Torvalds 			{
730*1da177e4SLinus Torvalds 				if (((laarr[i].extLength & UDF_EXTENT_LENGTH_MASK) +
731*1da177e4SLinus Torvalds 					(laarr[i+1].extLength & UDF_EXTENT_LENGTH_MASK) +
732*1da177e4SLinus Torvalds 					inode->i_sb->s_blocksize - 1) & ~UDF_EXTENT_LENGTH_MASK)
733*1da177e4SLinus Torvalds 				{
734*1da177e4SLinus Torvalds 					laarr[i+1].extLength = (laarr[i+1].extLength -
735*1da177e4SLinus Torvalds 						(laarr[i].extLength & UDF_EXTENT_LENGTH_MASK) +
736*1da177e4SLinus Torvalds 						UDF_EXTENT_LENGTH_MASK) & ~(inode->i_sb->s_blocksize-1);
737*1da177e4SLinus Torvalds 					laarr[i].extLength = (laarr[i].extLength & UDF_EXTENT_FLAG_MASK) +
738*1da177e4SLinus Torvalds 						(UDF_EXTENT_LENGTH_MASK + 1) - inode->i_sb->s_blocksize;
739*1da177e4SLinus Torvalds 					laarr[i+1].extLocation.logicalBlockNum =
740*1da177e4SLinus Torvalds 						laarr[i].extLocation.logicalBlockNum +
741*1da177e4SLinus Torvalds 						((laarr[i].extLength & UDF_EXTENT_LENGTH_MASK) >>
742*1da177e4SLinus Torvalds 							inode->i_sb->s_blocksize_bits);
743*1da177e4SLinus Torvalds 				}
744*1da177e4SLinus Torvalds 				else
745*1da177e4SLinus Torvalds 				{
746*1da177e4SLinus Torvalds 					laarr[i].extLength = laarr[i+1].extLength +
747*1da177e4SLinus Torvalds 						(((laarr[i].extLength & UDF_EXTENT_LENGTH_MASK) +
748*1da177e4SLinus Torvalds 						inode->i_sb->s_blocksize - 1) & ~(inode->i_sb->s_blocksize-1));
749*1da177e4SLinus Torvalds 					if (*endnum > (i+2))
750*1da177e4SLinus Torvalds 						memmove(&laarr[i+1], &laarr[i+2],
751*1da177e4SLinus Torvalds 							sizeof(long_ad) * (*endnum - (i+2)));
752*1da177e4SLinus Torvalds 					i --;
753*1da177e4SLinus Torvalds 					(*endnum) --;
754*1da177e4SLinus Torvalds 				}
755*1da177e4SLinus Torvalds 			}
756*1da177e4SLinus Torvalds 		}
757*1da177e4SLinus Torvalds 		else if (((laarr[i].extLength >> 30) == (EXT_NOT_RECORDED_ALLOCATED >> 30)) &&
758*1da177e4SLinus Torvalds 			((laarr[i+1].extLength >> 30) == (EXT_NOT_RECORDED_NOT_ALLOCATED >> 30)))
759*1da177e4SLinus Torvalds 		{
760*1da177e4SLinus Torvalds 			udf_free_blocks(inode->i_sb, inode, laarr[i].extLocation, 0,
761*1da177e4SLinus Torvalds 				((laarr[i].extLength & UDF_EXTENT_LENGTH_MASK) +
762*1da177e4SLinus Torvalds 				inode->i_sb->s_blocksize - 1) >> inode->i_sb->s_blocksize_bits);
763*1da177e4SLinus Torvalds 			laarr[i].extLocation.logicalBlockNum = 0;
764*1da177e4SLinus Torvalds 			laarr[i].extLocation.partitionReferenceNum = 0;
765*1da177e4SLinus Torvalds 
766*1da177e4SLinus Torvalds 			if (((laarr[i].extLength & UDF_EXTENT_LENGTH_MASK) +
767*1da177e4SLinus Torvalds 				(laarr[i+1].extLength & UDF_EXTENT_LENGTH_MASK) +
768*1da177e4SLinus Torvalds 				inode->i_sb->s_blocksize - 1) & ~UDF_EXTENT_LENGTH_MASK)
769*1da177e4SLinus Torvalds 			{
770*1da177e4SLinus Torvalds 				laarr[i+1].extLength = (laarr[i+1].extLength -
771*1da177e4SLinus Torvalds 					(laarr[i].extLength & UDF_EXTENT_LENGTH_MASK) +
772*1da177e4SLinus Torvalds 					UDF_EXTENT_LENGTH_MASK) & ~(inode->i_sb->s_blocksize-1);
773*1da177e4SLinus Torvalds 				laarr[i].extLength = (laarr[i].extLength & UDF_EXTENT_FLAG_MASK) +
774*1da177e4SLinus Torvalds 					(UDF_EXTENT_LENGTH_MASK + 1) - inode->i_sb->s_blocksize;
775*1da177e4SLinus Torvalds 			}
776*1da177e4SLinus Torvalds 			else
777*1da177e4SLinus Torvalds 			{
778*1da177e4SLinus Torvalds 				laarr[i].extLength = laarr[i+1].extLength +
779*1da177e4SLinus Torvalds 					(((laarr[i].extLength & UDF_EXTENT_LENGTH_MASK) +
780*1da177e4SLinus Torvalds 					inode->i_sb->s_blocksize - 1) & ~(inode->i_sb->s_blocksize-1));
781*1da177e4SLinus Torvalds 				if (*endnum > (i+2))
782*1da177e4SLinus Torvalds 					memmove(&laarr[i+1], &laarr[i+2],
783*1da177e4SLinus Torvalds 						sizeof(long_ad) * (*endnum - (i+2)));
784*1da177e4SLinus Torvalds 				i --;
785*1da177e4SLinus Torvalds 				(*endnum) --;
786*1da177e4SLinus Torvalds 			}
787*1da177e4SLinus Torvalds 		}
788*1da177e4SLinus Torvalds 		else if ((laarr[i].extLength >> 30) == (EXT_NOT_RECORDED_ALLOCATED >> 30))
789*1da177e4SLinus Torvalds 		{
790*1da177e4SLinus Torvalds 			udf_free_blocks(inode->i_sb, inode, laarr[i].extLocation, 0,
791*1da177e4SLinus Torvalds 				((laarr[i].extLength & UDF_EXTENT_LENGTH_MASK) +
792*1da177e4SLinus Torvalds 			       inode->i_sb->s_blocksize - 1) >> inode->i_sb->s_blocksize_bits);
793*1da177e4SLinus Torvalds 			laarr[i].extLocation.logicalBlockNum = 0;
794*1da177e4SLinus Torvalds 			laarr[i].extLocation.partitionReferenceNum = 0;
795*1da177e4SLinus Torvalds 			laarr[i].extLength = (laarr[i].extLength & UDF_EXTENT_LENGTH_MASK) |
796*1da177e4SLinus Torvalds 				EXT_NOT_RECORDED_NOT_ALLOCATED;
797*1da177e4SLinus Torvalds 		}
798*1da177e4SLinus Torvalds 	}
799*1da177e4SLinus Torvalds }
800*1da177e4SLinus Torvalds 
801*1da177e4SLinus Torvalds static void udf_update_extents(struct inode *inode,
802*1da177e4SLinus Torvalds 	kernel_long_ad laarr[EXTENT_MERGE_SIZE], int startnum, int endnum,
803*1da177e4SLinus Torvalds 	kernel_lb_addr pbloc, uint32_t pextoffset, struct buffer_head **pbh)
804*1da177e4SLinus Torvalds {
805*1da177e4SLinus Torvalds 	int start = 0, i;
806*1da177e4SLinus Torvalds 	kernel_lb_addr tmploc;
807*1da177e4SLinus Torvalds 	uint32_t tmplen;
808*1da177e4SLinus Torvalds 
809*1da177e4SLinus Torvalds 	if (startnum > endnum)
810*1da177e4SLinus Torvalds 	{
811*1da177e4SLinus Torvalds 		for (i=0; i<(startnum-endnum); i++)
812*1da177e4SLinus Torvalds 		{
813*1da177e4SLinus Torvalds 			udf_delete_aext(inode, pbloc, pextoffset, laarr[i].extLocation,
814*1da177e4SLinus Torvalds 				laarr[i].extLength, *pbh);
815*1da177e4SLinus Torvalds 		}
816*1da177e4SLinus Torvalds 	}
817*1da177e4SLinus Torvalds 	else if (startnum < endnum)
818*1da177e4SLinus Torvalds 	{
819*1da177e4SLinus Torvalds 		for (i=0; i<(endnum-startnum); i++)
820*1da177e4SLinus Torvalds 		{
821*1da177e4SLinus Torvalds 			udf_insert_aext(inode, pbloc, pextoffset, laarr[i].extLocation,
822*1da177e4SLinus Torvalds 				laarr[i].extLength, *pbh);
823*1da177e4SLinus Torvalds 			udf_next_aext(inode, &pbloc, &pextoffset, &laarr[i].extLocation,
824*1da177e4SLinus Torvalds 				&laarr[i].extLength, pbh, 1);
825*1da177e4SLinus Torvalds 			start ++;
826*1da177e4SLinus Torvalds 		}
827*1da177e4SLinus Torvalds 	}
828*1da177e4SLinus Torvalds 
829*1da177e4SLinus Torvalds 	for (i=start; i<endnum; i++)
830*1da177e4SLinus Torvalds 	{
831*1da177e4SLinus Torvalds 		udf_next_aext(inode, &pbloc, &pextoffset, &tmploc, &tmplen, pbh, 0);
832*1da177e4SLinus Torvalds 		udf_write_aext(inode, pbloc, &pextoffset, laarr[i].extLocation,
833*1da177e4SLinus Torvalds 			laarr[i].extLength, *pbh, 1);
834*1da177e4SLinus Torvalds 	}
835*1da177e4SLinus Torvalds }
836*1da177e4SLinus Torvalds 
837*1da177e4SLinus Torvalds struct buffer_head * udf_bread(struct inode * inode, int block,
838*1da177e4SLinus Torvalds 	int create, int * err)
839*1da177e4SLinus Torvalds {
840*1da177e4SLinus Torvalds 	struct buffer_head * bh = NULL;
841*1da177e4SLinus Torvalds 
842*1da177e4SLinus Torvalds 	bh = udf_getblk(inode, block, create, err);
843*1da177e4SLinus Torvalds 	if (!bh)
844*1da177e4SLinus Torvalds 		return NULL;
845*1da177e4SLinus Torvalds 
846*1da177e4SLinus Torvalds 	if (buffer_uptodate(bh))
847*1da177e4SLinus Torvalds 		return bh;
848*1da177e4SLinus Torvalds 	ll_rw_block(READ, 1, &bh);
849*1da177e4SLinus Torvalds 	wait_on_buffer(bh);
850*1da177e4SLinus Torvalds 	if (buffer_uptodate(bh))
851*1da177e4SLinus Torvalds 		return bh;
852*1da177e4SLinus Torvalds 	brelse(bh);
853*1da177e4SLinus Torvalds 	*err = -EIO;
854*1da177e4SLinus Torvalds 	return NULL;
855*1da177e4SLinus Torvalds }
856*1da177e4SLinus Torvalds 
857*1da177e4SLinus Torvalds void udf_truncate(struct inode * inode)
858*1da177e4SLinus Torvalds {
859*1da177e4SLinus Torvalds 	int offset;
860*1da177e4SLinus Torvalds 	int err;
861*1da177e4SLinus Torvalds 
862*1da177e4SLinus Torvalds 	if (!(S_ISREG(inode->i_mode) || S_ISDIR(inode->i_mode) ||
863*1da177e4SLinus Torvalds 			S_ISLNK(inode->i_mode)))
864*1da177e4SLinus Torvalds 		return;
865*1da177e4SLinus Torvalds 	if (IS_APPEND(inode) || IS_IMMUTABLE(inode))
866*1da177e4SLinus Torvalds 		return;
867*1da177e4SLinus Torvalds 
868*1da177e4SLinus Torvalds 	lock_kernel();
869*1da177e4SLinus Torvalds 	if (UDF_I_ALLOCTYPE(inode) == ICBTAG_FLAG_AD_IN_ICB)
870*1da177e4SLinus Torvalds 	{
871*1da177e4SLinus Torvalds 		if (inode->i_sb->s_blocksize < (udf_file_entry_alloc_offset(inode) +
872*1da177e4SLinus Torvalds 			inode->i_size))
873*1da177e4SLinus Torvalds 		{
874*1da177e4SLinus Torvalds 			udf_expand_file_adinicb(inode, inode->i_size, &err);
875*1da177e4SLinus Torvalds 			if (UDF_I_ALLOCTYPE(inode) == ICBTAG_FLAG_AD_IN_ICB)
876*1da177e4SLinus Torvalds 			{
877*1da177e4SLinus Torvalds 				inode->i_size = UDF_I_LENALLOC(inode);
878*1da177e4SLinus Torvalds 				unlock_kernel();
879*1da177e4SLinus Torvalds 				return;
880*1da177e4SLinus Torvalds 			}
881*1da177e4SLinus Torvalds 			else
882*1da177e4SLinus Torvalds 				udf_truncate_extents(inode);
883*1da177e4SLinus Torvalds 		}
884*1da177e4SLinus Torvalds 		else
885*1da177e4SLinus Torvalds 		{
886*1da177e4SLinus Torvalds 			offset = inode->i_size & (inode->i_sb->s_blocksize - 1);
887*1da177e4SLinus Torvalds 			memset(UDF_I_DATA(inode) + UDF_I_LENEATTR(inode) + offset, 0x00, inode->i_sb->s_blocksize - offset - udf_file_entry_alloc_offset(inode));
888*1da177e4SLinus Torvalds 			UDF_I_LENALLOC(inode) = inode->i_size;
889*1da177e4SLinus Torvalds 		}
890*1da177e4SLinus Torvalds 	}
891*1da177e4SLinus Torvalds 	else
892*1da177e4SLinus Torvalds 	{
893*1da177e4SLinus Torvalds 		block_truncate_page(inode->i_mapping, inode->i_size, udf_get_block);
894*1da177e4SLinus Torvalds 		udf_truncate_extents(inode);
895*1da177e4SLinus Torvalds 	}
896*1da177e4SLinus Torvalds 
897*1da177e4SLinus Torvalds 	inode->i_mtime = inode->i_ctime = current_fs_time(inode->i_sb);
898*1da177e4SLinus Torvalds 	if (IS_SYNC(inode))
899*1da177e4SLinus Torvalds 		udf_sync_inode (inode);
900*1da177e4SLinus Torvalds 	else
901*1da177e4SLinus Torvalds 		mark_inode_dirty(inode);
902*1da177e4SLinus Torvalds 	unlock_kernel();
903*1da177e4SLinus Torvalds }
904*1da177e4SLinus Torvalds 
905*1da177e4SLinus Torvalds static void
906*1da177e4SLinus Torvalds __udf_read_inode(struct inode *inode)
907*1da177e4SLinus Torvalds {
908*1da177e4SLinus Torvalds 	struct buffer_head *bh = NULL;
909*1da177e4SLinus Torvalds 	struct fileEntry *fe;
910*1da177e4SLinus Torvalds 	uint16_t ident;
911*1da177e4SLinus Torvalds 
912*1da177e4SLinus Torvalds 	/*
913*1da177e4SLinus Torvalds 	 * Set defaults, but the inode is still incomplete!
914*1da177e4SLinus Torvalds 	 * Note: get_new_inode() sets the following on a new inode:
915*1da177e4SLinus Torvalds 	 *      i_sb = sb
916*1da177e4SLinus Torvalds 	 *      i_no = ino
917*1da177e4SLinus Torvalds 	 *      i_flags = sb->s_flags
918*1da177e4SLinus Torvalds 	 *      i_state = 0
919*1da177e4SLinus Torvalds 	 * clean_inode(): zero fills and sets
920*1da177e4SLinus Torvalds 	 *      i_count = 1
921*1da177e4SLinus Torvalds 	 *      i_nlink = 1
922*1da177e4SLinus Torvalds 	 *      i_op = NULL;
923*1da177e4SLinus Torvalds 	 */
924*1da177e4SLinus Torvalds 	inode->i_blksize = PAGE_SIZE;
925*1da177e4SLinus Torvalds 
926*1da177e4SLinus Torvalds 	bh = udf_read_ptagged(inode->i_sb, UDF_I_LOCATION(inode), 0, &ident);
927*1da177e4SLinus Torvalds 
928*1da177e4SLinus Torvalds 	if (!bh)
929*1da177e4SLinus Torvalds 	{
930*1da177e4SLinus Torvalds 		printk(KERN_ERR "udf: udf_read_inode(ino %ld) failed !bh\n",
931*1da177e4SLinus Torvalds 			inode->i_ino);
932*1da177e4SLinus Torvalds 		make_bad_inode(inode);
933*1da177e4SLinus Torvalds 		return;
934*1da177e4SLinus Torvalds 	}
935*1da177e4SLinus Torvalds 
936*1da177e4SLinus Torvalds 	if (ident != TAG_IDENT_FE && ident != TAG_IDENT_EFE &&
937*1da177e4SLinus Torvalds 		ident != TAG_IDENT_USE)
938*1da177e4SLinus Torvalds 	{
939*1da177e4SLinus Torvalds 		printk(KERN_ERR "udf: udf_read_inode(ino %ld) failed ident=%d\n",
940*1da177e4SLinus Torvalds 			inode->i_ino, ident);
941*1da177e4SLinus Torvalds 		udf_release_data(bh);
942*1da177e4SLinus Torvalds 		make_bad_inode(inode);
943*1da177e4SLinus Torvalds 		return;
944*1da177e4SLinus Torvalds 	}
945*1da177e4SLinus Torvalds 
946*1da177e4SLinus Torvalds 	fe = (struct fileEntry *)bh->b_data;
947*1da177e4SLinus Torvalds 
948*1da177e4SLinus Torvalds 	if (le16_to_cpu(fe->icbTag.strategyType) == 4096)
949*1da177e4SLinus Torvalds 	{
950*1da177e4SLinus Torvalds 		struct buffer_head *ibh = NULL, *nbh = NULL;
951*1da177e4SLinus Torvalds 		struct indirectEntry *ie;
952*1da177e4SLinus Torvalds 
953*1da177e4SLinus Torvalds 		ibh = udf_read_ptagged(inode->i_sb, UDF_I_LOCATION(inode), 1, &ident);
954*1da177e4SLinus Torvalds 		if (ident == TAG_IDENT_IE)
955*1da177e4SLinus Torvalds 		{
956*1da177e4SLinus Torvalds 			if (ibh)
957*1da177e4SLinus Torvalds 			{
958*1da177e4SLinus Torvalds 				kernel_lb_addr loc;
959*1da177e4SLinus Torvalds 				ie = (struct indirectEntry *)ibh->b_data;
960*1da177e4SLinus Torvalds 
961*1da177e4SLinus Torvalds 				loc = lelb_to_cpu(ie->indirectICB.extLocation);
962*1da177e4SLinus Torvalds 
963*1da177e4SLinus Torvalds 				if (ie->indirectICB.extLength &&
964*1da177e4SLinus Torvalds 					(nbh = udf_read_ptagged(inode->i_sb, loc, 0, &ident)))
965*1da177e4SLinus Torvalds 				{
966*1da177e4SLinus Torvalds 					if (ident == TAG_IDENT_FE ||
967*1da177e4SLinus Torvalds 						ident == TAG_IDENT_EFE)
968*1da177e4SLinus Torvalds 					{
969*1da177e4SLinus Torvalds 						memcpy(&UDF_I_LOCATION(inode), &loc, sizeof(kernel_lb_addr));
970*1da177e4SLinus Torvalds 						udf_release_data(bh);
971*1da177e4SLinus Torvalds 						udf_release_data(ibh);
972*1da177e4SLinus Torvalds 						udf_release_data(nbh);
973*1da177e4SLinus Torvalds 						__udf_read_inode(inode);
974*1da177e4SLinus Torvalds 						return;
975*1da177e4SLinus Torvalds 					}
976*1da177e4SLinus Torvalds 					else
977*1da177e4SLinus Torvalds 					{
978*1da177e4SLinus Torvalds 						udf_release_data(nbh);
979*1da177e4SLinus Torvalds 						udf_release_data(ibh);
980*1da177e4SLinus Torvalds 					}
981*1da177e4SLinus Torvalds 				}
982*1da177e4SLinus Torvalds 				else
983*1da177e4SLinus Torvalds 					udf_release_data(ibh);
984*1da177e4SLinus Torvalds 			}
985*1da177e4SLinus Torvalds 		}
986*1da177e4SLinus Torvalds 		else
987*1da177e4SLinus Torvalds 			udf_release_data(ibh);
988*1da177e4SLinus Torvalds 	}
989*1da177e4SLinus Torvalds 	else if (le16_to_cpu(fe->icbTag.strategyType) != 4)
990*1da177e4SLinus Torvalds 	{
991*1da177e4SLinus Torvalds 		printk(KERN_ERR "udf: unsupported strategy type: %d\n",
992*1da177e4SLinus Torvalds 			le16_to_cpu(fe->icbTag.strategyType));
993*1da177e4SLinus Torvalds 		udf_release_data(bh);
994*1da177e4SLinus Torvalds 		make_bad_inode(inode);
995*1da177e4SLinus Torvalds 		return;
996*1da177e4SLinus Torvalds 	}
997*1da177e4SLinus Torvalds 	udf_fill_inode(inode, bh);
998*1da177e4SLinus Torvalds 	udf_release_data(bh);
999*1da177e4SLinus Torvalds }
1000*1da177e4SLinus Torvalds 
1001*1da177e4SLinus Torvalds static void udf_fill_inode(struct inode *inode, struct buffer_head *bh)
1002*1da177e4SLinus Torvalds {
1003*1da177e4SLinus Torvalds 	struct fileEntry *fe;
1004*1da177e4SLinus Torvalds 	struct extendedFileEntry *efe;
1005*1da177e4SLinus Torvalds 	time_t convtime;
1006*1da177e4SLinus Torvalds 	long convtime_usec;
1007*1da177e4SLinus Torvalds 	int offset;
1008*1da177e4SLinus Torvalds 
1009*1da177e4SLinus Torvalds 	fe = (struct fileEntry *)bh->b_data;
1010*1da177e4SLinus Torvalds 	efe = (struct extendedFileEntry *)bh->b_data;
1011*1da177e4SLinus Torvalds 
1012*1da177e4SLinus Torvalds 	if (le16_to_cpu(fe->icbTag.strategyType) == 4)
1013*1da177e4SLinus Torvalds 		UDF_I_STRAT4096(inode) = 0;
1014*1da177e4SLinus Torvalds 	else /* if (le16_to_cpu(fe->icbTag.strategyType) == 4096) */
1015*1da177e4SLinus Torvalds 		UDF_I_STRAT4096(inode) = 1;
1016*1da177e4SLinus Torvalds 
1017*1da177e4SLinus Torvalds 	UDF_I_ALLOCTYPE(inode) = le16_to_cpu(fe->icbTag.flags) & ICBTAG_FLAG_AD_MASK;
1018*1da177e4SLinus Torvalds 	UDF_I_UNIQUE(inode) = 0;
1019*1da177e4SLinus Torvalds 	UDF_I_LENEATTR(inode) = 0;
1020*1da177e4SLinus Torvalds 	UDF_I_LENEXTENTS(inode) = 0;
1021*1da177e4SLinus Torvalds 	UDF_I_LENALLOC(inode) = 0;
1022*1da177e4SLinus Torvalds 	UDF_I_NEXT_ALLOC_BLOCK(inode) = 0;
1023*1da177e4SLinus Torvalds 	UDF_I_NEXT_ALLOC_GOAL(inode) = 0;
1024*1da177e4SLinus Torvalds 	if (le16_to_cpu(fe->descTag.tagIdent) == TAG_IDENT_EFE)
1025*1da177e4SLinus Torvalds 	{
1026*1da177e4SLinus Torvalds 		UDF_I_EFE(inode) = 1;
1027*1da177e4SLinus Torvalds 		UDF_I_USE(inode) = 0;
1028*1da177e4SLinus Torvalds 		UDF_I_DATA(inode) = kmalloc(inode->i_sb->s_blocksize - sizeof(struct extendedFileEntry), GFP_KERNEL);
1029*1da177e4SLinus Torvalds 		memcpy(UDF_I_DATA(inode), bh->b_data + sizeof(struct extendedFileEntry), inode->i_sb->s_blocksize - sizeof(struct extendedFileEntry));
1030*1da177e4SLinus Torvalds 	}
1031*1da177e4SLinus Torvalds 	else if (le16_to_cpu(fe->descTag.tagIdent) == TAG_IDENT_FE)
1032*1da177e4SLinus Torvalds 	{
1033*1da177e4SLinus Torvalds 		UDF_I_EFE(inode) = 0;
1034*1da177e4SLinus Torvalds 		UDF_I_USE(inode) = 0;
1035*1da177e4SLinus Torvalds 		UDF_I_DATA(inode) = kmalloc(inode->i_sb->s_blocksize - sizeof(struct fileEntry), GFP_KERNEL);
1036*1da177e4SLinus Torvalds 		memcpy(UDF_I_DATA(inode), bh->b_data + sizeof(struct fileEntry), inode->i_sb->s_blocksize - sizeof(struct fileEntry));
1037*1da177e4SLinus Torvalds 	}
1038*1da177e4SLinus Torvalds 	else if (le16_to_cpu(fe->descTag.tagIdent) == TAG_IDENT_USE)
1039*1da177e4SLinus Torvalds 	{
1040*1da177e4SLinus Torvalds 		UDF_I_EFE(inode) = 0;
1041*1da177e4SLinus Torvalds 		UDF_I_USE(inode) = 1;
1042*1da177e4SLinus Torvalds 		UDF_I_LENALLOC(inode) =
1043*1da177e4SLinus Torvalds 			le32_to_cpu(
1044*1da177e4SLinus Torvalds 				((struct unallocSpaceEntry *)bh->b_data)->lengthAllocDescs);
1045*1da177e4SLinus Torvalds 		UDF_I_DATA(inode) = kmalloc(inode->i_sb->s_blocksize - sizeof(struct unallocSpaceEntry), GFP_KERNEL);
1046*1da177e4SLinus Torvalds 		memcpy(UDF_I_DATA(inode), bh->b_data + sizeof(struct unallocSpaceEntry), inode->i_sb->s_blocksize - sizeof(struct unallocSpaceEntry));
1047*1da177e4SLinus Torvalds 		return;
1048*1da177e4SLinus Torvalds 	}
1049*1da177e4SLinus Torvalds 
1050*1da177e4SLinus Torvalds 	inode->i_uid = le32_to_cpu(fe->uid);
1051*1da177e4SLinus Torvalds 	if ( inode->i_uid == -1 ) inode->i_uid = UDF_SB(inode->i_sb)->s_uid;
1052*1da177e4SLinus Torvalds 
1053*1da177e4SLinus Torvalds 	inode->i_gid = le32_to_cpu(fe->gid);
1054*1da177e4SLinus Torvalds 	if ( inode->i_gid == -1 ) inode->i_gid = UDF_SB(inode->i_sb)->s_gid;
1055*1da177e4SLinus Torvalds 
1056*1da177e4SLinus Torvalds 	inode->i_nlink = le16_to_cpu(fe->fileLinkCount);
1057*1da177e4SLinus Torvalds 	if (!inode->i_nlink)
1058*1da177e4SLinus Torvalds 		inode->i_nlink = 1;
1059*1da177e4SLinus Torvalds 
1060*1da177e4SLinus Torvalds 	inode->i_size = le64_to_cpu(fe->informationLength);
1061*1da177e4SLinus Torvalds 	UDF_I_LENEXTENTS(inode) = inode->i_size;
1062*1da177e4SLinus Torvalds 
1063*1da177e4SLinus Torvalds 	inode->i_mode = udf_convert_permissions(fe);
1064*1da177e4SLinus Torvalds 	inode->i_mode &= ~UDF_SB(inode->i_sb)->s_umask;
1065*1da177e4SLinus Torvalds 
1066*1da177e4SLinus Torvalds 	if (UDF_I_EFE(inode) == 0)
1067*1da177e4SLinus Torvalds 	{
1068*1da177e4SLinus Torvalds 		inode->i_blocks = le64_to_cpu(fe->logicalBlocksRecorded) <<
1069*1da177e4SLinus Torvalds 			(inode->i_sb->s_blocksize_bits - 9);
1070*1da177e4SLinus Torvalds 
1071*1da177e4SLinus Torvalds 		if ( udf_stamp_to_time(&convtime, &convtime_usec,
1072*1da177e4SLinus Torvalds 			lets_to_cpu(fe->accessTime)) )
1073*1da177e4SLinus Torvalds 		{
1074*1da177e4SLinus Torvalds 			inode->i_atime.tv_sec = convtime;
1075*1da177e4SLinus Torvalds 			inode->i_atime.tv_nsec = convtime_usec * 1000;
1076*1da177e4SLinus Torvalds 		}
1077*1da177e4SLinus Torvalds 		else
1078*1da177e4SLinus Torvalds 		{
1079*1da177e4SLinus Torvalds 			inode->i_atime = UDF_SB_RECORDTIME(inode->i_sb);
1080*1da177e4SLinus Torvalds 		}
1081*1da177e4SLinus Torvalds 
1082*1da177e4SLinus Torvalds 		if ( udf_stamp_to_time(&convtime, &convtime_usec,
1083*1da177e4SLinus Torvalds 			lets_to_cpu(fe->modificationTime)) )
1084*1da177e4SLinus Torvalds 		{
1085*1da177e4SLinus Torvalds 			inode->i_mtime.tv_sec = convtime;
1086*1da177e4SLinus Torvalds 			inode->i_mtime.tv_nsec = convtime_usec * 1000;
1087*1da177e4SLinus Torvalds 		}
1088*1da177e4SLinus Torvalds 		else
1089*1da177e4SLinus Torvalds 		{
1090*1da177e4SLinus Torvalds 			inode->i_mtime = UDF_SB_RECORDTIME(inode->i_sb);
1091*1da177e4SLinus Torvalds 		}
1092*1da177e4SLinus Torvalds 
1093*1da177e4SLinus Torvalds 		if ( udf_stamp_to_time(&convtime, &convtime_usec,
1094*1da177e4SLinus Torvalds 			lets_to_cpu(fe->attrTime)) )
1095*1da177e4SLinus Torvalds 		{
1096*1da177e4SLinus Torvalds 			inode->i_ctime.tv_sec = convtime;
1097*1da177e4SLinus Torvalds 			inode->i_ctime.tv_nsec = convtime_usec * 1000;
1098*1da177e4SLinus Torvalds 		}
1099*1da177e4SLinus Torvalds 		else
1100*1da177e4SLinus Torvalds 		{
1101*1da177e4SLinus Torvalds 			inode->i_ctime = UDF_SB_RECORDTIME(inode->i_sb);
1102*1da177e4SLinus Torvalds 		}
1103*1da177e4SLinus Torvalds 
1104*1da177e4SLinus Torvalds 		UDF_I_UNIQUE(inode) = le64_to_cpu(fe->uniqueID);
1105*1da177e4SLinus Torvalds 		UDF_I_LENEATTR(inode) = le32_to_cpu(fe->lengthExtendedAttr);
1106*1da177e4SLinus Torvalds 		UDF_I_LENALLOC(inode) = le32_to_cpu(fe->lengthAllocDescs);
1107*1da177e4SLinus Torvalds 		offset = sizeof(struct fileEntry) + UDF_I_LENEATTR(inode);
1108*1da177e4SLinus Torvalds 	}
1109*1da177e4SLinus Torvalds 	else
1110*1da177e4SLinus Torvalds 	{
1111*1da177e4SLinus Torvalds 		inode->i_blocks = le64_to_cpu(efe->logicalBlocksRecorded) <<
1112*1da177e4SLinus Torvalds 			(inode->i_sb->s_blocksize_bits - 9);
1113*1da177e4SLinus Torvalds 
1114*1da177e4SLinus Torvalds 		if ( udf_stamp_to_time(&convtime, &convtime_usec,
1115*1da177e4SLinus Torvalds 			lets_to_cpu(efe->accessTime)) )
1116*1da177e4SLinus Torvalds 		{
1117*1da177e4SLinus Torvalds 			inode->i_atime.tv_sec = convtime;
1118*1da177e4SLinus Torvalds 			inode->i_atime.tv_nsec = convtime_usec * 1000;
1119*1da177e4SLinus Torvalds 		}
1120*1da177e4SLinus Torvalds 		else
1121*1da177e4SLinus Torvalds 		{
1122*1da177e4SLinus Torvalds 			inode->i_atime = UDF_SB_RECORDTIME(inode->i_sb);
1123*1da177e4SLinus Torvalds 		}
1124*1da177e4SLinus Torvalds 
1125*1da177e4SLinus Torvalds 		if ( udf_stamp_to_time(&convtime, &convtime_usec,
1126*1da177e4SLinus Torvalds 			lets_to_cpu(efe->modificationTime)) )
1127*1da177e4SLinus Torvalds 		{
1128*1da177e4SLinus Torvalds 			inode->i_mtime.tv_sec = convtime;
1129*1da177e4SLinus Torvalds 			inode->i_mtime.tv_nsec = convtime_usec * 1000;
1130*1da177e4SLinus Torvalds 		}
1131*1da177e4SLinus Torvalds 		else
1132*1da177e4SLinus Torvalds 		{
1133*1da177e4SLinus Torvalds 			inode->i_mtime = UDF_SB_RECORDTIME(inode->i_sb);
1134*1da177e4SLinus Torvalds 		}
1135*1da177e4SLinus Torvalds 
1136*1da177e4SLinus Torvalds 		if ( udf_stamp_to_time(&convtime, &convtime_usec,
1137*1da177e4SLinus Torvalds 			lets_to_cpu(efe->createTime)) )
1138*1da177e4SLinus Torvalds 		{
1139*1da177e4SLinus Torvalds 			UDF_I_CRTIME(inode).tv_sec = convtime;
1140*1da177e4SLinus Torvalds 			UDF_I_CRTIME(inode).tv_nsec = convtime_usec * 1000;
1141*1da177e4SLinus Torvalds 		}
1142*1da177e4SLinus Torvalds 		else
1143*1da177e4SLinus Torvalds 		{
1144*1da177e4SLinus Torvalds 			UDF_I_CRTIME(inode) = UDF_SB_RECORDTIME(inode->i_sb);
1145*1da177e4SLinus Torvalds 		}
1146*1da177e4SLinus Torvalds 
1147*1da177e4SLinus Torvalds 		if ( udf_stamp_to_time(&convtime, &convtime_usec,
1148*1da177e4SLinus Torvalds 			lets_to_cpu(efe->attrTime)) )
1149*1da177e4SLinus Torvalds 		{
1150*1da177e4SLinus Torvalds 			inode->i_ctime.tv_sec = convtime;
1151*1da177e4SLinus Torvalds 			inode->i_ctime.tv_nsec = convtime_usec * 1000;
1152*1da177e4SLinus Torvalds 		}
1153*1da177e4SLinus Torvalds 		else
1154*1da177e4SLinus Torvalds 		{
1155*1da177e4SLinus Torvalds 			inode->i_ctime = UDF_SB_RECORDTIME(inode->i_sb);
1156*1da177e4SLinus Torvalds 		}
1157*1da177e4SLinus Torvalds 
1158*1da177e4SLinus Torvalds 		UDF_I_UNIQUE(inode) = le64_to_cpu(efe->uniqueID);
1159*1da177e4SLinus Torvalds 		UDF_I_LENEATTR(inode) = le32_to_cpu(efe->lengthExtendedAttr);
1160*1da177e4SLinus Torvalds 		UDF_I_LENALLOC(inode) = le32_to_cpu(efe->lengthAllocDescs);
1161*1da177e4SLinus Torvalds 		offset = sizeof(struct extendedFileEntry) + UDF_I_LENEATTR(inode);
1162*1da177e4SLinus Torvalds 	}
1163*1da177e4SLinus Torvalds 
1164*1da177e4SLinus Torvalds 	switch (fe->icbTag.fileType)
1165*1da177e4SLinus Torvalds 	{
1166*1da177e4SLinus Torvalds 		case ICBTAG_FILE_TYPE_DIRECTORY:
1167*1da177e4SLinus Torvalds 		{
1168*1da177e4SLinus Torvalds 			inode->i_op = &udf_dir_inode_operations;
1169*1da177e4SLinus Torvalds 			inode->i_fop = &udf_dir_operations;
1170*1da177e4SLinus Torvalds 			inode->i_mode |= S_IFDIR;
1171*1da177e4SLinus Torvalds 			inode->i_nlink ++;
1172*1da177e4SLinus Torvalds 			break;
1173*1da177e4SLinus Torvalds 		}
1174*1da177e4SLinus Torvalds 		case ICBTAG_FILE_TYPE_REALTIME:
1175*1da177e4SLinus Torvalds 		case ICBTAG_FILE_TYPE_REGULAR:
1176*1da177e4SLinus Torvalds 		case ICBTAG_FILE_TYPE_UNDEF:
1177*1da177e4SLinus Torvalds 		{
1178*1da177e4SLinus Torvalds 			if (UDF_I_ALLOCTYPE(inode) == ICBTAG_FLAG_AD_IN_ICB)
1179*1da177e4SLinus Torvalds 				inode->i_data.a_ops = &udf_adinicb_aops;
1180*1da177e4SLinus Torvalds 			else
1181*1da177e4SLinus Torvalds 				inode->i_data.a_ops = &udf_aops;
1182*1da177e4SLinus Torvalds 			inode->i_op = &udf_file_inode_operations;
1183*1da177e4SLinus Torvalds 			inode->i_fop = &udf_file_operations;
1184*1da177e4SLinus Torvalds 			inode->i_mode |= S_IFREG;
1185*1da177e4SLinus Torvalds 			break;
1186*1da177e4SLinus Torvalds 		}
1187*1da177e4SLinus Torvalds 		case ICBTAG_FILE_TYPE_BLOCK:
1188*1da177e4SLinus Torvalds 		{
1189*1da177e4SLinus Torvalds 			inode->i_mode |= S_IFBLK;
1190*1da177e4SLinus Torvalds 			break;
1191*1da177e4SLinus Torvalds 		}
1192*1da177e4SLinus Torvalds 		case ICBTAG_FILE_TYPE_CHAR:
1193*1da177e4SLinus Torvalds 		{
1194*1da177e4SLinus Torvalds 			inode->i_mode |= S_IFCHR;
1195*1da177e4SLinus Torvalds 			break;
1196*1da177e4SLinus Torvalds 		}
1197*1da177e4SLinus Torvalds 		case ICBTAG_FILE_TYPE_FIFO:
1198*1da177e4SLinus Torvalds 		{
1199*1da177e4SLinus Torvalds 			init_special_inode(inode, inode->i_mode | S_IFIFO, 0);
1200*1da177e4SLinus Torvalds 			break;
1201*1da177e4SLinus Torvalds 		}
1202*1da177e4SLinus Torvalds 		case ICBTAG_FILE_TYPE_SOCKET:
1203*1da177e4SLinus Torvalds 		{
1204*1da177e4SLinus Torvalds 			init_special_inode(inode, inode->i_mode | S_IFSOCK, 0);
1205*1da177e4SLinus Torvalds 			break;
1206*1da177e4SLinus Torvalds 		}
1207*1da177e4SLinus Torvalds 		case ICBTAG_FILE_TYPE_SYMLINK:
1208*1da177e4SLinus Torvalds 		{
1209*1da177e4SLinus Torvalds 			inode->i_data.a_ops = &udf_symlink_aops;
1210*1da177e4SLinus Torvalds 			inode->i_op = &page_symlink_inode_operations;
1211*1da177e4SLinus Torvalds 			inode->i_mode = S_IFLNK|S_IRWXUGO;
1212*1da177e4SLinus Torvalds 			break;
1213*1da177e4SLinus Torvalds 		}
1214*1da177e4SLinus Torvalds 		default:
1215*1da177e4SLinus Torvalds 		{
1216*1da177e4SLinus Torvalds 			printk(KERN_ERR "udf: udf_fill_inode(ino %ld) failed unknown file type=%d\n",
1217*1da177e4SLinus Torvalds 				inode->i_ino, fe->icbTag.fileType);
1218*1da177e4SLinus Torvalds 			make_bad_inode(inode);
1219*1da177e4SLinus Torvalds 			return;
1220*1da177e4SLinus Torvalds 		}
1221*1da177e4SLinus Torvalds 	}
1222*1da177e4SLinus Torvalds 	if (S_ISCHR(inode->i_mode) || S_ISBLK(inode->i_mode))
1223*1da177e4SLinus Torvalds 	{
1224*1da177e4SLinus Torvalds 		struct deviceSpec *dsea =
1225*1da177e4SLinus Torvalds 			(struct deviceSpec *)
1226*1da177e4SLinus Torvalds 				udf_get_extendedattr(inode, 12, 1);
1227*1da177e4SLinus Torvalds 
1228*1da177e4SLinus Torvalds 		if (dsea)
1229*1da177e4SLinus Torvalds 		{
1230*1da177e4SLinus Torvalds 			init_special_inode(inode, inode->i_mode, MKDEV(
1231*1da177e4SLinus Torvalds 				le32_to_cpu(dsea->majorDeviceIdent),
1232*1da177e4SLinus Torvalds 				le32_to_cpu(dsea->minorDeviceIdent)));
1233*1da177e4SLinus Torvalds 			/* Developer ID ??? */
1234*1da177e4SLinus Torvalds 		}
1235*1da177e4SLinus Torvalds 		else
1236*1da177e4SLinus Torvalds 		{
1237*1da177e4SLinus Torvalds 			make_bad_inode(inode);
1238*1da177e4SLinus Torvalds 		}
1239*1da177e4SLinus Torvalds 	}
1240*1da177e4SLinus Torvalds }
1241*1da177e4SLinus Torvalds 
1242*1da177e4SLinus Torvalds static mode_t
1243*1da177e4SLinus Torvalds udf_convert_permissions(struct fileEntry *fe)
1244*1da177e4SLinus Torvalds {
1245*1da177e4SLinus Torvalds 	mode_t mode;
1246*1da177e4SLinus Torvalds 	uint32_t permissions;
1247*1da177e4SLinus Torvalds 	uint32_t flags;
1248*1da177e4SLinus Torvalds 
1249*1da177e4SLinus Torvalds 	permissions = le32_to_cpu(fe->permissions);
1250*1da177e4SLinus Torvalds 	flags = le16_to_cpu(fe->icbTag.flags);
1251*1da177e4SLinus Torvalds 
1252*1da177e4SLinus Torvalds 	mode =	(( permissions      ) & S_IRWXO) |
1253*1da177e4SLinus Torvalds 		(( permissions >> 2 ) & S_IRWXG) |
1254*1da177e4SLinus Torvalds 		(( permissions >> 4 ) & S_IRWXU) |
1255*1da177e4SLinus Torvalds 		(( flags & ICBTAG_FLAG_SETUID) ? S_ISUID : 0) |
1256*1da177e4SLinus Torvalds 		(( flags & ICBTAG_FLAG_SETGID) ? S_ISGID : 0) |
1257*1da177e4SLinus Torvalds 		(( flags & ICBTAG_FLAG_STICKY) ? S_ISVTX : 0);
1258*1da177e4SLinus Torvalds 
1259*1da177e4SLinus Torvalds 	return mode;
1260*1da177e4SLinus Torvalds }
1261*1da177e4SLinus Torvalds 
1262*1da177e4SLinus Torvalds /*
1263*1da177e4SLinus Torvalds  * udf_write_inode
1264*1da177e4SLinus Torvalds  *
1265*1da177e4SLinus Torvalds  * PURPOSE
1266*1da177e4SLinus Torvalds  *	Write out the specified inode.
1267*1da177e4SLinus Torvalds  *
1268*1da177e4SLinus Torvalds  * DESCRIPTION
1269*1da177e4SLinus Torvalds  *	This routine is called whenever an inode is synced.
1270*1da177e4SLinus Torvalds  *	Currently this routine is just a placeholder.
1271*1da177e4SLinus Torvalds  *
1272*1da177e4SLinus Torvalds  * HISTORY
1273*1da177e4SLinus Torvalds  *	July 1, 1997 - Andrew E. Mileski
1274*1da177e4SLinus Torvalds  *	Written, tested, and released.
1275*1da177e4SLinus Torvalds  */
1276*1da177e4SLinus Torvalds 
1277*1da177e4SLinus Torvalds int udf_write_inode(struct inode * inode, int sync)
1278*1da177e4SLinus Torvalds {
1279*1da177e4SLinus Torvalds 	int ret;
1280*1da177e4SLinus Torvalds 	lock_kernel();
1281*1da177e4SLinus Torvalds 	ret = udf_update_inode(inode, sync);
1282*1da177e4SLinus Torvalds 	unlock_kernel();
1283*1da177e4SLinus Torvalds 	return ret;
1284*1da177e4SLinus Torvalds }
1285*1da177e4SLinus Torvalds 
1286*1da177e4SLinus Torvalds int udf_sync_inode(struct inode * inode)
1287*1da177e4SLinus Torvalds {
1288*1da177e4SLinus Torvalds 	return udf_update_inode(inode, 1);
1289*1da177e4SLinus Torvalds }
1290*1da177e4SLinus Torvalds 
1291*1da177e4SLinus Torvalds static int
1292*1da177e4SLinus Torvalds udf_update_inode(struct inode *inode, int do_sync)
1293*1da177e4SLinus Torvalds {
1294*1da177e4SLinus Torvalds 	struct buffer_head *bh = NULL;
1295*1da177e4SLinus Torvalds 	struct fileEntry *fe;
1296*1da177e4SLinus Torvalds 	struct extendedFileEntry *efe;
1297*1da177e4SLinus Torvalds 	uint32_t udfperms;
1298*1da177e4SLinus Torvalds 	uint16_t icbflags;
1299*1da177e4SLinus Torvalds 	uint16_t crclen;
1300*1da177e4SLinus Torvalds 	int i;
1301*1da177e4SLinus Torvalds 	kernel_timestamp cpu_time;
1302*1da177e4SLinus Torvalds 	int err = 0;
1303*1da177e4SLinus Torvalds 
1304*1da177e4SLinus Torvalds 	bh = udf_tread(inode->i_sb,
1305*1da177e4SLinus Torvalds 		udf_get_lb_pblock(inode->i_sb, UDF_I_LOCATION(inode), 0));
1306*1da177e4SLinus Torvalds 
1307*1da177e4SLinus Torvalds 	if (!bh)
1308*1da177e4SLinus Torvalds 	{
1309*1da177e4SLinus Torvalds 		udf_debug("bread failure\n");
1310*1da177e4SLinus Torvalds 		return -EIO;
1311*1da177e4SLinus Torvalds 	}
1312*1da177e4SLinus Torvalds 
1313*1da177e4SLinus Torvalds 	memset(bh->b_data, 0x00, inode->i_sb->s_blocksize);
1314*1da177e4SLinus Torvalds 
1315*1da177e4SLinus Torvalds 	fe = (struct fileEntry *)bh->b_data;
1316*1da177e4SLinus Torvalds 	efe = (struct extendedFileEntry *)bh->b_data;
1317*1da177e4SLinus Torvalds 
1318*1da177e4SLinus Torvalds 	if (le16_to_cpu(fe->descTag.tagIdent) == TAG_IDENT_USE)
1319*1da177e4SLinus Torvalds 	{
1320*1da177e4SLinus Torvalds 		struct unallocSpaceEntry *use =
1321*1da177e4SLinus Torvalds 			(struct unallocSpaceEntry *)bh->b_data;
1322*1da177e4SLinus Torvalds 
1323*1da177e4SLinus Torvalds 		use->lengthAllocDescs = cpu_to_le32(UDF_I_LENALLOC(inode));
1324*1da177e4SLinus Torvalds 		memcpy(bh->b_data + sizeof(struct unallocSpaceEntry), UDF_I_DATA(inode), inode->i_sb->s_blocksize - sizeof(struct unallocSpaceEntry));
1325*1da177e4SLinus Torvalds 		crclen = sizeof(struct unallocSpaceEntry) + UDF_I_LENALLOC(inode) -
1326*1da177e4SLinus Torvalds 			sizeof(tag);
1327*1da177e4SLinus Torvalds 		use->descTag.tagLocation = cpu_to_le32(UDF_I_LOCATION(inode).logicalBlockNum);
1328*1da177e4SLinus Torvalds 		use->descTag.descCRCLength = cpu_to_le16(crclen);
1329*1da177e4SLinus Torvalds 		use->descTag.descCRC = cpu_to_le16(udf_crc((char *)use + sizeof(tag), crclen, 0));
1330*1da177e4SLinus Torvalds 
1331*1da177e4SLinus Torvalds 		use->descTag.tagChecksum = 0;
1332*1da177e4SLinus Torvalds 		for (i=0; i<16; i++)
1333*1da177e4SLinus Torvalds 			if (i != 4)
1334*1da177e4SLinus Torvalds 				use->descTag.tagChecksum += ((uint8_t *)&(use->descTag))[i];
1335*1da177e4SLinus Torvalds 
1336*1da177e4SLinus Torvalds 		mark_buffer_dirty(bh);
1337*1da177e4SLinus Torvalds 		udf_release_data(bh);
1338*1da177e4SLinus Torvalds 		return err;
1339*1da177e4SLinus Torvalds 	}
1340*1da177e4SLinus Torvalds 
1341*1da177e4SLinus Torvalds 	if (inode->i_uid != UDF_SB(inode->i_sb)->s_uid)
1342*1da177e4SLinus Torvalds 		fe->uid = cpu_to_le32(inode->i_uid);
1343*1da177e4SLinus Torvalds 
1344*1da177e4SLinus Torvalds 	if (inode->i_gid != UDF_SB(inode->i_sb)->s_gid)
1345*1da177e4SLinus Torvalds 		fe->gid = cpu_to_le32(inode->i_gid);
1346*1da177e4SLinus Torvalds 
1347*1da177e4SLinus Torvalds 	udfperms =	((inode->i_mode & S_IRWXO)     ) |
1348*1da177e4SLinus Torvalds 			((inode->i_mode & S_IRWXG) << 2) |
1349*1da177e4SLinus Torvalds 			((inode->i_mode & S_IRWXU) << 4);
1350*1da177e4SLinus Torvalds 
1351*1da177e4SLinus Torvalds 	udfperms |=	(le32_to_cpu(fe->permissions) &
1352*1da177e4SLinus Torvalds 			(FE_PERM_O_DELETE | FE_PERM_O_CHATTR |
1353*1da177e4SLinus Torvalds 			 FE_PERM_G_DELETE | FE_PERM_G_CHATTR |
1354*1da177e4SLinus Torvalds 			 FE_PERM_U_DELETE | FE_PERM_U_CHATTR));
1355*1da177e4SLinus Torvalds 	fe->permissions = cpu_to_le32(udfperms);
1356*1da177e4SLinus Torvalds 
1357*1da177e4SLinus Torvalds 	if (S_ISDIR(inode->i_mode))
1358*1da177e4SLinus Torvalds 		fe->fileLinkCount = cpu_to_le16(inode->i_nlink - 1);
1359*1da177e4SLinus Torvalds 	else
1360*1da177e4SLinus Torvalds 		fe->fileLinkCount = cpu_to_le16(inode->i_nlink);
1361*1da177e4SLinus Torvalds 
1362*1da177e4SLinus Torvalds 	fe->informationLength = cpu_to_le64(inode->i_size);
1363*1da177e4SLinus Torvalds 
1364*1da177e4SLinus Torvalds 	if (S_ISCHR(inode->i_mode) || S_ISBLK(inode->i_mode))
1365*1da177e4SLinus Torvalds 	{
1366*1da177e4SLinus Torvalds 		regid *eid;
1367*1da177e4SLinus Torvalds 		struct deviceSpec *dsea =
1368*1da177e4SLinus Torvalds 			(struct deviceSpec *)
1369*1da177e4SLinus Torvalds 				udf_get_extendedattr(inode, 12, 1);
1370*1da177e4SLinus Torvalds 
1371*1da177e4SLinus Torvalds 		if (!dsea)
1372*1da177e4SLinus Torvalds 		{
1373*1da177e4SLinus Torvalds 			dsea = (struct deviceSpec *)
1374*1da177e4SLinus Torvalds 				udf_add_extendedattr(inode,
1375*1da177e4SLinus Torvalds 					sizeof(struct deviceSpec) +
1376*1da177e4SLinus Torvalds 					sizeof(regid), 12, 0x3);
1377*1da177e4SLinus Torvalds 			dsea->attrType = cpu_to_le32(12);
1378*1da177e4SLinus Torvalds 			dsea->attrSubtype = 1;
1379*1da177e4SLinus Torvalds 			dsea->attrLength = cpu_to_le32(sizeof(struct deviceSpec) +
1380*1da177e4SLinus Torvalds 				sizeof(regid));
1381*1da177e4SLinus Torvalds 			dsea->impUseLength = cpu_to_le32(sizeof(regid));
1382*1da177e4SLinus Torvalds 		}
1383*1da177e4SLinus Torvalds 		eid = (regid *)dsea->impUse;
1384*1da177e4SLinus Torvalds 		memset(eid, 0, sizeof(regid));
1385*1da177e4SLinus Torvalds 		strcpy(eid->ident, UDF_ID_DEVELOPER);
1386*1da177e4SLinus Torvalds 		eid->identSuffix[0] = UDF_OS_CLASS_UNIX;
1387*1da177e4SLinus Torvalds 		eid->identSuffix[1] = UDF_OS_ID_LINUX;
1388*1da177e4SLinus Torvalds 		dsea->majorDeviceIdent = cpu_to_le32(imajor(inode));
1389*1da177e4SLinus Torvalds 		dsea->minorDeviceIdent = cpu_to_le32(iminor(inode));
1390*1da177e4SLinus Torvalds 	}
1391*1da177e4SLinus Torvalds 
1392*1da177e4SLinus Torvalds 	if (UDF_I_EFE(inode) == 0)
1393*1da177e4SLinus Torvalds 	{
1394*1da177e4SLinus Torvalds 		memcpy(bh->b_data + sizeof(struct fileEntry), UDF_I_DATA(inode), inode->i_sb->s_blocksize - sizeof(struct fileEntry));
1395*1da177e4SLinus Torvalds 		fe->logicalBlocksRecorded = cpu_to_le64(
1396*1da177e4SLinus Torvalds 			(inode->i_blocks + (1 << (inode->i_sb->s_blocksize_bits - 9)) - 1) >>
1397*1da177e4SLinus Torvalds 			(inode->i_sb->s_blocksize_bits - 9));
1398*1da177e4SLinus Torvalds 
1399*1da177e4SLinus Torvalds 		if (udf_time_to_stamp(&cpu_time, inode->i_atime))
1400*1da177e4SLinus Torvalds 			fe->accessTime = cpu_to_lets(cpu_time);
1401*1da177e4SLinus Torvalds 		if (udf_time_to_stamp(&cpu_time, inode->i_mtime))
1402*1da177e4SLinus Torvalds 			fe->modificationTime = cpu_to_lets(cpu_time);
1403*1da177e4SLinus Torvalds 		if (udf_time_to_stamp(&cpu_time, inode->i_ctime))
1404*1da177e4SLinus Torvalds 			fe->attrTime = cpu_to_lets(cpu_time);
1405*1da177e4SLinus Torvalds 		memset(&(fe->impIdent), 0, sizeof(regid));
1406*1da177e4SLinus Torvalds 		strcpy(fe->impIdent.ident, UDF_ID_DEVELOPER);
1407*1da177e4SLinus Torvalds 		fe->impIdent.identSuffix[0] = UDF_OS_CLASS_UNIX;
1408*1da177e4SLinus Torvalds 		fe->impIdent.identSuffix[1] = UDF_OS_ID_LINUX;
1409*1da177e4SLinus Torvalds 		fe->uniqueID = cpu_to_le64(UDF_I_UNIQUE(inode));
1410*1da177e4SLinus Torvalds 		fe->lengthExtendedAttr = cpu_to_le32(UDF_I_LENEATTR(inode));
1411*1da177e4SLinus Torvalds 		fe->lengthAllocDescs = cpu_to_le32(UDF_I_LENALLOC(inode));
1412*1da177e4SLinus Torvalds 		fe->descTag.tagIdent = cpu_to_le16(TAG_IDENT_FE);
1413*1da177e4SLinus Torvalds 		crclen = sizeof(struct fileEntry);
1414*1da177e4SLinus Torvalds 	}
1415*1da177e4SLinus Torvalds 	else
1416*1da177e4SLinus Torvalds 	{
1417*1da177e4SLinus Torvalds 		memcpy(bh->b_data + sizeof(struct extendedFileEntry), UDF_I_DATA(inode), inode->i_sb->s_blocksize - sizeof(struct extendedFileEntry));
1418*1da177e4SLinus Torvalds 		efe->objectSize = cpu_to_le64(inode->i_size);
1419*1da177e4SLinus Torvalds 		efe->logicalBlocksRecorded = cpu_to_le64(
1420*1da177e4SLinus Torvalds 			(inode->i_blocks + (1 << (inode->i_sb->s_blocksize_bits - 9)) - 1) >>
1421*1da177e4SLinus Torvalds 			(inode->i_sb->s_blocksize_bits - 9));
1422*1da177e4SLinus Torvalds 
1423*1da177e4SLinus Torvalds 		if (UDF_I_CRTIME(inode).tv_sec > inode->i_atime.tv_sec ||
1424*1da177e4SLinus Torvalds 			(UDF_I_CRTIME(inode).tv_sec == inode->i_atime.tv_sec &&
1425*1da177e4SLinus Torvalds 			 UDF_I_CRTIME(inode).tv_nsec > inode->i_atime.tv_nsec))
1426*1da177e4SLinus Torvalds 		{
1427*1da177e4SLinus Torvalds 			UDF_I_CRTIME(inode) = inode->i_atime;
1428*1da177e4SLinus Torvalds 		}
1429*1da177e4SLinus Torvalds 		if (UDF_I_CRTIME(inode).tv_sec > inode->i_mtime.tv_sec ||
1430*1da177e4SLinus Torvalds 			(UDF_I_CRTIME(inode).tv_sec == inode->i_mtime.tv_sec &&
1431*1da177e4SLinus Torvalds 			 UDF_I_CRTIME(inode).tv_nsec > inode->i_mtime.tv_nsec))
1432*1da177e4SLinus Torvalds 		{
1433*1da177e4SLinus Torvalds 			UDF_I_CRTIME(inode) = inode->i_mtime;
1434*1da177e4SLinus Torvalds 		}
1435*1da177e4SLinus Torvalds 		if (UDF_I_CRTIME(inode).tv_sec > inode->i_ctime.tv_sec ||
1436*1da177e4SLinus Torvalds 			(UDF_I_CRTIME(inode).tv_sec == inode->i_ctime.tv_sec &&
1437*1da177e4SLinus Torvalds 			 UDF_I_CRTIME(inode).tv_nsec > inode->i_ctime.tv_nsec))
1438*1da177e4SLinus Torvalds 		{
1439*1da177e4SLinus Torvalds 			UDF_I_CRTIME(inode) = inode->i_ctime;
1440*1da177e4SLinus Torvalds 		}
1441*1da177e4SLinus Torvalds 
1442*1da177e4SLinus Torvalds 		if (udf_time_to_stamp(&cpu_time, inode->i_atime))
1443*1da177e4SLinus Torvalds 			efe->accessTime = cpu_to_lets(cpu_time);
1444*1da177e4SLinus Torvalds 		if (udf_time_to_stamp(&cpu_time, inode->i_mtime))
1445*1da177e4SLinus Torvalds 			efe->modificationTime = cpu_to_lets(cpu_time);
1446*1da177e4SLinus Torvalds 		if (udf_time_to_stamp(&cpu_time, UDF_I_CRTIME(inode)))
1447*1da177e4SLinus Torvalds 			efe->createTime = cpu_to_lets(cpu_time);
1448*1da177e4SLinus Torvalds 		if (udf_time_to_stamp(&cpu_time, inode->i_ctime))
1449*1da177e4SLinus Torvalds 			efe->attrTime = cpu_to_lets(cpu_time);
1450*1da177e4SLinus Torvalds 
1451*1da177e4SLinus Torvalds 		memset(&(efe->impIdent), 0, sizeof(regid));
1452*1da177e4SLinus Torvalds 		strcpy(efe->impIdent.ident, UDF_ID_DEVELOPER);
1453*1da177e4SLinus Torvalds 		efe->impIdent.identSuffix[0] = UDF_OS_CLASS_UNIX;
1454*1da177e4SLinus Torvalds 		efe->impIdent.identSuffix[1] = UDF_OS_ID_LINUX;
1455*1da177e4SLinus Torvalds 		efe->uniqueID = cpu_to_le64(UDF_I_UNIQUE(inode));
1456*1da177e4SLinus Torvalds 		efe->lengthExtendedAttr = cpu_to_le32(UDF_I_LENEATTR(inode));
1457*1da177e4SLinus Torvalds 		efe->lengthAllocDescs = cpu_to_le32(UDF_I_LENALLOC(inode));
1458*1da177e4SLinus Torvalds 		efe->descTag.tagIdent = cpu_to_le16(TAG_IDENT_EFE);
1459*1da177e4SLinus Torvalds 		crclen = sizeof(struct extendedFileEntry);
1460*1da177e4SLinus Torvalds 	}
1461*1da177e4SLinus Torvalds 	if (UDF_I_STRAT4096(inode))
1462*1da177e4SLinus Torvalds 	{
1463*1da177e4SLinus Torvalds 		fe->icbTag.strategyType = cpu_to_le16(4096);
1464*1da177e4SLinus Torvalds 		fe->icbTag.strategyParameter = cpu_to_le16(1);
1465*1da177e4SLinus Torvalds 		fe->icbTag.numEntries = cpu_to_le16(2);
1466*1da177e4SLinus Torvalds 	}
1467*1da177e4SLinus Torvalds 	else
1468*1da177e4SLinus Torvalds 	{
1469*1da177e4SLinus Torvalds 		fe->icbTag.strategyType = cpu_to_le16(4);
1470*1da177e4SLinus Torvalds 		fe->icbTag.numEntries = cpu_to_le16(1);
1471*1da177e4SLinus Torvalds 	}
1472*1da177e4SLinus Torvalds 
1473*1da177e4SLinus Torvalds 	if (S_ISDIR(inode->i_mode))
1474*1da177e4SLinus Torvalds 		fe->icbTag.fileType = ICBTAG_FILE_TYPE_DIRECTORY;
1475*1da177e4SLinus Torvalds 	else if (S_ISREG(inode->i_mode))
1476*1da177e4SLinus Torvalds 		fe->icbTag.fileType = ICBTAG_FILE_TYPE_REGULAR;
1477*1da177e4SLinus Torvalds 	else if (S_ISLNK(inode->i_mode))
1478*1da177e4SLinus Torvalds 		fe->icbTag.fileType = ICBTAG_FILE_TYPE_SYMLINK;
1479*1da177e4SLinus Torvalds 	else if (S_ISBLK(inode->i_mode))
1480*1da177e4SLinus Torvalds 		fe->icbTag.fileType = ICBTAG_FILE_TYPE_BLOCK;
1481*1da177e4SLinus Torvalds 	else if (S_ISCHR(inode->i_mode))
1482*1da177e4SLinus Torvalds 		fe->icbTag.fileType = ICBTAG_FILE_TYPE_CHAR;
1483*1da177e4SLinus Torvalds 	else if (S_ISFIFO(inode->i_mode))
1484*1da177e4SLinus Torvalds 		fe->icbTag.fileType = ICBTAG_FILE_TYPE_FIFO;
1485*1da177e4SLinus Torvalds 	else if (S_ISSOCK(inode->i_mode))
1486*1da177e4SLinus Torvalds 		fe->icbTag.fileType = ICBTAG_FILE_TYPE_SOCKET;
1487*1da177e4SLinus Torvalds 
1488*1da177e4SLinus Torvalds 	icbflags =	UDF_I_ALLOCTYPE(inode) |
1489*1da177e4SLinus Torvalds 			((inode->i_mode & S_ISUID) ? ICBTAG_FLAG_SETUID : 0) |
1490*1da177e4SLinus Torvalds 			((inode->i_mode & S_ISGID) ? ICBTAG_FLAG_SETGID : 0) |
1491*1da177e4SLinus Torvalds 			((inode->i_mode & S_ISVTX) ? ICBTAG_FLAG_STICKY : 0) |
1492*1da177e4SLinus Torvalds 			(le16_to_cpu(fe->icbTag.flags) &
1493*1da177e4SLinus Torvalds 				~(ICBTAG_FLAG_AD_MASK | ICBTAG_FLAG_SETUID |
1494*1da177e4SLinus Torvalds 				ICBTAG_FLAG_SETGID | ICBTAG_FLAG_STICKY));
1495*1da177e4SLinus Torvalds 
1496*1da177e4SLinus Torvalds 	fe->icbTag.flags = cpu_to_le16(icbflags);
1497*1da177e4SLinus Torvalds 	if (UDF_SB_UDFREV(inode->i_sb) >= 0x0200)
1498*1da177e4SLinus Torvalds 		fe->descTag.descVersion = cpu_to_le16(3);
1499*1da177e4SLinus Torvalds 	else
1500*1da177e4SLinus Torvalds 		fe->descTag.descVersion = cpu_to_le16(2);
1501*1da177e4SLinus Torvalds 	fe->descTag.tagSerialNum = cpu_to_le16(UDF_SB_SERIALNUM(inode->i_sb));
1502*1da177e4SLinus Torvalds 	fe->descTag.tagLocation = cpu_to_le32(UDF_I_LOCATION(inode).logicalBlockNum);
1503*1da177e4SLinus Torvalds 	crclen += UDF_I_LENEATTR(inode) + UDF_I_LENALLOC(inode) - sizeof(tag);
1504*1da177e4SLinus Torvalds 	fe->descTag.descCRCLength = cpu_to_le16(crclen);
1505*1da177e4SLinus Torvalds 	fe->descTag.descCRC = cpu_to_le16(udf_crc((char *)fe + sizeof(tag), crclen, 0));
1506*1da177e4SLinus Torvalds 
1507*1da177e4SLinus Torvalds 	fe->descTag.tagChecksum = 0;
1508*1da177e4SLinus Torvalds 	for (i=0; i<16; i++)
1509*1da177e4SLinus Torvalds 		if (i != 4)
1510*1da177e4SLinus Torvalds 			fe->descTag.tagChecksum += ((uint8_t *)&(fe->descTag))[i];
1511*1da177e4SLinus Torvalds 
1512*1da177e4SLinus Torvalds 	/* write the data blocks */
1513*1da177e4SLinus Torvalds 	mark_buffer_dirty(bh);
1514*1da177e4SLinus Torvalds 	if (do_sync)
1515*1da177e4SLinus Torvalds 	{
1516*1da177e4SLinus Torvalds 		sync_dirty_buffer(bh);
1517*1da177e4SLinus Torvalds 		if (buffer_req(bh) && !buffer_uptodate(bh))
1518*1da177e4SLinus Torvalds 		{
1519*1da177e4SLinus Torvalds 			printk("IO error syncing udf inode [%s:%08lx]\n",
1520*1da177e4SLinus Torvalds 				inode->i_sb->s_id, inode->i_ino);
1521*1da177e4SLinus Torvalds 			err = -EIO;
1522*1da177e4SLinus Torvalds 		}
1523*1da177e4SLinus Torvalds 	}
1524*1da177e4SLinus Torvalds 	udf_release_data(bh);
1525*1da177e4SLinus Torvalds 	return err;
1526*1da177e4SLinus Torvalds }
1527*1da177e4SLinus Torvalds 
1528*1da177e4SLinus Torvalds struct inode *
1529*1da177e4SLinus Torvalds udf_iget(struct super_block *sb, kernel_lb_addr ino)
1530*1da177e4SLinus Torvalds {
1531*1da177e4SLinus Torvalds 	unsigned long block = udf_get_lb_pblock(sb, ino, 0);
1532*1da177e4SLinus Torvalds 	struct inode *inode = iget_locked(sb, block);
1533*1da177e4SLinus Torvalds 
1534*1da177e4SLinus Torvalds 	if (!inode)
1535*1da177e4SLinus Torvalds 		return NULL;
1536*1da177e4SLinus Torvalds 
1537*1da177e4SLinus Torvalds 	if (inode->i_state & I_NEW) {
1538*1da177e4SLinus Torvalds 		memcpy(&UDF_I_LOCATION(inode), &ino, sizeof(kernel_lb_addr));
1539*1da177e4SLinus Torvalds 		__udf_read_inode(inode);
1540*1da177e4SLinus Torvalds 		unlock_new_inode(inode);
1541*1da177e4SLinus Torvalds 	}
1542*1da177e4SLinus Torvalds 
1543*1da177e4SLinus Torvalds 	if (is_bad_inode(inode))
1544*1da177e4SLinus Torvalds 		goto out_iput;
1545*1da177e4SLinus Torvalds 
1546*1da177e4SLinus Torvalds 	if (ino.logicalBlockNum >= UDF_SB_PARTLEN(sb, ino.partitionReferenceNum)) {
1547*1da177e4SLinus Torvalds 		udf_debug("block=%d, partition=%d out of range\n",
1548*1da177e4SLinus Torvalds 			ino.logicalBlockNum, ino.partitionReferenceNum);
1549*1da177e4SLinus Torvalds 		make_bad_inode(inode);
1550*1da177e4SLinus Torvalds 		goto out_iput;
1551*1da177e4SLinus Torvalds 	}
1552*1da177e4SLinus Torvalds 
1553*1da177e4SLinus Torvalds 	return inode;
1554*1da177e4SLinus Torvalds 
1555*1da177e4SLinus Torvalds  out_iput:
1556*1da177e4SLinus Torvalds 	iput(inode);
1557*1da177e4SLinus Torvalds 	return NULL;
1558*1da177e4SLinus Torvalds }
1559*1da177e4SLinus Torvalds 
1560*1da177e4SLinus Torvalds int8_t udf_add_aext(struct inode *inode, kernel_lb_addr *bloc, int *extoffset,
1561*1da177e4SLinus Torvalds 	kernel_lb_addr eloc, uint32_t elen, struct buffer_head **bh, int inc)
1562*1da177e4SLinus Torvalds {
1563*1da177e4SLinus Torvalds 	int adsize;
1564*1da177e4SLinus Torvalds 	short_ad *sad = NULL;
1565*1da177e4SLinus Torvalds 	long_ad *lad = NULL;
1566*1da177e4SLinus Torvalds 	struct allocExtDesc *aed;
1567*1da177e4SLinus Torvalds 	int8_t etype;
1568*1da177e4SLinus Torvalds 	uint8_t *ptr;
1569*1da177e4SLinus Torvalds 
1570*1da177e4SLinus Torvalds 	if (!*bh)
1571*1da177e4SLinus Torvalds 		ptr = UDF_I_DATA(inode) + *extoffset - udf_file_entry_alloc_offset(inode) + UDF_I_LENEATTR(inode);
1572*1da177e4SLinus Torvalds 	else
1573*1da177e4SLinus Torvalds 		ptr = (*bh)->b_data + *extoffset;
1574*1da177e4SLinus Torvalds 
1575*1da177e4SLinus Torvalds 	if (UDF_I_ALLOCTYPE(inode) == ICBTAG_FLAG_AD_SHORT)
1576*1da177e4SLinus Torvalds 		adsize = sizeof(short_ad);
1577*1da177e4SLinus Torvalds 	else if (UDF_I_ALLOCTYPE(inode) == ICBTAG_FLAG_AD_LONG)
1578*1da177e4SLinus Torvalds 		adsize = sizeof(long_ad);
1579*1da177e4SLinus Torvalds 	else
1580*1da177e4SLinus Torvalds 		return -1;
1581*1da177e4SLinus Torvalds 
1582*1da177e4SLinus Torvalds 	if (*extoffset + (2 * adsize) > inode->i_sb->s_blocksize)
1583*1da177e4SLinus Torvalds 	{
1584*1da177e4SLinus Torvalds 		char *sptr, *dptr;
1585*1da177e4SLinus Torvalds 		struct buffer_head *nbh;
1586*1da177e4SLinus Torvalds 		int err, loffset;
1587*1da177e4SLinus Torvalds 		kernel_lb_addr obloc = *bloc;
1588*1da177e4SLinus Torvalds 
1589*1da177e4SLinus Torvalds 		if (!(bloc->logicalBlockNum = udf_new_block(inode->i_sb, NULL,
1590*1da177e4SLinus Torvalds 			obloc.partitionReferenceNum, obloc.logicalBlockNum, &err)))
1591*1da177e4SLinus Torvalds 		{
1592*1da177e4SLinus Torvalds 			return -1;
1593*1da177e4SLinus Torvalds 		}
1594*1da177e4SLinus Torvalds 		if (!(nbh = udf_tgetblk(inode->i_sb, udf_get_lb_pblock(inode->i_sb,
1595*1da177e4SLinus Torvalds 			*bloc, 0))))
1596*1da177e4SLinus Torvalds 		{
1597*1da177e4SLinus Torvalds 			return -1;
1598*1da177e4SLinus Torvalds 		}
1599*1da177e4SLinus Torvalds 		lock_buffer(nbh);
1600*1da177e4SLinus Torvalds 		memset(nbh->b_data, 0x00, inode->i_sb->s_blocksize);
1601*1da177e4SLinus Torvalds 		set_buffer_uptodate(nbh);
1602*1da177e4SLinus Torvalds 		unlock_buffer(nbh);
1603*1da177e4SLinus Torvalds 		mark_buffer_dirty_inode(nbh, inode);
1604*1da177e4SLinus Torvalds 
1605*1da177e4SLinus Torvalds 		aed = (struct allocExtDesc *)(nbh->b_data);
1606*1da177e4SLinus Torvalds 		if (!UDF_QUERY_FLAG(inode->i_sb, UDF_FLAG_STRICT))
1607*1da177e4SLinus Torvalds 			aed->previousAllocExtLocation = cpu_to_le32(obloc.logicalBlockNum);
1608*1da177e4SLinus Torvalds 		if (*extoffset + adsize > inode->i_sb->s_blocksize)
1609*1da177e4SLinus Torvalds 		{
1610*1da177e4SLinus Torvalds 			loffset = *extoffset;
1611*1da177e4SLinus Torvalds 			aed->lengthAllocDescs = cpu_to_le32(adsize);
1612*1da177e4SLinus Torvalds 			sptr = ptr - adsize;
1613*1da177e4SLinus Torvalds 			dptr = nbh->b_data + sizeof(struct allocExtDesc);
1614*1da177e4SLinus Torvalds 			memcpy(dptr, sptr, adsize);
1615*1da177e4SLinus Torvalds 			*extoffset = sizeof(struct allocExtDesc) + adsize;
1616*1da177e4SLinus Torvalds 		}
1617*1da177e4SLinus Torvalds 		else
1618*1da177e4SLinus Torvalds 		{
1619*1da177e4SLinus Torvalds 			loffset = *extoffset + adsize;
1620*1da177e4SLinus Torvalds 			aed->lengthAllocDescs = cpu_to_le32(0);
1621*1da177e4SLinus Torvalds 			sptr = ptr;
1622*1da177e4SLinus Torvalds 			*extoffset = sizeof(struct allocExtDesc);
1623*1da177e4SLinus Torvalds 
1624*1da177e4SLinus Torvalds 			if (*bh)
1625*1da177e4SLinus Torvalds 			{
1626*1da177e4SLinus Torvalds 				aed = (struct allocExtDesc *)(*bh)->b_data;
1627*1da177e4SLinus Torvalds 				aed->lengthAllocDescs =
1628*1da177e4SLinus Torvalds 					cpu_to_le32(le32_to_cpu(aed->lengthAllocDescs) + adsize);
1629*1da177e4SLinus Torvalds 			}
1630*1da177e4SLinus Torvalds 			else
1631*1da177e4SLinus Torvalds 			{
1632*1da177e4SLinus Torvalds 				UDF_I_LENALLOC(inode) += adsize;
1633*1da177e4SLinus Torvalds 				mark_inode_dirty(inode);
1634*1da177e4SLinus Torvalds 			}
1635*1da177e4SLinus Torvalds 		}
1636*1da177e4SLinus Torvalds 		if (UDF_SB_UDFREV(inode->i_sb) >= 0x0200)
1637*1da177e4SLinus Torvalds 			udf_new_tag(nbh->b_data, TAG_IDENT_AED, 3, 1,
1638*1da177e4SLinus Torvalds 				bloc->logicalBlockNum, sizeof(tag));
1639*1da177e4SLinus Torvalds 		else
1640*1da177e4SLinus Torvalds 			udf_new_tag(nbh->b_data, TAG_IDENT_AED, 2, 1,
1641*1da177e4SLinus Torvalds 				bloc->logicalBlockNum, sizeof(tag));
1642*1da177e4SLinus Torvalds 		switch (UDF_I_ALLOCTYPE(inode))
1643*1da177e4SLinus Torvalds 		{
1644*1da177e4SLinus Torvalds 			case ICBTAG_FLAG_AD_SHORT:
1645*1da177e4SLinus Torvalds 			{
1646*1da177e4SLinus Torvalds 				sad = (short_ad *)sptr;
1647*1da177e4SLinus Torvalds 				sad->extLength = cpu_to_le32(
1648*1da177e4SLinus Torvalds 					EXT_NEXT_EXTENT_ALLOCDECS |
1649*1da177e4SLinus Torvalds 					inode->i_sb->s_blocksize);
1650*1da177e4SLinus Torvalds 				sad->extPosition = cpu_to_le32(bloc->logicalBlockNum);
1651*1da177e4SLinus Torvalds 				break;
1652*1da177e4SLinus Torvalds 			}
1653*1da177e4SLinus Torvalds 			case ICBTAG_FLAG_AD_LONG:
1654*1da177e4SLinus Torvalds 			{
1655*1da177e4SLinus Torvalds 				lad = (long_ad *)sptr;
1656*1da177e4SLinus Torvalds 				lad->extLength = cpu_to_le32(
1657*1da177e4SLinus Torvalds 					EXT_NEXT_EXTENT_ALLOCDECS |
1658*1da177e4SLinus Torvalds 					inode->i_sb->s_blocksize);
1659*1da177e4SLinus Torvalds 				lad->extLocation = cpu_to_lelb(*bloc);
1660*1da177e4SLinus Torvalds 				memset(lad->impUse, 0x00, sizeof(lad->impUse));
1661*1da177e4SLinus Torvalds 				break;
1662*1da177e4SLinus Torvalds 			}
1663*1da177e4SLinus Torvalds 		}
1664*1da177e4SLinus Torvalds 		if (*bh)
1665*1da177e4SLinus Torvalds 		{
1666*1da177e4SLinus Torvalds 			if (!UDF_QUERY_FLAG(inode->i_sb, UDF_FLAG_STRICT) || UDF_SB_UDFREV(inode->i_sb) >= 0x0201)
1667*1da177e4SLinus Torvalds 				udf_update_tag((*bh)->b_data, loffset);
1668*1da177e4SLinus Torvalds 			else
1669*1da177e4SLinus Torvalds 				udf_update_tag((*bh)->b_data, sizeof(struct allocExtDesc));
1670*1da177e4SLinus Torvalds 			mark_buffer_dirty_inode(*bh, inode);
1671*1da177e4SLinus Torvalds 			udf_release_data(*bh);
1672*1da177e4SLinus Torvalds 		}
1673*1da177e4SLinus Torvalds 		else
1674*1da177e4SLinus Torvalds 			mark_inode_dirty(inode);
1675*1da177e4SLinus Torvalds 		*bh = nbh;
1676*1da177e4SLinus Torvalds 	}
1677*1da177e4SLinus Torvalds 
1678*1da177e4SLinus Torvalds 	etype = udf_write_aext(inode, *bloc, extoffset, eloc, elen, *bh, inc);
1679*1da177e4SLinus Torvalds 
1680*1da177e4SLinus Torvalds 	if (!*bh)
1681*1da177e4SLinus Torvalds 	{
1682*1da177e4SLinus Torvalds 		UDF_I_LENALLOC(inode) += adsize;
1683*1da177e4SLinus Torvalds 		mark_inode_dirty(inode);
1684*1da177e4SLinus Torvalds 	}
1685*1da177e4SLinus Torvalds 	else
1686*1da177e4SLinus Torvalds 	{
1687*1da177e4SLinus Torvalds 		aed = (struct allocExtDesc *)(*bh)->b_data;
1688*1da177e4SLinus Torvalds 		aed->lengthAllocDescs =
1689*1da177e4SLinus Torvalds 			cpu_to_le32(le32_to_cpu(aed->lengthAllocDescs) + adsize);
1690*1da177e4SLinus Torvalds 		if (!UDF_QUERY_FLAG(inode->i_sb, UDF_FLAG_STRICT) || UDF_SB_UDFREV(inode->i_sb) >= 0x0201)
1691*1da177e4SLinus Torvalds 			udf_update_tag((*bh)->b_data, *extoffset + (inc ? 0 : adsize));
1692*1da177e4SLinus Torvalds 		else
1693*1da177e4SLinus Torvalds 			udf_update_tag((*bh)->b_data, sizeof(struct allocExtDesc));
1694*1da177e4SLinus Torvalds 		mark_buffer_dirty_inode(*bh, inode);
1695*1da177e4SLinus Torvalds 	}
1696*1da177e4SLinus Torvalds 
1697*1da177e4SLinus Torvalds 	return etype;
1698*1da177e4SLinus Torvalds }
1699*1da177e4SLinus Torvalds 
1700*1da177e4SLinus Torvalds int8_t udf_write_aext(struct inode *inode, kernel_lb_addr bloc, int *extoffset,
1701*1da177e4SLinus Torvalds     kernel_lb_addr eloc, uint32_t elen, struct buffer_head *bh, int inc)
1702*1da177e4SLinus Torvalds {
1703*1da177e4SLinus Torvalds 	int adsize;
1704*1da177e4SLinus Torvalds 	uint8_t *ptr;
1705*1da177e4SLinus Torvalds 
1706*1da177e4SLinus Torvalds 	if (!bh)
1707*1da177e4SLinus Torvalds 		ptr = UDF_I_DATA(inode) + *extoffset - udf_file_entry_alloc_offset(inode) + UDF_I_LENEATTR(inode);
1708*1da177e4SLinus Torvalds 	else
1709*1da177e4SLinus Torvalds 	{
1710*1da177e4SLinus Torvalds 		ptr = bh->b_data + *extoffset;
1711*1da177e4SLinus Torvalds 		atomic_inc(&bh->b_count);
1712*1da177e4SLinus Torvalds 	}
1713*1da177e4SLinus Torvalds 
1714*1da177e4SLinus Torvalds 	switch (UDF_I_ALLOCTYPE(inode))
1715*1da177e4SLinus Torvalds 	{
1716*1da177e4SLinus Torvalds 		case ICBTAG_FLAG_AD_SHORT:
1717*1da177e4SLinus Torvalds 		{
1718*1da177e4SLinus Torvalds 			short_ad *sad = (short_ad *)ptr;
1719*1da177e4SLinus Torvalds 			sad->extLength = cpu_to_le32(elen);
1720*1da177e4SLinus Torvalds 			sad->extPosition = cpu_to_le32(eloc.logicalBlockNum);
1721*1da177e4SLinus Torvalds 			adsize = sizeof(short_ad);
1722*1da177e4SLinus Torvalds 			break;
1723*1da177e4SLinus Torvalds 		}
1724*1da177e4SLinus Torvalds 		case ICBTAG_FLAG_AD_LONG:
1725*1da177e4SLinus Torvalds 		{
1726*1da177e4SLinus Torvalds 			long_ad *lad = (long_ad *)ptr;
1727*1da177e4SLinus Torvalds 			lad->extLength = cpu_to_le32(elen);
1728*1da177e4SLinus Torvalds 			lad->extLocation = cpu_to_lelb(eloc);
1729*1da177e4SLinus Torvalds 			memset(lad->impUse, 0x00, sizeof(lad->impUse));
1730*1da177e4SLinus Torvalds 			adsize = sizeof(long_ad);
1731*1da177e4SLinus Torvalds 			break;
1732*1da177e4SLinus Torvalds 		}
1733*1da177e4SLinus Torvalds 		default:
1734*1da177e4SLinus Torvalds 			return -1;
1735*1da177e4SLinus Torvalds 	}
1736*1da177e4SLinus Torvalds 
1737*1da177e4SLinus Torvalds 	if (bh)
1738*1da177e4SLinus Torvalds 	{
1739*1da177e4SLinus Torvalds 		if (!UDF_QUERY_FLAG(inode->i_sb, UDF_FLAG_STRICT) || UDF_SB_UDFREV(inode->i_sb) >= 0x0201)
1740*1da177e4SLinus Torvalds 		{
1741*1da177e4SLinus Torvalds 			struct allocExtDesc *aed = (struct allocExtDesc *)(bh)->b_data;
1742*1da177e4SLinus Torvalds 			udf_update_tag((bh)->b_data,
1743*1da177e4SLinus Torvalds 				le32_to_cpu(aed->lengthAllocDescs) + sizeof(struct allocExtDesc));
1744*1da177e4SLinus Torvalds 		}
1745*1da177e4SLinus Torvalds 		mark_buffer_dirty_inode(bh, inode);
1746*1da177e4SLinus Torvalds 		udf_release_data(bh);
1747*1da177e4SLinus Torvalds 	}
1748*1da177e4SLinus Torvalds 	else
1749*1da177e4SLinus Torvalds 		mark_inode_dirty(inode);
1750*1da177e4SLinus Torvalds 
1751*1da177e4SLinus Torvalds 	if (inc)
1752*1da177e4SLinus Torvalds 		*extoffset += adsize;
1753*1da177e4SLinus Torvalds 	return (elen >> 30);
1754*1da177e4SLinus Torvalds }
1755*1da177e4SLinus Torvalds 
1756*1da177e4SLinus Torvalds int8_t udf_next_aext(struct inode *inode, kernel_lb_addr *bloc, int *extoffset,
1757*1da177e4SLinus Torvalds 	kernel_lb_addr *eloc, uint32_t *elen, struct buffer_head **bh, int inc)
1758*1da177e4SLinus Torvalds {
1759*1da177e4SLinus Torvalds 	int8_t etype;
1760*1da177e4SLinus Torvalds 
1761*1da177e4SLinus Torvalds 	while ((etype = udf_current_aext(inode, bloc, extoffset, eloc, elen, bh, inc)) ==
1762*1da177e4SLinus Torvalds 		(EXT_NEXT_EXTENT_ALLOCDECS >> 30))
1763*1da177e4SLinus Torvalds 	{
1764*1da177e4SLinus Torvalds 		*bloc = *eloc;
1765*1da177e4SLinus Torvalds 		*extoffset = sizeof(struct allocExtDesc);
1766*1da177e4SLinus Torvalds 		udf_release_data(*bh);
1767*1da177e4SLinus Torvalds 		if (!(*bh = udf_tread(inode->i_sb, udf_get_lb_pblock(inode->i_sb, *bloc, 0))))
1768*1da177e4SLinus Torvalds 		{
1769*1da177e4SLinus Torvalds 			udf_debug("reading block %d failed!\n",
1770*1da177e4SLinus Torvalds 				udf_get_lb_pblock(inode->i_sb, *bloc, 0));
1771*1da177e4SLinus Torvalds 			return -1;
1772*1da177e4SLinus Torvalds 		}
1773*1da177e4SLinus Torvalds 	}
1774*1da177e4SLinus Torvalds 
1775*1da177e4SLinus Torvalds 	return etype;
1776*1da177e4SLinus Torvalds }
1777*1da177e4SLinus Torvalds 
1778*1da177e4SLinus Torvalds int8_t udf_current_aext(struct inode *inode, kernel_lb_addr *bloc, int *extoffset,
1779*1da177e4SLinus Torvalds 	kernel_lb_addr *eloc, uint32_t *elen, struct buffer_head **bh, int inc)
1780*1da177e4SLinus Torvalds {
1781*1da177e4SLinus Torvalds 	int alen;
1782*1da177e4SLinus Torvalds 	int8_t etype;
1783*1da177e4SLinus Torvalds 	uint8_t *ptr;
1784*1da177e4SLinus Torvalds 
1785*1da177e4SLinus Torvalds 	if (!*bh)
1786*1da177e4SLinus Torvalds 	{
1787*1da177e4SLinus Torvalds 		if (!(*extoffset))
1788*1da177e4SLinus Torvalds 			*extoffset = udf_file_entry_alloc_offset(inode);
1789*1da177e4SLinus Torvalds 		ptr = UDF_I_DATA(inode) + *extoffset - udf_file_entry_alloc_offset(inode) + UDF_I_LENEATTR(inode);
1790*1da177e4SLinus Torvalds 		alen = udf_file_entry_alloc_offset(inode) + UDF_I_LENALLOC(inode);
1791*1da177e4SLinus Torvalds 	}
1792*1da177e4SLinus Torvalds 	else
1793*1da177e4SLinus Torvalds 	{
1794*1da177e4SLinus Torvalds 		if (!(*extoffset))
1795*1da177e4SLinus Torvalds 			*extoffset = sizeof(struct allocExtDesc);
1796*1da177e4SLinus Torvalds 		ptr = (*bh)->b_data + *extoffset;
1797*1da177e4SLinus Torvalds 		alen = sizeof(struct allocExtDesc) + le32_to_cpu(((struct allocExtDesc *)(*bh)->b_data)->lengthAllocDescs);
1798*1da177e4SLinus Torvalds 	}
1799*1da177e4SLinus Torvalds 
1800*1da177e4SLinus Torvalds 	switch (UDF_I_ALLOCTYPE(inode))
1801*1da177e4SLinus Torvalds 	{
1802*1da177e4SLinus Torvalds 		case ICBTAG_FLAG_AD_SHORT:
1803*1da177e4SLinus Torvalds 		{
1804*1da177e4SLinus Torvalds 			short_ad *sad;
1805*1da177e4SLinus Torvalds 
1806*1da177e4SLinus Torvalds 			if (!(sad = udf_get_fileshortad(ptr, alen, extoffset, inc)))
1807*1da177e4SLinus Torvalds 				return -1;
1808*1da177e4SLinus Torvalds 
1809*1da177e4SLinus Torvalds 			etype = le32_to_cpu(sad->extLength) >> 30;
1810*1da177e4SLinus Torvalds 			eloc->logicalBlockNum = le32_to_cpu(sad->extPosition);
1811*1da177e4SLinus Torvalds 			eloc->partitionReferenceNum = UDF_I_LOCATION(inode).partitionReferenceNum;
1812*1da177e4SLinus Torvalds 			*elen = le32_to_cpu(sad->extLength) & UDF_EXTENT_LENGTH_MASK;
1813*1da177e4SLinus Torvalds 			break;
1814*1da177e4SLinus Torvalds 		}
1815*1da177e4SLinus Torvalds 		case ICBTAG_FLAG_AD_LONG:
1816*1da177e4SLinus Torvalds 		{
1817*1da177e4SLinus Torvalds 			long_ad *lad;
1818*1da177e4SLinus Torvalds 
1819*1da177e4SLinus Torvalds 			if (!(lad = udf_get_filelongad(ptr, alen, extoffset, inc)))
1820*1da177e4SLinus Torvalds 				return -1;
1821*1da177e4SLinus Torvalds 
1822*1da177e4SLinus Torvalds 			etype = le32_to_cpu(lad->extLength) >> 30;
1823*1da177e4SLinus Torvalds 			*eloc = lelb_to_cpu(lad->extLocation);
1824*1da177e4SLinus Torvalds 			*elen = le32_to_cpu(lad->extLength) & UDF_EXTENT_LENGTH_MASK;
1825*1da177e4SLinus Torvalds 			break;
1826*1da177e4SLinus Torvalds 		}
1827*1da177e4SLinus Torvalds 		default:
1828*1da177e4SLinus Torvalds 		{
1829*1da177e4SLinus Torvalds 			udf_debug("alloc_type = %d unsupported\n", UDF_I_ALLOCTYPE(inode));
1830*1da177e4SLinus Torvalds 			return -1;
1831*1da177e4SLinus Torvalds 		}
1832*1da177e4SLinus Torvalds 	}
1833*1da177e4SLinus Torvalds 
1834*1da177e4SLinus Torvalds 	return etype;
1835*1da177e4SLinus Torvalds }
1836*1da177e4SLinus Torvalds 
1837*1da177e4SLinus Torvalds static int8_t
1838*1da177e4SLinus Torvalds udf_insert_aext(struct inode *inode, kernel_lb_addr bloc, int extoffset,
1839*1da177e4SLinus Torvalds 		kernel_lb_addr neloc, uint32_t nelen, struct buffer_head *bh)
1840*1da177e4SLinus Torvalds {
1841*1da177e4SLinus Torvalds 	kernel_lb_addr oeloc;
1842*1da177e4SLinus Torvalds 	uint32_t oelen;
1843*1da177e4SLinus Torvalds 	int8_t etype;
1844*1da177e4SLinus Torvalds 
1845*1da177e4SLinus Torvalds 	if (bh)
1846*1da177e4SLinus Torvalds 		atomic_inc(&bh->b_count);
1847*1da177e4SLinus Torvalds 
1848*1da177e4SLinus Torvalds 	while ((etype = udf_next_aext(inode, &bloc, &extoffset, &oeloc, &oelen, &bh, 0)) != -1)
1849*1da177e4SLinus Torvalds 	{
1850*1da177e4SLinus Torvalds 		udf_write_aext(inode, bloc, &extoffset, neloc, nelen, bh, 1);
1851*1da177e4SLinus Torvalds 
1852*1da177e4SLinus Torvalds 		neloc = oeloc;
1853*1da177e4SLinus Torvalds 		nelen = (etype << 30) | oelen;
1854*1da177e4SLinus Torvalds 	}
1855*1da177e4SLinus Torvalds 	udf_add_aext(inode, &bloc, &extoffset, neloc, nelen, &bh, 1);
1856*1da177e4SLinus Torvalds 	udf_release_data(bh);
1857*1da177e4SLinus Torvalds 	return (nelen >> 30);
1858*1da177e4SLinus Torvalds }
1859*1da177e4SLinus Torvalds 
1860*1da177e4SLinus Torvalds int8_t udf_delete_aext(struct inode *inode, kernel_lb_addr nbloc, int nextoffset,
1861*1da177e4SLinus Torvalds 	kernel_lb_addr eloc, uint32_t elen, struct buffer_head *nbh)
1862*1da177e4SLinus Torvalds {
1863*1da177e4SLinus Torvalds 	struct buffer_head *obh;
1864*1da177e4SLinus Torvalds 	kernel_lb_addr obloc;
1865*1da177e4SLinus Torvalds 	int oextoffset, adsize;
1866*1da177e4SLinus Torvalds 	int8_t etype;
1867*1da177e4SLinus Torvalds 	struct allocExtDesc *aed;
1868*1da177e4SLinus Torvalds 
1869*1da177e4SLinus Torvalds 	if (nbh)
1870*1da177e4SLinus Torvalds 	{
1871*1da177e4SLinus Torvalds 		atomic_inc(&nbh->b_count);
1872*1da177e4SLinus Torvalds 		atomic_inc(&nbh->b_count);
1873*1da177e4SLinus Torvalds 	}
1874*1da177e4SLinus Torvalds 
1875*1da177e4SLinus Torvalds 	if (UDF_I_ALLOCTYPE(inode) == ICBTAG_FLAG_AD_SHORT)
1876*1da177e4SLinus Torvalds 		adsize = sizeof(short_ad);
1877*1da177e4SLinus Torvalds 	else if (UDF_I_ALLOCTYPE(inode) == ICBTAG_FLAG_AD_LONG)
1878*1da177e4SLinus Torvalds 		adsize = sizeof(long_ad);
1879*1da177e4SLinus Torvalds 	else
1880*1da177e4SLinus Torvalds 		adsize = 0;
1881*1da177e4SLinus Torvalds 
1882*1da177e4SLinus Torvalds 	obh = nbh;
1883*1da177e4SLinus Torvalds 	obloc = nbloc;
1884*1da177e4SLinus Torvalds 	oextoffset = nextoffset;
1885*1da177e4SLinus Torvalds 
1886*1da177e4SLinus Torvalds 	if (udf_next_aext(inode, &nbloc, &nextoffset, &eloc, &elen, &nbh, 1) == -1)
1887*1da177e4SLinus Torvalds 		return -1;
1888*1da177e4SLinus Torvalds 
1889*1da177e4SLinus Torvalds 	while ((etype = udf_next_aext(inode, &nbloc, &nextoffset, &eloc, &elen, &nbh, 1)) != -1)
1890*1da177e4SLinus Torvalds 	{
1891*1da177e4SLinus Torvalds 		udf_write_aext(inode, obloc, &oextoffset, eloc, (etype << 30) | elen, obh, 1);
1892*1da177e4SLinus Torvalds 		if (obh != nbh)
1893*1da177e4SLinus Torvalds 		{
1894*1da177e4SLinus Torvalds 			obloc = nbloc;
1895*1da177e4SLinus Torvalds 			udf_release_data(obh);
1896*1da177e4SLinus Torvalds 			atomic_inc(&nbh->b_count);
1897*1da177e4SLinus Torvalds 			obh = nbh;
1898*1da177e4SLinus Torvalds 			oextoffset = nextoffset - adsize;
1899*1da177e4SLinus Torvalds 		}
1900*1da177e4SLinus Torvalds 	}
1901*1da177e4SLinus Torvalds 	memset(&eloc, 0x00, sizeof(kernel_lb_addr));
1902*1da177e4SLinus Torvalds 	elen = 0;
1903*1da177e4SLinus Torvalds 
1904*1da177e4SLinus Torvalds 	if (nbh != obh)
1905*1da177e4SLinus Torvalds 	{
1906*1da177e4SLinus Torvalds 		udf_free_blocks(inode->i_sb, inode, nbloc, 0, 1);
1907*1da177e4SLinus Torvalds 		udf_write_aext(inode, obloc, &oextoffset, eloc, elen, obh, 1);
1908*1da177e4SLinus Torvalds 		udf_write_aext(inode, obloc, &oextoffset, eloc, elen, obh, 1);
1909*1da177e4SLinus Torvalds 		if (!obh)
1910*1da177e4SLinus Torvalds 		{
1911*1da177e4SLinus Torvalds 			UDF_I_LENALLOC(inode) -= (adsize * 2);
1912*1da177e4SLinus Torvalds 			mark_inode_dirty(inode);
1913*1da177e4SLinus Torvalds 		}
1914*1da177e4SLinus Torvalds 		else
1915*1da177e4SLinus Torvalds 		{
1916*1da177e4SLinus Torvalds 			aed = (struct allocExtDesc *)(obh)->b_data;
1917*1da177e4SLinus Torvalds 			aed->lengthAllocDescs =
1918*1da177e4SLinus Torvalds 				cpu_to_le32(le32_to_cpu(aed->lengthAllocDescs) - (2*adsize));
1919*1da177e4SLinus Torvalds 			if (!UDF_QUERY_FLAG(inode->i_sb, UDF_FLAG_STRICT) || UDF_SB_UDFREV(inode->i_sb) >= 0x0201)
1920*1da177e4SLinus Torvalds 				udf_update_tag((obh)->b_data, oextoffset - (2*adsize));
1921*1da177e4SLinus Torvalds 			else
1922*1da177e4SLinus Torvalds 				udf_update_tag((obh)->b_data, sizeof(struct allocExtDesc));
1923*1da177e4SLinus Torvalds 			mark_buffer_dirty_inode(obh, inode);
1924*1da177e4SLinus Torvalds 		}
1925*1da177e4SLinus Torvalds 	}
1926*1da177e4SLinus Torvalds 	else
1927*1da177e4SLinus Torvalds 	{
1928*1da177e4SLinus Torvalds 		udf_write_aext(inode, obloc, &oextoffset, eloc, elen, obh, 1);
1929*1da177e4SLinus Torvalds 		if (!obh)
1930*1da177e4SLinus Torvalds 		{
1931*1da177e4SLinus Torvalds 			UDF_I_LENALLOC(inode) -= adsize;
1932*1da177e4SLinus Torvalds 			mark_inode_dirty(inode);
1933*1da177e4SLinus Torvalds 		}
1934*1da177e4SLinus Torvalds 		else
1935*1da177e4SLinus Torvalds 		{
1936*1da177e4SLinus Torvalds 			aed = (struct allocExtDesc *)(obh)->b_data;
1937*1da177e4SLinus Torvalds 			aed->lengthAllocDescs =
1938*1da177e4SLinus Torvalds 				cpu_to_le32(le32_to_cpu(aed->lengthAllocDescs) - adsize);
1939*1da177e4SLinus Torvalds 			if (!UDF_QUERY_FLAG(inode->i_sb, UDF_FLAG_STRICT) || UDF_SB_UDFREV(inode->i_sb) >= 0x0201)
1940*1da177e4SLinus Torvalds 				udf_update_tag((obh)->b_data, oextoffset - adsize);
1941*1da177e4SLinus Torvalds 			else
1942*1da177e4SLinus Torvalds 				udf_update_tag((obh)->b_data, sizeof(struct allocExtDesc));
1943*1da177e4SLinus Torvalds 			mark_buffer_dirty_inode(obh, inode);
1944*1da177e4SLinus Torvalds 		}
1945*1da177e4SLinus Torvalds 	}
1946*1da177e4SLinus Torvalds 
1947*1da177e4SLinus Torvalds 	udf_release_data(nbh);
1948*1da177e4SLinus Torvalds 	udf_release_data(obh);
1949*1da177e4SLinus Torvalds 	return (elen >> 30);
1950*1da177e4SLinus Torvalds }
1951*1da177e4SLinus Torvalds 
1952*1da177e4SLinus Torvalds int8_t inode_bmap(struct inode *inode, int block, kernel_lb_addr *bloc, uint32_t *extoffset,
1953*1da177e4SLinus Torvalds 	kernel_lb_addr *eloc, uint32_t *elen, uint32_t *offset, struct buffer_head **bh)
1954*1da177e4SLinus Torvalds {
1955*1da177e4SLinus Torvalds 	uint64_t lbcount = 0, bcount = (uint64_t)block << inode->i_sb->s_blocksize_bits;
1956*1da177e4SLinus Torvalds 	int8_t etype;
1957*1da177e4SLinus Torvalds 
1958*1da177e4SLinus Torvalds 	if (block < 0)
1959*1da177e4SLinus Torvalds 	{
1960*1da177e4SLinus Torvalds 		printk(KERN_ERR "udf: inode_bmap: block < 0\n");
1961*1da177e4SLinus Torvalds 		return -1;
1962*1da177e4SLinus Torvalds 	}
1963*1da177e4SLinus Torvalds 	if (!inode)
1964*1da177e4SLinus Torvalds 	{
1965*1da177e4SLinus Torvalds 		printk(KERN_ERR "udf: inode_bmap: NULL inode\n");
1966*1da177e4SLinus Torvalds 		return -1;
1967*1da177e4SLinus Torvalds 	}
1968*1da177e4SLinus Torvalds 
1969*1da177e4SLinus Torvalds 	*extoffset = 0;
1970*1da177e4SLinus Torvalds 	*elen = 0;
1971*1da177e4SLinus Torvalds 	*bloc = UDF_I_LOCATION(inode);
1972*1da177e4SLinus Torvalds 
1973*1da177e4SLinus Torvalds 	do
1974*1da177e4SLinus Torvalds 	{
1975*1da177e4SLinus Torvalds 		if ((etype = udf_next_aext(inode, bloc, extoffset, eloc, elen, bh, 1)) == -1)
1976*1da177e4SLinus Torvalds 		{
1977*1da177e4SLinus Torvalds 			*offset = bcount - lbcount;
1978*1da177e4SLinus Torvalds 			UDF_I_LENEXTENTS(inode) = lbcount;
1979*1da177e4SLinus Torvalds 			return -1;
1980*1da177e4SLinus Torvalds 		}
1981*1da177e4SLinus Torvalds 		lbcount += *elen;
1982*1da177e4SLinus Torvalds 	} while (lbcount <= bcount);
1983*1da177e4SLinus Torvalds 
1984*1da177e4SLinus Torvalds 	*offset = bcount + *elen - lbcount;
1985*1da177e4SLinus Torvalds 
1986*1da177e4SLinus Torvalds 	return etype;
1987*1da177e4SLinus Torvalds }
1988*1da177e4SLinus Torvalds 
1989*1da177e4SLinus Torvalds long udf_block_map(struct inode *inode, long block)
1990*1da177e4SLinus Torvalds {
1991*1da177e4SLinus Torvalds 	kernel_lb_addr eloc, bloc;
1992*1da177e4SLinus Torvalds 	uint32_t offset, extoffset, elen;
1993*1da177e4SLinus Torvalds 	struct buffer_head *bh = NULL;
1994*1da177e4SLinus Torvalds 	int ret;
1995*1da177e4SLinus Torvalds 
1996*1da177e4SLinus Torvalds 	lock_kernel();
1997*1da177e4SLinus Torvalds 
1998*1da177e4SLinus Torvalds 	if (inode_bmap(inode, block, &bloc, &extoffset, &eloc, &elen, &offset, &bh) == (EXT_RECORDED_ALLOCATED >> 30))
1999*1da177e4SLinus Torvalds 		ret = udf_get_lb_pblock(inode->i_sb, eloc, offset >> inode->i_sb->s_blocksize_bits);
2000*1da177e4SLinus Torvalds 	else
2001*1da177e4SLinus Torvalds 		ret = 0;
2002*1da177e4SLinus Torvalds 
2003*1da177e4SLinus Torvalds 	unlock_kernel();
2004*1da177e4SLinus Torvalds 	udf_release_data(bh);
2005*1da177e4SLinus Torvalds 
2006*1da177e4SLinus Torvalds 	if (UDF_QUERY_FLAG(inode->i_sb, UDF_FLAG_VARCONV))
2007*1da177e4SLinus Torvalds 		return udf_fixed_to_variable(ret);
2008*1da177e4SLinus Torvalds 	else
2009*1da177e4SLinus Torvalds 		return ret;
2010*1da177e4SLinus Torvalds }
2011