Blame view
fs/reiserfs/inode.c
92.2 KB
1da177e4c Linux-2.6.12-rc2 |
1 2 3 |
/* * Copyright 2000 by Hans Reiser, licensing governed by reiserfs/README */ |
1da177e4c Linux-2.6.12-rc2 |
4 5 |
#include <linux/time.h> #include <linux/fs.h> |
f466c6fdb move private bits... |
6 |
#include "reiserfs.h" |
a3063ab88 move reiserfs_acl... |
7 |
#include "acl.h" |
c45ac8887 take private bits... |
8 |
#include "xattr.h" |
a56942551 knfsd: exportfs: ... |
9 |
#include <linux/exportfs.h> |
1da177e4c Linux-2.6.12-rc2 |
10 11 |
#include <linux/pagemap.h> #include <linux/highmem.h> |
5a0e3ad6a include cleanup: ... |
12 |
#include <linux/slab.h> |
17093991a fs/reiserfs: use ... |
13 |
#include <linux/uaccess.h> |
1da177e4c Linux-2.6.12-rc2 |
14 15 16 17 18 |
#include <asm/unaligned.h> #include <linux/buffer_head.h> #include <linux/mpage.h> #include <linux/writeback.h> #include <linux/quotaops.h> |
ba9d8cec6 reiserfs: convert... |
19 |
#include <linux/swap.h> |
e2e40f2c1 fs: move struct k... |
20 |
#include <linux/uio.h> |
be297968d mm: only include ... |
21 |
#include <linux/bio.h> |
1da177e4c Linux-2.6.12-rc2 |
22 |
|
ba9d8cec6 reiserfs: convert... |
23 24 |
int reiserfs_commit_write(struct file *f, struct page *page, unsigned from, unsigned to); |
1da177e4c Linux-2.6.12-rc2 |
25 |
|
845a2cc05 convert reiserfs ... |
26 |
void reiserfs_evict_inode(struct inode *inode) |
1da177e4c Linux-2.6.12-rc2 |
27 |
{ |
098297b27 reiserfs: cleanup... |
28 29 30 31 |
/* * We need blocks for transaction + (user+group) quota * update (possibly delete) */ |
bd4c625c0 reiserfs: run scr... |
32 33 34 35 |
int jbegin_count = JOURNAL_PER_BALANCE_CNT * 2 + 2 * REISERFS_QUOTA_INIT_BLOCKS(inode->i_sb); struct reiserfs_transaction_handle th; |
249960496 [PATCH] reiserfs:... |
36 |
int err; |
1da177e4c Linux-2.6.12-rc2 |
37 |
|
845a2cc05 convert reiserfs ... |
38 |
if (!inode->i_nlink && !is_bad_inode(inode)) |
871a29315 dquot: cleanup dq... |
39 |
dquot_initialize(inode); |
907f4554e dquot: move dquot... |
40 |
|
91b0abe36 mm + fs: store sh... |
41 |
truncate_inode_pages_final(&inode->i_data); |
845a2cc05 convert reiserfs ... |
42 43 |
if (inode->i_nlink) goto no_delete; |
fef266580 [PATCH] update fi... |
44 |
|
098297b27 reiserfs: cleanup... |
45 46 47 48 49 50 |
/* * The = 0 happens when we abort creating a new inode * for some reason like lack of space.. * also handles bad_inode case */ if (!(inode->i_state & I_NEW) && INODE_PKEY(inode)->k_objectid != 0) { |
4c05141df reiserfs: locking... |
51 |
|
bd4c625c0 reiserfs: run scr... |
52 |
reiserfs_delete_xattrs(inode); |
1da177e4c Linux-2.6.12-rc2 |
53 |
|
278f6679f reiserfs: locking... |
54 |
reiserfs_write_lock(inode->i_sb); |
4c05141df reiserfs: locking... |
55 |
|
b0b33dee2 [PATCH] i_mutex d... |
56 |
if (journal_begin(&th, inode->i_sb, jbegin_count)) |
bd4c625c0 reiserfs: run scr... |
57 |
goto out; |
bd4c625c0 reiserfs: run scr... |
58 |
reiserfs_update_inode_transaction(inode); |
1da177e4c Linux-2.6.12-rc2 |
59 |
|
eb35c218d reiserfs: discard... |
60 |
reiserfs_discard_prealloc(&th, inode); |
249960496 [PATCH] reiserfs:... |
61 |
err = reiserfs_delete_object(&th, inode); |
1da177e4c Linux-2.6.12-rc2 |
62 |
|
098297b27 reiserfs: cleanup... |
63 64 65 66 67 |
/* * Do quota update inside a transaction for journaled quotas. * We must do that after delete_object so that quota updates * go into the same transaction as stat data deletion */ |
d2d0395fd reiserfs: locking... |
68 69 |
if (!err) { int depth = reiserfs_write_unlock_nested(inode->i_sb); |
63936ddaa dquot: cleanup in... |
70 |
dquot_free_inode(inode); |
d2d0395fd reiserfs: locking... |
71 72 |
reiserfs_write_lock_nested(inode->i_sb, depth); } |
bd4c625c0 reiserfs: run scr... |
73 |
|
58d854265 reiserfs: cleanup... |
74 |
if (journal_end(&th)) |
bd4c625c0 reiserfs: run scr... |
75 |
goto out; |
1da177e4c Linux-2.6.12-rc2 |
76 |
|
098297b27 reiserfs: cleanup... |
77 78 |
/* * check return value from reiserfs_delete_object after |
249960496 [PATCH] reiserfs:... |
79 80 81 82 |
* ending the transaction */ if (err) goto out; |
098297b27 reiserfs: cleanup... |
83 84 85 86 87 88 |
/* * all items of file are deleted, so we can remove * "save" link * we can't do anything about an error here */ remove_save_link(inode, 0 /* not truncate */); |
4c05141df reiserfs: locking... |
89 |
out: |
278f6679f reiserfs: locking... |
90 |
reiserfs_write_unlock(inode->i_sb); |
bd4c625c0 reiserfs: run scr... |
91 92 93 94 |
} else { /* no object items are in the tree */ ; } |
098297b27 reiserfs: cleanup... |
95 96 97 |
/* note this must go after the journal_end to prevent deadlock */ clear_inode(inode); |
845a2cc05 convert reiserfs ... |
98 |
dquot_drop(inode); |
bd4c625c0 reiserfs: run scr... |
99 |
inode->i_blocks = 0; |
f4ae2faa4 fix reiserfs_evic... |
100 |
return; |
845a2cc05 convert reiserfs ... |
101 102 |
no_delete: |
dbd5768f8 vfs: Rename end_w... |
103 |
clear_inode(inode); |
845a2cc05 convert reiserfs ... |
104 |
dquot_drop(inode); |
1da177e4c Linux-2.6.12-rc2 |
105 |
} |
bd4c625c0 reiserfs: run scr... |
106 107 |
static void _make_cpu_key(struct cpu_key *key, int version, __u32 dirid, __u32 objectid, loff_t offset, int type, int length) |
1da177e4c Linux-2.6.12-rc2 |
108 |
{ |
bd4c625c0 reiserfs: run scr... |
109 |
key->version = version; |
1da177e4c Linux-2.6.12-rc2 |
110 |
|
bd4c625c0 reiserfs: run scr... |
111 112 113 114 115 |
key->on_disk_key.k_dir_id = dirid; key->on_disk_key.k_objectid = objectid; set_cpu_key_k_offset(key, offset); set_cpu_key_k_type(key, type); key->key_length = length; |
1da177e4c Linux-2.6.12-rc2 |
116 |
} |
098297b27 reiserfs: cleanup... |
117 118 119 120 |
/* * take base of inode_key (it comes from inode always) (dirid, objectid) * and version from an inode, set offset and type of key */ |
bd4c625c0 reiserfs: run scr... |
121 122 |
void make_cpu_key(struct cpu_key *key, struct inode *inode, loff_t offset, int type, int length) |
1da177e4c Linux-2.6.12-rc2 |
123 |
{ |
bd4c625c0 reiserfs: run scr... |
124 125 126 127 |
_make_cpu_key(key, get_inode_item_key_version(inode), le32_to_cpu(INODE_PKEY(inode)->k_dir_id), le32_to_cpu(INODE_PKEY(inode)->k_objectid), offset, type, length); |
1da177e4c Linux-2.6.12-rc2 |
128 |
} |
098297b27 reiserfs: cleanup... |
129 |
/* when key is 0, do not set version and short key */ |
bd4c625c0 reiserfs: run scr... |
130 131 132 133 |
inline void make_le_item_head(struct item_head *ih, const struct cpu_key *key, int version, loff_t offset, int type, int length, int entry_count /*or ih_free_space */ ) |
1da177e4c Linux-2.6.12-rc2 |
134 |
{ |
bd4c625c0 reiserfs: run scr... |
135 136 137 138 139 140 141 142 143 144 |
if (key) { ih->ih_key.k_dir_id = cpu_to_le32(key->on_disk_key.k_dir_id); ih->ih_key.k_objectid = cpu_to_le32(key->on_disk_key.k_objectid); } put_ih_version(ih, version); set_le_ih_k_offset(ih, offset); set_le_ih_k_type(ih, type); put_ih_item_len(ih, length); /* set_ih_free_space (ih, 0); */ |
098297b27 reiserfs: cleanup... |
145 146 147 148 |
/* * for directory items it is entry count, for directs and stat * datas - 0xffff, for indirects - 0 */ |
bd4c625c0 reiserfs: run scr... |
149 |
put_ih_entry_count(ih, entry_count); |
1da177e4c Linux-2.6.12-rc2 |
150 |
} |
098297b27 reiserfs: cleanup... |
151 152 153 154 155 156 |
/* * FIXME: we might cache recently accessed indirect item * Ugh. Not too eager for that.... * I cut the code until such time as I see a convincing argument (benchmark). * I don't want a bloated inode struct..., and I don't like code complexity.... */ |
1da177e4c Linux-2.6.12-rc2 |
157 |
|
098297b27 reiserfs: cleanup... |
158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 |
/* * cutting the code is fine, since it really isn't in use yet and is easy * to add back in. But, Vladimir has a really good idea here. Think * about what happens for reading a file. For each page, * The VFS layer calls reiserfs_readpage, who searches the tree to find * an indirect item. This indirect item has X number of pointers, where * X is a big number if we've done the block allocation right. But, * we only use one or two of these pointers during each call to readpage, * needlessly researching again later on. * * The size of the cache could be dynamic based on the size of the file. * * I'd also like to see us cache the location the stat data item, since * we are needlessly researching for that frequently. * * --chris */ /* * If this page has a file tail in it, and * it was read in by get_block_create_0, the page data is valid, * but tail is still sitting in a direct item, and we can't write to * it. So, look through this page, and check all the mapped buffers * to make sure they have valid block numbers. Any that don't need * to be unmapped, so that __block_write_begin will correctly call * reiserfs_get_block to convert the tail into an unformatted node */ |
bd4c625c0 reiserfs: run scr... |
185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 |
static inline void fix_tail_page_for_writing(struct page *page) { struct buffer_head *head, *next, *bh; if (page && page_has_buffers(page)) { head = page_buffers(page); bh = head; do { next = bh->b_this_page; if (buffer_mapped(bh) && bh->b_blocknr == 0) { reiserfs_unmap_buffer(bh); } bh = next; } while (bh != head); } |
1da177e4c Linux-2.6.12-rc2 |
200 |
} |
098297b27 reiserfs: cleanup... |
201 202 203 204 |
/* * reiserfs_get_block does not need to allocate a block only if it has been * done already or non-hole position has been found in the indirect item */ |
bd4c625c0 reiserfs: run scr... |
205 206 207 |
static inline int allocation_needed(int retval, b_blocknr_t allocated, struct item_head *ih, __le32 * item, int pos_in_item) |
1da177e4c Linux-2.6.12-rc2 |
208 |
{ |
bd4c625c0 reiserfs: run scr... |
209 210 211 212 213 214 |
if (allocated) return 0; if (retval == POSITION_FOUND && is_indirect_le_ih(ih) && get_block_num(item, pos_in_item)) return 0; return 1; |
1da177e4c Linux-2.6.12-rc2 |
215 |
} |
bd4c625c0 reiserfs: run scr... |
216 |
static inline int indirect_item_found(int retval, struct item_head *ih) |
1da177e4c Linux-2.6.12-rc2 |
217 |
{ |
bd4c625c0 reiserfs: run scr... |
218 |
return (retval == POSITION_FOUND) && is_indirect_le_ih(ih); |
1da177e4c Linux-2.6.12-rc2 |
219 |
} |
bd4c625c0 reiserfs: run scr... |
220 221 |
static inline void set_block_dev_mapped(struct buffer_head *bh, b_blocknr_t block, struct inode *inode) |
1da177e4c Linux-2.6.12-rc2 |
222 223 224 |
{ map_bh(bh, inode->i_sb, block); } |
098297b27 reiserfs: cleanup... |
225 226 227 228 |
/* * files which were created in the earlier version can not be longer, * than 2 gb */ |
3ee166704 reiserfs: fix usa... |
229 |
static int file_capable(struct inode *inode, sector_t block) |
1da177e4c Linux-2.6.12-rc2 |
230 |
{ |
098297b27 reiserfs: cleanup... |
231 232 233 234 |
/* it is new file. */ if (get_inode_item_key_version(inode) != KEY_FORMAT_3_5 || /* old file, but 'block' is inside of 2gb */ block < (1 << (31 - inode->i_sb->s_blocksize_bits))) |
bd4c625c0 reiserfs: run scr... |
235 |
return 1; |
1da177e4c Linux-2.6.12-rc2 |
236 |
|
bd4c625c0 reiserfs: run scr... |
237 |
return 0; |
1da177e4c Linux-2.6.12-rc2 |
238 |
} |
deba0f49b fs/reiserfs/: cle... |
239 240 |
static int restart_transaction(struct reiserfs_transaction_handle *th, struct inode *inode, struct treepath *path) |
bd4c625c0 reiserfs: run scr... |
241 242 |
{ struct super_block *s = th->t_super; |
bd4c625c0 reiserfs: run scr... |
243 244 245 246 |
int err; BUG_ON(!th->t_trans_id); BUG_ON(!th->t_refcount); |
87b4126f1 [PATCH] fix reise... |
247 |
pathrelse(path); |
bd4c625c0 reiserfs: run scr... |
248 249 250 251 |
/* we cannot restart while nested */ if (th->t_refcount > 1) { return 0; } |
bd4c625c0 reiserfs: run scr... |
252 |
reiserfs_update_sd(th, inode); |
58d854265 reiserfs: cleanup... |
253 |
err = journal_end(th); |
bd4c625c0 reiserfs: run scr... |
254 255 256 257 258 259 |
if (!err) { err = journal_begin(th, s, JOURNAL_PER_BALANCE_CNT * 6); if (!err) reiserfs_update_inode_transaction(inode); } return err; |
1da177e4c Linux-2.6.12-rc2 |
260 |
} |
098297b27 reiserfs: cleanup... |
261 262 263 264 265 266 267 268 |
/* * it is called by get_block when create == 0. Returns block number * for 'block'-th logical block of file. When it hits direct item it * returns 0 (being called from bmap) or read direct item into piece * of page (bh_result) * Please improve the english/clarity in the comment above, as it is * hard to understand. */ |
3ee166704 reiserfs: fix usa... |
269 |
static int _get_block_create_0(struct inode *inode, sector_t block, |
bd4c625c0 reiserfs: run scr... |
270 |
struct buffer_head *bh_result, int args) |
1da177e4c Linux-2.6.12-rc2 |
271 |
{ |
bd4c625c0 reiserfs: run scr... |
272 273 274 275 |
INITIALIZE_PATH(path); struct cpu_key key; struct buffer_head *bh; struct item_head *ih, tmp_ih; |
3ee166704 reiserfs: fix usa... |
276 |
b_blocknr_t blocknr; |
bd4c625c0 reiserfs: run scr... |
277 278 279 280 281 282 |
char *p = NULL; int chars; int ret; int result; int done = 0; unsigned long offset; |
098297b27 reiserfs: cleanup... |
283 |
/* prepare the key to look for the 'block'-th block of file */ |
bd4c625c0 reiserfs: run scr... |
284 285 286 |
make_cpu_key(&key, inode, (loff_t) block * inode->i_sb->s_blocksize + 1, TYPE_ANY, 3); |
bd4c625c0 reiserfs: run scr... |
287 288 289 290 291 292 293 |
result = search_for_position_by_key(inode->i_sb, &key, &path); if (result != POSITION_FOUND) { pathrelse(&path); if (p) kunmap(bh_result->b_page); if (result == IO_ERROR) return -EIO; |
098297b27 reiserfs: cleanup... |
294 295 296 297 298 |
/* * We do not return -ENOENT if there is a hole but page is * uptodate, because it means that there is some MMAPED data * associated with it that is yet to be written to disk. */ |
bd4c625c0 reiserfs: run scr... |
299 300 301 302 303 304 |
if ((args & GET_BLOCK_NO_HOLE) && !PageUptodate(bh_result->b_page)) { return -ENOENT; } return 0; } |
098297b27 reiserfs: cleanup... |
305 |
|
bd4c625c0 reiserfs: run scr... |
306 |
bh = get_last_bh(&path); |
4cf5f7add reiserfs: cleanup... |
307 |
ih = tp_item_head(&path); |
bd4c625c0 reiserfs: run scr... |
308 |
if (is_indirect_le_ih(ih)) { |
4cf5f7add reiserfs: cleanup... |
309 |
__le32 *ind_item = (__le32 *) ih_item_body(bh, ih); |
bd4c625c0 reiserfs: run scr... |
310 |
|
098297b27 reiserfs: cleanup... |
311 312 313 314 315 |
/* * FIXME: here we could cache indirect item or part of it in * the inode to avoid search_by_key in case of subsequent * access to file */ |
bd4c625c0 reiserfs: run scr... |
316 317 318 319 320 321 322 323 324 |
blocknr = get_block_num(ind_item, path.pos_in_item); ret = 0; if (blocknr) { map_bh(bh_result, inode->i_sb, blocknr); if (path.pos_in_item == ((ih_item_len(ih) / UNFM_P_SIZE) - 1)) { set_buffer_boundary(bh_result); } } else |
098297b27 reiserfs: cleanup... |
325 326 327 328 329 330 |
/* * We do not return -ENOENT if there is a hole but * page is uptodate, because it means that there is * some MMAPED data associated with it that is * yet to be written to disk. */ |
bd4c625c0 reiserfs: run scr... |
331 332 333 334 335 336 337 338 339 340 |
if ((args & GET_BLOCK_NO_HOLE) && !PageUptodate(bh_result->b_page)) { ret = -ENOENT; } pathrelse(&path); if (p) kunmap(bh_result->b_page); return ret; } |
098297b27 reiserfs: cleanup... |
341 |
/* requested data are in direct item(s) */ |
bd4c625c0 reiserfs: run scr... |
342 |
if (!(args & GET_BLOCK_READ_DIRECT)) { |
098297b27 reiserfs: cleanup... |
343 344 345 346 |
/* * we are called by bmap. FIXME: we can not map block of file * when it is stored in direct item(s) */ |
bd4c625c0 reiserfs: run scr... |
347 348 349 350 351 |
pathrelse(&path); if (p) kunmap(bh_result->b_page); return -ENOENT; } |
098297b27 reiserfs: cleanup... |
352 353 354 355 |
/* * if we've got a direct item, and the buffer or page was uptodate, * we don't want to pull data off disk again. skip to the * end, where we map the buffer and return |
bd4c625c0 reiserfs: run scr... |
356 357 358 359 360 |
*/ if (buffer_uptodate(bh_result)) { goto finished; } else /* |
098297b27 reiserfs: cleanup... |
361 362 363 364 |
* grab_tail_page can trigger calls to reiserfs_get_block on * up to date pages without any buffers. If the page is up * to date, we don't want read old data off disk. Set the up * to date bit on the buffer instead and jump to the end |
bd4c625c0 reiserfs: run scr... |
365 366 |
*/ if (!bh_result->b_page || PageUptodate(bh_result->b_page)) { |
1da177e4c Linux-2.6.12-rc2 |
367 |
set_buffer_uptodate(bh_result); |
bd4c625c0 reiserfs: run scr... |
368 369 |
goto finished; } |
098297b27 reiserfs: cleanup... |
370 |
/* read file tail into part of page */ |
09cbfeaf1 mm, fs: get rid o... |
371 |
offset = (cpu_key_k_offset(&key) - 1) & (PAGE_SIZE - 1); |
bd4c625c0 reiserfs: run scr... |
372 |
copy_item_head(&tmp_ih, ih); |
098297b27 reiserfs: cleanup... |
373 374 375 376 377 |
/* * we only want to kmap if we are reading the tail into the page. * this is not the common case, so we don't kmap until we are * sure we need to. But, this means the item might move if * kmap schedules |
bd4c625c0 reiserfs: run scr... |
378 |
*/ |
27b3a5c51 kill-the-bkl/reis... |
379 |
if (!p) |
bd4c625c0 reiserfs: run scr... |
380 |
p = (char *)kmap(bh_result->b_page); |
27b3a5c51 kill-the-bkl/reis... |
381 |
|
bd4c625c0 reiserfs: run scr... |
382 383 384 385 386 387 |
p += offset; memset(p, 0, inode->i_sb->s_blocksize); do { if (!is_direct_le_ih(ih)) { BUG(); } |
098297b27 reiserfs: cleanup... |
388 389 390 391 392 |
/* * make sure we don't read more bytes than actually exist in * the file. This can happen in odd cases where i_size isn't * correct, and when direct item padding results in a few * extra bytes at the end of the direct item |
bd4c625c0 reiserfs: run scr... |
393 394 395 396 397 398 399 400 401 402 403 |
*/ if ((le_ih_k_offset(ih) + path.pos_in_item) > inode->i_size) break; if ((le_ih_k_offset(ih) - 1 + ih_item_len(ih)) > inode->i_size) { chars = inode->i_size - (le_ih_k_offset(ih) - 1) - path.pos_in_item; done = 1; } else { chars = ih_item_len(ih) - path.pos_in_item; } |
4cf5f7add reiserfs: cleanup... |
404 |
memcpy(p, ih_item_body(bh, ih) + path.pos_in_item, chars); |
bd4c625c0 reiserfs: run scr... |
405 406 407 408 409 |
if (done) break; p += chars; |
098297b27 reiserfs: cleanup... |
410 411 412 413 414 415 |
/* * we done, if read direct item is not the last item of * node FIXME: we could try to check right delimiting key * to see whether direct item continues in the right * neighbor or rely on i_size */ |
bd4c625c0 reiserfs: run scr... |
416 |
if (PATH_LAST_POSITION(&path) != (B_NR_ITEMS(bh) - 1)) |
bd4c625c0 reiserfs: run scr... |
417 |
break; |
098297b27 reiserfs: cleanup... |
418 |
/* update key to look for the next piece */ |
bd4c625c0 reiserfs: run scr... |
419 420 421 |
set_cpu_key_k_offset(&key, cpu_key_k_offset(&key) + chars); result = search_for_position_by_key(inode->i_sb, &key, &path); if (result != POSITION_FOUND) |
098297b27 reiserfs: cleanup... |
422 |
/* i/o error most likely */ |
bd4c625c0 reiserfs: run scr... |
423 424 |
break; bh = get_last_bh(&path); |
4cf5f7add reiserfs: cleanup... |
425 |
ih = tp_item_head(&path); |
bd4c625c0 reiserfs: run scr... |
426 427 428 429 |
} while (1); flush_dcache_page(bh_result->b_page); kunmap(bh_result->b_page); |
cf776a7a4 reiserfs: cleanup... |
430 |
finished: |
bd4c625c0 reiserfs: run scr... |
431 432 433 434 |
pathrelse(&path); if (result == IO_ERROR) return -EIO; |
1da177e4c Linux-2.6.12-rc2 |
435 |
|
098297b27 reiserfs: cleanup... |
436 437 |
/* * this buffer has valid data, but isn't valid for io. mapping it to |
bd4c625c0 reiserfs: run scr... |
438 439 440 441 442 443 |
* block #0 tells the rest of reiserfs it just has a tail in it */ map_bh(bh_result, inode->i_sb, 0); set_buffer_uptodate(bh_result); return 0; } |
1da177e4c Linux-2.6.12-rc2 |
444 |
|
098297b27 reiserfs: cleanup... |
445 446 447 448 |
/* * this is called to create file map. So, _get_block_create_0 will not * read direct item */ |
bd4c625c0 reiserfs: run scr... |
449 450 |
static int reiserfs_bmap(struct inode *inode, sector_t block, struct buffer_head *bh_result, int create) |
1da177e4c Linux-2.6.12-rc2 |
451 |
{ |
bd4c625c0 reiserfs: run scr... |
452 453 454 455 456 457 458 459 |
if (!file_capable(inode, block)) return -EFBIG; reiserfs_write_lock(inode->i_sb); /* do not read the direct item */ _get_block_create_0(inode, block, bh_result, 0); reiserfs_write_unlock(inode->i_sb); return 0; |
1da177e4c Linux-2.6.12-rc2 |
460 |
} |
098297b27 reiserfs: cleanup... |
461 462 463 464 465 466 467 468 469 470 471 472 473 474 475 476 477 |
/* * special version of get_block that is only used by grab_tail_page right * now. It is sent to __block_write_begin, and when you try to get a * block past the end of the file (or a block from a hole) it returns * -ENOENT instead of a valid buffer. __block_write_begin expects to * be able to do i/o on the buffers returned, unless an error value * is also returned. * * So, this allows __block_write_begin to be used for reading a single block * in a page. Where it does not produce a valid page for holes, or past the * end of the file. This turns out to be exactly what we need for reading * tails for conversion. * * The point of the wrapper is forcing a certain value for create, even * though the VFS layer is calling this function with create==1. If you * don't want to send create == GET_BLOCK_NO_HOLE to reiserfs_get_block, * don't use this function. |
1da177e4c Linux-2.6.12-rc2 |
478 |
*/ |
bd4c625c0 reiserfs: run scr... |
479 480 481 482 483 |
static int reiserfs_get_block_create_0(struct inode *inode, sector_t block, struct buffer_head *bh_result, int create) { return reiserfs_get_block(inode, block, bh_result, GET_BLOCK_NO_HOLE); |
1da177e4c Linux-2.6.12-rc2 |
484 |
} |
098297b27 reiserfs: cleanup... |
485 486 487 488 |
/* * This is special helper for reiserfs_get_block in case we are executing * direct_IO request. */ |
1da177e4c Linux-2.6.12-rc2 |
489 490 |
static int reiserfs_get_blocks_direct_io(struct inode *inode, sector_t iblock, |
1da177e4c Linux-2.6.12-rc2 |
491 492 493 |
struct buffer_head *bh_result, int create) { |
bd4c625c0 reiserfs: run scr... |
494 495 496 |
int ret; bh_result->b_page = NULL; |
1da177e4c Linux-2.6.12-rc2 |
497 |
|
098297b27 reiserfs: cleanup... |
498 499 500 501 502 |
/* * We set the b_size before reiserfs_get_block call since it is * referenced in convert_tail_for_hole() that may be called from * reiserfs_get_block() */ |
93407472a fs: add i_blocksi... |
503 |
bh_result->b_size = i_blocksize(inode); |
bd4c625c0 reiserfs: run scr... |
504 505 506 507 508 509 510 511 |
ret = reiserfs_get_block(inode, iblock, bh_result, create | GET_BLOCK_NO_DANGLE); if (ret) goto out; /* don't allow direct io onto tail pages */ if (buffer_mapped(bh_result) && bh_result->b_blocknr == 0) { |
098297b27 reiserfs: cleanup... |
512 513 514 |
/* * make sure future calls to the direct io funcs for this * offset in the file fail by unmapping the buffer |
bd4c625c0 reiserfs: run scr... |
515 516 517 518 |
*/ clear_buffer_mapped(bh_result); ret = -EINVAL; } |
098297b27 reiserfs: cleanup... |
519 520 521 522 523 |
/* * Possible unpacked tail. Flush the data before pages have * disappeared */ |
bd4c625c0 reiserfs: run scr... |
524 525 |
if (REISERFS_I(inode)->i_flags & i_pack_on_close_mask) { int err; |
8ebc42323 reiserfs: kill-th... |
526 527 |
reiserfs_write_lock(inode->i_sb); |
bd4c625c0 reiserfs: run scr... |
528 529 |
err = reiserfs_commit_for_inode(inode); REISERFS_I(inode)->i_flags &= ~i_pack_on_close_mask; |
8ebc42323 reiserfs: kill-th... |
530 531 |
reiserfs_write_unlock(inode->i_sb); |
bd4c625c0 reiserfs: run scr... |
532 533 534 |
if (err < 0) ret = err; } |
cf776a7a4 reiserfs: cleanup... |
535 |
out: |
bd4c625c0 reiserfs: run scr... |
536 537 |
return ret; } |
1da177e4c Linux-2.6.12-rc2 |
538 539 |
/* |
098297b27 reiserfs: cleanup... |
540 541 542 543 544 545 546 547 548 |
* helper function for when reiserfs_get_block is called for a hole * but the file tail is still in a direct item * bh_result is the buffer head for the hole * tail_offset is the offset of the start of the tail in the file * * This calls prepare_write, which will start a new transaction * you should not be in a transaction, or have any paths held when you * call this. */ |
bd4c625c0 reiserfs: run scr... |
549 550 551 552 553 554 555 556 557 558 559 560 561 562 563 |
static int convert_tail_for_hole(struct inode *inode, struct buffer_head *bh_result, loff_t tail_offset) { unsigned long index; unsigned long tail_end; unsigned long tail_start; struct page *tail_page; struct page *hole_page = bh_result->b_page; int retval = 0; if ((tail_offset & (bh_result->b_size - 1)) != 1) return -EIO; /* always try to read until the end of the block */ |
09cbfeaf1 mm, fs: get rid o... |
564 |
tail_start = tail_offset & (PAGE_SIZE - 1); |
bd4c625c0 reiserfs: run scr... |
565 |
tail_end = (tail_start | (bh_result->b_size - 1)) + 1; |
09cbfeaf1 mm, fs: get rid o... |
566 |
index = tail_offset >> PAGE_SHIFT; |
098297b27 reiserfs: cleanup... |
567 568 569 570 |
/* * hole_page can be zero in case of direct_io, we are sure * that we cannot get here if we write with O_DIRECT into tail page */ |
bd4c625c0 reiserfs: run scr... |
571 572 573 574 575 576 577 578 579 |
if (!hole_page || index != hole_page->index) { tail_page = grab_cache_page(inode->i_mapping, index); retval = -ENOMEM; if (!tail_page) { goto out; } } else { tail_page = hole_page; } |
098297b27 reiserfs: cleanup... |
580 581 582 583 584 585 586 587 588 |
/* * we don't have to make sure the conversion did not happen while * we were locking the page because anyone that could convert * must first take i_mutex. * * We must fix the tail page for writing because it might have buffers * that are mapped, but have a block number of 0. This indicates tail * data that has been read directly into the page, and * __block_write_begin won't trigger a get_block in this case. |
bd4c625c0 reiserfs: run scr... |
589 590 |
*/ fix_tail_page_for_writing(tail_page); |
ebdec241d fs: kill block_pr... |
591 592 |
retval = __reiserfs_write_begin(tail_page, tail_start, tail_end - tail_start); |
bd4c625c0 reiserfs: run scr... |
593 594 595 596 597 598 599 |
if (retval) goto unlock; /* tail conversion might change the data in the page */ flush_dcache_page(tail_page); retval = reiserfs_commit_write(NULL, tail_page, tail_start, tail_end); |
cf776a7a4 reiserfs: cleanup... |
600 |
unlock: |
bd4c625c0 reiserfs: run scr... |
601 602 |
if (tail_page != hole_page) { unlock_page(tail_page); |
09cbfeaf1 mm, fs: get rid o... |
603 |
put_page(tail_page); |
bd4c625c0 reiserfs: run scr... |
604 |
} |
cf776a7a4 reiserfs: cleanup... |
605 |
out: |
bd4c625c0 reiserfs: run scr... |
606 |
return retval; |
1da177e4c Linux-2.6.12-rc2 |
607 608 609 |
} static inline int _allocate_block(struct reiserfs_transaction_handle *th, |
3ee166704 reiserfs: fix usa... |
610 |
sector_t block, |
bd4c625c0 reiserfs: run scr... |
611 612 |
struct inode *inode, b_blocknr_t * allocated_block_nr, |
fec6d055d [PATCH] struct pa... |
613 |
struct treepath *path, int flags) |
bd4c625c0 reiserfs: run scr... |
614 615 |
{ BUG_ON(!th->t_trans_id); |
1da177e4c Linux-2.6.12-rc2 |
616 |
#ifdef REISERFS_PREALLOCATE |
1b1dcc1b5 [PATCH] mutex sub... |
617 |
if (!(flags & GET_BLOCK_NO_IMUX)) { |
bd4c625c0 reiserfs: run scr... |
618 619 620 |
return reiserfs_new_unf_blocknrs2(th, inode, allocated_block_nr, path, block); } |
1da177e4c Linux-2.6.12-rc2 |
621 |
#endif |
bd4c625c0 reiserfs: run scr... |
622 623 |
return reiserfs_new_unf_blocknrs(th, inode, allocated_block_nr, path, block); |
1da177e4c Linux-2.6.12-rc2 |
624 |
} |
bd4c625c0 reiserfs: run scr... |
625 626 |
int reiserfs_get_block(struct inode *inode, sector_t block, struct buffer_head *bh_result, int create) |
1da177e4c Linux-2.6.12-rc2 |
627 |
{ |
bd4c625c0 reiserfs: run scr... |
628 |
int repeat, retval = 0; |
098297b27 reiserfs: cleanup... |
629 630 |
/* b_blocknr_t is (unsigned) 32 bit int*/ b_blocknr_t allocated_block_nr = 0; |
bd4c625c0 reiserfs: run scr... |
631 632 633 634 635 636 637 638 639 |
INITIALIZE_PATH(path); int pos_in_item; struct cpu_key key; struct buffer_head *bh, *unbh = NULL; struct item_head *ih, tmp_ih; __le32 *item; int done; int fs_gen; struct reiserfs_transaction_handle *th = NULL; |
098297b27 reiserfs: cleanup... |
640 641 642 643 644 645 646 647 |
/* * space reserved in transaction batch: * . 3 balancings in direct->indirect conversion * . 1 block involved into reiserfs_update_sd() * XXX in practically impossible worst case direct2indirect() * can incur (much) more than 3 balancings. * quota update for user, group */ |
bd4c625c0 reiserfs: run scr... |
648 649 650 651 652 653 654 |
int jbegin_count = JOURNAL_PER_BALANCE_CNT * 3 + 1 + 2 * REISERFS_QUOTA_TRANS_BLOCKS(inode->i_sb); int version; int dangle = 1; loff_t new_offset = (((loff_t) block) << inode->i_sb->s_blocksize_bits) + 1; |
278f6679f reiserfs: locking... |
655 |
reiserfs_write_lock(inode->i_sb); |
bd4c625c0 reiserfs: run scr... |
656 |
version = get_inode_item_key_version(inode); |
1da177e4c Linux-2.6.12-rc2 |
657 |
|
bd4c625c0 reiserfs: run scr... |
658 |
if (!file_capable(inode, block)) { |
278f6679f reiserfs: locking... |
659 |
reiserfs_write_unlock(inode->i_sb); |
bd4c625c0 reiserfs: run scr... |
660 661 |
return -EFBIG; } |
098297b27 reiserfs: cleanup... |
662 663 664 |
/* * if !create, we aren't changing the FS, so we don't need to * log anything, so we don't need to start a transaction |
bd4c625c0 reiserfs: run scr... |
665 666 667 668 669 670 |
*/ if (!(create & GET_BLOCK_CREATE)) { int ret; /* find number of block-th logical block of the file */ ret = _get_block_create_0(inode, block, bh_result, create | GET_BLOCK_READ_DIRECT); |
278f6679f reiserfs: locking... |
671 |
reiserfs_write_unlock(inode->i_sb); |
bd4c625c0 reiserfs: run scr... |
672 673 |
return ret; } |
098297b27 reiserfs: cleanup... |
674 |
|
bd4c625c0 reiserfs: run scr... |
675 676 677 678 679 680 681 |
/* * if we're already in a transaction, make sure to close * any new transactions we start in this func */ if ((create & GET_BLOCK_NO_DANGLE) || reiserfs_transaction_running(inode->i_sb)) dangle = 0; |
098297b27 reiserfs: cleanup... |
682 683 684 685 |
/* * If file is of such a size, that it might have a tail and * tails are enabled we should mark it as possibly needing * tail packing on close |
bd4c625c0 reiserfs: run scr... |
686 687 688 689 690 691 692 693 694 695 |
*/ if ((have_large_tails(inode->i_sb) && inode->i_size < i_block_size(inode) * 4) || (have_small_tails(inode->i_sb) && inode->i_size < i_block_size(inode))) REISERFS_I(inode)->i_flags |= i_pack_on_close_mask; /* set the key of the first byte in the 'block'-th block of file */ make_cpu_key(&key, inode, new_offset, TYPE_ANY, 3 /*key length */ ); if ((new_offset + inode->i_sb->s_blocksize - 1) > inode->i_size) { |
cf776a7a4 reiserfs: cleanup... |
696 |
start_trans: |
bd4c625c0 reiserfs: run scr... |
697 698 699 |
th = reiserfs_persistent_transaction(inode->i_sb, jbegin_count); if (!th) { retval = -ENOMEM; |
1da177e4c Linux-2.6.12-rc2 |
700 701 |
goto failure; } |
bd4c625c0 reiserfs: run scr... |
702 703 |
reiserfs_update_inode_transaction(inode); } |
cf776a7a4 reiserfs: cleanup... |
704 |
research: |
1da177e4c Linux-2.6.12-rc2 |
705 |
|
bd4c625c0 reiserfs: run scr... |
706 |
retval = search_for_position_by_key(inode->i_sb, &key, &path); |
1da177e4c Linux-2.6.12-rc2 |
707 |
if (retval == IO_ERROR) { |
bd4c625c0 reiserfs: run scr... |
708 709 710 711 712 |
retval = -EIO; goto failure; } bh = get_last_bh(&path); |
4cf5f7add reiserfs: cleanup... |
713 714 |
ih = tp_item_head(&path); item = tp_item_body(&path); |
1da177e4c Linux-2.6.12-rc2 |
715 |
pos_in_item = path.pos_in_item; |
1da177e4c Linux-2.6.12-rc2 |
716 |
|
bd4c625c0 reiserfs: run scr... |
717 718 719 720 721 722 723 724 725 726 727 728 729 730 |
fs_gen = get_generation(inode->i_sb); copy_item_head(&tmp_ih, ih); if (allocation_needed (retval, allocated_block_nr, ih, item, pos_in_item)) { /* we have to allocate block for the unformatted node */ if (!th) { pathrelse(&path); goto start_trans; } repeat = _allocate_block(th, block, inode, &allocated_block_nr, &path, create); |
098297b27 reiserfs: cleanup... |
731 732 733 734 735 |
/* * restart the transaction to give the journal a chance to free * some blocks. releases the path, so we have to go back to * research if we succeed on the second try */ |
bd4c625c0 reiserfs: run scr... |
736 |
if (repeat == NO_DISK_SPACE || repeat == QUOTA_EXCEEDED) { |
bd4c625c0 reiserfs: run scr... |
737 738 739 740 741 742 743 744 745 746 747 748 749 750 751 752 753 754 755 756 757 758 759 760 761 762 |
SB_JOURNAL(inode->i_sb)->j_next_async_flush = 1; retval = restart_transaction(th, inode, &path); if (retval) goto failure; repeat = _allocate_block(th, block, inode, &allocated_block_nr, NULL, create); if (repeat != NO_DISK_SPACE && repeat != QUOTA_EXCEEDED) { goto research; } if (repeat == QUOTA_EXCEEDED) retval = -EDQUOT; else retval = -ENOSPC; goto failure; } if (fs_changed(fs_gen, inode->i_sb) && item_moved(&tmp_ih, &path)) { goto research; } } if (indirect_item_found(retval, ih)) { b_blocknr_t unfm_ptr; |
098297b27 reiserfs: cleanup... |
763 764 765 766 767 |
/* * 'block'-th block is in the file already (there is * corresponding cell in some indirect item). But it may be * zero unformatted node pointer (hole) */ |
bd4c625c0 reiserfs: run scr... |
768 769 770 771 772 773 774 775 776 777 778 779 780 781 782 783 |
unfm_ptr = get_block_num(item, pos_in_item); if (unfm_ptr == 0) { /* use allocated block to plug the hole */ reiserfs_prepare_for_journal(inode->i_sb, bh, 1); if (fs_changed(fs_gen, inode->i_sb) && item_moved(&tmp_ih, &path)) { reiserfs_restore_prepared_buffer(inode->i_sb, bh); goto research; } set_buffer_new(bh_result); if (buffer_dirty(bh_result) && reiserfs_data_ordered(inode->i_sb)) reiserfs_add_ordered_list(inode, bh_result); put_block_num(item, pos_in_item, allocated_block_nr); unfm_ptr = allocated_block_nr; |
09f1b80ba reiserfs: cleanup... |
784 |
journal_mark_dirty(th, bh); |
bd4c625c0 reiserfs: run scr... |
785 786 787 788 789 790 791 |
reiserfs_update_sd(th, inode); } set_block_dev_mapped(bh_result, unfm_ptr, inode); pathrelse(&path); retval = 0; if (!dangle && th) retval = reiserfs_end_persistent_transaction(th); |
278f6679f reiserfs: locking... |
792 |
reiserfs_write_unlock(inode->i_sb); |
bd4c625c0 reiserfs: run scr... |
793 |
|
098297b27 reiserfs: cleanup... |
794 795 796 797 |
/* * the item was found, so new blocks were not added to the file * there is no need to make sure the inode is updated with this * transaction |
bd4c625c0 reiserfs: run scr... |
798 799 800 801 802 803 804 805 |
*/ return retval; } if (!th) { pathrelse(&path); goto start_trans; } |
098297b27 reiserfs: cleanup... |
806 807 808 809 810 |
/* * desired position is not found or is in the direct item. We have * to append file with holes up to 'block'-th block converting * direct items to indirect one if necessary */ |
bd4c625c0 reiserfs: run scr... |
811 812 813 814 815 816 817 818 819 820 |
done = 0; do { if (is_statdata_le_ih(ih)) { __le32 unp = 0; struct cpu_key tmp_key; /* indirect item has to be inserted */ make_le_item_head(&tmp_ih, &key, version, 1, TYPE_INDIRECT, UNFM_P_SIZE, 0 /* free_space */ ); |
098297b27 reiserfs: cleanup... |
821 822 823 824 |
/* * we are going to add 'block'-th block to the file. * Use allocated block for that */ |
bd4c625c0 reiserfs: run scr... |
825 |
if (cpu_key_k_offset(&key) == 1) { |
bd4c625c0 reiserfs: run scr... |
826 827 828 829 830 831 |
unp = cpu_to_le32(allocated_block_nr); set_block_dev_mapped(bh_result, allocated_block_nr, inode); set_buffer_new(bh_result); done = 1; } |
098297b27 reiserfs: cleanup... |
832 |
tmp_key = key; /* ;) */ |
bd4c625c0 reiserfs: run scr... |
833 834 835 836 837 838 839 840 841 |
set_cpu_key_k_offset(&tmp_key, 1); PATH_LAST_POSITION(&path)++; retval = reiserfs_insert_item(th, &path, &tmp_key, &tmp_ih, inode, (char *)&unp); if (retval) { reiserfs_free_block(th, inode, allocated_block_nr, 1); |
098297b27 reiserfs: cleanup... |
842 843 844 845 846 |
/* * retval == -ENOSPC, -EDQUOT or -EIO * or -EEXIST */ goto failure; |
bd4c625c0 reiserfs: run scr... |
847 |
} |
bd4c625c0 reiserfs: run scr... |
848 849 850 851 852 853 854 |
} else if (is_direct_le_ih(ih)) { /* direct item has to be converted */ loff_t tail_offset; tail_offset = ((le_ih_k_offset(ih) - 1) & ~(inode->i_sb->s_blocksize - 1)) + 1; |
098297b27 reiserfs: cleanup... |
855 856 857 858 859 860 |
/* * direct item we just found fits into block we have * to map. Convert it into unformatted node: use * bh_result for the conversion */ |
bd4c625c0 reiserfs: run scr... |
861 |
if (tail_offset == cpu_key_k_offset(&key)) { |
bd4c625c0 reiserfs: run scr... |
862 863 864 865 866 |
set_block_dev_mapped(bh_result, allocated_block_nr, inode); unbh = bh_result; done = 1; } else { |
098297b27 reiserfs: cleanup... |
867 868 869 870 871 872 |
/* * we have to pad file tail stored in direct * item(s) up to block size and convert it * to unformatted node. FIXME: this should * also get into page cache */ |
bd4c625c0 reiserfs: run scr... |
873 874 875 876 877 878 879 880 881 882 883 884 885 886 887 888 889 890 891 892 893 |
pathrelse(&path); /* * ugly, but we can only end the transaction if * we aren't nested */ BUG_ON(!th->t_refcount); if (th->t_refcount == 1) { retval = reiserfs_end_persistent_transaction (th); th = NULL; if (retval) goto failure; } retval = convert_tail_for_hole(inode, bh_result, tail_offset); if (retval) { if (retval != -ENOSPC) |
0030b6457 reiserfs: use rei... |
894 895 896 897 898 899 |
reiserfs_error(inode->i_sb, "clm-6004", "convert tail failed " "inode %lu, error %d", inode->i_ino, retval); |
bd4c625c0 reiserfs: run scr... |
900 |
if (allocated_block_nr) { |
098297b27 reiserfs: cleanup... |
901 902 903 904 |
/* * the bitmap, the super, * and the stat data == 3 */ |
bd4c625c0 reiserfs: run scr... |
905 906 907 908 909 910 911 912 913 914 915 916 917 918 919 920 921 922 923 924 925 |
if (!th) th = reiserfs_persistent_transaction(inode->i_sb, 3); if (th) reiserfs_free_block(th, inode, allocated_block_nr, 1); } goto failure; } goto research; } retval = direct2indirect(th, inode, &path, unbh, tail_offset); if (retval) { reiserfs_unmap_buffer(unbh); reiserfs_free_block(th, inode, allocated_block_nr, 1); goto failure; } |
098297b27 reiserfs: cleanup... |
926 927 928 929 930 931 932 933 934 |
/* * it is important the set_buffer_uptodate is done * after the direct2indirect. The buffer might * contain valid data newer than the data on disk * (read by readpage, changed, and then sent here by * writepage). direct2indirect needs to know if unbh * was already up to date, so it can decide if the * data in unbh needs to be replaced with data from * the disk |
bd4c625c0 reiserfs: run scr... |
935 936 |
*/ set_buffer_uptodate(unbh); |
098297b27 reiserfs: cleanup... |
937 938 939 940 |
/* * unbh->b_page == NULL in case of DIRECT_IO request, * this means buffer will disappear shortly, so it * should not be added to |
bd4c625c0 reiserfs: run scr... |
941 942 |
*/ if (unbh->b_page) { |
098297b27 reiserfs: cleanup... |
943 944 945 |
/* * we've converted the tail, so we must * flush unbh before the transaction commits |
bd4c625c0 reiserfs: run scr... |
946 947 |
*/ reiserfs_add_tail_list(inode, unbh); |
098297b27 reiserfs: cleanup... |
948 949 950 951 |
/* * mark it dirty now to prevent commit_write * from adding this buffer to the inode's * dirty buffer list |
bd4c625c0 reiserfs: run scr... |
952 953 |
*/ /* |
098297b27 reiserfs: cleanup... |
954 955 956 957 958 959 |
* AKPM: changed __mark_buffer_dirty to * mark_buffer_dirty(). It's still atomic, * but it sets the page dirty too, which makes * it eligible for writeback at any time by the * VM (which was also the case with * __mark_buffer_dirty()) |
bd4c625c0 reiserfs: run scr... |
960 961 962 963 |
*/ mark_buffer_dirty(unbh); } } else { |
098297b27 reiserfs: cleanup... |
964 965 966 967 968 |
/* * append indirect item with holes if needed, when * appending pointer to 'block'-th block use block, * which is already allocated */ |
bd4c625c0 reiserfs: run scr... |
969 |
struct cpu_key tmp_key; |
098297b27 reiserfs: cleanup... |
970 971 972 973 974 |
/* * We use this in case we need to allocate * only one block which is a fastpath */ unp_t unf_single = 0; |
bd4c625c0 reiserfs: run scr... |
975 976 977 978 979 980 981 982 |
unp_t *un; __u64 max_to_insert = MAX_ITEM_LEN(inode->i_sb->s_blocksize) / UNFM_P_SIZE; __u64 blocks_needed; RFALSE(pos_in_item != ih_item_len(ih) / UNFM_P_SIZE, "vs-804: invalid position for append"); |
098297b27 reiserfs: cleanup... |
983 984 985 986 987 |
/* * indirect item has to be appended, * set up key of that position * (key type is unimportant) */ |
bd4c625c0 reiserfs: run scr... |
988 989 |
make_cpu_key(&tmp_key, inode, le_key_k_offset(version, |
a228bf8f0 reiserfs: cleanup... |
990 |
&ih->ih_key) + |
bd4c625c0 reiserfs: run scr... |
991 992 |
op_bytes_number(ih, inode->i_sb->s_blocksize), |
098297b27 reiserfs: cleanup... |
993 |
TYPE_INDIRECT, 3); |
bd4c625c0 reiserfs: run scr... |
994 |
|
c499ec24c [PATCH] reiserfs:... |
995 996 |
RFALSE(cpu_key_k_offset(&tmp_key) > cpu_key_k_offset(&key), "green-805: invalid offset"); |
bd4c625c0 reiserfs: run scr... |
997 998 999 1000 1001 |
blocks_needed = 1 + ((cpu_key_k_offset(&key) - cpu_key_k_offset(&tmp_key)) >> inode->i_sb-> s_blocksize_bits); |
bd4c625c0 reiserfs: run scr... |
1002 1003 1004 1005 |
if (blocks_needed == 1) { un = &unf_single; } else { |
6396bb221 treewide: kzalloc... |
1006 1007 |
un = kcalloc(min(blocks_needed, max_to_insert), UNFM_P_SIZE, GFP_NOFS); |
bd4c625c0 reiserfs: run scr... |
1008 1009 1010 1011 |
if (!un) { un = &unf_single; blocks_needed = 1; max_to_insert = 0; |
01afb2134 [PATCH] reiser: r... |
1012 |
} |
bd4c625c0 reiserfs: run scr... |
1013 1014 |
} if (blocks_needed <= max_to_insert) { |
098297b27 reiserfs: cleanup... |
1015 1016 1017 1018 |
/* * we are going to add target block to * the file. Use allocated block for that */ |
bd4c625c0 reiserfs: run scr... |
1019 1020 1021 1022 1023 1024 1025 1026 |
un[blocks_needed - 1] = cpu_to_le32(allocated_block_nr); set_block_dev_mapped(bh_result, allocated_block_nr, inode); set_buffer_new(bh_result); done = 1; } else { /* paste hole to the indirect item */ |
098297b27 reiserfs: cleanup... |
1027 |
/* |
5626de1e9 reiserfs: Replace... |
1028 |
* If kcalloc failed, max_to_insert becomes |
098297b27 reiserfs: cleanup... |
1029 1030 1031 |
* zero and it means we only have space for * one block */ |
bd4c625c0 reiserfs: run scr... |
1032 1033 1034 1035 1036 1037 1038 1039 1040 1041 1042 1043 1044 1045 1046 1047 1048 1049 |
blocks_needed = max_to_insert ? max_to_insert : 1; } retval = reiserfs_paste_into_item(th, &path, &tmp_key, inode, (char *)un, UNFM_P_SIZE * blocks_needed); if (blocks_needed != 1) kfree(un); if (retval) { reiserfs_free_block(th, inode, allocated_block_nr, 1); goto failure; } if (!done) { |
098297b27 reiserfs: cleanup... |
1050 1051 1052 1053 1054 1055 |
/* * We need to mark new file size in case * this function will be interrupted/aborted * later on. And we may do this only for * holes. */ |
bd4c625c0 reiserfs: run scr... |
1056 1057 1058 1059 |
inode->i_size += inode->i_sb->s_blocksize * blocks_needed; } } |
1da177e4c Linux-2.6.12-rc2 |
1060 |
|
bd4c625c0 reiserfs: run scr... |
1061 1062 |
if (done == 1) break; |
1da177e4c Linux-2.6.12-rc2 |
1063 |
|
098297b27 reiserfs: cleanup... |
1064 1065 1066 1067 1068 1069 1070 |
/* * this loop could log more blocks than we had originally * asked for. So, we have to allow the transaction to end * if it is too big or too full. Update the inode so things * are consistent if we crash before the function returns * release the path so that anybody waiting on the path before * ending their transaction will be able to continue. |
bd4c625c0 reiserfs: run scr... |
1071 1072 1073 1074 1075 1076 |
*/ if (journal_transaction_should_end(th, th->t_blocks_allocated)) { retval = restart_transaction(th, inode, &path); if (retval) goto failure; } |
8ebc42323 reiserfs: kill-th... |
1077 1078 1079 1080 |
/* * inserting indirect pointers for a hole can take a * long time. reschedule if needed and also release the write * lock for others. |
bd4c625c0 reiserfs: run scr... |
1081 |
*/ |
278f6679f reiserfs: locking... |
1082 |
reiserfs_cond_resched(inode->i_sb); |
1da177e4c Linux-2.6.12-rc2 |
1083 |
|
bd4c625c0 reiserfs: run scr... |
1084 1085 1086 1087 1088 1089 |
retval = search_for_position_by_key(inode->i_sb, &key, &path); if (retval == IO_ERROR) { retval = -EIO; goto failure; } if (retval == POSITION_FOUND) { |
45b03d5e8 reiserfs: rework ... |
1090 |
reiserfs_warning(inode->i_sb, "vs-825", |
bd4c625c0 reiserfs: run scr... |
1091 1092 1093 1094 1095 1096 1097 1098 1099 |
"%K should not be found", &key); retval = -EEXIST; if (allocated_block_nr) reiserfs_free_block(th, inode, allocated_block_nr, 1); pathrelse(&path); goto failure; } bh = get_last_bh(&path); |
4cf5f7add reiserfs: cleanup... |
1100 1101 |
ih = tp_item_head(&path); item = tp_item_body(&path); |
bd4c625c0 reiserfs: run scr... |
1102 1103 1104 1105 |
pos_in_item = path.pos_in_item; } while (1); retval = 0; |
cf776a7a4 reiserfs: cleanup... |
1106 |
failure: |
bd4c625c0 reiserfs: run scr... |
1107 1108 1109 1110 1111 1112 1113 1114 |
if (th && (!dangle || (retval && !th->t_trans_id))) { int err; if (th->t_trans_id) reiserfs_update_sd(th, inode); err = reiserfs_end_persistent_transaction(th); if (err) retval = err; } |
278f6679f reiserfs: locking... |
1115 |
reiserfs_write_unlock(inode->i_sb); |
bd4c625c0 reiserfs: run scr... |
1116 1117 |
reiserfs_check_path(&path); return retval; |
1da177e4c Linux-2.6.12-rc2 |
1118 |
} |
d4388340a fs: convert mpage... |
1119 |
static void reiserfs_readahead(struct readahead_control *rac) |
1da177e4c Linux-2.6.12-rc2 |
1120 |
{ |
d4388340a fs: convert mpage... |
1121 |
mpage_readahead(rac, reiserfs_get_block); |
1da177e4c Linux-2.6.12-rc2 |
1122 |
} |
098297b27 reiserfs: cleanup... |
1123 1124 1125 1126 |
/* * Compute real number of used bytes by file * Following three functions can go away when we'll have enough space in * stat item |
1da177e4c Linux-2.6.12-rc2 |
1127 1128 1129 |
*/ static int real_space_diff(struct inode *inode, int sd_size) { |
bd4c625c0 reiserfs: run scr... |
1130 1131 1132 1133 1134 |
int bytes; loff_t blocksize = inode->i_sb->s_blocksize; if (S_ISLNK(inode->i_mode) || S_ISDIR(inode->i_mode)) return sd_size; |
098297b27 reiserfs: cleanup... |
1135 1136 1137 1138 1139 1140 1141 1142 |
/* * End of file is also in full block with indirect reference, so round * up to the next block. * * there is just no way to know if the tail is actually packed * on the file, so we have to assume it isn't. When we pack the * tail, we add 4 bytes to pretend there really is an unformatted * node pointer |
bd4c625c0 reiserfs: run scr... |
1143 1144 1145 1146 1147 1148 |
*/ bytes = ((inode->i_size + (blocksize - 1)) >> inode->i_sb->s_blocksize_bits) * UNFM_P_SIZE + sd_size; return bytes; |
1da177e4c Linux-2.6.12-rc2 |
1149 1150 1151 |
} static inline loff_t to_real_used_space(struct inode *inode, ulong blocks, |
bd4c625c0 reiserfs: run scr... |
1152 |
int sd_size) |
1da177e4c Linux-2.6.12-rc2 |
1153 |
{ |
bd4c625c0 reiserfs: run scr... |
1154 1155 1156 1157 1158 1159 |
if (S_ISLNK(inode->i_mode) || S_ISDIR(inode->i_mode)) { return inode->i_size + (loff_t) (real_space_diff(inode, sd_size)); } return ((loff_t) real_space_diff(inode, sd_size)) + (((loff_t) blocks) << 9); |
1da177e4c Linux-2.6.12-rc2 |
1160 1161 1162 1163 1164 |
} /* Compute number of blocks used by file in ReiserFS counting */ static inline ulong to_fake_used_blocks(struct inode *inode, int sd_size) { |
bd4c625c0 reiserfs: run scr... |
1165 1166 1167 1168 1169 1170 1171 |
loff_t bytes = inode_get_bytes(inode); loff_t real_space = real_space_diff(inode, sd_size); /* keeps fsck and non-quota versions of reiserfs happy */ if (S_ISLNK(inode->i_mode) || S_ISDIR(inode->i_mode)) { bytes += (loff_t) 511; } |
098297b27 reiserfs: cleanup... |
1172 1173 1174 1175 |
/* * files from before the quota patch might i_blocks such that * bytes < real_space. Deal with that here to prevent it from * going negative. |
bd4c625c0 reiserfs: run scr... |
1176 1177 1178 1179 |
*/ if (bytes < real_space) return 0; return (bytes - real_space) >> 9; |
1da177e4c Linux-2.6.12-rc2 |
1180 |
} |
098297b27 reiserfs: cleanup... |
1181 1182 1183 1184 1185 1186 |
/* * BAD: new directories have stat data of new type and all other items * of old type. Version stored in the inode says about body items, so * in update_stat_data we can not rely on inode, but have to check * item version directly */ |
1da177e4c Linux-2.6.12-rc2 |
1187 |
|
098297b27 reiserfs: cleanup... |
1188 |
/* called by read_locked_inode */ |
fec6d055d [PATCH] struct pa... |
1189 |
static void init_inode(struct inode *inode, struct treepath *path) |
1da177e4c Linux-2.6.12-rc2 |
1190 |
{ |
bd4c625c0 reiserfs: run scr... |
1191 1192 1193 |
struct buffer_head *bh; struct item_head *ih; __u32 rdev; |
bd4c625c0 reiserfs: run scr... |
1194 1195 |
bh = PATH_PLAST_BUFFER(path); |
4cf5f7add reiserfs: cleanup... |
1196 |
ih = tp_item_head(path); |
bd4c625c0 reiserfs: run scr... |
1197 |
|
a228bf8f0 reiserfs: cleanup... |
1198 |
copy_key(INODE_PKEY(inode), &ih->ih_key); |
bd4c625c0 reiserfs: run scr... |
1199 |
|
a228bf8f0 reiserfs: cleanup... |
1200 |
INIT_LIST_HEAD(&REISERFS_I(inode)->i_prealloc_list); |
bd4c625c0 reiserfs: run scr... |
1201 1202 1203 1204 1205 |
REISERFS_I(inode)->i_flags = 0; REISERFS_I(inode)->i_prealloc_block = 0; REISERFS_I(inode)->i_prealloc_count = 0; REISERFS_I(inode)->i_trans_id = 0; REISERFS_I(inode)->i_jl = NULL; |
068fbb315 [PATCH] reiserfs:... |
1206 |
reiserfs_init_xattr_rwsem(inode); |
bd4c625c0 reiserfs: run scr... |
1207 1208 1209 |
if (stat_data_v1(ih)) { struct stat_data_v1 *sd = |
4cf5f7add reiserfs: cleanup... |
1210 |
(struct stat_data_v1 *)ih_item_body(bh, ih); |
bd4c625c0 reiserfs: run scr... |
1211 1212 1213 1214 1215 |
unsigned long blocks; set_inode_item_key_version(inode, KEY_FORMAT_3_5); set_inode_sd_version(inode, STAT_DATA_V1); inode->i_mode = sd_v1_mode(sd); |
bfe868486 filesystems: add ... |
1216 |
set_nlink(inode, sd_v1_nlink(sd)); |
df814654f userns: Convert r... |
1217 1218 |
i_uid_write(inode, sd_v1_uid(sd)); i_gid_write(inode, sd_v1_gid(sd)); |
bd4c625c0 reiserfs: run scr... |
1219 1220 1221 1222 1223 1224 1225 1226 1227 1228 1229 1230 |
inode->i_size = sd_v1_size(sd); inode->i_atime.tv_sec = sd_v1_atime(sd); inode->i_mtime.tv_sec = sd_v1_mtime(sd); inode->i_ctime.tv_sec = sd_v1_ctime(sd); inode->i_atime.tv_nsec = 0; inode->i_ctime.tv_nsec = 0; inode->i_mtime.tv_nsec = 0; inode->i_blocks = sd_v1_blocks(sd); inode->i_generation = le32_to_cpu(INODE_PKEY(inode)->k_dir_id); blocks = (inode->i_size + 511) >> 9; blocks = _ROUND_UP(blocks, inode->i_sb->s_blocksize >> 9); |
098297b27 reiserfs: cleanup... |
1231 1232 1233 1234 1235 1236 1237 1238 1239 |
/* * there was a bug in <=3.5.23 when i_blocks could take * negative values. Starting from 3.5.17 this value could * even be stored in stat data. For such files we set * i_blocks based on file size. Just 2 notes: this can be * wrong for sparse files. On-disk value will be only * updated if file's inode will ever change */ |
bd4c625c0 reiserfs: run scr... |
1240 |
if (inode->i_blocks > blocks) { |
bd4c625c0 reiserfs: run scr... |
1241 1242 |
inode->i_blocks = blocks; } |
1da177e4c Linux-2.6.12-rc2 |
1243 |
|
bd4c625c0 reiserfs: run scr... |
1244 1245 1246 |
rdev = sd_v1_rdev(sd); REISERFS_I(inode)->i_first_direct_byte = sd_v1_first_direct_byte(sd); |
098297b27 reiserfs: cleanup... |
1247 1248 1249 1250 |
/* * an early bug in the quota code can give us an odd * number for the block count. This is incorrect, fix it here. |
bd4c625c0 reiserfs: run scr... |
1251 1252 1253 1254 1255 1256 1257 |
*/ if (inode->i_blocks & 1) { inode->i_blocks++; } inode_set_bytes(inode, to_real_used_space(inode, inode->i_blocks, SD_V1_SIZE)); |
098297b27 reiserfs: cleanup... |
1258 1259 1260 1261 |
/* * nopack is initially zero for v1 objects. For v2 objects, * nopack is initialised from sd_attrs */ |
bd4c625c0 reiserfs: run scr... |
1262 1263 |
REISERFS_I(inode)->i_flags &= ~i_nopack_mask; } else { |
098297b27 reiserfs: cleanup... |
1264 1265 1266 1267 |
/* * new stat data found, but object may have old items * (directories and symlinks) */ |
4cf5f7add reiserfs: cleanup... |
1268 |
struct stat_data *sd = (struct stat_data *)ih_item_body(bh, ih); |
bd4c625c0 reiserfs: run scr... |
1269 1270 |
inode->i_mode = sd_v2_mode(sd); |
bfe868486 filesystems: add ... |
1271 |
set_nlink(inode, sd_v2_nlink(sd)); |
df814654f userns: Convert r... |
1272 |
i_uid_write(inode, sd_v2_uid(sd)); |
bd4c625c0 reiserfs: run scr... |
1273 |
inode->i_size = sd_v2_size(sd); |
df814654f userns: Convert r... |
1274 |
i_gid_write(inode, sd_v2_gid(sd)); |
bd4c625c0 reiserfs: run scr... |
1275 1276 1277 1278 1279 1280 1281 1282 1283 1284 1285 1286 1287 |
inode->i_mtime.tv_sec = sd_v2_mtime(sd); inode->i_atime.tv_sec = sd_v2_atime(sd); inode->i_ctime.tv_sec = sd_v2_ctime(sd); inode->i_ctime.tv_nsec = 0; inode->i_mtime.tv_nsec = 0; inode->i_atime.tv_nsec = 0; inode->i_blocks = sd_v2_blocks(sd); rdev = sd_v2_rdev(sd); if (S_ISCHR(inode->i_mode) || S_ISBLK(inode->i_mode)) inode->i_generation = le32_to_cpu(INODE_PKEY(inode)->k_dir_id); else inode->i_generation = sd_v2_generation(sd); |
1da177e4c Linux-2.6.12-rc2 |
1288 |
|
bd4c625c0 reiserfs: run scr... |
1289 1290 1291 1292 1293 1294 1295 1296 1297 |
if (S_ISDIR(inode->i_mode) || S_ISLNK(inode->i_mode)) set_inode_item_key_version(inode, KEY_FORMAT_3_5); else set_inode_item_key_version(inode, KEY_FORMAT_3_6); REISERFS_I(inode)->i_first_direct_byte = 0; set_inode_sd_version(inode, STAT_DATA_V2); inode_set_bytes(inode, to_real_used_space(inode, inode->i_blocks, SD_V2_SIZE)); |
098297b27 reiserfs: cleanup... |
1298 1299 1300 1301 |
/* * read persistent inode attributes from sd and initialise * generic inode flags from them */ |
bd4c625c0 reiserfs: run scr... |
1302 1303 1304 1305 1306 1307 1308 1309 1310 1311 1312 1313 1314 1315 |
REISERFS_I(inode)->i_attrs = sd_v2_attrs(sd); sd_attrs_to_i_attrs(sd_v2_attrs(sd), inode); } pathrelse(path); if (S_ISREG(inode->i_mode)) { inode->i_op = &reiserfs_file_inode_operations; inode->i_fop = &reiserfs_file_operations; inode->i_mapping->a_ops = &reiserfs_address_space_operations; } else if (S_ISDIR(inode->i_mode)) { inode->i_op = &reiserfs_dir_inode_operations; inode->i_fop = &reiserfs_dir_operations; } else if (S_ISLNK(inode->i_mode)) { inode->i_op = &reiserfs_symlink_inode_operations; |
21fc61c73 don't put symlink... |
1316 |
inode_nohighmem(inode); |
bd4c625c0 reiserfs: run scr... |
1317 1318 1319 1320 1321 1322 1323 |
inode->i_mapping->a_ops = &reiserfs_address_space_operations; } else { inode->i_blocks = 0; inode->i_op = &reiserfs_special_inode_operations; init_special_inode(inode, inode->i_mode, new_decode_dev(rdev)); } } |
1da177e4c Linux-2.6.12-rc2 |
1324 |
|
098297b27 reiserfs: cleanup... |
1325 |
/* update new stat data with inode fields */ |
bd4c625c0 reiserfs: run scr... |
1326 |
static void inode2sd(void *sd, struct inode *inode, loff_t size) |
1da177e4c Linux-2.6.12-rc2 |
1327 |
{ |
bd4c625c0 reiserfs: run scr... |
1328 |
struct stat_data *sd_v2 = (struct stat_data *)sd; |
bd4c625c0 reiserfs: run scr... |
1329 1330 1331 |
set_sd_v2_mode(sd_v2, inode->i_mode); set_sd_v2_nlink(sd_v2, inode->i_nlink); |
df814654f userns: Convert r... |
1332 |
set_sd_v2_uid(sd_v2, i_uid_read(inode)); |
bd4c625c0 reiserfs: run scr... |
1333 |
set_sd_v2_size(sd_v2, size); |
df814654f userns: Convert r... |
1334 |
set_sd_v2_gid(sd_v2, i_gid_read(inode)); |
bd4c625c0 reiserfs: run scr... |
1335 1336 1337 1338 1339 1340 1341 1342 |
set_sd_v2_mtime(sd_v2, inode->i_mtime.tv_sec); set_sd_v2_atime(sd_v2, inode->i_atime.tv_sec); set_sd_v2_ctime(sd_v2, inode->i_ctime.tv_sec); set_sd_v2_blocks(sd_v2, to_fake_used_blocks(inode, SD_V2_SIZE)); if (S_ISCHR(inode->i_mode) || S_ISBLK(inode->i_mode)) set_sd_v2_rdev(sd_v2, new_encode_dev(inode->i_rdev)); else set_sd_v2_generation(sd_v2, inode->i_generation); |
a480b5beb reiserfs: Remove ... |
1343 |
set_sd_v2_attrs(sd_v2, REISERFS_I(inode)->i_attrs); |
1da177e4c Linux-2.6.12-rc2 |
1344 |
} |
098297b27 reiserfs: cleanup... |
1345 |
/* used to copy inode's fields to old stat data */ |
bd4c625c0 reiserfs: run scr... |
1346 |
static void inode2sd_v1(void *sd, struct inode *inode, loff_t size) |
1da177e4c Linux-2.6.12-rc2 |
1347 |
{ |
bd4c625c0 reiserfs: run scr... |
1348 1349 1350 |
struct stat_data_v1 *sd_v1 = (struct stat_data_v1 *)sd; set_sd_v1_mode(sd_v1, inode->i_mode); |
df814654f userns: Convert r... |
1351 1352 |
set_sd_v1_uid(sd_v1, i_uid_read(inode)); set_sd_v1_gid(sd_v1, i_gid_read(inode)); |
bd4c625c0 reiserfs: run scr... |
1353 1354 1355 1356 1357 1358 1359 1360 1361 1362 |
set_sd_v1_nlink(sd_v1, inode->i_nlink); set_sd_v1_size(sd_v1, size); set_sd_v1_atime(sd_v1, inode->i_atime.tv_sec); set_sd_v1_ctime(sd_v1, inode->i_ctime.tv_sec); set_sd_v1_mtime(sd_v1, inode->i_mtime.tv_sec); if (S_ISCHR(inode->i_mode) || S_ISBLK(inode->i_mode)) set_sd_v1_rdev(sd_v1, new_encode_dev(inode->i_rdev)); else set_sd_v1_blocks(sd_v1, to_fake_used_blocks(inode, SD_V1_SIZE)); |
1da177e4c Linux-2.6.12-rc2 |
1363 |
|
098297b27 reiserfs: cleanup... |
1364 |
/* Sigh. i_first_direct_byte is back */ |
bd4c625c0 reiserfs: run scr... |
1365 1366 1367 |
set_sd_v1_first_direct_byte(sd_v1, REISERFS_I(inode)->i_first_direct_byte); } |
1da177e4c Linux-2.6.12-rc2 |
1368 |
|
098297b27 reiserfs: cleanup... |
1369 1370 1371 1372 |
/* * NOTE, you must prepare the buffer head before sending it here, * and then log it after the call */ |
fec6d055d [PATCH] struct pa... |
1373 |
static void update_stat_data(struct treepath *path, struct inode *inode, |
bd4c625c0 reiserfs: run scr... |
1374 |
loff_t size) |
1da177e4c Linux-2.6.12-rc2 |
1375 |
{ |
bd4c625c0 reiserfs: run scr... |
1376 1377 1378 1379 |
struct buffer_head *bh; struct item_head *ih; bh = PATH_PLAST_BUFFER(path); |
4cf5f7add reiserfs: cleanup... |
1380 |
ih = tp_item_head(path); |
bd4c625c0 reiserfs: run scr... |
1381 1382 |
if (!is_statdata_le_ih(ih)) |
c3a9c2109 reiserfs: rework ... |
1383 |
reiserfs_panic(inode->i_sb, "vs-13065", "key %k, found item %h", |
bd4c625c0 reiserfs: run scr... |
1384 |
INODE_PKEY(inode), ih); |
098297b27 reiserfs: cleanup... |
1385 |
/* path points to old stat data */ |
bd4c625c0 reiserfs: run scr... |
1386 |
if (stat_data_v1(ih)) { |
4cf5f7add reiserfs: cleanup... |
1387 |
inode2sd_v1(ih_item_body(bh, ih), inode, size); |
bd4c625c0 reiserfs: run scr... |
1388 |
} else { |
4cf5f7add reiserfs: cleanup... |
1389 |
inode2sd(ih_item_body(bh, ih), inode, size); |
bd4c625c0 reiserfs: run scr... |
1390 |
} |
1da177e4c Linux-2.6.12-rc2 |
1391 |
|
bd4c625c0 reiserfs: run scr... |
1392 1393 |
return; } |
1da177e4c Linux-2.6.12-rc2 |
1394 |
|
bd4c625c0 reiserfs: run scr... |
1395 1396 |
void reiserfs_update_sd_size(struct reiserfs_transaction_handle *th, struct inode *inode, loff_t size) |
1da177e4c Linux-2.6.12-rc2 |
1397 |
{ |
bd4c625c0 reiserfs: run scr... |
1398 1399 1400 1401 1402 1403 1404 1405 |
struct cpu_key key; INITIALIZE_PATH(path); struct buffer_head *bh; int fs_gen; struct item_head *ih, tmp_ih; int retval; BUG_ON(!th->t_trans_id); |
098297b27 reiserfs: cleanup... |
1406 1407 |
/* key type is unimportant */ make_cpu_key(&key, inode, SD_OFFSET, TYPE_STAT_DATA, 3); |
bd4c625c0 reiserfs: run scr... |
1408 1409 1410 1411 1412 1413 |
for (;;) { int pos; /* look for the object's stat data */ retval = search_item(inode->i_sb, &key, &path); if (retval == IO_ERROR) { |
0030b6457 reiserfs: use rei... |
1414 1415 1416 |
reiserfs_error(inode->i_sb, "vs-13050", "i/o failure occurred trying to " "update %K stat data", &key); |
bd4c625c0 reiserfs: run scr... |
1417 1418 1419 1420 1421 1422 1423 1424 1425 |
return; } if (retval == ITEM_NOT_FOUND) { pos = PATH_LAST_POSITION(&path); pathrelse(&path); if (inode->i_nlink == 0) { /*reiserfs_warning (inode->i_sb, "vs-13050: reiserfs_update_sd: i_nlink == 0, stat data not found"); */ return; } |
45b03d5e8 reiserfs: rework ... |
1426 1427 1428 |
reiserfs_warning(inode->i_sb, "vs-13060", "stat data of object %k (nlink == %d) " "not found (pos %d)", |
bd4c625c0 reiserfs: run scr... |
1429 1430 1431 1432 1433 |
INODE_PKEY(inode), inode->i_nlink, pos); reiserfs_check_path(&path); return; } |
098297b27 reiserfs: cleanup... |
1434 1435 1436 1437 |
/* * sigh, prepare_for_journal might schedule. When it * schedules the FS might change. We have to detect that, * and loop back to the search if the stat data item has moved |
bd4c625c0 reiserfs: run scr... |
1438 1439 |
*/ bh = get_last_bh(&path); |
4cf5f7add reiserfs: cleanup... |
1440 |
ih = tp_item_head(&path); |
bd4c625c0 reiserfs: run scr... |
1441 1442 1443 |
copy_item_head(&tmp_ih, ih); fs_gen = get_generation(inode->i_sb); reiserfs_prepare_for_journal(inode->i_sb, bh, 1); |
098297b27 reiserfs: cleanup... |
1444 1445 |
/* Stat_data item has been moved after scheduling. */ |
bd4c625c0 reiserfs: run scr... |
1446 1447 1448 |
if (fs_changed(fs_gen, inode->i_sb) && item_moved(&tmp_ih, &path)) { reiserfs_restore_prepared_buffer(inode->i_sb, bh); |
098297b27 reiserfs: cleanup... |
1449 |
continue; |
bd4c625c0 reiserfs: run scr... |
1450 1451 1452 1453 |
} break; } update_stat_data(&path, inode, size); |
09f1b80ba reiserfs: cleanup... |
1454 |
journal_mark_dirty(th, bh); |
bd4c625c0 reiserfs: run scr... |
1455 1456 |
pathrelse(&path); return; |
1da177e4c Linux-2.6.12-rc2 |
1457 |
} |
098297b27 reiserfs: cleanup... |
1458 1459 1460 1461 1462 1463 1464 |
/* * reiserfs_read_locked_inode is called to read the inode off disk, and it * does a make_bad_inode when things go wrong. But, we need to make sure * and clear the key in the private portion of the inode, otherwise a * corresponding iput might try to delete whatever object the inode last * represented. */ |
bd4c625c0 reiserfs: run scr... |
1465 1466 1467 1468 |
static void reiserfs_make_bad_inode(struct inode *inode) { memset(INODE_PKEY(inode), 0, KEY_SIZE); make_bad_inode(inode); |
1da177e4c Linux-2.6.12-rc2 |
1469 |
} |
098297b27 reiserfs: cleanup... |
1470 1471 1472 1473 |
/* * initially this function was derived from minix or ext2's analog and * evolved as the prototype did */ |
bd4c625c0 reiserfs: run scr... |
1474 |
int reiserfs_init_locked_inode(struct inode *inode, void *p) |
1da177e4c Linux-2.6.12-rc2 |
1475 |
{ |
bd4c625c0 reiserfs: run scr... |
1476 1477 1478 1479 |
struct reiserfs_iget_args *args = (struct reiserfs_iget_args *)p; inode->i_ino = args->objectid; INODE_PKEY(inode)->k_dir_id = cpu_to_le32(args->dirid); return 0; |
1da177e4c Linux-2.6.12-rc2 |
1480 |
} |
098297b27 reiserfs: cleanup... |
1481 1482 1483 1484 |
/* * looks for stat data in the tree, and fills up the fields of in-core * inode stat data fields */ |
bd4c625c0 reiserfs: run scr... |
1485 1486 |
void reiserfs_read_locked_inode(struct inode *inode, struct reiserfs_iget_args *args) |
1da177e4c Linux-2.6.12-rc2 |
1487 |
{ |
bd4c625c0 reiserfs: run scr... |
1488 1489 1490 1491 1492 1493 |
INITIALIZE_PATH(path_to_sd); struct cpu_key key; unsigned long dirino; int retval; dirino = args->dirid; |
098297b27 reiserfs: cleanup... |
1494 1495 1496 1497 |
/* * set version 1, version 2 could be used too, because stat data * key is the same in both versions */ |
4443390e0 reiserfs: Initial... |
1498 |
_make_cpu_key(&key, KEY_FORMAT_3_5, dirino, inode->i_ino, 0, 0, 3); |
bd4c625c0 reiserfs: run scr... |
1499 1500 1501 1502 |
/* look for the object's stat data */ retval = search_item(inode->i_sb, &key, &path_to_sd); if (retval == IO_ERROR) { |
0030b6457 reiserfs: use rei... |
1503 1504 1505 |
reiserfs_error(inode->i_sb, "vs-13070", "i/o failure occurred trying to find " "stat data of %K", &key); |
bd4c625c0 reiserfs: run scr... |
1506 1507 1508 |
reiserfs_make_bad_inode(inode); return; } |
098297b27 reiserfs: cleanup... |
1509 1510 |
/* a stale NFS handle can trigger this without it being an error */ |
bd4c625c0 reiserfs: run scr... |
1511 |
if (retval != ITEM_FOUND) { |
bd4c625c0 reiserfs: run scr... |
1512 1513 |
pathrelse(&path_to_sd); reiserfs_make_bad_inode(inode); |
6d6b77f16 filesystems: add ... |
1514 |
clear_nlink(inode); |
bd4c625c0 reiserfs: run scr... |
1515 1516 1517 1518 |
return; } init_inode(inode, &path_to_sd); |
098297b27 reiserfs: cleanup... |
1519 1520 1521 1522 1523 1524 1525 1526 1527 1528 1529 1530 1531 1532 1533 1534 1535 1536 1537 |
/* * It is possible that knfsd is trying to access inode of a file * that is being removed from the disk by some other thread. As we * update sd on unlink all that is required is to check for nlink * here. This bug was first found by Sizif when debugging * SquidNG/Butterfly, forgotten, and found again after Philippe * Gramoulle <philippe.gramoulle@mmania.com> reproduced it. * More logical fix would require changes in fs/inode.c:iput() to * remove inode from hash-table _after_ fs cleaned disk stuff up and * in iget() to return NULL if I_FREEING inode is found in * hash-table. */ /* * Currently there is one place where it's ok to meet inode with * nlink==0: processing of open-unlinked and half-truncated files * during mount (fs/reiserfs/super.c:finish_unfinished()). */ |
bd4c625c0 reiserfs: run scr... |
1538 1539 |
if ((inode->i_nlink == 0) && !REISERFS_SB(inode->i_sb)->s_is_unlinked_ok) { |
45b03d5e8 reiserfs: rework ... |
1540 |
reiserfs_warning(inode->i_sb, "vs-13075", |
bd4c625c0 reiserfs: run scr... |
1541 1542 1543 1544 1545 |
"dead inode read from disk %K. " "This is likely to be race with knfsd. Ignore", &key); reiserfs_make_bad_inode(inode); } |
098297b27 reiserfs: cleanup... |
1546 1547 |
/* init inode should be relsing */ reiserfs_check_path(&path_to_sd); |
1da177e4c Linux-2.6.12-rc2 |
1548 |
|
4482a087d reiserfs: cache n... |
1549 1550 1551 1552 1553 |
/* * Stat data v1 doesn't support ACLs. */ if (get_inode_sd_version(inode) == STAT_DATA_V1) cache_no_acl(inode); |
1da177e4c Linux-2.6.12-rc2 |
1554 |
} |
098297b27 reiserfs: cleanup... |
1555 |
/* |
1da177e4c Linux-2.6.12-rc2 |
1556 1557 1558 1559 1560 1561 1562 1563 1564 1565 1566 |
* reiserfs_find_actor() - "find actor" reiserfs supplies to iget5_locked(). * * @inode: inode from hash table to check * @opaque: "cookie" passed to iget5_locked(). This is &reiserfs_iget_args. * * This function is called by iget5_locked() to distinguish reiserfs inodes * having the same inode numbers. Such inodes can only exist due to some * error condition. One of them should be bad. Inodes with identical * inode numbers (objectids) are distinguished by parent directory ids. * */ |
bd4c625c0 reiserfs: run scr... |
1567 |
int reiserfs_find_actor(struct inode *inode, void *opaque) |
1da177e4c Linux-2.6.12-rc2 |
1568 |
{ |
bd4c625c0 reiserfs: run scr... |
1569 |
struct reiserfs_iget_args *args; |
1da177e4c Linux-2.6.12-rc2 |
1570 |
|
bd4c625c0 reiserfs: run scr... |
1571 1572 1573 1574 |
args = opaque; /* args is already in CPU order */ return (inode->i_ino == args->objectid) && (le32_to_cpu(INODE_PKEY(inode)->k_dir_id) == args->dirid); |
1da177e4c Linux-2.6.12-rc2 |
1575 |
} |
bd4c625c0 reiserfs: run scr... |
1576 |
struct inode *reiserfs_iget(struct super_block *s, const struct cpu_key *key) |
1da177e4c Linux-2.6.12-rc2 |
1577 |
{ |
bd4c625c0 reiserfs: run scr... |
1578 1579 |
struct inode *inode; struct reiserfs_iget_args args; |
278f6679f reiserfs: locking... |
1580 |
int depth; |
bd4c625c0 reiserfs: run scr... |
1581 1582 1583 |
args.objectid = key->on_disk_key.k_objectid; args.dirid = key->on_disk_key.k_dir_id; |
278f6679f reiserfs: locking... |
1584 |
depth = reiserfs_write_unlock_nested(s); |
bd4c625c0 reiserfs: run scr... |
1585 1586 1587 |
inode = iget5_locked(s, key->on_disk_key.k_objectid, reiserfs_find_actor, reiserfs_init_locked_inode, (void *)(&args)); |
278f6679f reiserfs: locking... |
1588 |
reiserfs_write_lock_nested(s, depth); |
bd4c625c0 reiserfs: run scr... |
1589 1590 1591 1592 1593 1594 1595 1596 1597 1598 1599 1600 1601 1602 |
if (!inode) return ERR_PTR(-ENOMEM); if (inode->i_state & I_NEW) { reiserfs_read_locked_inode(inode, &args); unlock_new_inode(inode); } if (comp_short_keys(INODE_PKEY(inode), key) || is_bad_inode(inode)) { /* either due to i/o error or a stale NFS handle */ iput(inode); inode = NULL; } return inode; |
1da177e4c Linux-2.6.12-rc2 |
1603 |
} |
be55caf17 reiserfs: new exp... |
1604 1605 |
static struct dentry *reiserfs_get_dentry(struct super_block *sb, u32 objectid, u32 dir_id, u32 generation) |
1da177e4c Linux-2.6.12-rc2 |
1606 |
{ |
bd4c625c0 reiserfs: run scr... |
1607 |
struct cpu_key key; |
bd4c625c0 reiserfs: run scr... |
1608 |
struct inode *inode; |
be55caf17 reiserfs: new exp... |
1609 1610 |
key.on_disk_key.k_objectid = objectid; key.on_disk_key.k_dir_id = dir_id; |
bd4c625c0 reiserfs: run scr... |
1611 1612 |
reiserfs_write_lock(sb); inode = reiserfs_iget(sb, &key); |
be55caf17 reiserfs: new exp... |
1613 1614 |
if (inode && !IS_ERR(inode) && generation != 0 && generation != inode->i_generation) { |
bd4c625c0 reiserfs: run scr... |
1615 1616 1617 1618 |
iput(inode); inode = NULL; } reiserfs_write_unlock(sb); |
440037287 [PATCH] switch al... |
1619 1620 |
return d_obtain_alias(inode); |
1da177e4c Linux-2.6.12-rc2 |
1621 |
} |
be55caf17 reiserfs: new exp... |
1622 1623 |
struct dentry *reiserfs_fh_to_dentry(struct super_block *sb, struct fid *fid, int fh_len, int fh_type) |
bd4c625c0 reiserfs: run scr... |
1624 |
{ |
098297b27 reiserfs: cleanup... |
1625 1626 |
/* * fhtype happens to reflect the number of u32s encoded. |
bd4c625c0 reiserfs: run scr... |
1627 1628 1629 1630 1631 1632 1633 1634 1635 1636 1637 |
* due to a bug in earlier code, fhtype might indicate there * are more u32s then actually fitted. * so if fhtype seems to be more than len, reduce fhtype. * Valid types are: * 2 - objectid + dir_id - legacy support * 3 - objectid + dir_id + generation * 4 - objectid + dir_id + objectid and dirid of parent - legacy * 5 - objectid + dir_id + generation + objectid and dirid of parent * 6 - as above plus generation of directory * 6 does not fit in NFSv2 handles */ |
be55caf17 reiserfs: new exp... |
1638 1639 |
if (fh_type > fh_len) { if (fh_type != 6 || fh_len != 5) |
45b03d5e8 reiserfs: rework ... |
1640 |
reiserfs_warning(sb, "reiserfs-13077", |
be55caf17 reiserfs: new exp... |
1641 1642 |
"nfsd/reiserfs, fhtype=%d, len=%d - odd", fh_type, fh_len); |
35c2a7f49 tmpfs,ceph,gfs2,i... |
1643 |
fh_type = fh_len; |
bd4c625c0 reiserfs: run scr... |
1644 |
} |
35c2a7f49 tmpfs,ceph,gfs2,i... |
1645 1646 |
if (fh_len < 2) return NULL; |
bd4c625c0 reiserfs: run scr... |
1647 |
|
be55caf17 reiserfs: new exp... |
1648 1649 1650 |
return reiserfs_get_dentry(sb, fid->raw[0], fid->raw[1], (fh_type == 3 || fh_type >= 5) ? fid->raw[2] : 0); } |
1da177e4c Linux-2.6.12-rc2 |
1651 |
|
be55caf17 reiserfs: new exp... |
1652 1653 1654 |
struct dentry *reiserfs_fh_to_parent(struct super_block *sb, struct fid *fid, int fh_len, int fh_type) { |
35c2a7f49 tmpfs,ceph,gfs2,i... |
1655 1656 |
if (fh_type > fh_len) fh_type = fh_len; |
be55caf17 reiserfs: new exp... |
1657 1658 1659 1660 1661 1662 1663 |
if (fh_type < 4) return NULL; return reiserfs_get_dentry(sb, (fh_type >= 5) ? fid->raw[3] : fid->raw[2], (fh_type >= 5) ? fid->raw[4] : fid->raw[3], (fh_type == 6) ? fid->raw[5] : 0); |
1da177e4c Linux-2.6.12-rc2 |
1664 |
} |
b0b0382bb ->encode_fh() API... |
1665 1666 |
int reiserfs_encode_fh(struct inode *inode, __u32 * data, int *lenp, struct inode *parent) |
bd4c625c0 reiserfs: run scr... |
1667 |
{ |
bd4c625c0 reiserfs: run scr... |
1668 |
int maxlen = *lenp; |
b0b0382bb ->encode_fh() API... |
1669 |
if (parent && (maxlen < 5)) { |
5fe0c2378 exportfs: Return ... |
1670 |
*lenp = 5; |
94e07a759 fs: encode_fh: re... |
1671 |
return FILEID_INVALID; |
5fe0c2378 exportfs: Return ... |
1672 1673 |
} else if (maxlen < 3) { *lenp = 3; |
94e07a759 fs: encode_fh: re... |
1674 |
return FILEID_INVALID; |
5fe0c2378 exportfs: Return ... |
1675 |
} |
bd4c625c0 reiserfs: run scr... |
1676 1677 1678 1679 1680 |
data[0] = inode->i_ino; data[1] = le32_to_cpu(INODE_PKEY(inode)->k_dir_id); data[2] = inode->i_generation; *lenp = 3; |
b0b0382bb ->encode_fh() API... |
1681 1682 1683 1684 1685 1686 1687 1688 |
if (parent) { data[3] = parent->i_ino; data[4] = le32_to_cpu(INODE_PKEY(parent)->k_dir_id); *lenp = 5; if (maxlen >= 6) { data[5] = parent->i_generation; *lenp = 6; } |
bd4c625c0 reiserfs: run scr... |
1689 |
} |
bd4c625c0 reiserfs: run scr... |
1690 1691 |
return *lenp; } |
1da177e4c Linux-2.6.12-rc2 |
1692 |
|
098297b27 reiserfs: cleanup... |
1693 1694 1695 1696 1697 1698 1699 1700 1701 1702 |
/* * looks for stat data, then copies fields to it, marks the buffer * containing stat data as dirty */ /* * reiserfs inodes are never really dirty, since the dirty inode call * always logs them. This call allows the VFS inode marking routines * to properly mark inodes for datasync and such, but only actually * does something when called for a synchronous update. */ |
a9185b41a pass writeback_co... |
1703 |
int reiserfs_write_inode(struct inode *inode, struct writeback_control *wbc) |
bd4c625c0 reiserfs: run scr... |
1704 1705 1706 |
{ struct reiserfs_transaction_handle th; int jbegin_count = 1; |
bc98a42c1 VFS: Convert sb->... |
1707 |
if (sb_rdonly(inode->i_sb)) |
bd4c625c0 reiserfs: run scr... |
1708 |
return -EROFS; |
098297b27 reiserfs: cleanup... |
1709 1710 1711 1712 1713 1714 |
/* * memory pressure can sometimes initiate write_inode calls with * sync == 1, * these cases are just when the system needs ram, not when the * inode needs to reach disk for safety, and they can safely be * ignored because the altered inode has already been logged. |
bd4c625c0 reiserfs: run scr... |
1715 |
*/ |
a9185b41a pass writeback_co... |
1716 |
if (wbc->sync_mode == WB_SYNC_ALL && !(current->flags & PF_MEMALLOC)) { |
bd4c625c0 reiserfs: run scr... |
1717 1718 1719 |
reiserfs_write_lock(inode->i_sb); if (!journal_begin(&th, inode->i_sb, jbegin_count)) { reiserfs_update_sd(&th, inode); |
58d854265 reiserfs: cleanup... |
1720 |
journal_end_sync(&th); |
bd4c625c0 reiserfs: run scr... |
1721 1722 1723 1724 |
} reiserfs_write_unlock(inode->i_sb); } return 0; |
1da177e4c Linux-2.6.12-rc2 |
1725 |
} |
098297b27 reiserfs: cleanup... |
1726 1727 1728 1729 |
/* * stat data of new object is inserted already, this inserts the item * containing "." and ".." entries */ |
bd4c625c0 reiserfs: run scr... |
1730 1731 |
static int reiserfs_new_directory(struct reiserfs_transaction_handle *th, struct inode *inode, |
fec6d055d [PATCH] struct pa... |
1732 |
struct item_head *ih, struct treepath *path, |
bd4c625c0 reiserfs: run scr... |
1733 |
struct inode *dir) |
1da177e4c Linux-2.6.12-rc2 |
1734 |
{ |
bd4c625c0 reiserfs: run scr... |
1735 1736 1737 1738 1739 1740 1741 1742 1743 1744 1745 |
struct super_block *sb = th->t_super; char empty_dir[EMPTY_DIR_SIZE]; char *body = empty_dir; struct cpu_key key; int retval; BUG_ON(!th->t_trans_id); _make_cpu_key(&key, KEY_FORMAT_3_5, le32_to_cpu(ih->ih_key.k_dir_id), le32_to_cpu(ih->ih_key.k_objectid), DOT_OFFSET, TYPE_DIRENTRY, 3 /*key length */ ); |
098297b27 reiserfs: cleanup... |
1746 1747 1748 1749 1750 |
/* * compose item head for new item. Directories consist of items of * old type (ITEM_VERSION_1). Do not set key (second arg is 0), it * is done by reiserfs_new_inode */ |
bd4c625c0 reiserfs: run scr... |
1751 1752 1753 1754 1755 1756 1757 1758 1759 1760 1761 1762 1763 1764 1765 1766 1767 1768 1769 1770 1771 |
if (old_format_only(sb)) { make_le_item_head(ih, NULL, KEY_FORMAT_3_5, DOT_OFFSET, TYPE_DIRENTRY, EMPTY_DIR_SIZE_V1, 2); make_empty_dir_item_v1(body, ih->ih_key.k_dir_id, ih->ih_key.k_objectid, INODE_PKEY(dir)->k_dir_id, INODE_PKEY(dir)->k_objectid); } else { make_le_item_head(ih, NULL, KEY_FORMAT_3_5, DOT_OFFSET, TYPE_DIRENTRY, EMPTY_DIR_SIZE, 2); make_empty_dir_item(body, ih->ih_key.k_dir_id, ih->ih_key.k_objectid, INODE_PKEY(dir)->k_dir_id, INODE_PKEY(dir)->k_objectid); } /* look for place in the tree for new item */ retval = search_item(sb, &key, path); if (retval == IO_ERROR) { |
0030b6457 reiserfs: use rei... |
1772 1773 |
reiserfs_error(sb, "vs-13080", "i/o failure occurred creating new directory"); |
bd4c625c0 reiserfs: run scr... |
1774 1775 1776 1777 |
return -EIO; } if (retval == ITEM_FOUND) { pathrelse(path); |
45b03d5e8 reiserfs: rework ... |
1778 |
reiserfs_warning(sb, "vs-13070", |
bd4c625c0 reiserfs: run scr... |
1779 1780 1781 1782 |
"object with this key exists (%k)", &(ih->ih_key)); return -EEXIST; } |
1da177e4c Linux-2.6.12-rc2 |
1783 |
|
bd4c625c0 reiserfs: run scr... |
1784 1785 1786 |
/* insert item, that is empty directory item */ return reiserfs_insert_item(th, path, &key, ih, inode, body); } |
1da177e4c Linux-2.6.12-rc2 |
1787 |
|
098297b27 reiserfs: cleanup... |
1788 1789 1790 1791 1792 1793 |
/* * stat data of object has been inserted, this inserts the item * containing the body of symlink */ static int reiserfs_new_symlink(struct reiserfs_transaction_handle *th, struct inode *inode, |
bd4c625c0 reiserfs: run scr... |
1794 |
struct item_head *ih, |
fec6d055d [PATCH] struct pa... |
1795 |
struct treepath *path, const char *symname, |
bd4c625c0 reiserfs: run scr... |
1796 |
int item_len) |
1da177e4c Linux-2.6.12-rc2 |
1797 |
{ |
bd4c625c0 reiserfs: run scr... |
1798 1799 1800 1801 1802 1803 1804 1805 1806 1807 1808 1809 1810 1811 1812 1813 1814 |
struct super_block *sb = th->t_super; struct cpu_key key; int retval; BUG_ON(!th->t_trans_id); _make_cpu_key(&key, KEY_FORMAT_3_5, le32_to_cpu(ih->ih_key.k_dir_id), le32_to_cpu(ih->ih_key.k_objectid), 1, TYPE_DIRECT, 3 /*key length */ ); make_le_item_head(ih, NULL, KEY_FORMAT_3_5, 1, TYPE_DIRECT, item_len, 0 /*free_space */ ); /* look for place in the tree for new item */ retval = search_item(sb, &key, path); if (retval == IO_ERROR) { |
0030b6457 reiserfs: use rei... |
1815 1816 |
reiserfs_error(sb, "vs-13080", "i/o failure occurred creating new symlink"); |
bd4c625c0 reiserfs: run scr... |
1817 1818 1819 1820 |
return -EIO; } if (retval == ITEM_FOUND) { pathrelse(path); |
45b03d5e8 reiserfs: rework ... |
1821 |
reiserfs_warning(sb, "vs-13080", |
bd4c625c0 reiserfs: run scr... |
1822 1823 1824 1825 |
"object with this key exists (%k)", &(ih->ih_key)); return -EEXIST; } |
1da177e4c Linux-2.6.12-rc2 |
1826 |
|
bd4c625c0 reiserfs: run scr... |
1827 1828 1829 |
/* insert item, that is body of symlink */ return reiserfs_insert_item(th, path, &key, ih, inode, symname); } |
1da177e4c Linux-2.6.12-rc2 |
1830 |
|
098297b27 reiserfs: cleanup... |
1831 1832 1833 1834 1835 1836 1837 1838 1839 1840 1841 1842 1843 1844 1845 1846 1847 1848 1849 1850 |
/* * inserts the stat data into the tree, and then calls * reiserfs_new_directory (to insert ".", ".." item if new object is * directory) or reiserfs_new_symlink (to insert symlink body if new * object is symlink) or nothing (if new object is regular file) * NOTE! uid and gid must already be set in the inode. If we return * non-zero due to an error, we have to drop the quota previously allocated * for the fresh inode. This can only be done outside a transaction, so * if we return non-zero, we also end the transaction. * * @th: active transaction handle * @dir: parent directory for new inode * @mode: mode of new inode * @symname: symlink contents if inode is symlink * @isize: 0 for regular file, EMPTY_DIR_SIZE for dirs, strlen(symname) for * symlinks * @inode: inode to be filled * @security: optional security context to associate with this inode */ |
bd4c625c0 reiserfs: run scr... |
1851 |
int reiserfs_new_inode(struct reiserfs_transaction_handle *th, |
8e0718924 reiserfs: propaga... |
1852 |
struct inode *dir, umode_t mode, const char *symname, |
0222e6571 reiserfs: strip t... |
1853 |
/* 0 for regular, EMTRY_DIR_SIZE for dirs, |
bd4c625c0 reiserfs: run scr... |
1854 1855 |
strlen (symname) for symlinks) */ loff_t i_size, struct dentry *dentry, |
57fe60df6 reiserfs: add ato... |
1856 1857 |
struct inode *inode, struct reiserfs_security_handle *security) |
1da177e4c Linux-2.6.12-rc2 |
1858 |
{ |
d2d0395fd reiserfs: locking... |
1859 |
struct super_block *sb = dir->i_sb; |
c1eaa26b6 nfsd race fixes: ... |
1860 |
struct reiserfs_iget_args args; |
bd4c625c0 reiserfs: run scr... |
1861 1862 1863 1864 1865 1866 |
INITIALIZE_PATH(path_to_key); struct cpu_key key; struct item_head ih; struct stat_data sd; int retval; int err; |
278f6679f reiserfs: locking... |
1867 |
int depth; |
bd4c625c0 reiserfs: run scr... |
1868 1869 |
BUG_ON(!th->t_trans_id); |
d2d0395fd reiserfs: locking... |
1870 |
depth = reiserfs_write_unlock_nested(sb); |
63936ddaa dquot: cleanup in... |
1871 |
err = dquot_alloc_inode(inode); |
d2d0395fd reiserfs: locking... |
1872 |
reiserfs_write_lock_nested(sb, depth); |
63936ddaa dquot: cleanup in... |
1873 |
if (err) |
bd4c625c0 reiserfs: run scr... |
1874 |
goto out_end_trans; |
585b7747d [PATCH] Remove un... |
1875 |
if (!dir->i_nlink) { |
bd4c625c0 reiserfs: run scr... |
1876 1877 1878 |
err = -EPERM; goto out_bad_inode; } |
bd4c625c0 reiserfs: run scr... |
1879 1880 1881 1882 1883 1884 1885 |
/* item head of new item */ ih.ih_key.k_dir_id = reiserfs_choose_packing(dir); ih.ih_key.k_objectid = cpu_to_le32(reiserfs_get_unused_objectid(th)); if (!ih.ih_key.k_objectid) { err = -ENOMEM; goto out_bad_inode; } |
c1eaa26b6 nfsd race fixes: ... |
1886 |
args.objectid = inode->i_ino = le32_to_cpu(ih.ih_key.k_objectid); |
2f1169e2d fix breakage in r... |
1887 1888 1889 1890 1891 1892 |
if (old_format_only(sb)) make_le_item_head(&ih, NULL, KEY_FORMAT_3_5, SD_OFFSET, TYPE_STAT_DATA, SD_V1_SIZE, MAX_US_INT); else make_le_item_head(&ih, NULL, KEY_FORMAT_3_6, SD_OFFSET, TYPE_STAT_DATA, SD_SIZE, MAX_US_INT); |
a228bf8f0 reiserfs: cleanup... |
1893 |
memcpy(INODE_PKEY(inode), &ih.ih_key, KEY_SIZE); |
c1eaa26b6 nfsd race fixes: ... |
1894 |
args.dirid = le32_to_cpu(ih.ih_key.k_dir_id); |
a1457c0ce reiserfs: fix dea... |
1895 |
|
278f6679f reiserfs: locking... |
1896 |
depth = reiserfs_write_unlock_nested(inode->i_sb); |
a1457c0ce reiserfs: fix dea... |
1897 1898 |
err = insert_inode_locked4(inode, args.objectid, reiserfs_find_actor, &args); |
278f6679f reiserfs: locking... |
1899 |
reiserfs_write_lock_nested(inode->i_sb, depth); |
a1457c0ce reiserfs: fix dea... |
1900 |
if (err) { |
c1eaa26b6 nfsd race fixes: ... |
1901 1902 1903 |
err = -EINVAL; goto out_bad_inode; } |
a1457c0ce reiserfs: fix dea... |
1904 |
|
bd4c625c0 reiserfs: run scr... |
1905 |
if (old_format_only(sb)) |
098297b27 reiserfs: cleanup... |
1906 1907 1908 1909 1910 |
/* * not a perfect generation count, as object ids can be reused, * but this is as good as reiserfs can do right now. * note that the private part of inode isn't filled in yet, * we have to use the directory. |
bd4c625c0 reiserfs: run scr... |
1911 1912 1913 |
*/ inode->i_generation = le32_to_cpu(INODE_PKEY(dir)->k_objectid); else |
1da177e4c Linux-2.6.12-rc2 |
1914 |
#if defined( USE_INODE_GENERATION_COUNTER ) |
bd4c625c0 reiserfs: run scr... |
1915 1916 |
inode->i_generation = le32_to_cpu(REISERFS_SB(sb)->s_rs->s_inode_generation); |
1da177e4c Linux-2.6.12-rc2 |
1917 |
#else |
bd4c625c0 reiserfs: run scr... |
1918 |
inode->i_generation = ++event; |
1da177e4c Linux-2.6.12-rc2 |
1919 |
#endif |
bd4c625c0 reiserfs: run scr... |
1920 |
/* fill stat data */ |
bfe868486 filesystems: add ... |
1921 |
set_nlink(inode, (S_ISDIR(mode) ? 2 : 1)); |
bd4c625c0 reiserfs: run scr... |
1922 1923 |
/* uid and gid must already be set by the caller for quota init */ |
02027d42c fs: Replace CURRE... |
1924 |
inode->i_mtime = inode->i_atime = inode->i_ctime = current_time(inode); |
bd4c625c0 reiserfs: run scr... |
1925 1926 1927 1928 1929 |
inode->i_size = i_size; inode->i_blocks = 0; inode->i_bytes = 0; REISERFS_I(inode)->i_first_direct_byte = S_ISLNK(mode) ? 1 : U32_MAX /*NO_BYTES_IN_DIRECT_ITEM */ ; |
a228bf8f0 reiserfs: cleanup... |
1930 |
INIT_LIST_HEAD(&REISERFS_I(inode)->i_prealloc_list); |
bd4c625c0 reiserfs: run scr... |
1931 1932 1933 1934 1935 1936 1937 1938 |
REISERFS_I(inode)->i_flags = 0; REISERFS_I(inode)->i_prealloc_block = 0; REISERFS_I(inode)->i_prealloc_count = 0; REISERFS_I(inode)->i_trans_id = 0; REISERFS_I(inode)->i_jl = NULL; REISERFS_I(inode)->i_attrs = REISERFS_I(dir)->i_attrs & REISERFS_INHERIT_MASK; sd_attrs_to_i_attrs(REISERFS_I(inode)->i_attrs, inode); |
068fbb315 [PATCH] reiserfs:... |
1939 |
reiserfs_init_xattr_rwsem(inode); |
bd4c625c0 reiserfs: run scr... |
1940 |
|
bd4c625c0 reiserfs: run scr... |
1941 1942 1943 1944 1945 1946 1947 1948 1949 1950 1951 1952 1953 1954 1955 1956 1957 |
/* key to search for correct place for new stat data */ _make_cpu_key(&key, KEY_FORMAT_3_6, le32_to_cpu(ih.ih_key.k_dir_id), le32_to_cpu(ih.ih_key.k_objectid), SD_OFFSET, TYPE_STAT_DATA, 3 /*key length */ ); /* find proper place for inserting of stat data */ retval = search_item(sb, &key, &path_to_key); if (retval == IO_ERROR) { err = -EIO; goto out_bad_inode; } if (retval == ITEM_FOUND) { pathrelse(&path_to_key); err = -EEXIST; goto out_bad_inode; } if (old_format_only(sb)) { |
098297b27 reiserfs: cleanup... |
1958 |
/* i_uid or i_gid is too big to be stored in stat data v3.5 */ |
df814654f userns: Convert r... |
1959 |
if (i_uid_read(inode) & ~0xffff || i_gid_read(inode) & ~0xffff) { |
bd4c625c0 reiserfs: run scr... |
1960 |
pathrelse(&path_to_key); |
bd4c625c0 reiserfs: run scr... |
1961 1962 1963 1964 1965 1966 1967 |
err = -EINVAL; goto out_bad_inode; } inode2sd_v1(&sd, inode, inode->i_size); } else { inode2sd(&sd, inode, inode->i_size); } |
098297b27 reiserfs: cleanup... |
1968 1969 1970 1971 1972 |
/* * store in in-core inode the key of stat data and version all * object items will have (directory items will have old offset * format, other new objects will consist of new items) */ |
bd4c625c0 reiserfs: run scr... |
1973 1974 1975 1976 1977 1978 1979 1980 1981 1982 |
if (old_format_only(sb) || S_ISDIR(mode) || S_ISLNK(mode)) set_inode_item_key_version(inode, KEY_FORMAT_3_5); else set_inode_item_key_version(inode, KEY_FORMAT_3_6); if (old_format_only(sb)) set_inode_sd_version(inode, STAT_DATA_V1); else set_inode_sd_version(inode, STAT_DATA_V2); /* insert the stat data into the tree */ |
1da177e4c Linux-2.6.12-rc2 |
1983 |
#ifdef DISPLACE_NEW_PACKING_LOCALITIES |
bd4c625c0 reiserfs: run scr... |
1984 1985 |
if (REISERFS_I(dir)->new_packing_locality) th->displace_new_blocks = 1; |
1da177e4c Linux-2.6.12-rc2 |
1986 |
#endif |
bd4c625c0 reiserfs: run scr... |
1987 1988 1989 1990 1991 1992 1993 1994 |
retval = reiserfs_insert_item(th, &path_to_key, &key, &ih, inode, (char *)(&sd)); if (retval) { err = retval; reiserfs_check_path(&path_to_key); goto out_bad_inode; } |
1da177e4c Linux-2.6.12-rc2 |
1995 |
#ifdef DISPLACE_NEW_PACKING_LOCALITIES |
bd4c625c0 reiserfs: run scr... |
1996 1997 |
if (!th->displace_new_blocks) REISERFS_I(dir)->new_packing_locality = 0; |
1da177e4c Linux-2.6.12-rc2 |
1998 |
#endif |
bd4c625c0 reiserfs: run scr... |
1999 2000 2001 2002 2003 2004 2005 2006 2007 2008 2009 2010 2011 2012 2013 2014 2015 |
if (S_ISDIR(mode)) { /* insert item with "." and ".." */ retval = reiserfs_new_directory(th, inode, &ih, &path_to_key, dir); } if (S_ISLNK(mode)) { /* insert body of symlink */ if (!old_format_only(sb)) i_size = ROUND_UP(i_size); retval = reiserfs_new_symlink(th, inode, &ih, &path_to_key, symname, i_size); } if (retval) { err = retval; reiserfs_check_path(&path_to_key); |
58d854265 reiserfs: cleanup... |
2016 |
journal_end(th); |
bd4c625c0 reiserfs: run scr... |
2017 2018 |
goto out_inserted_sd; } |
60e4cf67a reiserfs: fix ext... |
2019 2020 2021 2022 2023 2024 2025 2026 |
/* * Mark it private if we're creating the privroot * or something under it. */ if (IS_PRIVATE(dir) || dentry == REISERFS_SB(sb)->priv_root) { inode->i_flags |= S_PRIVATE; inode->i_opflags &= ~IOP_XATTR; } |
bd4c625c0 reiserfs: run scr... |
2027 |
if (reiserfs_posixacl(inode->i_sb)) { |
4c05141df reiserfs: locking... |
2028 |
reiserfs_write_unlock(inode->i_sb); |
0ab2621eb reiserfs: journal... |
2029 |
retval = reiserfs_inherit_default_acl(th, dir, dentry, inode); |
4c05141df reiserfs: locking... |
2030 |
reiserfs_write_lock(inode->i_sb); |
bd4c625c0 reiserfs: run scr... |
2031 2032 2033 |
if (retval) { err = retval; reiserfs_check_path(&path_to_key); |
58d854265 reiserfs: cleanup... |
2034 |
journal_end(th); |
bd4c625c0 reiserfs: run scr... |
2035 2036 |
goto out_inserted_sd; } |
1751e8a6c Rename superblock... |
2037 |
} else if (inode->i_sb->s_flags & SB_POSIXACL) { |
45b03d5e8 reiserfs: rework ... |
2038 2039 |
reiserfs_warning(inode->i_sb, "jdm-13090", "ACLs aren't enabled in the fs, " |
bd4c625c0 reiserfs: run scr... |
2040 |
"but vfs thinks they are!"); |
60e4cf67a reiserfs: fix ext... |
2041 |
} |
bd4c625c0 reiserfs: run scr... |
2042 |
|
57fe60df6 reiserfs: add ato... |
2043 |
if (security->name) { |
4c05141df reiserfs: locking... |
2044 |
reiserfs_write_unlock(inode->i_sb); |
57fe60df6 reiserfs: add ato... |
2045 |
retval = reiserfs_security_write(th, inode, security); |
4c05141df reiserfs: locking... |
2046 |
reiserfs_write_lock(inode->i_sb); |
57fe60df6 reiserfs: add ato... |
2047 2048 2049 |
if (retval) { err = retval; reiserfs_check_path(&path_to_key); |
58d854265 reiserfs: cleanup... |
2050 |
retval = journal_end(th); |
57fe60df6 reiserfs: add ato... |
2051 2052 2053 2054 |
if (retval) err = retval; goto out_inserted_sd; } |
bd4c625c0 reiserfs: run scr... |
2055 |
} |
bd4c625c0 reiserfs: run scr... |
2056 2057 2058 2059 |
reiserfs_update_sd(th, inode); reiserfs_check_path(&path_to_key); return 0; |
1da177e4c Linux-2.6.12-rc2 |
2060 |
|
cf776a7a4 reiserfs: cleanup... |
2061 |
out_bad_inode: |
bd4c625c0 reiserfs: run scr... |
2062 2063 2064 2065 |
/* Invalidate the object, nothing was inserted yet */ INODE_PKEY(inode)->k_objectid = 0; /* Quota change must be inside a transaction for journaling */ |
d2d0395fd reiserfs: locking... |
2066 |
depth = reiserfs_write_unlock_nested(inode->i_sb); |
63936ddaa dquot: cleanup in... |
2067 |
dquot_free_inode(inode); |
d2d0395fd reiserfs: locking... |
2068 |
reiserfs_write_lock_nested(inode->i_sb, depth); |
bd4c625c0 reiserfs: run scr... |
2069 |
|
cf776a7a4 reiserfs: cleanup... |
2070 |
out_end_trans: |
58d854265 reiserfs: cleanup... |
2071 |
journal_end(th); |
098297b27 reiserfs: cleanup... |
2072 2073 2074 2075 |
/* * Drop can be outside and it needs more credits so it's better * to have it outside */ |
d2d0395fd reiserfs: locking... |
2076 |
depth = reiserfs_write_unlock_nested(inode->i_sb); |
9f7547580 dquot: cleanup dq... |
2077 |
dquot_drop(inode); |
d2d0395fd reiserfs: locking... |
2078 |
reiserfs_write_lock_nested(inode->i_sb, depth); |
bd4c625c0 reiserfs: run scr... |
2079 2080 |
inode->i_flags |= S_NOQUOTA; make_bad_inode(inode); |
cf776a7a4 reiserfs: cleanup... |
2081 |
out_inserted_sd: |
6d6b77f16 filesystems: add ... |
2082 |
clear_nlink(inode); |
bd4c625c0 reiserfs: run scr... |
2083 |
th->t_trans_id = 0; /* so the caller can't use this handle later */ |
8859bf2b1 reiserfs: only ca... |
2084 2085 |
if (inode->i_state & I_NEW) unlock_new_inode(inode); |
d984561b3 reiserfs: elimina... |
2086 |
iput(inode); |
bd4c625c0 reiserfs: run scr... |
2087 |
return err; |
1da177e4c Linux-2.6.12-rc2 |
2088 2089 2090 |
} /* |
098297b27 reiserfs: cleanup... |
2091 2092 2093 2094 2095 2096 2097 2098 2099 2100 2101 2102 |
* finds the tail page in the page cache, * reads the last block in. * * On success, page_result is set to a locked, pinned page, and bh_result * is set to an up to date buffer for the last block in the file. returns 0. * * tail conversion is not done, so bh_result might not be valid for writing * check buffer_mapped(bh_result) and bh_result->b_blocknr != 0 before * trying to write the block. * * on failure, nonzero is returned, page_result and bh_result are untouched. */ |
995c762ea reiserfs: rename ... |
2103 |
static int grab_tail_page(struct inode *inode, |
bd4c625c0 reiserfs: run scr... |
2104 2105 2106 |
struct page **page_result, struct buffer_head **bh_result) { |
098297b27 reiserfs: cleanup... |
2107 2108 2109 |
/* * we want the page with the last byte in the file, * not the page that will hold the next byte for appending |
bd4c625c0 reiserfs: run scr... |
2110 |
*/ |
09cbfeaf1 mm, fs: get rid o... |
2111 |
unsigned long index = (inode->i_size - 1) >> PAGE_SHIFT; |
bd4c625c0 reiserfs: run scr... |
2112 2113 |
unsigned long pos = 0; unsigned long start = 0; |
995c762ea reiserfs: rename ... |
2114 |
unsigned long blocksize = inode->i_sb->s_blocksize; |
09cbfeaf1 mm, fs: get rid o... |
2115 |
unsigned long offset = (inode->i_size) & (PAGE_SIZE - 1); |
bd4c625c0 reiserfs: run scr... |
2116 2117 2118 2119 |
struct buffer_head *bh; struct buffer_head *head; struct page *page; int error; |
098297b27 reiserfs: cleanup... |
2120 2121 2122 2123 2124 |
/* * we know that we are only called with inode->i_size > 0. * we also know that a file tail can never be as big as a block * If i_size % blocksize == 0, our file is currently block aligned * and it won't need converting or zeroing after a truncate. |
bd4c625c0 reiserfs: run scr... |
2125 2126 2127 2128 |
*/ if ((offset & (blocksize - 1)) == 0) { return -ENOENT; } |
995c762ea reiserfs: rename ... |
2129 |
page = grab_cache_page(inode->i_mapping, index); |
bd4c625c0 reiserfs: run scr... |
2130 2131 2132 2133 2134 2135 |
error = -ENOMEM; if (!page) { goto out; } /* start within the page of the last block in the file */ start = (offset / blocksize) * blocksize; |
ebdec241d fs: kill block_pr... |
2136 |
error = __block_write_begin(page, start, offset - start, |
bd4c625c0 reiserfs: run scr... |
2137 2138 2139 2140 2141 2142 2143 2144 2145 2146 2147 2148 2149 2150 2151 |
reiserfs_get_block_create_0); if (error) goto unlock; head = page_buffers(page); bh = head; do { if (pos >= start) { break; } bh = bh->b_this_page; pos += blocksize; } while (bh != head); if (!buffer_uptodate(bh)) { |
098297b27 reiserfs: cleanup... |
2152 2153 2154 2155 2156 |
/* * note, this should never happen, prepare_write should be * taking care of this for us. If the buffer isn't up to * date, I've screwed up the code to find the buffer, or the * code to call prepare_write |
bd4c625c0 reiserfs: run scr... |
2157 |
*/ |
995c762ea reiserfs: rename ... |
2158 |
reiserfs_error(inode->i_sb, "clm-6000", |
0030b6457 reiserfs: use rei... |
2159 |
"error reading block %lu", bh->b_blocknr); |
bd4c625c0 reiserfs: run scr... |
2160 2161 2162 2163 2164 |
error = -EIO; goto unlock; } *bh_result = bh; *page_result = page; |
cf776a7a4 reiserfs: cleanup... |
2165 |
out: |
bd4c625c0 reiserfs: run scr... |
2166 |
return error; |
cf776a7a4 reiserfs: cleanup... |
2167 |
unlock: |
bd4c625c0 reiserfs: run scr... |
2168 |
unlock_page(page); |
09cbfeaf1 mm, fs: get rid o... |
2169 |
put_page(page); |
bd4c625c0 reiserfs: run scr... |
2170 |
return error; |
1da177e4c Linux-2.6.12-rc2 |
2171 2172 2173 |
} /* |
098297b27 reiserfs: cleanup... |
2174 2175 2176 2177 2178 |
* vfs version of truncate file. Must NOT be called with * a transaction already started. * * some code taken from block_truncate_page */ |
995c762ea reiserfs: rename ... |
2179 |
int reiserfs_truncate_file(struct inode *inode, int update_timestamps) |
bd4c625c0 reiserfs: run scr... |
2180 2181 2182 |
{ struct reiserfs_transaction_handle th; /* we want the offset for the first byte after the end of the file */ |
09cbfeaf1 mm, fs: get rid o... |
2183 |
unsigned long offset = inode->i_size & (PAGE_SIZE - 1); |
995c762ea reiserfs: rename ... |
2184 |
unsigned blocksize = inode->i_sb->s_blocksize; |
bd4c625c0 reiserfs: run scr... |
2185 2186 2187 2188 |
unsigned length; struct page *page = NULL; int error; struct buffer_head *bh = NULL; |
249960496 [PATCH] reiserfs:... |
2189 |
int err2; |
bd4c625c0 reiserfs: run scr... |
2190 |
|
278f6679f reiserfs: locking... |
2191 |
reiserfs_write_lock(inode->i_sb); |
bd4c625c0 reiserfs: run scr... |
2192 |
|
995c762ea reiserfs: rename ... |
2193 2194 2195 |
if (inode->i_size > 0) { error = grab_tail_page(inode, &page, &bh); if (error) { |
098297b27 reiserfs: cleanup... |
2196 2197 2198 2199 2200 |
/* * -ENOENT means we truncated past the end of the * file, and get_block_create_0 could not find a * block to read in, which is ok. */ |
bd4c625c0 reiserfs: run scr... |
2201 |
if (error != -ENOENT) |
995c762ea reiserfs: rename ... |
2202 |
reiserfs_error(inode->i_sb, "clm-6001", |
0030b6457 reiserfs: use rei... |
2203 2204 |
"grab_tail_page failed %d", error); |
bd4c625c0 reiserfs: run scr... |
2205 2206 2207 2208 |
page = NULL; bh = NULL; } } |
1da177e4c Linux-2.6.12-rc2 |
2209 |
|
098297b27 reiserfs: cleanup... |
2210 2211 2212 2213 2214 2215 2216 2217 2218 2219 2220 |
/* * so, if page != NULL, we have a buffer head for the offset at * the end of the file. if the bh is mapped, and bh->b_blocknr != 0, * then we have an unformatted node. Otherwise, we have a direct item, * and no zeroing is required on disk. We zero after the truncate, * because the truncate might pack the item anyway * (it will unmap bh if it packs). * * it is enough to reserve space in transaction for 2 balancings: * one for "save" link adding and another for the first * cut_from_item. 1 is for update_sd |
1da177e4c Linux-2.6.12-rc2 |
2221 |
*/ |
995c762ea reiserfs: rename ... |
2222 |
error = journal_begin(&th, inode->i_sb, |
bd4c625c0 reiserfs: run scr... |
2223 2224 2225 |
JOURNAL_PER_BALANCE_CNT * 2 + 1); if (error) goto out; |
995c762ea reiserfs: rename ... |
2226 |
reiserfs_update_inode_transaction(inode); |
bd4c625c0 reiserfs: run scr... |
2227 |
if (update_timestamps) |
098297b27 reiserfs: cleanup... |
2228 2229 2230 2231 2232 2233 |
/* * we are doing real truncate: if the system crashes * before the last transaction of truncating gets committed * - on reboot the file either appears truncated properly * or not truncated at all */ |
995c762ea reiserfs: rename ... |
2234 2235 |
add_save_link(&th, inode, 1); err2 = reiserfs_do_truncate(&th, inode, page, update_timestamps); |
58d854265 reiserfs: cleanup... |
2236 |
error = journal_end(&th); |
bd4c625c0 reiserfs: run scr... |
2237 2238 |
if (error) goto out; |
249960496 [PATCH] reiserfs:... |
2239 2240 2241 2242 2243 2244 |
/* check reiserfs_do_truncate after ending the transaction */ if (err2) { error = err2; goto out; } |
bd4c625c0 reiserfs: run scr... |
2245 |
if (update_timestamps) { |
995c762ea reiserfs: rename ... |
2246 |
error = remove_save_link(inode, 1 /* truncate */); |
bd4c625c0 reiserfs: run scr... |
2247 2248 2249 2250 2251 2252 2253 2254 |
if (error) goto out; } if (page) { length = offset & (blocksize - 1); /* if we are not on a block boundary */ if (length) { |
bd4c625c0 reiserfs: run scr... |
2255 |
length = blocksize - length; |
eebd2aa35 Pagecache zeroing... |
2256 |
zero_user(page, offset, length); |
bd4c625c0 reiserfs: run scr... |
2257 2258 2259 2260 2261 |
if (buffer_mapped(bh) && bh->b_blocknr != 0) { mark_buffer_dirty(bh); } } unlock_page(page); |
09cbfeaf1 mm, fs: get rid o... |
2262 |
put_page(page); |
bd4c625c0 reiserfs: run scr... |
2263 |
} |
278f6679f reiserfs: locking... |
2264 |
reiserfs_write_unlock(inode->i_sb); |
22c963add kill-the-BKL/reis... |
2265 |
|
bd4c625c0 reiserfs: run scr... |
2266 |
return 0; |
cf776a7a4 reiserfs: cleanup... |
2267 |
out: |
bd4c625c0 reiserfs: run scr... |
2268 2269 |
if (page) { unlock_page(page); |
09cbfeaf1 mm, fs: get rid o... |
2270 |
put_page(page); |
bd4c625c0 reiserfs: run scr... |
2271 |
} |
22c963add kill-the-BKL/reis... |
2272 |
|
278f6679f reiserfs: locking... |
2273 |
reiserfs_write_unlock(inode->i_sb); |
22c963add kill-the-BKL/reis... |
2274 |
|
bd4c625c0 reiserfs: run scr... |
2275 2276 2277 2278 2279 2280 2281 2282 2283 2284 2285 2286 2287 2288 2289 2290 2291 |
return error; } static int map_block_for_writepage(struct inode *inode, struct buffer_head *bh_result, unsigned long block) { struct reiserfs_transaction_handle th; int fs_gen; struct item_head tmp_ih; struct item_head *ih; struct buffer_head *bh; __le32 *item; struct cpu_key key; INITIALIZE_PATH(path); int pos_in_item; int jbegin_count = JOURNAL_PER_BALANCE_CNT; |
7729ac5ef [PATCH] reiserfs:... |
2292 |
loff_t byte_offset = ((loff_t)block << inode->i_sb->s_blocksize_bits)+1; |
bd4c625c0 reiserfs: run scr... |
2293 2294 2295 2296 2297 |
int retval; int use_get_block = 0; int bytes_copied = 0; int copy_size; int trans_running = 0; |
098297b27 reiserfs: cleanup... |
2298 2299 2300 2301 |
/* * catch places below that try to log something without * starting a trans */ |
bd4c625c0 reiserfs: run scr... |
2302 2303 2304 2305 2306 2307 2308 |
th.t_trans_id = 0; if (!buffer_uptodate(bh_result)) { return -EIO; } kmap(bh_result->b_page); |
cf776a7a4 reiserfs: cleanup... |
2309 |
start_over: |
bd4c625c0 reiserfs: run scr... |
2310 2311 |
reiserfs_write_lock(inode->i_sb); make_cpu_key(&key, inode, byte_offset, TYPE_ANY, 3); |
cf776a7a4 reiserfs: cleanup... |
2312 |
research: |
bd4c625c0 reiserfs: run scr... |
2313 2314 2315 2316 2317 2318 2319 |
retval = search_for_position_by_key(inode->i_sb, &key, &path); if (retval != POSITION_FOUND) { use_get_block = 1; goto out; } bh = get_last_bh(&path); |
4cf5f7add reiserfs: cleanup... |
2320 2321 |
ih = tp_item_head(&path); item = tp_item_body(&path); |
bd4c625c0 reiserfs: run scr... |
2322 2323 2324 2325 2326 |
pos_in_item = path.pos_in_item; /* we've found an unformatted node */ if (indirect_item_found(retval, ih)) { if (bytes_copied > 0) { |
45b03d5e8 reiserfs: rework ... |
2327 2328 |
reiserfs_warning(inode->i_sb, "clm-6002", "bytes_copied %d", bytes_copied); |
bd4c625c0 reiserfs: run scr... |
2329 2330 2331 2332 2333 2334 2335 2336 2337 2338 2339 |
} if (!get_block_num(item, pos_in_item)) { /* crap, we are writing to a hole */ use_get_block = 1; goto out; } set_block_dev_mapped(bh_result, get_block_num(item, pos_in_item), inode); } else if (is_direct_le_ih(ih)) { char *p; p = page_address(bh_result->b_page); |
09cbfeaf1 mm, fs: get rid o... |
2340 |
p += (byte_offset - 1) & (PAGE_SIZE - 1); |
bd4c625c0 reiserfs: run scr... |
2341 2342 2343 2344 2345 2346 2347 2348 2349 2350 2351 2352 2353 2354 2355 2356 2357 2358 2359 2360 2361 2362 2363 2364 2365 2366 2367 |
copy_size = ih_item_len(ih) - pos_in_item; fs_gen = get_generation(inode->i_sb); copy_item_head(&tmp_ih, ih); if (!trans_running) { /* vs-3050 is gone, no need to drop the path */ retval = journal_begin(&th, inode->i_sb, jbegin_count); if (retval) goto out; reiserfs_update_inode_transaction(inode); trans_running = 1; if (fs_changed(fs_gen, inode->i_sb) && item_moved(&tmp_ih, &path)) { reiserfs_restore_prepared_buffer(inode->i_sb, bh); goto research; } } reiserfs_prepare_for_journal(inode->i_sb, bh, 1); if (fs_changed(fs_gen, inode->i_sb) && item_moved(&tmp_ih, &path)) { reiserfs_restore_prepared_buffer(inode->i_sb, bh); goto research; } |
4cf5f7add reiserfs: cleanup... |
2368 |
memcpy(ih_item_body(bh, ih) + pos_in_item, p + bytes_copied, |
bd4c625c0 reiserfs: run scr... |
2369 |
copy_size); |
09f1b80ba reiserfs: cleanup... |
2370 |
journal_mark_dirty(&th, bh); |
bd4c625c0 reiserfs: run scr... |
2371 2372 2373 2374 2375 2376 2377 2378 2379 2380 2381 2382 |
bytes_copied += copy_size; set_block_dev_mapped(bh_result, 0, inode); /* are there still bytes left? */ if (bytes_copied < bh_result->b_size && (byte_offset + bytes_copied) < inode->i_size) { set_cpu_key_k_offset(&key, cpu_key_k_offset(&key) + copy_size); goto research; } } else { |
45b03d5e8 reiserfs: rework ... |
2383 2384 |
reiserfs_warning(inode->i_sb, "clm-6003", "bad item inode %lu", inode->i_ino); |
bd4c625c0 reiserfs: run scr... |
2385 2386 2387 2388 |
retval = -EIO; goto out; } retval = 0; |
cf776a7a4 reiserfs: cleanup... |
2389 |
out: |
bd4c625c0 reiserfs: run scr... |
2390 2391 |
pathrelse(&path); if (trans_running) { |
58d854265 reiserfs: cleanup... |
2392 |
int err = journal_end(&th); |
bd4c625c0 reiserfs: run scr... |
2393 2394 2395 2396 2397 2398 2399 2400 2401 |
if (err) retval = err; trans_running = 0; } reiserfs_write_unlock(inode->i_sb); /* this is where we fill in holes in the file. */ if (use_get_block) { retval = reiserfs_get_block(inode, block, bh_result, |
1b1dcc1b5 [PATCH] mutex sub... |
2402 |
GET_BLOCK_CREATE | GET_BLOCK_NO_IMUX |
bd4c625c0 reiserfs: run scr... |
2403 2404 2405 2406 2407 2408 2409 2410 2411 2412 2413 2414 2415 |
| GET_BLOCK_NO_DANGLE); if (!retval) { if (!buffer_mapped(bh_result) || bh_result->b_blocknr == 0) { /* get_block failed to find a mapped unformatted node. */ use_get_block = 0; goto start_over; } } } kunmap(bh_result->b_page); if (!retval && buffer_mapped(bh_result) && bh_result->b_blocknr == 0) { |
098297b27 reiserfs: cleanup... |
2416 2417 |
/* * we've copied data from the page into the direct item, so the |
bd4c625c0 reiserfs: run scr... |
2418 2419 2420 2421 2422 2423 2424 |
* buffer in the page is now clean, mark it to reflect that. */ lock_buffer(bh_result); clear_buffer_dirty(bh_result); unlock_buffer(bh_result); } return retval; |
1da177e4c Linux-2.6.12-rc2 |
2425 |
} |
0222e6571 reiserfs: strip t... |
2426 2427 |
/* * mason@suse.com: updated in 2.5.54 to follow the same general io |
1da177e4c Linux-2.6.12-rc2 |
2428 2429 2430 |
* start/recovery path as __block_write_full_page, along with special * code to handle reiserfs tails. */ |
bd4c625c0 reiserfs: run scr... |
2431 2432 2433 2434 |
static int reiserfs_write_full_page(struct page *page, struct writeback_control *wbc) { struct inode *inode = page->mapping->host; |
09cbfeaf1 mm, fs: get rid o... |
2435 |
unsigned long end_index = inode->i_size >> PAGE_SHIFT; |
bd4c625c0 reiserfs: run scr... |
2436 2437 |
int error = 0; unsigned long block; |
b4c76fa72 [PATCH] reiserfs_... |
2438 |
sector_t last_block; |
bd4c625c0 reiserfs: run scr... |
2439 2440 2441 2442 2443 2444 |
struct buffer_head *head, *bh; int partial = 0; int nr = 0; int checked = PageChecked(page); struct reiserfs_transaction_handle th; struct super_block *s = inode->i_sb; |
09cbfeaf1 mm, fs: get rid o... |
2445 |
int bh_per_page = PAGE_SIZE / s->s_blocksize; |
bd4c625c0 reiserfs: run scr... |
2446 |
th.t_trans_id = 0; |
e0e851cf3 [PATCH] reiserfs:... |
2447 2448 2449 2450 2451 2452 |
/* no logging allowed when nonblocking or from PF_MEMALLOC */ if (checked && (current->flags & PF_MEMALLOC)) { redirty_page_for_writepage(wbc, page); unlock_page(page); return 0; } |
098297b27 reiserfs: cleanup... |
2453 2454 |
/* * The page dirty bit is cleared before writepage is called, which |
bd4c625c0 reiserfs: run scr... |
2455 2456 2457 2458 2459 2460 2461 2462 2463 |
* means we have to tell create_empty_buffers to make dirty buffers * The page really should be up to date at this point, so tossing * in the BH_Uptodate is just a sanity check. */ if (!page_has_buffers(page)) { create_empty_buffers(page, s->s_blocksize, (1 << BH_Dirty) | (1 << BH_Uptodate)); } head = page_buffers(page); |
1da177e4c Linux-2.6.12-rc2 |
2464 |
|
098297b27 reiserfs: cleanup... |
2465 2466 2467 |
/* * last page in the file, zero out any contents past the * last byte in the file |
bd4c625c0 reiserfs: run scr... |
2468 2469 |
*/ if (page->index >= end_index) { |
bd4c625c0 reiserfs: run scr... |
2470 |
unsigned last_offset; |
09cbfeaf1 mm, fs: get rid o... |
2471 |
last_offset = inode->i_size & (PAGE_SIZE - 1); |
bd4c625c0 reiserfs: run scr... |
2472 2473 2474 2475 2476 |
/* no file contents in this page */ if (page->index >= end_index + 1 || !last_offset) { unlock_page(page); return 0; } |
09cbfeaf1 mm, fs: get rid o... |
2477 |
zero_user_segment(page, last_offset, PAGE_SIZE); |
1da177e4c Linux-2.6.12-rc2 |
2478 |
} |
bd4c625c0 reiserfs: run scr... |
2479 |
bh = head; |
09cbfeaf1 mm, fs: get rid o... |
2480 |
block = page->index << (PAGE_SHIFT - s->s_blocksize_bits); |
b4c76fa72 [PATCH] reiserfs_... |
2481 |
last_block = (i_size_read(inode) - 1) >> inode->i_blkbits; |
bd4c625c0 reiserfs: run scr... |
2482 2483 |
/* first map all the buffers, logging any direct items we find */ do { |
b4c76fa72 [PATCH] reiserfs_... |
2484 2485 2486 2487 2488 2489 2490 2491 2492 2493 |
if (block > last_block) { /* * This can happen when the block size is less than * the page size. The corresponding bytes in the page * were zero filled above */ clear_buffer_dirty(bh); set_buffer_uptodate(bh); } else if ((checked || buffer_dirty(bh)) && (!buffer_mapped(bh) || (buffer_mapped(bh) |
bd4c625c0 reiserfs: run scr... |
2494 2495 |
&& bh->b_blocknr == 0))) { |
098297b27 reiserfs: cleanup... |
2496 2497 |
/* * not mapped yet, or it points to a direct item, search |
bd4c625c0 reiserfs: run scr... |
2498 2499 2500 2501 2502 2503 2504 2505 2506 2507 2508 2509 2510 2511 2512 2513 |
* the btree for the mapping info, and log any direct * items found */ if ((error = map_block_for_writepage(inode, bh, block))) { goto fail; } } bh = bh->b_this_page; block++; } while (bh != head); /* * we start the transaction after map_block_for_writepage, * because it can create holes in the file (an unbounded operation). * starting it here, we can make a reliable estimate for how many * blocks we're going to log |
1da177e4c Linux-2.6.12-rc2 |
2514 |
*/ |
bd4c625c0 reiserfs: run scr... |
2515 2516 2517 2518 2519 2520 2521 2522 2523 |
if (checked) { ClearPageChecked(page); reiserfs_write_lock(s); error = journal_begin(&th, s, bh_per_page + 1); if (error) { reiserfs_write_unlock(s); goto fail; } reiserfs_update_inode_transaction(inode); |
1da177e4c Linux-2.6.12-rc2 |
2524 |
} |
bd4c625c0 reiserfs: run scr... |
2525 2526 2527 2528 2529 2530 2531 2532 2533 2534 |
/* now go through and lock any dirty buffers on the page */ do { get_bh(bh); if (!buffer_mapped(bh)) continue; if (buffer_mapped(bh) && bh->b_blocknr == 0) continue; if (checked) { reiserfs_prepare_for_journal(s, bh, 1); |
09f1b80ba reiserfs: cleanup... |
2535 |
journal_mark_dirty(&th, bh); |
bd4c625c0 reiserfs: run scr... |
2536 2537 |
continue; } |
098297b27 reiserfs: cleanup... |
2538 2539 |
/* * from this point on, we know the buffer is mapped to a |
bd4c625c0 reiserfs: run scr... |
2540 2541 |
* real block and not a direct item */ |
1b430beee writeback: remove... |
2542 |
if (wbc->sync_mode != WB_SYNC_NONE) { |
bd4c625c0 reiserfs: run scr... |
2543 2544 |
lock_buffer(bh); } else { |
ca5de404f fs: rename buffer... |
2545 |
if (!trylock_buffer(bh)) { |
bd4c625c0 reiserfs: run scr... |
2546 2547 2548 2549 2550 2551 2552 2553 2554 2555 2556 2557 |
redirty_page_for_writepage(wbc, page); continue; } } if (test_clear_buffer_dirty(bh)) { mark_buffer_async_write(bh); } else { unlock_buffer(bh); } } while ((bh = bh->b_this_page) != head); if (checked) { |
58d854265 reiserfs: cleanup... |
2558 |
error = journal_end(&th); |
bd4c625c0 reiserfs: run scr... |
2559 2560 2561 |
reiserfs_write_unlock(s); if (error) goto fail; |
1da177e4c Linux-2.6.12-rc2 |
2562 |
} |
bd4c625c0 reiserfs: run scr... |
2563 2564 2565 |
BUG_ON(PageWriteback(page)); set_page_writeback(page); unlock_page(page); |
1da177e4c Linux-2.6.12-rc2 |
2566 |
|
bd4c625c0 reiserfs: run scr... |
2567 |
/* |
0222e6571 reiserfs: strip t... |
2568 |
* since any buffer might be the only dirty buffer on the page, |
bd4c625c0 reiserfs: run scr... |
2569 2570 |
* the first submit_bh can bring the page out of writeback. * be careful with the buffers. |
1da177e4c Linux-2.6.12-rc2 |
2571 |
*/ |
1da177e4c Linux-2.6.12-rc2 |
2572 |
do { |
bd4c625c0 reiserfs: run scr... |
2573 2574 |
struct buffer_head *next = bh->b_this_page; if (buffer_async_write(bh)) { |
2a222ca99 fs: have submit_b... |
2575 |
submit_bh(REQ_OP_WRITE, 0, bh); |
bd4c625c0 reiserfs: run scr... |
2576 2577 2578 2579 2580 |
nr++; } put_bh(bh); bh = next; } while (bh != head); |
1da177e4c Linux-2.6.12-rc2 |
2581 |
|
bd4c625c0 reiserfs: run scr... |
2582 |
error = 0; |
cf776a7a4 reiserfs: cleanup... |
2583 |
done: |
bd4c625c0 reiserfs: run scr... |
2584 2585 2586 |
if (nr == 0) { /* * if this page only had a direct item, it is very possible for |
0222e6571 reiserfs: strip t... |
2587 2588 |
* no io to be required without there being an error. Or, * someone else could have locked them and sent them down the |
bd4c625c0 reiserfs: run scr... |
2589 2590 2591 2592 2593 2594 2595 2596 2597 2598 2599 2600 2601 2602 2603 |
* pipe without locking the page */ bh = head; do { if (!buffer_uptodate(bh)) { partial = 1; break; } bh = bh->b_this_page; } while (bh != head); if (!partial) SetPageUptodate(page); end_page_writeback(page); } return error; |
1da177e4c Linux-2.6.12-rc2 |
2604 |
|
cf776a7a4 reiserfs: cleanup... |
2605 |
fail: |
098297b27 reiserfs: cleanup... |
2606 2607 |
/* * catches various errors, we need to make sure any valid dirty blocks |
0222e6571 reiserfs: strip t... |
2608 |
* get to the media. The page is currently locked and not marked for |
bd4c625c0 reiserfs: run scr... |
2609 2610 2611 2612 2613 2614 2615 2616 2617 2618 2619 |
* writeback */ ClearPageUptodate(page); bh = head; do { get_bh(bh); if (buffer_mapped(bh) && buffer_dirty(bh) && bh->b_blocknr) { lock_buffer(bh); mark_buffer_async_write(bh); } else { /* |
098297b27 reiserfs: cleanup... |
2620 2621 |
* clear any dirty bits that might have come from * getting attached to a dirty page |
bd4c625c0 reiserfs: run scr... |
2622 2623 2624 2625 2626 2627 2628 2629 2630 2631 2632 2633 2634 |
*/ clear_buffer_dirty(bh); } bh = bh->b_this_page; } while (bh != head); SetPageError(page); BUG_ON(PageWriteback(page)); set_page_writeback(page); unlock_page(page); do { struct buffer_head *next = bh->b_this_page; if (buffer_async_write(bh)) { clear_buffer_dirty(bh); |
2a222ca99 fs: have submit_b... |
2635 |
submit_bh(REQ_OP_WRITE, 0, bh); |
bd4c625c0 reiserfs: run scr... |
2636 2637 2638 2639 2640 2641 |
nr++; } put_bh(bh); bh = next; } while (bh != head); goto done; |
1da177e4c Linux-2.6.12-rc2 |
2642 |
} |
bd4c625c0 reiserfs: run scr... |
2643 2644 2645 2646 |
static int reiserfs_readpage(struct file *f, struct page *page) { return block_read_full_page(page, reiserfs_get_block); } |
1da177e4c Linux-2.6.12-rc2 |
2647 |
|
bd4c625c0 reiserfs: run scr... |
2648 |
static int reiserfs_writepage(struct page *page, struct writeback_control *wbc) |
1da177e4c Linux-2.6.12-rc2 |
2649 |
{ |
bd4c625c0 reiserfs: run scr... |
2650 2651 2652 |
struct inode *inode = page->mapping->host; reiserfs_wait_on_write_block(inode->i_sb); return reiserfs_write_full_page(page, wbc); |
1da177e4c Linux-2.6.12-rc2 |
2653 |
} |
ec8e2f746 reiserfs: truncat... |
2654 2655 2656 2657 2658 |
static void reiserfs_truncate_failed_write(struct inode *inode) { truncate_inode_pages(inode->i_mapping, inode->i_size); reiserfs_truncate_file(inode, 0); } |
ba9d8cec6 reiserfs: convert... |
2659 2660 2661 2662 2663 2664 2665 2666 2667 2668 |
static int reiserfs_write_begin(struct file *file, struct address_space *mapping, loff_t pos, unsigned len, unsigned flags, struct page **pagep, void **fsdata) { struct inode *inode; struct page *page; pgoff_t index; int ret; int old_ref = 0; |
f7557e8f7 reiserfs: use gen... |
2669 |
inode = mapping->host; |
714b71a3a fs/reiserfs/inode... |
2670 |
*fsdata = NULL; |
f7557e8f7 reiserfs: use gen... |
2671 2672 2673 2674 2675 |
if (flags & AOP_FLAG_CONT_EXPAND && (pos & (inode->i_sb->s_blocksize - 1)) == 0) { pos ++; *fsdata = (void *)(unsigned long)flags; } |
09cbfeaf1 mm, fs: get rid o... |
2676 |
index = pos >> PAGE_SHIFT; |
54566b2c1 fs: symlink write... |
2677 |
page = grab_cache_page_write_begin(mapping, index, flags); |
ba9d8cec6 reiserfs: convert... |
2678 2679 2680 |
if (!page) return -ENOMEM; *pagep = page; |
ba9d8cec6 reiserfs: convert... |
2681 2682 2683 2684 2685 2686 2687 2688 2689 2690 2691 |
reiserfs_wait_on_write_block(inode->i_sb); fix_tail_page_for_writing(page); if (reiserfs_transaction_running(inode->i_sb)) { struct reiserfs_transaction_handle *th; th = (struct reiserfs_transaction_handle *)current-> journal_info; BUG_ON(!th->t_refcount); BUG_ON(!th->t_trans_id); old_ref = th->t_refcount; th->t_refcount++; } |
6e1db88d5 introduce __block... |
2692 |
ret = __block_write_begin(page, pos, len, reiserfs_get_block); |
ba9d8cec6 reiserfs: convert... |
2693 2694 |
if (ret && reiserfs_transaction_running(inode->i_sb)) { struct reiserfs_transaction_handle *th = current->journal_info; |
098297b27 reiserfs: cleanup... |
2695 2696 2697 2698 2699 |
/* * this gets a little ugly. If reiserfs_get_block returned an * error and left a transacstion running, we've got to close * it, and we've got to free handle if it was a persistent * transaction. |
ba9d8cec6 reiserfs: convert... |
2700 2701 2702 2703 2704 |
* * But, if we had nested into an existing transaction, we need * to just drop the ref count on the handle. * * If old_ref == 0, the transaction is from reiserfs_get_block, |
098297b27 reiserfs: cleanup... |
2705 2706 |
* and it was a persistent trans. Otherwise, it was nested * above. |
ba9d8cec6 reiserfs: convert... |
2707 2708 2709 2710 2711 2712 2713 2714 2715 2716 2717 2718 2719 2720 2721 2722 |
*/ if (th->t_refcount > old_ref) { if (old_ref) th->t_refcount--; else { int err; reiserfs_write_lock(inode->i_sb); err = reiserfs_end_persistent_transaction(th); reiserfs_write_unlock(inode->i_sb); if (err) ret = err; } } } if (ret) { unlock_page(page); |
09cbfeaf1 mm, fs: get rid o... |
2723 |
put_page(page); |
ec8e2f746 reiserfs: truncat... |
2724 2725 |
/* Truncate allocated blocks */ reiserfs_truncate_failed_write(inode); |
ba9d8cec6 reiserfs: convert... |
2726 2727 2728 |
} return ret; } |
ebdec241d fs: kill block_pr... |
2729 |
int __reiserfs_write_begin(struct page *page, unsigned from, unsigned len) |
bd4c625c0 reiserfs: run scr... |
2730 2731 2732 2733 |
{ struct inode *inode = page->mapping->host; int ret; int old_ref = 0; |
278f6679f reiserfs: locking... |
2734 |
int depth; |
bd4c625c0 reiserfs: run scr... |
2735 |
|
278f6679f reiserfs: locking... |
2736 |
depth = reiserfs_write_unlock_nested(inode->i_sb); |
bd4c625c0 reiserfs: run scr... |
2737 |
reiserfs_wait_on_write_block(inode->i_sb); |
278f6679f reiserfs: locking... |
2738 |
reiserfs_write_lock_nested(inode->i_sb, depth); |
8ebc42323 reiserfs: kill-th... |
2739 |
|
bd4c625c0 reiserfs: run scr... |
2740 2741 2742 2743 2744 2745 2746 2747 2748 |
fix_tail_page_for_writing(page); if (reiserfs_transaction_running(inode->i_sb)) { struct reiserfs_transaction_handle *th; th = (struct reiserfs_transaction_handle *)current-> journal_info; BUG_ON(!th->t_refcount); BUG_ON(!th->t_trans_id); old_ref = th->t_refcount; th->t_refcount++; |
1da177e4c Linux-2.6.12-rc2 |
2749 |
} |
1da177e4c Linux-2.6.12-rc2 |
2750 |
|
ebdec241d fs: kill block_pr... |
2751 |
ret = __block_write_begin(page, from, len, reiserfs_get_block); |
bd4c625c0 reiserfs: run scr... |
2752 2753 |
if (ret && reiserfs_transaction_running(inode->i_sb)) { struct reiserfs_transaction_handle *th = current->journal_info; |
098297b27 reiserfs: cleanup... |
2754 2755 2756 2757 2758 |
/* * this gets a little ugly. If reiserfs_get_block returned an * error and left a transacstion running, we've got to close * it, and we've got to free handle if it was a persistent * transaction. |
bd4c625c0 reiserfs: run scr... |
2759 2760 2761 2762 2763 |
* * But, if we had nested into an existing transaction, we need * to just drop the ref count on the handle. * * If old_ref == 0, the transaction is from reiserfs_get_block, |
098297b27 reiserfs: cleanup... |
2764 2765 |
* and it was a persistent trans. Otherwise, it was nested * above. |
bd4c625c0 reiserfs: run scr... |
2766 2767 2768 2769 2770 2771 2772 2773 2774 2775 2776 2777 2778 2779 2780 |
*/ if (th->t_refcount > old_ref) { if (old_ref) th->t_refcount--; else { int err; reiserfs_write_lock(inode->i_sb); err = reiserfs_end_persistent_transaction(th); reiserfs_write_unlock(inode->i_sb); if (err) ret = err; } } } return ret; |
1da177e4c Linux-2.6.12-rc2 |
2781 |
|
bd4c625c0 reiserfs: run scr... |
2782 |
} |
1da177e4c Linux-2.6.12-rc2 |
2783 |
|
bd4c625c0 reiserfs: run scr... |
2784 2785 2786 |
static sector_t reiserfs_aop_bmap(struct address_space *as, sector_t block) { return generic_block_bmap(as, block, reiserfs_bmap); |
1da177e4c Linux-2.6.12-rc2 |
2787 |
} |
ba9d8cec6 reiserfs: convert... |
2788 2789 2790 2791 2792 2793 2794 2795 2796 |
static int reiserfs_write_end(struct file *file, struct address_space *mapping, loff_t pos, unsigned len, unsigned copied, struct page *page, void *fsdata) { struct inode *inode = page->mapping->host; int ret = 0; int update_sd = 0; struct reiserfs_transaction_handle *th; unsigned start; |
d6f5b0aa0 kill-the-bkl/reis... |
2797 |
bool locked = false; |
ba9d8cec6 reiserfs: convert... |
2798 |
|
f7557e8f7 reiserfs: use gen... |
2799 2800 |
if ((unsigned long)fsdata & AOP_FLAG_CONT_EXPAND) pos ++; |
ba9d8cec6 reiserfs: convert... |
2801 2802 2803 2804 2805 2806 |
reiserfs_wait_on_write_block(inode->i_sb); if (reiserfs_transaction_running(inode->i_sb)) th = current->journal_info; else th = NULL; |
09cbfeaf1 mm, fs: get rid o... |
2807 |
start = pos & (PAGE_SIZE - 1); |
ba9d8cec6 reiserfs: convert... |
2808 2809 2810 2811 2812 2813 2814 2815 2816 |
if (unlikely(copied < len)) { if (!PageUptodate(page)) copied = 0; page_zero_new_buffers(page, start + copied, start + len); } flush_dcache_page(page); reiserfs_commit_page(inode, page, start, start + copied); |
098297b27 reiserfs: cleanup... |
2817 2818 2819 2820 |
/* * generic_commit_write does this for us, but does not update the * transaction tracking stuff when the size changes. So, we have * to do the i_size updates here. |
ba9d8cec6 reiserfs: convert... |
2821 |
*/ |
ec8e2f746 reiserfs: truncat... |
2822 |
if (pos + copied > inode->i_size) { |
ba9d8cec6 reiserfs: convert... |
2823 |
struct reiserfs_transaction_handle myth; |
278f6679f reiserfs: locking... |
2824 |
reiserfs_write_lock(inode->i_sb); |
d6f5b0aa0 kill-the-bkl/reis... |
2825 |
locked = true; |
098297b27 reiserfs: cleanup... |
2826 2827 2828 2829 2830 |
/* * If the file have grown beyond the border where it * can have a tail, unmark it as needing a tail * packing */ |
ba9d8cec6 reiserfs: convert... |
2831 2832 2833 2834 2835 2836 2837 |
if ((have_large_tails(inode->i_sb) && inode->i_size > i_block_size(inode) * 4) || (have_small_tails(inode->i_sb) && inode->i_size > i_block_size(inode))) REISERFS_I(inode)->i_flags &= ~i_pack_on_close_mask; ret = journal_begin(&myth, inode->i_sb, 1); |
d6f5b0aa0 kill-the-bkl/reis... |
2838 |
if (ret) |
ba9d8cec6 reiserfs: convert... |
2839 |
goto journal_error; |
d6f5b0aa0 kill-the-bkl/reis... |
2840 |
|
ba9d8cec6 reiserfs: convert... |
2841 |
reiserfs_update_inode_transaction(inode); |
ec8e2f746 reiserfs: truncat... |
2842 |
inode->i_size = pos + copied; |
ba9d8cec6 reiserfs: convert... |
2843 2844 |
/* * this will just nest into our transaction. It's important |
098297b27 reiserfs: cleanup... |
2845 2846 |
* to use mark_inode_dirty so the inode gets pushed around on * the dirty lists, and so that O_SYNC works as expected |
ba9d8cec6 reiserfs: convert... |
2847 2848 2849 2850 |
*/ mark_inode_dirty(inode); reiserfs_update_sd(&myth, inode); update_sd = 1; |
58d854265 reiserfs: cleanup... |
2851 |
ret = journal_end(&myth); |
ba9d8cec6 reiserfs: convert... |
2852 2853 2854 2855 |
if (ret) goto journal_error; } if (th) { |
d6f5b0aa0 kill-the-bkl/reis... |
2856 |
if (!locked) { |
278f6679f reiserfs: locking... |
2857 |
reiserfs_write_lock(inode->i_sb); |
d6f5b0aa0 kill-the-bkl/reis... |
2858 2859 |
locked = true; } |
ba9d8cec6 reiserfs: convert... |
2860 2861 2862 |
if (!update_sd) mark_inode_dirty(inode); ret = reiserfs_end_persistent_transaction(th); |
ba9d8cec6 reiserfs: convert... |
2863 2864 2865 |
if (ret) goto out; } |
cf776a7a4 reiserfs: cleanup... |
2866 |
out: |
d6f5b0aa0 kill-the-bkl/reis... |
2867 |
if (locked) |
278f6679f reiserfs: locking... |
2868 |
reiserfs_write_unlock(inode->i_sb); |
ba9d8cec6 reiserfs: convert... |
2869 |
unlock_page(page); |
09cbfeaf1 mm, fs: get rid o... |
2870 |
put_page(page); |
ec8e2f746 reiserfs: truncat... |
2871 2872 2873 |
if (pos + len > inode->i_size) reiserfs_truncate_failed_write(inode); |
ba9d8cec6 reiserfs: convert... |
2874 |
return ret == 0 ? copied : ret; |
cf776a7a4 reiserfs: cleanup... |
2875 |
journal_error: |
278f6679f reiserfs: locking... |
2876 |
reiserfs_write_unlock(inode->i_sb); |
d6f5b0aa0 kill-the-bkl/reis... |
2877 |
locked = false; |
ba9d8cec6 reiserfs: convert... |
2878 |
if (th) { |
ba9d8cec6 reiserfs: convert... |
2879 2880 2881 |
if (!update_sd) reiserfs_update_sd(th, inode); ret = reiserfs_end_persistent_transaction(th); |
ba9d8cec6 reiserfs: convert... |
2882 |
} |
ba9d8cec6 reiserfs: convert... |
2883 2884 2885 2886 2887 |
goto out; } int reiserfs_commit_write(struct file *f, struct page *page, unsigned from, unsigned to) |
bd4c625c0 reiserfs: run scr... |
2888 2889 |
{ struct inode *inode = page->mapping->host; |
09cbfeaf1 mm, fs: get rid o... |
2890 |
loff_t pos = ((loff_t) page->index << PAGE_SHIFT) + to; |
bd4c625c0 reiserfs: run scr... |
2891 2892 2893 |
int ret = 0; int update_sd = 0; struct reiserfs_transaction_handle *th = NULL; |
278f6679f reiserfs: locking... |
2894 |
int depth; |
bd4c625c0 reiserfs: run scr... |
2895 |
|
278f6679f reiserfs: locking... |
2896 |
depth = reiserfs_write_unlock_nested(inode->i_sb); |
bd4c625c0 reiserfs: run scr... |
2897 |
reiserfs_wait_on_write_block(inode->i_sb); |
278f6679f reiserfs: locking... |
2898 |
reiserfs_write_lock_nested(inode->i_sb, depth); |
8ebc42323 reiserfs: kill-th... |
2899 |
|
bd4c625c0 reiserfs: run scr... |
2900 2901 2902 2903 |
if (reiserfs_transaction_running(inode->i_sb)) { th = current->journal_info; } reiserfs_commit_page(inode, page, from, to); |
1da177e4c Linux-2.6.12-rc2 |
2904 |
|
098297b27 reiserfs: cleanup... |
2905 2906 2907 2908 |
/* * generic_commit_write does this for us, but does not update the * transaction tracking stuff when the size changes. So, we have * to do the i_size updates here. |
bd4c625c0 reiserfs: run scr... |
2909 2910 2911 |
*/ if (pos > inode->i_size) { struct reiserfs_transaction_handle myth; |
098297b27 reiserfs: cleanup... |
2912 2913 2914 2915 2916 |
/* * If the file have grown beyond the border where it * can have a tail, unmark it as needing a tail * packing */ |
bd4c625c0 reiserfs: run scr... |
2917 2918 2919 2920 2921 2922 2923 |
if ((have_large_tails(inode->i_sb) && inode->i_size > i_block_size(inode) * 4) || (have_small_tails(inode->i_sb) && inode->i_size > i_block_size(inode))) REISERFS_I(inode)->i_flags &= ~i_pack_on_close_mask; ret = journal_begin(&myth, inode->i_sb, 1); |
7e9427705 kill-the-bkl/reis... |
2924 |
if (ret) |
bd4c625c0 reiserfs: run scr... |
2925 |
goto journal_error; |
7e9427705 kill-the-bkl/reis... |
2926 |
|
bd4c625c0 reiserfs: run scr... |
2927 2928 |
reiserfs_update_inode_transaction(inode); inode->i_size = pos; |
9f03783ce [PATCH] reiserfs:... |
2929 2930 |
/* * this will just nest into our transaction. It's important |
098297b27 reiserfs: cleanup... |
2931 2932 |
* to use mark_inode_dirty so the inode gets pushed around * on the dirty lists, and so that O_SYNC works as expected |
9f03783ce [PATCH] reiserfs:... |
2933 2934 |
*/ mark_inode_dirty(inode); |
bd4c625c0 reiserfs: run scr... |
2935 2936 |
reiserfs_update_sd(&myth, inode); update_sd = 1; |
58d854265 reiserfs: cleanup... |
2937 |
ret = journal_end(&myth); |
bd4c625c0 reiserfs: run scr... |
2938 2939 2940 2941 |
if (ret) goto journal_error; } if (th) { |
bd4c625c0 reiserfs: run scr... |
2942 |
if (!update_sd) |
9f03783ce [PATCH] reiserfs:... |
2943 |
mark_inode_dirty(inode); |
bd4c625c0 reiserfs: run scr... |
2944 |
ret = reiserfs_end_persistent_transaction(th); |
bd4c625c0 reiserfs: run scr... |
2945 2946 2947 |
if (ret) goto out; } |
cf776a7a4 reiserfs: cleanup... |
2948 |
out: |
bd4c625c0 reiserfs: run scr... |
2949 |
return ret; |
1da177e4c Linux-2.6.12-rc2 |
2950 |
|
cf776a7a4 reiserfs: cleanup... |
2951 |
journal_error: |
bd4c625c0 reiserfs: run scr... |
2952 |
if (th) { |
bd4c625c0 reiserfs: run scr... |
2953 2954 2955 |
if (!update_sd) reiserfs_update_sd(th, inode); ret = reiserfs_end_persistent_transaction(th); |
bd4c625c0 reiserfs: run scr... |
2956 2957 2958 |
} return ret; |
1da177e4c Linux-2.6.12-rc2 |
2959 |
} |
bd4c625c0 reiserfs: run scr... |
2960 |
void sd_attrs_to_i_attrs(__u16 sd_attrs, struct inode *inode) |
1da177e4c Linux-2.6.12-rc2 |
2961 |
{ |
bd4c625c0 reiserfs: run scr... |
2962 2963 2964 |
if (reiserfs_attrs(inode->i_sb)) { if (sd_attrs & REISERFS_SYNC_FL) inode->i_flags |= S_SYNC; |
1da177e4c Linux-2.6.12-rc2 |
2965 |
else |
bd4c625c0 reiserfs: run scr... |
2966 2967 2968 |
inode->i_flags &= ~S_SYNC; if (sd_attrs & REISERFS_IMMUTABLE_FL) inode->i_flags |= S_IMMUTABLE; |
1da177e4c Linux-2.6.12-rc2 |
2969 |
else |
bd4c625c0 reiserfs: run scr... |
2970 2971 2972 |
inode->i_flags &= ~S_IMMUTABLE; if (sd_attrs & REISERFS_APPEND_FL) inode->i_flags |= S_APPEND; |
1da177e4c Linux-2.6.12-rc2 |
2973 |
else |
bd4c625c0 reiserfs: run scr... |
2974 2975 2976 |
inode->i_flags &= ~S_APPEND; if (sd_attrs & REISERFS_NOATIME_FL) inode->i_flags |= S_NOATIME; |
1da177e4c Linux-2.6.12-rc2 |
2977 |
else |
bd4c625c0 reiserfs: run scr... |
2978 2979 |
inode->i_flags &= ~S_NOATIME; if (sd_attrs & REISERFS_NOTAIL_FL) |
1da177e4c Linux-2.6.12-rc2 |
2980 2981 2982 2983 2984 |
REISERFS_I(inode)->i_flags |= i_nopack_mask; else REISERFS_I(inode)->i_flags &= ~i_nopack_mask; } } |
098297b27 reiserfs: cleanup... |
2985 2986 2987 2988 |
/* * decide if this buffer needs to stay around for data logging or ordered * write purposes */ |
1da177e4c Linux-2.6.12-rc2 |
2989 2990 |
static int invalidatepage_can_drop(struct inode *inode, struct buffer_head *bh) { |
bd4c625c0 reiserfs: run scr... |
2991 2992 |
int ret = 1; struct reiserfs_journal *j = SB_JOURNAL(inode->i_sb); |
d62b1b87a [PATCH] resierfs:... |
2993 |
lock_buffer(bh); |
bd4c625c0 reiserfs: run scr... |
2994 2995 2996 2997 |
spin_lock(&j->j_dirty_buffers_lock); if (!buffer_mapped(bh)) { goto free_jh; } |
098297b27 reiserfs: cleanup... |
2998 2999 |
/* * the page is locked, and the only places that log a data buffer |
bd4c625c0 reiserfs: run scr... |
3000 |
* also lock the page. |
1da177e4c Linux-2.6.12-rc2 |
3001 |
*/ |
bd4c625c0 reiserfs: run scr... |
3002 3003 3004 3005 3006 3007 3008 3009 |
if (reiserfs_file_data_log(inode)) { /* * very conservative, leave the buffer pinned if * anyone might need it. */ if (buffer_journaled(bh) || buffer_journal_dirty(bh)) { ret = 0; } |
d62b1b87a [PATCH] resierfs:... |
3010 |
} else if (buffer_dirty(bh)) { |
bd4c625c0 reiserfs: run scr... |
3011 3012 |
struct reiserfs_journal_list *jl; struct reiserfs_jh *jh = bh->b_private; |
098297b27 reiserfs: cleanup... |
3013 3014 |
/* * why is this safe? |
bd4c625c0 reiserfs: run scr... |
3015 3016 3017 3018 3019 3020 3021 3022 3023 3024 3025 3026 3027 3028 3029 3030 |
* reiserfs_setattr updates i_size in the on disk * stat data before allowing vmtruncate to be called. * * If buffer was put onto the ordered list for this * transaction, we know for sure either this transaction * or an older one already has updated i_size on disk, * and this ordered data won't be referenced in the file * if we crash. * * if the buffer was put onto the ordered list for an older * transaction, we need to leave it around */ if (jh && (jl = jh->jl) && jl != SB_JOURNAL(inode->i_sb)->j_current_jl) ret = 0; } |
cf776a7a4 reiserfs: cleanup... |
3031 |
free_jh: |
bd4c625c0 reiserfs: run scr... |
3032 3033 3034 3035 |
if (ret && bh->b_private) { reiserfs_free_jh(bh); } spin_unlock(&j->j_dirty_buffers_lock); |
d62b1b87a [PATCH] resierfs:... |
3036 |
unlock_buffer(bh); |
bd4c625c0 reiserfs: run scr... |
3037 |
return ret; |
1da177e4c Linux-2.6.12-rc2 |
3038 3039 3040 |
} /* clm -- taken from fs/buffer.c:block_invalidate_page */ |
d47992f86 mm: change invali... |
3041 3042 |
static void reiserfs_invalidatepage(struct page *page, unsigned int offset, unsigned int length) |
1da177e4c Linux-2.6.12-rc2 |
3043 |
{ |
bd4c625c0 reiserfs: run scr... |
3044 3045 3046 |
struct buffer_head *head, *bh, *next; struct inode *inode = page->mapping->host; unsigned int curr_off = 0; |
bad548319 reiserfs: use ->i... |
3047 |
unsigned int stop = offset + length; |
09cbfeaf1 mm, fs: get rid o... |
3048 |
int partial_page = (offset || length < PAGE_SIZE); |
bd4c625c0 reiserfs: run scr... |
3049 |
int ret = 1; |
1da177e4c Linux-2.6.12-rc2 |
3050 |
|
bd4c625c0 reiserfs: run scr... |
3051 |
BUG_ON(!PageLocked(page)); |
1da177e4c Linux-2.6.12-rc2 |
3052 |
|
bad548319 reiserfs: use ->i... |
3053 |
if (!partial_page) |
bd4c625c0 reiserfs: run scr... |
3054 |
ClearPageChecked(page); |
1da177e4c Linux-2.6.12-rc2 |
3055 |
|
bd4c625c0 reiserfs: run scr... |
3056 3057 3058 3059 3060 3061 3062 3063 |
if (!page_has_buffers(page)) goto out; head = page_buffers(page); bh = head; do { unsigned int next_off = curr_off + bh->b_size; next = bh->b_this_page; |
1da177e4c Linux-2.6.12-rc2 |
3064 |
|
bad548319 reiserfs: use ->i... |
3065 3066 |
if (next_off > stop) goto out; |
bd4c625c0 reiserfs: run scr... |
3067 3068 3069 3070 3071 3072 3073 3074 3075 3076 3077 3078 |
/* * is this block fully invalidated? */ if (offset <= curr_off) { if (invalidatepage_can_drop(inode, bh)) reiserfs_unmap_buffer(bh); else ret = 0; } curr_off = next_off; bh = next; } while (bh != head); |
1da177e4c Linux-2.6.12-rc2 |
3079 3080 |
/* |
bd4c625c0 reiserfs: run scr... |
3081 3082 3083 |
* We release buffers only if the entire page is being invalidated. * The get_block cached value has been unconditionally invalidated, * so real IO is not possible anymore. |
1da177e4c Linux-2.6.12-rc2 |
3084 |
*/ |
bad548319 reiserfs: use ->i... |
3085 |
if (!partial_page && ret) { |
bd4c625c0 reiserfs: run scr... |
3086 |
ret = try_to_release_page(page, 0); |
2ff28e22b [PATCH] Make addr... |
3087 3088 |
/* maybe should BUG_ON(!ret); - neilb */ } |
cf776a7a4 reiserfs: cleanup... |
3089 |
out: |
2ff28e22b [PATCH] Make addr... |
3090 |
return; |
1da177e4c Linux-2.6.12-rc2 |
3091 |
} |
bd4c625c0 reiserfs: run scr... |
3092 3093 3094 3095 3096 3097 3098 3099 |
static int reiserfs_set_page_dirty(struct page *page) { struct inode *inode = page->mapping->host; if (reiserfs_file_data_log(inode)) { SetPageChecked(page); return __set_page_dirty_nobuffers(page); } return __set_page_dirty_buffers(page); |
1da177e4c Linux-2.6.12-rc2 |
3100 3101 3102 3103 3104 3105 3106 3107 3108 3109 3110 |
} /* * Returns 1 if the page's buffers were dropped. The page is locked. * * Takes j_dirty_buffers_lock to protect the b_assoc_buffers list_heads * in the buffers at page_buffers(page). * * even in -o notail mode, we can't be sure an old mount without -o notail * didn't create files with tails. */ |
27496a8c6 [PATCH] gfp_t: fs/* |
3111 |
static int reiserfs_releasepage(struct page *page, gfp_t unused_gfp_flags) |
1da177e4c Linux-2.6.12-rc2 |
3112 |
{ |
bd4c625c0 reiserfs: run scr... |
3113 3114 3115 3116 3117 3118 3119 3120 3121 3122 3123 3124 3125 3126 3127 3128 3129 3130 3131 3132 3133 3134 3135 3136 3137 |
struct inode *inode = page->mapping->host; struct reiserfs_journal *j = SB_JOURNAL(inode->i_sb); struct buffer_head *head; struct buffer_head *bh; int ret = 1; WARN_ON(PageChecked(page)); spin_lock(&j->j_dirty_buffers_lock); head = page_buffers(page); bh = head; do { if (bh->b_private) { if (!buffer_dirty(bh) && !buffer_locked(bh)) { reiserfs_free_jh(bh); } else { ret = 0; break; } } bh = bh->b_this_page; } while (bh != head); if (ret) ret = try_to_free_buffers(page); spin_unlock(&j->j_dirty_buffers_lock); return ret; |
1da177e4c Linux-2.6.12-rc2 |
3138 |
} |
098297b27 reiserfs: cleanup... |
3139 3140 3141 3142 |
/* * We thank Mingming Cao for helping us understand in great detail what * to do in this section of the code. */ |
c8b8e32d7 direct-io: elimin... |
3143 |
static ssize_t reiserfs_direct_IO(struct kiocb *iocb, struct iov_iter *iter) |
1da177e4c Linux-2.6.12-rc2 |
3144 |
{ |
bd4c625c0 reiserfs: run scr... |
3145 3146 |
struct file *file = iocb->ki_filp; struct inode *inode = file->f_mapping->host; |
a6cbcd4a4 get rid of pointl... |
3147 |
size_t count = iov_iter_count(iter); |
eafdc7d19 sort out blockdev... |
3148 |
ssize_t ret; |
1da177e4c Linux-2.6.12-rc2 |
3149 |
|
c8b8e32d7 direct-io: elimin... |
3150 |
ret = blockdev_direct_IO(iocb, inode, iter, |
31b140398 switch {__,}block... |
3151 |
reiserfs_get_blocks_direct_io); |
eafdc7d19 sort out blockdev... |
3152 3153 3154 3155 3156 |
/* * In case of error extending write may have instantiated a few * blocks outside i_size. Trim these off again. */ |
6f6737631 direct_IO: use io... |
3157 |
if (unlikely(iov_iter_rw(iter) == WRITE && ret < 0)) { |
eafdc7d19 sort out blockdev... |
3158 |
loff_t isize = i_size_read(inode); |
c8b8e32d7 direct-io: elimin... |
3159 |
loff_t end = iocb->ki_pos + count; |
eafdc7d19 sort out blockdev... |
3160 |
|
cfac4b47c reiserfs: drop vm... |
3161 3162 3163 3164 |
if ((end > isize) && inode_newsize_ok(inode, isize) == 0) { truncate_setsize(inode, isize); reiserfs_vfs_truncate_file(inode); } |
eafdc7d19 sort out blockdev... |
3165 3166 3167 |
} return ret; |
1da177e4c Linux-2.6.12-rc2 |
3168 |
} |
bd4c625c0 reiserfs: run scr... |
3169 3170 |
int reiserfs_setattr(struct dentry *dentry, struct iattr *attr) { |
2b0143b5c VFS: normal files... |
3171 |
struct inode *inode = d_inode(dentry); |
cdd6fe6e2 reiserfs: turn of... |
3172 |
unsigned int ia_valid; |
5fe1533fd reiserfs: Fix rec... |
3173 |
int error; |
cdd6fe6e2 reiserfs: turn of... |
3174 |
|
31051c85b fs: Give dentry t... |
3175 |
error = setattr_prepare(dentry, attr); |
db78b877f always call inode... |
3176 3177 |
if (error) return error; |
cdd6fe6e2 reiserfs: turn of... |
3178 3179 |
/* must be turned off for recursive notify_change calls */ ia_valid = attr->ia_valid &= ~(ATTR_KILL_SUID|ATTR_KILL_SGID); |
2e6c97ea4 reiserfs: Handle ... |
3180 3181 3182 3183 3184 |
if (is_quota_modification(inode, attr)) { error = dquot_initialize(inode); if (error) return error; } |
278f6679f reiserfs: locking... |
3185 |
reiserfs_write_lock(inode->i_sb); |
12755627b quota: unify quot... |
3186 |
if (attr->ia_valid & ATTR_SIZE) { |
098297b27 reiserfs: cleanup... |
3187 3188 3189 |
/* * version 2 items will be caught by the s_maxbytes check * done for us in vmtruncate |
bd4c625c0 reiserfs: run scr... |
3190 3191 3192 |
*/ if (get_inode_item_key_version(inode) == KEY_FORMAT_3_5 && attr->ia_size > MAX_NON_LFS) { |
278f6679f reiserfs: locking... |
3193 |
reiserfs_write_unlock(inode->i_sb); |
bd4c625c0 reiserfs: run scr... |
3194 3195 3196 |
error = -EFBIG; goto out; } |
562c72aa5 fs: move inode_di... |
3197 3198 |
inode_dio_wait(inode); |
bd4c625c0 reiserfs: run scr... |
3199 3200 |
/* fill in hole pointers in the expanding truncate case. */ if (attr->ia_size > inode->i_size) { |
f7557e8f7 reiserfs: use gen... |
3201 |
error = generic_cont_expand_simple(inode, attr->ia_size); |
bd4c625c0 reiserfs: run scr... |
3202 3203 3204 3205 3206 3207 3208 |
if (REISERFS_I(inode)->i_prealloc_count > 0) { int err; struct reiserfs_transaction_handle th; /* we're changing at most 2 bitmaps, inode + super */ err = journal_begin(&th, inode->i_sb, 4); if (!err) { reiserfs_discard_prealloc(&th, inode); |
58d854265 reiserfs: cleanup... |
3209 |
err = journal_end(&th); |
bd4c625c0 reiserfs: run scr... |
3210 3211 3212 3213 |
} if (err) error = err; } |
4c05141df reiserfs: locking... |
3214 |
if (error) { |
278f6679f reiserfs: locking... |
3215 |
reiserfs_write_unlock(inode->i_sb); |
bd4c625c0 reiserfs: run scr... |
3216 |
goto out; |
4c05141df reiserfs: locking... |
3217 |
} |
dd535a596 [PATCH] reiserfs:... |
3218 3219 3220 3221 3222 |
/* * file size is changed, ctime and mtime are * to be updated */ attr->ia_valid |= (ATTR_MTIME | ATTR_CTIME); |
1da177e4c Linux-2.6.12-rc2 |
3223 |
} |
1da177e4c Linux-2.6.12-rc2 |
3224 |
} |
278f6679f reiserfs: locking... |
3225 |
reiserfs_write_unlock(inode->i_sb); |
1da177e4c Linux-2.6.12-rc2 |
3226 |
|
df814654f userns: Convert r... |
3227 3228 |
if ((((attr->ia_valid & ATTR_UID) && (from_kuid(&init_user_ns, attr->ia_uid) & ~0xffff)) || ((attr->ia_valid & ATTR_GID) && (from_kgid(&init_user_ns, attr->ia_gid) & ~0xffff))) && |
bd4c625c0 reiserfs: run scr... |
3229 |
(get_inode_sd_version(inode) == STAT_DATA_V1)) { |
1da177e4c Linux-2.6.12-rc2 |
3230 |
/* stat data of format v3.5 has 16 bit uid and gid */ |
bd4c625c0 reiserfs: run scr... |
3231 3232 3233 |
error = -EINVAL; goto out; } |
1da177e4c Linux-2.6.12-rc2 |
3234 |
|
df814654f userns: Convert r... |
3235 3236 |
if ((ia_valid & ATTR_UID && !uid_eq(attr->ia_uid, inode->i_uid)) || (ia_valid & ATTR_GID && !gid_eq(attr->ia_gid, inode->i_gid))) { |
1025774ce remove inode_setattr |
3237 3238 3239 3240 3241 3242 |
struct reiserfs_transaction_handle th; int jbegin_count = 2 * (REISERFS_QUOTA_INIT_BLOCKS(inode->i_sb) + REISERFS_QUOTA_DEL_BLOCKS(inode->i_sb)) + 2; |
bd4c625c0 reiserfs: run scr... |
3243 |
|
1025774ce remove inode_setattr |
3244 3245 3246 3247 |
error = reiserfs_chown_xattrs(inode, attr); if (error) return error; |
098297b27 reiserfs: cleanup... |
3248 3249 3250 3251 |
/* * (user+group)*(old+new) structure - we count quota * info and , inode write (sb, inode) */ |
278f6679f reiserfs: locking... |
3252 |
reiserfs_write_lock(inode->i_sb); |
1025774ce remove inode_setattr |
3253 |
error = journal_begin(&th, inode->i_sb, jbegin_count); |
278f6679f reiserfs: locking... |
3254 |
reiserfs_write_unlock(inode->i_sb); |
1025774ce remove inode_setattr |
3255 3256 3257 |
if (error) goto out; error = dquot_transfer(inode, attr); |
278f6679f reiserfs: locking... |
3258 |
reiserfs_write_lock(inode->i_sb); |
1025774ce remove inode_setattr |
3259 |
if (error) { |
58d854265 reiserfs: cleanup... |
3260 |
journal_end(&th); |
278f6679f reiserfs: locking... |
3261 |
reiserfs_write_unlock(inode->i_sb); |
1025774ce remove inode_setattr |
3262 |
goto out; |
108d3943c reiserfs: Relax t... |
3263 |
} |
1025774ce remove inode_setattr |
3264 |
|
098297b27 reiserfs: cleanup... |
3265 3266 3267 3268 |
/* * Update corresponding info in inode so that everything * is in one transaction */ |
1025774ce remove inode_setattr |
3269 3270 3271 3272 3273 |
if (attr->ia_valid & ATTR_UID) inode->i_uid = attr->ia_uid; if (attr->ia_valid & ATTR_GID) inode->i_gid = attr->ia_gid; mark_inode_dirty(inode); |
58d854265 reiserfs: cleanup... |
3274 |
error = journal_end(&th); |
278f6679f reiserfs: locking... |
3275 |
reiserfs_write_unlock(inode->i_sb); |
1025774ce remove inode_setattr |
3276 3277 |
if (error) goto out; |
bd4c625c0 reiserfs: run scr... |
3278 |
} |
1da177e4c Linux-2.6.12-rc2 |
3279 |
|
1025774ce remove inode_setattr |
3280 |
if ((attr->ia_valid & ATTR_SIZE) && |
cfac4b47c reiserfs: drop vm... |
3281 3282 3283 |
attr->ia_size != i_size_read(inode)) { error = inode_newsize_ok(inode, attr->ia_size); if (!error) { |
22e7478dd reiserfs: call tr... |
3284 3285 3286 3287 3288 |
/* * Could race against reiserfs_file_release * if called from NFS, so take tailpack mutex. */ mutex_lock(&REISERFS_I(inode)->tailpack); |
cfac4b47c reiserfs: drop vm... |
3289 |
truncate_setsize(inode, attr->ia_size); |
22e7478dd reiserfs: call tr... |
3290 3291 |
reiserfs_truncate_file(inode, 1); mutex_unlock(&REISERFS_I(inode)->tailpack); |
cfac4b47c reiserfs: drop vm... |
3292 3293 |
} } |
1025774ce remove inode_setattr |
3294 3295 3296 3297 |
if (!error) { setattr_copy(inode, attr); mark_inode_dirty(inode); |
bd4c625c0 reiserfs: run scr... |
3298 |
} |
1da177e4c Linux-2.6.12-rc2 |
3299 |
|
bd4c625c0 reiserfs: run scr... |
3300 3301 3302 3303 |
if (!error && reiserfs_posixacl(inode->i_sb)) { if (attr->ia_valid & ATTR_MODE) error = reiserfs_acl_chmod(inode); } |
1da177e4c Linux-2.6.12-rc2 |
3304 |
|
4c05141df reiserfs: locking... |
3305 |
out: |
bd4c625c0 reiserfs: run scr... |
3306 |
return error; |
1da177e4c Linux-2.6.12-rc2 |
3307 |
} |
f5e54d6e5 [PATCH] mark addr... |
3308 |
const struct address_space_operations reiserfs_address_space_operations = { |
bd4c625c0 reiserfs: run scr... |
3309 3310 |
.writepage = reiserfs_writepage, .readpage = reiserfs_readpage, |
d4388340a fs: convert mpage... |
3311 |
.readahead = reiserfs_readahead, |
bd4c625c0 reiserfs: run scr... |
3312 3313 |
.releasepage = reiserfs_releasepage, .invalidatepage = reiserfs_invalidatepage, |
ba9d8cec6 reiserfs: convert... |
3314 3315 |
.write_begin = reiserfs_write_begin, .write_end = reiserfs_write_end, |
bd4c625c0 reiserfs: run scr... |
3316 3317 3318 3319 |
.bmap = reiserfs_aop_bmap, .direct_IO = reiserfs_direct_IO, .set_page_dirty = reiserfs_set_page_dirty, }; |