Blame view
fs/jffs2/fs.c
19.3 KB
1da177e4c Linux-2.6.12-rc2 |
1 2 3 |
/* * JFFS2 -- Journalling Flash File System, Version 2. * |
c00c310ea [JFFS2] Tidy up l... |
4 |
* Copyright © 2001-2007 Red Hat, Inc. |
6088c0587 jffs2: Update cop... |
5 |
* Copyright © 2004-2010 David Woodhouse <dwmw2@infradead.org> |
1da177e4c Linux-2.6.12-rc2 |
6 7 8 9 10 |
* * Created by David Woodhouse <dwmw2@infradead.org> * * For licensing information, see the file 'LICENCE' in this directory. * |
1da177e4c Linux-2.6.12-rc2 |
11 |
*/ |
5a528957e jffs2: Use pr_fmt... |
12 |
#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt |
16f7e0fe2 [PATCH] capable/c... |
13 |
#include <linux/capability.h> |
1da177e4c Linux-2.6.12-rc2 |
14 15 |
#include <linux/kernel.h> #include <linux/sched.h> |
5b825c3af sched/headers: Pr... |
16 |
#include <linux/cred.h> |
1da177e4c Linux-2.6.12-rc2 |
17 |
#include <linux/fs.h> |
ec10a24f1 vfs: Convert jffs... |
18 |
#include <linux/fs_context.h> |
1da177e4c Linux-2.6.12-rc2 |
19 20 21 22 23 24 25 26 27 28 |
#include <linux/list.h> #include <linux/mtd/mtd.h> #include <linux/pagemap.h> #include <linux/slab.h> #include <linux/vmalloc.h> #include <linux/vfs.h> #include <linux/crc32.h> #include "nodelist.h" static int jffs2_flash_setup(struct jffs2_sb_info *c); |
9ed437c50 [JFFS2] Fix ACL v... |
29 |
int jffs2_do_setattr (struct inode *inode, struct iattr *iattr) |
1da177e4c Linux-2.6.12-rc2 |
30 31 32 33 34 |
{ struct jffs2_full_dnode *old_metadata, *new_metadata; struct jffs2_inode_info *f = JFFS2_INODE_INFO(inode); struct jffs2_sb_info *c = JFFS2_SB_INFO(inode->i_sb); struct jffs2_raw_inode *ri; |
aef9ab478 [JFFS2] Support n... |
35 |
union jffs2_device_node dev; |
1da177e4c Linux-2.6.12-rc2 |
36 37 38 |
unsigned char *mdata = NULL; int mdatalen = 0; unsigned int ivalid; |
9fe4854cd [JFFS2] Remove fl... |
39 |
uint32_t alloclen; |
1da177e4c Linux-2.6.12-rc2 |
40 |
int ret; |
dd919660a [JFFS2] Use ALLOC... |
41 |
int alloc_type = ALLOC_NORMAL; |
9ed437c50 [JFFS2] Fix ACL v... |
42 |
|
9c261b33a jffs2: Convert mo... |
43 44 |
jffs2_dbg(1, "%s(): ino #%lu ", __func__, inode->i_ino); |
1da177e4c Linux-2.6.12-rc2 |
45 46 47 48 49 50 51 52 |
/* Special cases - we don't want more than one data node for these types on the medium at any time. So setattr must read the original data associated with the node (i.e. the device numbers or the target name) and write it out again with the appropriate data attached */ if (S_ISBLK(inode->i_mode) || S_ISCHR(inode->i_mode)) { /* For these, we don't actually need to read the old node */ |
aef9ab478 [JFFS2] Support n... |
53 |
mdatalen = jffs2_encode_dev(&dev, inode->i_rdev); |
1da177e4c Linux-2.6.12-rc2 |
54 |
mdata = (char *)&dev; |
9c261b33a jffs2: Convert mo... |
55 56 57 |
jffs2_dbg(1, "%s(): Writing %d bytes of kdev_t ", __func__, mdatalen); |
1da177e4c Linux-2.6.12-rc2 |
58 |
} else if (S_ISLNK(inode->i_mode)) { |
ced220703 [JFFS2] semaphore... |
59 |
mutex_lock(&f->sem); |
1da177e4c Linux-2.6.12-rc2 |
60 61 |
mdatalen = f->metadata->size; mdata = kmalloc(f->metadata->size, GFP_USER); |
422138dd6 [JFFS2] Fix race ... |
62 |
if (!mdata) { |
ced220703 [JFFS2] semaphore... |
63 |
mutex_unlock(&f->sem); |
1da177e4c Linux-2.6.12-rc2 |
64 |
return -ENOMEM; |
422138dd6 [JFFS2] Fix race ... |
65 |
} |
1da177e4c Linux-2.6.12-rc2 |
66 67 |
ret = jffs2_read_dnode(c, f, f->metadata, mdata, 0, mdatalen); if (ret) { |
ced220703 [JFFS2] semaphore... |
68 |
mutex_unlock(&f->sem); |
1da177e4c Linux-2.6.12-rc2 |
69 70 71 |
kfree(mdata); return ret; } |
ced220703 [JFFS2] semaphore... |
72 |
mutex_unlock(&f->sem); |
9c261b33a jffs2: Convert mo... |
73 74 75 |
jffs2_dbg(1, "%s(): Writing %d bytes of symlink target ", __func__, mdatalen); |
1da177e4c Linux-2.6.12-rc2 |
76 77 78 79 80 81 82 83 |
} ri = jffs2_alloc_raw_inode(); if (!ri) { if (S_ISLNK(inode->i_mode)) kfree(mdata); return -ENOMEM; } |
182ec4eee [JFFS2] Clean up ... |
84 |
|
9fe4854cd [JFFS2] Remove fl... |
85 86 |
ret = jffs2_reserve_space(c, sizeof(*ri) + mdatalen, &alloclen, ALLOC_NORMAL, JFFS2_SUMMARY_INODE_SIZE); |
1da177e4c Linux-2.6.12-rc2 |
87 88 |
if (ret) { jffs2_free_raw_inode(ri); |
61effb519 jffs2: S_ISLNK(mo... |
89 |
if (S_ISLNK(inode->i_mode)) |
1da177e4c Linux-2.6.12-rc2 |
90 91 92 |
kfree(mdata); return ret; } |
ced220703 [JFFS2] semaphore... |
93 |
mutex_lock(&f->sem); |
1da177e4c Linux-2.6.12-rc2 |
94 |
ivalid = iattr->ia_valid; |
182ec4eee [JFFS2] Clean up ... |
95 |
|
1da177e4c Linux-2.6.12-rc2 |
96 97 98 99 100 101 102 |
ri->magic = cpu_to_je16(JFFS2_MAGIC_BITMASK); ri->nodetype = cpu_to_je16(JFFS2_NODETYPE_INODE); ri->totlen = cpu_to_je32(sizeof(*ri) + mdatalen); ri->hdr_crc = cpu_to_je32(crc32(0, ri, sizeof(struct jffs2_unknown_node)-4)); ri->ino = cpu_to_je32(inode->i_ino); ri->version = cpu_to_je32(++f->highest_version); |
0cfe53d3c userns: Convert j... |
103 104 105 106 |
ri->uid = cpu_to_je16((ivalid & ATTR_UID)? from_kuid(&init_user_ns, iattr->ia_uid):i_uid_read(inode)); ri->gid = cpu_to_je16((ivalid & ATTR_GID)? from_kgid(&init_user_ns, iattr->ia_gid):i_gid_read(inode)); |
1da177e4c Linux-2.6.12-rc2 |
107 108 |
if (ivalid & ATTR_MODE) |
857013b87 [JFFS2] Don't str... |
109 |
ri->mode = cpu_to_jemode(iattr->ia_mode); |
1da177e4c Linux-2.6.12-rc2 |
110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 |
else ri->mode = cpu_to_jemode(inode->i_mode); ri->isize = cpu_to_je32((ivalid & ATTR_SIZE)?iattr->ia_size:inode->i_size); ri->atime = cpu_to_je32(I_SEC((ivalid & ATTR_ATIME)?iattr->ia_atime:inode->i_atime)); ri->mtime = cpu_to_je32(I_SEC((ivalid & ATTR_MTIME)?iattr->ia_mtime:inode->i_mtime)); ri->ctime = cpu_to_je32(I_SEC((ivalid & ATTR_CTIME)?iattr->ia_ctime:inode->i_ctime)); ri->offset = cpu_to_je32(0); ri->csize = ri->dsize = cpu_to_je32(mdatalen); ri->compr = JFFS2_COMPR_NONE; if (ivalid & ATTR_SIZE && inode->i_size < iattr->ia_size) { /* It's an extension. Make it a hole node */ ri->compr = JFFS2_COMPR_ZERO; ri->dsize = cpu_to_je32(iattr->ia_size - inode->i_size); ri->offset = cpu_to_je32(inode->i_size); |
dd919660a [JFFS2] Use ALLOC... |
127 128 129 130 |
} else if (ivalid & ATTR_SIZE && !iattr->ia_size) { /* For truncate-to-zero, treat it as deletion because it'll always be obsoleting all previous nodes */ alloc_type = ALLOC_DELETION; |
1da177e4c Linux-2.6.12-rc2 |
131 132 133 134 135 136 |
} ri->node_crc = cpu_to_je32(crc32(0, ri, sizeof(*ri)-8)); if (mdatalen) ri->data_crc = cpu_to_je32(crc32(0, mdata, mdatalen)); else ri->data_crc = cpu_to_je32(0); |
dd919660a [JFFS2] Use ALLOC... |
137 |
new_metadata = jffs2_write_dnode(c, f, ri, mdata, mdatalen, alloc_type); |
1da177e4c Linux-2.6.12-rc2 |
138 139 |
if (S_ISLNK(inode->i_mode)) kfree(mdata); |
182ec4eee [JFFS2] Clean up ... |
140 |
|
1da177e4c Linux-2.6.12-rc2 |
141 142 143 |
if (IS_ERR(new_metadata)) { jffs2_complete_reservation(c); jffs2_free_raw_inode(ri); |
ced220703 [JFFS2] semaphore... |
144 |
mutex_unlock(&f->sem); |
1da177e4c Linux-2.6.12-rc2 |
145 146 147 |
return PTR_ERR(new_metadata); } /* It worked. Update the inode */ |
c4592b9c3 jffs2: use 64-bit... |
148 149 150 |
inode->i_atime = ITIME(je32_to_cpu(ri->atime)); inode->i_ctime = ITIME(je32_to_cpu(ri->ctime)); inode->i_mtime = ITIME(je32_to_cpu(ri->mtime)); |
1da177e4c Linux-2.6.12-rc2 |
151 |
inode->i_mode = jemode_to_cpu(ri->mode); |
0cfe53d3c userns: Convert j... |
152 153 |
i_uid_write(inode, je16_to_cpu(ri->uid)); i_gid_write(inode, je16_to_cpu(ri->gid)); |
1da177e4c Linux-2.6.12-rc2 |
154 155 156 157 158 |
old_metadata = f->metadata; if (ivalid & ATTR_SIZE && inode->i_size > iattr->ia_size) |
f302cd028 [JFFS2] Namespace... |
159 |
jffs2_truncate_fragtree (c, &f->fragtree, iattr->ia_size); |
1da177e4c Linux-2.6.12-rc2 |
160 161 162 163 |
if (ivalid & ATTR_SIZE && inode->i_size < iattr->ia_size) { jffs2_add_full_dnode_to_inode(c, f, new_metadata); inode->i_size = iattr->ia_size; |
b28ba9fa0 [JFFS2] Set i_blo... |
164 |
inode->i_blocks = (inode->i_size + 511) >> 9; |
1da177e4c Linux-2.6.12-rc2 |
165 166 167 168 169 170 171 172 173 |
f->metadata = NULL; } else { f->metadata = new_metadata; } if (old_metadata) { jffs2_mark_node_obsolete(c, old_metadata->raw); jffs2_free_full_dnode(old_metadata); } jffs2_free_raw_inode(ri); |
ced220703 [JFFS2] semaphore... |
174 |
mutex_unlock(&f->sem); |
1da177e4c Linux-2.6.12-rc2 |
175 |
jffs2_complete_reservation(c); |
2c27c65ed check ATTR_SIZE c... |
176 |
/* We have to do the truncate_setsize() without f->sem held, since |
182ec4eee [JFFS2] Clean up ... |
177 |
some pages may be locked and waiting for it in readpage(). |
1da177e4c Linux-2.6.12-rc2 |
178 179 180 |
We are protected from a simultaneous write() extending i_size back past iattr->ia_size, because do_truncate() holds the generic inode semaphore. */ |
b28ba9fa0 [JFFS2] Set i_blo... |
181 |
if (ivalid & ATTR_SIZE && inode->i_size > iattr->ia_size) { |
2c27c65ed check ATTR_SIZE c... |
182 |
truncate_setsize(inode, iattr->ia_size); |
b28ba9fa0 [JFFS2] Set i_blo... |
183 |
inode->i_blocks = (inode->i_size + 511) >> 9; |
ec10a24f1 vfs: Convert jffs... |
184 |
} |
1da177e4c Linux-2.6.12-rc2 |
185 186 187 188 189 190 |
return 0; } int jffs2_setattr(struct dentry *dentry, struct iattr *iattr) { |
2b0143b5c VFS: normal files... |
191 |
struct inode *inode = d_inode(dentry); |
aa98d7cf5 [JFFS2][XATTR] XA... |
192 |
int rc; |
31051c85b fs: Give dentry t... |
193 |
rc = setattr_prepare(dentry, iattr); |
9ed437c50 [JFFS2] Fix ACL v... |
194 195 |
if (rc) return rc; |
f2963d455 jffs2: use generi... |
196 |
rc = jffs2_do_setattr(inode, iattr); |
aa98d7cf5 [JFFS2][XATTR] XA... |
197 |
if (!rc && (iattr->ia_valid & ATTR_MODE)) |
f2963d455 jffs2: use generi... |
198 |
rc = posix_acl_chmod(inode, inode->i_mode); |
9ed437c50 [JFFS2] Fix ACL v... |
199 |
|
aa98d7cf5 [JFFS2][XATTR] XA... |
200 |
return rc; |
1da177e4c Linux-2.6.12-rc2 |
201 |
} |
726c33422 [PATCH] VFS: Perm... |
202 |
int jffs2_statfs(struct dentry *dentry, struct kstatfs *buf) |
1da177e4c Linux-2.6.12-rc2 |
203 |
{ |
726c33422 [PATCH] VFS: Perm... |
204 |
struct jffs2_sb_info *c = JFFS2_SB_INFO(dentry->d_sb); |
1da177e4c Linux-2.6.12-rc2 |
205 206 207 208 209 210 211 212 |
unsigned long avail; buf->f_type = JFFS2_SUPER_MAGIC; buf->f_bsize = 1 << PAGE_SHIFT; buf->f_blocks = c->flash_size >> PAGE_SHIFT; buf->f_files = 0; buf->f_ffree = 0; buf->f_namelen = JFFS2_MAX_NAME_LEN; |
75caf6b5a [JFFS2] Fill in f... |
213 214 |
buf->f_fsid.val[0] = JFFS2_SUPER_MAGIC; buf->f_fsid.val[1] = c->mtd->index; |
1da177e4c Linux-2.6.12-rc2 |
215 216 |
spin_lock(&c->erase_completion_lock); |
1da177e4c Linux-2.6.12-rc2 |
217 218 219 220 221 |
avail = c->dirty_size + c->free_size; if (avail > c->sector_size * c->resv_blocks_write) avail -= c->sector_size * c->resv_blocks_write; else avail = 0; |
e0c8e42f8 [JFFS2] Debug cod... |
222 |
spin_unlock(&c->erase_completion_lock); |
1da177e4c Linux-2.6.12-rc2 |
223 224 |
buf->f_bavail = buf->f_bfree = avail >> PAGE_SHIFT; |
1da177e4c Linux-2.6.12-rc2 |
225 226 |
return 0; } |
b57922d97 convert remaining... |
227 |
void jffs2_evict_inode (struct inode *inode) |
1da177e4c Linux-2.6.12-rc2 |
228 |
{ |
182ec4eee [JFFS2] Clean up ... |
229 |
/* We can forget about this inode for now - drop all |
1da177e4c Linux-2.6.12-rc2 |
230 231 232 233 |
* the nodelists associated with it, etc. */ struct jffs2_sb_info *c = JFFS2_SB_INFO(inode->i_sb); struct jffs2_inode_info *f = JFFS2_INODE_INFO(inode); |
182ec4eee [JFFS2] Clean up ... |
234 |
|
9c261b33a jffs2: Convert mo... |
235 236 237 |
jffs2_dbg(1, "%s(): ino #%lu mode %o ", __func__, inode->i_ino, inode->i_mode); |
91b0abe36 mm + fs: store sh... |
238 |
truncate_inode_pages_final(&inode->i_data); |
dbd5768f8 vfs: Rename end_w... |
239 |
clear_inode(inode); |
1da177e4c Linux-2.6.12-rc2 |
240 241 |
jffs2_do_clear_inode(c, f); } |
5451f79f5 iget: stop JFFS2 ... |
242 |
struct inode *jffs2_iget(struct super_block *sb, unsigned long ino) |
1da177e4c Linux-2.6.12-rc2 |
243 244 245 246 |
{ struct jffs2_inode_info *f; struct jffs2_sb_info *c; struct jffs2_raw_inode latest_node; |
aef9ab478 [JFFS2] Support n... |
247 |
union jffs2_device_node jdev; |
5451f79f5 iget: stop JFFS2 ... |
248 |
struct inode *inode; |
aef9ab478 [JFFS2] Support n... |
249 |
dev_t rdev = 0; |
1da177e4c Linux-2.6.12-rc2 |
250 |
int ret; |
9c261b33a jffs2: Convert mo... |
251 252 |
jffs2_dbg(1, "%s(): ino == %lu ", __func__, ino); |
5451f79f5 iget: stop JFFS2 ... |
253 254 255 256 257 258 |
inode = iget_locked(sb, ino); if (!inode) return ERR_PTR(-ENOMEM); if (!(inode->i_state & I_NEW)) return inode; |
1da177e4c Linux-2.6.12-rc2 |
259 260 261 262 263 |
f = JFFS2_INODE_INFO(inode); c = JFFS2_SB_INFO(inode->i_sb); jffs2_init_inode_info(f); |
ced220703 [JFFS2] semaphore... |
264 |
mutex_lock(&f->sem); |
182ec4eee [JFFS2] Clean up ... |
265 |
|
1da177e4c Linux-2.6.12-rc2 |
266 |
ret = jffs2_do_read_inode(c, f, inode->i_ino, &latest_node); |
7aaea7605 jffs2: fix unbala... |
267 268 |
if (ret) goto error; |
1da177e4c Linux-2.6.12-rc2 |
269 |
|
1da177e4c Linux-2.6.12-rc2 |
270 |
inode->i_mode = jemode_to_cpu(latest_node.mode); |
0cfe53d3c userns: Convert j... |
271 272 |
i_uid_write(inode, je16_to_cpu(latest_node.uid)); i_gid_write(inode, je16_to_cpu(latest_node.gid)); |
1da177e4c Linux-2.6.12-rc2 |
273 |
inode->i_size = je32_to_cpu(latest_node.isize); |
c4592b9c3 jffs2: use 64-bit... |
274 275 276 |
inode->i_atime = ITIME(je32_to_cpu(latest_node.atime)); inode->i_mtime = ITIME(je32_to_cpu(latest_node.mtime)); inode->i_ctime = ITIME(je32_to_cpu(latest_node.ctime)); |
1da177e4c Linux-2.6.12-rc2 |
277 |
|
bfe868486 filesystems: add ... |
278 |
set_nlink(inode, f->inocache->pino_nlink); |
1da177e4c Linux-2.6.12-rc2 |
279 |
|
1da177e4c Linux-2.6.12-rc2 |
280 |
inode->i_blocks = (inode->i_size + 511) >> 9; |
182ec4eee [JFFS2] Clean up ... |
281 |
|
1da177e4c Linux-2.6.12-rc2 |
282 |
switch (inode->i_mode & S_IFMT) { |
1da177e4c Linux-2.6.12-rc2 |
283 284 285 |
case S_IFLNK: inode->i_op = &jffs2_symlink_inode_operations; |
a8db149fc jffs2: switch to ... |
286 |
inode->i_link = f->target; |
1da177e4c Linux-2.6.12-rc2 |
287 |
break; |
182ec4eee [JFFS2] Clean up ... |
288 |
|
1da177e4c Linux-2.6.12-rc2 |
289 290 291 |
case S_IFDIR: { struct jffs2_full_dirent *fd; |
bfe868486 filesystems: add ... |
292 |
set_nlink(inode, 2); /* parent and '.' */ |
1da177e4c Linux-2.6.12-rc2 |
293 294 295 |
for (fd=f->dents; fd; fd = fd->next) { if (fd->type == DT_DIR && fd->ino) |
d8c76e6f4 [PATCH] r/o bind ... |
296 |
inc_nlink(inode); |
1da177e4c Linux-2.6.12-rc2 |
297 |
} |
1da177e4c Linux-2.6.12-rc2 |
298 299 |
/* Root dir gets i_nlink 3 for some reason */ if (inode->i_ino == 1) |
d8c76e6f4 [PATCH] r/o bind ... |
300 |
inc_nlink(inode); |
1da177e4c Linux-2.6.12-rc2 |
301 302 303 304 305 306 307 308 309 310 311 312 313 314 315 |
inode->i_op = &jffs2_dir_inode_operations; inode->i_fop = &jffs2_dir_operations; break; } case S_IFREG: inode->i_op = &jffs2_file_inode_operations; inode->i_fop = &jffs2_file_operations; inode->i_mapping->a_ops = &jffs2_file_address_operations; inode->i_mapping->nrpages = 0; break; case S_IFBLK: case S_IFCHR: /* Read the device numbers from the media */ |
91f802660 JFFS2: avoid usin... |
316 317 |
if (f->metadata->size != sizeof(jdev.old_id) && f->metadata->size != sizeof(jdev.new_id)) { |
da320f055 jffs2: Convert pr... |
318 319 320 |
pr_notice("Device node has strange size %d ", f->metadata->size); |
5451f79f5 iget: stop JFFS2 ... |
321 |
goto error_io; |
aef9ab478 [JFFS2] Support n... |
322 |
} |
9c261b33a jffs2: Convert mo... |
323 324 |
jffs2_dbg(1, "Reading device numbers from flash "); |
5451f79f5 iget: stop JFFS2 ... |
325 326 |
ret = jffs2_read_dnode(c, f, f->metadata, (char *)&jdev, 0, f->metadata->size); if (ret < 0) { |
1da177e4c Linux-2.6.12-rc2 |
327 |
/* Eep */ |
da320f055 jffs2: Convert pr... |
328 329 330 |
pr_notice("Read device numbers for inode %lu failed ", (unsigned long)inode->i_ino); |
5451f79f5 iget: stop JFFS2 ... |
331 |
goto error; |
182ec4eee [JFFS2] Clean up ... |
332 |
} |
91f802660 JFFS2: avoid usin... |
333 334 |
if (f->metadata->size == sizeof(jdev.old_id)) rdev = old_decode_dev(je16_to_cpu(jdev.old_id)); |
aef9ab478 [JFFS2] Support n... |
335 |
else |
91f802660 JFFS2: avoid usin... |
336 |
rdev = new_decode_dev(je32_to_cpu(jdev.new_id)); |
df561f668 treewide: Use fal... |
337 |
fallthrough; |
1da177e4c Linux-2.6.12-rc2 |
338 339 340 341 |
case S_IFSOCK: case S_IFIFO: inode->i_op = &jffs2_file_inode_operations; |
aef9ab478 [JFFS2] Support n... |
342 |
init_special_inode(inode, inode->i_mode, rdev); |
1da177e4c Linux-2.6.12-rc2 |
343 344 345 |
break; default: |
da320f055 jffs2: Convert pr... |
346 347 348 |
pr_warn("%s(): Bogus i_mode %o for ino %lu ", __func__, inode->i_mode, (unsigned long)inode->i_ino); |
1da177e4c Linux-2.6.12-rc2 |
349 |
} |
ced220703 [JFFS2] semaphore... |
350 |
mutex_unlock(&f->sem); |
1da177e4c Linux-2.6.12-rc2 |
351 |
|
9c261b33a jffs2: Convert mo... |
352 353 |
jffs2_dbg(1, "jffs2_read_inode() returning "); |
5451f79f5 iget: stop JFFS2 ... |
354 355 356 357 358 359 |
unlock_new_inode(inode); return inode; error_io: ret = -EIO; error: |
ced220703 [JFFS2] semaphore... |
360 |
mutex_unlock(&f->sem); |
5451f79f5 iget: stop JFFS2 ... |
361 362 |
iget_failed(inode); return ERR_PTR(ret); |
1da177e4c Linux-2.6.12-rc2 |
363 |
} |
aa3857295 fs: pass exact ty... |
364 |
void jffs2_dirty_inode(struct inode *inode, int flags) |
1da177e4c Linux-2.6.12-rc2 |
365 366 367 368 |
{ struct iattr iattr; if (!(inode->i_state & I_DIRTY_DATASYNC)) { |
9c261b33a jffs2: Convert mo... |
369 370 371 |
jffs2_dbg(2, "%s(): not calling setattr() for ino #%lu ", __func__, inode->i_ino); |
1da177e4c Linux-2.6.12-rc2 |
372 373 |
return; } |
9c261b33a jffs2: Convert mo... |
374 375 376 |
jffs2_dbg(1, "%s(): calling setattr() for ino #%lu ", __func__, inode->i_ino); |
1da177e4c Linux-2.6.12-rc2 |
377 378 379 380 381 382 383 384 385 386 387 |
iattr.ia_valid = ATTR_MODE|ATTR_UID|ATTR_GID|ATTR_ATIME|ATTR_MTIME|ATTR_CTIME; iattr.ia_mode = inode->i_mode; iattr.ia_uid = inode->i_uid; iattr.ia_gid = inode->i_gid; iattr.ia_atime = inode->i_atime; iattr.ia_mtime = inode->i_mtime; iattr.ia_ctime = inode->i_ctime; jffs2_do_setattr(inode, &iattr); } |
ec10a24f1 vfs: Convert jffs... |
388 |
int jffs2_do_remount_fs(struct super_block *sb, struct fs_context *fc) |
1da177e4c Linux-2.6.12-rc2 |
389 390 |
{ struct jffs2_sb_info *c = JFFS2_SB_INFO(sb); |
bc98a42c1 VFS: Convert sb->... |
391 |
if (c->flags & JFFS2_SB_FLAG_RO && !sb_rdonly(sb)) |
1da177e4c Linux-2.6.12-rc2 |
392 393 394 395 396 397 |
return -EROFS; /* We stop if it was running, then restart if it needs to. This also catches the case where it was stopped and this is just a remount to restart it. Flush the writebuffer, if neccecary, else we loose it */ |
bc98a42c1 VFS: Convert sb->... |
398 |
if (!sb_rdonly(sb)) { |
1da177e4c Linux-2.6.12-rc2 |
399 |
jffs2_stop_garbage_collect_thread(c); |
ced220703 [JFFS2] semaphore... |
400 |
mutex_lock(&c->alloc_sem); |
1da177e4c Linux-2.6.12-rc2 |
401 |
jffs2_flush_wbuf_pad(c); |
ced220703 [JFFS2] semaphore... |
402 |
mutex_unlock(&c->alloc_sem); |
182ec4eee [JFFS2] Clean up ... |
403 |
} |
1da177e4c Linux-2.6.12-rc2 |
404 |
|
ec10a24f1 vfs: Convert jffs... |
405 |
if (!(fc->sb_flags & SB_RDONLY)) |
1da177e4c Linux-2.6.12-rc2 |
406 |
jffs2_start_garbage_collect_thread(c); |
182ec4eee [JFFS2] Clean up ... |
407 |
|
ec10a24f1 vfs: Convert jffs... |
408 |
fc->sb_flags |= SB_NOATIME; |
1da177e4c Linux-2.6.12-rc2 |
409 410 |
return 0; } |
1da177e4c Linux-2.6.12-rc2 |
411 412 |
/* jffs2_new_inode: allocate a new inode and inocache, add it to the hash, fill in the raw_inode while you're at it. */ |
d3fb61207 switch posix_acl_... |
413 |
struct inode *jffs2_new_inode (struct inode *dir_i, umode_t mode, struct jffs2_raw_inode *ri) |
1da177e4c Linux-2.6.12-rc2 |
414 415 416 417 418 419 |
{ struct inode *inode; struct super_block *sb = dir_i->i_sb; struct jffs2_sb_info *c; struct jffs2_inode_info *f; int ret; |
9c261b33a jffs2: Convert mo... |
420 421 422 |
jffs2_dbg(1, "%s(): dir_i %ld, mode 0x%x ", __func__, dir_i->i_ino, mode); |
1da177e4c Linux-2.6.12-rc2 |
423 424 |
c = JFFS2_SB_INFO(sb); |
182ec4eee [JFFS2] Clean up ... |
425 |
|
1da177e4c Linux-2.6.12-rc2 |
426 |
inode = new_inode(sb); |
182ec4eee [JFFS2] Clean up ... |
427 |
|
1da177e4c Linux-2.6.12-rc2 |
428 429 430 431 432 |
if (!inode) return ERR_PTR(-ENOMEM); f = JFFS2_INODE_INFO(inode); jffs2_init_inode_info(f); |
ced220703 [JFFS2] semaphore... |
433 |
mutex_lock(&f->sem); |
1da177e4c Linux-2.6.12-rc2 |
434 435 436 |
memset(ri, 0, sizeof(*ri)); /* Set OS-specific defaults for new inodes */ |
0cfe53d3c userns: Convert j... |
437 |
ri->uid = cpu_to_je16(from_kuid(&init_user_ns, current_fsuid())); |
1da177e4c Linux-2.6.12-rc2 |
438 439 |
if (dir_i->i_mode & S_ISGID) { |
0cfe53d3c userns: Convert j... |
440 |
ri->gid = cpu_to_je16(i_gid_read(dir_i)); |
1da177e4c Linux-2.6.12-rc2 |
441 442 443 |
if (S_ISDIR(mode)) mode |= S_ISGID; } else { |
0cfe53d3c userns: Convert j... |
444 |
ri->gid = cpu_to_je16(from_kgid(&init_user_ns, current_fsgid())); |
1da177e4c Linux-2.6.12-rc2 |
445 |
} |
9ed437c50 [JFFS2] Fix ACL v... |
446 447 448 |
/* POSIX ACLs have to be processed now, at least partly. The umask is only applied if there's no default ACL */ |
cfc8dc6f6 [JFFS2] Tidy up f... |
449 450 |
ret = jffs2_init_acl_pre(dir_i, inode, &mode); if (ret) { |
01887a3a2 jffs2: unlock f->... |
451 452 453 454 |
mutex_unlock(&f->sem); make_bad_inode(inode); iput(inode); return ERR_PTR(ret); |
9ed437c50 [JFFS2] Fix ACL v... |
455 |
} |
1da177e4c Linux-2.6.12-rc2 |
456 457 |
ret = jffs2_do_new_inode (c, f, mode, ri); if (ret) { |
01887a3a2 jffs2: unlock f->... |
458 |
mutex_unlock(&f->sem); |
1da177e4c Linux-2.6.12-rc2 |
459 460 461 462 |
make_bad_inode(inode); iput(inode); return ERR_PTR(ret); } |
bfe868486 filesystems: add ... |
463 |
set_nlink(inode, 1); |
1da177e4c Linux-2.6.12-rc2 |
464 465 |
inode->i_ino = je32_to_cpu(ri->ino); inode->i_mode = jemode_to_cpu(ri->mode); |
0cfe53d3c userns: Convert j... |
466 467 |
i_gid_write(inode, je16_to_cpu(ri->gid)); i_uid_write(inode, je16_to_cpu(ri->uid)); |
02027d42c fs: Replace CURRE... |
468 |
inode->i_atime = inode->i_ctime = inode->i_mtime = current_time(inode); |
1da177e4c Linux-2.6.12-rc2 |
469 |
ri->atime = ri->mtime = ri->ctime = cpu_to_je32(I_SEC(inode->i_mtime)); |
1da177e4c Linux-2.6.12-rc2 |
470 471 |
inode->i_blocks = 0; inode->i_size = 0; |
e72e6497e jffs2: Fix NFS ra... |
472 |
if (insert_inode_locked(inode) < 0) { |
01887a3a2 jffs2: unlock f->... |
473 |
mutex_unlock(&f->sem); |
e72e6497e jffs2: Fix NFS ra... |
474 |
make_bad_inode(inode); |
e72e6497e jffs2: Fix NFS ra... |
475 476 477 |
iput(inode); return ERR_PTR(-EINVAL); } |
1da177e4c Linux-2.6.12-rc2 |
478 479 480 |
return inode; } |
65e5a0e18 jffs2: Dynamicall... |
481 482 483 484 485 486 487 488 489 490 491 492 493 494 495 496 497 498 499 |
static int calculate_inocache_hashsize(uint32_t flash_size) { /* * Pick a inocache hash size based on the size of the medium. * Count how many megabytes we're dealing with, apply a hashsize twice * that size, but rounding down to the usual big powers of 2. And keep * to sensible bounds. */ int size_mb = flash_size / 1024 / 1024; int hashsize = (size_mb * 2) & ~0x3f; if (hashsize < INOCACHE_HASHSIZE_MIN) return INOCACHE_HASHSIZE_MIN; if (hashsize > INOCACHE_HASHSIZE_MAX) return INOCACHE_HASHSIZE_MAX; return hashsize; } |
1da177e4c Linux-2.6.12-rc2 |
500 |
|
ec10a24f1 vfs: Convert jffs... |
501 |
int jffs2_do_fill_super(struct super_block *sb, struct fs_context *fc) |
1da177e4c Linux-2.6.12-rc2 |
502 503 504 505 506 507 508 |
{ struct jffs2_sb_info *c; struct inode *root_i; int ret; size_t blocks; c = JFFS2_SB_INFO(sb); |
e104f1e9d jffs2: do not sup... |
509 510 511 |
/* Do not support the MLC nand */ if (c->mtd->type == MTD_MLCNANDFLASH) return -EINVAL; |
2f82ce1eb [JFFS2] Use a sin... |
512 |
#ifndef CONFIG_JFFS2_FS_WRITEBUFFER |
1da177e4c Linux-2.6.12-rc2 |
513 |
if (c->mtd->type == MTD_NANDFLASH) { |
ec10a24f1 vfs: Convert jffs... |
514 |
errorf(fc, "Cannot operate on NAND flash unless jffs2 NAND support is compiled in"); |
1da177e4c Linux-2.6.12-rc2 |
515 516 |
return -EINVAL; } |
8f15fd55f [JFFS2] Add suppo... |
517 |
if (c->mtd->type == MTD_DATAFLASH) { |
ec10a24f1 vfs: Convert jffs... |
518 |
errorf(fc, "Cannot operate on DataFlash unless jffs2 DataFlash support is compiled in"); |
8f15fd55f [JFFS2] Add suppo... |
519 520 521 |
return -EINVAL; } #endif |
1da177e4c Linux-2.6.12-rc2 |
522 523 |
c->flash_size = c->mtd->size; |
182ec4eee [JFFS2] Clean up ... |
524 |
c->sector_size = c->mtd->erasesize; |
1da177e4c Linux-2.6.12-rc2 |
525 |
blocks = c->flash_size / c->sector_size; |
1da177e4c Linux-2.6.12-rc2 |
526 527 528 529 530 |
/* * Size alignment check */ if ((c->sector_size * blocks) != c->flash_size) { |
182ec4eee [JFFS2] Clean up ... |
531 |
c->flash_size = c->sector_size * blocks; |
ec10a24f1 vfs: Convert jffs... |
532 533 |
infof(fc, "Flash size not aligned to erasesize, reducing to %dKiB", c->flash_size / 1024); |
1da177e4c Linux-2.6.12-rc2 |
534 |
} |
1da177e4c Linux-2.6.12-rc2 |
535 |
if (c->flash_size < 5*c->sector_size) { |
ec10a24f1 vfs: Convert jffs... |
536 |
errorf(fc, "Too few erase blocks (%d)", |
da320f055 jffs2: Convert pr... |
537 |
c->flash_size / c->sector_size); |
1da177e4c Linux-2.6.12-rc2 |
538 539 540 541 |
return -EINVAL; } c->cleanmarker_size = sizeof(struct jffs2_unknown_node); |
1da177e4c Linux-2.6.12-rc2 |
542 543 544 545 546 |
/* NAND (or other bizarre) flash... do setup accordingly */ ret = jffs2_flash_setup(c); if (ret) return ret; |
65e5a0e18 jffs2: Dynamicall... |
547 548 |
c->inocache_hashsize = calculate_inocache_hashsize(c->flash_size); c->inocache_list = kcalloc(c->inocache_hashsize, sizeof(struct jffs2_inode_cache *), GFP_KERNEL); |
1da177e4c Linux-2.6.12-rc2 |
549 550 551 552 |
if (!c->inocache_list) { ret = -ENOMEM; goto out_wbuf; } |
1da177e4c Linux-2.6.12-rc2 |
553 |
|
aa98d7cf5 [JFFS2][XATTR] XA... |
554 |
jffs2_init_xattr_subsystem(c); |
1da177e4c Linux-2.6.12-rc2 |
555 556 |
if ((ret = jffs2_do_mount_fs(c))) goto out_inohash; |
9c261b33a jffs2: Convert mo... |
557 558 |
jffs2_dbg(1, "%s(): Getting root inode ", __func__); |
5451f79f5 iget: stop JFFS2 ... |
559 560 |
root_i = jffs2_iget(sb, 1); if (IS_ERR(root_i)) { |
9c261b33a jffs2: Convert mo... |
561 562 |
jffs2_dbg(1, "get root inode failed "); |
5451f79f5 iget: stop JFFS2 ... |
563 564 |
ret = PTR_ERR(root_i); goto out_root; |
1da177e4c Linux-2.6.12-rc2 |
565 |
} |
5451f79f5 iget: stop JFFS2 ... |
566 |
ret = -ENOMEM; |
623ff7739 Merge tag 'for-li... |
567 568 |
jffs2_dbg(1, "%s(): d_make_root() ", __func__); |
48fde701a switch open-coded... |
569 |
sb->s_root = d_make_root(root_i); |
1da177e4c Linux-2.6.12-rc2 |
570 |
if (!sb->s_root) |
48fde701a switch open-coded... |
571 |
goto out_root; |
1da177e4c Linux-2.6.12-rc2 |
572 |
|
1da177e4c Linux-2.6.12-rc2 |
573 |
sb->s_maxbytes = 0xFFFFFFFF; |
09cbfeaf1 mm, fs: get rid o... |
574 575 |
sb->s_blocksize = PAGE_SIZE; sb->s_blocksize_bits = PAGE_SHIFT; |
1da177e4c Linux-2.6.12-rc2 |
576 |
sb->s_magic = JFFS2_SUPER_MAGIC; |
22b139691 fs: Fill in max a... |
577 578 |
sb->s_time_min = 0; sb->s_time_max = U32_MAX; |
bc98a42c1 VFS: Convert sb->... |
579 |
if (!sb_rdonly(sb)) |
1da177e4c Linux-2.6.12-rc2 |
580 581 |
jffs2_start_garbage_collect_thread(c); return 0; |
5451f79f5 iget: stop JFFS2 ... |
582 |
out_root: |
1da177e4c Linux-2.6.12-rc2 |
583 584 |
jffs2_free_ino_caches(c); jffs2_free_raw_node_refs(c); |
1d5cfdb07 tree wide: use kv... |
585 |
kvfree(c->blocks); |
1da177e4c Linux-2.6.12-rc2 |
586 |
out_inohash: |
aa98d7cf5 [JFFS2][XATTR] XA... |
587 |
jffs2_clear_xattr_subsystem(c); |
1da177e4c Linux-2.6.12-rc2 |
588 589 590 591 592 593 594 595 596 597 598 599 600 601 |
kfree(c->inocache_list); out_wbuf: jffs2_flash_cleanup(c); return ret; } void jffs2_gc_release_inode(struct jffs2_sb_info *c, struct jffs2_inode_info *f) { iput(OFNI_EDONI_2SFFJ(f)); } struct jffs2_inode_info *jffs2_gc_fetch_inode(struct jffs2_sb_info *c, |
1b690b487 [JFFS2] Invert la... |
602 |
int inum, int unlinked) |
1da177e4c Linux-2.6.12-rc2 |
603 604 605 |
{ struct inode *inode; struct jffs2_inode_cache *ic; |
1b690b487 [JFFS2] Invert la... |
606 607 |
if (unlinked) { |
1da177e4c Linux-2.6.12-rc2 |
608 |
/* The inode has zero nlink but its nodes weren't yet marked |
182ec4eee [JFFS2] Clean up ... |
609 |
obsolete. This has to be because we're still waiting for |
1da177e4c Linux-2.6.12-rc2 |
610 |
the final (close() and) iput() to happen. |
182ec4eee [JFFS2] Clean up ... |
611 |
There's a possibility that the final iput() could have |
1da177e4c Linux-2.6.12-rc2 |
612 613 614 615 |
happened while we were contemplating. In order to ensure that we don't cause a new read_inode() (which would fail) for the inode in question, we use ilookup() in this case instead of iget(). |
182ec4eee [JFFS2] Clean up ... |
616 |
The nlink can't _become_ zero at this point because we're |
1da177e4c Linux-2.6.12-rc2 |
617 618 619 620 621 |
holding the alloc_sem, and jffs2_do_unlink() would also need that while decrementing nlink on any inode. */ inode = ilookup(OFNI_BS_2SFFJ(c), inum); if (!inode) { |
9c261b33a jffs2: Convert mo... |
622 623 624 |
jffs2_dbg(1, "ilookup() failed for ino #%u; inode is probably deleted. ", inum); |
1da177e4c Linux-2.6.12-rc2 |
625 626 627 628 |
spin_lock(&c->inocache_lock); ic = jffs2_get_ino_cache(c, inum); if (!ic) { |
9c261b33a jffs2: Convert mo... |
629 630 631 |
jffs2_dbg(1, "Inode cache for ino #%u is gone ", inum); |
1da177e4c Linux-2.6.12-rc2 |
632 633 634 635 636 |
spin_unlock(&c->inocache_lock); return NULL; } if (ic->state != INO_STATE_CHECKEDABSENT) { /* Wait for progress. Don't just loop */ |
9c261b33a jffs2: Convert mo... |
637 638 639 |
jffs2_dbg(1, "Waiting for ino #%u in state %d ", ic->ino, ic->state); |
1da177e4c Linux-2.6.12-rc2 |
640 641 642 643 644 645 646 647 648 649 650 651 |
sleep_on_spinunlock(&c->inocache_wq, &c->inocache_lock); } else { spin_unlock(&c->inocache_lock); } return NULL; } } else { /* Inode has links to it still; they're not going away because jffs2_do_unlink() would need the alloc_sem and we have it. Just iget() it, and if read_inode() is necessary that's OK. */ |
5451f79f5 iget: stop JFFS2 ... |
652 653 654 |
inode = jffs2_iget(OFNI_BS_2SFFJ(c), inum); if (IS_ERR(inode)) return ERR_CAST(inode); |
1da177e4c Linux-2.6.12-rc2 |
655 656 |
} if (is_bad_inode(inode)) { |
da320f055 jffs2: Convert pr... |
657 658 659 |
pr_notice("Eep. read_inode() failed for ino #%u. unlinked %d ", inum, unlinked); |
1da177e4c Linux-2.6.12-rc2 |
660 661 662 663 664 665 666 |
/* NB. This will happen again. We need to do something appropriate here. */ iput(inode); return ERR_PTR(-EIO); } return JFFS2_INODE_INFO(inode); } |
1da177e4c Linux-2.6.12-rc2 |
667 668 |
static int jffs2_flash_setup(struct jffs2_sb_info *c) { int ret = 0; |
182ec4eee [JFFS2] Clean up ... |
669 |
|
1da177e4c Linux-2.6.12-rc2 |
670 671 672 673 674 675 |
if (jffs2_cleanmarker_oob(c)) { /* NAND flash... do setup accordingly */ ret = jffs2_nand_flash_setup(c); if (ret) return ret; } |
8f15fd55f [JFFS2] Add suppo... |
676 677 678 679 680 681 |
/* and Dataflash */ if (jffs2_dataflash(c)) { ret = jffs2_dataflash_setup(c); if (ret) return ret; } |
59da721a2 [JFFS2] Teach JFF... |
682 683 684 685 686 687 688 |
/* and Intel "Sibley" flash */ if (jffs2_nor_wbuf_flash(c)) { ret = jffs2_nor_wbuf_flash_setup(c); if (ret) return ret; } |
0029da3bf JFFS2: add UBI su... |
689 690 691 692 693 694 |
/* and an UBI volume */ if (jffs2_ubivol(c)) { ret = jffs2_ubivol_setup(c); if (ret) return ret; } |
1da177e4c Linux-2.6.12-rc2 |
695 696 697 698 699 700 701 702 |
return ret; } void jffs2_flash_cleanup(struct jffs2_sb_info *c) { if (jffs2_cleanmarker_oob(c)) { jffs2_nand_flash_cleanup(c); } |
8f15fd55f [JFFS2] Add suppo... |
703 704 705 706 |
/* and DataFlash */ if (jffs2_dataflash(c)) { jffs2_dataflash_cleanup(c); } |
59da721a2 [JFFS2] Teach JFF... |
707 708 709 710 711 |
/* and Intel "Sibley" flash */ if (jffs2_nor_wbuf_flash(c)) { jffs2_nor_wbuf_flash_cleanup(c); } |
0029da3bf JFFS2: add UBI su... |
712 713 714 715 716 |
/* and an UBI volume */ if (jffs2_ubivol(c)) { jffs2_ubivol_cleanup(c); } |
1da177e4c Linux-2.6.12-rc2 |
717 |
} |