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; } ................................................... }