本文整理汇总了C++中HFSPLUS_I函数的典型用法代码示例。如果您正苦于以下问题:C++ HFSPLUS_I函数的具体用法?C++ HFSPLUS_I怎么用?C++ HFSPLUS_I使用的例子?那么恭喜您, 这里精选的函数代码示例或许可以为您提供帮助。
在下文中一共展示了HFSPLUS_I函数的20个代码示例,这些例子默认根据受欢迎程度排序。您可以为喜欢或者感觉有用的代码点赞,您的评价将有助于我们的系统推荐出更棒的C++代码示例。
示例1: hfsplus_unlink
static int hfsplus_unlink(struct inode *dir, struct dentry *dentry)
{
struct super_block *sb = dir->i_sb;
struct inode *inode = dentry->d_inode;
struct qstr str;
char name[32];
u32 cnid;
int res;
hfsplus_handle_t hfsplus_handle;
if (HFSPLUS_IS_RSRC(inode))
return -EPERM;
if ((res = hfsplus_journal_start(__FUNCTION__, dir->i_sb, &hfsplus_handle)))
return res;
cnid = (u32)(unsigned long)dentry->d_fsdata;
if (inode->i_ino == cnid &&
atomic_read(&HFSPLUS_I(inode).opencnt)) {
str.name = name;
str.len = sprintf(name, "temp%lu", inode->i_ino);
res = hfsplus_rename_cat(&hfsplus_handle, inode->i_ino,
dir, &dentry->d_name,
HFSPLUS_SB(sb).hidden_dir, &str);
if (!res)
inode->i_flags |= S_DEAD;
hfsplus_journal_stop(&hfsplus_handle);
return res;
}
res = hfsplus_delete_cat(&hfsplus_handle, cnid, dir, &dentry->d_name);
if (res) {
hfsplus_journal_stop(&hfsplus_handle);
return res;
}
if (inode->i_nlink > 0)
drop_nlink(inode);
if (inode->i_ino == cnid)
clear_nlink(inode);
if (!inode->i_nlink) {
if (inode->i_ino != cnid) {
HFSPLUS_SB(sb).file_count--;
if (!atomic_read(&HFSPLUS_I(inode).opencnt)) {
res = hfsplus_delete_cat(&hfsplus_handle, inode->i_ino, HFSPLUS_SB(sb).hidden_dir, NULL);
if (!res)
hfsplus_delete_inode(&hfsplus_handle, inode);
} else
inode->i_flags |= S_DEAD;
} else
hfsplus_delete_inode(&hfsplus_handle,inode);
} else
HFSPLUS_SB(sb).file_count--;
inode->i_ctime = CURRENT_TIME_SEC;
res = hfsplus_journalled_mark_inode_dirty(__FUNCTION__, &hfsplus_handle, inode);
hfsplus_journal_stop(&hfsplus_handle);
return res;
}
开发者ID:patrick-ken,项目名称:R7000,代码行数:57,代码来源:dir.c
示例2: hfsplus_unlink
static int hfsplus_unlink(struct inode *dir, struct dentry *dentry)
{
struct hfsplus_sb_info *sbi = HFSPLUS_SB(dir->i_sb);
struct inode *inode = dentry->d_inode;
struct qstr str;
char name[32];
u32 cnid;
int res;
if (HFSPLUS_IS_RSRC(inode))
return -EPERM;
mutex_lock(&sbi->vh_mutex);
cnid = (u32)(unsigned long)dentry->d_fsdata;
if (inode->i_ino == cnid &&
atomic_read(&HFSPLUS_I(inode)->opencnt)) {
str.name = name;
str.len = sprintf(name, "temp%lu", inode->i_ino);
res = hfsplus_rename_cat(inode->i_ino,
dir, &dentry->d_name,
sbi->hidden_dir, &str);
if (!res) {
inode->i_flags |= S_DEAD;
drop_nlink(inode);
}
goto out;
}
res = hfsplus_delete_cat(cnid, dir, &dentry->d_name);
if (res)
goto out;
if (inode->i_nlink > 0)
drop_nlink(inode);
if (inode->i_ino == cnid)
clear_nlink(inode);
if (!inode->i_nlink) {
if (inode->i_ino != cnid) {
sbi->file_count--;
if (!atomic_read(&HFSPLUS_I(inode)->opencnt)) {
res = hfsplus_delete_cat(inode->i_ino,
sbi->hidden_dir,
NULL);
if (!res)
hfsplus_delete_inode(inode);
} else
inode->i_flags |= S_DEAD;
} else
hfsplus_delete_inode(inode);
} else
sbi->file_count--;
inode->i_ctime = CURRENT_TIME_SEC;
mark_inode_dirty(inode);
out:
mutex_unlock(&sbi->vh_mutex);
return res;
}
开发者ID:virtuoso,项目名称:linux-ci,代码行数:56,代码来源:dir.c
示例3: hfsplus_ext_write_extent
int hfsplus_ext_write_extent(struct inode *inode)
{
int res;
mutex_lock(&HFSPLUS_I(inode)->extents_lock);
res = hfsplus_ext_write_extent_locked(inode);
mutex_unlock(&HFSPLUS_I(inode)->extents_lock);
return res;
}
开发者ID:reporter123,项目名称:hfsplusdkms,代码行数:10,代码来源:extents.c
示例4: hfsplus_evict_inode
static void hfsplus_evict_inode(struct inode *inode)
{
dprint(DBG_INODE, "hfsplus_evict_inode: %lu\n", inode->i_ino);
truncate_inode_pages(&inode->i_data, 0);
end_writeback(inode);
if (HFSPLUS_IS_RSRC(inode)) {
HFSPLUS_I(HFSPLUS_I(inode)->rsrc_inode)->rsrc_inode = NULL;
iput(HFSPLUS_I(inode)->rsrc_inode);
}
}
开发者ID:JamesAng,项目名称:lx-sk,代码行数:10,代码来源:super.c
示例5: hfsplus_dir_release
static int hfsplus_dir_release(struct inode *inode, struct file *file)
{
struct hfsplus_readdir_data *rd = file->private_data;
if (rd) {
spin_lock(&HFSPLUS_I(inode)->open_dir_lock);
list_del(&rd->list);
spin_unlock(&HFSPLUS_I(inode)->open_dir_lock);
kfree(rd);
}
return 0;
}
开发者ID:SantoshShilimkar,项目名称:linux,代码行数:11,代码来源:dir.c
示例6: hfsplus_ext_read_extent
static int hfsplus_ext_read_extent(struct inode *inode, u32 block)
{
struct hfs_find_data fd;
int res;
if (block >= HFSPLUS_I(inode).cached_start &&
block < HFSPLUS_I(inode).cached_start + HFSPLUS_I(inode).cached_blocks)
return 0;
hfs_find_init(HFSPLUS_SB(inode->i_sb).ext_tree, &fd);
res = __hfsplus_ext_cache_extent(&fd, inode, block);
hfs_find_exit(&fd);
return res;
}
开发者ID:BackupTheBerlios,项目名称:tuxap,代码行数:14,代码来源:extents.c
示例7: hfsplus_get_block
/* Get a block at iblock for inode, possibly allocating if create */
int hfsplus_get_block(struct inode *inode, sector_t iblock,
struct buffer_head *bh_result, int create)
{
struct super_block *sb;
int res = -EIO;
u32 ablock, dblock, mask;
int shift;
sb = inode->i_sb;
/* Convert inode block to disk allocation block */
shift = HFSPLUS_SB(sb).alloc_blksz_shift - sb->s_blocksize_bits;
ablock = iblock >> HFSPLUS_SB(sb).fs_shift;
if (iblock >= inode->i_blocks) {
if (iblock > inode->i_blocks || !create)
return -EIO;
if (ablock >= HFSPLUS_I(inode).alloc_blocks) {
res = hfsplus_file_extend(inode);
if (res)
return res;
}
} else
create = 0;
if (ablock < HFSPLUS_I(inode).first_blocks) {
dblock = hfsplus_ext_find_block(HFSPLUS_I(inode).first_extents, ablock);
goto done;
}
down(&HFSPLUS_I(inode).extents_lock);
res = hfsplus_ext_read_extent(inode, ablock);
if (!res) {
dblock = hfsplus_ext_find_block(HFSPLUS_I(inode).cached_extents, ablock -
HFSPLUS_I(inode).cached_start);
} else {
up(&HFSPLUS_I(inode).extents_lock);
return -EIO;
}
up(&HFSPLUS_I(inode).extents_lock);
done:
dprint(DBG_EXTENT, "get_block(%lu): %llu - %u\n", inode->i_ino, (long long)iblock, dblock);
mask = (1 << HFSPLUS_SB(sb).fs_shift) - 1;
map_bh(bh_result, sb, (dblock << HFSPLUS_SB(sb).fs_shift) + HFSPLUS_SB(sb).blockoffset + (iblock & mask));
if (create) {
set_buffer_new(bh_result);
HFSPLUS_I(inode).phys_size += sb->s_blocksize;
inode->i_blocks++;
mark_inode_dirty(inode);
}
return 0;
}
开发者ID:BackupTheBerlios,项目名称:tuxap,代码行数:54,代码来源:extents.c
示例8: hfsplus_ioctl_setflags
static int hfsplus_ioctl_setflags(struct file *file, int __user *user_flags)
{
struct inode *inode = file_inode(file);
struct hfsplus_inode_info *hip = HFSPLUS_I(inode);
unsigned int flags, new_fl = 0;
int err = 0;
err = mnt_want_write_file(file);
if (err)
goto out;
if (!inode_owner_or_capable(inode)) {
err = -EACCES;
goto out_drop_write;
}
if (get_user(flags, user_flags)) {
err = -EFAULT;
goto out_drop_write;
}
mutex_lock(&inode->i_mutex);
if ((flags & (FS_IMMUTABLE_FL|FS_APPEND_FL)) ||
inode->i_flags & (S_IMMUTABLE|S_APPEND)) {
if (!capable(CAP_LINUX_IMMUTABLE)) {
err = -EPERM;
goto out_unlock_inode;
}
}
/* don't silently ignore unsupported ext2 flags */
if (flags & ~(FS_IMMUTABLE_FL|FS_APPEND_FL|FS_NODUMP_FL)) {
err = -EOPNOTSUPP;
goto out_unlock_inode;
}
if (flags & FS_IMMUTABLE_FL)
new_fl |= S_IMMUTABLE;
if (flags & FS_APPEND_FL)
new_fl |= S_APPEND;
inode_set_flags(inode, new_fl, S_IMMUTABLE | S_APPEND);
if (flags & FS_NODUMP_FL)
hip->userflags |= HFSPLUS_FLG_NODUMP;
else
hip->userflags &= ~HFSPLUS_FLG_NODUMP;
inode->i_ctime = CURRENT_TIME_SEC;
mark_inode_dirty(inode);
out_unlock_inode:
mutex_unlock(&inode->i_mutex);
out_drop_write:
mnt_drop_write_file(file);
out:
return err;
}
开发者ID:19Dan01,项目名称:linux,代码行数:60,代码来源:ioctl.c
示例9: hfsplus_journaled_get_block
int hfsplus_journaled_get_block(struct page *page)
{
struct inode * const inode = page->mapping->host;
struct super_block * const sb = inode->i_sb;
struct hfsplus_inode_info *hip = HFSPLUS_I(inode);
u32 ablock, res;
sector_t iblock;
s32 block_num = -1;
iblock = page->index << (PAGE_CACHE_SHIFT - inode->i_blkbits);
ablock = iblock >> HFSPLUS_SB(sb)->fs_shift;
if (ablock < hip->first_blocks) {
block_num = hfsplus_ext_find_block(hip->first_extents, ablock);
}
else {
mutex_lock(&hip->extents_lock);
res = hfsplus_ext_read_extent(inode, ablock);
if (!res) {
mutex_lock(&hip->extents_lock);
block_num = hfsplus_ext_find_block(hip->cached_extents, ablock -
hip->cached_start);
mutex_unlock(&hip->extents_lock);
} else {
mutex_unlock(&hip->extents_lock);
}
mutex_unlock(&hip->extents_lock);
}
return block_num;
}
开发者ID:reporter123,项目名称:hfsplusdkms,代码行数:30,代码来源:extents.c
示例10: hfsplus_i_callback
static void hfsplus_i_callback(struct rcu_head *head)
{
struct inode *inode = container_of(head, struct inode, i_rcu);
INIT_LIST_HEAD(&inode->i_dentry);
kmem_cache_free(hfsplus_inode_cachep, HFSPLUS_I(inode));
}
开发者ID:JamesAng,项目名称:lx-sk,代码行数:7,代码来源:super.c
示例11: __hfsplus_ext_cache_extent
static inline int __hfsplus_ext_cache_extent(struct hfs_find_data *fd,
struct inode *inode, u32 block)
{
struct hfsplus_inode_info *hip = HFSPLUS_I(inode);
int res;
WARN_ON(!mutex_is_locked(&hip->extents_lock));
if (hip->extent_state & HFSPLUS_EXT_DIRTY) {
res = __hfsplus_ext_write_extent(inode, fd);
if (res)
return res;
}
res = __hfsplus_ext_read_extent(fd, hip->cached_extents, inode->i_ino,
block, HFSPLUS_IS_RSRC(inode) ?
HFSPLUS_TYPE_RSRC :
HFSPLUS_TYPE_DATA);
if (!res) {
hip->cached_start = be32_to_cpu(fd->key->ext.start_block);
hip->cached_blocks =
hfsplus_ext_block_count(hip->cached_extents);
} else {
hip->cached_start = hip->cached_blocks = 0;
hip->extent_state &= ~(HFSPLUS_EXT_DIRTY | HFSPLUS_EXT_NEW);
}
return res;
}
开发者ID:reporter123,项目名称:hfsplusdkms,代码行数:28,代码来源:extents.c
示例12: __hfsplus_ext_write_extent
static void __hfsplus_ext_write_extent(struct inode *inode,
struct hfs_find_data *fd)
{
struct hfsplus_inode_info *hip = HFSPLUS_I(inode);
int res;
WARN_ON(!mutex_is_locked(&hip->extents_lock));
hfsplus_ext_build_key(fd->search_key, inode->i_ino, hip->cached_start,
HFSPLUS_IS_RSRC(inode) ?
HFSPLUS_TYPE_RSRC : HFSPLUS_TYPE_DATA);
res = hfs_brec_find(fd);
if (hip->extent_state & HFSPLUS_EXT_NEW) {
if (res != -ENOENT)
return;
hfs_brec_insert(fd, hip->cached_extents,
sizeof(hfsplus_extent_rec));
hip->extent_state &= ~(HFSPLUS_EXT_DIRTY | HFSPLUS_EXT_NEW);
} else {
if (res)
return;
hfs_bnode_write(fd->bnode, hip->cached_extents,
fd->entryoffset, fd->entrylength);
hip->extent_state &= ~HFSPLUS_EXT_DIRTY;
}
/*
* We can't just use hfsplus_mark_inode_dirty here, because we
* also get called from hfsplus_write_inode, which should not
* redirty the inode. Instead the callers have to be careful
* to explicily mark the inode dirty, too.
*/
set_bit(HFSPLUS_I_EXT_DIRTY, &hip->flags);
}
开发者ID:0xroot,项目名称:Blackphone-BP1-Kernel,代码行数:35,代码来源:extents.c
示例13: hfsplus_unlink
static int hfsplus_unlink(struct inode *dir, struct dentry *dentry)
{
struct super_block *sb = dir->i_sb;
struct inode *inode = dentry->d_inode;
struct qstr str;
char name[32];
u32 cnid;
int res;
if (HFSPLUS_IS_RSRC(inode))
return -EPERM;
cnid = (u32)(unsigned long)dentry->d_fsdata;
if (inode->i_ino == cnid &&
atomic_read(&HFSPLUS_I(inode).opencnt)) {
str.name = name;
str.len = sprintf(name, "temp%lu", inode->i_ino);
res = hfsplus_rename_cat(inode->i_ino,
dir, &dentry->d_name,
HFSPLUS_SB(sb).hidden_dir, &str);
if (!res)
inode->i_flags |= S_DEAD;
return res;
}
res = hfsplus_delete_cat(cnid, dir, &dentry->d_name);
if (res)
return res;
if (inode->i_nlink > 0)
drop_nlink(inode);
hfsplus_delete_inode(inode);
if (inode->i_ino != cnid && !inode->i_nlink) {
if (!atomic_read(&HFSPLUS_I(inode).opencnt)) {
res = hfsplus_delete_cat(inode->i_ino, HFSPLUS_SB(sb).hidden_dir, NULL);
if (!res)
hfsplus_delete_inode(inode);
} else
inode->i_flags |= S_DEAD;
} else
clear_nlink(inode);
inode->i_ctime = CURRENT_TIME_SEC;
mark_inode_dirty(inode);
return res;
}
开发者ID:xiandaicxsj,项目名称:copyKvm,代码行数:45,代码来源:dir.c
示例14: hfsplus_link
static int hfsplus_link(struct dentry *src_dentry, struct inode *dst_dir,
struct dentry *dst_dentry)
{
struct hfsplus_sb_info *sbi = HFSPLUS_SB(dst_dir->i_sb);
struct inode *inode = src_dentry->d_inode;
struct inode *src_dir = src_dentry->d_parent->d_inode;
struct qstr str;
char name[32];
u32 cnid, id;
int res;
if (HFSPLUS_IS_RSRC(inode))
return -EPERM;
if (!S_ISREG(inode->i_mode))
return -EPERM;
mutex_lock(&sbi->vh_mutex);
if (inode->i_ino == (u32)(unsigned long)src_dentry->d_fsdata) {
for (;;) {
get_random_bytes(&id, sizeof(cnid));
id &= 0x3fffffff;
str.name = name;
str.len = sprintf(name, "iNode%d", id);
res = hfsplus_rename_cat(inode->i_ino,
src_dir, &src_dentry->d_name,
sbi->hidden_dir, &str);
if (!res)
break;
if (res != -EEXIST)
goto out;
}
HFSPLUS_I(inode)->linkid = id;
cnid = sbi->next_cnid++;
src_dentry->d_fsdata = (void *)(unsigned long)cnid;
res = hfsplus_create_cat(cnid, src_dir,
&src_dentry->d_name, inode);
if (res)
/* panic? */
goto out;
sbi->file_count++;
}
cnid = sbi->next_cnid++;
res = hfsplus_create_cat(cnid, dst_dir, &dst_dentry->d_name, inode);
if (res)
goto out;
inc_nlink(inode);
hfsplus_instantiate(dst_dentry, inode, cnid);
ihold(inode);
inode->i_ctime = CURRENT_TIME_SEC;
mark_inode_dirty(inode);
sbi->file_count++;
hfsplus_mark_mdb_dirty(dst_dir->i_sb);
out:
mutex_unlock(&sbi->vh_mutex);
return res;
}
开发者ID:virtuoso,项目名称:linux-ci,代码行数:57,代码来源:dir.c
示例15: hfsplus_write_begin
static int hfsplus_write_begin(struct file *file, struct address_space *mapping,
loff_t pos, unsigned len, unsigned flags,
struct page **pagep, void **fsdata)
{
*pagep = NULL;
return cont_write_begin(file, mapping, pos, len, flags, pagep, fsdata,
hfsplus_get_block,
&HFSPLUS_I(mapping->host).phys_size);
}
开发者ID:johnny,项目名称:CobraDroidBeta,代码行数:9,代码来源:inode.c
示例16: hfsplus_ext_write_extent
void hfsplus_ext_write_extent(struct inode *inode)
{
if (HFSPLUS_I(inode).flags & HFSPLUS_FLG_EXT_DIRTY) {
struct hfs_find_data fd;
hfs_find_init(HFSPLUS_SB(inode->i_sb).ext_tree, &fd);
__hfsplus_ext_write_extent(inode, &fd);
hfs_find_exit(&fd);
}
}
开发者ID:BackupTheBerlios,项目名称:tuxap,代码行数:10,代码来源:extents.c
示例17: hfsplus_ext_write_extent_locked
static void hfsplus_ext_write_extent_locked(struct inode *inode)
{
if (HFSPLUS_I(inode)->extent_state & HFSPLUS_EXT_DIRTY) {
struct hfs_find_data fd;
hfs_find_init(HFSPLUS_SB(inode->i_sb)->ext_tree, &fd);
__hfsplus_ext_write_extent(inode, &fd);
hfs_find_exit(&fd);
}
}
开发者ID:kcleung,项目名称:hfsplus-module,代码行数:10,代码来源:extents.c
示例18: hfsplus_link
static int hfsplus_link(struct dentry *src_dentry, struct inode *dst_dir,
struct dentry *dst_dentry)
{
struct super_block *sb = dst_dir->i_sb;
struct inode *inode = src_dentry->d_inode;
struct inode *src_dir = src_dentry->d_parent->d_inode;
struct qstr str;
char name[32];
u32 cnid, id;
int res;
if (HFSPLUS_IS_RSRC(inode))
return -EPERM;
if (inode->i_ino == (u32)(unsigned long)src_dentry->d_fsdata) {
for (;;) {
get_random_bytes(&id, sizeof(cnid));
id &= 0x3fffffff;
str.name = name;
str.len = sprintf(name, "iNode%d", id);
res = hfsplus_rename_cat(inode->i_ino,
src_dir, &src_dentry->d_name,
HFSPLUS_SB(sb).hidden_dir, &str);
if (!res)
break;
if (res != -EEXIST)
return res;
}
HFSPLUS_I(inode).dev = id;
cnid = HFSPLUS_SB(sb).next_cnid++;
src_dentry->d_fsdata = (void *)(unsigned long)cnid;
res = hfsplus_create_cat(cnid, src_dir, &src_dentry->d_name, inode);
if (res)
/* panic? */
return res;
HFSPLUS_SB(sb).file_count++;
}
cnid = HFSPLUS_SB(sb).next_cnid++;
res = hfsplus_create_cat(cnid, dst_dir, &dst_dentry->d_name, inode);
if (res)
return res;
inc_nlink(inode);
hfsplus_instantiate(dst_dentry, inode, cnid);
atomic_inc(&inode->i_count);
inode->i_ctime = CURRENT_TIME_SEC;
mark_inode_dirty(inode);
HFSPLUS_SB(sb).file_count++;
sb->s_dirt = 1;
return 0;
}
开发者ID:flwh,项目名称:Alcatel_OT_985_kernel,代码行数:52,代码来源:dir.c
示例19: hfsplus_file_truncate
void hfsplus_file_truncate(struct inode *inode)
{
struct super_block *sb = inode->i_sb;
struct hfs_find_data fd;
u32 alloc_cnt, blk_cnt, start;
int res;
hfsplus_handle_t hfsplus_handle;
dprint(DBG_INODE, "truncate: %lu, %Lu -> %Lu\n", inode->i_ino,
(long long)HFSPLUS_I(inode).phys_size, inode->i_size);
if (inode->i_size > HFSPLUS_I(inode).phys_size) {
struct address_space *mapping = inode->i_mapping;
struct page *page;
void *fsdata;
u32 size = inode->i_size - 1;
int res;
page = grab_cache_page(mapping, size >> PAGE_CACHE_SHIFT);
if (!page)
return;
size &= PAGE_CACHE_SIZE - 1;
size++;
res = mapping->a_ops->write_begin(NULL, mapping, size, 0,
AOP_FLAG_UNINTERRUPTIBLE,
&page, &fsdata);
if (!res)
res = mapping->a_ops->write_end(NULL, mapping, size, 0, 0, page, fsdata);
if (res)
inode->i_size = HFSPLUS_I(inode).phys_size;
unlock_page(page);
page_cache_release(page);
if (hfsplus_journal_start(__FUNCTION__, sb, &hfsplus_handle))
return;
hfsplus_journalled_mark_inode_dirty(__FUNCTION__, &hfsplus_handle, inode);
hfsplus_journal_stop(&hfsplus_handle);
return;
} else if (inode->i_size == HFSPLUS_I(inode).phys_size)
开发者ID:JackieXie168,项目名称:hfsplus-journal-mod,代码行数:39,代码来源:extents.c
示例20: hfsplus_ext_write_extent_locked
static int hfsplus_ext_write_extent_locked(struct inode *inode)
{
int res = 0;
if (HFSPLUS_I(inode)->extent_state & HFSPLUS_EXT_DIRTY) {
struct hfs_find_data fd;
res = hfs_find_init(HFSPLUS_SB(inode->i_sb)->ext_tree, &fd);
if (res)
return res;
res = __hfsplus_ext_write_extent(inode, &fd);
hfs_find_exit(&fd);
}
return res;
}
开发者ID:reporter123,项目名称:hfsplusdkms,代码行数:15,代码来源:extents.c
注:本文中的HFSPLUS_I函数示例由纯净天空整理自Github/MSDocs等源码及文档管理平台,相关代码片段筛选自各路编程大神贡献的开源项目,源码版权归原作者所有,传播和使用请参考对应项目的License;未经允许,请勿转载。 |
请发表评论