📄 super.c
字号:
s->s_root = NULL; goto error; } if ((errval = reiserfs_xattr_init(s, s->s_flags))) { dput(s->s_root); s->s_root = NULL; goto error; } /* look for files which were to be removed in previous session */ finish_unfinished(s); } else { if (old_format_only(s) && !silent) { reiserfs_info(s, "using 3.5.x disk format\n"); } if ((errval = reiserfs_xattr_init(s, s->s_flags))) { dput(s->s_root); s->s_root = NULL; goto error; } } // mark hash in super block: it could be unset. overwrite should be ok set_sb_hash_function_code(rs, function2code(sbi->s_hash_function)); handle_attrs(s); reiserfs_proc_info_init(s); init_waitqueue_head(&(sbi->s_wait)); spin_lock_init(&sbi->bitmap_lock); return (0); error: if (jinit_done) { /* kill the commit thread, free journal ram */ journal_release_error(NULL, s); } reiserfs_free_bitmap_cache(s); if (SB_BUFFER_WITH_SB(s)) brelse(SB_BUFFER_WITH_SB(s));#ifdef CONFIG_QUOTA { int j; for (j = 0; j < MAXQUOTAS; j++) { kfree(sbi->s_qf_names[j]); sbi->s_qf_names[j] = NULL; } }#endif kfree(sbi); s->s_fs_info = NULL; return errval;}static int reiserfs_statfs(struct dentry *dentry, struct kstatfs *buf){ struct reiserfs_super_block *rs = SB_DISK_SUPER_BLOCK(dentry->d_sb); buf->f_namelen = (REISERFS_MAX_NAME(s->s_blocksize)); buf->f_bfree = sb_free_blocks(rs); buf->f_bavail = buf->f_bfree; buf->f_blocks = sb_block_count(rs) - sb_bmap_nr(rs) - 1; buf->f_bsize = dentry->d_sb->s_blocksize; /* changed to accommodate gcc folks. */ buf->f_type = REISERFS_SUPER_MAGIC; return 0;}#ifdef CONFIG_QUOTAstatic int reiserfs_dquot_initialize(struct inode *inode, int type){ struct reiserfs_transaction_handle th; int ret, err; /* We may create quota structure so we need to reserve enough blocks */ reiserfs_write_lock(inode->i_sb); ret = journal_begin(&th, inode->i_sb, 2 * REISERFS_QUOTA_INIT_BLOCKS(inode->i_sb)); if (ret) goto out; ret = dquot_initialize(inode, type); err = journal_end(&th, inode->i_sb, 2 * REISERFS_QUOTA_INIT_BLOCKS(inode->i_sb)); if (!ret && err) ret = err; out: reiserfs_write_unlock(inode->i_sb); return ret;}static int reiserfs_dquot_drop(struct inode *inode){ struct reiserfs_transaction_handle th; int ret, err; /* We may delete quota structure so we need to reserve enough blocks */ reiserfs_write_lock(inode->i_sb); ret = journal_begin(&th, inode->i_sb, 2 * REISERFS_QUOTA_DEL_BLOCKS(inode->i_sb)); if (ret) goto out; ret = dquot_drop(inode); err = journal_end(&th, inode->i_sb, 2 * REISERFS_QUOTA_DEL_BLOCKS(inode->i_sb)); if (!ret && err) ret = err; out: reiserfs_write_unlock(inode->i_sb); return ret;}static int reiserfs_write_dquot(struct dquot *dquot){ struct reiserfs_transaction_handle th; int ret, err; reiserfs_write_lock(dquot->dq_sb); ret = journal_begin(&th, dquot->dq_sb, REISERFS_QUOTA_TRANS_BLOCKS(dquot->dq_sb)); if (ret) goto out; ret = dquot_commit(dquot); err = journal_end(&th, dquot->dq_sb, REISERFS_QUOTA_TRANS_BLOCKS(dquot->dq_sb)); if (!ret && err) ret = err; out: reiserfs_write_unlock(dquot->dq_sb); return ret;}static int reiserfs_acquire_dquot(struct dquot *dquot){ struct reiserfs_transaction_handle th; int ret, err; reiserfs_write_lock(dquot->dq_sb); ret = journal_begin(&th, dquot->dq_sb, REISERFS_QUOTA_INIT_BLOCKS(dquot->dq_sb)); if (ret) goto out; ret = dquot_acquire(dquot); err = journal_end(&th, dquot->dq_sb, REISERFS_QUOTA_INIT_BLOCKS(dquot->dq_sb)); if (!ret && err) ret = err; out: reiserfs_write_unlock(dquot->dq_sb); return ret;}static int reiserfs_release_dquot(struct dquot *dquot){ struct reiserfs_transaction_handle th; int ret, err; reiserfs_write_lock(dquot->dq_sb); ret = journal_begin(&th, dquot->dq_sb, REISERFS_QUOTA_DEL_BLOCKS(dquot->dq_sb)); if (ret) { /* Release dquot anyway to avoid endless cycle in dqput() */ dquot_release(dquot); goto out; } ret = dquot_release(dquot); err = journal_end(&th, dquot->dq_sb, REISERFS_QUOTA_DEL_BLOCKS(dquot->dq_sb)); if (!ret && err) ret = err; out: reiserfs_write_unlock(dquot->dq_sb); return ret;}static int reiserfs_mark_dquot_dirty(struct dquot *dquot){ /* Are we journalling quotas? */ if (REISERFS_SB(dquot->dq_sb)->s_qf_names[USRQUOTA] || REISERFS_SB(dquot->dq_sb)->s_qf_names[GRPQUOTA]) { dquot_mark_dquot_dirty(dquot); return reiserfs_write_dquot(dquot); } else return dquot_mark_dquot_dirty(dquot);}static int reiserfs_write_info(struct super_block *sb, int type){ struct reiserfs_transaction_handle th; int ret, err; /* Data block + inode block */ reiserfs_write_lock(sb); ret = journal_begin(&th, sb, 2); if (ret) goto out; ret = dquot_commit_info(sb, type); err = journal_end(&th, sb, 2); if (!ret && err) ret = err; out: reiserfs_write_unlock(sb); return ret;}/* * Turn on quotas during mount time - we need to find the quota file and such... */static int reiserfs_quota_on_mount(struct super_block *sb, int type){ return vfs_quota_on_mount(sb, REISERFS_SB(sb)->s_qf_names[type], REISERFS_SB(sb)->s_jquota_fmt, type);}/* * Standard function to be called on quota_on */static int reiserfs_quota_on(struct super_block *sb, int type, int format_id, char *path){ int err; struct nameidata nd; if (!(REISERFS_SB(sb)->s_mount_opt & (1 << REISERFS_QUOTA))) return -EINVAL; err = path_lookup(path, LOOKUP_FOLLOW, &nd); if (err) return err; /* Quotafile not on the same filesystem? */ if (nd.mnt->mnt_sb != sb) { path_release(&nd); return -EXDEV; } /* We must not pack tails for quota files on reiserfs for quota IO to work */ if (!REISERFS_I(nd.dentry->d_inode)->i_flags & i_nopack_mask) { reiserfs_warning(sb, "reiserfs: Quota file must have tail packing disabled."); path_release(&nd); return -EINVAL; } /* Not journalling quota? No more tests needed... */ if (!REISERFS_SB(sb)->s_qf_names[USRQUOTA] && !REISERFS_SB(sb)->s_qf_names[GRPQUOTA]) { path_release(&nd); return vfs_quota_on(sb, type, format_id, path); } /* Quotafile not of fs root? */ if (nd.dentry->d_parent->d_inode != sb->s_root->d_inode) reiserfs_warning(sb, "reiserfs: Quota file not on filesystem root. " "Journalled quota will not work."); path_release(&nd); return vfs_quota_on(sb, type, format_id, path);}/* 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 reiserfs_quota_read(struct super_block *sb, int type, char *data, size_t len, loff_t off){ struct inode *inode = sb_dqopt(sb)->files[type]; unsigned long blk = off >> sb->s_blocksize_bits; int err = 0, offset = off & (sb->s_blocksize - 1), tocopy; size_t toread; struct buffer_head tmp_bh, *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; /* Quota files are without tails so we can safely use this function */ reiserfs_write_lock(sb); err = reiserfs_get_block(inode, blk, &tmp_bh, 0); reiserfs_write_unlock(sb); 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 (we know the transaction is already started and has * enough credits) */static ssize_t reiserfs_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]; unsigned long blk = off >> sb->s_blocksize_bits; int err = 0, offset = off & (sb->s_blocksize - 1), tocopy; int journal_quota = REISERFS_SB(sb)->s_qf_names[type] != NULL; size_t towrite = len; struct buffer_head tmp_bh, *bh; if (!current->journal_info) { printk(KERN_WARNING "reiserfs: Quota write (off=%Lu, len=%Lu)" " cancelled because transaction is not started.\n", (unsigned long long)off, (unsigned long long)len); return -EIO; } mutex_lock_nested(&inode->i_mutex, I_MUTEX_QUOTA); while (towrite > 0) { tocopy = sb->s_blocksize - offset < towrite ? sb->s_blocksize - offset : towrite; tmp_bh.b_state = 0; err = reiserfs_get_block(inode, blk, &tmp_bh, GET_BLOCK_CREATE); 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); unlock_buffer(bh); reiserfs_prepare_for_journal(sb, bh, 1); journal_mark_dirty(current->journal_info, sb, bh); if (!journal_quota) reiserfs_add_ordered_list(inode, 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 int get_super_block(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, reiserfs_fill_super, mnt);}static int __init init_reiserfs_fs(void){ int ret; if ((ret = init_inodecache())) { return ret; } if ((ret = reiserfs_xattr_register_handlers())) goto failed_reiserfs_xattr_register_handlers; reiserfs_proc_info_global_init(); reiserfs_proc_register_global("version", reiserfs_global_version_in_proc); ret = register_filesystem(&reiserfs_fs_type); if (ret == 0) { return 0; } reiserfs_xattr_unregister_handlers(); failed_reiserfs_xattr_register_handlers: reiserfs_proc_unregister_global("version"); reiserfs_proc_info_global_done(); destroy_inodecache(); return ret;}static void __exit exit_reiserfs_fs(void){ reiserfs_xattr_unregister_handlers(); reiserfs_proc_unregister_global("version"); reiserfs_proc_info_global_done(); unregister_filesystem(&reiserfs_fs_type); destroy_inodecache();}struct file_system_type reiserfs_fs_type = { .owner = THIS_MODULE, .name = "reiserfs", .get_sb = get_super_block, .kill_sb = reiserfs_kill_sb, .fs_flags = FS_REQUIRES_DEV,};MODULE_DESCRIPTION("ReiserFS journaled filesystem");MODULE_AUTHOR("Hans Reiser <reiser@namesys.com>");MODULE_LICENSE("GPL");module_init(init_reiserfs_fs);module_exit(exit_reiserfs_fs);
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -