?? fs.c
字號:
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);}int jffs2_remount_fs (struct super_block *sb, int *flags, char *data){ struct jffs2_sb_info *c = JFFS2_SB_INFO(sb); if (c->flags & JFFS2_SB_FLAG_RO && !(sb->s_flags & MS_RDONLY)) 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 */ if (!(sb->s_flags & MS_RDONLY)) { jffs2_stop_garbage_collect_thread(c); down(&c->alloc_sem); jffs2_flush_wbuf_pad(c); up(&c->alloc_sem); } if (!(*flags & MS_RDONLY)) jffs2_start_garbage_collect_thread(c); *flags |= MS_NOATIME; return 0;}void jffs2_write_super (struct super_block *sb){ struct jffs2_sb_info *c = JFFS2_SB_INFO(sb); sb->s_dirt = 0; if (sb->s_flags & MS_RDONLY) return; D1(printk(KERN_DEBUG "jffs2_write_super()\n")); jffs2_garbage_collect_trigger(c); jffs2_erase_pending_blocks(c, 0); jffs2_flush_wbuf_gc(c, 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, int 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; D1(printk(KERN_DEBUG "jffs2_new_inode(): dir_i %ld, mode 0x%x\n", dir_i->i_ino, mode)); c = JFFS2_SB_INFO(sb); inode = new_inode(sb); if (!inode) return ERR_PTR(-ENOMEM); f = JFFS2_INODE_INFO(inode); jffs2_init_inode_info(f); memset(ri, 0, sizeof(*ri)); /* Set OS-specific defaults for new inodes */ ri->uid = cpu_to_je16(current->fsuid); if (dir_i->i_mode & S_ISGID) { ri->gid = cpu_to_je16(dir_i->i_gid); if (S_ISDIR(mode)) mode |= S_ISGID; } else { ri->gid = cpu_to_je16(current->fsgid); } ri->mode = cpu_to_jemode(mode); ret = jffs2_do_new_inode (c, f, mode, ri); if (ret) { make_bad_inode(inode); iput(inode); return ERR_PTR(ret); } inode->i_nlink = 1; inode->i_ino = je32_to_cpu(ri->ino); inode->i_mode = jemode_to_cpu(ri->mode); inode->i_gid = je16_to_cpu(ri->gid); inode->i_uid = je16_to_cpu(ri->uid); inode->i_atime = inode->i_ctime = inode->i_mtime = CURRENT_TIME; ri->atime = ri->mtime = ri->ctime = cpu_to_je32(I_SEC(inode->i_mtime)); inode->i_blksize = PAGE_SIZE; inode->i_blocks = 0; inode->i_size = 0; insert_inode_hash(inode); return inode;}int jffs2_do_fill_super(struct super_block *sb, void *data, int silent){ struct jffs2_sb_info *c; struct inode *root_i; int ret; size_t blocks; c = JFFS2_SB_INFO(sb);#ifndef CONFIG_JFFS2_FS_NAND if (c->mtd->type == MTD_NANDFLASH) { printk(KERN_ERR "jffs2: Cannot operate on NAND flash unless jffs2 NAND support is compiled in.\n"); return -EINVAL; }#endif c->flash_size = c->mtd->size; /* * Check, if we have to concatenate physical blocks to larger virtual blocks * to reduce the memorysize for c->blocks. (kmalloc allows max. 128K allocation) */ c->sector_size = c->mtd->erasesize; blocks = c->flash_size / c->sector_size; while ((blocks * sizeof (struct jffs2_eraseblock)) > (128 * 1024)) { blocks >>= 1; c->sector_size <<= 1; } /* * Size alignment check */ if ((c->sector_size * blocks) != c->flash_size) { c->flash_size = c->sector_size * blocks; printk(KERN_INFO "jffs2: Flash size not aligned to erasesize, reducing to %dKiB\n", c->flash_size / 1024); } if (c->sector_size != c->mtd->erasesize) printk(KERN_INFO "jffs2: Erase block size too small (%dKiB). Using virtual blocks size (%dKiB) instead\n", c->mtd->erasesize / 1024, c->sector_size / 1024); if (c->flash_size < 5*c->sector_size) { printk(KERN_ERR "jffs2: Too few erase blocks (%d)\n", c->flash_size / c->sector_size); return -EINVAL; } c->cleanmarker_size = sizeof(struct jffs2_unknown_node); /* Joern -- stick alignment for weird 8-byte-page flash here */ /* NAND (or other bizarre) flash... do setup accordingly */ ret = jffs2_flash_setup(c); if (ret) return ret; c->inocache_list = kmalloc(INOCACHE_HASHSIZE * sizeof(struct jffs2_inode_cache *), GFP_KERNEL); if (!c->inocache_list) { ret = -ENOMEM; goto out_wbuf; } memset(c->inocache_list, 0, INOCACHE_HASHSIZE * sizeof(struct jffs2_inode_cache *)); if ((ret = jffs2_do_mount_fs(c))) goto out_inohash; ret = -EINVAL; D1(printk(KERN_DEBUG "jffs2_do_fill_super(): Getting root inode\n")); root_i = iget(sb, 1); if (is_bad_inode(root_i)) { D1(printk(KERN_WARNING "get root inode failed\n")); goto out_nodes; } D1(printk(KERN_DEBUG "jffs2_do_fill_super(): d_alloc_root()\n")); sb->s_root = d_alloc_root(root_i); if (!sb->s_root) goto out_root_i;#if LINUX_VERSION_CODE >= 0x20403 sb->s_maxbytes = 0xFFFFFFFF;#endif sb->s_blocksize = PAGE_CACHE_SIZE; sb->s_blocksize_bits = PAGE_CACHE_SHIFT; sb->s_magic = JFFS2_SUPER_MAGIC; if (!(sb->s_flags & MS_RDONLY)) jffs2_start_garbage_collect_thread(c); return 0; out_root_i: iput(root_i); out_nodes: jffs2_free_ino_caches(c); jffs2_free_raw_node_refs(c); kfree(c->blocks); out_inohash: 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, int inum, int nlink){ struct inode *inode; struct jffs2_inode_cache *ic; if (!nlink) { /* 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) { D1(printk(KERN_DEBUG "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) { D1(printk(KERN_DEBUG "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 */ D1(printk(KERN_DEBUG "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 = iget(OFNI_BS_2SFFJ(c), inum); if (!inode) return ERR_PTR(-ENOMEM); } if (is_bad_inode(inode)) { printk(KERN_NOTICE "Eep. read_inode() failed for ino #%u. nlink %d\n", inum, nlink); /* NB. This will happen again. We need to do something appropriate here. */ iput(inode); return ERR_PTR(-EIO); } return JFFS2_INODE_INFO(inode);}unsigned char *jffs2_gc_fetch_page(struct jffs2_sb_info *c, struct jffs2_inode_info *f, unsigned long offset, unsigned long *priv){ struct inode *inode = OFNI_EDONI_2SFFJ(f); struct page *pg; pg = read_cache_page(inode->i_mapping, offset >> PAGE_CACHE_SHIFT, (void *)jffs2_do_readpage_unlock, inode); if (IS_ERR(pg)) return (void *)pg; *priv = (unsigned long)pg; return kmap(pg);}void jffs2_gc_release_page(struct jffs2_sb_info *c, unsigned char *ptr, unsigned long *priv){ struct page *pg = (void *)*priv; kunmap(pg); page_cache_release(pg);}int 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; } /* add setups for other bizarre flashes here... */ return ret;}void jffs2_flash_cleanup(struct jffs2_sb_info *c) { if (jffs2_cleanmarker_oob(c)) { jffs2_nand_flash_cleanup(c); } /* add cleanups for other bizarre flashes here... */}
?? 快捷鍵說明
復制代碼
Ctrl + C
搜索代碼
Ctrl + F
全屏模式
F11
切換主題
Ctrl + Shift + D
顯示快捷鍵
?
增大字號
Ctrl + =
減小字號
Ctrl + -