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