Blame view
fs/ufs/inode.c
32.6 KB
1da177e4c Linux-2.6.12-rc2 |
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 |
/* * 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> |
1da177e4c Linux-2.6.12-rc2 |
29 30 31 |
#include <linux/errno.h> #include <linux/fs.h> |
1da177e4c Linux-2.6.12-rc2 |
32 33 34 35 |
#include <linux/time.h> #include <linux/stat.h> #include <linux/string.h> #include <linux/mm.h> |
1da177e4c Linux-2.6.12-rc2 |
36 |
#include <linux/buffer_head.h> |
a9185b41a pass writeback_co... |
37 |
#include <linux/writeback.h> |
1da177e4c Linux-2.6.12-rc2 |
38 |
|
e54205988 drop linux/ufs_fs... |
39 |
#include "ufs_fs.h" |
bcd6d4ecf ufs: move non-lay... |
40 |
#include "ufs.h" |
1da177e4c Linux-2.6.12-rc2 |
41 42 |
#include "swab.h" #include "util.h" |
4e3911f3d ufs: the offsets ... |
43 |
static int ufs_block_to_path(struct inode *inode, sector_t i_block, unsigned offsets[4]) |
1da177e4c Linux-2.6.12-rc2 |
44 45 46 47 48 49 50 51 |
{ 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; |
abf5d15fd [PATCH] ufs: easy... |
52 53 |
UFSD("ptrs=uspi->s_apb = %d,double_blocks=%ld ",ptrs,double_blocks); |
37044c86b ufs: sector_t can... |
54 |
if (i_block < direct_blocks) { |
1da177e4c Linux-2.6.12-rc2 |
55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 |
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; } |
724bb09fd ufs: don't use lo... |
73 74 75 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 |
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); } |
1da177e4c Linux-2.6.12-rc2 |
113 114 |
/* * Returns the location of the fragment from |
25985edce Fix common misspe... |
115 |
* the beginning of the filesystem. |
1da177e4c Linux-2.6.12-rc2 |
116 |
*/ |
4b7068c8b ufs: move calcula... |
117 |
static u64 ufs_frag_map(struct inode *inode, unsigned offsets[4], int depth) |
1da177e4c Linux-2.6.12-rc2 |
118 119 120 121 122 123 |
{ 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; |
724bb09fd ufs: don't use lo... |
124 |
Indirect chain[4], *q = chain; |
4b7068c8b ufs: move calcula... |
125 |
unsigned *p; |
1da177e4c Linux-2.6.12-rc2 |
126 |
unsigned flags = UFS_SB(sb)->s_flags; |
724bb09fd ufs: don't use lo... |
127 |
u64 res = 0; |
1da177e4c Linux-2.6.12-rc2 |
128 |
|
7256d819e [PATCH] ufs: prin... |
129 130 131 132 |
UFSD(": uspi->s_fpbshift = %d ,uspi->s_apbmask = %x, mask=%llx ", uspi->s_fpbshift, uspi->s_apbmask, (unsigned long long)mask); |
1da177e4c Linux-2.6.12-rc2 |
133 134 |
if (depth == 0) |
724bb09fd ufs: don't use lo... |
135 |
goto no_block; |
1da177e4c Linux-2.6.12-rc2 |
136 |
|
724bb09fd ufs: don't use lo... |
137 |
again: |
1da177e4c Linux-2.6.12-rc2 |
138 |
p = offsets; |
1da177e4c Linux-2.6.12-rc2 |
139 140 |
if ((flags & UFS_TYPE_MASK) == UFS_TYPE_UFS2) goto ufs2; |
724bb09fd ufs: don't use lo... |
141 142 143 144 |
if (!grow_chain32(ufsi, NULL, &ufsi->i_u1.i_data[*p++], chain, q)) goto changed; if (!q->key32) goto no_block; |
1da177e4c Linux-2.6.12-rc2 |
145 |
while (--depth) { |
724bb09fd ufs: don't use lo... |
146 |
__fs32 *ptr; |
1da177e4c Linux-2.6.12-rc2 |
147 |
struct buffer_head *bh; |
4e3911f3d ufs: the offsets ... |
148 |
unsigned n = *p++; |
1da177e4c Linux-2.6.12-rc2 |
149 |
|
724bb09fd ufs: don't use lo... |
150 151 |
bh = sb_bread(sb, uspi->s_sbbase + fs32_to_cpu(sb, q->key32) + (n>>shift)); |
1da177e4c Linux-2.6.12-rc2 |
152 |
if (!bh) |
724bb09fd ufs: don't use lo... |
153 154 155 156 157 158 |
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; |
1da177e4c Linux-2.6.12-rc2 |
159 |
} |
724bb09fd ufs: don't use lo... |
160 161 |
res = fs32_to_cpu(sb, q->key32); goto found; |
1da177e4c Linux-2.6.12-rc2 |
162 |
|
724bb09fd ufs: don't use lo... |
163 164 165 166 167 |
ufs2: if (!grow_chain64(ufsi, NULL, &ufsi->i_u1.u2_i_data[*p++], chain, q)) goto changed; if (!q->key64) goto no_block; |
1da177e4c Linux-2.6.12-rc2 |
168 169 |
while (--depth) { |
724bb09fd ufs: don't use lo... |
170 |
__fs64 *ptr; |
1da177e4c Linux-2.6.12-rc2 |
171 |
struct buffer_head *bh; |
4e3911f3d ufs: the offsets ... |
172 |
unsigned n = *p++; |
1da177e4c Linux-2.6.12-rc2 |
173 |
|
724bb09fd ufs: don't use lo... |
174 175 |
bh = sb_bread(sb, uspi->s_sbbase + fs64_to_cpu(sb, q->key64) + (n>>shift)); |
1da177e4c Linux-2.6.12-rc2 |
176 |
if (!bh) |
724bb09fd ufs: don't use lo... |
177 178 179 180 181 182 183 184 185 |
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: |
4b7068c8b ufs: move calcula... |
186 |
res += uspi->s_sbbase; |
724bb09fd ufs: don't use lo... |
187 188 189 190 |
no_block: while (q > chain) { brelse(q->bh); q--; |
1da177e4c Linux-2.6.12-rc2 |
191 |
} |
724bb09fd ufs: don't use lo... |
192 |
return res; |
1da177e4c Linux-2.6.12-rc2 |
193 |
|
724bb09fd ufs: don't use lo... |
194 195 196 197 198 199 |
changed: while (q > chain) { brelse(q->bh); q--; } goto again; |
1da177e4c Linux-2.6.12-rc2 |
200 |
} |
0f3c1294b ufs_inode_getfrag... |
201 202 203 204 205 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 |
/* * 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; } |
022a6dc5f [PATCH] ufs: zero... |
234 235 |
/** * ufs_inode_getfrag() - allocate new fragment(s) |
edc023caf fs/ufs/inode.c: k... |
236 |
* @inode: pointer to inode |
5336970be ufs_inode_getfrag... |
237 |
* @index: number of block pointer within the inode's array. |
edc023caf fs/ufs/inode.c: k... |
238 |
* @new_fragment: number of new allocated fragment(s) |
edc023caf fs/ufs/inode.c: k... |
239 |
* @err: we set it if something wrong |
edc023caf fs/ufs/inode.c: k... |
240 241 |
* @new: we set it if we allocate new block * @locked_page: for ufs_new_fragments() |
022a6dc5f [PATCH] ufs: zero... |
242 |
*/ |
177848a01 ufs_inode_get{fra... |
243 |
static u64 |
5336970be ufs_inode_getfrag... |
244 245 |
ufs_inode_getfrag(struct inode *inode, unsigned index, sector_t new_fragment, int *err, |
4e317ce73 ufs_inode_get{fra... |
246 |
int *new, struct page *locked_page) |
1da177e4c Linux-2.6.12-rc2 |
247 248 |
{ struct ufs_inode_info *ufsi = UFS_I(inode); |
022a6dc5f [PATCH] ufs: zero... |
249 250 |
struct super_block *sb = inode->i_sb; struct ufs_sb_private_info *uspi = UFS_SB(sb)->s_uspi; |
5336970be ufs_inode_getfrag... |
251 |
u64 tmp, goal, lastfrag; |
0f3c1294b ufs_inode_getfrag... |
252 253 |
unsigned nfrags = uspi->s_fpb; void *p; |
1da177e4c Linux-2.6.12-rc2 |
254 |
|
1da177e4c Linux-2.6.12-rc2 |
255 256 257 258 |
/* TODO : to be done for write support if ( (flags & UFS_TYPE_MASK) == UFS_TYPE_UFS2) goto ufs2; */ |
5336970be ufs_inode_getfrag... |
259 |
p = ufs_get_direct_data_ptr(uspi, ufsi, index); |
54fb996ac [PATCH] ufs2 writ... |
260 |
tmp = ufs_data_ptr_to_cpu(sb, p); |
0f3c1294b ufs_inode_getfrag... |
261 262 |
if (tmp) goto out; |
54fb996ac [PATCH] ufs2 writ... |
263 |
|
1da177e4c Linux-2.6.12-rc2 |
264 |
lastfrag = ufsi->i_lastfrag; |
1da177e4c Linux-2.6.12-rc2 |
265 |
|
0f3c1294b ufs_inode_getfrag... |
266 267 268 269 270 |
/* will that be a new tail? */ if (new_fragment < UFS_NDIR_FRAGMENT && new_fragment >= lastfrag) nfrags = (new_fragment & uspi->s_fpbmask) + 1; goal = 0; |
5336970be ufs_inode_getfrag... |
271 |
if (index) { |
0f3c1294b ufs_inode_getfrag... |
272 |
goal = ufs_data_ptr_to_cpu(sb, |
5336970be ufs_inode_getfrag... |
273 |
ufs_get_direct_data_ptr(uspi, ufsi, index - 1)); |
0f3c1294b ufs_inode_getfrag... |
274 275 |
if (goal) goal += uspi->s_fpb; |
1da177e4c Linux-2.6.12-rc2 |
276 |
} |
5336970be ufs_inode_getfrag... |
277 |
tmp = ufs_new_fragments(inode, p, ufs_blknum(new_fragment), |
4e317ce73 ufs_inode_get{fra... |
278 |
goal, uspi->s_fpb, err, locked_page); |
0f3c1294b ufs_inode_getfrag... |
279 |
|
1da177e4c Linux-2.6.12-rc2 |
280 |
if (!tmp) { |
1da177e4c Linux-2.6.12-rc2 |
281 |
*err = -ENOSPC; |
177848a01 ufs_inode_get{fra... |
282 |
return 0; |
1da177e4c Linux-2.6.12-rc2 |
283 |
} |
4e317ce73 ufs_inode_get{fra... |
284 |
if (new) |
1da177e4c Linux-2.6.12-rc2 |
285 |
*new = 1; |
02027d42c fs: Replace CURRE... |
286 |
inode->i_ctime = current_time(inode); |
1da177e4c Linux-2.6.12-rc2 |
287 288 289 |
if (IS_SYNC(inode)) ufs_sync_inode (inode); mark_inode_dirty(inode); |
bbb3eb9d3 ufs_inode_get{fra... |
290 |
out: |
177848a01 ufs_inode_get{fra... |
291 |
return tmp + uspi->s_sbbase; |
1da177e4c Linux-2.6.12-rc2 |
292 293 294 295 296 297 298 299 300 301 302 303 304 305 306 307 |
/* 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; */ } |
022a6dc5f [PATCH] ufs: zero... |
308 309 |
/** * ufs_inode_getblock() - allocate new block |
edc023caf fs/ufs/inode.c: k... |
310 |
* @inode: pointer to inode |
619cfac09 ufs_inode_getbloc... |
311 312 |
* @ind_block: block number of the indirect block * @index: number of pointer within the indirect block |
edc023caf fs/ufs/inode.c: k... |
313 |
* @new_fragment: number of new allocated fragment |
022a6dc5f [PATCH] ufs: zero... |
314 |
* (block will hold this fragment and also uspi->s_fpb-1) |
edc023caf fs/ufs/inode.c: k... |
315 |
* @err: see ufs_inode_getfrag() |
edc023caf fs/ufs/inode.c: k... |
316 317 |
* @new: see ufs_inode_getfrag() * @locked_page: see ufs_inode_getfrag() |
022a6dc5f [PATCH] ufs: zero... |
318 |
*/ |
177848a01 ufs_inode_get{fra... |
319 |
static u64 |
619cfac09 ufs_inode_getbloc... |
320 |
ufs_inode_getblock(struct inode *inode, u64 ind_block, |
721435a76 ufs_inode_getbloc... |
321 |
unsigned index, sector_t new_fragment, int *err, |
4e317ce73 ufs_inode_get{fra... |
322 |
int *new, struct page *locked_page) |
1da177e4c Linux-2.6.12-rc2 |
323 |
{ |
022a6dc5f [PATCH] ufs: zero... |
324 325 |
struct super_block *sb = inode->i_sb; struct ufs_sb_private_info *uspi = UFS_SB(sb)->s_uspi; |
619cfac09 ufs_inode_getbloc... |
326 |
int shift = uspi->s_apbshift - uspi->s_fpbshift; |
721435a76 ufs_inode_getbloc... |
327 |
u64 tmp = 0, goal; |
619cfac09 ufs_inode_getbloc... |
328 |
struct buffer_head *bh; |
54fb996ac [PATCH] ufs2 writ... |
329 |
void *p; |
1da177e4c Linux-2.6.12-rc2 |
330 |
|
619cfac09 ufs_inode_getbloc... |
331 332 333 334 |
if (!ind_block) return 0; bh = sb_bread(sb, ind_block + (index >> shift)); |
5fbfb238f ufs_inode_getbloc... |
335 336 |
if (unlikely(!bh)) { *err = -EIO; |
619cfac09 ufs_inode_getbloc... |
337 |
return 0; |
5fbfb238f ufs_inode_getbloc... |
338 |
} |
619cfac09 ufs_inode_getbloc... |
339 340 |
index &= uspi->s_apbmask >> uspi->s_fpbshift; |
54fb996ac [PATCH] ufs2 writ... |
341 |
if (uspi->fs_magic == UFS2_MAGIC) |
721435a76 ufs_inode_getbloc... |
342 |
p = (__fs64 *)bh->b_data + index; |
54fb996ac [PATCH] ufs2 writ... |
343 |
else |
721435a76 ufs_inode_getbloc... |
344 |
p = (__fs32 *)bh->b_data + index; |
5a39c2556 ufs_inode_get{fra... |
345 |
|
54fb996ac [PATCH] ufs2 writ... |
346 |
tmp = ufs_data_ptr_to_cpu(sb, p); |
bbb3eb9d3 ufs_inode_get{fra... |
347 |
if (tmp) |
5a39c2556 ufs_inode_get{fra... |
348 |
goto out; |
1da177e4c Linux-2.6.12-rc2 |
349 |
|
721435a76 ufs_inode_getbloc... |
350 351 352 |
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])))) |
1da177e4c Linux-2.6.12-rc2 |
353 354 355 |
goal = tmp + uspi->s_fpb; else goal = bh->b_blocknr + uspi->s_fpb; |
6ef4d6bf8 [PATCH] ufs: chan... |
356 357 |
tmp = ufs_new_fragments(inode, p, ufs_blknum(new_fragment), goal, uspi->s_fpb, err, locked_page); |
5a39c2556 ufs_inode_get{fra... |
358 |
if (!tmp) |
1da177e4c Linux-2.6.12-rc2 |
359 |
goto out; |
c9a27b5dc [PATCH] ufs: righ... |
360 |
|
bbb3eb9d3 ufs_inode_get{fra... |
361 |
if (new) |
1da177e4c Linux-2.6.12-rc2 |
362 |
*new = 1; |
1da177e4c Linux-2.6.12-rc2 |
363 364 365 366 |
mark_buffer_dirty(bh); if (IS_SYNC(inode)) sync_dirty_buffer(bh); |
02027d42c fs: Replace CURRE... |
367 |
inode->i_ctime = current_time(inode); |
1da177e4c Linux-2.6.12-rc2 |
368 369 370 |
mark_inode_dirty(inode); out: brelse (bh); |
abf5d15fd [PATCH] ufs: easy... |
371 372 |
UFSD("EXIT "); |
177848a01 ufs_inode_get{fra... |
373 374 375 |
if (tmp) tmp += uspi->s_sbbase; return tmp; |
1da177e4c Linux-2.6.12-rc2 |
376 |
} |
022a6dc5f [PATCH] ufs: zero... |
377 |
/** |
7422caa5a ufs: Fix a typo |
378 |
* ufs_getfrag_block() - `get_block_t' function, interface between UFS and |
022a6dc5f [PATCH] ufs: zero... |
379 |
* readpage, writepage and so on |
1da177e4c Linux-2.6.12-rc2 |
380 |
*/ |
010d331fc ufs: move truncat... |
381 |
static int ufs_getfrag_block(struct inode *inode, sector_t fragment, struct buffer_head *bh_result, int create) |
1da177e4c Linux-2.6.12-rc2 |
382 |
{ |
0385f1f9e ufs_getfrag_block... |
383 384 385 |
struct super_block *sb = inode->i_sb; struct ufs_sb_private_info *uspi = UFS_SB(sb)->s_uspi; int err = 0, new = 0; |
4b7068c8b ufs: move calcula... |
386 387 |
unsigned offsets[4]; int depth = ufs_block_to_path(inode, fragment >> uspi->s_fpbshift, offsets); |
1da177e4c Linux-2.6.12-rc2 |
388 |
u64 phys64 = 0; |
177848a01 ufs_inode_get{fra... |
389 |
unsigned frag = fragment & uspi->s_fpbmask; |
010d331fc ufs: move truncat... |
390 |
|
1da177e4c Linux-2.6.12-rc2 |
391 |
if (!create) { |
4b7068c8b ufs: move calcula... |
392 |
phys64 = ufs_frag_map(inode, offsets, depth); |
0385f1f9e ufs_getfrag_block... |
393 |
goto out; |
1da177e4c Linux-2.6.12-rc2 |
394 395 396 |
} /* This code entered only while writing ....? */ |
724bb09fd ufs: don't use lo... |
397 |
mutex_lock(&UFS_I(inode)->truncate_mutex); |
1da177e4c Linux-2.6.12-rc2 |
398 |
|
abf5d15fd [PATCH] ufs: easy... |
399 400 |
UFSD("ENTER, ino %lu, fragment %llu ", inode->i_ino, (unsigned long long)fragment); |
0385f1f9e ufs_getfrag_block... |
401 402 403 404 405 |
if (unlikely(!depth)) { ufs_warning(sb, "ufs_get_block", "block > big"); err = -EIO; goto out; } |
0f3c1294b ufs_inode_getfrag... |
406 407 408 409 410 411 412 |
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)) |
0385f1f9e ufs_getfrag_block... |
413 |
goto out; |
0f3c1294b ufs_inode_getfrag... |
414 415 |
} } |
71dd42846 ufs: use the bran... |
416 |
if (depth == 1) { |
5336970be ufs_inode_getfrag... |
417 |
phys64 = ufs_inode_getfrag(inode, offsets[0], fragment, |
4e317ce73 ufs_inode_get{fra... |
418 |
&err, &new, bh_result->b_page); |
4eeff4c93 ufs_getfrag_block... |
419 420 |
} else { int i; |
5336970be ufs_inode_getfrag... |
421 |
phys64 = ufs_inode_getfrag(inode, offsets[0], fragment, |
4e317ce73 ufs_inode_get{fra... |
422 |
&err, NULL, NULL); |
4eeff4c93 ufs_getfrag_block... |
423 424 |
for (i = 1; i < depth - 1; i++) phys64 = ufs_inode_getblock(inode, phys64, offsets[i], |
4e317ce73 ufs_inode_get{fra... |
425 |
fragment, &err, NULL, NULL); |
4eeff4c93 ufs_getfrag_block... |
426 |
phys64 = ufs_inode_getblock(inode, phys64, offsets[depth - 1], |
4e317ce73 ufs_inode_get{fra... |
427 |
fragment, &err, &new, bh_result->b_page); |
1da177e4c Linux-2.6.12-rc2 |
428 |
} |
0385f1f9e ufs_getfrag_block... |
429 |
out: |
177848a01 ufs_inode_get{fra... |
430 431 |
if (phys64) { phys64 += frag; |
0385f1f9e ufs_getfrag_block... |
432 433 434 |
map_bh(bh_result, sb, phys64); if (new) set_buffer_new(bh_result); |
177848a01 ufs_inode_get{fra... |
435 |
} |
724bb09fd ufs: don't use lo... |
436 |
mutex_unlock(&UFS_I(inode)->truncate_mutex); |
1da177e4c Linux-2.6.12-rc2 |
437 |
return err; |
1da177e4c Linux-2.6.12-rc2 |
438 |
} |
1da177e4c Linux-2.6.12-rc2 |
439 440 441 442 |
static int ufs_writepage(struct page *page, struct writeback_control *wbc) { return block_write_full_page(page,ufs_getfrag_block,wbc); } |
82b9d1d0d ufs: convert to n... |
443 |
|
1da177e4c Linux-2.6.12-rc2 |
444 445 446 447 |
static int ufs_readpage(struct file *file, struct page *page) { return block_read_full_page(page,ufs_getfrag_block); } |
82b9d1d0d ufs: convert to n... |
448 |
|
f4e420dc4 clean up write_be... |
449 |
int ufs_prepare_chunk(struct page *page, loff_t pos, unsigned len) |
1da177e4c Linux-2.6.12-rc2 |
450 |
{ |
6e1db88d5 introduce __block... |
451 |
return __block_write_begin(page, pos, len, ufs_getfrag_block); |
1da177e4c Linux-2.6.12-rc2 |
452 |
} |
82b9d1d0d ufs: convert to n... |
453 |
|
010d331fc ufs: move truncat... |
454 |
static void ufs_truncate_blocks(struct inode *); |
83f6e3710 ufs: drop vmtruncate |
455 456 457 |
static void ufs_write_failed(struct address_space *mapping, loff_t to) { struct inode *inode = mapping->host; |
3b7a3a05e ufs: free excessi... |
458 |
if (to > inode->i_size) { |
7caef2676 truncate: drop 'o... |
459 |
truncate_pagecache(inode, inode->i_size); |
3b7a3a05e ufs: free excessi... |
460 461 |
ufs_truncate_blocks(inode); } |
83f6e3710 ufs: drop vmtruncate |
462 |
} |
82b9d1d0d ufs: convert to n... |
463 464 465 466 |
static int ufs_write_begin(struct file *file, struct address_space *mapping, loff_t pos, unsigned len, unsigned flags, struct page **pagep, void **fsdata) { |
155130a4f get rid of block_... |
467 468 469 |
int ret; ret = block_write_begin(mapping, pos, len, flags, pagep, |
f4e420dc4 clean up write_be... |
470 |
ufs_getfrag_block); |
83f6e3710 ufs: drop vmtruncate |
471 472 |
if (unlikely(ret)) ufs_write_failed(mapping, pos + len); |
155130a4f get rid of block_... |
473 474 |
return ret; |
82b9d1d0d ufs: convert to n... |
475 |
} |
3b7a3a05e ufs: free excessi... |
476 477 478 479 480 481 482 483 484 485 486 |
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; } |
1da177e4c Linux-2.6.12-rc2 |
487 488 489 490 |
static sector_t ufs_bmap(struct address_space *mapping, sector_t block) { return generic_block_bmap(mapping,block,ufs_getfrag_block); } |
82b9d1d0d ufs: convert to n... |
491 |
|
f5e54d6e5 [PATCH] mark addr... |
492 |
const struct address_space_operations ufs_aops = { |
1da177e4c Linux-2.6.12-rc2 |
493 494 |
.readpage = ufs_readpage, .writepage = ufs_writepage, |
82b9d1d0d ufs: convert to n... |
495 |
.write_begin = ufs_write_begin, |
3b7a3a05e ufs: free excessi... |
496 |
.write_end = ufs_write_end, |
1da177e4c Linux-2.6.12-rc2 |
497 498 |
.bmap = ufs_bmap }; |
826843a34 [PATCH] ufs: dire... |
499 500 501 502 503 504 505 506 507 508 509 |
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)) { |
4b8061a67 ufs: switch to si... |
510 |
if (!inode->i_blocks) { |
4b8061a67 ufs: switch to si... |
511 |
inode->i_link = (char *)UFS_I(inode)->i_u1.i_symlink; |
9cdce3c07 ufs: get rid of -... |
512 |
inode->i_op = &simple_symlink_inode_operations; |
4b8061a67 ufs: switch to si... |
513 |
} else { |
826843a34 [PATCH] ufs: dire... |
514 |
inode->i_mapping->a_ops = &ufs_aops; |
9cdce3c07 ufs: get rid of -... |
515 |
inode->i_op = &page_symlink_inode_operations; |
21fc61c73 don't put symlink... |
516 |
inode_nohighmem(inode); |
826843a34 [PATCH] ufs: dire... |
517 518 519 520 521 |
} } else init_special_inode(inode, inode->i_mode, ufs_get_inode_dev(inode->i_sb, UFS_I(inode))); } |
07a0cfec3 ufs proper handli... |
522 |
static int ufs1_read_inode(struct inode *inode, struct ufs_inode *ufs_inode) |
1da177e4c Linux-2.6.12-rc2 |
523 524 |
{ struct ufs_inode_info *ufsi = UFS_I(inode); |
05f225dc8 [PATCH] ufs: ufs_... |
525 |
struct super_block *sb = inode->i_sb; |
6a9a06d9c ufs: propagate um... |
526 |
umode_t mode; |
1da177e4c Linux-2.6.12-rc2 |
527 528 529 530 531 |
/* * Copy data to the in-core inode. */ inode->i_mode = mode = fs16_to_cpu(sb, ufs_inode->ui_mode); |
bfe868486 filesystems: add ... |
532 |
set_nlink(inode, fs16_to_cpu(sb, ufs_inode->ui_nlink)); |
07a0cfec3 ufs proper handli... |
533 |
if (inode->i_nlink == 0) { |
1da177e4c Linux-2.6.12-rc2 |
534 535 |
ufs_error (sb, "ufs_read_inode", "inode %lu has zero nlink ", inode->i_ino); |
07a0cfec3 ufs proper handli... |
536 537 |
return -1; } |
010d331fc ufs: move truncat... |
538 |
|
1da177e4c Linux-2.6.12-rc2 |
539 540 541 |
/* * Linux now has 32-bit uid and gid, so we can support EFT. */ |
722354658 userns: Convert t... |
542 543 |
i_uid_write(inode, ufs_get_inode_uid(sb, ufs_inode)); i_gid_write(inode, ufs_get_inode_gid(sb, ufs_inode)); |
1da177e4c Linux-2.6.12-rc2 |
544 545 546 547 548 549 550 551 552 |
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); |
3313e2926 [PATCH] ufs2 writ... |
553 |
inode->i_generation = fs32_to_cpu(sb, ufs_inode->ui_gen); |
1da177e4c Linux-2.6.12-rc2 |
554 |
ufsi->i_flags = fs32_to_cpu(sb, ufs_inode->ui_flags); |
1da177e4c Linux-2.6.12-rc2 |
555 556 |
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); |
05f225dc8 [PATCH] ufs: ufs_... |
557 |
|
010d331fc ufs: move truncat... |
558 |
|
1da177e4c Linux-2.6.12-rc2 |
559 |
if (S_ISCHR(mode) || S_ISBLK(mode) || inode->i_blocks) { |
f33219b7a ufs: don't trunca... |
560 561 |
memcpy(ufsi->i_u1.i_data, &ufs_inode->ui_u2.ui_addr, sizeof(ufs_inode->ui_u2.ui_addr)); |
dd187a260 [PATCH] ufs: litt... |
562 |
} else { |
f33219b7a ufs: don't trunca... |
563 |
memcpy(ufsi->i_u1.i_symlink, ufs_inode->ui_u2.ui_symlink, |
b12903f13 ufs: ensure fast ... |
564 565 |
sizeof(ufs_inode->ui_u2.ui_symlink) - 1); ufsi->i_u1.i_symlink[sizeof(ufs_inode->ui_u2.ui_symlink) - 1] = 0; |
1da177e4c Linux-2.6.12-rc2 |
566 |
} |
07a0cfec3 ufs proper handli... |
567 |
return 0; |
05f225dc8 [PATCH] ufs: ufs_... |
568 |
} |
1da177e4c Linux-2.6.12-rc2 |
569 |
|
07a0cfec3 ufs proper handli... |
570 |
static int ufs2_read_inode(struct inode *inode, struct ufs2_inode *ufs2_inode) |
05f225dc8 [PATCH] ufs: ufs_... |
571 572 573 |
{ struct ufs_inode_info *ufsi = UFS_I(inode); struct super_block *sb = inode->i_sb; |
6a9a06d9c ufs: propagate um... |
574 |
umode_t mode; |
1da177e4c Linux-2.6.12-rc2 |
575 |
|
abf5d15fd [PATCH] ufs: easy... |
576 577 |
UFSD("Reading ufs2 inode, ino %lu ", inode->i_ino); |
1da177e4c Linux-2.6.12-rc2 |
578 579 580 581 |
/* * Copy data to the in-core inode. */ inode->i_mode = mode = fs16_to_cpu(sb, ufs2_inode->ui_mode); |
bfe868486 filesystems: add ... |
582 |
set_nlink(inode, fs16_to_cpu(sb, ufs2_inode->ui_nlink)); |
07a0cfec3 ufs proper handli... |
583 |
if (inode->i_nlink == 0) { |
1da177e4c Linux-2.6.12-rc2 |
584 585 |
ufs_error (sb, "ufs_read_inode", "inode %lu has zero nlink ", inode->i_ino); |
07a0cfec3 ufs proper handli... |
586 587 |
return -1; } |
1da177e4c Linux-2.6.12-rc2 |
588 589 590 591 |
/* * Linux now has 32-bit uid and gid, so we can support EFT. */ |
722354658 userns: Convert t... |
592 593 |
i_uid_write(inode, fs32_to_cpu(sb, ufs2_inode->ui_uid)); i_gid_write(inode, fs32_to_cpu(sb, ufs2_inode->ui_gid)); |
1da177e4c Linux-2.6.12-rc2 |
594 595 |
inode->i_size = fs64_to_cpu(sb, ufs2_inode->ui_size); |
2189850f4 [PATCH] ufs2: mor... |
596 597 598 599 600 601 |
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); |
1da177e4c Linux-2.6.12-rc2 |
602 |
inode->i_blocks = fs64_to_cpu(sb, ufs2_inode->ui_blocks); |
3313e2926 [PATCH] ufs2 writ... |
603 |
inode->i_generation = fs32_to_cpu(sb, ufs2_inode->ui_gen); |
1da177e4c Linux-2.6.12-rc2 |
604 |
ufsi->i_flags = fs32_to_cpu(sb, ufs2_inode->ui_flags); |
1da177e4c Linux-2.6.12-rc2 |
605 606 607 608 |
/* 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); */ |
1da177e4c Linux-2.6.12-rc2 |
609 610 |
if (S_ISCHR(mode) || S_ISBLK(mode) || inode->i_blocks) { |
f33219b7a ufs: don't trunca... |
611 612 |
memcpy(ufsi->i_u1.u2_i_data, &ufs2_inode->ui_u2.ui_addr, sizeof(ufs2_inode->ui_u2.ui_addr)); |
05f225dc8 [PATCH] ufs: ufs_... |
613 |
} else { |
f33219b7a ufs: don't trunca... |
614 |
memcpy(ufsi->i_u1.i_symlink, ufs2_inode->ui_u2.ui_symlink, |
b12903f13 ufs: ensure fast ... |
615 616 |
sizeof(ufs2_inode->ui_u2.ui_symlink) - 1); ufsi->i_u1.i_symlink[sizeof(ufs2_inode->ui_u2.ui_symlink) - 1] = 0; |
1da177e4c Linux-2.6.12-rc2 |
617 |
} |
07a0cfec3 ufs proper handli... |
618 |
return 0; |
05f225dc8 [PATCH] ufs: ufs_... |
619 |
} |
b55c460da iget: stop UFS fr... |
620 |
struct inode *ufs_iget(struct super_block *sb, unsigned long ino) |
05f225dc8 [PATCH] ufs: ufs_... |
621 |
{ |
b55c460da iget: stop UFS fr... |
622 623 |
struct ufs_inode_info *ufsi; struct ufs_sb_private_info *uspi = UFS_SB(sb)->s_uspi; |
05f225dc8 [PATCH] ufs: ufs_... |
624 |
struct buffer_head * bh; |
b55c460da iget: stop UFS fr... |
625 |
struct inode *inode; |
07a0cfec3 ufs proper handli... |
626 |
int err; |
05f225dc8 [PATCH] ufs: ufs_... |
627 |
|
b55c460da iget: stop UFS fr... |
628 629 |
UFSD("ENTER, ino %lu ", ino); |
05f225dc8 [PATCH] ufs: ufs_... |
630 |
|
b55c460da iget: stop UFS fr... |
631 |
if (ino < UFS_ROOTINO || ino > (uspi->s_ncg * uspi->s_ipg)) { |
05f225dc8 [PATCH] ufs: ufs_... |
632 633 |
ufs_warning(sb, "ufs_read_inode", "bad inode number (%lu) ", |
b55c460da iget: stop UFS fr... |
634 635 |
ino); return ERR_PTR(-EIO); |
05f225dc8 [PATCH] ufs: ufs_... |
636 |
} |
b55c460da iget: stop UFS fr... |
637 638 639 640 641 642 643 |
inode = iget_locked(sb, ino); if (!inode) return ERR_PTR(-ENOMEM); if (!(inode->i_state & I_NEW)) return inode; ufsi = UFS_I(inode); |
05f225dc8 [PATCH] ufs: ufs_... |
644 645 646 647 648 649 650 651 652 |
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 ", 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; |
07a0cfec3 ufs proper handli... |
653 654 |
err = ufs2_read_inode(inode, ufs2_inode + ufs_inotofsbo(inode->i_ino)); |
05f225dc8 [PATCH] ufs: ufs_... |
655 656 |
} else { struct ufs_inode *ufs_inode = (struct ufs_inode *)bh->b_data; |
07a0cfec3 ufs proper handli... |
657 658 |
err = ufs1_read_inode(inode, ufs_inode + ufs_inotofsbo(inode->i_ino)); |
05f225dc8 [PATCH] ufs: ufs_... |
659 |
} |
07a0cfec3 ufs proper handli... |
660 661 |
if (err) goto bad_inode; |
05f225dc8 [PATCH] ufs: ufs_... |
662 663 664 665 |
inode->i_version++; ufsi->i_lastfrag = (inode->i_size + uspi->s_fsize - 1) >> uspi->s_fshift; ufsi->i_dir_start_lookup = 0; |
1da177e4c Linux-2.6.12-rc2 |
666 |
ufsi->i_osync = 0; |
826843a34 [PATCH] ufs: dire... |
667 |
ufs_set_inode_ops(inode); |
1da177e4c Linux-2.6.12-rc2 |
668 669 |
brelse(bh); |
abf5d15fd [PATCH] ufs: easy... |
670 671 |
UFSD("EXIT "); |
b55c460da iget: stop UFS fr... |
672 673 |
unlock_new_inode(inode); return inode; |
05f225dc8 [PATCH] ufs: ufs_... |
674 675 |
bad_inode: |
b55c460da iget: stop UFS fr... |
676 677 |
iget_failed(inode); return ERR_PTR(-EIO); |
1da177e4c Linux-2.6.12-rc2 |
678 |
} |
3313e2926 [PATCH] ufs2 writ... |
679 |
static void ufs1_update_inode(struct inode *inode, struct ufs_inode *ufs_inode) |
1da177e4c Linux-2.6.12-rc2 |
680 |
{ |
3313e2926 [PATCH] ufs2 writ... |
681 682 |
struct super_block *sb = inode->i_sb; struct ufs_inode_info *ufsi = UFS_I(inode); |
1da177e4c Linux-2.6.12-rc2 |
683 684 685 |
ufs_inode->ui_mode = cpu_to_fs16(sb, inode->i_mode); ufs_inode->ui_nlink = cpu_to_fs16(sb, inode->i_nlink); |
722354658 userns: Convert t... |
686 687 |
ufs_set_inode_uid(sb, ufs_inode, i_uid_read(inode)); ufs_set_inode_gid(sb, ufs_inode, i_gid_read(inode)); |
010d331fc ufs: move truncat... |
688 |
|
1da177e4c Linux-2.6.12-rc2 |
689 690 691 692 693 694 695 696 697 |
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); |
3313e2926 [PATCH] ufs2 writ... |
698 |
ufs_inode->ui_gen = cpu_to_fs32(sb, inode->i_generation); |
1da177e4c Linux-2.6.12-rc2 |
699 |
|
3313e2926 [PATCH] ufs2 writ... |
700 |
if ((UFS_SB(sb)->s_flags & UFS_UID_MASK) == UFS_UID_EFT) { |
1da177e4c Linux-2.6.12-rc2 |
701 702 703 704 705 706 707 708 |
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) { |
f33219b7a ufs: don't trunca... |
709 710 |
memcpy(&ufs_inode->ui_u2.ui_addr, ufsi->i_u1.i_data, sizeof(ufs_inode->ui_u2.ui_addr)); |
1da177e4c Linux-2.6.12-rc2 |
711 712 |
} else { |
f33219b7a ufs: don't trunca... |
713 714 |
memcpy(&ufs_inode->ui_u2.ui_symlink, ufsi->i_u1.i_symlink, sizeof(ufs_inode->ui_u2.ui_symlink)); |
1da177e4c Linux-2.6.12-rc2 |
715 716 717 718 |
} if (!inode->i_nlink) memset (ufs_inode, 0, sizeof(struct ufs_inode)); |
3313e2926 [PATCH] ufs2 writ... |
719 720 721 722 723 724 |
} 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); |
3313e2926 [PATCH] ufs2 writ... |
725 726 727 728 729 |
UFSD("ENTER "); ufs_inode->ui_mode = cpu_to_fs16(sb, inode->i_mode); ufs_inode->ui_nlink = cpu_to_fs16(sb, inode->i_nlink); |
722354658 userns: Convert t... |
730 731 |
ufs_inode->ui_uid = cpu_to_fs32(sb, i_uid_read(inode)); ufs_inode->ui_gid = cpu_to_fs32(sb, i_gid_read(inode)); |
3313e2926 [PATCH] ufs2 writ... |
732 733 |
ufs_inode->ui_size = cpu_to_fs64(sb, inode->i_size); |
2189850f4 [PATCH] ufs2: mor... |
734 735 736 737 738 739 |
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); |
3313e2926 [PATCH] ufs2 writ... |
740 741 742 743 744 745 746 747 748 |
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) { |
f33219b7a ufs: don't trunca... |
749 750 |
memcpy(&ufs_inode->ui_u2.ui_addr, ufsi->i_u1.u2_i_data, sizeof(ufs_inode->ui_u2.ui_addr)); |
3313e2926 [PATCH] ufs2 writ... |
751 |
} else { |
f33219b7a ufs: don't trunca... |
752 753 |
memcpy(&ufs_inode->ui_u2.ui_symlink, ufsi->i_u1.i_symlink, sizeof(ufs_inode->ui_u2.ui_symlink)); |
3313e2926 [PATCH] ufs2 writ... |
754 755 756 757 758 759 760 761 762 763 764 765 766 767 768 769 770 771 772 773 774 775 776 777 778 779 780 781 782 783 784 785 786 787 788 789 790 791 792 793 |
} if (!inode->i_nlink) memset (ufs_inode, 0, sizeof(struct ufs2_inode)); UFSD("EXIT "); } 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 ", 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) ", 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 ", 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)); } |
010d331fc ufs: move truncat... |
794 |
|
1da177e4c Linux-2.6.12-rc2 |
795 796 797 798 |
mark_buffer_dirty(bh); if (do_sync) sync_dirty_buffer(bh); brelse (bh); |
010d331fc ufs: move truncat... |
799 |
|
abf5d15fd [PATCH] ufs: easy... |
800 801 |
UFSD("EXIT "); |
1da177e4c Linux-2.6.12-rc2 |
802 803 |
return 0; } |
a9185b41a pass writeback_co... |
804 |
int ufs_write_inode(struct inode *inode, struct writeback_control *wbc) |
1da177e4c Linux-2.6.12-rc2 |
805 |
{ |
f3e0f3da1 ufs: kill more lo... |
806 |
return ufs_update_inode(inode, wbc->sync_mode == WB_SYNC_ALL); |
1da177e4c Linux-2.6.12-rc2 |
807 808 809 810 811 812 |
} int ufs_sync_inode (struct inode *inode) { return ufs_update_inode (inode, 1); } |
58e8268c7 switch ufs to ->e... |
813 |
void ufs_evict_inode(struct inode * inode) |
1da177e4c Linux-2.6.12-rc2 |
814 |
{ |
58e8268c7 switch ufs to ->e... |
815 816 817 818 |
int want_delete = 0; if (!inode->i_nlink && !is_bad_inode(inode)) want_delete = 1; |
10e5dce07 [PATCH] ufs: trun... |
819 |
|
91b0abe36 mm + fs: store sh... |
820 |
truncate_inode_pages_final(&inode->i_data); |
58e8268c7 switch ufs to ->e... |
821 |
if (want_delete) { |
58e8268c7 switch ufs to ->e... |
822 |
inode->i_size = 0; |
d622f167b ufs: switch ufs_e... |
823 824 |
if (inode->i_blocks) ufs_truncate_blocks(inode); |
58e8268c7 switch ufs to ->e... |
825 826 827 |
} invalidate_inode_buffers(inode); |
dbd5768f8 vfs: Rename end_w... |
828 |
clear_inode(inode); |
58e8268c7 switch ufs to ->e... |
829 |
|
f3e0f3da1 ufs: kill more lo... |
830 |
if (want_delete) |
9ef7db7f3 ufs: fix deadlock... |
831 |
ufs_free_inode(inode); |
1da177e4c Linux-2.6.12-rc2 |
832 |
} |
010d331fc ufs: move truncat... |
833 |
|
a138b4b68 ufs: unify the lo... |
834 835 836 837 838 839 840 841 842 843 844 845 846 847 848 |
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; } |
010d331fc ufs: move truncat... |
849 850 851 852 853 854 855 856 857 858 |
#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; |
a138b4b68 ufs: unify the lo... |
859 |
struct to_free ctx = {.inode = inode}; |
010d331fc ufs: move truncat... |
860 861 862 863 864 865 866 |
unsigned i, tmp; UFSD("ENTER: ino %lu ", inode->i_ino); sb = inode->i_sb; uspi = UFS_SB(sb)->s_uspi; |
010d331fc ufs: move truncat... |
867 868 869 870 871 872 873 874 875 876 877 878 879 880 881 882 883 884 885 886 887 888 889 890 891 892 893 894 895 896 897 898 899 900 |
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 ", 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); |
010d331fc ufs: move truncat... |
901 902 903 904 905 906 907 908 909 910 911 912 913 |
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); |
a138b4b68 ufs: unify the lo... |
914 |
free_data(&ctx, tmp, uspi->s_fpb); |
010d331fc ufs: move truncat... |
915 |
} |
a138b4b68 ufs: unify the lo... |
916 |
free_data(&ctx, 0, 0); |
010d331fc ufs: move truncat... |
917 918 919 920 921 922 923 924 925 926 927 928 929 930 931 932 933 |
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); |
010d331fc ufs: move truncat... |
934 935 936 937 938 |
next3: UFSD("EXIT: ino %lu ", inode->i_ino); } |
163073db5 free_full_branch(... |
939 |
static void free_full_branch(struct inode *inode, u64 ind_block, int depth) |
6d1ebbca2 split ufs_truncat... |
940 941 942 |
{ struct super_block *sb = inode->i_sb; struct ufs_sb_private_info *uspi = UFS_SB(sb)->s_uspi; |
163073db5 free_full_branch(... |
943 |
struct ufs_buffer_head *ubh = ubh_bread(sb, ind_block, uspi->s_bsize); |
6d1ebbca2 split ufs_truncat... |
944 |
unsigned i; |
163073db5 free_full_branch(... |
945 |
if (!ubh) |
6d1ebbca2 split ufs_truncat... |
946 |
return; |
6d1ebbca2 split ufs_truncat... |
947 948 |
if (--depth) { |
163073db5 free_full_branch(... |
949 950 951 |
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); |
cc7231e30 free_full_branch(... |
952 |
if (block) |
163073db5 free_full_branch(... |
953 |
free_full_branch(inode, block, depth); |
6d1ebbca2 split ufs_truncat... |
954 955 956 957 958 |
} } else { struct to_free ctx = {.inode = inode}; for (i = 0; i < uspi->s_apb; i++) { |
163073db5 free_full_branch(... |
959 960 |
void *p = ubh_get_data_ptr(uspi, ubh, i); u64 block = ufs_data_ptr_to_cpu(sb, p); |
cc7231e30 free_full_branch(... |
961 |
if (block) |
163073db5 free_full_branch(... |
962 |
free_data(&ctx, block, uspi->s_fpb); |
6d1ebbca2 split ufs_truncat... |
963 964 965 |
} free_data(&ctx, 0, 0); } |
6d1ebbca2 split ufs_truncat... |
966 967 |
ubh_bforget(ubh); |
163073db5 free_full_branch(... |
968 |
ufs_free_blocks(inode, ind_block, uspi->s_fpb); |
6d1ebbca2 split ufs_truncat... |
969 |
} |
7b4e4f7f8 ufs_trunc_branch(... |
970 |
static void free_branch_tail(struct inode *inode, unsigned from, struct ufs_buffer_head *ubh, int depth) |
010d331fc ufs: move truncat... |
971 |
{ |
7bad5939f ufs_trunc_dindire... |
972 973 |
struct super_block *sb = inode->i_sb; struct ufs_sb_private_info *uspi = UFS_SB(sb)->s_uspi; |
7bad5939f ufs_trunc_dindire... |
974 |
unsigned i; |
010d331fc ufs: move truncat... |
975 |
|
9e0fbbde2 unify ufs_trunc_.... |
976 |
if (--depth) { |
7b4e4f7f8 ufs_trunc_branch(... |
977 |
for (i = from; i < uspi->s_apb ; i++) { |
163073db5 free_full_branch(... |
978 979 980 981 982 983 984 985 986 |
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); } |
a96574233 ufs_trunc_branch(... |
987 |
} |
9e0fbbde2 unify ufs_trunc_.... |
988 |
} else { |
a138b4b68 ufs: unify the lo... |
989 |
struct to_free ctx = {.inode = inode}; |
9e0fbbde2 unify ufs_trunc_.... |
990 991 |
for (i = from; i < uspi->s_apb; i++) { |
163073db5 free_full_branch(... |
992 993 994 995 996 997 998 999 |
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); |
163073db5 free_full_branch(... |
1000 |
} |
9e0fbbde2 unify ufs_trunc_.... |
1001 |
} |
a138b4b68 ufs: unify the lo... |
1002 |
free_data(&ctx, 0, 0); |
010d331fc ufs: move truncat... |
1003 |
} |
9e0fbbde2 unify ufs_trunc_.... |
1004 1005 1006 |
if (IS_SYNC(inode) && ubh_buffer_dirty(ubh)) ubh_sync_block(ubh); ubh_brelse(ubh); |
010d331fc ufs: move truncat... |
1007 1008 1009 1010 1011 1012 1013 1014 1015 1016 1017 1018 1019 1020 1021 1022 1023 1024 1025 1026 1027 1028 |
} 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 >> |
09cbfeaf1 mm, fs: get rid o... |
1029 |
(PAGE_SHIFT - inode->i_blkbits)); |
010d331fc ufs: move truncat... |
1030 1031 1032 1033 |
if (IS_ERR(lastpage)) { err = -EIO; goto out; } |
09cbfeaf1 mm, fs: get rid o... |
1034 |
end = lastfrag & ((1 << (PAGE_SHIFT - inode->i_blkbits)) - 1); |
010d331fc ufs: move truncat... |
1035 1036 1037 1038 1039 1040 1041 1042 1043 1044 1045 1046 1047 1048 1049 1050 1051 1052 1053 1054 1055 1056 1057 1058 1059 1060 1061 1062 1063 1064 1065 1066 1067 1068 1069 1070 1071 1072 1073 1074 1075 1076 1077 1078 1079 1080 1081 1082 |
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); unmap_underlying_metadata(bh->b_bdev, bh->b_blocknr); /* * 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; |
7bad5939f ufs_trunc_dindire... |
1083 |
unsigned offsets[4]; |
31cd043e1 ufs: beginning of... |
1084 |
int depth = ufs_block_to_path(inode, DIRECT_BLOCK, offsets); |
6775e24d9 ufs_trunc_..indir... |
1085 |
int depth2; |
42432739b __ufs_trunc_block... |
1086 |
unsigned i; |
7b4e4f7f8 ufs_trunc_branch(... |
1087 1088 1089 |
struct ufs_buffer_head *ubh[3]; void *p; u64 block; |
6775e24d9 ufs_trunc_..indir... |
1090 1091 1092 1093 1094 1095 1096 1097 |
if (!depth) return; /* find the last non-zero in offsets[] */ for (depth2 = depth - 1; depth2; depth2--) if (offsets[depth2]) break; |
010d331fc ufs: move truncat... |
1098 1099 |
mutex_lock(&ufsi->truncate_mutex); |
42432739b __ufs_trunc_block... |
1100 |
if (depth == 1) { |
31cd043e1 ufs: beginning of... |
1101 |
ufs_trunc_direct(inode); |
42432739b __ufs_trunc_block... |
1102 1103 |
offsets[0] = UFS_IND_BLOCK; } else { |
7b4e4f7f8 ufs_trunc_branch(... |
1104 1105 1106 1107 1108 1109 1110 1111 1112 1113 1114 1115 1116 1117 1118 1119 |
/* 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]); } |
f53bd1421 __ufs_truncate_bl... |
1120 |
while (i--) |
7b4e4f7f8 ufs_trunc_branch(... |
1121 |
free_branch_tail(inode, offsets[i + 1], ubh[i], depth - i - 1); |
42432739b __ufs_trunc_block... |
1122 1123 |
} for (i = offsets[0]; i <= UFS_TIND_BLOCK; i++) { |
163073db5 free_full_branch(... |
1124 1125 1126 1127 1128 1129 1130 1131 |
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); } |
31cd043e1 ufs: beginning of... |
1132 |
} |
010d331fc ufs: move truncat... |
1133 |
ufsi->i_lastfrag = DIRECT_FRAGMENT; |
b6eede0ec move marking inod... |
1134 |
mark_inode_dirty(inode); |
010d331fc ufs: move truncat... |
1135 1136 1137 1138 1139 1140 1141 1142 1143 1144 1145 1146 1147 1148 1149 1150 1151 1152 1153 1154 1155 1156 1157 1158 1159 1160 1161 1162 |
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 ", 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); |
02027d42c fs: Replace CURRE... |
1163 |
inode->i_mtime = inode->i_ctime = current_time(inode); |
010d331fc ufs: move truncat... |
1164 1165 1166 1167 1168 1169 1170 1171 1172 1173 1174 1175 1176 1177 1178 1179 1180 1181 1182 1183 1184 1185 |
mark_inode_dirty(inode); out: UFSD("EXIT: err %d ", 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; |
31051c85b fs: Give dentry t... |
1186 |
error = setattr_prepare(dentry, attr); |
010d331fc ufs: move truncat... |
1187 1188 1189 1190 1191 1192 1193 1194 1195 1196 1197 1198 1199 1200 1201 1202 1203 |
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, }; |