您当前的位置:首页 > IT编程 > C++
| C语言 | Java | VB | VC | python | Android | TensorFlow | C++ | oracle | 学术与代码 | cnn卷积神经网络 | gnn | 图像修复 | Keras | 数据集 | Neo4j | 自然语言处理 | 深度学习 | 医学CAD | 医学影像 | 超参数 | pointnet | pytorch | 异常检测 | Transformers | 情感分类 | 知识图谱 |

自学教程:C++ HFS_SB函数代码示例

51自学网 2021-06-01 21:23:05
  C++
这篇教程C++ HFS_SB函数代码示例写得很实用,希望能帮到您。

本文整理汇总了C++中HFS_SB函数的典型用法代码示例。如果您正苦于以下问题:C++ HFS_SB函数的具体用法?C++ HFS_SB怎么用?C++ HFS_SB使用的例子?那么恭喜您, 这里精选的函数代码示例或许可以为您提供帮助。

在下文中一共展示了HFS_SB函数的27个代码示例,这些例子默认根据受欢迎程度排序。您可以为喜欢或者感觉有用的代码点赞,您的评价将有助于我们的系统推荐出更棒的C++代码示例。

示例1: hfs_remount

static int hfs_remount(struct super_block *sb, int *flags, char *data){	*flags |= MS_NODIRATIME;	if ((*flags & MS_RDONLY) == (sb->s_flags & MS_RDONLY))		return 0;	if (!(*flags & MS_RDONLY)) {		if (!(HFS_SB(sb)->mdb->drAtrb & cpu_to_be16(HFS_SB_ATTRIB_UNMNT))) {			printk(KERN_WARNING "hfs: filesystem was not cleanly unmounted, "			       "running fsck.hfs is recommended.  leaving read-only./n");			sb->s_flags |= MS_RDONLY;			*flags |= MS_RDONLY;		} else if (HFS_SB(sb)->mdb->drAtrb & cpu_to_be16(HFS_SB_ATTRIB_SLOCK)) {			printk(KERN_WARNING "hfs: filesystem is marked locked, leaving read-only./n");			sb->s_flags |= MS_RDONLY;			*flags |= MS_RDONLY;		}	}	return 0;}
开发者ID:325116067,项目名称:semc-qsd8x50,代码行数:19,


示例2: hfs_mdb_put

/* * hfs_mdb_put() * * Release the resources associated with the in-core MDB.  */void hfs_mdb_put(struct super_block *sb){	if (!HFS_SB(sb))		return;	/* free the B-trees */	hfs_btree_close(HFS_SB(sb)->ext_tree);	hfs_btree_close(HFS_SB(sb)->cat_tree);	/* free the buffers holding the primary and alternate MDBs */	brelse(HFS_SB(sb)->mdb_bh);	brelse(HFS_SB(sb)->alt_mdb_bh);	if (HFS_SB(sb)->nls_io)		unload_nls(HFS_SB(sb)->nls_io);	if (HFS_SB(sb)->nls_disk)		unload_nls(HFS_SB(sb)->nls_disk);	kfree(HFS_SB(sb));	sb->s_fs_info = NULL;}
开发者ID:458941968,项目名称:mini2440-kernel-2.6.29,代码行数:24,


示例3: hfs_releasepage

int hfs_releasepage(struct page *page, int mask){	struct inode *inode = page->mapping->host;	struct super_block *sb = inode->i_sb;	struct hfs_btree *tree;	struct hfs_bnode *node;	u32 nidx;	int i, res = 1;	switch (inode->i_ino) {	case HFS_EXT_CNID:		tree = HFS_SB(sb)->ext_tree;		break;	case HFS_CAT_CNID:		tree = HFS_SB(sb)->cat_tree;		break;	default:		BUG();		return 0;	}	if (tree->node_size >= PAGE_CACHE_SIZE) {		nidx = page->index >> (tree->node_size_shift - PAGE_CACHE_SHIFT);		spin_lock(&tree->hash_lock);		node = hfs_bnode_findhash(tree, nidx);		if (!node)			;		else if (atomic_read(&node->refcnt))			res = 0;		else for (i = 0; i < tree->pages_per_bnode; i++) {			if (PageActive(node->page[i])) {				res = 0;				break;			}		}		if (res && node) {			hfs_bnode_unhash(node);			hfs_bnode_free(node);		}		spin_unlock(&tree->hash_lock);	} else {
开发者ID:Antonio-Zhou,项目名称:Linux-2.6.11,代码行数:40,


示例4: hfs_mdb_put

/* * hfs_mdb_put() * * Release the resources associated with the in-core MDB.  */void hfs_mdb_put(struct super_block *sb){	if (!HFS_SB(sb))		return;	/* free the B-trees */	hfs_btree_close(HFS_SB(sb)->ext_tree);	hfs_btree_close(HFS_SB(sb)->cat_tree);	/* free the buffers holding the primary and alternate MDBs */	brelse(HFS_SB(sb)->mdb_bh);	brelse(HFS_SB(sb)->alt_mdb_bh);	unload_nls(HFS_SB(sb)->nls_io);	unload_nls(HFS_SB(sb)->nls_disk);	free_pages((unsigned long)HFS_SB(sb)->bitmap, PAGE_SIZE < 8192 ? 1 : 0);	kfree(HFS_SB(sb));	sb->s_fs_info = NULL;}
开发者ID:19Dan01,项目名称:linux,代码行数:23,


示例5: hfs_put_super

/* * hfs_put_super() * * This is the put_super() entry in the super_operations structure for * HFS filesystems.  The purpose is to release the resources * associated with the superblock sb. */static void hfs_put_super(struct super_block *sb){	struct hfs_mdb *mdb = HFS_SB(sb)->s_mdb; 	if (!(sb->s_flags & MS_RDONLY)) {		hfs_mdb_commit(mdb, 0);		sb->s_dirt = 0;	}	/* release the MDB's resources */	hfs_mdb_put(mdb, sb->s_flags & MS_RDONLY);	kfree(sb->s_fs_info);	sb->s_fs_info = NULL;}
开发者ID:xricson,项目名称:knoppix,代码行数:22,


示例6: hfs_statfs

/* * hfs_statfs() * * This is the statfs() entry in the super_operations structure for * HFS filesystems.  The purpose is to return various data about the * filesystem. * * changed f_files/f_ffree to reflect the fs_ablock/free_ablocks. */static int hfs_statfs(struct super_block *sb, struct statfs *buf){	struct hfs_mdb *mdb = HFS_SB(sb)->s_mdb;	buf->f_type = HFS_SUPER_MAGIC;	buf->f_bsize = HFS_SECTOR_SIZE;	buf->f_blocks = mdb->alloc_blksz * mdb->fs_ablocks;	buf->f_bfree = mdb->alloc_blksz * mdb->free_ablocks;	buf->f_bavail = buf->f_bfree;	buf->f_files = mdb->fs_ablocks;  	buf->f_ffree = mdb->free_ablocks;	buf->f_namelen = HFS_NAMELEN;	return 0;}
开发者ID:hugh712,项目名称:Jollen,代码行数:24,


示例7: hfs_put_super

/* * hfs_put_super() * * This is the put_super() entry in the super_operations structure for * HFS filesystems.  The purpose is to release the resources * associated with the superblock sb. */static void hfs_put_super(struct super_block *sb){	struct hfs_mdb *mdb = HFS_SB(sb)->s_mdb; 	if (!(sb->s_flags & MS_RDONLY)) {		hfs_mdb_commit(mdb, 0);		sb->s_dirt = 0;	}	/* release the MDB's resources */	hfs_mdb_put(mdb, sb->s_flags & MS_RDONLY);	/* restore default blocksize for the device */	set_blocksize(sb->s_dev, BLOCK_SIZE);}
开发者ID:hugh712,项目名称:Jollen,代码行数:22,


示例8: hfs_write_super

/* * hfs_write_super() * * Description: *   This function is called by the VFS only. When the filesystem *   is mounted r/w it updates the MDB on disk. * Input Variable(s): *   struct super_block *sb: Pointer to the hfs superblock * Output Variable(s): *   NONE * Returns: *   void * Preconditions: *   'sb' points to a "valid" (struct super_block). * Postconditions: *   The MDB is marked 'unsuccessfully unmounted' by clearing bit 8 of drAtrb *   (hfs_put_super() must set this flag!). Some MDB fields are updated *   and the MDB buffer is written to disk by calling hfs_mdb_commit(). */static void hfs_write_super(struct super_block *sb){	struct hfs_mdb *mdb = HFS_SB(sb)->s_mdb;	/* is this a valid hfs superblock? */	if (!sb || sb->s_magic != HFS_SUPER_MAGIC) {		return;	}	if (!(sb->s_flags & MS_RDONLY)) {		/* sync everything to the buffers */		hfs_mdb_commit(mdb, 0);	}	sb->s_dirt = 0;}
开发者ID:hugh712,项目名称:Jollen,代码行数:34,


示例9: hfs_remount

static int hfs_remount(struct super_block *sb, int *flags, char *data){	*flags |= MS_NODIRATIME;	if ((*flags & MS_RDONLY) == (sb->s_flags & MS_RDONLY))		return 0;	if (!(*flags & MS_RDONLY)) {		if (!(HFS_SB(sb)->mdb->drAtrb & cpu_to_be16(HFS_SB_ATTRIB_UNMNT))) {			printk(KERN_WARNING "hfs: filesystem was not cleanly unmounted, "			       "running fsck.hfs is recommended.  leaving read-only./n");        /* Foxconn removed start pling 05/31/2010 */        /* Ignore this flag to force writeable */#if 0			sb->s_flags |= MS_RDONLY;			*flags |= MS_RDONLY;#endif        /* Foxconn removed end pling 05/31/2010 */		} else if (HFS_SB(sb)->mdb->drAtrb & cpu_to_be16(HFS_SB_ATTRIB_SLOCK)) {			printk(KERN_WARNING "hfs: filesystem is marked locked, leaving read-only./n");			sb->s_flags |= MS_RDONLY;			*flags |= MS_RDONLY;		}	}	return 0;}
开发者ID:hajuuk,项目名称:R7000,代码行数:24,


示例10: hfs_mark_mdb_dirty

void hfs_mark_mdb_dirty(struct super_block *sb){	struct hfs_sb_info *sbi = HFS_SB(sb);	unsigned long delay;	if (sb->s_flags & MS_RDONLY)		return;	spin_lock(&sbi->work_lock);	if (!sbi->work_queued) {		delay = msecs_to_jiffies(dirty_writeback_interval * 10);		queue_delayed_work(system_long_wq, &sbi->mdb_work, delay);		sbi->work_queued = 1;	}	spin_unlock(&sbi->work_lock);}
开发者ID:19Dan01,项目名称:linux,代码行数:16,


示例11: __hfs_getxattr

static ssize_t __hfs_getxattr(struct inode *inode, enum hfs_xattr_type type,			      void *value, size_t size){	struct hfs_find_data fd;	hfs_cat_rec rec;	struct hfs_cat_file *file;	ssize_t res = 0;	if (!S_ISREG(inode->i_mode) || HFS_IS_RSRC(inode))		return -EOPNOTSUPP;	if (size) {		res = hfs_find_init(HFS_SB(inode->i_sb)->cat_tree, &fd);		if (res)			return res;		fd.search_key->cat = HFS_I(inode)->cat_key;		res = hfs_brec_find(&fd);		if (res)			goto out;		hfs_bnode_read(fd.bnode, &rec, fd.entryoffset,				sizeof(struct hfs_cat_file));	}	file = &rec.file;	switch (type) {	case HFS_TYPE:		if (size >= 4) {			memcpy(value, &file->UsrWds.fdType, 4);			res = 4;		} else			res = size ? -ERANGE : 4;		break;	case HFS_CREATOR:		if (size >= 4) {			memcpy(value, &file->UsrWds.fdCreator, 4);			res = 4;		} else			res = size ? -ERANGE : 4;		break;	}out:	if (size)		hfs_find_exit(&fd);	return res;}
开发者ID:AshishNamdev,项目名称:linux,代码行数:47,


示例12: __hfs_setxattr

static int __hfs_setxattr(struct inode *inode, enum hfs_xattr_type type,			  const void *value, size_t size, int flags){	struct hfs_find_data fd;	hfs_cat_rec rec;	struct hfs_cat_file *file;	int res;	if (!S_ISREG(inode->i_mode) || HFS_IS_RSRC(inode))		return -EOPNOTSUPP;	res = hfs_find_init(HFS_SB(inode->i_sb)->cat_tree, &fd);	if (res)		return res;	fd.search_key->cat = HFS_I(inode)->cat_key;	res = hfs_brec_find(&fd);	if (res)		goto out;	hfs_bnode_read(fd.bnode, &rec, fd.entryoffset,			sizeof(struct hfs_cat_file));	file = &rec.file;	switch (type) {	case HFS_TYPE:		if (size == 4)			memcpy(&file->UsrWds.fdType, value, 4);		else			res = -ERANGE;		break;	case HFS_CREATOR:		if (size == 4)			memcpy(&file->UsrWds.fdCreator, value, 4);		else			res = -ERANGE;		break;	}	if (!res)		hfs_bnode_write(fd.bnode, &rec, fd.entryoffset,				sizeof(struct hfs_cat_file));out:	hfs_find_exit(&fd);	return res;}
开发者ID:AshishNamdev,项目名称:linux,代码行数:45,


示例13: hfs_statfs

/* * hfs_statfs() * * This is the statfs() entry in the super_operations structure for * HFS filesystems.  The purpose is to return various data about the * filesystem. * * changed f_files/f_ffree to reflect the fs_ablock/free_ablocks. */static int hfs_statfs(struct super_block *sb, struct kstatfs *buf){	buf->f_type = HFS_SUPER_MAGIC;	buf->f_bsize = sb->s_blocksize;	buf->f_blocks = (u32)HFS_SB(sb)->fs_ablocks * HFS_SB(sb)->fs_div;	buf->f_bfree = (u32)HFS_SB(sb)->free_ablocks * HFS_SB(sb)->fs_div;	buf->f_bavail = buf->f_bfree;	buf->f_files = HFS_SB(sb)->fs_ablocks;	buf->f_ffree = HFS_SB(sb)->free_ablocks;	buf->f_namelen = HFS_NAMELEN;	return 0;}
开发者ID:FelipeFernandes1988,项目名称:Alice-1121-Modem,代码行数:22,


示例14: hfs_getxattr

ssize_t hfs_getxattr(struct dentry *dentry, const char *name,			 void *value, size_t size){	struct inode *inode = dentry->d_inode;	struct hfs_find_data fd;	hfs_cat_rec rec;	struct hfs_cat_file *file;	ssize_t res = 0;	if (!S_ISREG(inode->i_mode) || HFS_IS_RSRC(inode))		return -EOPNOTSUPP;	if (size) {		res = hfs_find_init(HFS_SB(inode->i_sb)->cat_tree, &fd);		if (res)			return res;		fd.search_key->cat = HFS_I(inode)->cat_key;		res = hfs_brec_find(&fd);		if (res)			goto out;		hfs_bnode_read(fd.bnode, &rec, fd.entryoffset,				sizeof(struct hfs_cat_file));	}	file = &rec.file;	if (!strcmp(name, "hfs.type")) {		if (size >= 4) {			memcpy(value, &file->UsrWds.fdType, 4);			res = 4;		} else			res = size ? -ERANGE : 4;	} else if (!strcmp(name, "hfs.creator")) {		if (size >= 4) {			memcpy(value, &file->UsrWds.fdCreator, 4);			res = 4;		} else			res = size ? -ERANGE : 4;	} else		res = -ENODATA;out:	if (size)		hfs_find_exit(&fd);	return res;}
开发者ID:0xroot,项目名称:Blackphone-BP1-Kernel,代码行数:44,


示例15: hfs_setxattr

int hfs_setxattr(struct dentry *dentry, const char *name,		 const void *value, size_t size, int flags){	struct inode *inode = dentry->d_inode;	struct hfs_find_data fd;	hfs_cat_rec rec;	struct hfs_cat_file *file;	int res;	if (!S_ISREG(inode->i_mode) || HFS_IS_RSRC(inode))		return -EOPNOTSUPP;	res = hfs_find_init(HFS_SB(inode->i_sb)->cat_tree, &fd);	if (res)		return res;	fd.search_key->cat = HFS_I(inode)->cat_key;	res = hfs_brec_find(&fd);	if (res)		goto out;	hfs_bnode_read(fd.bnode, &rec, fd.entryoffset,			sizeof(struct hfs_cat_file));	file = &rec.file;	if (!strcmp(name, "hfs.type")) {		if (size == 4)			memcpy(&file->UsrWds.fdType, value, 4);		else			res = -ERANGE;	} else if (!strcmp(name, "hfs.creator")) {		if (size == 4)			memcpy(&file->UsrWds.fdCreator, value, 4);		else			res = -ERANGE;	} else		res = -EOPNOTSUPP;	if (!res)		hfs_bnode_write(fd.bnode, &rec, fd.entryoffset,				sizeof(struct hfs_cat_file));out:	hfs_find_exit(&fd);	return res;}
开发者ID:0xroot,项目名称:Blackphone-BP1-Kernel,代码行数:42,


示例16: hfs_statfs

/* * hfs_statfs() * * This is the statfs() entry in the super_operations structure for * HFS filesystems.  The purpose is to return various data about the * filesystem. * * changed f_files/f_ffree to reflect the fs_ablock/free_ablocks. */static int hfs_statfs(struct dentry *dentry, struct kstatfs *buf){	struct super_block *sb = dentry->d_sb;	u64 id = huge_encode_dev(sb->s_bdev->bd_dev);	buf->f_type = HFS_SUPER_MAGIC;	buf->f_bsize = sb->s_blocksize;	buf->f_blocks = (u32)HFS_SB(sb)->fs_ablocks * HFS_SB(sb)->fs_div;	buf->f_bfree = (u32)HFS_SB(sb)->free_ablocks * HFS_SB(sb)->fs_div;	buf->f_bavail = buf->f_bfree;	buf->f_files = HFS_SB(sb)->fs_ablocks;	buf->f_ffree = HFS_SB(sb)->free_ablocks;	buf->f_fsid.val[0] = (u32)id;	buf->f_fsid.val[1] = (u32)(id >> 32);	buf->f_namelen = HFS_NAMELEN;	return 0;}
开发者ID:CSCLOG,项目名称:beaglebone,代码行数:27,


示例17: nat_hdr_rename

/* * nat_hdr_rename() * * This is the rename() entry in the inode_operations structure for * Netatalk header directories.  The purpose is to rename an existing * file given the inode for the current directory and the name  * (and its length) of the existing file and the inode for the new * directory and the name (and its length) of the new file/directory. * * WE NEVER MOVE ANYTHING. * In non-afpd-compatible mode: *   We return -EPERM. * In afpd-compatible mode: *   If the source header doesn't exist, we return -ENOENT. *   If the destination is not a header directory we return -EPERM. *   We return success if the destination is also a header directory *    and the header exists or is ".Parent". */static int nat_hdr_rename(struct inode *old_dir, const char *old_name,			  int old_len, struct inode *new_dir,			  const char *new_name, int new_len, int must_be_dir){	struct hfs_cat_entry *entry = HFS_I(old_dir)->entry;	int error = 0;	if (!HFS_SB(old_dir->i_sb)->s_afpd) {		/* Not in AFPD compatibility mode */		error = -EPERM;	} else {		struct hfs_name cname;		hfs_nameout(old_dir, &cname, old_name, old_len);		if (!hfs_streq(&cname, DOT_PARENT)) {			struct hfs_cat_entry *victim;			struct hfs_cat_key key;			hfs_cat_build_key(entry->cnid, &cname, &key);			victim = hfs_cat_get(entry->mdb, &key);			if (victim) {				/* pretend to succeed */				hfs_cat_put(victim);			} else {				error = -ENOENT;			}		}		if (!error && (HFS_ITYPE(new_dir->i_ino) != HFS_NAT_HDIR)) {			error = -EPERM;		}	}	iput(old_dir);	iput(new_dir);	return error;}
开发者ID:rohsaini,项目名称:mkunity,代码行数:55,


示例18: hfs_find_init

/* * hfs_lookup() */static struct dentry *hfs_lookup(struct inode *dir, struct dentry *dentry,				 unsigned int flags){	hfs_cat_rec rec;	struct hfs_find_data fd;	struct inode *inode = NULL;	int res;	res = hfs_find_init(HFS_SB(dir->i_sb)->cat_tree, &fd);	if (res)		return ERR_PTR(res);	hfs_cat_build_key(dir->i_sb, fd.search_key, dir->i_ino, &dentry->d_name);	res = hfs_brec_read(&fd, &rec, sizeof(rec));	if (res) {		if (res != -ENOENT)			inode = ERR_PTR(res);	} else {		inode = hfs_iget(dir->i_sb, &fd.search_key->cat, &rec);		if (!inode)			inode = ERR_PTR(-EACCES);	}	hfs_find_exit(&fd);	return d_splice_alias(inode, dentry);}
开发者ID:AlexShiLucky,项目名称:linux,代码行数:27,


示例19: nat_rmdir

/* * nat_rmdir() * * This is the rmdir() entry in the inode_operations structure for * Netatalk directories.  The purpose is to delete an existing * directory, given the inode for the parent directory and the name * (and its length) of the existing directory. * * We handle .AppleDouble and call hfs_rmdir() for all other cases. */static int nat_rmdir(struct inode *parent, const char *name, int len){	struct hfs_cat_entry *entry = HFS_I(parent)->entry;	struct hfs_name cname;	int error;	hfs_nameout(parent, &cname, name, len);	if (hfs_streq(&cname, DOT_APPLEDOUBLE)) {		if (!HFS_SB(parent->i_sb)->s_afpd) {			/* Not in AFPD compatibility mode */			error = -EPERM;		} else if (entry->u.dir.files || entry->u.dir.dirs) {			/* AFPD compatible, but the directory is not empty */			error = -ENOTEMPTY;		} else {			/* AFPD compatible, so pretend to succeed */			error = 0;		}		iput(parent);	} else {		error = hfs_rmdir(parent, name, len);	}	return error;}
开发者ID:rohsaini,项目名称:mkunity,代码行数:34,


示例20: hfs_readdir

/* * hfs_readdir */static int hfs_readdir(struct file *filp, void *dirent, filldir_t filldir){	struct inode *inode = filp->f_path.dentry->d_inode;	struct super_block *sb = inode->i_sb;	int len, err;	char strbuf[HFS_MAX_NAMELEN];	union hfs_cat_rec entry;	struct hfs_find_data fd;	struct hfs_readdir_data *rd;	u16 type;	if (filp->f_pos >= inode->i_size)		return 0;	hfs_find_init(HFS_SB(sb)->cat_tree, &fd);	hfs_cat_build_key(sb, fd.search_key, inode->i_ino, NULL);	err = hfs_brec_find(&fd);	if (err)		goto out;	switch ((u32)filp->f_pos) {	case 0:		/* This is completely artificial... */		if (filldir(dirent, ".", 1, 0, inode->i_ino, DT_DIR))			goto out;		filp->f_pos++;		/* fall through */	case 1:		if (fd.entrylength > sizeof(entry) || fd.entrylength < 0) {			err = -EIO;			goto out;		}		hfs_bnode_read(fd.bnode, &entry, fd.entryoffset, fd.entrylength);		if (entry.type != HFS_CDR_THD) {			printk(KERN_ERR "hfs: bad catalog folder thread/n");			err = -EIO;			goto out;		}		//if (fd.entrylength < HFS_MIN_THREAD_SZ) {		//	printk(KERN_ERR "hfs: truncated catalog thread/n");		//	err = -EIO;		//	goto out;		//}		if (filldir(dirent, "..", 2, 1,			    be32_to_cpu(entry.thread.ParID), DT_DIR))			goto out;		filp->f_pos++;		/* fall through */	default:		if (filp->f_pos >= inode->i_size)			goto out;		err = hfs_brec_goto(&fd, filp->f_pos - 1);		if (err)			goto out;	}	for (;;) {		if (be32_to_cpu(fd.key->cat.ParID) != inode->i_ino) {			printk(KERN_ERR "hfs: walked past end of dir/n");			err = -EIO;			goto out;		}		if (fd.entrylength > sizeof(entry) || fd.entrylength < 0) {			err = -EIO;			goto out;		}		hfs_bnode_read(fd.bnode, &entry, fd.entryoffset, fd.entrylength);		type = entry.type;		len = hfs_mac2asc(sb, strbuf, &fd.key->cat.CName);		if (type == HFS_CDR_DIR) {			if (fd.entrylength < sizeof(struct hfs_cat_dir)) {				printk(KERN_ERR "hfs: small dir entry/n");				err = -EIO;				goto out;			}			if (filldir(dirent, strbuf, len, filp->f_pos,				    be32_to_cpu(entry.dir.DirID), DT_DIR))				break;		} else if (type == HFS_CDR_FIL) {			if (fd.entrylength < sizeof(struct hfs_cat_file)) {				printk(KERN_ERR "hfs: small file entry/n");				err = -EIO;				goto out;			}			if (filldir(dirent, strbuf, len, filp->f_pos,				    be32_to_cpu(entry.file.FlNum), DT_REG))				break;		} else {			printk(KERN_ERR "hfs: bad catalog entry type %d/n", type);			err = -EIO;			goto out;		}		filp->f_pos++;		if (filp->f_pos >= inode->i_size)//.........这里部分代码省略.........
开发者ID:CSCLOG,项目名称:beaglebone,代码行数:101,


示例21: hfs_fill_super

/* * hfs_read_super() * * This is the function that is responsible for mounting an HFS * filesystem.	It performs all the tasks necessary to get enough data * from the disk to read the root inode.  This includes parsing the * mount options, dealing with Macintosh partitions, reading the * superblock and the allocation bitmap blocks, calling * hfs_btree_init() to get the necessary data about the extents and * catalog B-trees and, finally, reading the root inode into memory. */static int hfs_fill_super(struct super_block *sb, void *data, int silent){	struct hfs_sb_info *sbi;	struct hfs_find_data fd;	hfs_cat_rec rec;	struct inode *root_inode;	int res;	sbi = kzalloc(sizeof(struct hfs_sb_info), GFP_KERNEL);	if (!sbi)		return -ENOMEM;	sb->s_fs_info = sbi;	res = -EINVAL;	if (!parse_options((char *)data, sbi)) {		printk(KERN_ERR "hfs: unable to parse mount options./n");		goto bail;	}	sb->s_op = &hfs_super_operations;	sb->s_flags |= MS_NODIRATIME;	mutex_init(&sbi->bitmap_lock);	res = hfs_mdb_get(sb);	if (res) {		if (!silent)			printk(KERN_WARNING "hfs: can't find a HFS filesystem on dev %s./n",				hfs_mdb_name(sb));		res = -EINVAL;		goto bail;	}	/* try to get the root inode */	hfs_find_init(HFS_SB(sb)->cat_tree, &fd);	res = hfs_cat_find_brec(sb, HFS_ROOT_CNID, &fd);	if (!res) {		if (fd.entrylength > sizeof(rec) || fd.entrylength < 0) {			res =  -EIO;			goto bail;		}		hfs_bnode_read(fd.bnode, &rec, fd.entryoffset, fd.entrylength);	}	if (res) {		hfs_find_exit(&fd);		goto bail_no_root;	}	res = -EINVAL;	root_inode = hfs_iget(sb, &fd.search_key->cat, &rec);	hfs_find_exit(&fd);	if (!root_inode)		goto bail_no_root;	sb->s_d_op = &hfs_dentry_operations;	res = -ENOMEM;	sb->s_root = d_alloc_root(root_inode);	if (!sb->s_root)		goto bail_iput;	/* everything's okay */	return 0;bail_iput:	iput(root_inode);bail_no_root:	printk(KERN_ERR "hfs: get root inode failed./n");bail:	hfs_mdb_put(sb);	return res;}
开发者ID:CSCLOG,项目名称:beaglebone,代码行数:81,


示例22: __hfs_notify_change

static int __hfs_notify_change(struct dentry *dentry, struct iattr * attr, int kind){    struct inode *inode = dentry->d_inode;    struct hfs_cat_entry *entry = HFS_I(inode)->entry;    struct dentry **de = entry->sys_entry;    struct hfs_sb_info *hsb = HFS_SB(inode->i_sb);    int error=0, i;    lock_kernel();    error = inode_change_ok(inode, attr); /* basic permission checks */    if (error) {        /* Let netatalk's afpd think chmod() always succeeds */        if (hsb->s_afpd &&                (attr->ia_valid == (ATTR_MODE | ATTR_CTIME))) {            error = 0;        }        goto out;    }    /* no uig/gid changes and limit which mode bits can be set */    if (((attr->ia_valid & ATTR_UID) &&            (attr->ia_uid != hsb->s_uid)) ||            ((attr->ia_valid & ATTR_GID) &&             (attr->ia_gid != hsb->s_gid)) ||            ((attr->ia_valid & ATTR_MODE) &&             (((entry->type == HFS_CDR_DIR) &&               (attr->ia_mode != inode->i_mode))||              (attr->ia_mode & ~HFS_VALID_MODE_BITS)))) {        if( hsb->s_quiet ) {            error = 0;            goto out;        }    }    if (entry->type == HFS_CDR_DIR) {        attr->ia_valid &= ~ATTR_MODE;    } else if (attr->ia_valid & ATTR_MODE) {        /* Only the 'w' bits can ever change and only all together. */        if (attr->ia_mode & S_IWUSR) {            attr->ia_mode = inode->i_mode | S_IWUGO;        } else {            attr->ia_mode = inode->i_mode & ~S_IWUGO;        }        attr->ia_mode &= ~hsb->s_umask;    }    /*     * Normal files handle size change in normal way.     * Oddballs are served here.     */    if (attr->ia_valid & ATTR_SIZE) {        if (kind == HFS_CAP) {            inode->i_size = attr->ia_size;            if (inode->i_size > HFS_FORK_MAX)                inode->i_size = HFS_FORK_MAX;            mark_inode_dirty(inode);            attr->ia_valid &= ~ATTR_SIZE;        } else if (kind == HFS_HDR) {            hdr_truncate(inode, attr->ia_size);            attr->ia_valid &= ~ATTR_SIZE;        }    }    error = inode_setattr(inode, attr);    if (error)        goto out;    /* We wouldn't want to mess with the sizes of the other fork */    attr->ia_valid &= ~ATTR_SIZE;    /* We must change all in-core inodes corresponding to this file. */    for (i = 0; i < 4; ++i) {        if (de[i] && (de[i] != dentry)) {            inode_setattr(de[i]->d_inode, attr);        }    }    /* Change the catalog entry if needed */    if (attr->ia_valid & ATTR_MTIME) {        entry->modify_date = hfs_u_to_mtime(inode->i_mtime.tv_sec);        hfs_cat_mark_dirty(entry);    }    if (attr->ia_valid & ATTR_MODE) {        hfs_u8 new_flags;        if (inode->i_mode & S_IWUSR) {            new_flags = entry->u.file.flags & ~HFS_FIL_LOCK;        } else {            new_flags = entry->u.file.flags | HFS_FIL_LOCK;        }        if (new_flags != entry->u.file.flags) {            entry->u.file.flags = new_flags;            hfs_cat_mark_dirty(entry);        }    }    /* size changes handled in hfs_extent_adj() */out:    unlock_kernel();    return error;//.........这里部分代码省略.........
开发者ID:xricson,项目名称:knoppix,代码行数:101,


示例23: hfs_mdb_commit

/* * hfs_mdb_commit() * * Description: *   This updates the MDB on disk (look also at hfs_write_super()). *   It does not check, if the superblock has been modified, or *   if the filesystem has been mounted read-only. It is mainly *   called by hfs_write_super() and hfs_btree_extend(). * Input Variable(s): *   struct hfs_mdb *mdb: Pointer to the hfs MDB *   int backup; * Output Variable(s): *   NONE * Returns: *   void * Preconditions: *   'mdb' points to a "valid" (struct hfs_mdb). * Postconditions: *   The HFS MDB and on disk will be updated, by copying the possibly *   modified fields from the in memory MDB (in native byte order) to *   the disk block buffer. *   If 'backup' is non-zero then the alternate MDB is also written *   and the function doesn't return until it is actually on disk. */void hfs_mdb_commit(struct super_block *sb){	struct hfs_mdb *mdb = HFS_SB(sb)->mdb;	if (test_and_clear_bit(HFS_FLG_MDB_DIRTY, &HFS_SB(sb)->flags)) {		/* These parameters may have been modified, so write them back */		mdb->drLsMod = hfs_mtime();		mdb->drFreeBks = cpu_to_be16(HFS_SB(sb)->free_ablocks);		mdb->drNxtCNID = cpu_to_be32(HFS_SB(sb)->next_id);		mdb->drNmFls = cpu_to_be16(HFS_SB(sb)->root_files);		mdb->drNmRtDirs = cpu_to_be16(HFS_SB(sb)->root_dirs);		mdb->drFilCnt = cpu_to_be32(HFS_SB(sb)->file_count);		mdb->drDirCnt = cpu_to_be32(HFS_SB(sb)->folder_count);		/* write MDB to disk */		mark_buffer_dirty(HFS_SB(sb)->mdb_bh);	}	/* write the backup MDB, not returning until it is written.	 * we only do this when either the catalog or extents overflow	 * files grow. */	if (test_and_clear_bit(HFS_FLG_ALT_MDB_DIRTY, &HFS_SB(sb)->flags) &&	    HFS_SB(sb)->alt_mdb) {		hfs_inode_write_fork(HFS_SB(sb)->ext_tree->inode, mdb->drXTExtRec,				     &mdb->drXTFlSize, NULL);		hfs_inode_write_fork(HFS_SB(sb)->cat_tree->inode, mdb->drCTExtRec,				     &mdb->drCTFlSize, NULL);		memcpy(HFS_SB(sb)->alt_mdb, HFS_SB(sb)->mdb, HFS_SECTOR_SIZE);		HFS_SB(sb)->alt_mdb->drAtrb |= cpu_to_be16(HFS_SB_ATTRIB_UNMNT);		HFS_SB(sb)->alt_mdb->drAtrb &= cpu_to_be16(~HFS_SB_ATTRIB_INCNSTNT);		mark_buffer_dirty(HFS_SB(sb)->alt_mdb_bh);		hfs_buffer_sync(HFS_SB(sb)->alt_mdb_bh);	}	if (test_and_clear_bit(HFS_FLG_BITMAP_DIRTY, &HFS_SB(sb)->flags)) {		struct buffer_head *bh;		sector_t block;		char *ptr;		int off, size, len;		block = be16_to_cpu(HFS_SB(sb)->mdb->drVBMSt) + HFS_SB(sb)->part_start;		off = (block << HFS_SECTOR_SIZE_BITS) & (sb->s_blocksize - 1);		block >>= sb->s_blocksize_bits - HFS_SECTOR_SIZE_BITS;		size = (HFS_SB(sb)->fs_ablocks + 7) / 8;		ptr = (u8 *)HFS_SB(sb)->bitmap;		while (size) {			bh = sb_bread(sb, block);			if (!bh) {				hfs_warn("hfs_fs: unable to read volume bitmap/n");				break;			}			len = min((int)sb->s_blocksize - off, size);			memcpy(bh->b_data + off, ptr, len);			mark_buffer_dirty(bh);			brelse(bh);			block++;			off = 0;			ptr += len;			size -= len;		}	}}
开发者ID:BackupTheBerlios,项目名称:tuxap,代码行数:86,


示例24: hfs_mdb_get

/* * hfs_mdb_get() * * Build the in-core MDB for a filesystem, including * the B-trees and the volume bitmap. */int hfs_mdb_get(struct super_block *sb){	struct buffer_head *bh;	struct hfs_mdb *mdb, *mdb2;	unsigned int block;	char *ptr;	int off2, len, size, sect;	sector_t part_start, part_size;	loff_t off;	__be16 attrib;	/* set the device driver to 512-byte blocks */	size = sb_min_blocksize(sb, HFS_SECTOR_SIZE);	if (!size)		return -EINVAL;	if (hfs_get_last_session(sb, &part_start, &part_size))		return -EINVAL;	while (1) {		/* See if this is an HFS filesystem */		bh = sb_bread512(sb, part_start + HFS_MDB_BLK, mdb);		if (!bh)			goto out;		if (mdb->drSigWord == cpu_to_be16(HFS_SUPER_MAGIC))			break;		brelse(bh);		/* check for a partition block		 * (should do this only for cdrom/loop though)		 */		if (hfs_part_find(sb, &part_start, &part_size))			goto out;	}	HFS_SB(sb)->alloc_blksz = size = be32_to_cpu(mdb->drAlBlkSiz);	if (!size || (size & (HFS_SECTOR_SIZE - 1))) {		hfs_warn("hfs_fs: bad allocation block size %d/n", size);		goto out_bh;	}	size = min(HFS_SB(sb)->alloc_blksz, (u32)PAGE_SIZE);	/* size must be a multiple of 512 */	while (size & (size - 1))		size -= HFS_SECTOR_SIZE;	sect = be16_to_cpu(mdb->drAlBlSt) + part_start;	/* align block size to first sector */	while (sect & ((size - 1) >> HFS_SECTOR_SIZE_BITS))		size >>= 1;	/* align block size to weird alloc size */	while (HFS_SB(sb)->alloc_blksz & (size - 1))		size >>= 1;	brelse(bh);	if (!sb_set_blocksize(sb, size)) {		printk("hfs_fs: unable to set blocksize to %u/n", size);		goto out;	}	bh = sb_bread512(sb, part_start + HFS_MDB_BLK, mdb);	if (!bh)		goto out;	if (mdb->drSigWord != cpu_to_be16(HFS_SUPER_MAGIC))		goto out_bh;	HFS_SB(sb)->mdb_bh = bh;	HFS_SB(sb)->mdb = mdb;	/* These parameters are read from the MDB, and never written */	HFS_SB(sb)->part_start = part_start;	HFS_SB(sb)->fs_ablocks = be16_to_cpu(mdb->drNmAlBlks);	HFS_SB(sb)->fs_div = HFS_SB(sb)->alloc_blksz >> sb->s_blocksize_bits;	HFS_SB(sb)->clumpablks = be32_to_cpu(mdb->drClpSiz) /				 HFS_SB(sb)->alloc_blksz;	if (!HFS_SB(sb)->clumpablks)		HFS_SB(sb)->clumpablks = 1;	HFS_SB(sb)->fs_start = (be16_to_cpu(mdb->drAlBlSt) + part_start) >>			       (sb->s_blocksize_bits - HFS_SECTOR_SIZE_BITS);	/* These parameters are read from and written to the MDB */	HFS_SB(sb)->free_ablocks = be16_to_cpu(mdb->drFreeBks);	HFS_SB(sb)->next_id = be32_to_cpu(mdb->drNxtCNID);	HFS_SB(sb)->root_files = be16_to_cpu(mdb->drNmFls);	HFS_SB(sb)->root_dirs = be16_to_cpu(mdb->drNmRtDirs);	HFS_SB(sb)->file_count = be32_to_cpu(mdb->drFilCnt);	HFS_SB(sb)->folder_count = be32_to_cpu(mdb->drDirCnt);	/* TRY to get the alternate (backup) MDB. */	sect = part_start + part_size - 2;	bh = sb_bread512(sb, sect, mdb2);	if (bh) {		if (mdb2->drSigWord == cpu_to_be16(HFS_SUPER_MAGIC)) {			HFS_SB(sb)->alt_mdb_bh = bh;			HFS_SB(sb)->alt_mdb = mdb2;		} else//.........这里部分代码省略.........
开发者ID:BackupTheBerlios,项目名称:tuxap,代码行数:101,


示例25: __iget

/* * __hfs_iget() * * Given the MDB for a HFS filesystem, a 'key' and an 'entry' in * the catalog B-tree and the 'type' of the desired file return the * inode for that file/directory or NULL.  Note that 'type' indicates * whether we want the actual file or directory, or the corresponding * metadata (AppleDouble header file or CAP metadata file). * * In an ideal world we could call iget() and would not need this * function.  However, since there is no way to even know the inode * number until we've found the file/directory in the catalog B-tree * that simply won't happen. * * The main idea here is to look in the catalog B-tree to get the * vital info about the file or directory (including the file id which * becomes the inode number) and then to call iget() and return the * inode if it is complete.  If it is not then we use the catalog * entry to fill in the missing info, by calling the appropriate * 'fillin' function.  Note that these fillin functions are * essentially hfs_*_read_inode() functions, but since there is no way * to pass the catalog entry through iget() to such a read_inode() * function, we have to call them after iget() returns an incomplete * inode to us.	 This is pretty much the same problem faced in the NFS * code, and pretty much the same solution. The SMB filesystem deals * with this in a different way: by using the address of the * kmalloc()'d space which holds the data as the inode number. * * XXX: Both this function and NFS's corresponding nfs_fhget() would * benefit from a way to pass an additional (void *) through iget() to * the VFS read_inode() function. * * this will hfs_cat_put() the entry if it fails. */struct inode *hfs_iget(struct hfs_cat_entry *entry, ino_t type,                       struct dentry *dentry){    struct dentry **sys_entry;    struct super_block *sb;    struct inode *inode;    if (!entry) {        return NULL;    }    /* If there are several processes all calling __iget() for       the same inode then they will all get the same one back.       The first one to return from __iget() will notice that the       i_mode field of the inode is blank and KNOW that it is       the first to return.  Therefore, it will set the appropriate       'sys_entry' field in the entry and initialize the inode.       All the initialization must be done without sleeping,       or else other processes could end up using a partially       initialized inode.				*/    sb = entry->mdb->sys_mdb;    sys_entry = &entry->sys_entry[HFS_ITYPE_TO_INT(type)];    if (!(inode = iget(sb, ntohl(entry->cnid) | type))) {        hfs_cat_put(entry);        return NULL;    }    if (!inode->i_mode || (*sys_entry == NULL)) {        /* Initialize the inode */        struct hfs_sb_info *hsb = HFS_SB(sb);        inode->i_ctime.tv_sec = inode->i_atime.tv_sec = inode->i_mtime.tv_sec =                                    hfs_m_to_utime(entry->modify_date);        inode->i_ctime.tv_nsec = 0;        inode->i_mtime.tv_nsec = 0;        inode->i_atime.tv_nsec = 0;        inode->i_blksize = HFS_SECTOR_SIZE;        inode->i_uid = hsb->s_uid;        inode->i_gid = hsb->s_gid;        HFS_I(inode)->mmu_private = 0;        HFS_I(inode)->fork = NULL;        HFS_I(inode)->convert = 0;        HFS_I(inode)->file_type = 0;        HFS_I(inode)->dir_size = 0;        HFS_I(inode)->default_layout = NULL;        HFS_I(inode)->layout = NULL;        HFS_I(inode)->magic = HFS_INO_MAGIC;        HFS_I(inode)->entry = entry;        HFS_I(inode)->tz_secondswest = hfs_to_utc(0);        hsb->s_ifill(inode, type, hsb->s_version);        if (!hsb->s_afpd && (entry->type == HFS_CDR_FIL) &&                (entry->u.file.flags & HFS_FIL_LOCK)) {            inode->i_mode &= ~S_IWUGO;        }        inode->i_mode &= ~hsb->s_umask;        if (!inode->i_mode) {            iput(inode); /* does an hfs_cat_put */            inode = NULL;        } else            *sys_entry = dentry; /* cache dentry *///.........这里部分代码省略.........
开发者ID:xricson,项目名称:knoppix,代码行数:101,


示例26: hfs_fill_super

/* * hfs_read_super() * * This is the function that is responsible for mounting an HFS * filesystem.	It performs all the tasks necessary to get enough data * from the disk to read the root inode.  This includes parsing the * mount options, dealing with Macintosh partitions, reading the * superblock and the allocation bitmap blocks, calling * hfs_btree_init() to get the necessary data about the extents and * catalog B-trees and, finally, reading the root inode into memory. */static int hfs_fill_super(struct super_block *sb, void *data, int silent){	struct hfs_sb_info *sbi;	struct hfs_find_data fd;	hfs_cat_rec rec;	struct inode *root_inode;	int res;	sbi = kmalloc(sizeof(struct hfs_sb_info), GFP_KERNEL);	if (!sbi)		return -ENOMEM;	sb->s_fs_info = sbi;	memset(sbi, 0, sizeof(struct hfs_sb_info));	INIT_HLIST_HEAD(&sbi->rsrc_inodes);	res = -EINVAL;	if (!parse_options((char *)data, sbi)) {		hfs_warn("hfs_fs: unable to parse mount options./n");		goto bail3;	}	sb->s_op = &hfs_super_operations;	sb->s_flags |= MS_NODIRATIME;	init_MUTEX(&sbi->bitmap_lock);	res = hfs_mdb_get(sb);	if (res) {		if (!silent)			hfs_warn("VFS: Can't find a HFS filesystem on dev %s./n",				hfs_mdb_name(sb));		res = -EINVAL;		goto bail2;	}	/* try to get the root inode */	hfs_find_init(HFS_SB(sb)->cat_tree, &fd);	res = hfs_cat_find_brec(sb, HFS_ROOT_CNID, &fd);	if (!res)		hfs_bnode_read(fd.bnode, &rec, fd.entryoffset, fd.entrylength);	if (res) {		hfs_find_exit(&fd);		goto bail_no_root;	}	root_inode = hfs_iget(sb, &fd.search_key->cat, &rec);	hfs_find_exit(&fd);	if (!root_inode)		goto bail_no_root;	sb->s_root = d_alloc_root(root_inode);	if (!sb->s_root)		goto bail_iput;	sb->s_root->d_op = &hfs_dentry_operations;	/* everything's okay */	return 0;bail_iput:	iput(root_inode);bail_no_root:	hfs_warn("hfs_fs: get root inode failed./n");	hfs_mdb_put(sb);bail2:bail3:	kfree(sbi);	return res;}
开发者ID:FelipeFernandes1988,项目名称:Alice-1121-Modem,代码行数:78,


示例27: hfs_warn

/* * hfs_read_super() * * This is the function that is responsible for mounting an HFS * filesystem.	It performs all the tasks necessary to get enough data * from the disk to read the root inode.  This includes parsing the * mount options, dealing with Macintosh partitions, reading the * superblock and the allocation bitmap blocks, calling * hfs_btree_init() to get the necessary data about the extents and * catalog B-trees and, finally, reading the root inode into memory. */struct super_block *hfs_read_super(struct super_block *s, void *data,				   int silent){	struct hfs_mdb *mdb;	struct hfs_cat_key key;	kdev_t dev = s->s_dev;	hfs_s32 part_size, part_start;	struct inode *root_inode;	int part;	if (!parse_options((char *)data, HFS_SB(s), &part)) {		hfs_warn("hfs_fs: unable to parse mount options./n");		goto bail3;	}	/* set the device driver to 512-byte blocks */	set_blocksize(dev, HFS_SECTOR_SIZE);	s->s_blocksize_bits = HFS_SECTOR_SIZE_BITS;	s->s_blocksize = HFS_SECTOR_SIZE;#ifdef CONFIG_MAC_PARTITION	/* check to see if we're in a partition */	mdb = hfs_mdb_get(s, s->s_flags & MS_RDONLY, 0);	/* erk. try parsing the partition table ourselves */	if (!mdb) {		if (hfs_part_find(s, part, silent, &part_size, &part_start)) {	    		goto bail2;	  	}	  	mdb = hfs_mdb_get(s, s->s_flags & MS_RDONLY, part_start);	}#else	if (hfs_part_find(s, part, silent, &part_size, &part_start)) {		goto bail2;	}	mdb = hfs_mdb_get(s, s->s_flags & MS_RDONLY, part_start);#endif	if (!mdb) {		if (!silent) {			hfs_warn("VFS: Can't find a HFS filesystem on dev %s./n",			       kdevname(dev));		}		goto bail2;	}	HFS_SB(s)->s_mdb = mdb;	if (HFS_ITYPE(mdb->next_id) != 0) {		hfs_warn("hfs_fs: too many files./n");		goto bail1;	}	s->s_magic = HFS_SUPER_MAGIC;	s->s_op = &hfs_super_operations;	/* try to get the root inode */	hfs_cat_build_key(htonl(HFS_POR_CNID),			  (struct hfs_name *)(mdb->vname), &key);	root_inode = hfs_iget(hfs_cat_get(mdb, &key), HFS_ITYPE_NORM, NULL);	if (!root_inode) 		goto bail_no_root;	  	s->s_root = d_alloc_root(root_inode);	if (!s->s_root) 		goto bail_no_root;	/* fix up pointers. */	HFS_I(root_inode)->entry->sys_entry[HFS_ITYPE_TO_INT(HFS_ITYPE_NORM)] =	  s->s_root;	s->s_root->d_op = &hfs_dentry_operations;	/* everything's okay */	return s;bail_no_root: 	hfs_warn("hfs_fs: get root inode failed./n");	iput(root_inode);bail1:	hfs_mdb_put(mdb, s->s_flags & MS_RDONLY);bail2:	set_blocksize(dev, BLOCK_SIZE);bail3:	return NULL;	}
开发者ID:hugh712,项目名称:Jollen,代码行数:97,



注:本文中的HFS_SB函数示例整理自Github/MSDocs等源码及文档管理平台,相关代码片段筛选自各路编程大神贡献的开源项目,源码版权归原作者所有,传播和使用请参考对应项目的License;未经允许,请勿转载。


C++ HFree函数代码示例
C++ HFS_I函数代码示例
万事OK自学网:51自学网_软件自学网_CAD自学网自学excel、自学PS、自学CAD、自学C语言、自学css3实例,是一个通过网络自主学习工作技能的自学平台,网友喜欢的软件自学网站。