Release 4.10 fs/ufs/inode.c
/*
* 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 <linux/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>
#include <linux/writeback.h>
#include "ufs_fs.h"
#include "ufs.h"
#include "swab.h"
#include "util.h"
static int ufs_block_to_path(struct inode *inode, sector_t i_block, unsigned offsets[4])
{
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;
UFSD("ptrs=uspi->s_apb = %d,double_blocks=%ld \n",ptrs,double_blocks);
if (i_block < direct_blocks) {
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;
}
Contributors
| Person | Tokens | Prop | Commits | CommitProp |
linus torvalds | linus torvalds | 182 | 68.42% | 1 | 12.50% |
pre-git | pre-git | 70 | 26.32% | 2 | 25.00% |
andrew morton | andrew morton | 7 | 2.63% | 1 | 12.50% |
dave jones | dave jones | 3 | 1.13% | 1 | 12.50% |
evgeniy dushistov | evgeniy dushistov | 3 | 1.13% | 2 | 25.00% |
al viro | al viro | 1 | 0.38% | 1 | 12.50% |
| Total | 266 | 100.00% | 8 | 100.00% |
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);
}
Contributors
| Person | Tokens | Prop | Commits | CommitProp |
al viro | al viro | 119 | 100.00% | 1 | 100.00% |
| Total | 119 | 100.00% | 1 | 100.00% |
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);
}
Contributors
| Person | Tokens | Prop | Commits | CommitProp |
al viro | al viro | 119 | 100.00% | 1 | 100.00% |
| Total | 119 | 100.00% | 1 | 100.00% |
/*
* Returns the location of the fragment from
* the beginning of the filesystem.
*/
static u64 ufs_frag_map(struct inode *inode, unsigned offsets[4], int depth)
{
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;
Indirect chain[4], *q = chain;
unsigned *p;
unsigned flags = UFS_SB(sb)->s_flags;
u64 res = 0;
UFSD(": uspi->s_fpbshift = %d ,uspi->s_apbmask = %x, mask=%llx\n",
uspi->s_fpbshift, uspi->s_apbmask,
(unsigned long long)mask);
if (depth == 0)
goto no_block;
again:
p = offsets;
if ((flags & UFS_TYPE_MASK) == UFS_TYPE_UFS2)
goto ufs2;
if (!grow_chain32(ufsi, NULL, &ufsi->i_u1.i_data[*p++], chain, q))
goto changed;
if (!q->key32)
goto no_block;
while (--depth) {
__fs32 *ptr;
struct buffer_head *bh;
unsigned n = *p++;
bh = sb_bread(sb, uspi->s_sbbase +
fs32_to_cpu(sb, q->key32) + (n>>shift));
if (!bh)
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;
}
res = fs32_to_cpu(sb, q->key32);
goto found;
ufs2:
if (!grow_chain64(ufsi, NULL, &ufsi->i_u1.u2_i_data[*p++], chain, q))
goto changed;
if (!q->key64)
goto no_block;
while (--depth) {
__fs64 *ptr;
struct buffer_head *bh;
unsigned n = *p++;
bh = sb_bread(sb, uspi->s_sbbase +
fs64_to_cpu(sb, q->key64) + (n>>shift));
if (!bh)
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:
res += uspi->s_sbbase;
no_block:
while (q > chain) {
brelse(q->bh);
q--;
}
return res;
changed:
while (q > chain) {
brelse(q->bh);
q--;
}
goto again;
}
Contributors
| Person | Tokens | Prop | Commits | CommitProp |
al viro | al viro | 204 | 39.31% | 4 | 22.22% |
andrew morton | andrew morton | 137 | 26.40% | 3 | 16.67% |
linus torvalds | linus torvalds | 106 | 20.42% | 4 | 22.22% |
pre-git | pre-git | 59 | 11.37% | 3 | 16.67% |
arnd bergmann | arnd bergmann | 6 | 1.16% | 1 | 5.56% |
evgeniy dushistov | evgeniy dushistov | 3 | 0.58% | 1 | 5.56% |
dave jones | dave jones | 3 | 0.58% | 1 | 5.56% |
adrian bunk | adrian bunk | 1 | 0.19% | 1 | 5.56% |
| Total | 519 | 100.00% | 18 | 100.00% |
/*
* 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;
}
Contributors
| Person | Tokens | Prop | Commits | CommitProp |
al viro | al viro | 151 | 100.00% | 1 | 100.00% |
| Total | 151 | 100.00% | 1 | 100.00% |
/**
* ufs_inode_getfrag() - allocate new fragment(s)
* @inode: pointer to inode
* @index: number of block pointer within the inode's array.
* @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()
*/
static u64
ufs_inode_getfrag(struct inode *inode, unsigned index,
sector_t new_fragment, int *err,
int *new, 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;
u64 tmp, goal, lastfrag;
unsigned nfrags = uspi->s_fpb;
void *p;
/* TODO : to be done for write support
if ( (flags & UFS_TYPE_MASK) == UFS_TYPE_UFS2)
goto ufs2;
*/
p = ufs_get_direct_data_ptr(uspi, ufsi, index);
tmp = ufs_data_ptr_to_cpu(sb, p);
if (tmp)
goto out;
lastfrag = ufsi->i_lastfrag;
/* will that be a new tail? */
if (new_fragment < UFS_NDIR_FRAGMENT && new_fragment >= lastfrag)
nfrags = (new_fragment & uspi->s_fpbmask) + 1;
goal = 0;
if (index) {
goal = ufs_data_ptr_to_cpu(sb,
ufs_get_direct_data_ptr(uspi, ufsi, index - 1));
if (goal)
goal += uspi->s_fpb;
}
tmp = ufs_new_fragments(inode, p, ufs_blknum(new_fragment),
goal, uspi->s_fpb, err, locked_page);
if (!tmp) {
*err = -ENOSPC;
return 0;
}
if (new)
*new = 1;
inode->i_ctime = current_time(inode);
if (IS_SYNC(inode))
ufs_sync_inode (inode);
mark_inode_dirty(inode);
out:
return tmp + uspi->s_sbbase;
/* 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;
*/
}
Contributors
| Person | Tokens | Prop | Commits | CommitProp |
pre-git | pre-git | 131 | 50.58% | 3 | 18.75% |
evgeniy dushistov | evgeniy dushistov | 55 | 21.24% | 4 | 25.00% |
al viro | al viro | 50 | 19.31% | 5 | 31.25% |
linus torvalds | linus torvalds | 17 | 6.56% | 2 | 12.50% |
deepa dinamani | deepa dinamani | 4 | 1.54% | 1 | 6.25% |
andrew morton | andrew morton | 2 | 0.77% | 1 | 6.25% |
| Total | 259 | 100.00% | 16 | 100.00% |
/**
* ufs_inode_getblock() - allocate new block
* @inode: pointer to inode
* @ind_block: block number of the indirect block
* @index: number of pointer within the indirect block
* @new_fragment: number of new allocated fragment
* (block will hold this fragment and also uspi->s_fpb-1)
* @err: see ufs_inode_getfrag()
* @new: see ufs_inode_getfrag()
* @locked_page: see ufs_inode_getfrag()
*/
static u64
ufs_inode_getblock(struct inode *inode, u64 ind_block,
unsigned index, sector_t new_fragment, int *err,
int *new, struct page *locked_page)
{
struct super_block *sb = inode->i_sb;
struct ufs_sb_private_info *uspi = UFS_SB(sb)->s_uspi;
int shift = uspi->s_apbshift - uspi->s_fpbshift;
u64 tmp = 0, goal;
struct buffer_head *bh;
void *p;
if (!ind_block)
return 0;
bh = sb_bread(sb, ind_block + (index >> shift));
if (unlikely(!bh)) {
*err = -EIO;
return 0;
}
index &= uspi->s_apbmask >> uspi->s_fpbshift;
if (uspi->fs_magic == UFS2_MAGIC)
p = (__fs64 *)bh->b_data + index;
else
p = (__fs32 *)bh->b_data + index;
tmp = ufs_data_ptr_to_cpu(sb, p);
if (tmp)
goto out;
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]))))
goal = tmp + uspi->s_fpb;
else
goal = bh->b_blocknr + uspi->s_fpb;
tmp = ufs_new_fragments(inode, p, ufs_blknum(new_fragment), goal,
uspi->s_fpb, err, locked_page);
if (!tmp)
goto out;
if (new)
*new = 1;
mark_buffer_dirty(bh);
if (IS_SYNC(inode))
sync_dirty_buffer(bh);
inode->i_ctime = current_time(inode);
mark_inode_dirty(inode);
out:
brelse (bh);
UFSD("EXIT\n");
if (tmp)
tmp += uspi->s_sbbase;
return tmp;
}
Contributors
| Person | Tokens | Prop | Commits | CommitProp |
pre-git | pre-git | 190 | 53.07% | 3 | 18.75% |
al viro | al viro | 83 | 23.18% | 6 | 37.50% |
evgeniy dushistov | evgeniy dushistov | 75 | 20.95% | 4 | 25.00% |
linus torvalds | linus torvalds | 5 | 1.40% | 1 | 6.25% |
deepa dinamani | deepa dinamani | 4 | 1.12% | 1 | 6.25% |
andrew morton | andrew morton | 1 | 0.28% | 1 | 6.25% |
| Total | 358 | 100.00% | 16 | 100.00% |
/**
* ufs_getfrag_block() - `get_block_t' function, interface between UFS and
* readpage, writepage and so on
*/
static int ufs_getfrag_block(struct inode *inode, sector_t fragment, struct buffer_head *bh_result, int create)
{
struct super_block *sb = inode->i_sb;
struct ufs_sb_private_info *uspi = UFS_SB(sb)->s_uspi;
int err = 0, new = 0;
unsigned offsets[4];
int depth = ufs_block_to_path(inode, fragment >> uspi->s_fpbshift, offsets);
u64 phys64 = 0;
unsigned frag = fragment & uspi->s_fpbmask;
if (!create) {
phys64 = ufs_frag_map(inode, offsets, depth);
goto out;
}
/* This code entered only while writing ....? */
mutex_lock(&UFS_I(inode)->truncate_mutex);
UFSD("ENTER, ino %lu, fragment %llu\n", inode->i_ino, (unsigned long long)fragment);
if (unlikely(!depth)) {
ufs_warning(sb, "ufs_get_block", "block > big");
err = -EIO;
goto out;
}
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))
goto out;
}
}
if (depth == 1) {
phys64 = ufs_inode_getfrag(inode, offsets[0], fragment,
&err, &new, bh_result->b_page);
} else {
int i;
phys64 = ufs_inode_getfrag(inode, offsets[0], fragment,
&err, NULL, NULL);
for (i = 1; i < depth - 1; i++)
phys64 = ufs_inode_getblock(inode, phys64, offsets[i],
fragment, &err, NULL, NULL);
phys64 = ufs_inode_getblock(inode, phys64, offsets[depth - 1],
fragment, &err, &new, bh_result->b_page);
}
out:
if (phys64) {
phys64 += frag;
map_bh(bh_result, sb, phys64);
if (new)
set_buffer_new(bh_result);
}
mutex_unlock(&UFS_I(inode)->truncate_mutex);
return err;
}
Contributors
| Person | Tokens | Prop | Commits | CommitProp |
al viro | al viro | 265 | 67.09% | 12 | 50.00% |
pre-git | pre-git | 88 | 22.28% | 3 | 12.50% |
evgeniy dushistov | evgeniy dushistov | 14 | 3.54% | 2 | 8.33% |
andrew morton | andrew morton | 12 | 3.04% | 3 | 12.50% |
linus torvalds | linus torvalds | 9 | 2.28% | 2 | 8.33% |
arnd bergmann | arnd bergmann | 4 | 1.01% | 1 | 4.17% |
dave jones | dave jones | 3 | 0.76% | 1 | 4.17% |
| Total | 395 | 100.00% | 24 | 100.00% |
static int ufs_writepage(struct page *page, struct writeback_control *wbc)
{
return block_write_full_page(page,ufs_getfrag_block,wbc);
}
Contributors
| Person | Tokens | Prop | Commits | CommitProp |
pre-git | pre-git | 19 | 73.08% | 1 | 50.00% |
andrew morton | andrew morton | 7 | 26.92% | 1 | 50.00% |
| Total | 26 | 100.00% | 2 | 100.00% |
static int ufs_readpage(struct file *file, struct page *page)
{
return block_read_full_page(page,ufs_getfrag_block);
}
Contributors
| Person | Tokens | Prop | Commits | CommitProp |
pre-git | pre-git | 24 | 100.00% | 2 | 100.00% |
| Total | 24 | 100.00% | 2 | 100.00% |
int ufs_prepare_chunk(struct page *page, loff_t pos, unsigned len)
{
return __block_write_begin(page, pos, len, ufs_getfrag_block);
}
Contributors
| Person | Tokens | Prop | Commits | CommitProp |
pre-git | pre-git | 15 | 53.57% | 1 | 25.00% |
nick piggin | nick piggin | 8 | 28.57% | 1 | 25.00% |
christoph hellwig | christoph hellwig | 5 | 17.86% | 2 | 50.00% |
| Total | 28 | 100.00% | 4 | 100.00% |
static void ufs_truncate_blocks(struct inode *);
static void ufs_write_failed(struct address_space *mapping, loff_t to)
{
struct inode *inode = mapping->host;
if (to > inode->i_size) {
truncate_pagecache(inode, inode->i_size);
ufs_truncate_blocks(inode);
}
}
Contributors
| Person | Tokens | Prop | Commits | CommitProp |
marco stornelli | marco stornelli | 40 | 85.11% | 1 | 50.00% |
al viro | al viro | 7 | 14.89% | 1 | 50.00% |
| Total | 47 | 100.00% | 2 | 100.00% |
static int ufs_write_begin(struct file *file, struct address_space *mapping,
loff_t pos, unsigned len, unsigned flags,
struct page **pagep, void **fsdata)
{
int ret;
ret = block_write_begin(mapping, pos, len, flags, pagep,
ufs_getfrag_block);
if (unlikely(ret))
ufs_write_failed(mapping, pos + len);
return ret;
}
Contributors
| Person | Tokens | Prop | Commits | CommitProp |
nick piggin | nick piggin | 50 | 66.67% | 1 | 25.00% |
christoph hellwig | christoph hellwig | 22 | 29.33% | 2 | 50.00% |
marco stornelli | marco stornelli | 3 | 4.00% | 1 | 25.00% |
| Total | 75 | 100.00% | 4 | 100.00% |
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;
}
Contributors
| Person | Tokens | Prop | Commits | CommitProp |
al viro | al viro | 74 | 100.00% | 1 | 100.00% |
| Total | 74 | 100.00% | 1 | 100.00% |
static sector_t ufs_bmap(struct address_space *mapping, sector_t block)
{
return generic_block_bmap(mapping,block,ufs_getfrag_block);
}
Contributors
| Person | Tokens | Prop | Commits | CommitProp |
pre-git | pre-git | 22 | 91.67% | 1 | 50.00% |
andrew morton | andrew morton | 2 | 8.33% | 1 | 50.00% |
| Total | 24 | 100.00% | 2 | 100.00% |
const struct address_space_operations ufs_aops = {
.readpage = ufs_readpage,
.writepage = ufs_writepage,
.write_begin = ufs_write_begin,
.write_end = ufs_write_end,
.bmap = ufs_bmap
};
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)) {
if (!inode->i_blocks) {
inode->i_link = (char *)UFS_I(inode)->i_u1.i_symlink;
inode->i_op = &simple_symlink_inode_operations;
} else {
inode->i_mapping->a_ops = &ufs_aops;
inode->i_op = &page_symlink_inode_operations;
inode_nohighmem(inode);
}
} else
init_special_inode(inode, inode->i_mode,
ufs_get_inode_dev(inode->i_sb, UFS_I(inode)));
}
Contributors
| Person | Tokens | Prop | Commits | CommitProp |
evgeniy dushistov | evgeniy dushistov | 139 | 81.29% | 1 | 25.00% |
al viro | al viro | 32 | 18.71% | 3 | 75.00% |
| Total | 171 | 100.00% | 4 | 100.00% |
static int ufs1_read_inode(struct inode *inode, struct ufs_inode *ufs_inode)
{
struct ufs_inode_info *ufsi = UFS_I(inode);
struct super_block *sb = inode->i_sb;
umode_t mode;
/*
* Copy data to the in-core inode.
*/
inode->i_mode = mode = fs16_to_cpu(sb, ufs_inode->ui_mode);
set_nlink(inode, fs16_to_cpu(sb, ufs_inode->ui_nlink));
if (inode->i_nlink == 0) {
ufs_error (sb, "ufs_read_inode", "inode %lu has zero nlink\n", inode->i_ino);
return -1;
}
/*
* Linux now has 32-bit uid and gid, so we can support EFT.
*/
i_uid_write(inode, ufs_get_inode_uid(sb, ufs_inode));
i_gid_write(inode, ufs_get_inode_gid(sb, ufs_inode));
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);
inode->i_generation = fs32_to_cpu(sb, ufs_inode->ui_gen);
ufsi->i_flags = fs32_to_cpu(sb, ufs_inode->ui_flags);
ufsi->i_shadow = fs32_to_cpu(sb