diff options
| author | Linus Torvalds <torvalds@linux-foundation.org> | 2008-05-01 14:15:28 -0400 |
|---|---|---|
| committer | Linus Torvalds <torvalds@linux-foundation.org> | 2008-05-01 14:15:28 -0400 |
| commit | 2c4aabcca847ac4c92aa5e960c3f6053e1051b62 (patch) | |
| tree | 756481631c3375d6a1b07233013efa12d8aa3725 | |
| parent | bcf35afb528109a31264b45d4851fa6ae72dbe18 (diff) | |
| parent | a98889f3d8882995b5aa2255b931cf0202325cc0 (diff) | |
Merge git://git.infradead.org/mtd-2.6
* git://git.infradead.org/mtd-2.6:
[MTD][NOR] Add physical address to point() method
[JFFS2] Track parent inode for directories (for NFS export)
[JFFS2] Invert last argument of jffs2_gc_fetch_inode(), make it boolean.
[JFFS2] Quiet lockdep false positive.
[JFFS2] Clean up jffs2_alloc_inode() and jffs2_i_init_once()
[MTD] Delete long-unused jedec.h header file.
[MTD] [NAND] at91_nand: use at91_nand_{en,dis}able consistently.
| -rw-r--r-- | drivers/mtd/chips/cfi_cmdset_0001.c | 14 | ||||
| -rw-r--r-- | drivers/mtd/devices/mtdram.c | 11 | ||||
| -rw-r--r-- | drivers/mtd/devices/phram.c | 13 | ||||
| -rw-r--r-- | drivers/mtd/devices/pmc551.c | 27 | ||||
| -rw-r--r-- | drivers/mtd/devices/slram.c | 15 | ||||
| -rw-r--r-- | drivers/mtd/maps/uclinux.c | 6 | ||||
| -rw-r--r-- | drivers/mtd/mtdpart.c | 8 | ||||
| -rw-r--r-- | drivers/mtd/nand/at91_nand.c | 42 | ||||
| -rw-r--r-- | fs/jffs2/build.c | 31 | ||||
| -rw-r--r-- | fs/jffs2/dir.c | 42 | ||||
| -rw-r--r-- | fs/jffs2/erase.c | 9 | ||||
| -rw-r--r-- | fs/jffs2/fs.c | 14 | ||||
| -rw-r--r-- | fs/jffs2/gc.c | 8 | ||||
| -rw-r--r-- | fs/jffs2/nodelist.h | 5 | ||||
| -rw-r--r-- | fs/jffs2/nodemgmt.c | 2 | ||||
| -rw-r--r-- | fs/jffs2/os-linux.h | 2 | ||||
| -rw-r--r-- | fs/jffs2/readinode.c | 16 | ||||
| -rw-r--r-- | fs/jffs2/scan.c | 9 | ||||
| -rw-r--r-- | fs/jffs2/super.c | 15 | ||||
| -rw-r--r-- | fs/jffs2/wbuf.c | 2 | ||||
| -rw-r--r-- | fs/jffs2/write.c | 17 | ||||
| -rw-r--r-- | fs/jffs2/xattr.c | 4 | ||||
| -rw-r--r-- | include/linux/mtd/jedec.h | 66 | ||||
| -rw-r--r-- | include/linux/mtd/mtd.h | 6 | ||||
| -rw-r--r-- | include/linux/mtd/pmc551.h | 5 |
25 files changed, 193 insertions, 196 deletions
diff --git a/drivers/mtd/chips/cfi_cmdset_0001.c b/drivers/mtd/chips/cfi_cmdset_0001.c index e812df607a5c..fcd1aeccdf93 100644 --- a/drivers/mtd/chips/cfi_cmdset_0001.c +++ b/drivers/mtd/chips/cfi_cmdset_0001.c | |||
| @@ -82,9 +82,8 @@ static struct mtd_info *cfi_intelext_setup (struct mtd_info *); | |||
| 82 | static int cfi_intelext_partition_fixup(struct mtd_info *, struct cfi_private **); | 82 | static int cfi_intelext_partition_fixup(struct mtd_info *, struct cfi_private **); |
| 83 | 83 | ||
| 84 | static int cfi_intelext_point (struct mtd_info *mtd, loff_t from, size_t len, | 84 | static int cfi_intelext_point (struct mtd_info *mtd, loff_t from, size_t len, |
| 85 | size_t *retlen, u_char **mtdbuf); | 85 | size_t *retlen, void **virt, resource_size_t *phys); |
| 86 | static void cfi_intelext_unpoint (struct mtd_info *mtd, u_char *addr, loff_t from, | 86 | static void cfi_intelext_unpoint(struct mtd_info *mtd, loff_t from, size_t len); |
| 87 | size_t len); | ||
| 88 | 87 | ||
| 89 | static int chip_ready (struct map_info *map, struct flchip *chip, unsigned long adr, int mode); | 88 | static int chip_ready (struct map_info *map, struct flchip *chip, unsigned long adr, int mode); |
| 90 | static int get_chip(struct map_info *map, struct flchip *chip, unsigned long adr, int mode); | 89 | static int get_chip(struct map_info *map, struct flchip *chip, unsigned long adr, int mode); |
| @@ -1240,7 +1239,8 @@ static int do_point_onechip (struct map_info *map, struct flchip *chip, loff_t a | |||
| 1240 | return ret; | 1239 | return ret; |
| 1241 | } | 1240 | } |
| 1242 | 1241 | ||
| 1243 | static int cfi_intelext_point (struct mtd_info *mtd, loff_t from, size_t len, size_t *retlen, u_char **mtdbuf) | 1242 | static int cfi_intelext_point(struct mtd_info *mtd, loff_t from, size_t len, |
| 1243 | size_t *retlen, void **virt, resource_size_t *phys) | ||
| 1244 | { | 1244 | { |
| 1245 | struct map_info *map = mtd->priv; | 1245 | struct map_info *map = mtd->priv; |
| 1246 | struct cfi_private *cfi = map->fldrv_priv; | 1246 | struct cfi_private *cfi = map->fldrv_priv; |
| @@ -1257,8 +1257,10 @@ static int cfi_intelext_point (struct mtd_info *mtd, loff_t from, size_t len, si | |||
| 1257 | chipnum = (from >> cfi->chipshift); | 1257 | chipnum = (from >> cfi->chipshift); |
| 1258 | ofs = from - (chipnum << cfi->chipshift); | 1258 | ofs = from - (chipnum << cfi->chipshift); |
| 1259 | 1259 | ||
| 1260 | *mtdbuf = (void *)map->virt + cfi->chips[chipnum].start + ofs; | 1260 | *virt = map->virt + cfi->chips[chipnum].start + ofs; |
| 1261 | *retlen = 0; | 1261 | *retlen = 0; |
| 1262 | if (phys) | ||
| 1263 | *phys = map->phys + cfi->chips[chipnum].start + ofs; | ||
| 1262 | 1264 | ||
| 1263 | while (len) { | 1265 | while (len) { |
| 1264 | unsigned long thislen; | 1266 | unsigned long thislen; |
| @@ -1291,7 +1293,7 @@ static int cfi_intelext_point (struct mtd_info *mtd, loff_t from, size_t len, si | |||
| 1291 | return 0; | 1293 | return 0; |
| 1292 | } | 1294 | } |
| 1293 | 1295 | ||
| 1294 | static void cfi_intelext_unpoint (struct mtd_info *mtd, u_char *addr, loff_t from, size_t len) | 1296 | static void cfi_intelext_unpoint(struct mtd_info *mtd, loff_t from, size_t len) |
| 1295 | { | 1297 | { |
| 1296 | struct map_info *map = mtd->priv; | 1298 | struct map_info *map = mtd->priv; |
| 1297 | struct cfi_private *cfi = map->fldrv_priv; | 1299 | struct cfi_private *cfi = map->fldrv_priv; |
diff --git a/drivers/mtd/devices/mtdram.c b/drivers/mtd/devices/mtdram.c index bf485ff49457..0399be178620 100644 --- a/drivers/mtd/devices/mtdram.c +++ b/drivers/mtd/devices/mtdram.c | |||
| @@ -48,18 +48,21 @@ static int ram_erase(struct mtd_info *mtd, struct erase_info *instr) | |||
| 48 | } | 48 | } |
| 49 | 49 | ||
| 50 | static int ram_point(struct mtd_info *mtd, loff_t from, size_t len, | 50 | static int ram_point(struct mtd_info *mtd, loff_t from, size_t len, |
| 51 | size_t *retlen, u_char **mtdbuf) | 51 | size_t *retlen, void **virt, resource_size_t *phys) |
| 52 | { | 52 | { |
| 53 | if (from + len > mtd->size) | 53 | if (from + len > mtd->size) |
| 54 | return -EINVAL; | 54 | return -EINVAL; |
| 55 | 55 | ||
| 56 | *mtdbuf = mtd->priv + from; | 56 | /* can we return a physical address with this driver? */ |
| 57 | if (phys) | ||
| 58 | return -EINVAL; | ||
| 59 | |||
| 60 | *virt = mtd->priv + from; | ||
| 57 | *retlen = len; | 61 | *retlen = len; |
| 58 | return 0; | 62 | return 0; |
| 59 | } | 63 | } |
| 60 | 64 | ||
| 61 | static void ram_unpoint(struct mtd_info *mtd, u_char * addr, loff_t from, | 65 | static void ram_unpoint(struct mtd_info *mtd, loff_t from, size_t len) |
| 62 | size_t len) | ||
| 63 | { | 66 | { |
| 64 | } | 67 | } |
| 65 | 68 | ||
diff --git a/drivers/mtd/devices/phram.c b/drivers/mtd/devices/phram.c index 5f960182da95..c7987b1c5e01 100644 --- a/drivers/mtd/devices/phram.c +++ b/drivers/mtd/devices/phram.c | |||
| @@ -57,20 +57,21 @@ static int phram_erase(struct mtd_info *mtd, struct erase_info *instr) | |||
| 57 | } | 57 | } |
| 58 | 58 | ||
| 59 | static int phram_point(struct mtd_info *mtd, loff_t from, size_t len, | 59 | static int phram_point(struct mtd_info *mtd, loff_t from, size_t len, |
| 60 | size_t *retlen, u_char **mtdbuf) | 60 | size_t *retlen, void **virt, resource_size_t *phys) |
| 61 | { | 61 | { |
| 62 | u_char *start = mtd->priv; | ||
| 63 | |||
| 64 | if (from + len > mtd->size) | 62 | if (from + len > mtd->size) |
| 65 | return -EINVAL; | 63 | return -EINVAL; |
| 66 | 64 | ||
| 67 | *mtdbuf = start + from; | 65 | /* can we return a physical address with this driver? */ |
| 66 | if (phys) | ||
| 67 | return -EINVAL; | ||
| 68 | |||
| 69 | *virt = mtd->priv + from; | ||
| 68 | *retlen = len; | 70 | *retlen = len; |
| 69 | return 0; | 71 | return 0; |
| 70 | } | 72 | } |
| 71 | 73 | ||
| 72 | static void phram_unpoint(struct mtd_info *mtd, u_char *addr, loff_t from, | 74 | static void phram_unpoint(struct mtd_info *mtd, loff_t from, size_t len) |
| 73 | size_t len) | ||
| 74 | { | 75 | { |
| 75 | } | 76 | } |
| 76 | 77 | ||
diff --git a/drivers/mtd/devices/pmc551.c b/drivers/mtd/devices/pmc551.c index 7060a0895ce2..bc9981749064 100644 --- a/drivers/mtd/devices/pmc551.c +++ b/drivers/mtd/devices/pmc551.c | |||
| @@ -134,7 +134,8 @@ static int pmc551_erase(struct mtd_info *mtd, struct erase_info *instr) | |||
| 134 | eoff_lo = end & (priv->asize - 1); | 134 | eoff_lo = end & (priv->asize - 1); |
| 135 | soff_lo = instr->addr & (priv->asize - 1); | 135 | soff_lo = instr->addr & (priv->asize - 1); |
| 136 | 136 | ||
| 137 | pmc551_point(mtd, instr->addr, instr->len, &retlen, &ptr); | 137 | pmc551_point(mtd, instr->addr, instr->len, &retlen, |
| 138 | (void **)&ptr, NULL); | ||
| 138 | 139 | ||
| 139 | if (soff_hi == eoff_hi || mtd->size == priv->asize) { | 140 | if (soff_hi == eoff_hi || mtd->size == priv->asize) { |
| 140 | /* The whole thing fits within one access, so just one shot | 141 | /* The whole thing fits within one access, so just one shot |
| @@ -154,7 +155,8 @@ static int pmc551_erase(struct mtd_info *mtd, struct erase_info *instr) | |||
| 154 | } | 155 | } |
| 155 | soff_hi += priv->asize; | 156 | soff_hi += priv->asize; |
| 156 | pmc551_point(mtd, (priv->base_map0 | soff_hi), | 157 | pmc551_point(mtd, (priv->base_map0 | soff_hi), |
| 157 | priv->asize, &retlen, &ptr); | 158 | priv->asize, &retlen, |
| 159 | (void **)&ptr, NULL); | ||
| 158 | } | 160 | } |
| 159 | memset(ptr, 0xff, eoff_lo); | 161 | memset(ptr, 0xff, eoff_lo); |
| 160 | } | 162 | } |
| @@ -170,7 +172,7 @@ static int pmc551_erase(struct mtd_info *mtd, struct erase_info *instr) | |||
| 170 | } | 172 | } |
| 171 | 173 | ||
| 172 | static int pmc551_point(struct mtd_info *mtd, loff_t from, size_t len, | 174 | static int pmc551_point(struct mtd_info *mtd, loff_t from, size_t len, |
| 173 | size_t * retlen, u_char ** mtdbuf) | 175 | size_t *retlen, void **virt, resource_size_t *phys) |
| 174 | { | 176 | { |
| 175 | struct mypriv *priv = mtd->priv; | 177 | struct mypriv *priv = mtd->priv; |
| 176 | u32 soff_hi; | 178 | u32 soff_hi; |
| @@ -188,6 +190,10 @@ static int pmc551_point(struct mtd_info *mtd, loff_t from, size_t len, | |||
| 188 | return -EINVAL; | 190 | return -EINVAL; |
| 189 | } | 191 | } |
| 190 | 192 | ||
| 193 | /* can we return a physical address with this driver? */ | ||
| 194 | if (phys) | ||
| 195 | return -EINVAL; | ||
| 196 | |||
| 191 | soff_hi = from & ~(priv->asize - 1); | 197 | soff_hi = from & ~(priv->asize - 1); |
| 192 | soff_lo = from & (priv->asize - 1); | 198 | soff_lo = from & (priv->asize - 1); |
| 193 | 199 | ||
| @@ -198,13 +204,12 @@ static int pmc551_point(struct mtd_info *mtd, loff_t from, size_t len, | |||
| 198 | priv->curr_map0 = soff_hi; | 204 | priv->curr_map0 = soff_hi; |
| 199 | } | 205 | } |
| 200 | 206 | ||
| 201 | *mtdbuf = priv->start + soff_lo; | 207 | *virt = priv->start + soff_lo; |
| 202 | *retlen = len; | 208 | *retlen = len; |
| 203 | return 0; | 209 | return 0; |
| 204 | } | 210 | } |
| 205 | 211 | ||
| 206 | static void pmc551_unpoint(struct mtd_info *mtd, u_char * addr, loff_t from, | 212 | static void pmc551_unpoint(struct mtd_info *mtd, loff_t from, size_t len) |
| 207 | size_t len) | ||
| 208 | { | 213 | { |
| 209 | #ifdef CONFIG_MTD_PMC551_DEBUG | 214 | #ifdef CONFIG_MTD_PMC551_DEBUG |
| 210 | printk(KERN_DEBUG "pmc551_unpoint()\n"); | 215 | printk(KERN_DEBUG "pmc551_unpoint()\n"); |
| @@ -242,7 +247,7 @@ static int pmc551_read(struct mtd_info *mtd, loff_t from, size_t len, | |||
| 242 | soff_lo = from & (priv->asize - 1); | 247 | soff_lo = from & (priv->asize - 1); |
| 243 | eoff_lo = end & (priv->asize - 1); | 248 | eoff_lo = end & (priv->asize - 1); |
| 244 | 249 | ||
| 245 | pmc551_point(mtd, from, len, retlen, &ptr); | 250 | pmc551_point(mtd, from, len, retlen, (void **)&ptr, NULL); |
| 246 | 251 | ||
| 247 | if (soff_hi == eoff_hi) { | 252 | if (soff_hi == eoff_hi) { |
| 248 | /* The whole thing fits within one access, so just one shot | 253 | /* The whole thing fits within one access, so just one shot |
| @@ -263,7 +268,8 @@ static int pmc551_read(struct mtd_info *mtd, loff_t from, size_t len, | |||
| 263 | goto out; | 268 | goto out; |
| 264 | } | 269 | } |
| 265 | soff_hi += priv->asize; | 270 | soff_hi += priv->asize; |
| 266 | pmc551_point(mtd, soff_hi, priv->asize, retlen, &ptr); | 271 | pmc551_point(mtd, soff_hi, priv->asize, retlen, |
| 272 | (void **)&ptr, NULL); | ||
| 267 | } | 273 | } |
| 268 | memcpy(copyto, ptr, eoff_lo); | 274 | memcpy(copyto, ptr, eoff_lo); |
| 269 | copyto += eoff_lo; | 275 | copyto += eoff_lo; |
| @@ -308,7 +314,7 @@ static int pmc551_write(struct mtd_info *mtd, loff_t to, size_t len, | |||
| 308 | soff_lo = to & (priv->asize - 1); | 314 | soff_lo = to & (priv->asize - 1); |
| 309 | eoff_lo = end & (priv->asize - 1); | 315 | eoff_lo = end & (priv->asize - 1); |
| 310 | 316 | ||
| 311 | pmc551_point(mtd, to, len, retlen, &ptr); | 317 | pmc551_point(mtd, to, len, retlen, (void **)&ptr, NULL); |
| 312 | 318 | ||
| 313 | if (soff_hi == eoff_hi) { | 319 | if (soff_hi == eoff_hi) { |
| 314 | /* The whole thing fits within one access, so just one shot | 320 | /* The whole thing fits within one access, so just one shot |
| @@ -329,7 +335,8 @@ static int pmc551_write(struct mtd_info *mtd, loff_t to, size_t len, | |||
| 329 | goto out; | 335 | goto out; |
| 330 | } | 336 | } |
| 331 | soff_hi += priv->asize; | 337 | soff_hi += priv->asize; |
| 332 | pmc551_point(mtd, soff_hi, priv->asize, retlen, &ptr); | 338 | pmc551_point(mtd, soff_hi, priv->asize, retlen, |
| 339 | (void **)&ptr, NULL); | ||
| 333 | } | 340 | } |
| 334 | memcpy(ptr, copyfrom, eoff_lo); | 341 | memcpy(ptr, copyfrom, eoff_lo); |
| 335 | copyfrom += eoff_lo; | 342 | copyfrom += eoff_lo; |
diff --git a/drivers/mtd/devices/slram.c b/drivers/mtd/devices/slram.c index d293add1857c..cb86db746f28 100644 --- a/drivers/mtd/devices/slram.c +++ b/drivers/mtd/devices/slram.c | |||
| @@ -76,8 +76,9 @@ static char *map; | |||
| 76 | static slram_mtd_list_t *slram_mtdlist = NULL; | 76 | static slram_mtd_list_t *slram_mtdlist = NULL; |
| 77 | 77 | ||
| 78 | static int slram_erase(struct mtd_info *, struct erase_info *); | 78 | static int slram_erase(struct mtd_info *, struct erase_info *); |
| 79 | static int slram_point(struct mtd_info *, loff_t, size_t, size_t *, u_char **); | 79 | static int slram_point(struct mtd_info *, loff_t, size_t, size_t *, void **, |
| 80 | static void slram_unpoint(struct mtd_info *, u_char *, loff_t, size_t); | 80 | resource_size_t *); |
| 81 | static void slram_unpoint(struct mtd_info *, loff_t, size_t); | ||
| 81 | static int slram_read(struct mtd_info *, loff_t, size_t, size_t *, u_char *); | 82 | static int slram_read(struct mtd_info *, loff_t, size_t, size_t *, u_char *); |
| 82 | static int slram_write(struct mtd_info *, loff_t, size_t, size_t *, const u_char *); | 83 | static int slram_write(struct mtd_info *, loff_t, size_t, size_t *, const u_char *); |
| 83 | 84 | ||
| @@ -104,19 +105,23 @@ static int slram_erase(struct mtd_info *mtd, struct erase_info *instr) | |||
| 104 | } | 105 | } |
| 105 | 106 | ||
| 106 | static int slram_point(struct mtd_info *mtd, loff_t from, size_t len, | 107 | static int slram_point(struct mtd_info *mtd, loff_t from, size_t len, |
| 107 | size_t *retlen, u_char **mtdbuf) | 108 | size_t *retlen, void **virt, resource_size_t *phys) |
| 108 | { | 109 | { |
| 109 | slram_priv_t *priv = mtd->priv; | 110 | slram_priv_t *priv = mtd->priv; |
| 110 | 111 | ||
| 112 | /* can we return a physical address with this driver? */ | ||
| 113 | if (phys) | ||
| 114 | return -EINVAL; | ||
| 115 | |||
| 111 | if (from + len > mtd->size) | 116 | if (from + len > mtd->size) |
| 112 | return -EINVAL; | 117 | return -EINVAL; |
| 113 | 118 | ||
| 114 | *mtdbuf = priv->start + from; | 119 | *virt = priv->start + from; |
| 115 | *retlen = len; | 120 | *retlen = len; |
| 116 | return(0); | 121 | return(0); |
| 117 | } | 122 | } |
| 118 | 123 | ||
| 119 | static void slram_unpoint(struct mtd_info *mtd, u_char *addr, loff_t from, size_t len) | 124 | static void slram_unpoint(struct mtd_info *mtd, loff_t from, size_t len) |
| 120 | { | 125 | { |
| 121 | } | 126 | } |
| 122 | 127 | ||
diff --git a/drivers/mtd/maps/uclinux.c b/drivers/mtd/maps/uclinux.c index 14ffb1a9302a..c42f4b83f686 100644 --- a/drivers/mtd/maps/uclinux.c +++ b/drivers/mtd/maps/uclinux.c | |||
| @@ -40,10 +40,12 @@ struct mtd_partition uclinux_romfs[] = { | |||
| 40 | /****************************************************************************/ | 40 | /****************************************************************************/ |
| 41 | 41 | ||
| 42 | int uclinux_point(struct mtd_info *mtd, loff_t from, size_t len, | 42 | int uclinux_point(struct mtd_info *mtd, loff_t from, size_t len, |
| 43 | size_t *retlen, u_char **mtdbuf) | 43 | size_t *retlen, void **virt, resource_size_t *phys) |
| 44 | { | 44 | { |
| 45 | struct map_info *map = mtd->priv; | 45 | struct map_info *map = mtd->priv; |
| 46 | *mtdbuf = (u_char *) (map->virt + ((int) from)); | 46 | *virt = map->virt + from; |
| 47 | if (phys) | ||
| 48 | *phys = map->phys + from; | ||
| 47 | *retlen = len; | 49 | *retlen = len; |
| 48 | return(0); | 50 | return(0); |
| 49 | } | 51 | } |
diff --git a/drivers/mtd/mtdpart.c b/drivers/mtd/mtdpart.c index c66902df3171..07c701169344 100644 --- a/drivers/mtd/mtdpart.c +++ b/drivers/mtd/mtdpart.c | |||
| @@ -68,7 +68,7 @@ static int part_read (struct mtd_info *mtd, loff_t from, size_t len, | |||
| 68 | } | 68 | } |
| 69 | 69 | ||
| 70 | static int part_point (struct mtd_info *mtd, loff_t from, size_t len, | 70 | static int part_point (struct mtd_info *mtd, loff_t from, size_t len, |
| 71 | size_t *retlen, u_char **buf) | 71 | size_t *retlen, void **virt, resource_size_t *phys) |
| 72 | { | 72 | { |
| 73 | struct mtd_part *part = PART(mtd); | 73 | struct mtd_part *part = PART(mtd); |
| 74 | if (from >= mtd->size) | 74 | if (from >= mtd->size) |
| @@ -76,14 +76,14 @@ static int part_point (struct mtd_info *mtd, loff_t from, size_t len, | |||
| 76 | else if (from + len > mtd->size) | 76 | else if (from + len > mtd->size) |
| 77 | len = mtd->size - from; | 77 | len = mtd->size - from; |
| 78 | return part->master->point (part->master, from + part->offset, | 78 | return part->master->point (part->master, from + part->offset, |
| 79 | len, retlen, buf); | 79 | len, retlen, virt, phys); |
| 80 | } | 80 | } |
| 81 | 81 | ||
| 82 | static void part_unpoint (struct mtd_info *mtd, u_char *addr, loff_t from, size_t len) | 82 | static void part_unpoint(struct mtd_info *mtd, loff_t from, size_t len) |
| 83 | { | 83 | { |
| 84 | struct mtd_part *part = PART(mtd); | 84 | struct mtd_part *part = PART(mtd); |
| 85 | 85 | ||
| 86 | part->master->unpoint (part->master, addr, from + part->offset, len); | 86 | part->master->unpoint(part->master, from + part->offset, len); |
| 87 | } | 87 | } |
| 88 | 88 | ||
| 89 | static int part_read_oob(struct mtd_info *mtd, loff_t from, | 89 | static int part_read_oob(struct mtd_info *mtd, loff_t from, |
diff --git a/drivers/mtd/nand/at91_nand.c b/drivers/mtd/nand/at91_nand.c index 414ceaecdb3a..0adb287027a2 100644 --- a/drivers/mtd/nand/at91_nand.c +++ b/drivers/mtd/nand/at91_nand.c | |||
| @@ -94,6 +94,24 @@ struct at91_nand_host { | |||
| 94 | }; | 94 | }; |
| 95 | 95 | ||
| 96 | /* | 96 | /* |
| 97 | * Enable NAND. | ||
| 98 | */ | ||
| 99 | static void at91_nand_enable(struct at91_nand_host *host) | ||
| 100 | { | ||
| 101 | if (host->board->enable_pin) | ||
| 102 | at91_set_gpio_value(host->board->enable_pin, 0); | ||
| 103 | } | ||
| 104 | |||
| 105 | /* | ||
| 106 | * Disable NAND. | ||
| 107 | */ | ||
| 108 | static void at91_nand_disable(struct at91_nand_host *host) | ||
| 109 | { | ||
| 110 | if (host->board->enable_pin) | ||
| 111 | at91_set_gpio_value(host->board->enable_pin, 1); | ||
| 112 | } | ||
| 113 | |||
| 114 | /* | ||
| 97 | * Hardware specific access to control-lines | 115 | * Hardware specific access to control-lines |
| 98 | */ | 116 | */ |
| 99 | static void at91_nand_cmd_ctrl(struct mtd_info *mtd, int cmd, unsigned int ctrl) | 117 | static void at91_nand_cmd_ctrl(struct mtd_info *mtd, int cmd, unsigned int ctrl) |
| @@ -101,11 +119,11 @@ static void at91_nand_cmd_ctrl(struct mtd_info *mtd, int cmd, unsigned int ctrl) | |||
| 101 | struct nand_chip *nand_chip = mtd->priv; | 119 | struct nand_chip *nand_chip = mtd->priv; |
| 102 | struct at91_nand_host *host = nand_chip->priv; | 120 | struct at91_nand_host *host = nand_chip->priv; |
| 103 | 121 | ||
| 104 | if (host->board->enable_pin && (ctrl & NAND_CTRL_CHANGE)) { | 122 | if (ctrl & NAND_CTRL_CHANGE) { |
| 105 | if (ctrl & NAND_NCE) | 123 | if (ctrl & NAND_NCE) |
| 106 | at91_set_gpio_value(host->board->enable_pin, 0); | 124 | at91_nand_enable(host); |
| 107 | else | 125 | else |
| 108 | at91_set_gpio_value(host->board->enable_pin, 1); | 126 | at91_nand_disable(host); |
| 109 | } | 127 | } |
| 110 | if (cmd == NAND_CMD_NONE) | 128 | if (cmd == NAND_CMD_NONE) |
| 111 | return; | 129 | return; |
| @@ -128,24 +146,6 @@ static int at91_nand_device_ready(struct mtd_info *mtd) | |||
| 128 | } | 146 | } |
| 129 | 147 | ||
| 130 | /* | 148 | /* |
| 131 | * Enable NAND. | ||
| 132 | */ | ||
| 133 | static void at91_nand_enable(struct at91_nand_host *host) | ||
| 134 | { | ||
| 135 | if (host->board->enable_pin) | ||
| 136 | at91_set_gpio_value(host->board->enable_pin, 0); | ||
| 137 | } | ||
| 138 | |||
| 139 | /* | ||
| 140 | * Disable NAND. | ||
| 141 | */ | ||
| 142 | static void at91_nand_disable(struct at91_nand_host *host) | ||
| 143 | { | ||
| 144 | if (host->board->enable_pin) | ||
| 145 | at91_set_gpio_value(host->board->enable_pin, 1); | ||
| 146 | } | ||
| 147 | |||
| 148 | /* | ||
| 149 | * write oob for small pages | 149 | * write oob for small pages |
| 150 | */ | 150 | */ |
| 151 | static int at91_nand_write_oob_512(struct mtd_info *mtd, | 151 | static int at91_nand_write_oob_512(struct mtd_info *mtd, |
diff --git a/fs/jffs2/build.c b/fs/jffs2/build.c index d58f845ccb85..c5e1450d79f9 100644 --- a/fs/jffs2/build.c +++ b/fs/jffs2/build.c | |||
| @@ -46,7 +46,7 @@ next_inode(int *i, struct jffs2_inode_cache *ic, struct jffs2_sb_info *c) | |||
| 46 | 46 | ||
| 47 | 47 | ||
| 48 | static void jffs2_build_inode_pass1(struct jffs2_sb_info *c, | 48 | static void jffs2_build_inode_pass1(struct jffs2_sb_info *c, |
| 49 | struct jffs2_inode_cache *ic) | 49 | struct jffs2_inode_cache *ic) |
| 50 | { | 50 | { |
| 51 | struct jffs2_full_dirent *fd; | 51 | struct jffs2_full_dirent *fd; |
| 52 | 52 | ||
| @@ -68,11 +68,17 @@ static void jffs2_build_inode_pass1(struct jffs2_sb_info *c, | |||
| 68 | continue; | 68 | continue; |
| 69 | } | 69 | } |
| 70 | 70 | ||
| 71 | if (child_ic->nlink++ && fd->type == DT_DIR) { | 71 | if (fd->type == DT_DIR) { |
| 72 | JFFS2_ERROR("child dir \"%s\" (ino #%u) of dir ino #%u appears to be a hard link\n", | 72 | if (child_ic->pino_nlink) { |
| 73 | fd->name, fd->ino, ic->ino); | 73 | JFFS2_ERROR("child dir \"%s\" (ino #%u) of dir ino #%u appears to be a hard link\n", |
| 74 | /* TODO: What do we do about it? */ | 74 | fd->name, fd->ino, ic->ino); |
| 75 | } | 75 | /* TODO: What do we do about it? */ |
| 76 | } else { | ||
| 77 | child_ic->pino_nlink = ic->ino; | ||
| 78 | } | ||
| 79 | } else | ||
| 80 | child_ic->pino_nlink++; | ||
| 81 | |||
| 76 | dbg_fsbuild("increased nlink for child \"%s\" (ino #%u)\n", fd->name, fd->ino); | 82 | dbg_fsbuild("increased nlink for child \"%s\" (ino #%u)\n", fd->name, fd->ino); |
| 77 | /* Can't free scan_dents so far. We might need them in pass 2 */ | 83 | /* Can't free scan_dents so far. We might need them in pass 2 */ |
| 78 | } | 84 | } |
| @@ -125,7 +131,7 @@ static int jffs2_build_filesystem(struct jffs2_sb_info *c) | |||
| 125 | dbg_fsbuild("pass 2 starting\n"); | 131 | dbg_fsbuild("pass 2 starting\n"); |
| 126 | 132 | ||
| 127 | for_each_inode(i, c, ic) { | 133 | for_each_inode(i, c, ic) { |
| 128 | if (ic->nlink) | 134 | if (ic->pino_nlink) |
| 129 | continue; | 135 | continue; |
| 130 | 136 | ||
| 131 | jffs2_build_remove_unlinked_inode(c, ic, &dead_fds); | 137 | jffs2_build_remove_unlinked_inode(c, ic, &dead_fds); |
| @@ -232,16 +238,19 @@ static void jffs2_build_remove_unlinked_inode(struct jffs2_sb_info *c, | |||
| 232 | /* Reduce nlink of the child. If it's now zero, stick it on the | 238 | /* Reduce nlink of the child. If it's now zero, stick it on the |
| 233 | dead_fds list to be cleaned up later. Else just free the fd */ | 239 | dead_fds list to be cleaned up later. Else just free the fd */ |
| 234 | 240 | ||
| 235 | child_ic->nlink--; | 241 | if (fd->type == DT_DIR) |
| 242 | child_ic->pino_nlink = 0; | ||
| 243 | else | ||
| 244 | child_ic->pino_nlink--; | ||
| 236 | 245 | ||
| 237 | if (!child_ic->nlink) { | 246 | if (!child_ic->pino_nlink) { |
| 238 | dbg_fsbuild("inode #%u (\"%s\") has now got zero nlink, adding to dead_fds list.\n", | 247 | dbg_fsbuild("inode #%u (\"%s\") now has no links; adding to dead_fds list.\n", |
| 239 | fd->ino, fd->name); | 248 | fd->ino, fd->name); |
| 240 | fd->next = *dead_fds; | 249 | fd->next = *dead_fds; |
| 241 | *dead_fds = fd; | 250 | *dead_fds = fd; |
| 242 | } else { | 251 | } else { |
| 243 | dbg_fsbuild("inode #%u (\"%s\") has now got nlink %d. Ignoring.\n", | 252 | dbg_fsbuild("inode #%u (\"%s\") has now got nlink %d. Ignoring.\n", |
| 244 | fd->ino, fd->name, child_ic->nlink); | 253 | fd->ino, fd->name, child_ic->pino_nlink); |
| 245 | jffs2_free_full_dirent(fd); | 254 | jffs2_free_full_dirent(fd); |
| 246 | } | 255 | } |
| 247 | } | 256 | } |
diff --git a/fs/jffs2/dir.c b/fs/jffs2/dir.c index c63e7a96af0d..c0c141f6fde1 100644 --- a/fs/jffs2/dir.c +++ b/fs/jffs2/dir.c | |||
| @@ -208,6 +208,13 @@ static int jffs2_create(struct inode *dir_i, struct dentry *dentry, int mode, | |||
| 208 | f = JFFS2_INODE_INFO(inode); | 208 | f = JFFS2_INODE_INFO(inode); |
| 209 | dir_f = JFFS2_INODE_INFO(dir_i); | 209 | dir_f = JFFS2_INODE_INFO(dir_i); |
| 210 | 210 | ||
| 211 | /* jffs2_do_create() will want to lock it, _after_ reserving | ||
| 212 | space and taking c-alloc_sem. If we keep it locked here, | ||
| 213 | lockdep gets unhappy (although it's a false positive; | ||
| 214 | nothing else will be looking at this inode yet so there's | ||
| 215 | no chance of AB-BA deadlock involving its f->sem). */ | ||
| 216 | mutex_unlock(&f->sem); | ||
| 217 | |||
| 211 | ret = jffs2_do_create(c, dir_f, f, ri, | 218 | ret = jffs2_do_create(c, dir_f, f, ri, |
| 212 | dentry->d_name.name, dentry->d_name.len); | 219 | dentry->d_name.name, dentry->d_name.len); |
| 213 | if (ret) | 220 | if (ret) |
| @@ -219,7 +226,8 @@ static int jffs2_create(struct inode *dir_i, struct dentry *dentry, int mode, | |||
| 219 | d_instantiate(dentry, inode); | 226 | d_instantiate(dentry, inode); |
| 220 | 227 | ||
| 221 | D1(printk(KERN_DEBUG "jffs2_create: Created ino #%lu with mode %o, nlink %d(%d). nrpages %ld\n", | 228 | D1(printk(KERN_DEBUG "jffs2_create: Created ino #%lu with mode %o, nlink %d(%d). nrpages %ld\n", |
| 222 | inode->i_ino, inode->i_mode, inode->i_nlink, f->inocache->nlink, inode->i_mapping->nrpages)); | 229 | inode->i_ino, inode->i_mode, inode->i_nlink, |
| 230 | f->inocache->pino_nlink, inode->i_mapping->nrpages)); | ||
| 223 | return 0; | 231 | return 0; |
| 224 | 232 | ||
| 225 | fail: | 233 | fail: |
| @@ -243,7 +251,7 @@ static int jffs2_unlink(struct inode *dir_i, struct dentry *dentry) | |||
| 243 | ret = jffs2_do_unlink(c, dir_f, dentry->d_name.name, | 251 | ret = jffs2_do_unlink(c, dir_f, dentry->d_name.name, |
| 244 | dentry->d_name.len, dead_f, now); | 252 | dentry->d_name.len, dead_f, now); |
| 245 | if (dead_f->inocache) | 253 | if (dead_f->inocache) |
| 246 | dentry->d_inode->i_nlink = dead_f->inocache->nlink; | 254 | dentry->d_inode->i_nlink = dead_f->inocache->pino_nlink; |
| 247 | if (!ret) | 255 | if (!ret) |
| 248 | dir_i->i_mtime = dir_i->i_ctime = ITIME(now); | 256 | dir_i->i_mtime = dir_i->i_ctime = ITIME(now); |
| 249 | return ret; | 257 | return ret; |
| @@ -276,7 +284,7 @@ static int jffs2_link (struct dentry *old_dentry, struct inode *dir_i, struct de | |||
| 276 | 284 | ||
| 277 | if (!ret) { | 285 | if (!ret) { |
| 278 | mutex_lock(&f->sem); | 286 | mutex_lock(&f->sem); |
| 279 | old_dentry->d_inode->i_nlink = ++f->inocache->nlink; | 287 | old_dentry->d_inode->i_nlink = ++f->inocache->pino_nlink; |
| 280 | mutex_unlock(&f->sem); | 288 | mutex_unlock(&f->sem); |
| 281 | d_instantiate(dentry, old_dentry->d_inode); | 289 | d_instantiate(dentry, old_dentry->d_inode); |
| 282 | dir_i->i_mtime = dir_i->i_ctime = ITIME(now); | 290 | dir_i->i_mtime = dir_i->i_ctime = ITIME(now); |
| @@ -493,11 +501,14 @@ static int jffs2_mkdir (struct inode *dir_i, struct dentry *dentry, int mode) | |||
| 493 | 501 | ||
| 494 | inode->i_op = &jffs2_dir_inode_operations; | 502 | inode->i_op = &jffs2_dir_inode_operations; |
| 495 | inode->i_fop = &jffs2_dir_operations; | 503 | inode->i_fop = &jffs2_dir_operations; |
| 496 | /* Directories get nlink 2 at start */ | ||
| 497 | inode->i_nlink = 2; | ||
| 498 | 504 | ||
| 499 | f = JFFS2_INODE_INFO(inode); | 505 | f = JFFS2_INODE_INFO(inode); |
| 500 | 506 | ||
| 507 | /* Directories get nlink 2 at start */ | ||
| 508 | inode->i_nlink = 2; | ||
| 509 | /* but ic->pino_nlink is the parent ino# */ | ||
| 510 | f->inocache->pino_nlink = dir_i->i_ino; | ||
| 511 | |||
| 501 | ri->data_crc = cpu_to_je32(0); | 512 | ri->data_crc = cpu_to_je32(0); |
| 502 | ri->node_crc = cpu_to_je32(crc32(0, ri, sizeof(*ri)-8)); | 513 | ri->node_crc = cpu_to_je32(crc32(0, ri, sizeof(*ri)-8)); |
| 503 | 514 | ||
| @@ -594,17 +605,25 @@ static int jffs2_mkdir (struct inode *dir_i, struct dentry *dentry, int mode) | |||
| 594 | 605 | ||
| 595 | static int jffs2_rmdir (struct inode *dir_i, struct dentry *dentry) | 606 | static int jffs2_rmdir (struct inode *dir_i, struct dentry *dentry) |
| 596 | { | 607 | { |
| 608 | struct jffs2_sb_info *c = JFFS2_SB_INFO(dir_i->i_sb); | ||
| 609 | struct jffs2_inode_info *dir_f = JFFS2_INODE_INFO(dir_i); | ||
| 597 | struct jffs2_inode_info *f = JFFS2_INODE_INFO(dentry->d_inode); | 610 | struct jffs2_inode_info *f = JFFS2_INODE_INFO(dentry->d_inode); |
| 598 | struct jffs2_full_dirent *fd; | 611 | struct jffs2_full_dirent *fd; |
| 599 | int ret; | 612 | int ret; |
| 613 | uint32_t now = get_seconds(); | ||
| 600 | 614 | ||
| 601 | for (fd = f->dents ; fd; fd = fd->next) { | 615 | for (fd = f->dents ; fd; fd = fd->next) { |
| 602 | if (fd->ino) | 616 | if (fd->ino) |
| 603 | return -ENOTEMPTY; | 617 | return -ENOTEMPTY; |
| 604 | } | 618 | } |
| 605 | ret = jffs2_unlink(dir_i, dentry); | 619 | |
| 606 | if (!ret) | 620 | ret = jffs2_do_unlink(c, dir_f, dentry->d_name.name, |
| 621 | dentry->d_name.len, f, now); | ||
| 622 | if (!ret) { | ||
| 623 | dir_i->i_mtime = dir_i->i_ctime = ITIME(now); | ||
| 624 | clear_nlink(dentry->d_inode); | ||
| 607 | drop_nlink(dir_i); | 625 | drop_nlink(dir_i); |
| 626 | } | ||
| 608 | return ret; | 627 | return ret; |
| 609 | } | 628 | } |
| 610 | 629 | ||
| @@ -817,7 +836,10 @@ static int jffs2_rename (struct inode *old_dir_i, struct dentry *old_dentry, | |||
| 817 | inode which didn't exist. */ | 836 | inode which didn't exist. */ |
| 818 | if (victim_f->inocache) { | 837 | if (victim_f->inocache) { |
| 819 | mutex_lock(&victim_f->sem); | 838 | mutex_lock(&victim_f->sem); |
| 820 | victim_f->inocache->nlink--; | 839 | if (S_ISDIR(new_dentry->d_inode->i_mode)) |
| 840 | victim_f->inocache->pino_nlink = 0; | ||
| 841 | else | ||
| 842 | victim_f->inocache->pino_nlink--; | ||
| 821 | mutex_unlock(&victim_f->sem); | 843 | mutex_unlock(&victim_f->sem); |
| 822 | } | 844 | } |
| 823 | } | 845 | } |
| @@ -838,8 +860,8 @@ static int jffs2_rename (struct inode *old_dir_i, struct dentry *old_dentry, | |||
| 838 | struct jffs2_inode_info *f = JFFS2_INODE_INFO(old_dentry->d_inode); | 860 | struct jffs2_inode_info *f = JFFS2_INODE_INFO(old_dentry->d_inode); |
| 839 | mutex_lock(&f->sem); | 861 | mutex_lock(&f->sem); |
| 840 | inc_nlink(old_dentry->d_inode); | 862 | inc_nlink(old_dentry->d_inode); |
| 841 | if (f->inocache) | 863 | if (f->inocache && !S_ISDIR(old_dentry->d_inode->i_mode)) |
| 842 | f->inocache->nlink++; | 864 | f->inocache->pino_nlink++; |
| 843 | mutex_unlock(&f->sem); | 865 | mutex_unlock(&f->sem); |
| 844 | 866 | ||
| 845 | printk(KERN_NOTICE "jffs2_rename(): Link succeeded, unlink failed (err %d). You now have a hard link\n", ret); | 867 | printk(KERN_NOTICE "jffs2_rename(): Link succeeded, unlink failed (err %d). You now have a hard link\n", ret); |
diff --git a/fs/jffs2/erase.c b/fs/jffs2/erase.c index 25a640e566d3..dddb2a6c9e2c 100644 --- a/fs/jffs2/erase.c +++ b/fs/jffs2/erase.c | |||
| @@ -294,7 +294,7 @@ static inline void jffs2_remove_node_refs_from_ino_list(struct jffs2_sb_info *c, | |||
| 294 | break; | 294 | break; |
| 295 | #endif | 295 | #endif |
| 296 | default: | 296 | default: |
| 297 | if (ic->nodes == (void *)ic && ic->nlink == 0) | 297 | if (ic->nodes == (void *)ic && ic->pino_nlink == 0) |
| 298 | jffs2_del_ino_cache(c, ic); | 298 | jffs2_del_ino_cache(c, ic); |
| 299 | } | 299 | } |
| 300 | } | 300 | } |
| @@ -332,7 +332,8 @@ static int jffs2_block_check_erase(struct jffs2_sb_info *c, struct jffs2_erasebl | |||
| 332 | if (c->mtd->point) { | 332 | if (c->mtd->point) { |
| 333 | unsigned long *wordebuf; | 333 | unsigned long *wordebuf; |
| 334 | 334 | ||
| 335 | ret = c->mtd->point(c->mtd, jeb->offset, c->sector_size, &retlen, (unsigned char **)&ebuf); | 335 | ret = c->mtd->point(c->mtd, jeb->offset, c->sector_size, |
| 336 | &retlen, &ebuf, NULL); | ||
| 336 | if (ret) { | 337 | if (ret) { |
| 337 | D1(printk(KERN_DEBUG "MTD point failed %d\n", ret)); | 338 | D1(printk(KERN_DEBUG "MTD point failed %d\n", ret)); |
| 338 | goto do_flash_read; | 339 | goto do_flash_read; |
| @@ -340,7 +341,7 @@ static int jffs2_block_check_erase(struct jffs2_sb_info *c, struct jffs2_erasebl | |||
| 340 | if (retlen < c->sector_size) { | 341 | if (retlen < c->sector_size) { |
| 341 | /* Don't muck about if it won't let us point to the whole erase sector */ | 342 | /* Don't muck about if it won't let us point to the whole erase sector */ |
| 342 | D1(printk(KERN_DEBUG "MTD point returned len too short: 0x%zx\n", retlen)); | 343 | D1(printk(KERN_DEBUG "MTD point returned len too short: 0x%zx\n", retlen)); |
| 343 | c->mtd->unpoint(c->mtd, ebuf, jeb->offset, retlen); | 344 | c->mtd->unpoint(c->mtd, jeb->offset, retlen); |
| 344 | goto do_flash_read; | 345 | goto do_flash_read; |
| 345 | } | 346 | } |
| 346 | wordebuf = ebuf-sizeof(*wordebuf); | 347 | wordebuf = ebuf-sizeof(*wordebuf); |
| @@ -349,7 +350,7 @@ static int jffs2_block_check_erase(struct jffs2_sb_info *c, struct jffs2_erasebl | |||
| 349 | if (*++wordebuf != ~0) | 350 | if (*++wordebuf != ~0) |
| 350 | break; | 351 | break; |
| 351 | } while(--retlen); | 352 | } while(--retlen); |
| 352 | c->mtd->unpoint(c->mtd, ebuf, jeb->offset, c->sector_size); | 353 | c->mtd->unpoint(c->mtd, jeb->offset, c->sector_size); |
| 353 | if (retlen) { | 354 | if (retlen) { |
| 354 | printk(KERN_WARNING "Newly-erased block contained word 0x%lx at offset 0x%08tx\n", | 355 | printk(KERN_WARNING "Newly-erased block contained word 0x%lx at offset 0x%08tx\n", |
| 355 | *wordebuf, jeb->offset + c->sector_size-retlen*sizeof(*wordebuf)); | 356 | *wordebuf, jeb->offset + c->sector_size-retlen*sizeof(*wordebuf)); |
diff --git a/fs/jffs2/fs.c b/fs/jffs2/fs.c index 3eb1c84b0a33..086c43830221 100644 --- a/fs/jffs2/fs.c +++ b/fs/jffs2/fs.c | |||
| @@ -273,7 +273,7 @@ struct inode *jffs2_iget(struct super_block *sb, unsigned long ino) | |||
| 273 | inode->i_mtime = ITIME(je32_to_cpu(latest_node.mtime)); | 273 | inode->i_mtime = ITIME(je32_to_cpu(latest_node.mtime)); |
| 274 | inode->i_ctime = ITIME(je32_to_cpu(latest_node.ctime)); | 274 | inode->i_ctime = ITIME(je32_to_cpu(latest_node.ctime)); |
| 275 | 275 | ||
| 276 | inode->i_nlink = f->inocache->nlink; | 276 | inode->i_nlink = f->inocache->pino_nlink; |
| 277 | 277 | ||
| 278 | inode->i_blocks = (inode->i_size + 511) >> 9; | 278 | inode->i_blocks = (inode->i_size + 511) >> 9; |
| 279 | 279 | ||
| @@ -286,13 +286,12 @@ struct inode *jffs2_iget(struct super_block *sb, unsigned long ino) | |||
| 286 | case S_IFDIR: | 286 | case S_IFDIR: |
| 287 | { | 287 | { |
| 288 | struct jffs2_full_dirent *fd; | 288 | struct jffs2_full_dirent *fd; |
| 289 | inode->i_nlink = 2; /* parent and '.' */ | ||
| 289 | 290 | ||
| 290 | for (fd=f->dents; fd; fd = fd->next) { | 291 | for (fd=f->dents; fd; fd = fd->next) { |
| 291 | if (fd->type == DT_DIR && fd->ino) | 292 | if (fd->type == DT_DIR && fd->ino) |
| 292 | inc_nlink(inode); | 293 | inc_nlink(inode); |
| 293 | } | 294 | } |
| 294 | /* and '..' */ | ||
| 295 | inc_nlink(inode); | ||
| 296 | /* Root dir gets i_nlink 3 for some reason */ | 295 | /* Root dir gets i_nlink 3 for some reason */ |
| 297 | if (inode->i_ino == 1) | 296 | if (inode->i_ino == 1) |
| 298 | inc_nlink(inode); | 297 | inc_nlink(inode); |
| @@ -586,11 +585,12 @@ void jffs2_gc_release_inode(struct jffs2_sb_info *c, | |||
| 586 | } | 585 | } |
| 587 | 586 | ||
| 588 | struct jffs2_inode_info *jffs2_gc_fetch_inode(struct jffs2_sb_info *c, | 587 | struct jffs2_inode_info *jffs2_gc_fetch_inode(struct jffs2_sb_info *c, |
| 589 | int inum, int nlink) | 588 | int inum, int unlinked) |
| 590 | { | 589 | { |
| 591 | struct inode *inode; | 590 | struct inode *inode; |
| 592 | struct jffs2_inode_cache *ic; | 591 | struct jffs2_inode_cache *ic; |
| 593 | if (!nlink) { | 592 | |
| 593 | if (unlinked) { | ||
| 594 | /* The inode has zero nlink but its nodes weren't yet marked | 594 | /* The inode has zero nlink but its nodes weren't yet marked |
| 595 | obsolete. This has to be because we're still waiting for | 595 | obsolete. This has to be because we're still waiting for |
| 596 | the final (close() and) iput() to happen. | 596 | the final (close() and) iput() to happen. |
| @@ -638,8 +638,8 @@ struct jffs2_inode_info *jffs2_gc_fetch_inode(struct jffs2_sb_info *c, | |||
| 638 | return ERR_CAST(inode); | 638 | return ERR_CAST(inode); |
| 639 | } | 639 | } |
| 640 | if (is_bad_inode(inode)) { | 640 | if (is_bad_inode(inode)) { |
| 641 | printk(KERN_NOTICE "Eep. read_inode() failed for ino #%u. nlink %d\n", | 641 | printk(KERN_NOTICE "Eep. read_inode() failed for ino #%u. unlinked %d\n", |
| 642 | inum, nlink); | 642 | inum, unlinked); |
| 643 | /* NB. This will happen again. We need to do something appropriate here. */ | 643 | /* NB. This will happen again. We need to do something appropriate here. */ |
| 644 | iput(inode); | 644 | iput(inode); |
| 645 | return ERR_PTR(-EIO); | 645 | return ERR_PTR(-EIO); |
diff --git a/fs/jffs2/gc.c b/fs/jffs2/gc.c index bad005664e30..090c556ffed2 100644 --- a/fs/jffs2/gc.c +++ b/fs/jffs2/gc.c | |||
| @@ -161,8 +161,8 @@ int jffs2_garbage_collect_pass(struct jffs2_sb_info *c) | |||
| 161 | continue; | 161 | continue; |
| 162 | } | 162 | } |
| 163 | 163 | ||
| 164 | if (!ic->nlink) { | 164 | if (!ic->pino_nlink) { |
| 165 | D1(printk(KERN_DEBUG "Skipping check of ino #%d with nlink zero\n", | 165 | D1(printk(KERN_DEBUG "Skipping check of ino #%d with nlink/pino zero\n", |
| 166 | ic->ino)); | 166 | ic->ino)); |
| 167 | spin_unlock(&c->inocache_lock); | 167 | spin_unlock(&c->inocache_lock); |
| 168 | jffs2_xattr_delete_inode(c, ic); | 168 | jffs2_xattr_delete_inode(c, ic); |
| @@ -398,10 +398,10 @@ int jffs2_garbage_collect_pass(struct jffs2_sb_info *c) | |||
| 398 | it's vaguely possible. */ | 398 | it's vaguely possible. */ |
| 399 | 399 | ||
| 400 | inum = ic->ino; | 400 | inum = ic->ino; |
| 401 | nlink = ic->nlink; | 401 | nlink = ic->pino_nlink; |
| 402 | spin_unlock(&c->inocache_lock); | 402 | spin_unlock(&c->inocache_lock); |
| 403 | 403 | ||
| 404 | f = jffs2_gc_fetch_inode(c, inum, nlink); | 404 | f = jffs2_gc_fetch_inode(c, inum, !nlink); |
| 405 | if (IS_ERR(f)) { | 405 | if (IS_ERR(f)) { |
| 406 | ret = PTR_ERR(f); | 406 | ret = PTR_ERR(f); |
| 407 | goto release_sem; | 407 | goto release_sem; |
diff --git a/fs/jffs2/nodelist.h b/fs/jffs2/nodelist.h index 8219df6eb6d8..1750445556c3 100644 --- a/fs/jffs2/nodelist.h +++ b/fs/jffs2/nodelist.h | |||
| @@ -177,7 +177,10 @@ struct jffs2_inode_cache { | |||
| 177 | #ifdef CONFIG_JFFS2_FS_XATTR | 177 | #ifdef CONFIG_JFFS2_FS_XATTR |
| 178 | struct jffs2_xattr_ref *xref; | 178 | struct jffs2_xattr_ref *xref; |
| 179 | #endif | 179 | #endif |
| 180 | int nlink; | 180 | uint32_t pino_nlink; /* Directories store parent inode |
| 181 | here; other inodes store nlink. | ||
| 182 | Zero always means that it's | ||
| 183 | completely unlinked. */ | ||
| 181 | }; | 184 | }; |
| 182 | 185 | ||
| 183 | /* Inode states for 'state' above. We need the 'GC' state to prevent | 186 | /* Inode states for 'state' above. We need the 'GC' state to prevent |
diff --git a/fs/jffs2/nodemgmt.c b/fs/jffs2/nodemgmt.c index 9df8f3ef20df..a9bf9603c1ba 100644 --- a/fs/jffs2/nodemgmt.c +++ b/fs/jffs2/nodemgmt.c | |||
| @@ -709,7 +709,7 @@ void jffs2_mark_node_obsolete(struct jffs2_sb_info *c, struct jffs2_raw_node_ref | |||
| 709 | break; | 709 | break; |
| 710 | #endif | 710 | #endif |
| 711 | default: | 711 | default: |
| 712 | if (ic->nodes == (void *)ic && ic->nlink == 0) | 712 | if (ic->nodes == (void *)ic && ic->pino_nlink == 0) |
| 713 | jffs2_del_ino_cache(c, ic); | 713 | jffs2_del_ino_cache(c, ic); |
| 714 | break; | 714 | break; |
| 715 | } | 715 | } |
diff --git a/fs/jffs2/os-linux.h b/fs/jffs2/os-linux.h index 1b10d2594092..2cc866cf134f 100644 --- a/fs/jffs2/os-linux.h +++ b/fs/jffs2/os-linux.h | |||
| @@ -187,7 +187,7 @@ int jffs2_do_fill_super(struct super_block *sb, void *data, int silent); | |||
| 187 | void jffs2_gc_release_inode(struct jffs2_sb_info *c, | 187 | void jffs2_gc_release_inode(struct jffs2_sb_info *c, |
| 188 | struct jffs2_inode_info *f); | 188 | struct jffs2_inode_info *f); |
| 189 | struct jffs2_inode_info *jffs2_gc_fetch_inode(struct jffs2_sb_info *c, | 189 | struct jffs2_inode_info *jffs2_gc_fetch_inode(struct jffs2_sb_info *c, |
| 190 | int inum, int nlink); | 190 | int inum, int unlinked); |
| 191 | 191 | ||
| 192 | unsigned char *jffs2_gc_fetch_page(struct jffs2_sb_info *c, | 192 | unsigned char *jffs2_gc_fetch_page(struct jffs2_sb_info *c, |
| 193 | struct jffs2_inode_info *f, | 193 | struct jffs2_inode_info *f, |
diff --git a/fs/jffs2/readinode.c b/fs/jffs2/readinode.c index 4cb4d76de07f..6ca08ad887c0 100644 --- a/fs/jffs2/readinode.c +++ b/fs/jffs2/readinode.c | |||
| @@ -63,10 +63,11 @@ static int check_node_data(struct jffs2_sb_info *c, struct jffs2_tmp_dnode_info | |||
| 63 | /* TODO: instead, incapsulate point() stuff to jffs2_flash_read(), | 63 | /* TODO: instead, incapsulate point() stuff to jffs2_flash_read(), |
| 64 | * adding and jffs2_flash_read_end() interface. */ | 64 | * adding and jffs2_flash_read_end() interface. */ |
| 65 | if (c->mtd->point) { | 65 | if (c->mtd->point) { |
| 66 | err = c->mtd->point(c->mtd, ofs, len, &retlen, &buffer); | 66 | err = c->mtd->point(c->mtd, ofs, len, &retlen, |
| 67 | (void **)&buffer, NULL); | ||
| 67 | if (!err && retlen < len) { | 68 | if (!err && retlen < len) { |
| 68 | JFFS2_WARNING("MTD point returned len too short: %zu instead of %u.\n", retlen, tn->csize); | 69 | JFFS2_WARNING("MTD point returned len too short: %zu instead of %u.\n", retlen, tn->csize); |
| 69 | c->mtd->unpoint(c->mtd, buffer, ofs, retlen); | 70 | c->mtd->unpoint(c->mtd, ofs, retlen); |
| 70 | } else if (err) | 71 | } else if (err) |
| 71 | JFFS2_WARNING("MTD point failed: error code %d.\n", err); | 72 | JFFS2_WARNING("MTD point failed: error code %d.\n", err); |
| 72 | else | 73 | else |
| @@ -100,7 +101,7 @@ static int check_node_data(struct jffs2_sb_info *c, struct jffs2_tmp_dnode_info | |||
| 100 | kfree(buffer); | 101 | kfree(buffer); |
| 101 | #ifndef __ECOS | 102 | #ifndef __ECOS |
| 102 | else | 103 | else |
| 103 | c->mtd->unpoint(c->mtd, buffer, ofs, len); | 104 | c->mtd->unpoint(c->mtd, ofs, len); |
| 104 | #endif | 105 | #endif |
| 105 | 106 | ||
| 106 | if (crc != tn->data_crc) { | 107 | if (crc != tn->data_crc) { |
| @@ -136,7 +137,7 @@ free_out: | |||
| 136 | kfree(buffer); | 137 | kfree(buffer); |
| 137 | #ifndef __ECOS | 138 | #ifndef __ECOS |
| 138 | else | 139 | else |
| 139 | c->mtd->unpoint(c->mtd, buffer, ofs, len); | 140 | c->mtd->unpoint(c->mtd, ofs, len); |
| 140 | #endif | 141 | #endif |
| 141 | return err; | 142 | return err; |
| 142 | } | 143 | } |
| @@ -1123,7 +1124,8 @@ static int jffs2_do_read_inode_internal(struct jffs2_sb_info *c, | |||
| 1123 | size_t retlen; | 1124 | size_t retlen; |
| 1124 | int ret; | 1125 | int ret; |
| 1125 | 1126 | ||
| 1126 | dbg_readinode("ino #%u nlink is %d\n", f->inocache->ino, f->inocache->nlink); | 1127 | dbg_readinode("ino #%u pino/nlink is %d\n", f->inocache->ino, |
| 1128 | f->inocache->pino_nlink); | ||
| 1127 | 1129 | ||
| 1128 | memset(&rii, 0, sizeof(rii)); | 1130 | memset(&rii, 0, sizeof(rii)); |
| 1129 | 1131 | ||
| @@ -1358,7 +1360,7 @@ int jffs2_do_read_inode(struct jffs2_sb_info *c, struct jffs2_inode_info *f, | |||
| 1358 | } | 1360 | } |
| 1359 | dbg_readinode("creating inocache for root inode\n"); | 1361 | dbg_readinode("creating inocache for root inode\n"); |
| 1360 | memset(f->inocache, 0, sizeof(struct jffs2_inode_cache)); | 1362 | memset(f->inocache, 0, sizeof(struct jffs2_inode_cache)); |
| 1361 | f->inocache->ino = f->inocache->nlink = 1; | 1363 | f->inocache->ino = f->inocache->pino_nlink = 1; |
| 1362 | f->inocache->nodes = (struct jffs2_raw_node_ref *)f->inocache; | 1364 | f->inocache->nodes = (struct jffs2_raw_node_ref *)f->inocache; |
| 1363 | f->inocache->state = INO_STATE_READING; | 1365 | f->inocache->state = INO_STATE_READING; |
| 1364 | jffs2_add_ino_cache(c, f->inocache); | 1366 | jffs2_add_ino_cache(c, f->inocache); |
| @@ -1401,7 +1403,7 @@ void jffs2_do_clear_inode(struct jffs2_sb_info *c, struct jffs2_inode_info *f) | |||
| 1401 | jffs2_clear_acl(f); | 1403 | jffs2_clear_acl(f); |
| 1402 | jffs2_xattr_delete_inode(c, f->inocache); | 1404 | jffs2_xattr_delete_inode(c, f->inocache); |
| 1403 | mutex_lock(&f->sem); | 1405 | mutex_lock(&f->sem); |
| 1404 | deleted = f->inocache && !f->inocache->nlink; | 1406 | deleted = f->inocache && !f->inocache->pino_nlink; |
| 1405 | 1407 | ||
| 1406 | if (f->inocache && f->inocache->state != INO_STATE_CHECKING) | 1408 | if (f->inocache && f->inocache->state != INO_STATE_CHECKING) |
| 1407 | jffs2_set_inocache_state(c, f->inocache, INO_STATE_CLEARING); | 1409 | jffs2_set_inocache_state(c, f->inocache, INO_STATE_CLEARING); |
diff --git a/fs/jffs2/scan.c b/fs/jffs2/scan.c index 272872d27fd5..1d437de1e9a8 100644 --- a/fs/jffs2/scan.c +++ b/fs/jffs2/scan.c | |||
| @@ -97,11 +97,12 @@ int jffs2_scan_medium(struct jffs2_sb_info *c) | |||
| 97 | size_t pointlen; | 97 | size_t pointlen; |
| 98 | 98 | ||
| 99 | if (c->mtd->point) { | 99 | if (c->mtd->point) { |
| 100 | ret = c->mtd->point (c->mtd, 0, c->mtd->size, &pointlen, &flashbuf); | 100 | ret = c->mtd->point(c->mtd, 0, c->mtd->size, &pointlen, |
| 101 | (void **)&flashbuf, NULL); | ||
| 101 | if (!ret && pointlen < c->mtd->size) { | 102 | if (!ret && pointlen < c->mtd->size) { |
| 102 | /* Don't muck about if it won't let us point to the whole flash */ | 103 | /* Don't muck about if it won't let us point to the whole flash */ |
| 103 | D1(printk(KERN_DEBUG "MTD point returned len too short: 0x%zx\n", pointlen)); | 104 | D1(printk(KERN_DEBUG "MTD point returned len too short: 0x%zx\n", pointlen)); |
| 104 | c->mtd->unpoint(c->mtd, flashbuf, 0, pointlen); | 105 | c->mtd->unpoint(c->mtd, 0, pointlen); |
| 105 | flashbuf = NULL; | 106 | flashbuf = NULL; |
| 106 | } | 107 | } |
| 107 | if (ret) | 108 | if (ret) |
| @@ -267,7 +268,7 @@ int jffs2_scan_medium(struct jffs2_sb_info *c) | |||
| 267 | kfree(flashbuf); | 268 | kfree(flashbuf); |
| 268 | #ifndef __ECOS | 269 | #ifndef __ECOS |
| 269 | else | 270 | else |
| 270 | c->mtd->unpoint(c->mtd, flashbuf, 0, c->mtd->size); | 271 | c->mtd->unpoint(c->mtd, 0, c->mtd->size); |
| 271 | #endif | 272 | #endif |
| 272 | if (s) | 273 | if (s) |
| 273 | kfree(s); | 274 | kfree(s); |
| @@ -940,7 +941,7 @@ struct jffs2_inode_cache *jffs2_scan_make_ino_cache(struct jffs2_sb_info *c, uin | |||
| 940 | ic->nodes = (void *)ic; | 941 | ic->nodes = (void *)ic; |
| 941 | jffs2_add_ino_cache(c, ic); | 942 | jffs2_add_ino_cache(c, ic); |
| 942 | if (ino == 1) | 943 | if (ino == 1) |
| 943 | ic->nlink = 1; | 944 | ic->pino_nlink = 1; |
| 944 | return ic; | 945 | return ic; |
| 945 | } | 946 | } |
| 946 | 947 | ||
diff --git a/fs/jffs2/super.c b/fs/jffs2/super.c index f3353df178e7..7da69eae49e4 100644 --- a/fs/jffs2/super.c +++ b/fs/jffs2/super.c | |||
| @@ -31,11 +31,12 @@ static struct kmem_cache *jffs2_inode_cachep; | |||
| 31 | 31 | ||
| 32 | static struct inode *jffs2_alloc_inode(struct super_block *sb) | 32 | static struct inode *jffs2_alloc_inode(struct super_block *sb) |
| 33 | { | 33 | { |
| 34 | struct jffs2_inode_info *ei; | 34 | struct jffs2_inode_info *f; |
| 35 | ei = (struct jffs2_inode_info *)kmem_cache_alloc(jffs2_inode_cachep, GFP_KERNEL); | 35 | |
| 36 | if (!ei) | 36 | f = kmem_cache_alloc(jffs2_inode_cachep, GFP_KERNEL); |
| 37 | if (!f) | ||
| 37 | return NULL; | 38 | return NULL; |
| 38 | return &ei->vfs_inode; | 39 | return &f->vfs_inode; |
| 39 | } | 40 | } |
| 40 | 41 | ||
| 41 | static void jffs2_destroy_inode(struct inode *inode) | 42 | static void jffs2_destroy_inode(struct inode *inode) |
| @@ -45,10 +46,10 @@ static void jffs2_destroy_inode(struct inode *inode) | |||
| 45 | 46 | ||
| 46 | static void jffs2_i_init_once(struct kmem_cache *cachep, void *foo) | 47 | static void jffs2_i_init_once(struct kmem_cache *cachep, void *foo) |
| 47 | { | 48 | { |
| 48 | struct jffs2_inode_info *ei = (struct jffs2_inode_info *) foo; | 49 | struct jffs2_inode_info *f = foo; |
| 49 | 50 | ||
| 50 | mutex_init(&ei->sem); | 51 | mutex_init(&f->sem); |
| 51 | inode_init_once(&ei->vfs_inode); | 52 | inode_init_once(&f->vfs_inode); |
| 52 | } | 53 | } |
| 53 | 54 | ||
| 54 | static int jffs2_sync_fs(struct super_block *sb, int wait) | 55 | static int jffs2_sync_fs(struct super_block *sb, int wait) |
diff --git a/fs/jffs2/wbuf.c b/fs/jffs2/wbuf.c index 8de52b607678..0e78b00035e4 100644 --- a/fs/jffs2/wbuf.c +++ b/fs/jffs2/wbuf.c | |||
| @@ -494,7 +494,7 @@ static void jffs2_wbuf_recover(struct jffs2_sb_info *c) | |||
| 494 | /* If it's an in-core inode, then we have to adjust any | 494 | /* If it's an in-core inode, then we have to adjust any |
| 495 | full_dirent or full_dnode structure to point to the | 495 | full_dirent or full_dnode structure to point to the |
| 496 | new version instead of the old */ | 496 | new version instead of the old */ |
| 497 | f = jffs2_gc_fetch_inode(c, ic->ino, ic->nlink); | 497 | f = jffs2_gc_fetch_inode(c, ic->ino, !ic->pino_nlink); |
| 498 | if (IS_ERR(f)) { | 498 | if (IS_ERR(f)) { |
| 499 | /* Should never happen; it _must_ be present */ | 499 | /* Should never happen; it _must_ be present */ |
| 500 | JFFS2_ERROR("Failed to iget() ino #%u, err %ld\n", | 500 | JFFS2_ERROR("Failed to iget() ino #%u, err %ld\n", |
diff --git a/fs/jffs2/write.c b/fs/jffs2/write.c index 665fce9797d3..ca29440e9435 100644 --- a/fs/jffs2/write.c +++ b/fs/jffs2/write.c | |||
| @@ -19,7 +19,8 @@ | |||
| 19 | #include "compr.h" | 19 | #include "compr.h" |
| 20 | 20 | ||
| 21 | 21 | ||
| 22 | int jffs2_do_new_inode(struct jffs2_sb_info *c, struct jffs2_inode_info *f, uint32_t mode, struct jffs2_raw_inode *ri) | 22 | int jffs2_do_new_inode(struct jffs2_sb_info *c, struct jffs2_inode_info *f, |
| 23 | uint32_t mode, struct jffs2_raw_inode *ri) | ||
| 23 | { | 24 | { |
| 24 | struct jffs2_inode_cache *ic; | 25 | struct jffs2_inode_cache *ic; |
| 25 | 26 | ||
| @@ -31,7 +32,7 @@ int jffs2_do_new_inode(struct jffs2_sb_info *c, struct jffs2_inode_info *f, uint | |||
| 31 | memset(ic, 0, sizeof(*ic)); | 32 | memset(ic, 0, sizeof(*ic)); |
| 32 | 33 | ||
| 33 | f->inocache = ic; | 34 | f->inocache = ic; |
| 34 | f->inocache->nlink = 1; | 35 | f->inocache->pino_nlink = 1; /* Will be overwritten shortly for directories */ |
| 35 | f->inocache->nodes = (struct jffs2_raw_node_ref *)f->inocache; | 36 | f->inocache->nodes = (struct jffs2_raw_node_ref *)f->inocache; |
| 36 | f->inocache->state = INO_STATE_PRESENT; | 37 | f->inocache->state = INO_STATE_PRESENT; |
| 37 | 38 | ||
| @@ -438,10 +439,10 @@ int jffs2_do_create(struct jffs2_sb_info *c, struct jffs2_inode_info *dir_f, str | |||
| 438 | ret = jffs2_reserve_space(c, sizeof(*ri), &alloclen, ALLOC_NORMAL, | 439 | ret = jffs2_reserve_space(c, sizeof(*ri), &alloclen, ALLOC_NORMAL, |
| 439 | JFFS2_SUMMARY_INODE_SIZE); | 440 | JFFS2_SUMMARY_INODE_SIZE); |
| 440 | D1(printk(KERN_DEBUG "jffs2_do_create(): reserved 0x%x bytes\n", alloclen)); | 441 | D1(printk(KERN_DEBUG "jffs2_do_create(): reserved 0x%x bytes\n", alloclen)); |
| 441 | if (ret) { | 442 | if (ret) |
| 442 | mutex_unlock(&f->sem); | ||
| 443 | return ret; | 443 | return ret; |
| 444 | } | 444 | |
| 445 | mutex_lock(&f->sem); | ||
| 445 | 446 | ||
| 446 | ri->data_crc = cpu_to_je32(0); | 447 | ri->data_crc = cpu_to_je32(0); |
| 447 | ri->node_crc = cpu_to_je32(crc32(0, ri, sizeof(*ri)-8)); | 448 | ri->node_crc = cpu_to_je32(crc32(0, ri, sizeof(*ri)-8)); |
| @@ -635,9 +636,9 @@ int jffs2_do_unlink(struct jffs2_sb_info *c, struct jffs2_inode_info *dir_f, | |||
| 635 | jffs2_mark_node_obsolete(c, fd->raw); | 636 | jffs2_mark_node_obsolete(c, fd->raw); |
| 636 | jffs2_free_full_dirent(fd); | 637 | jffs2_free_full_dirent(fd); |
| 637 | } | 638 | } |
| 638 | } | 639 | dead_f->inocache->pino_nlink = 0; |
| 639 | 640 | } else | |
| 640 | dead_f->inocache->nlink--; | 641 | dead_f->inocache->pino_nlink--; |
| 641 | /* NB: Caller must set inode nlink if appropriate */ | 642 | /* NB: Caller must set inode nlink if appropriate */ |
| 642 | mutex_unlock(&dead_f->sem); | 643 | mutex_unlock(&dead_f->sem); |
| 643 | } | 644 | } |
diff --git a/fs/jffs2/xattr.c b/fs/jffs2/xattr.c index 574cb7532d6c..082e844ab2db 100644 --- a/fs/jffs2/xattr.c +++ b/fs/jffs2/xattr.c | |||
| @@ -592,7 +592,7 @@ void jffs2_xattr_delete_inode(struct jffs2_sb_info *c, struct jffs2_inode_cache | |||
| 592 | When an inode with XATTR is removed, those XATTRs must be removed. */ | 592 | When an inode with XATTR is removed, those XATTRs must be removed. */ |
| 593 | struct jffs2_xattr_ref *ref, *_ref; | 593 | struct jffs2_xattr_ref *ref, *_ref; |
| 594 | 594 | ||
| 595 | if (!ic || ic->nlink > 0) | 595 | if (!ic || ic->pino_nlink > 0) |
| 596 | return; | 596 | return; |
| 597 | 597 | ||
| 598 | down_write(&c->xattr_sem); | 598 | down_write(&c->xattr_sem); |
| @@ -829,7 +829,7 @@ void jffs2_build_xattr_subsystem(struct jffs2_sb_info *c) | |||
| 829 | ref->xd and ref->ic are not valid yet. */ | 829 | ref->xd and ref->ic are not valid yet. */ |
| 830 | xd = jffs2_find_xattr_datum(c, ref->xid); | 830 | xd = jffs2_find_xattr_datum(c, ref->xid); |
| 831 | ic = jffs2_get_ino_cache(c, ref->ino); | 831 | ic = jffs2_get_ino_cache(c, ref->ino); |
| 832 | if (!xd || !ic || !ic->nlink) { | 832 | if (!xd || !ic || !ic->pino_nlink) { |
| 833 | dbg_xattr("xref(ino=%u, xid=%u, xseqno=%u) is orphan.\n", | 833 | dbg_xattr("xref(ino=%u, xid=%u, xseqno=%u) is orphan.\n", |
| 834 | ref->ino, ref->xid, ref->xseqno); | 834 | ref->ino, ref->xid, ref->xseqno); |
| 835 | ref->xseqno |= XREF_DELETE_MARKER; | 835 | ref->xseqno |= XREF_DELETE_MARKER; |
diff --git a/include/linux/mtd/jedec.h b/include/linux/mtd/jedec.h deleted file mode 100644 index 9006feb218b9..000000000000 --- a/include/linux/mtd/jedec.h +++ /dev/null | |||
| @@ -1,66 +0,0 @@ | |||
| 1 | |||
| 2 | /* JEDEC Flash Interface. | ||
| 3 | * This is an older type of interface for self programming flash. It is | ||
| 4 | * commonly use in older AMD chips and is obsolete compared with CFI. | ||
| 5 | * It is called JEDEC because the JEDEC association distributes the ID codes | ||
| 6 | * for the chips. | ||
| 7 | * | ||
| 8 | * See the AMD flash databook for information on how to operate the interface. | ||
| 9 | * | ||
| 10 | * $Id: jedec.h,v 1.4 2005/11/07 11:14:54 gleixner Exp $ | ||
| 11 | */ | ||
| 12 | |||
| 13 | #ifndef __LINUX_MTD_JEDEC_H__ | ||
| 14 | #define __LINUX_MTD_JEDEC_H__ | ||
| 15 | |||
| 16 | #include <linux/types.h> | ||
| 17 | |||
| 18 | #define MAX_JEDEC_CHIPS 16 | ||
| 19 | |||
| 20 | // Listing of all supported chips and their information | ||
| 21 | struct JEDECTable | ||
| 22 | { | ||
| 23 | __u16 jedec; | ||
| 24 | char *name; | ||
| 25 | unsigned long size; | ||
| 26 | unsigned long sectorsize; | ||
| 27 | __u32 capabilities; | ||
| 28 | }; | ||
| 29 | |||
| 30 | // JEDEC being 0 is the end of the chip array | ||
| 31 | struct jedec_flash_chip | ||
| 32 | { | ||
| 33 | __u16 jedec; | ||
| 34 | unsigned long size; | ||
| 35 | unsigned long sectorsize; | ||
| 36 | |||
| 37 | // *(__u8*)(base + (adder << addrshift)) = data << datashift | ||
| 38 | // Address size = size << addrshift | ||
| 39 | unsigned long base; // Byte 0 of the flash, will be unaligned | ||
| 40 | unsigned int datashift; // Useful for 32bit/16bit accesses | ||
| 41 | unsigned int addrshift; | ||
| 42 | unsigned long offset; // linerized start. base==offset for unbanked, uninterleaved flash | ||
| 43 | |||
| 44 | __u32 capabilities; | ||
| 45 | |||
| 46 | // These markers are filled in by the flash_chip_scan function | ||
| 47 | unsigned long start; | ||
| 48 | unsigned long length; | ||
| 49 | }; | ||
| 50 | |||
| 51 | struct jedec_private | ||
| 52 | { | ||
| 53 | unsigned long size; // Total size of all the devices | ||
| 54 | |||
| 55 | /* Bank handling. If sum(bank_fill) == size then this is linear flash. | ||
| 56 | Otherwise the mapping has holes in it. bank_fill may be used to | ||
| 57 | find the holes, but in the common symetric case | ||
| 58 | bank_fill[0] == bank_fill[*], thus addresses may be computed | ||
| 59 | mathmatically. bank_fill must be powers of two */ | ||
| 60 | unsigned is_banked; | ||
| 61 | unsigned long bank_fill[MAX_JEDEC_CHIPS]; | ||
| 62 | |||
| 63 | struct jedec_flash_chip chips[MAX_JEDEC_CHIPS]; | ||
| 64 | }; | ||
| 65 | |||
| 66 | #endif | ||
diff --git a/include/linux/mtd/mtd.h b/include/linux/mtd/mtd.h index 0a13bb35f044..245f9098e171 100644 --- a/include/linux/mtd/mtd.h +++ b/include/linux/mtd/mtd.h | |||
| @@ -143,10 +143,12 @@ struct mtd_info { | |||
| 143 | int (*erase) (struct mtd_info *mtd, struct erase_info *instr); | 143 | int (*erase) (struct mtd_info *mtd, struct erase_info *instr); |
| 144 | 144 | ||
| 145 | /* This stuff for eXecute-In-Place */ | 145 | /* This stuff for eXecute-In-Place */ |
| 146 | int (*point) (struct mtd_info *mtd, loff_t from, size_t len, size_t *retlen, u_char **mtdbuf); | 146 | /* phys is optional and may be set to NULL */ |
| 147 | int (*point) (struct mtd_info *mtd, loff_t from, size_t len, | ||
| 148 | size_t *retlen, void **virt, resource_size_t *phys); | ||
| 147 | 149 | ||
| 148 | /* We probably shouldn't allow XIP if the unpoint isn't a NULL */ | 150 | /* We probably shouldn't allow XIP if the unpoint isn't a NULL */ |
| 149 | void (*unpoint) (struct mtd_info *mtd, u_char * addr, loff_t from, size_t len); | 151 | void (*unpoint) (struct mtd_info *mtd, loff_t from, size_t len); |
| 150 | 152 | ||
| 151 | 153 | ||
| 152 | int (*read) (struct mtd_info *mtd, loff_t from, size_t len, size_t *retlen, u_char *buf); | 154 | int (*read) (struct mtd_info *mtd, loff_t from, size_t len, size_t *retlen, u_char *buf); |
diff --git a/include/linux/mtd/pmc551.h b/include/linux/mtd/pmc551.h index a7f6d20ad407..5cc070c24d88 100644 --- a/include/linux/mtd/pmc551.h +++ b/include/linux/mtd/pmc551.h | |||
| @@ -36,8 +36,9 @@ struct mypriv { | |||
| 36 | * Function Prototypes | 36 | * Function Prototypes |
| 37 | */ | 37 | */ |
| 38 | static int pmc551_erase(struct mtd_info *, struct erase_info *); | 38 | static int pmc551_erase(struct mtd_info *, struct erase_info *); |
| 39 | static void pmc551_unpoint(struct mtd_info *, u_char *, loff_t, size_t); | 39 | static void pmc551_unpoint(struct mtd_info *, loff_t, size_t); |
| 40 | static int pmc551_point (struct mtd_info *mtd, loff_t from, size_t len, size_t *retlen, u_char **mtdbuf); | 40 | static int pmc551_point(struct mtd_info *mtd, loff_t from, size_t len, |
| 41 | size_t *retlen, void **virt, resource_size_t *phys); | ||
| 41 | static int pmc551_read(struct mtd_info *, loff_t, size_t, size_t *, u_char *); | 42 | static int pmc551_read(struct mtd_info *, loff_t, size_t, size_t *, u_char *); |
| 42 | static int pmc551_write(struct mtd_info *, loff_t, size_t, size_t *, const u_char *); | 43 | static int pmc551_write(struct mtd_info *, loff_t, size_t, size_t *, const u_char *); |
| 43 | 44 | ||
