inode.c 32.5 KB
Newer Older
L
Linus Torvalds 已提交
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36
/*
 *  linux/fs/ufs/inode.c
 *
 * Copyright (C) 1998
 * Daniel Pirkl <daniel.pirkl@email.cz>
 * Charles University, Faculty of Mathematics and Physics
 *
 *  from
 *
 *  linux/fs/ext2/inode.c
 *
 * Copyright (C) 1992, 1993, 1994, 1995
 * Remy Card (card@masi.ibp.fr)
 * Laboratoire MASI - Institut Blaise Pascal
 * Universite Pierre et Marie Curie (Paris VI)
 *
 *  from
 *
 *  linux/fs/minix/inode.c
 *
 *  Copyright (C) 1991, 1992  Linus Torvalds
 *
 *  Goal-directed block allocation by Stephen Tweedie (sct@dcs.ed.ac.uk), 1993
 *  Big-endian to little-endian byte-swapping/bitmaps by
 *        David S. Miller (davem@caip.rutgers.edu), 1995
 */

#include <asm/uaccess.h>

#include <linux/errno.h>
#include <linux/fs.h>
#include <linux/time.h>
#include <linux/stat.h>
#include <linux/string.h>
#include <linux/mm.h>
#include <linux/buffer_head.h>
37
#include <linux/writeback.h>
L
Linus Torvalds 已提交
38

39
#include "ufs_fs.h"
40
#include "ufs.h"
L
Linus Torvalds 已提交
41 42 43
#include "swab.h"
#include "util.h"

44
static int ufs_block_to_path(struct inode *inode, sector_t i_block, unsigned offsets[4])
L
Linus Torvalds 已提交
45 46 47 48 49 50 51 52 53 54
{
	struct ufs_sb_private_info *uspi = UFS_SB(inode->i_sb)->s_uspi;
	int ptrs = uspi->s_apb;
	int ptrs_bits = uspi->s_apbshift;
	const long direct_blocks = UFS_NDADDR,
		indirect_blocks = ptrs,
		double_blocks = (1 << (ptrs_bits * 2));
	int n = 0;


E
Evgeniy Dushistov 已提交
55
	UFSD("ptrs=uspi->s_apb = %d,double_blocks=%ld \n",ptrs,double_blocks);
R
Roel Kluin 已提交
56
	if (i_block < direct_blocks) {
L
Linus Torvalds 已提交
57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75
		offsets[n++] = i_block;
	} else if ((i_block -= direct_blocks) < indirect_blocks) {
		offsets[n++] = UFS_IND_BLOCK;
		offsets[n++] = i_block;
	} else if ((i_block -= indirect_blocks) < double_blocks) {
		offsets[n++] = UFS_DIND_BLOCK;
		offsets[n++] = i_block >> ptrs_bits;
		offsets[n++] = i_block & (ptrs - 1);
	} else if (((i_block -= double_blocks) >> (ptrs_bits * 2)) < ptrs) {
		offsets[n++] = UFS_TIND_BLOCK;
		offsets[n++] = i_block >> (ptrs_bits * 2);
		offsets[n++] = (i_block >> ptrs_bits) & (ptrs - 1);
		offsets[n++] = i_block & (ptrs - 1);
	} else {
		ufs_warning(inode->i_sb, "ufs_block_to_path", "block > big");
	}
	return n;
}

76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116
typedef struct {
	void	*p;
	union {
		__fs32	key32;
		__fs64	key64;
	};
	struct buffer_head *bh;
} Indirect;

static inline int grow_chain32(struct ufs_inode_info *ufsi,
			       struct buffer_head *bh, __fs32 *v,
			       Indirect *from, Indirect *to)
{
	Indirect *p;
	unsigned seq;
	to->bh = bh;
	do {
		seq = read_seqbegin(&ufsi->meta_lock);
		to->key32 = *(__fs32 *)(to->p = v);
		for (p = from; p <= to && p->key32 == *(__fs32 *)p->p; p++)
			;
	} while (read_seqretry(&ufsi->meta_lock, seq));
	return (p > to);
}

static inline int grow_chain64(struct ufs_inode_info *ufsi,
			       struct buffer_head *bh, __fs64 *v,
			       Indirect *from, Indirect *to)
{
	Indirect *p;
	unsigned seq;
	to->bh = bh;
	do {
		seq = read_seqbegin(&ufsi->meta_lock);
		to->key64 = *(__fs64 *)(to->p = v);
		for (p = from; p <= to && p->key64 == *(__fs64 *)p->p; p++)
			;
	} while (read_seqretry(&ufsi->meta_lock, seq));
	return (p > to);
}

L
Linus Torvalds 已提交
117 118
/*
 * Returns the location of the fragment from
L
Lucas De Marchi 已提交
119
 * the beginning of the filesystem.
L
Linus Torvalds 已提交
120 121
 */

122
static u64 ufs_frag_map(struct inode *inode, unsigned offsets[4], int depth)
L
Linus Torvalds 已提交
123 124 125 126 127 128
{
	struct ufs_inode_info *ufsi = UFS_I(inode);
	struct super_block *sb = inode->i_sb;
	struct ufs_sb_private_info *uspi = UFS_SB(sb)->s_uspi;
	u64 mask = (u64) uspi->s_apbmask>>uspi->s_fpbshift;
	int shift = uspi->s_apbshift-uspi->s_fpbshift;
129
	Indirect chain[4], *q = chain;
130
	unsigned *p;
L
Linus Torvalds 已提交
131
	unsigned flags = UFS_SB(sb)->s_flags;
132
	u64 res = 0;
L
Linus Torvalds 已提交
133

A
Andrew Morton 已提交
134 135 136
	UFSD(": uspi->s_fpbshift = %d ,uspi->s_apbmask = %x, mask=%llx\n",
		uspi->s_fpbshift, uspi->s_apbmask,
		(unsigned long long)mask);
L
Linus Torvalds 已提交
137 138

	if (depth == 0)
139
		goto no_block;
L
Linus Torvalds 已提交
140

141
again:
L
Linus Torvalds 已提交
142 143 144 145 146
	p = offsets;

	if ((flags & UFS_TYPE_MASK) == UFS_TYPE_UFS2)
		goto ufs2;

147 148 149 150
	if (!grow_chain32(ufsi, NULL, &ufsi->i_u1.i_data[*p++], chain, q))
		goto changed;
	if (!q->key32)
		goto no_block;
L
Linus Torvalds 已提交
151
	while (--depth) {
152
		__fs32 *ptr;
L
Linus Torvalds 已提交
153
		struct buffer_head *bh;
154
		unsigned n = *p++;
L
Linus Torvalds 已提交
155

156 157
		bh = sb_bread(sb, uspi->s_sbbase +
				  fs32_to_cpu(sb, q->key32) + (n>>shift));
L
Linus Torvalds 已提交
158
		if (!bh)
159 160 161 162 163 164
			goto no_block;
		ptr = (__fs32 *)bh->b_data + (n & mask);
		if (!grow_chain32(ufsi, bh, ptr, chain, ++q))
			goto changed;
		if (!q->key32)
			goto no_block;
L
Linus Torvalds 已提交
165
	}
166 167
	res = fs32_to_cpu(sb, q->key32);
	goto found;
L
Linus Torvalds 已提交
168

169 170 171 172 173
ufs2:
	if (!grow_chain64(ufsi, NULL, &ufsi->i_u1.u2_i_data[*p++], chain, q))
		goto changed;
	if (!q->key64)
		goto no_block;
L
Linus Torvalds 已提交
174 175

	while (--depth) {
176
		__fs64 *ptr;
L
Linus Torvalds 已提交
177
		struct buffer_head *bh;
178
		unsigned n = *p++;
L
Linus Torvalds 已提交
179

180 181
		bh = sb_bread(sb, uspi->s_sbbase +
				  fs64_to_cpu(sb, q->key64) + (n>>shift));
L
Linus Torvalds 已提交
182
		if (!bh)
183 184 185 186 187 188 189 190 191
			goto no_block;
		ptr = (__fs64 *)bh->b_data + (n & mask);
		if (!grow_chain64(ufsi, bh, ptr, chain, ++q))
			goto changed;
		if (!q->key64)
			goto no_block;
	}
	res = fs64_to_cpu(sb, q->key64);
found:
192
	res += uspi->s_sbbase;
193 194 195 196
no_block:
	while (q > chain) {
		brelse(q->bh);
		q--;
L
Linus Torvalds 已提交
197
	}
198
	return res;
L
Linus Torvalds 已提交
199

200 201 202 203 204 205
changed:
	while (q > chain) {
		brelse(q->bh);
		q--;
	}
	goto again;
L
Linus Torvalds 已提交
206 207
}

208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241
/*
 * Unpacking tails: we have a file with partial final block and
 * we had been asked to extend it.  If the fragment being written
 * is within the same block, we need to extend the tail just to cover
 * that fragment.  Otherwise the tail is extended to full block.
 *
 * Note that we might need to create a _new_ tail, but that will
 * be handled elsewhere; this is strictly for resizing old
 * ones.
 */
static bool
ufs_extend_tail(struct inode *inode, u64 writes_to,
		  int *err, struct page *locked_page)
{
	struct ufs_inode_info *ufsi = UFS_I(inode);
	struct super_block *sb = inode->i_sb;
	struct ufs_sb_private_info *uspi = UFS_SB(sb)->s_uspi;
	unsigned lastfrag = ufsi->i_lastfrag;	/* it's a short file, so unsigned is enough */
	unsigned block = ufs_fragstoblks(lastfrag);
	unsigned new_size;
	void *p;
	u64 tmp;

	if (writes_to < (lastfrag | uspi->s_fpbmask))
		new_size = (writes_to & uspi->s_fpbmask) + 1;
	else
		new_size = uspi->s_fpb;

	p = ufs_get_direct_data_ptr(uspi, ufsi, block);
	tmp = ufs_new_fragments(inode, p, lastfrag, ufs_data_ptr_to_cpu(sb, p),
				new_size, err, locked_page);
	return tmp != 0;
}

E
Evgeniy Dushistov 已提交
242 243
/**
 * ufs_inode_getfrag() - allocate new fragment(s)
244
 * @inode: pointer to inode
245
 * @index: number of block pointer within the inode's array.
246 247 248 249
 * @new_fragment: number of new allocated fragment(s)
 * @err: we set it if something wrong
 * @new: we set it if we allocate new block
 * @locked_page: for ufs_new_fragments()
E
Evgeniy Dushistov 已提交
250
 */
251
static u64
252 253
ufs_inode_getfrag(struct inode *inode, unsigned index,
		  sector_t new_fragment, int *err,
254
		  int *new, struct page *locked_page)
L
Linus Torvalds 已提交
255 256
{
	struct ufs_inode_info *ufsi = UFS_I(inode);
E
Evgeniy Dushistov 已提交
257 258
	struct super_block *sb = inode->i_sb;
	struct ufs_sb_private_info *uspi = UFS_SB(sb)->s_uspi;
259
	u64 tmp, goal, lastfrag;
260 261
	unsigned nfrags = uspi->s_fpb;
	void *p;
L
Linus Torvalds 已提交
262 263 264 265 266 267

        /* TODO : to be done for write support
        if ( (flags & UFS_TYPE_MASK) == UFS_TYPE_UFS2)
             goto ufs2;
         */

268
	p = ufs_get_direct_data_ptr(uspi, ufsi, index);
269
	tmp = ufs_data_ptr_to_cpu(sb, p);
270 271
	if (tmp)
		goto out;
272

L
Linus Torvalds 已提交
273 274
	lastfrag = ufsi->i_lastfrag;

275 276 277 278 279
	/* will that be a new tail? */
	if (new_fragment < UFS_NDIR_FRAGMENT && new_fragment >= lastfrag)
		nfrags = (new_fragment & uspi->s_fpbmask) + 1;

	goal = 0;
280
	if (index) {
281
		goal = ufs_data_ptr_to_cpu(sb,
282
				 ufs_get_direct_data_ptr(uspi, ufsi, index - 1));
283 284
		if (goal)
			goal += uspi->s_fpb;
L
Linus Torvalds 已提交
285
	}
286
	tmp = ufs_new_fragments(inode, p, ufs_blknum(new_fragment),
287
				goal, uspi->s_fpb, err, locked_page);
288

L
Linus Torvalds 已提交
289 290
	if (!tmp) {
		*err = -ENOSPC;
291
		return 0;
L
Linus Torvalds 已提交
292 293
	}

294
	if (new)
L
Linus Torvalds 已提交
295
		*new = 1;
296
	inode->i_ctime = current_time(inode);
L
Linus Torvalds 已提交
297 298 299
	if (IS_SYNC(inode))
		ufs_sync_inode (inode);
	mark_inode_dirty(inode);
300
out:
301
	return tmp + uspi->s_sbbase;
L
Linus Torvalds 已提交
302 303 304 305 306 307 308 309 310 311 312 313 314 315 316 317 318

     /* This part : To be implemented ....
        Required only for writing, not required for READ-ONLY.
ufs2:

	u2_block = ufs_fragstoblks(fragment);
	u2_blockoff = ufs_fragnum(fragment);
	p = ufsi->i_u1.u2_i_data + block;
	goal = 0;

repeat2:
	tmp = fs32_to_cpu(sb, *p);
	lastfrag = ufsi->i_lastfrag;

     */
}

E
Evgeniy Dushistov 已提交
319 320
/**
 * ufs_inode_getblock() - allocate new block
321
 * @inode: pointer to inode
322 323
 * @ind_block: block number of the indirect block
 * @index: number of pointer within the indirect block
324
 * @new_fragment: number of new allocated fragment
E
Evgeniy Dushistov 已提交
325
 *  (block will hold this fragment and also uspi->s_fpb-1)
326 327 328
 * @err: see ufs_inode_getfrag()
 * @new: see ufs_inode_getfrag()
 * @locked_page: see ufs_inode_getfrag()
E
Evgeniy Dushistov 已提交
329
 */
330
static u64
331
ufs_inode_getblock(struct inode *inode, u64 ind_block,
332
		  unsigned index, sector_t new_fragment, int *err,
333
		  int *new, struct page *locked_page)
L
Linus Torvalds 已提交
334
{
E
Evgeniy Dushistov 已提交
335 336
	struct super_block *sb = inode->i_sb;
	struct ufs_sb_private_info *uspi = UFS_SB(sb)->s_uspi;
337
	int shift = uspi->s_apbshift - uspi->s_fpbshift;
338
	u64 tmp = 0, goal;
339
	struct buffer_head *bh;
340
	void *p;
L
Linus Torvalds 已提交
341

342 343 344 345
	if (!ind_block)
		return 0;

	bh = sb_bread(sb, ind_block + (index >> shift));
346 347
	if (unlikely(!bh)) {
		*err = -EIO;
348
		return 0;
349
	}
350 351

	index &= uspi->s_apbmask >> uspi->s_fpbshift;
352
	if (uspi->fs_magic == UFS2_MAGIC)
353
		p = (__fs64 *)bh->b_data + index;
354
	else
355
		p = (__fs32 *)bh->b_data + index;
356

357
	tmp = ufs_data_ptr_to_cpu(sb, p);
358
	if (tmp)
359
		goto out;
L
Linus Torvalds 已提交
360

361 362 363
	if (index && (uspi->fs_magic == UFS2_MAGIC ?
		      (tmp = fs64_to_cpu(sb, ((__fs64 *)bh->b_data)[index-1])) :
		      (tmp = fs32_to_cpu(sb, ((__fs32 *)bh->b_data)[index-1]))))
L
Linus Torvalds 已提交
364 365 366
		goal = tmp + uspi->s_fpb;
	else
		goal = bh->b_blocknr + uspi->s_fpb;
367 368
	tmp = ufs_new_fragments(inode, p, ufs_blknum(new_fragment), goal,
				uspi->s_fpb, err, locked_page);
369
	if (!tmp)
L
Linus Torvalds 已提交
370
		goto out;
371

372
	if (new)
L
Linus Torvalds 已提交
373 374 375 376 377
		*new = 1;

	mark_buffer_dirty(bh);
	if (IS_SYNC(inode))
		sync_dirty_buffer(bh);
378
	inode->i_ctime = current_time(inode);
L
Linus Torvalds 已提交
379 380 381
	mark_inode_dirty(inode);
out:
	brelse (bh);
E
Evgeniy Dushistov 已提交
382
	UFSD("EXIT\n");
383 384 385
	if (tmp)
		tmp += uspi->s_sbbase;
	return tmp;
L
Linus Torvalds 已提交
386 387
}

E
Evgeniy Dushistov 已提交
388
/**
A
Alessio Igor Bogani 已提交
389
 * ufs_getfrag_block() - `get_block_t' function, interface between UFS and
E
Evgeniy Dushistov 已提交
390
 * readpage, writepage and so on
L
Linus Torvalds 已提交
391 392
 */

A
Al Viro 已提交
393
static int ufs_getfrag_block(struct inode *inode, sector_t fragment, struct buffer_head *bh_result, int create)
L
Linus Torvalds 已提交
394
{
A
Al Viro 已提交
395 396 397
	struct super_block *sb = inode->i_sb;
	struct ufs_sb_private_info *uspi = UFS_SB(sb)->s_uspi;
	int err = 0, new = 0;
398 399
	unsigned offsets[4];
	int depth = ufs_block_to_path(inode, fragment >> uspi->s_fpbshift, offsets);
L
Linus Torvalds 已提交
400
	u64 phys64 = 0;
401
	unsigned frag = fragment & uspi->s_fpbmask;
A
Al Viro 已提交
402

L
Linus Torvalds 已提交
403
	if (!create) {
404
		phys64 = ufs_frag_map(inode, offsets, depth);
A
Al Viro 已提交
405
		goto out;
L
Linus Torvalds 已提交
406 407 408 409
	}

        /* This code entered only while writing ....? */

410
	mutex_lock(&UFS_I(inode)->truncate_mutex);
L
Linus Torvalds 已提交
411

E
Evgeniy Dushistov 已提交
412
	UFSD("ENTER, ino %lu, fragment %llu\n", inode->i_ino, (unsigned long long)fragment);
A
Al Viro 已提交
413 414 415 416 417
	if (unlikely(!depth)) {
		ufs_warning(sb, "ufs_get_block", "block > big");
		err = -EIO;
		goto out;
	}
418 419 420 421 422 423 424

	if (UFS_I(inode)->i_lastfrag < UFS_NDIR_FRAGMENT) {
		unsigned lastfrag = UFS_I(inode)->i_lastfrag;
		unsigned tailfrags = lastfrag & uspi->s_fpbmask;
		if (tailfrags && fragment >= lastfrag) {
			if (!ufs_extend_tail(inode, fragment,
					     &err, bh_result->b_page))
A
Al Viro 已提交
425
				goto out;
426 427 428
		}
	}

429
	if (depth == 1) {
430
		phys64 = ufs_inode_getfrag(inode, offsets[0], fragment,
431
					   &err, &new, bh_result->b_page);
432 433
	} else {
		int i;
434
		phys64 = ufs_inode_getfrag(inode, offsets[0], fragment,
435
					   &err, NULL, NULL);
436 437
		for (i = 1; i < depth - 1; i++)
			phys64 = ufs_inode_getblock(inode, phys64, offsets[i],
438
						fragment, &err, NULL, NULL);
439
		phys64 = ufs_inode_getblock(inode, phys64, offsets[depth - 1],
440
					fragment, &err, &new, bh_result->b_page);
L
Linus Torvalds 已提交
441
	}
A
Al Viro 已提交
442
out:
443 444
	if (phys64) {
		phys64 += frag;
A
Al Viro 已提交
445 446 447
		map_bh(bh_result, sb, phys64);
		if (new)
			set_buffer_new(bh_result);
448
	}
449
	mutex_unlock(&UFS_I(inode)->truncate_mutex);
L
Linus Torvalds 已提交
450 451 452 453 454 455 456
	return err;
}

static int ufs_writepage(struct page *page, struct writeback_control *wbc)
{
	return block_write_full_page(page,ufs_getfrag_block,wbc);
}
N
Nick Piggin 已提交
457

L
Linus Torvalds 已提交
458 459 460 461
static int ufs_readpage(struct file *file, struct page *page)
{
	return block_read_full_page(page,ufs_getfrag_block);
}
N
Nick Piggin 已提交
462

463
int ufs_prepare_chunk(struct page *page, loff_t pos, unsigned len)
L
Linus Torvalds 已提交
464
{
465
	return __block_write_begin(page, pos, len, ufs_getfrag_block);
L
Linus Torvalds 已提交
466
}
N
Nick Piggin 已提交
467

A
Al Viro 已提交
468 469
static void ufs_truncate_blocks(struct inode *);

M
Marco Stornelli 已提交
470 471 472 473
static void ufs_write_failed(struct address_space *mapping, loff_t to)
{
	struct inode *inode = mapping->host;

474
	if (to > inode->i_size) {
475
		truncate_pagecache(inode, inode->i_size);
476 477
		ufs_truncate_blocks(inode);
	}
M
Marco Stornelli 已提交
478 479
}

N
Nick Piggin 已提交
480 481 482 483
static int ufs_write_begin(struct file *file, struct address_space *mapping,
			loff_t pos, unsigned len, unsigned flags,
			struct page **pagep, void **fsdata)
{
484 485 486
	int ret;

	ret = block_write_begin(mapping, pos, len, flags, pagep,
487
				ufs_getfrag_block);
M
Marco Stornelli 已提交
488 489
	if (unlikely(ret))
		ufs_write_failed(mapping, pos + len);
490 491

	return ret;
N
Nick Piggin 已提交
492 493
}

494 495 496 497 498 499 500 501 502 503 504 505
static int ufs_write_end(struct file *file, struct address_space *mapping,
			loff_t pos, unsigned len, unsigned copied,
			struct page *page, void *fsdata)
{
	int ret;

	ret = generic_write_end(file, mapping, pos, len, copied, page, fsdata);
	if (ret < len)
		ufs_write_failed(mapping, pos + len);
	return ret;
}

L
Linus Torvalds 已提交
506 507 508 509
static sector_t ufs_bmap(struct address_space *mapping, sector_t block)
{
	return generic_block_bmap(mapping,block,ufs_getfrag_block);
}
N
Nick Piggin 已提交
510

511
const struct address_space_operations ufs_aops = {
L
Linus Torvalds 已提交
512 513
	.readpage = ufs_readpage,
	.writepage = ufs_writepage,
N
Nick Piggin 已提交
514
	.write_begin = ufs_write_begin,
515
	.write_end = ufs_write_end,
L
Linus Torvalds 已提交
516 517 518
	.bmap = ufs_bmap
};

519 520 521 522 523 524 525 526 527 528 529
static void ufs_set_inode_ops(struct inode *inode)
{
	if (S_ISREG(inode->i_mode)) {
		inode->i_op = &ufs_file_inode_operations;
		inode->i_fop = &ufs_file_operations;
		inode->i_mapping->a_ops = &ufs_aops;
	} else if (S_ISDIR(inode->i_mode)) {
		inode->i_op = &ufs_dir_inode_operations;
		inode->i_fop = &ufs_dir_operations;
		inode->i_mapping->a_ops = &ufs_aops;
	} else if (S_ISLNK(inode->i_mode)) {
A
Al Viro 已提交
530 531
		if (!inode->i_blocks) {
			inode->i_link = (char *)UFS_I(inode)->i_u1.i_symlink;
A
Al Viro 已提交
532
			inode->i_op = &simple_symlink_inode_operations;
A
Al Viro 已提交
533
		} else {
534
			inode->i_mapping->a_ops = &ufs_aops;
A
Al Viro 已提交
535
			inode->i_op = &page_symlink_inode_operations;
536
			inode_nohighmem(inode);
537 538 539 540 541 542
		}
	} else
		init_special_inode(inode, inode->i_mode,
				   ufs_get_inode_dev(inode->i_sb, UFS_I(inode)));
}

543
static int ufs1_read_inode(struct inode *inode, struct ufs_inode *ufs_inode)
L
Linus Torvalds 已提交
544 545
{
	struct ufs_inode_info *ufsi = UFS_I(inode);
546
	struct super_block *sb = inode->i_sb;
A
Al Viro 已提交
547
	umode_t mode;
L
Linus Torvalds 已提交
548 549 550 551 552

	/*
	 * Copy data to the in-core inode.
	 */
	inode->i_mode = mode = fs16_to_cpu(sb, ufs_inode->ui_mode);
M
Miklos Szeredi 已提交
553
	set_nlink(inode, fs16_to_cpu(sb, ufs_inode->ui_nlink));
554
	if (inode->i_nlink == 0) {
L
Linus Torvalds 已提交
555
		ufs_error (sb, "ufs_read_inode", "inode %lu has zero nlink\n", inode->i_ino);
556 557
		return -1;
	}
A
Al Viro 已提交
558

L
Linus Torvalds 已提交
559 560 561
	/*
	 * Linux now has 32-bit uid and gid, so we can support EFT.
	 */
562 563
	i_uid_write(inode, ufs_get_inode_uid(sb, ufs_inode));
	i_gid_write(inode, ufs_get_inode_gid(sb, ufs_inode));
L
Linus Torvalds 已提交
564 565 566 567 568 569 570 571 572

	inode->i_size = fs64_to_cpu(sb, ufs_inode->ui_size);
	inode->i_atime.tv_sec = fs32_to_cpu(sb, ufs_inode->ui_atime.tv_sec);
	inode->i_ctime.tv_sec = fs32_to_cpu(sb, ufs_inode->ui_ctime.tv_sec);
	inode->i_mtime.tv_sec = fs32_to_cpu(sb, ufs_inode->ui_mtime.tv_sec);
	inode->i_mtime.tv_nsec = 0;
	inode->i_atime.tv_nsec = 0;
	inode->i_ctime.tv_nsec = 0;
	inode->i_blocks = fs32_to_cpu(sb, ufs_inode->ui_blocks);
573
	inode->i_generation = fs32_to_cpu(sb, ufs_inode->ui_gen);
L
Linus Torvalds 已提交
574 575 576
	ufsi->i_flags = fs32_to_cpu(sb, ufs_inode->ui_flags);
	ufsi->i_shadow = fs32_to_cpu(sb, ufs_inode->ui_u3.ui_sun.ui_shadow);
	ufsi->i_oeftflag = fs32_to_cpu(sb, ufs_inode->ui_u3.ui_sun.ui_oeftflag);
577

A
Al Viro 已提交
578

L
Linus Torvalds 已提交
579
	if (S_ISCHR(mode) || S_ISBLK(mode) || inode->i_blocks) {
580 581
		memcpy(ufsi->i_u1.i_data, &ufs_inode->ui_u2.ui_addr,
		       sizeof(ufs_inode->ui_u2.ui_addr));
582
	} else {
583
		memcpy(ufsi->i_u1.i_symlink, ufs_inode->ui_u2.ui_symlink,
584 585
		       sizeof(ufs_inode->ui_u2.ui_symlink) - 1);
		ufsi->i_u1.i_symlink[sizeof(ufs_inode->ui_u2.ui_symlink) - 1] = 0;
L
Linus Torvalds 已提交
586
	}
587
	return 0;
588
}
L
Linus Torvalds 已提交
589

590
static int ufs2_read_inode(struct inode *inode, struct ufs2_inode *ufs2_inode)
591 592 593
{
	struct ufs_inode_info *ufsi = UFS_I(inode);
	struct super_block *sb = inode->i_sb;
A
Al Viro 已提交
594
	umode_t mode;
L
Linus Torvalds 已提交
595

E
Evgeniy Dushistov 已提交
596
	UFSD("Reading ufs2 inode, ino %lu\n", inode->i_ino);
L
Linus Torvalds 已提交
597 598 599 600
	/*
	 * Copy data to the in-core inode.
	 */
	inode->i_mode = mode = fs16_to_cpu(sb, ufs2_inode->ui_mode);
M
Miklos Szeredi 已提交
601
	set_nlink(inode, fs16_to_cpu(sb, ufs2_inode->ui_nlink));
602
	if (inode->i_nlink == 0) {
L
Linus Torvalds 已提交
603
		ufs_error (sb, "ufs_read_inode", "inode %lu has zero nlink\n", inode->i_ino);
604 605
		return -1;
	}
L
Linus Torvalds 已提交
606 607 608 609

        /*
         * Linux now has 32-bit uid and gid, so we can support EFT.
         */
610 611
	i_uid_write(inode, fs32_to_cpu(sb, ufs2_inode->ui_uid));
	i_gid_write(inode, fs32_to_cpu(sb, ufs2_inode->ui_gid));
L
Linus Torvalds 已提交
612 613

	inode->i_size = fs64_to_cpu(sb, ufs2_inode->ui_size);
614 615 616 617 618 619
	inode->i_atime.tv_sec = fs64_to_cpu(sb, ufs2_inode->ui_atime);
	inode->i_ctime.tv_sec = fs64_to_cpu(sb, ufs2_inode->ui_ctime);
	inode->i_mtime.tv_sec = fs64_to_cpu(sb, ufs2_inode->ui_mtime);
	inode->i_atime.tv_nsec = fs32_to_cpu(sb, ufs2_inode->ui_atimensec);
	inode->i_ctime.tv_nsec = fs32_to_cpu(sb, ufs2_inode->ui_ctimensec);
	inode->i_mtime.tv_nsec = fs32_to_cpu(sb, ufs2_inode->ui_mtimensec);
L
Linus Torvalds 已提交
620
	inode->i_blocks = fs64_to_cpu(sb, ufs2_inode->ui_blocks);
621
	inode->i_generation = fs32_to_cpu(sb, ufs2_inode->ui_gen);
L
Linus Torvalds 已提交
622 623 624 625 626 627 628
	ufsi->i_flags = fs32_to_cpu(sb, ufs2_inode->ui_flags);
	/*
	ufsi->i_shadow = fs32_to_cpu(sb, ufs_inode->ui_u3.ui_sun.ui_shadow);
	ufsi->i_oeftflag = fs32_to_cpu(sb, ufs_inode->ui_u3.ui_sun.ui_oeftflag);
	*/

	if (S_ISCHR(mode) || S_ISBLK(mode) || inode->i_blocks) {
629 630
		memcpy(ufsi->i_u1.u2_i_data, &ufs2_inode->ui_u2.ui_addr,
		       sizeof(ufs2_inode->ui_u2.ui_addr));
631
	} else {
632
		memcpy(ufsi->i_u1.i_symlink, ufs2_inode->ui_u2.ui_symlink,
633 634
		       sizeof(ufs2_inode->ui_u2.ui_symlink) - 1);
		ufsi->i_u1.i_symlink[sizeof(ufs2_inode->ui_u2.ui_symlink) - 1] = 0;
L
Linus Torvalds 已提交
635
	}
636
	return 0;
637 638
}

639
struct inode *ufs_iget(struct super_block *sb, unsigned long ino)
640
{
641 642
	struct ufs_inode_info *ufsi;
	struct ufs_sb_private_info *uspi = UFS_SB(sb)->s_uspi;
643
	struct buffer_head * bh;
644
	struct inode *inode;
645
	int err;
646

647
	UFSD("ENTER, ino %lu\n", ino);
648

649
	if (ino < UFS_ROOTINO || ino > (uspi->s_ncg * uspi->s_ipg)) {
650
		ufs_warning(sb, "ufs_read_inode", "bad inode number (%lu)\n",
651 652
			    ino);
		return ERR_PTR(-EIO);
653 654
	}

655 656 657 658 659 660 661 662
	inode = iget_locked(sb, ino);
	if (!inode)
		return ERR_PTR(-ENOMEM);
	if (!(inode->i_state & I_NEW))
		return inode;

	ufsi = UFS_I(inode);

663 664 665 666 667 668 669 670 671
	bh = sb_bread(sb, uspi->s_sbbase + ufs_inotofsba(inode->i_ino));
	if (!bh) {
		ufs_warning(sb, "ufs_read_inode", "unable to read inode %lu\n",
			    inode->i_ino);
		goto bad_inode;
	}
	if ((UFS_SB(sb)->s_flags & UFS_TYPE_MASK) == UFS_TYPE_UFS2) {
		struct ufs2_inode *ufs2_inode = (struct ufs2_inode *)bh->b_data;

672 673
		err = ufs2_read_inode(inode,
				      ufs2_inode + ufs_inotofsbo(inode->i_ino));
674 675 676
	} else {
		struct ufs_inode *ufs_inode = (struct ufs_inode *)bh->b_data;

677 678
		err = ufs1_read_inode(inode,
				      ufs_inode + ufs_inotofsbo(inode->i_ino));
679 680
	}

681 682
	if (err)
		goto bad_inode;
683 684 685 686
	inode->i_version++;
	ufsi->i_lastfrag =
		(inode->i_size + uspi->s_fsize - 1) >> uspi->s_fshift;
	ufsi->i_dir_start_lookup = 0;
L
Linus Torvalds 已提交
687 688
	ufsi->i_osync = 0;

689
	ufs_set_inode_ops(inode);
L
Linus Torvalds 已提交
690 691 692

	brelse(bh);

E
Evgeniy Dushistov 已提交
693
	UFSD("EXIT\n");
694 695
	unlock_new_inode(inode);
	return inode;
696 697

bad_inode:
698 699
	iget_failed(inode);
	return ERR_PTR(-EIO);
L
Linus Torvalds 已提交
700 701
}

702
static void ufs1_update_inode(struct inode *inode, struct ufs_inode *ufs_inode)
L
Linus Torvalds 已提交
703
{
704 705
	struct super_block *sb = inode->i_sb;
 	struct ufs_inode_info *ufsi = UFS_I(inode);
L
Linus Torvalds 已提交
706 707 708 709

	ufs_inode->ui_mode = cpu_to_fs16(sb, inode->i_mode);
	ufs_inode->ui_nlink = cpu_to_fs16(sb, inode->i_nlink);

710 711
	ufs_set_inode_uid(sb, ufs_inode, i_uid_read(inode));
	ufs_set_inode_gid(sb, ufs_inode, i_gid_read(inode));
A
Al Viro 已提交
712

L
Linus Torvalds 已提交
713 714 715 716 717 718 719 720 721
	ufs_inode->ui_size = cpu_to_fs64(sb, inode->i_size);
	ufs_inode->ui_atime.tv_sec = cpu_to_fs32(sb, inode->i_atime.tv_sec);
	ufs_inode->ui_atime.tv_usec = 0;
	ufs_inode->ui_ctime.tv_sec = cpu_to_fs32(sb, inode->i_ctime.tv_sec);
	ufs_inode->ui_ctime.tv_usec = 0;
	ufs_inode->ui_mtime.tv_sec = cpu_to_fs32(sb, inode->i_mtime.tv_sec);
	ufs_inode->ui_mtime.tv_usec = 0;
	ufs_inode->ui_blocks = cpu_to_fs32(sb, inode->i_blocks);
	ufs_inode->ui_flags = cpu_to_fs32(sb, ufsi->i_flags);
722
	ufs_inode->ui_gen = cpu_to_fs32(sb, inode->i_generation);
L
Linus Torvalds 已提交
723

724
	if ((UFS_SB(sb)->s_flags & UFS_UID_MASK) == UFS_UID_EFT) {
L
Linus Torvalds 已提交
725 726 727 728 729 730 731 732
		ufs_inode->ui_u3.ui_sun.ui_shadow = cpu_to_fs32(sb, ufsi->i_shadow);
		ufs_inode->ui_u3.ui_sun.ui_oeftflag = cpu_to_fs32(sb, ufsi->i_oeftflag);
	}

	if (S_ISCHR(inode->i_mode) || S_ISBLK(inode->i_mode)) {
		/* ufs_inode->ui_u2.ui_addr.ui_db[0] = cpu_to_fs32(sb, inode->i_rdev); */
		ufs_inode->ui_u2.ui_addr.ui_db[0] = ufsi->i_u1.i_data[0];
	} else if (inode->i_blocks) {
733 734
		memcpy(&ufs_inode->ui_u2.ui_addr, ufsi->i_u1.i_data,
		       sizeof(ufs_inode->ui_u2.ui_addr));
L
Linus Torvalds 已提交
735 736
	}
	else {
737 738
		memcpy(&ufs_inode->ui_u2.ui_symlink, ufsi->i_u1.i_symlink,
		       sizeof(ufs_inode->ui_u2.ui_symlink));
L
Linus Torvalds 已提交
739 740 741 742
	}

	if (!inode->i_nlink)
		memset (ufs_inode, 0, sizeof(struct ufs_inode));
743 744 745 746 747 748 749 750 751 752 753
}

static void ufs2_update_inode(struct inode *inode, struct ufs2_inode *ufs_inode)
{
	struct super_block *sb = inode->i_sb;
 	struct ufs_inode_info *ufsi = UFS_I(inode);

	UFSD("ENTER\n");
	ufs_inode->ui_mode = cpu_to_fs16(sb, inode->i_mode);
	ufs_inode->ui_nlink = cpu_to_fs16(sb, inode->i_nlink);

754 755
	ufs_inode->ui_uid = cpu_to_fs32(sb, i_uid_read(inode));
	ufs_inode->ui_gid = cpu_to_fs32(sb, i_gid_read(inode));
756 757

	ufs_inode->ui_size = cpu_to_fs64(sb, inode->i_size);
758 759 760 761 762 763
	ufs_inode->ui_atime = cpu_to_fs64(sb, inode->i_atime.tv_sec);
	ufs_inode->ui_atimensec = cpu_to_fs32(sb, inode->i_atime.tv_nsec);
	ufs_inode->ui_ctime = cpu_to_fs64(sb, inode->i_ctime.tv_sec);
	ufs_inode->ui_ctimensec = cpu_to_fs32(sb, inode->i_ctime.tv_nsec);
	ufs_inode->ui_mtime = cpu_to_fs64(sb, inode->i_mtime.tv_sec);
	ufs_inode->ui_mtimensec = cpu_to_fs32(sb, inode->i_mtime.tv_nsec);
764 765 766 767 768 769 770 771 772

	ufs_inode->ui_blocks = cpu_to_fs64(sb, inode->i_blocks);
	ufs_inode->ui_flags = cpu_to_fs32(sb, ufsi->i_flags);
	ufs_inode->ui_gen = cpu_to_fs32(sb, inode->i_generation);

	if (S_ISCHR(inode->i_mode) || S_ISBLK(inode->i_mode)) {
		/* ufs_inode->ui_u2.ui_addr.ui_db[0] = cpu_to_fs32(sb, inode->i_rdev); */
		ufs_inode->ui_u2.ui_addr.ui_db[0] = ufsi->i_u1.u2_i_data[0];
	} else if (inode->i_blocks) {
773 774
		memcpy(&ufs_inode->ui_u2.ui_addr, ufsi->i_u1.u2_i_data,
		       sizeof(ufs_inode->ui_u2.ui_addr));
775
	} else {
776 777
		memcpy(&ufs_inode->ui_u2.ui_symlink, ufsi->i_u1.i_symlink,
		       sizeof(ufs_inode->ui_u2.ui_symlink));
778 779 780 781 782 783 784 785 786 787 788 789 790 791 792 793 794 795 796 797 798 799 800 801 802 803 804 805 806 807 808 809 810 811 812 813
 	}

	if (!inode->i_nlink)
		memset (ufs_inode, 0, sizeof(struct ufs2_inode));
	UFSD("EXIT\n");
}

static int ufs_update_inode(struct inode * inode, int do_sync)
{
	struct super_block *sb = inode->i_sb;
	struct ufs_sb_private_info *uspi = UFS_SB(sb)->s_uspi;
	struct buffer_head * bh;

	UFSD("ENTER, ino %lu\n", inode->i_ino);

	if (inode->i_ino < UFS_ROOTINO ||
	    inode->i_ino > (uspi->s_ncg * uspi->s_ipg)) {
		ufs_warning (sb, "ufs_read_inode", "bad inode number (%lu)\n", inode->i_ino);
		return -1;
	}

	bh = sb_bread(sb, ufs_inotofsba(inode->i_ino));
	if (!bh) {
		ufs_warning (sb, "ufs_read_inode", "unable to read inode %lu\n", inode->i_ino);
		return -1;
	}
	if (uspi->fs_magic == UFS2_MAGIC) {
		struct ufs2_inode *ufs2_inode = (struct ufs2_inode *)bh->b_data;

		ufs2_update_inode(inode,
				  ufs2_inode + ufs_inotofsbo(inode->i_ino));
	} else {
		struct ufs_inode *ufs_inode = (struct ufs_inode *) bh->b_data;

		ufs1_update_inode(inode, ufs_inode + ufs_inotofsbo(inode->i_ino));
	}
A
Al Viro 已提交
814

L
Linus Torvalds 已提交
815 816 817 818
	mark_buffer_dirty(bh);
	if (do_sync)
		sync_dirty_buffer(bh);
	brelse (bh);
A
Al Viro 已提交
819

E
Evgeniy Dushistov 已提交
820
	UFSD("EXIT\n");
L
Linus Torvalds 已提交
821 822 823
	return 0;
}

824
int ufs_write_inode(struct inode *inode, struct writeback_control *wbc)
L
Linus Torvalds 已提交
825
{
A
Al Viro 已提交
826
	return ufs_update_inode(inode, wbc->sync_mode == WB_SYNC_ALL);
L
Linus Torvalds 已提交
827 828 829 830 831 832 833
}

int ufs_sync_inode (struct inode *inode)
{
	return ufs_update_inode (inode, 1);
}

A
Al Viro 已提交
834
void ufs_evict_inode(struct inode * inode)
L
Linus Torvalds 已提交
835
{
A
Al Viro 已提交
836 837 838 839
	int want_delete = 0;

	if (!inode->i_nlink && !is_bad_inode(inode))
		want_delete = 1;
840

841
	truncate_inode_pages_final(&inode->i_data);
A
Al Viro 已提交
842 843
	if (want_delete) {
		inode->i_size = 0;
844 845
		if (inode->i_blocks)
			ufs_truncate_blocks(inode);
A
Al Viro 已提交
846 847 848
	}

	invalidate_inode_buffers(inode);
849
	clear_inode(inode);
A
Al Viro 已提交
850

A
Al Viro 已提交
851
	if (want_delete)
852
		ufs_free_inode(inode);
L
Linus Torvalds 已提交
853
}
A
Al Viro 已提交
854

855 856 857 858 859 860 861 862 863 864 865 866 867 868 869 870
struct to_free {
	struct inode *inode;
	u64 to;
	unsigned count;
};

static inline void free_data(struct to_free *ctx, u64 from, unsigned count)
{
	if (ctx->count && ctx->to != from) {
		ufs_free_blocks(ctx->inode, ctx->to - ctx->count, ctx->count);
		ctx->count = 0;
	}
	ctx->count += count;
	ctx->to = from + count;
}

A
Al Viro 已提交
871 872 873 874 875 876 877 878 879 880
#define DIRECT_BLOCK ((inode->i_size + uspi->s_bsize - 1) >> uspi->s_bshift)
#define DIRECT_FRAGMENT ((inode->i_size + uspi->s_fsize - 1) >> uspi->s_fshift)

static void ufs_trunc_direct(struct inode *inode)
{
	struct ufs_inode_info *ufsi = UFS_I(inode);
	struct super_block * sb;
	struct ufs_sb_private_info * uspi;
	void *p;
	u64 frag1, frag2, frag3, frag4, block1, block2;
881
	struct to_free ctx = {.inode = inode};
A
Al Viro 已提交
882 883 884 885 886 887 888 889 890 891 892 893 894 895 896 897 898 899 900 901 902 903 904 905 906 907 908 909 910 911 912 913 914 915 916 917 918 919 920 921 922 923 924 925 926 927 928 929 930 931 932 933 934 935
	unsigned i, tmp;

	UFSD("ENTER: ino %lu\n", inode->i_ino);

	sb = inode->i_sb;
	uspi = UFS_SB(sb)->s_uspi;

	frag1 = DIRECT_FRAGMENT;
	frag4 = min_t(u64, UFS_NDIR_FRAGMENT, ufsi->i_lastfrag);
	frag2 = ((frag1 & uspi->s_fpbmask) ? ((frag1 | uspi->s_fpbmask) + 1) : frag1);
	frag3 = frag4 & ~uspi->s_fpbmask;
	block1 = block2 = 0;
	if (frag2 > frag3) {
		frag2 = frag4;
		frag3 = frag4 = 0;
	} else if (frag2 < frag3) {
		block1 = ufs_fragstoblks (frag2);
		block2 = ufs_fragstoblks (frag3);
	}

	UFSD("ino %lu, frag1 %llu, frag2 %llu, block1 %llu, block2 %llu,"
	     " frag3 %llu, frag4 %llu\n", inode->i_ino,
	     (unsigned long long)frag1, (unsigned long long)frag2,
	     (unsigned long long)block1, (unsigned long long)block2,
	     (unsigned long long)frag3, (unsigned long long)frag4);

	if (frag1 >= frag2)
		goto next1;

	/*
	 * Free first free fragments
	 */
	p = ufs_get_direct_data_ptr(uspi, ufsi, ufs_fragstoblks(frag1));
	tmp = ufs_data_ptr_to_cpu(sb, p);
	if (!tmp )
		ufs_panic (sb, "ufs_trunc_direct", "internal error");
	frag2 -= frag1;
	frag1 = ufs_fragnum (frag1);

	ufs_free_fragments(inode, tmp + frag1, frag2);

next1:
	/*
	 * Free whole blocks
	 */
	for (i = block1 ; i < block2; i++) {
		p = ufs_get_direct_data_ptr(uspi, ufsi, i);
		tmp = ufs_data_ptr_to_cpu(sb, p);
		if (!tmp)
			continue;
		write_seqlock(&ufsi->meta_lock);
		ufs_data_ptr_clear(uspi, p);
		write_sequnlock(&ufsi->meta_lock);

936
		free_data(&ctx, tmp, uspi->s_fpb);
A
Al Viro 已提交
937 938
	}

939
	free_data(&ctx, 0, 0);
A
Al Viro 已提交
940 941 942 943 944 945 946 947 948 949 950 951 952 953 954 955 956 957 958 959 960 961

	if (frag3 >= frag4)
		goto next3;

	/*
	 * Free last free fragments
	 */
	p = ufs_get_direct_data_ptr(uspi, ufsi, ufs_fragstoblks(frag3));
	tmp = ufs_data_ptr_to_cpu(sb, p);
	if (!tmp )
		ufs_panic(sb, "ufs_truncate_direct", "internal error");
	frag4 = ufs_fragnum (frag4);
	write_seqlock(&ufsi->meta_lock);
	ufs_data_ptr_clear(uspi, p);
	write_sequnlock(&ufsi->meta_lock);

	ufs_free_fragments (inode, tmp, frag4);
 next3:

	UFSD("EXIT: ino %lu\n", inode->i_ino);
}

962
static void free_full_branch(struct inode *inode, u64 ind_block, int depth)
963 964 965
{
	struct super_block *sb = inode->i_sb;
	struct ufs_sb_private_info *uspi = UFS_SB(sb)->s_uspi;
966
	struct ufs_buffer_head *ubh = ubh_bread(sb, ind_block, uspi->s_bsize);
967 968
	unsigned i;

969
	if (!ubh)
970 971 972
		return;

	if (--depth) {
973 974 975
		for (i = 0; i < uspi->s_apb; i++) {
			void *p = ubh_get_data_ptr(uspi, ubh, i);
			u64 block = ufs_data_ptr_to_cpu(sb, p);
976
			if (block)
977
				free_full_branch(inode, block, depth);
978 979 980 981 982
		}
	} else {
		struct to_free ctx = {.inode = inode};

		for (i = 0; i < uspi->s_apb; i++) {
983 984
			void *p = ubh_get_data_ptr(uspi, ubh, i);
			u64 block = ufs_data_ptr_to_cpu(sb, p);
985
			if (block)
986
				free_data(&ctx, block, uspi->s_fpb);
987 988 989 990 991
		}
		free_data(&ctx, 0, 0);
	}

	ubh_bforget(ubh);
992
	ufs_free_blocks(inode, ind_block, uspi->s_fpb);
993 994
}

A
Al Viro 已提交
995
static void free_branch_tail(struct inode *inode, unsigned from, struct ufs_buffer_head *ubh, int depth)
A
Al Viro 已提交
996
{
997 998 999
	struct super_block *sb = inode->i_sb;
	struct ufs_sb_private_info *uspi = UFS_SB(sb)->s_uspi;
	unsigned i;
A
Al Viro 已提交
1000

A
Al Viro 已提交
1001
	if (--depth) {
A
Al Viro 已提交
1002
		for (i = from; i < uspi->s_apb ; i++) {
1003 1004 1005 1006 1007 1008 1009 1010 1011
			void *p = ubh_get_data_ptr(uspi, ubh, i);
			u64 block = ufs_data_ptr_to_cpu(sb, p);
			if (block) {
				write_seqlock(&UFS_I(inode)->meta_lock);
				ufs_data_ptr_clear(uspi, p);
				write_sequnlock(&UFS_I(inode)->meta_lock);
				ubh_mark_buffer_dirty(ubh);
				free_full_branch(inode, block, depth);
			}
1012
		}
A
Al Viro 已提交
1013
	} else {
1014
		struct to_free ctx = {.inode = inode};
A
Al Viro 已提交
1015 1016

		for (i = from; i < uspi->s_apb; i++) {
1017 1018 1019 1020 1021 1022 1023 1024 1025
			void *p = ubh_get_data_ptr(uspi, ubh, i);
			u64 block = ufs_data_ptr_to_cpu(sb, p);
			if (block) {
				write_seqlock(&UFS_I(inode)->meta_lock);
				ufs_data_ptr_clear(uspi, p);
				write_sequnlock(&UFS_I(inode)->meta_lock);
				ubh_mark_buffer_dirty(ubh);
				free_data(&ctx, block, uspi->s_fpb);
			}
A
Al Viro 已提交
1026
		}
1027
		free_data(&ctx, 0, 0);
A
Al Viro 已提交
1028
	}
A
Al Viro 已提交
1029 1030 1031
	if (IS_SYNC(inode) && ubh_buffer_dirty(ubh))
		ubh_sync_block(ubh);
	ubh_brelse(ubh);
A
Al Viro 已提交
1032 1033 1034 1035 1036 1037 1038 1039 1040 1041 1042 1043 1044 1045 1046 1047 1048 1049 1050 1051 1052 1053
}

static int ufs_alloc_lastblock(struct inode *inode, loff_t size)
{
	int err = 0;
	struct super_block *sb = inode->i_sb;
	struct address_space *mapping = inode->i_mapping;
	struct ufs_sb_private_info *uspi = UFS_SB(sb)->s_uspi;
	unsigned i, end;
	sector_t lastfrag;
	struct page *lastpage;
	struct buffer_head *bh;
	u64 phys64;

	lastfrag = (size + uspi->s_fsize - 1) >> uspi->s_fshift;

	if (!lastfrag)
		goto out;

	lastfrag--;

	lastpage = ufs_get_locked_page(mapping, lastfrag >>
1054
				       (PAGE_SHIFT - inode->i_blkbits));
A
Al Viro 已提交
1055 1056 1057 1058 1059
       if (IS_ERR(lastpage)) {
               err = -EIO;
               goto out;
       }

1060
       end = lastfrag & ((1 << (PAGE_SHIFT - inode->i_blkbits)) - 1);
A
Al Viro 已提交
1061 1062 1063 1064 1065 1066 1067 1068 1069 1070 1071 1072
       bh = page_buffers(lastpage);
       for (i = 0; i < end; ++i)
               bh = bh->b_this_page;


       err = ufs_getfrag_block(inode, lastfrag, bh, 1);

       if (unlikely(err))
	       goto out_unlock;

       if (buffer_new(bh)) {
	       clear_buffer_new(bh);
1073
	       clean_bdev_bh_alias(bh);
A
Al Viro 已提交
1074 1075 1076 1077 1078 1079 1080 1081 1082 1083 1084 1085 1086 1087 1088 1089 1090 1091 1092 1093 1094 1095 1096 1097 1098 1099 1100 1101 1102 1103 1104 1105 1106 1107
	       /*
		* we do not zeroize fragment, because of
		* if it maped to hole, it already contains zeroes
		*/
	       set_buffer_uptodate(bh);
	       mark_buffer_dirty(bh);
	       set_page_dirty(lastpage);
       }

       if (lastfrag >= UFS_IND_FRAGMENT) {
	       end = uspi->s_fpb - ufs_fragnum(lastfrag) - 1;
	       phys64 = bh->b_blocknr + 1;
	       for (i = 0; i < end; ++i) {
		       bh = sb_getblk(sb, i + phys64);
		       lock_buffer(bh);
		       memset(bh->b_data, 0, sb->s_blocksize);
		       set_buffer_uptodate(bh);
		       mark_buffer_dirty(bh);
		       unlock_buffer(bh);
		       sync_dirty_buffer(bh);
		       brelse(bh);
	       }
       }
out_unlock:
       ufs_put_locked_page(lastpage);
out:
       return err;
}

static void __ufs_truncate_blocks(struct inode *inode)
{
	struct ufs_inode_info *ufsi = UFS_I(inode);
	struct super_block *sb = inode->i_sb;
	struct ufs_sb_private_info *uspi = UFS_SB(sb)->s_uspi;
1108
	unsigned offsets[4];
1109
	int depth = ufs_block_to_path(inode, DIRECT_BLOCK, offsets);
1110
	int depth2;
1111
	unsigned i;
A
Al Viro 已提交
1112 1113 1114
	struct ufs_buffer_head *ubh[3];
	void *p;
	u64 block;
1115 1116 1117 1118 1119 1120 1121 1122

	if (!depth)
		return;

	/* find the last non-zero in offsets[] */
	for (depth2 = depth - 1; depth2; depth2--)
		if (offsets[depth2])
			break;
A
Al Viro 已提交
1123 1124

	mutex_lock(&ufsi->truncate_mutex);
1125
	if (depth == 1) {
1126
		ufs_trunc_direct(inode);
1127 1128
		offsets[0] = UFS_IND_BLOCK;
	} else {
A
Al Viro 已提交
1129 1130 1131 1132 1133 1134 1135 1136 1137 1138 1139 1140 1141 1142 1143 1144
		/* get the blocks that should be partially emptied */
		p = ufs_get_direct_data_ptr(uspi, ufsi, offsets[0]);
		for (i = 0; i < depth2; i++) {
			offsets[i]++;	/* next branch is fully freed */
			block = ufs_data_ptr_to_cpu(sb, p);
			if (!block)
				break;
			ubh[i] = ubh_bread(sb, block, uspi->s_bsize);
			if (!ubh[i]) {
				write_seqlock(&ufsi->meta_lock);
				ufs_data_ptr_clear(uspi, p);
				write_sequnlock(&ufsi->meta_lock);
				break;
			}
			p = ubh_get_data_ptr(uspi, ubh[i], offsets[i + 1]);
		}
1145
		while (i--)
A
Al Viro 已提交
1146
			free_branch_tail(inode, offsets[i + 1], ubh[i], depth - i - 1);
1147 1148
	}
	for (i = offsets[0]; i <= UFS_TIND_BLOCK; i++) {
1149 1150 1151 1152 1153 1154 1155 1156
		p = ufs_get_direct_data_ptr(uspi, ufsi, i);
		block = ufs_data_ptr_to_cpu(sb, p);
		if (block) {
			write_seqlock(&ufsi->meta_lock);
			ufs_data_ptr_clear(uspi, p);
			write_sequnlock(&ufsi->meta_lock);
			free_full_branch(inode, block, i - UFS_IND_BLOCK + 1);
		}
1157
	}
A
Al Viro 已提交
1158
	ufsi->i_lastfrag = DIRECT_FRAGMENT;
1159
	mark_inode_dirty(inode);
A
Al Viro 已提交
1160 1161 1162 1163 1164 1165 1166 1167 1168 1169 1170 1171 1172 1173 1174 1175 1176 1177 1178 1179 1180 1181 1182 1183 1184 1185 1186
	mutex_unlock(&ufsi->truncate_mutex);
}

static int ufs_truncate(struct inode *inode, loff_t size)
{
	int err = 0;

	UFSD("ENTER: ino %lu, i_size: %llu, old_i_size: %llu\n",
	     inode->i_ino, (unsigned long long)size,
	     (unsigned long long)i_size_read(inode));

	if (!(S_ISREG(inode->i_mode) || S_ISDIR(inode->i_mode) ||
	      S_ISLNK(inode->i_mode)))
		return -EINVAL;
	if (IS_APPEND(inode) || IS_IMMUTABLE(inode))
		return -EPERM;

	err = ufs_alloc_lastblock(inode, size);

	if (err)
		goto out;

	block_truncate_page(inode->i_mapping, size, ufs_getfrag_block);

	truncate_setsize(inode, size);

	__ufs_truncate_blocks(inode);
1187
	inode->i_mtime = inode->i_ctime = current_time(inode);
A
Al Viro 已提交
1188 1189 1190 1191 1192 1193 1194 1195 1196 1197 1198 1199 1200 1201 1202 1203 1204 1205 1206 1207 1208 1209
	mark_inode_dirty(inode);
out:
	UFSD("EXIT: err %d\n", err);
	return err;
}

void ufs_truncate_blocks(struct inode *inode)
{
	if (!(S_ISREG(inode->i_mode) || S_ISDIR(inode->i_mode) ||
	      S_ISLNK(inode->i_mode)))
		return;
	if (IS_APPEND(inode) || IS_IMMUTABLE(inode))
		return;
	__ufs_truncate_blocks(inode);
}

int ufs_setattr(struct dentry *dentry, struct iattr *attr)
{
	struct inode *inode = d_inode(dentry);
	unsigned int ia_valid = attr->ia_valid;
	int error;

1210
	error = setattr_prepare(dentry, attr);
A
Al Viro 已提交
1211 1212 1213 1214 1215 1216 1217 1218 1219 1220 1221 1222 1223 1224 1225 1226 1227
	if (error)
		return error;

	if (ia_valid & ATTR_SIZE && attr->ia_size != inode->i_size) {
		error = ufs_truncate(inode, attr->ia_size);
		if (error)
			return error;
	}

	setattr_copy(inode, attr);
	mark_inode_dirty(inode);
	return 0;
}

const struct inode_operations ufs_file_inode_operations = {
	.setattr = ufs_setattr,
};