diff options
-rw-r--r-- | fs/exofs/dir.c | 4 | ||||
-rw-r--r-- | fs/exofs/inode.c | 64 |
2 files changed, 27 insertions, 41 deletions
diff --git a/fs/exofs/dir.c b/fs/exofs/dir.c index d91e9d829bc1..dcc941d82d67 100644 --- a/fs/exofs/dir.c +++ b/fs/exofs/dir.c | |||
@@ -420,7 +420,7 @@ int exofs_set_link(struct inode *dir, struct exofs_dir_entry *de, | |||
420 | err = exofs_write_begin(NULL, page->mapping, pos, len, | 420 | err = exofs_write_begin(NULL, page->mapping, pos, len, |
421 | AOP_FLAG_UNINTERRUPTIBLE, &page, NULL); | 421 | AOP_FLAG_UNINTERRUPTIBLE, &page, NULL); |
422 | if (err) | 422 | if (err) |
423 | EXOFS_ERR("exofs_set_link: exofs_write_begin FAILD => %d\n", | 423 | EXOFS_ERR("exofs_set_link: exofs_write_begin FAILED => %d\n", |
424 | err); | 424 | err); |
425 | 425 | ||
426 | de->inode_no = cpu_to_le64(inode->i_ino); | 426 | de->inode_no = cpu_to_le64(inode->i_ino); |
@@ -556,7 +556,7 @@ int exofs_delete_entry(struct exofs_dir_entry *dir, struct page *page) | |||
556 | err = exofs_write_begin(NULL, page->mapping, pos, to - from, 0, | 556 | err = exofs_write_begin(NULL, page->mapping, pos, to - from, 0, |
557 | &page, NULL); | 557 | &page, NULL); |
558 | if (err) | 558 | if (err) |
559 | EXOFS_ERR("exofs_delete_entry: exofs_write_begin FAILD => %d\n", | 559 | EXOFS_ERR("exofs_delete_entry: exofs_write_begin FAILED => %d\n", |
560 | err); | 560 | err); |
561 | if (pde) | 561 | if (pde) |
562 | pde->rec_len = cpu_to_le16(to - from); | 562 | pde->rec_len = cpu_to_le16(to - from); |
diff --git a/fs/exofs/inode.c b/fs/exofs/inode.c index 44602754f758..42685424817b 100644 --- a/fs/exofs/inode.c +++ b/fs/exofs/inode.c | |||
@@ -185,7 +185,7 @@ static void update_write_page(struct page *page, int ret) | |||
185 | /* Called at the end of reads, to optionally unlock pages and update their | 185 | /* Called at the end of reads, to optionally unlock pages and update their |
186 | * status. | 186 | * status. |
187 | */ | 187 | */ |
188 | static int __readpages_done(struct page_collect *pcol, bool do_unlock) | 188 | static int __readpages_done(struct page_collect *pcol) |
189 | { | 189 | { |
190 | int i; | 190 | int i; |
191 | u64 resid; | 191 | u64 resid; |
@@ -221,7 +221,7 @@ static int __readpages_done(struct page_collect *pcol, bool do_unlock) | |||
221 | page_stat ? "bad_bytes" : "good_bytes"); | 221 | page_stat ? "bad_bytes" : "good_bytes"); |
222 | 222 | ||
223 | ret = update_read_page(page, page_stat); | 223 | ret = update_read_page(page, page_stat); |
224 | if (do_unlock) | 224 | if (!pcol->read_4_write) |
225 | unlock_page(page); | 225 | unlock_page(page); |
226 | length += PAGE_SIZE; | 226 | length += PAGE_SIZE; |
227 | } | 227 | } |
@@ -236,7 +236,7 @@ static void readpages_done(struct exofs_io_state *ios, void *p) | |||
236 | { | 236 | { |
237 | struct page_collect *pcol = p; | 237 | struct page_collect *pcol = p; |
238 | 238 | ||
239 | __readpages_done(pcol, true); | 239 | __readpages_done(pcol); |
240 | atomic_dec(&pcol->sbi->s_curr_pending); | 240 | atomic_dec(&pcol->sbi->s_curr_pending); |
241 | kfree(pcol); | 241 | kfree(pcol); |
242 | } | 242 | } |
@@ -257,7 +257,7 @@ static void _unlock_pcol_pages(struct page_collect *pcol, int ret, int rw) | |||
257 | } | 257 | } |
258 | } | 258 | } |
259 | 259 | ||
260 | static int read_exec(struct page_collect *pcol, bool is_sync) | 260 | static int read_exec(struct page_collect *pcol) |
261 | { | 261 | { |
262 | struct exofs_i_info *oi = exofs_i(pcol->inode); | 262 | struct exofs_i_info *oi = exofs_i(pcol->inode); |
263 | struct exofs_io_state *ios = pcol->ios; | 263 | struct exofs_io_state *ios = pcol->ios; |
@@ -267,17 +267,14 @@ static int read_exec(struct page_collect *pcol, bool is_sync) | |||
267 | if (!pcol->pages) | 267 | if (!pcol->pages) |
268 | return 0; | 268 | return 0; |
269 | 269 | ||
270 | /* see comment in _readpage() about sync reads */ | ||
271 | WARN_ON(is_sync && (pcol->nr_pages != 1)); | ||
272 | |||
273 | ios->pages = pcol->pages; | 270 | ios->pages = pcol->pages; |
274 | ios->nr_pages = pcol->nr_pages; | 271 | ios->nr_pages = pcol->nr_pages; |
275 | ios->length = pcol->length; | 272 | ios->length = pcol->length; |
276 | ios->offset = pcol->pg_first << PAGE_CACHE_SHIFT; | 273 | ios->offset = pcol->pg_first << PAGE_CACHE_SHIFT; |
277 | 274 | ||
278 | if (is_sync) { | 275 | if (pcol->read_4_write) { |
279 | exofs_oi_read(oi, pcol->ios); | 276 | exofs_oi_read(oi, pcol->ios); |
280 | return __readpages_done(pcol, false); | 277 | return __readpages_done(pcol); |
281 | } | 278 | } |
282 | 279 | ||
283 | pcol_copy = kmalloc(sizeof(*pcol_copy), GFP_KERNEL); | 280 | pcol_copy = kmalloc(sizeof(*pcol_copy), GFP_KERNEL); |
@@ -303,7 +300,7 @@ static int read_exec(struct page_collect *pcol, bool is_sync) | |||
303 | return 0; | 300 | return 0; |
304 | 301 | ||
305 | err: | 302 | err: |
306 | if (!is_sync) | 303 | if (!pcol->read_4_write) |
307 | _unlock_pcol_pages(pcol, ret, READ); | 304 | _unlock_pcol_pages(pcol, ret, READ); |
308 | 305 | ||
309 | pcol_free(pcol); | 306 | pcol_free(pcol); |
@@ -356,7 +353,7 @@ static int readpage_strip(void *data, struct page *page) | |||
356 | EXOFS_DBGMSG("readpage_strip(0x%lx, 0x%lx) empty page," | 353 | EXOFS_DBGMSG("readpage_strip(0x%lx, 0x%lx) empty page," |
357 | " splitting\n", inode->i_ino, page->index); | 354 | " splitting\n", inode->i_ino, page->index); |
358 | 355 | ||
359 | return read_exec(pcol, false); | 356 | return read_exec(pcol); |
360 | } | 357 | } |
361 | 358 | ||
362 | try_again: | 359 | try_again: |
@@ -366,7 +363,7 @@ try_again: | |||
366 | } else if (unlikely((pcol->pg_first + pcol->nr_pages) != | 363 | } else if (unlikely((pcol->pg_first + pcol->nr_pages) != |
367 | page->index)) { | 364 | page->index)) { |
368 | /* Discontinuity detected, split the request */ | 365 | /* Discontinuity detected, split the request */ |
369 | ret = read_exec(pcol, false); | 366 | ret = read_exec(pcol); |
370 | if (unlikely(ret)) | 367 | if (unlikely(ret)) |
371 | goto fail; | 368 | goto fail; |
372 | goto try_again; | 369 | goto try_again; |
@@ -391,7 +388,7 @@ try_again: | |||
391 | page, len, pcol->nr_pages, pcol->length); | 388 | page, len, pcol->nr_pages, pcol->length); |
392 | 389 | ||
393 | /* split the request, and start again with current page */ | 390 | /* split the request, and start again with current page */ |
394 | ret = read_exec(pcol, false); | 391 | ret = read_exec(pcol); |
395 | if (unlikely(ret)) | 392 | if (unlikely(ret)) |
396 | goto fail; | 393 | goto fail; |
397 | 394 | ||
@@ -420,27 +417,24 @@ static int exofs_readpages(struct file *file, struct address_space *mapping, | |||
420 | return ret; | 417 | return ret; |
421 | } | 418 | } |
422 | 419 | ||
423 | return read_exec(&pcol, false); | 420 | return read_exec(&pcol); |
424 | } | 421 | } |
425 | 422 | ||
426 | static int _readpage(struct page *page, bool is_sync) | 423 | static int _readpage(struct page *page, bool read_4_write) |
427 | { | 424 | { |
428 | struct page_collect pcol; | 425 | struct page_collect pcol; |
429 | int ret; | 426 | int ret; |
430 | 427 | ||
431 | _pcol_init(&pcol, 1, page->mapping->host); | 428 | _pcol_init(&pcol, 1, page->mapping->host); |
432 | 429 | ||
433 | /* readpage_strip might call read_exec(,is_sync==false) at several | 430 | pcol.read_4_write = read_4_write; |
434 | * places but not if we have a single page. | ||
435 | */ | ||
436 | pcol.read_4_write = is_sync; | ||
437 | ret = readpage_strip(&pcol, page); | 431 | ret = readpage_strip(&pcol, page); |
438 | if (ret) { | 432 | if (ret) { |
439 | EXOFS_ERR("_readpage => %d\n", ret); | 433 | EXOFS_ERR("_readpage => %d\n", ret); |
440 | return ret; | 434 | return ret; |
441 | } | 435 | } |
442 | 436 | ||
443 | return read_exec(&pcol, is_sync); | 437 | return read_exec(&pcol); |
444 | } | 438 | } |
445 | 439 | ||
446 | /* | 440 | /* |
@@ -1036,6 +1030,7 @@ struct inode *exofs_iget(struct super_block *sb, unsigned long ino) | |||
1036 | memcpy(oi->i_data, fcb.i_data, sizeof(fcb.i_data)); | 1030 | memcpy(oi->i_data, fcb.i_data, sizeof(fcb.i_data)); |
1037 | } | 1031 | } |
1038 | 1032 | ||
1033 | inode->i_mapping->backing_dev_info = sb->s_bdi; | ||
1039 | if (S_ISREG(inode->i_mode)) { | 1034 | if (S_ISREG(inode->i_mode)) { |
1040 | inode->i_op = &exofs_file_inode_operations; | 1035 | inode->i_op = &exofs_file_inode_operations; |
1041 | inode->i_fop = &exofs_file_operations; | 1036 | inode->i_fop = &exofs_file_operations; |
@@ -1072,8 +1067,10 @@ bad_inode: | |||
1072 | int __exofs_wait_obj_created(struct exofs_i_info *oi) | 1067 | int __exofs_wait_obj_created(struct exofs_i_info *oi) |
1073 | { | 1068 | { |
1074 | if (!obj_created(oi)) { | 1069 | if (!obj_created(oi)) { |
1070 | EXOFS_DBGMSG("!obj_created\n"); | ||
1075 | BUG_ON(!obj_2bcreated(oi)); | 1071 | BUG_ON(!obj_2bcreated(oi)); |
1076 | wait_event(oi->i_wq, obj_created(oi)); | 1072 | wait_event(oi->i_wq, obj_created(oi)); |
1073 | EXOFS_DBGMSG("wait_event done\n"); | ||
1077 | } | 1074 | } |
1078 | return unlikely(is_bad_inode(&oi->vfs_inode)) ? -EIO : 0; | 1075 | return unlikely(is_bad_inode(&oi->vfs_inode)) ? -EIO : 0; |
1079 | } | 1076 | } |
@@ -1107,7 +1104,6 @@ static void create_done(struct exofs_io_state *ios, void *p) | |||
1107 | 1104 | ||
1108 | set_obj_created(oi); | 1105 | set_obj_created(oi); |
1109 | 1106 | ||
1110 | atomic_dec(&inode->i_count); | ||
1111 | wake_up(&oi->i_wq); | 1107 | wake_up(&oi->i_wq); |
1112 | } | 1108 | } |
1113 | 1109 | ||
@@ -1135,6 +1131,7 @@ struct inode *exofs_new_inode(struct inode *dir, int mode) | |||
1135 | 1131 | ||
1136 | sbi = sb->s_fs_info; | 1132 | sbi = sb->s_fs_info; |
1137 | 1133 | ||
1134 | inode->i_mapping->backing_dev_info = sb->s_bdi; | ||
1138 | sb->s_dirt = 1; | 1135 | sb->s_dirt = 1; |
1139 | inode_init_owner(inode, dir, mode); | 1136 | inode_init_owner(inode, dir, mode); |
1140 | inode->i_ino = sbi->s_nextid++; | 1137 | inode->i_ino = sbi->s_nextid++; |
@@ -1157,17 +1154,11 @@ struct inode *exofs_new_inode(struct inode *dir, int mode) | |||
1157 | ios->obj.id = exofs_oi_objno(oi); | 1154 | ios->obj.id = exofs_oi_objno(oi); |
1158 | exofs_make_credential(oi->i_cred, &ios->obj); | 1155 | exofs_make_credential(oi->i_cred, &ios->obj); |
1159 | 1156 | ||
1160 | /* increment the refcount so that the inode will still be around when we | ||
1161 | * reach the callback | ||
1162 | */ | ||
1163 | atomic_inc(&inode->i_count); | ||
1164 | |||
1165 | ios->done = create_done; | 1157 | ios->done = create_done; |
1166 | ios->private = inode; | 1158 | ios->private = inode; |
1167 | ios->cred = oi->i_cred; | 1159 | ios->cred = oi->i_cred; |
1168 | ret = exofs_sbi_create(ios); | 1160 | ret = exofs_sbi_create(ios); |
1169 | if (ret) { | 1161 | if (ret) { |
1170 | atomic_dec(&inode->i_count); | ||
1171 | exofs_put_io_state(ios); | 1162 | exofs_put_io_state(ios); |
1172 | return ERR_PTR(ret); | 1163 | return ERR_PTR(ret); |
1173 | } | 1164 | } |
@@ -1257,12 +1248,7 @@ static int exofs_update_inode(struct inode *inode, int do_sync) | |||
1257 | ios->out_attr_len = 1; | 1248 | ios->out_attr_len = 1; |
1258 | ios->out_attr = &attr; | 1249 | ios->out_attr = &attr; |
1259 | 1250 | ||
1260 | if (!obj_created(oi)) { | 1251 | wait_obj_created(oi); |
1261 | EXOFS_DBGMSG("!obj_created\n"); | ||
1262 | BUG_ON(!obj_2bcreated(oi)); | ||
1263 | wait_event(oi->i_wq, obj_created(oi)); | ||
1264 | EXOFS_DBGMSG("wait_event done\n"); | ||
1265 | } | ||
1266 | 1252 | ||
1267 | if (!do_sync) { | 1253 | if (!do_sync) { |
1268 | args->sbi = sbi; | 1254 | args->sbi = sbi; |
@@ -1325,12 +1311,12 @@ void exofs_evict_inode(struct inode *inode) | |||
1325 | inode->i_size = 0; | 1311 | inode->i_size = 0; |
1326 | end_writeback(inode); | 1312 | end_writeback(inode); |
1327 | 1313 | ||
1328 | /* if we are deleting an obj that hasn't been created yet, wait */ | 1314 | /* if we are deleting an obj that hasn't been created yet, wait. |
1329 | if (!obj_created(oi)) { | 1315 | * This also makes sure that create_done cannot be called with an |
1330 | BUG_ON(!obj_2bcreated(oi)); | 1316 | * already evicted inode. |
1331 | wait_event(oi->i_wq, obj_created(oi)); | 1317 | */ |
1332 | /* ignore the error attempt a remove anyway */ | 1318 | wait_obj_created(oi); |
1333 | } | 1319 | /* ignore the error, attempt a remove anyway */ |
1334 | 1320 | ||
1335 | /* Now Remove the OSD objects */ | 1321 | /* Now Remove the OSD objects */ |
1336 | ret = exofs_get_io_state(&sbi->layout, &ios); | 1322 | ret = exofs_get_io_state(&sbi->layout, &ios); |