/* 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 */
mdatalen = jffs2_encode_dev(&dev, inode->i_rdev);
mdata = (char *)&dev;
jffs2_dbg(1, "%s(): Writing %d bytes of kdev_t\n",
__func__, mdatalen);
} elseif (S_ISLNK(inode->i_mode)) {
mutex_lock(&f->sem);
mdatalen = f->metadata->size;
mdata = kmalloc(f->metadata->size, GFP_USER); if (!mdata) {
mutex_unlock(&f->sem); return -ENOMEM;
}
ret = jffs2_read_dnode(c, f, f->metadata, mdata, 0, mdatalen); if (ret) {
mutex_unlock(&f->sem);
kfree(mdata); return ret;
}
mutex_unlock(&f->sem);
jffs2_dbg(1, "%s(): Writing %d bytes of symlink target\n",
__func__, mdatalen);
}
ri = jffs2_alloc_raw_inode(); if (!ri) { if (S_ISLNK(inode->i_mode))
kfree(mdata); return -ENOMEM;
}
ret = jffs2_reserve_space(c, sizeof(*ri) + mdatalen, &alloclen,
ALLOC_NORMAL, JFFS2_SUMMARY_INODE_SIZE); if (ret) {
jffs2_free_raw_inode(ri); if (S_ISLNK(inode->i_mode))
kfree(mdata); return ret;
}
mutex_lock(&f->sem);
ivalid = iattr->ia_valid;
/* We have to do the truncate_setsize() without f->sem held, since some pages may be locked and waiting for it in read_folio(). We are protected from a simultaneous write() extending i_size back past iattr->ia_size, because do_truncate() holds the
generic inode semaphore. */ if (ivalid & ATTR_SIZE && inode->i_size > iattr->ia_size) {
truncate_setsize(inode, iattr->ia_size);
inode->i_blocks = (inode->i_size + 511) >> 9;
}
return 0;
}
int jffs2_setattr(struct mnt_idmap *idmap, struct dentry *dentry, struct iattr *iattr)
{ struct inode *inode = d_inode(dentry); int rc;
rc = setattr_prepare(&nop_mnt_idmap, dentry, iattr); if (rc) return rc;
void jffs2_evict_inode (struct inode *inode)
{ /* We can forget about this inode for now - drop all * 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);
case S_IFLNK:
inode->i_op = &jffs2_symlink_inode_operations;
inode->i_link = f->target; break;
case S_IFDIR:
{ struct jffs2_full_dirent *fd;
set_nlink(inode, 2); /* parent and '.' */
for (fd=f->dents; fd; fd = fd->next) { if (fd->type == DT_DIR && fd->ino)
inc_nlink(inode);
} /* Root dir gets i_nlink 3 for some reason */ if (inode->i_ino == 1)
inc_nlink(inode);
if (c->flags & JFFS2_SB_FLAG_RO && !sb_rdonly(sb)) 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 necessary, else we loose it */ if (!sb_rdonly(sb)) {
jffs2_stop_garbage_collect_thread(c);
mutex_lock(&c->alloc_sem);
jffs2_flush_wbuf_pad(c);
mutex_unlock(&c->alloc_sem);
}
if (!(fc->sb_flags & SB_RDONLY))
jffs2_start_garbage_collect_thread(c);
fc->sb_flags |= SB_NOATIME; return 0;
}
/* jffs2_new_inode: allocate a new inode and inocache, add it to the hash,
fill in the raw_inode while you're at it. */ struct inode *jffs2_new_inode (struct inode *dir_i, umode_t mode, struct jffs2_raw_inode *ri)
{ struct inode *inode; struct super_block *sb = dir_i->i_sb; struct jffs2_sb_info *c; struct jffs2_inode_info *f; int ret;
staticint 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;
}
int jffs2_do_fill_super(struct super_block *sb, struct fs_context *fc)
{ struct jffs2_sb_info *c; struct inode *root_i; int ret;
size_t blocks;
c = JFFS2_SB_INFO(sb);
/* Do not support the MLC nand */ if (c->mtd->type == MTD_MLCNANDFLASH) return -EINVAL;
#ifndef CONFIG_JFFS2_FS_WRITEBUFFER if (c->mtd->type == MTD_NANDFLASH) {
errorf(fc, "Cannot operate on NAND flash unless jffs2 NAND support is compiled in"); return -EINVAL;
} if (c->mtd->type == MTD_DATAFLASH) {
errorf(fc, "Cannot operate on DataFlash unless jffs2 DataFlash support is compiled in"); return -EINVAL;
} #endif
struct jffs2_inode_info *jffs2_gc_fetch_inode(struct jffs2_sb_info *c, int inum, int unlinked)
{ struct inode *inode; struct jffs2_inode_cache *ic;
if (unlinked) { /* The inode has zero nlink but its nodes weren't yet marked obsolete. This has to be because we're still waiting for the final (close() and) iput() to happen.
There's a possibility that the final iput() could have 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().
The nlink can't _become_ zero at this point because we're 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) {
jffs2_dbg(1, "ilookup() failed for ino #%u; inode is probably deleted.\n",
inum);
spin_lock(&c->inocache_lock);
ic = jffs2_get_ino_cache(c, inum); if (!ic) {
jffs2_dbg(1, "Inode cache for ino #%u is gone\n",
inum);
spin_unlock(&c->inocache_lock); return NULL;
} if (ic->state != INO_STATE_CHECKEDABSENT) { /* Wait for progress. Don't just loop */
jffs2_dbg(1, "Waiting for ino #%u in state %d\n",
ic->ino, ic->state);
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.
*/
inode = jffs2_iget(OFNI_BS_2SFFJ(c), inum); if (IS_ERR(inode)) return ERR_CAST(inode);
} if (is_bad_inode(inode)) {
pr_notice("Eep. read_inode() failed for ino #%u. unlinked %d\n",
inum, unlinked); /* NB. This will happen again. We need to do something appropriate here. */
iput(inode); return ERR_PTR(-EIO);
}
return JFFS2_INODE_INFO(inode);
}
staticint jffs2_flash_setup(struct jffs2_sb_info *c) { int ret = 0;
if (jffs2_cleanmarker_oob(c)) { /* NAND flash... do setup accordingly */
ret = jffs2_nand_flash_setup(c); if (ret) return ret;
}
/* and Dataflash */ if (jffs2_dataflash(c)) {
ret = jffs2_dataflash_setup(c); if (ret) return ret;
}
/* and Intel "Sibley" flash */ if (jffs2_nor_wbuf_flash(c)) {
ret = jffs2_nor_wbuf_flash_setup(c); if (ret) return ret;
}
/* and an UBI volume */ if (jffs2_ubivol(c)) {
ret = jffs2_ubivol_setup(c); if (ret) return ret;
}
Die Informationen auf dieser Webseite wurden
nach bestem Wissen sorgfältig zusammengestellt. Es wird jedoch weder Vollständigkeit, noch Richtigkeit,
noch Qualität der bereit gestellten Informationen zugesichert.
Bemerkung:
Die farbliche Syntaxdarstellung und die Messung sind noch experimentell.