diff options
author | Len Brown <len.brown@intel.com> | 2010-08-15 01:06:31 -0400 |
---|---|---|
committer | Len Brown <len.brown@intel.com> | 2010-08-15 01:06:31 -0400 |
commit | 95ee46aa8698f2000647dfb362400fadbb5807cf (patch) | |
tree | e5a05c7297f997e191c73091934e42e3195c0e40 /fs/ubifs | |
parent | cfa806f059801dbe7e435745eb2e187c8bfe1e7f (diff) | |
parent | 92fa5bd9a946b6e7aab6764e7312e4e3d9bed295 (diff) |
Merge branch 'linus' into release
Conflicts:
drivers/acpi/debug.c
Signed-off-by: Len Brown <len.brown@intel.com>
Diffstat (limited to 'fs/ubifs')
-rw-r--r-- | fs/ubifs/file.c | 23 | ||||
-rw-r--r-- | fs/ubifs/lpt.c | 14 | ||||
-rw-r--r-- | fs/ubifs/lpt_commit.c | 2 | ||||
-rw-r--r-- | fs/ubifs/recovery.c | 23 | ||||
-rw-r--r-- | fs/ubifs/super.c | 16 | ||||
-rw-r--r-- | fs/ubifs/ubifs.h | 2 |
6 files changed, 46 insertions, 34 deletions
diff --git a/fs/ubifs/file.c b/fs/ubifs/file.c index 12f445cee9f7..03ae894c45de 100644 --- a/fs/ubifs/file.c +++ b/fs/ubifs/file.c | |||
@@ -967,14 +967,15 @@ static int do_writepage(struct page *page, int len) | |||
967 | * the page locked, and it locks @ui_mutex. However, write-back does take inode | 967 | * the page locked, and it locks @ui_mutex. However, write-back does take inode |
968 | * @i_mutex, which means other VFS operations may be run on this inode at the | 968 | * @i_mutex, which means other VFS operations may be run on this inode at the |
969 | * same time. And the problematic one is truncation to smaller size, from where | 969 | * same time. And the problematic one is truncation to smaller size, from where |
970 | * we have to call 'simple_setsize()', which first changes @inode->i_size, then | 970 | * we have to call 'truncate_setsize()', which first changes @inode->i_size, then |
971 | * drops the truncated pages. And while dropping the pages, it takes the page | 971 | * drops the truncated pages. And while dropping the pages, it takes the page |
972 | * lock. This means that 'do_truncation()' cannot call 'simple_setsize()' with | 972 | * lock. This means that 'do_truncation()' cannot call 'truncate_setsize()' with |
973 | * @ui_mutex locked, because it would deadlock with 'ubifs_writepage()'. This | 973 | * @ui_mutex locked, because it would deadlock with 'ubifs_writepage()'. This |
974 | * means that @inode->i_size is changed while @ui_mutex is unlocked. | 974 | * means that @inode->i_size is changed while @ui_mutex is unlocked. |
975 | * | 975 | * |
976 | * XXX: with the new truncate the above is not true anymore, the simple_setsize | 976 | * XXX(truncate): with the new truncate sequence this is not true anymore, |
977 | * calls can be replaced with the individual components. | 977 | * and the calls to truncate_setsize can be move around freely. They should |
978 | * be moved to the very end of the truncate sequence. | ||
978 | * | 979 | * |
979 | * But in 'ubifs_writepage()' we have to guarantee that we do not write beyond | 980 | * But in 'ubifs_writepage()' we have to guarantee that we do not write beyond |
980 | * inode size. How do we do this if @inode->i_size may became smaller while we | 981 | * inode size. How do we do this if @inode->i_size may became smaller while we |
@@ -1128,9 +1129,7 @@ static int do_truncation(struct ubifs_info *c, struct inode *inode, | |||
1128 | budgeted = 0; | 1129 | budgeted = 0; |
1129 | } | 1130 | } |
1130 | 1131 | ||
1131 | err = simple_setsize(inode, new_size); | 1132 | truncate_setsize(inode, new_size); |
1132 | if (err) | ||
1133 | goto out_budg; | ||
1134 | 1133 | ||
1135 | if (offset) { | 1134 | if (offset) { |
1136 | pgoff_t index = new_size >> PAGE_CACHE_SHIFT; | 1135 | pgoff_t index = new_size >> PAGE_CACHE_SHIFT; |
@@ -1217,16 +1216,14 @@ static int do_setattr(struct ubifs_info *c, struct inode *inode, | |||
1217 | 1216 | ||
1218 | if (attr->ia_valid & ATTR_SIZE) { | 1217 | if (attr->ia_valid & ATTR_SIZE) { |
1219 | dbg_gen("size %lld -> %lld", inode->i_size, new_size); | 1218 | dbg_gen("size %lld -> %lld", inode->i_size, new_size); |
1220 | err = simple_setsize(inode, new_size); | 1219 | truncate_setsize(inode, new_size); |
1221 | if (err) | ||
1222 | goto out; | ||
1223 | } | 1220 | } |
1224 | 1221 | ||
1225 | mutex_lock(&ui->ui_mutex); | 1222 | mutex_lock(&ui->ui_mutex); |
1226 | if (attr->ia_valid & ATTR_SIZE) { | 1223 | if (attr->ia_valid & ATTR_SIZE) { |
1227 | /* Truncation changes inode [mc]time */ | 1224 | /* Truncation changes inode [mc]time */ |
1228 | inode->i_mtime = inode->i_ctime = ubifs_current_time(inode); | 1225 | inode->i_mtime = inode->i_ctime = ubifs_current_time(inode); |
1229 | /* 'simple_setsize()' changed @i_size, update @ui_size */ | 1226 | /* 'truncate_setsize()' changed @i_size, update @ui_size */ |
1230 | ui->ui_size = inode->i_size; | 1227 | ui->ui_size = inode->i_size; |
1231 | } | 1228 | } |
1232 | 1229 | ||
@@ -1248,10 +1245,6 @@ static int do_setattr(struct ubifs_info *c, struct inode *inode, | |||
1248 | if (IS_SYNC(inode)) | 1245 | if (IS_SYNC(inode)) |
1249 | err = inode->i_sb->s_op->write_inode(inode, NULL); | 1246 | err = inode->i_sb->s_op->write_inode(inode, NULL); |
1250 | return err; | 1247 | return err; |
1251 | |||
1252 | out: | ||
1253 | ubifs_release_budget(c, &req); | ||
1254 | return err; | ||
1255 | } | 1248 | } |
1256 | 1249 | ||
1257 | int ubifs_setattr(struct dentry *dentry, struct iattr *attr) | 1250 | int ubifs_setattr(struct dentry *dentry, struct iattr *attr) |
diff --git a/fs/ubifs/lpt.c b/fs/ubifs/lpt.c index ad7f67b827ea..0084a33c4c69 100644 --- a/fs/ubifs/lpt.c +++ b/fs/ubifs/lpt.c | |||
@@ -1457,13 +1457,13 @@ struct ubifs_lprops *ubifs_lpt_lookup(struct ubifs_info *c, int lnum) | |||
1457 | shft -= UBIFS_LPT_FANOUT_SHIFT; | 1457 | shft -= UBIFS_LPT_FANOUT_SHIFT; |
1458 | nnode = ubifs_get_nnode(c, nnode, iip); | 1458 | nnode = ubifs_get_nnode(c, nnode, iip); |
1459 | if (IS_ERR(nnode)) | 1459 | if (IS_ERR(nnode)) |
1460 | return ERR_PTR(PTR_ERR(nnode)); | 1460 | return ERR_CAST(nnode); |
1461 | } | 1461 | } |
1462 | iip = ((i >> shft) & (UBIFS_LPT_FANOUT - 1)); | 1462 | iip = ((i >> shft) & (UBIFS_LPT_FANOUT - 1)); |
1463 | shft -= UBIFS_LPT_FANOUT_SHIFT; | 1463 | shft -= UBIFS_LPT_FANOUT_SHIFT; |
1464 | pnode = ubifs_get_pnode(c, nnode, iip); | 1464 | pnode = ubifs_get_pnode(c, nnode, iip); |
1465 | if (IS_ERR(pnode)) | 1465 | if (IS_ERR(pnode)) |
1466 | return ERR_PTR(PTR_ERR(pnode)); | 1466 | return ERR_CAST(pnode); |
1467 | iip = (i & (UBIFS_LPT_FANOUT - 1)); | 1467 | iip = (i & (UBIFS_LPT_FANOUT - 1)); |
1468 | dbg_lp("LEB %d, free %d, dirty %d, flags %d", lnum, | 1468 | dbg_lp("LEB %d, free %d, dirty %d, flags %d", lnum, |
1469 | pnode->lprops[iip].free, pnode->lprops[iip].dirty, | 1469 | pnode->lprops[iip].free, pnode->lprops[iip].dirty, |
@@ -1586,7 +1586,7 @@ struct ubifs_lprops *ubifs_lpt_lookup_dirty(struct ubifs_info *c, int lnum) | |||
1586 | nnode = c->nroot; | 1586 | nnode = c->nroot; |
1587 | nnode = dirty_cow_nnode(c, nnode); | 1587 | nnode = dirty_cow_nnode(c, nnode); |
1588 | if (IS_ERR(nnode)) | 1588 | if (IS_ERR(nnode)) |
1589 | return ERR_PTR(PTR_ERR(nnode)); | 1589 | return ERR_CAST(nnode); |
1590 | i = lnum - c->main_first; | 1590 | i = lnum - c->main_first; |
1591 | shft = c->lpt_hght * UBIFS_LPT_FANOUT_SHIFT; | 1591 | shft = c->lpt_hght * UBIFS_LPT_FANOUT_SHIFT; |
1592 | for (h = 1; h < c->lpt_hght; h++) { | 1592 | for (h = 1; h < c->lpt_hght; h++) { |
@@ -1594,19 +1594,19 @@ struct ubifs_lprops *ubifs_lpt_lookup_dirty(struct ubifs_info *c, int lnum) | |||
1594 | shft -= UBIFS_LPT_FANOUT_SHIFT; | 1594 | shft -= UBIFS_LPT_FANOUT_SHIFT; |
1595 | nnode = ubifs_get_nnode(c, nnode, iip); | 1595 | nnode = ubifs_get_nnode(c, nnode, iip); |
1596 | if (IS_ERR(nnode)) | 1596 | if (IS_ERR(nnode)) |
1597 | return ERR_PTR(PTR_ERR(nnode)); | 1597 | return ERR_CAST(nnode); |
1598 | nnode = dirty_cow_nnode(c, nnode); | 1598 | nnode = dirty_cow_nnode(c, nnode); |
1599 | if (IS_ERR(nnode)) | 1599 | if (IS_ERR(nnode)) |
1600 | return ERR_PTR(PTR_ERR(nnode)); | 1600 | return ERR_CAST(nnode); |
1601 | } | 1601 | } |
1602 | iip = ((i >> shft) & (UBIFS_LPT_FANOUT - 1)); | 1602 | iip = ((i >> shft) & (UBIFS_LPT_FANOUT - 1)); |
1603 | shft -= UBIFS_LPT_FANOUT_SHIFT; | 1603 | shft -= UBIFS_LPT_FANOUT_SHIFT; |
1604 | pnode = ubifs_get_pnode(c, nnode, iip); | 1604 | pnode = ubifs_get_pnode(c, nnode, iip); |
1605 | if (IS_ERR(pnode)) | 1605 | if (IS_ERR(pnode)) |
1606 | return ERR_PTR(PTR_ERR(pnode)); | 1606 | return ERR_CAST(pnode); |
1607 | pnode = dirty_cow_pnode(c, pnode); | 1607 | pnode = dirty_cow_pnode(c, pnode); |
1608 | if (IS_ERR(pnode)) | 1608 | if (IS_ERR(pnode)) |
1609 | return ERR_PTR(PTR_ERR(pnode)); | 1609 | return ERR_CAST(pnode); |
1610 | iip = (i & (UBIFS_LPT_FANOUT - 1)); | 1610 | iip = (i & (UBIFS_LPT_FANOUT - 1)); |
1611 | dbg_lp("LEB %d, free %d, dirty %d, flags %d", lnum, | 1611 | dbg_lp("LEB %d, free %d, dirty %d, flags %d", lnum, |
1612 | pnode->lprops[iip].free, pnode->lprops[iip].dirty, | 1612 | pnode->lprops[iip].free, pnode->lprops[iip].dirty, |
diff --git a/fs/ubifs/lpt_commit.c b/fs/ubifs/lpt_commit.c index 13cb7a4237bf..d12535b7fc78 100644 --- a/fs/ubifs/lpt_commit.c +++ b/fs/ubifs/lpt_commit.c | |||
@@ -646,7 +646,7 @@ static struct ubifs_pnode *pnode_lookup(struct ubifs_info *c, int i) | |||
646 | shft -= UBIFS_LPT_FANOUT_SHIFT; | 646 | shft -= UBIFS_LPT_FANOUT_SHIFT; |
647 | nnode = ubifs_get_nnode(c, nnode, iip); | 647 | nnode = ubifs_get_nnode(c, nnode, iip); |
648 | if (IS_ERR(nnode)) | 648 | if (IS_ERR(nnode)) |
649 | return ERR_PTR(PTR_ERR(nnode)); | 649 | return ERR_CAST(nnode); |
650 | } | 650 | } |
651 | iip = ((i >> shft) & (UBIFS_LPT_FANOUT - 1)); | 651 | iip = ((i >> shft) & (UBIFS_LPT_FANOUT - 1)); |
652 | return ubifs_get_pnode(c, nnode, iip); | 652 | return ubifs_get_pnode(c, nnode, iip); |
diff --git a/fs/ubifs/recovery.c b/fs/ubifs/recovery.c index 109c6ea03bb5..daae9e1f5382 100644 --- a/fs/ubifs/recovery.c +++ b/fs/ubifs/recovery.c | |||
@@ -24,7 +24,7 @@ | |||
24 | * This file implements functions needed to recover from unclean un-mounts. | 24 | * This file implements functions needed to recover from unclean un-mounts. |
25 | * When UBIFS is mounted, it checks a flag on the master node to determine if | 25 | * When UBIFS is mounted, it checks a flag on the master node to determine if |
26 | * an un-mount was completed successfully. If not, the process of mounting | 26 | * an un-mount was completed successfully. If not, the process of mounting |
27 | * incorparates additional checking and fixing of on-flash data structures. | 27 | * incorporates additional checking and fixing of on-flash data structures. |
28 | * UBIFS always cleans away all remnants of an unclean un-mount, so that | 28 | * UBIFS always cleans away all remnants of an unclean un-mount, so that |
29 | * errors do not accumulate. However UBIFS defers recovery if it is mounted | 29 | * errors do not accumulate. However UBIFS defers recovery if it is mounted |
30 | * read-only, and the flash is not modified in that case. | 30 | * read-only, and the flash is not modified in that case. |
@@ -1063,8 +1063,21 @@ int ubifs_rcvry_gc_commit(struct ubifs_info *c) | |||
1063 | } | 1063 | } |
1064 | err = ubifs_find_dirty_leb(c, &lp, wbuf->offs, 2); | 1064 | err = ubifs_find_dirty_leb(c, &lp, wbuf->offs, 2); |
1065 | if (err) { | 1065 | if (err) { |
1066 | if (err == -ENOSPC) | 1066 | /* |
1067 | dbg_err("could not find a dirty LEB"); | 1067 | * There are no dirty or empty LEBs subject to here being |
1068 | * enough for the index. Try to use | ||
1069 | * 'ubifs_find_free_leb_for_idx()', which will return any empty | ||
1070 | * LEBs (ignoring index requirements). If the index then | ||
1071 | * doesn't have enough LEBs the recovery commit will fail - | ||
1072 | * which is the same result anyway i.e. recovery fails. So | ||
1073 | * there is no problem ignoring index requirements and just | ||
1074 | * grabbing a free LEB since we have already established there | ||
1075 | * is not a dirty LEB we could have used instead. | ||
1076 | */ | ||
1077 | if (err == -ENOSPC) { | ||
1078 | dbg_rcvry("could not find a dirty LEB"); | ||
1079 | goto find_free; | ||
1080 | } | ||
1068 | return err; | 1081 | return err; |
1069 | } | 1082 | } |
1070 | ubifs_assert(!(lp.flags & LPROPS_INDEX)); | 1083 | ubifs_assert(!(lp.flags & LPROPS_INDEX)); |
@@ -1139,8 +1152,8 @@ int ubifs_rcvry_gc_commit(struct ubifs_info *c) | |||
1139 | find_free: | 1152 | find_free: |
1140 | /* | 1153 | /* |
1141 | * There is no GC head LEB or the free space in the GC head LEB is too | 1154 | * There is no GC head LEB or the free space in the GC head LEB is too |
1142 | * small. Allocate gc_lnum by calling 'ubifs_find_free_leb_for_idx()' so | 1155 | * small, or there are not dirty LEBs. Allocate gc_lnum by calling |
1143 | * GC is not run. | 1156 | * 'ubifs_find_free_leb_for_idx()' so GC is not run. |
1144 | */ | 1157 | */ |
1145 | lnum = ubifs_find_free_leb_for_idx(c); | 1158 | lnum = ubifs_find_free_leb_for_idx(c); |
1146 | if (lnum < 0) { | 1159 | if (lnum < 0) { |
diff --git a/fs/ubifs/super.c b/fs/ubifs/super.c index 4d2f2157dd3f..cd5900b85d38 100644 --- a/fs/ubifs/super.c +++ b/fs/ubifs/super.c | |||
@@ -327,7 +327,7 @@ static int ubifs_write_inode(struct inode *inode, struct writeback_control *wbc) | |||
327 | return err; | 327 | return err; |
328 | } | 328 | } |
329 | 329 | ||
330 | static void ubifs_delete_inode(struct inode *inode) | 330 | static void ubifs_evict_inode(struct inode *inode) |
331 | { | 331 | { |
332 | int err; | 332 | int err; |
333 | struct ubifs_info *c = inode->i_sb->s_fs_info; | 333 | struct ubifs_info *c = inode->i_sb->s_fs_info; |
@@ -343,9 +343,12 @@ static void ubifs_delete_inode(struct inode *inode) | |||
343 | 343 | ||
344 | dbg_gen("inode %lu, mode %#x", inode->i_ino, (int)inode->i_mode); | 344 | dbg_gen("inode %lu, mode %#x", inode->i_ino, (int)inode->i_mode); |
345 | ubifs_assert(!atomic_read(&inode->i_count)); | 345 | ubifs_assert(!atomic_read(&inode->i_count)); |
346 | ubifs_assert(inode->i_nlink == 0); | ||
347 | 346 | ||
348 | truncate_inode_pages(&inode->i_data, 0); | 347 | truncate_inode_pages(&inode->i_data, 0); |
348 | |||
349 | if (inode->i_nlink) | ||
350 | goto done; | ||
351 | |||
349 | if (is_bad_inode(inode)) | 352 | if (is_bad_inode(inode)) |
350 | goto out; | 353 | goto out; |
351 | 354 | ||
@@ -367,7 +370,8 @@ out: | |||
367 | c->nospace = c->nospace_rp = 0; | 370 | c->nospace = c->nospace_rp = 0; |
368 | smp_wmb(); | 371 | smp_wmb(); |
369 | } | 372 | } |
370 | clear_inode(inode); | 373 | done: |
374 | end_writeback(inode); | ||
371 | } | 375 | } |
372 | 376 | ||
373 | static void ubifs_dirty_inode(struct inode *inode) | 377 | static void ubifs_dirty_inode(struct inode *inode) |
@@ -1307,6 +1311,8 @@ static int mount_ubifs(struct ubifs_info *c) | |||
1307 | if (err) | 1311 | if (err) |
1308 | goto out_orphans; | 1312 | goto out_orphans; |
1309 | err = ubifs_rcvry_gc_commit(c); | 1313 | err = ubifs_rcvry_gc_commit(c); |
1314 | if (err) | ||
1315 | goto out_orphans; | ||
1310 | } else { | 1316 | } else { |
1311 | err = take_gc_lnum(c); | 1317 | err = take_gc_lnum(c); |
1312 | if (err) | 1318 | if (err) |
@@ -1318,7 +1324,7 @@ static int mount_ubifs(struct ubifs_info *c) | |||
1318 | */ | 1324 | */ |
1319 | err = ubifs_leb_unmap(c, c->gc_lnum); | 1325 | err = ubifs_leb_unmap(c, c->gc_lnum); |
1320 | if (err) | 1326 | if (err) |
1321 | return err; | 1327 | goto out_orphans; |
1322 | } | 1328 | } |
1323 | 1329 | ||
1324 | err = dbg_check_lprops(c); | 1330 | err = dbg_check_lprops(c); |
@@ -1824,7 +1830,7 @@ const struct super_operations ubifs_super_operations = { | |||
1824 | .destroy_inode = ubifs_destroy_inode, | 1830 | .destroy_inode = ubifs_destroy_inode, |
1825 | .put_super = ubifs_put_super, | 1831 | .put_super = ubifs_put_super, |
1826 | .write_inode = ubifs_write_inode, | 1832 | .write_inode = ubifs_write_inode, |
1827 | .delete_inode = ubifs_delete_inode, | 1833 | .evict_inode = ubifs_evict_inode, |
1828 | .statfs = ubifs_statfs, | 1834 | .statfs = ubifs_statfs, |
1829 | .dirty_inode = ubifs_dirty_inode, | 1835 | .dirty_inode = ubifs_dirty_inode, |
1830 | .remount_fs = ubifs_remount_fs, | 1836 | .remount_fs = ubifs_remount_fs, |
diff --git a/fs/ubifs/ubifs.h b/fs/ubifs/ubifs.h index 04310878f449..0c9876b396dd 100644 --- a/fs/ubifs/ubifs.h +++ b/fs/ubifs/ubifs.h | |||
@@ -379,7 +379,7 @@ struct ubifs_gced_idx_leb { | |||
379 | * The @ui_size is a "shadow" variable for @inode->i_size and UBIFS uses | 379 | * The @ui_size is a "shadow" variable for @inode->i_size and UBIFS uses |
380 | * @ui_size instead of @inode->i_size. The reason for this is that UBIFS cannot | 380 | * @ui_size instead of @inode->i_size. The reason for this is that UBIFS cannot |
381 | * make sure @inode->i_size is always changed under @ui_mutex, because it | 381 | * make sure @inode->i_size is always changed under @ui_mutex, because it |
382 | * cannot call 'simple_setsize()' with @ui_mutex locked, because it would deadlock | 382 | * cannot call 'truncate_setsize()' with @ui_mutex locked, because it would deadlock |
383 | * with 'ubifs_writepage()' (see file.c). All the other inode fields are | 383 | * with 'ubifs_writepage()' (see file.c). All the other inode fields are |
384 | * changed under @ui_mutex, so they do not need "shadow" fields. Note, one | 384 | * changed under @ui_mutex, so they do not need "shadow" fields. Note, one |
385 | * could consider to rework locking and base it on "shadow" fields. | 385 | * could consider to rework locking and base it on "shadow" fields. |