int notify_change(struct dentry * dentry, struct iattr * attr, struct inode **delegated_inode)
用于检查文件系统attribute的改动是否有效,有效的话,就通知文件系统这个改动,无效的话就返回error
其源码分析如下:
int notify_change(struct dentry * dentry, struct iattr * attr, struct inode **delegated_inode)
{
struct inode *inode = dentry->d_inode;
umode_t mode = inode->i_mode;
int error;
struct timespec now;
unsigned int ia_valid = attr->ia_valid;
WARN_ON_ONCE(!inode_is_locked(inode));
#首先检查是否允许attr的对ATTR_MODE/ATTR_UID/ATTR_GID/ATTR_TIMES_SET的改动
if (ia_valid & (ATTR_MODE | ATTR_UID | ATTR_GID | ATTR_TIMES_SET)) {
if (IS_IMMUTABLE(inode) || IS_APPEND(inode))
return -EPERM;
}
/*
* If utimes(2) and friends are called with times == NULL (or both
* times are UTIME_NOW), then we need to check for write permission
*/
#有效改动是否包含ATTR_TOUCH
if (ia_valid & ATTR_TOUCH) {
if (IS_IMMUTABLE(inode))
return -EPERM;
if (!inode_owner_or_capable(inode)) {
error = inode_permission(inode, MAY_WRITE);
if (error)
return error;
}
}
/*
* Verify that uid/gid changes are valid in the target
* namespace of the superblock.
*/
#检查对gid/uid的改动
if (ia_valid & ATTR_UID &&
!kuid_has_mapping(inode->i_sb->s_user_ns, attr->ia_uid))
return -EOVERFLOW;
if (ia_valid & ATTR_GID &&
!kgid_has_mapping(inode->i_sb->s_user_ns, attr->ia_gid))
return -EOVERFLOW;
#是否可以将改动更新到attr中
if (inode->i_op->setattr)
error = inode->i_op->setattr(dentry, attr);
else
error = simple_setattr(dentry, attr);
#如果可以更新到文件系统attr中,则这里主要通过fsnotify_change告诉文件系统这个dentry已经改动了
if (!error) {
fsnotify_change(dentry, ia_valid);
ima_inode_post_setattr(dentry);
evm_inode_post_setattr(dentry, ia_valid);
}
#正常情况下error 应该等于零
return error;
}
内核文件系统API之notify_change
最新推荐文章于 2024-11-30 15:05:46 发布