Hi, folks:
I found the reason and fix it.
I trace system call chown&chmod, then found(fs/attr.c):
*if (inode->i_op && inode->i_op->setattr) *
*{*
* error = inode->i_op->setattr(dentry,
attr); //regular file *
*}*
*Else*
*{ //device file for yaffs *
* error = inode_change_ok(inode, attr); *
* if (!error) {*
* if ((ia_valid & ATTR_UID && attr->ia_uid !=
inode->i_uid) ||*
* (ia_valid & ATTR_GID && attr->ia_gid !=
inode->i_gid))*
* error = vfs_dq_transfer(inode, attr) ?
*
* -EDQUOT : 0;*
* if (!error)*
* error = inode_setattr(inode, attr);*
* }*
*}*
when do chown&chmod on device file,the field *inode->i_op* not
assigned , so I assign the value in yaffs_fs.c
static const struct inode_operations
yaffs_special_inode_operations = {
.setattr = yaffs_setattr,
};
static void yaffs_FillInodeFromObject(struct inode *inode, yaffs_Object
*obj)
{
................................................
switch (obj->yst_mode & S_IFMT) {
default: /* fifo, device or socket */
inode->i_op = &yaffs_special_inode_operations;
#if (LINUX_VERSION_CODE > KERNEL_VERSION(2, 5, 0))
init_special_inode(inode, obj->yst_mode,
old_decode_dev(obj->yst_rdev));
#else
init_special_inode(inode, obj->yst_mode,
(dev_t) (obj->yst_rdev));
#endif
break;
case S_IFREG: /* file */
inode->i_op = &yaffs_file_inode_operations;
inode->i_fop = &yaffs_file_operations;
inode->i_mapping->a_ops =
&yaffs_file_address_operations;
break;
case S_IFDIR: /* directory */
inode->i_op = &yaffs_dir_inode_operations;
inode->i_fop = &yaffs_dir_operations;
break;
case S_IFLNK: /* symlink */
inode->i_op = &yaffs_symlink_inode_operations;
break;
}
...................................................
}