📄 super.c
字号:
#ifdef CONFIG_JFS_POSIX_ACL sb->s_flags |= MS_POSIXACL;#endif if (newLVSize) { printk(KERN_ERR "resize option for remount only\n"); return -EINVAL; } /* * Initialize blocksize to 4K. */ sb_set_blocksize(sb, PSIZE); /* * Set method vectors. */ sb->s_op = &jfs_super_operations; sb->s_export_op = &jfs_export_operations; /* * Initialize direct-mapping inode/address-space */ inode = new_inode(sb); if (inode == NULL) goto out_kfree; inode->i_ino = 0; inode->i_nlink = 1; inode->i_size = sb->s_bdev->bd_inode->i_size; inode->i_mapping->a_ops = &jfs_metapage_aops; insert_inode_hash(inode); mapping_set_gfp_mask(inode->i_mapping, GFP_NOFS); sbi->direct_inode = inode; rc = jfs_mount(sb); if (rc) { if (!silent) { jfs_err("jfs_mount failed w/return code = %d", rc); } goto out_mount_failed; } if (sb->s_flags & MS_RDONLY) sbi->log = NULL; else { rc = jfs_mount_rw(sb, 0); if (rc) { if (!silent) { jfs_err("jfs_mount_rw failed, return code = %d", rc); } goto out_no_rw; } } sb->s_magic = JFS_SUPER_MAGIC; inode = iget(sb, ROOT_I); if (!inode || is_bad_inode(inode)) goto out_no_root; sb->s_root = d_alloc_root(inode); if (!sb->s_root) goto out_no_root; if (sbi->mntflag & JFS_OS2) sb->s_root->d_op = &jfs_ci_dentry_operations; /* logical blocks are represented by 40 bits in pxd_t, etc. */ sb->s_maxbytes = ((u64) sb->s_blocksize) << 40;#if BITS_PER_LONG == 32 /* * Page cache is indexed by long. * I would use MAX_LFS_FILESIZE, but it's only half as big */ sb->s_maxbytes = min(((u64) PAGE_CACHE_SIZE << 32) - 1, sb->s_maxbytes);#endif sb->s_time_gran = 1; return 0;out_no_root: jfs_err("jfs_read_super: get root inode failed"); if (inode) iput(inode);out_no_rw: rc = jfs_umount(sb); if (rc) { jfs_err("jfs_umount failed with return code %d", rc); }out_mount_failed: filemap_write_and_wait(sbi->direct_inode->i_mapping); truncate_inode_pages(sbi->direct_inode->i_mapping, 0); make_bad_inode(sbi->direct_inode); iput(sbi->direct_inode); sbi->direct_inode = NULL;out_kfree: if (sbi->nls_tab) unload_nls(sbi->nls_tab); kfree(sbi); return -EINVAL;}static void jfs_write_super_lockfs(struct super_block *sb){ struct jfs_sb_info *sbi = JFS_SBI(sb); struct jfs_log *log = sbi->log; if (!(sb->s_flags & MS_RDONLY)) { txQuiesce(sb); lmLogShutdown(log); updateSuper(sb, FM_CLEAN); }}static void jfs_unlockfs(struct super_block *sb){ struct jfs_sb_info *sbi = JFS_SBI(sb); struct jfs_log *log = sbi->log; int rc = 0; if (!(sb->s_flags & MS_RDONLY)) { updateSuper(sb, FM_MOUNT); if ((rc = lmLogInit(log))) jfs_err("jfs_unlock failed with return code %d", rc); else txResume(sb); }}static int jfs_get_sb(struct file_system_type *fs_type, int flags, const char *dev_name, void *data, struct vfsmount *mnt){ return get_sb_bdev(fs_type, flags, dev_name, data, jfs_fill_super, mnt);}static int jfs_sync_fs(struct super_block *sb, int wait){ struct jfs_log *log = JFS_SBI(sb)->log; /* log == NULL indicates read-only mount */ if (log) { jfs_flush_journal(log, wait); jfs_syncpt(log, 0); } return 0;}static int jfs_show_options(struct seq_file *seq, struct vfsmount *vfs){ struct jfs_sb_info *sbi = JFS_SBI(vfs->mnt_sb); if (sbi->uid != -1) seq_printf(seq, ",uid=%d", sbi->uid); if (sbi->gid != -1) seq_printf(seq, ",gid=%d", sbi->gid); if (sbi->umask != -1) seq_printf(seq, ",umask=%03o", sbi->umask); if (sbi->flag & JFS_NOINTEGRITY) seq_puts(seq, ",nointegrity");#ifdef CONFIG_QUOTA if (sbi->flag & JFS_USRQUOTA) seq_puts(seq, ",usrquota"); if (sbi->flag & JFS_GRPQUOTA) seq_puts(seq, ",grpquota");#endif return 0;}#ifdef CONFIG_QUOTA/* Read data from quotafile - avoid pagecache and such because we cannot afford * acquiring the locks... As quota files are never truncated and quota code * itself serializes the operations (and noone else should touch the files) * we don't have to be afraid of races */static ssize_t jfs_quota_read(struct super_block *sb, int type, char *data, size_t len, loff_t off){ struct inode *inode = sb_dqopt(sb)->files[type]; sector_t blk = off >> sb->s_blocksize_bits; int err = 0; int offset = off & (sb->s_blocksize - 1); int tocopy; size_t toread; struct buffer_head tmp_bh; struct buffer_head *bh; loff_t i_size = i_size_read(inode); if (off > i_size) return 0; if (off+len > i_size) len = i_size-off; toread = len; while (toread > 0) { tocopy = sb->s_blocksize - offset < toread ? sb->s_blocksize - offset : toread; tmp_bh.b_state = 0; tmp_bh.b_size = 1 << inode->i_blkbits; err = jfs_get_block(inode, blk, &tmp_bh, 0); if (err) return err; if (!buffer_mapped(&tmp_bh)) /* A hole? */ memset(data, 0, tocopy); else { bh = sb_bread(sb, tmp_bh.b_blocknr); if (!bh) return -EIO; memcpy(data, bh->b_data+offset, tocopy); brelse(bh); } offset = 0; toread -= tocopy; data += tocopy; blk++; } return len;}/* Write to quotafile */static ssize_t jfs_quota_write(struct super_block *sb, int type, const char *data, size_t len, loff_t off){ struct inode *inode = sb_dqopt(sb)->files[type]; sector_t blk = off >> sb->s_blocksize_bits; int err = 0; int offset = off & (sb->s_blocksize - 1); int tocopy; size_t towrite = len; struct buffer_head tmp_bh; struct buffer_head *bh; mutex_lock(&inode->i_mutex); while (towrite > 0) { tocopy = sb->s_blocksize - offset < towrite ? sb->s_blocksize - offset : towrite; tmp_bh.b_state = 0; tmp_bh.b_size = 1 << inode->i_blkbits; err = jfs_get_block(inode, blk, &tmp_bh, 1); if (err) goto out; if (offset || tocopy != sb->s_blocksize) bh = sb_bread(sb, tmp_bh.b_blocknr); else bh = sb_getblk(sb, tmp_bh.b_blocknr); if (!bh) { err = -EIO; goto out; } lock_buffer(bh); memcpy(bh->b_data+offset, data, tocopy); flush_dcache_page(bh->b_page); set_buffer_uptodate(bh); mark_buffer_dirty(bh); unlock_buffer(bh); brelse(bh); offset = 0; towrite -= tocopy; data += tocopy; blk++; }out: if (len == towrite) return err; if (inode->i_size < off+len-towrite) i_size_write(inode, off+len-towrite); inode->i_version++; inode->i_mtime = inode->i_ctime = CURRENT_TIME; mark_inode_dirty(inode); mutex_unlock(&inode->i_mutex); return len - towrite;}#endifstatic const struct super_operations jfs_super_operations = { .alloc_inode = jfs_alloc_inode, .destroy_inode = jfs_destroy_inode, .read_inode = jfs_read_inode, .dirty_inode = jfs_dirty_inode, .write_inode = jfs_write_inode, .delete_inode = jfs_delete_inode, .put_super = jfs_put_super, .sync_fs = jfs_sync_fs, .write_super_lockfs = jfs_write_super_lockfs, .unlockfs = jfs_unlockfs, .statfs = jfs_statfs, .remount_fs = jfs_remount, .show_options = jfs_show_options,#ifdef CONFIG_QUOTA .quota_read = jfs_quota_read, .quota_write = jfs_quota_write,#endif};static const struct export_operations jfs_export_operations = { .fh_to_dentry = jfs_fh_to_dentry, .fh_to_parent = jfs_fh_to_parent, .get_parent = jfs_get_parent,};static struct file_system_type jfs_fs_type = { .owner = THIS_MODULE, .name = "jfs", .get_sb = jfs_get_sb, .kill_sb = kill_block_super, .fs_flags = FS_REQUIRES_DEV,};static void init_once(struct kmem_cache *cachep, void *foo){ struct jfs_inode_info *jfs_ip = (struct jfs_inode_info *) foo; memset(jfs_ip, 0, sizeof(struct jfs_inode_info)); INIT_LIST_HEAD(&jfs_ip->anon_inode_list); init_rwsem(&jfs_ip->rdwrlock); mutex_init(&jfs_ip->commit_mutex); init_rwsem(&jfs_ip->xattr_sem); spin_lock_init(&jfs_ip->ag_lock); jfs_ip->active_ag = -1;#ifdef CONFIG_JFS_POSIX_ACL jfs_ip->i_acl = JFS_ACL_NOT_CACHED; jfs_ip->i_default_acl = JFS_ACL_NOT_CACHED;#endif inode_init_once(&jfs_ip->vfs_inode);}static int __init init_jfs_fs(void){ int i; int rc; jfs_inode_cachep = kmem_cache_create("jfs_ip", sizeof(struct jfs_inode_info), 0, SLAB_RECLAIM_ACCOUNT|SLAB_MEM_SPREAD, init_once); if (jfs_inode_cachep == NULL) return -ENOMEM; /* * Metapage initialization */ rc = metapage_init(); if (rc) { jfs_err("metapage_init failed w/rc = %d", rc); goto free_slab; } /* * Transaction Manager initialization */ rc = txInit(); if (rc) { jfs_err("txInit failed w/rc = %d", rc); goto free_metapage; } /* * I/O completion thread (endio) */ jfsIOthread = kthread_run(jfsIOWait, NULL, "jfsIO"); if (IS_ERR(jfsIOthread)) { rc = PTR_ERR(jfsIOthread); jfs_err("init_jfs_fs: fork failed w/rc = %d", rc); goto end_txmngr; } if (commit_threads < 1) commit_threads = num_online_cpus(); if (commit_threads > MAX_COMMIT_THREADS) commit_threads = MAX_COMMIT_THREADS; for (i = 0; i < commit_threads; i++) { jfsCommitThread[i] = kthread_run(jfs_lazycommit, NULL, "jfsCommit"); if (IS_ERR(jfsCommitThread[i])) { rc = PTR_ERR(jfsCommitThread[i]); jfs_err("init_jfs_fs: fork failed w/rc = %d", rc); commit_threads = i; goto kill_committask; } } jfsSyncThread = kthread_run(jfs_sync, NULL, "jfsSync"); if (IS_ERR(jfsSyncThread)) { rc = PTR_ERR(jfsSyncThread); jfs_err("init_jfs_fs: fork failed w/rc = %d", rc); goto kill_committask; }#ifdef PROC_FS_JFS jfs_proc_init();#endif return register_filesystem(&jfs_fs_type);kill_committask: for (i = 0; i < commit_threads; i++) kthread_stop(jfsCommitThread[i]); kthread_stop(jfsIOthread);end_txmngr: txExit();free_metapage: metapage_exit();free_slab: kmem_cache_destroy(jfs_inode_cachep); return rc;}static void __exit exit_jfs_fs(void){ int i; jfs_info("exit_jfs_fs called"); txExit(); metapage_exit(); kthread_stop(jfsIOthread); for (i = 0; i < commit_threads; i++) kthread_stop(jfsCommitThread[i]); kthread_stop(jfsSyncThread);#ifdef PROC_FS_JFS jfs_proc_clean();#endif unregister_filesystem(&jfs_fs_type); kmem_cache_destroy(jfs_inode_cachep);}module_init(init_jfs_fs)module_exit(exit_jfs_fs)
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -