fs/attr.c
Source file repositories/reference/linux-study-clean/fs/attr.c
File Facts
- System
- Linux kernel
- Corpus path
fs/attr.c- Extension
.c- Size
- 17545 bytes
- Lines
- 568
- Domain
- Core OS
- Bucket
- VFS And Filesystem Core
- Inferred role
- Core OS: exported/initcall integration point
- Status
- integration implementation candidate
Why This File Exists
Core operating-system implementation surface: boot, tasks, memory, VFS, syscall-facing interfaces, synchronization, credentials, and isolation.
- Core operating-system implementation surface: boot, tasks, memory, VFS, syscall-facing interfaces, synchronization, credentials, and isolation.
- Exports symbols or registers init work; inspect boot/module ordering and who consumes the exported contract.
- Defines or uses C structs; map object ownership, embedded links, reference counts, and lock ownership.
Dependency Surface
linux/export.hlinux/time.hlinux/mm.hlinux/string.hlinux/sched/signal.hlinux/capability.hlinux/fsnotify.hlinux/fcntl.hlinux/filelock.hlinux/security.h
Detected Declarations
function Copyrightfunction setattr_should_drop_suidgidfunction chown_okfunction chgrp_okfunction setattr_preparefunction truncatefunction appropriatelyfunction setattr_copyfunction may_setattrfunction utimesfunction notify_changeexport setattr_should_drop_sgidexport setattr_should_drop_suidgidexport setattr_prepareexport inode_newsize_okexport setattr_copyexport may_setattrexport notify_change
Annotated Snippet
if (!inode_owner_or_capable(idmap, inode)) {
error = inode_permission(idmap, inode, MAY_WRITE);
if (error)
return error;
}
}
return 0;
}
EXPORT_SYMBOL(may_setattr);
/**
* notify_change - modify attributes of a filesystem object
* @idmap: idmap of the mount the inode was found from
* @dentry: object affected
* @attr: new attributes
* @delegated_inode: returns inode, if the inode is delegated
*
* The caller must hold the i_rwsem exclusively on the affected object.
*
* If notify_change discovers a delegation in need of breaking,
* it will return -EWOULDBLOCK and return a reference to the inode in
* delegated_inode. The caller should then break the delegation and
* retry. Because breaking a delegation may take a long time, the
* caller should drop the i_rwsem before doing so.
*
* Alternatively, a caller may pass NULL for delegated_inode. This may
* be appropriate for callers that expect the underlying filesystem not
* to be NFS exported. Also, passing NULL is fine for callers holding
* the file open for write, as there can be no conflicting delegation in
* that case.
*
* If the inode has been found through an idmapped mount the idmap of
* the vfsmount must be passed through @idmap. This function will then
* take care to map the inode according to @idmap before checking
* permissions. On non-idmapped mounts or if permission checking is to be
* performed on the raw inode simply pass @nop_mnt_idmap.
*/
int notify_change(struct mnt_idmap *idmap, struct dentry *dentry,
struct iattr *attr, struct delegated_inode *delegated_inode)
{
struct inode *inode = dentry->d_inode;
umode_t mode = inode->i_mode;
int error;
struct timespec64 now;
unsigned int ia_valid = attr->ia_valid;
WARN_ON_ONCE(!inode_is_locked(inode));
error = may_setattr(idmap, inode, ia_valid);
if (error)
return error;
if ((ia_valid & ATTR_MODE)) {
/*
* Don't allow changing the mode of symlinks:
*
* (1) The vfs doesn't take the mode of symlinks into account
* during permission checking.
* (2) This has never worked correctly. Most major filesystems
* did return EOPNOTSUPP due to interactions with POSIX ACLs
* but did still updated the mode of the symlink.
* This inconsistency led system call wrapper providers such
* as libc to block changing the mode of symlinks with
* EOPNOTSUPP already.
* (3) To even do this in the first place one would have to use
* specific file descriptors and quite some effort.
*/
if (S_ISLNK(inode->i_mode))
return -EOPNOTSUPP;
/* Flag setting protected by i_rwsem */
if (is_sxid(attr->ia_mode))
inode->i_flags &= ~S_NOSEC;
}
now = current_time(inode);
if (ia_valid & ATTR_ATIME_SET)
attr->ia_atime = timestamp_truncate(attr->ia_atime, inode);
else
attr->ia_atime = now;
if (ia_valid & ATTR_CTIME_SET)
attr->ia_ctime = timestamp_truncate(attr->ia_ctime, inode);
else
attr->ia_ctime = now;
if (ia_valid & ATTR_MTIME_SET)
attr->ia_mtime = timestamp_truncate(attr->ia_mtime, inode);
else
attr->ia_mtime = now;
Annotation
- Immediate include surface: `linux/export.h`, `linux/time.h`, `linux/mm.h`, `linux/string.h`, `linux/sched/signal.h`, `linux/capability.h`, `linux/fsnotify.h`, `linux/fcntl.h`.
- Detected declarations: `function Copyright`, `function setattr_should_drop_suidgid`, `function chown_ok`, `function chgrp_ok`, `function setattr_prepare`, `function truncate`, `function appropriately`, `function setattr_copy`, `function may_setattr`, `function utimes`.
- Atlas domain: Core OS / VFS And Filesystem Core.
- Implementation status: integration implementation candidate.
Implementation Notes
- This generated page is the file-by-file coverage layer; curated subsystem chapters should link here when they synthesize a multi-file control flow.
- Core OS pages should be promoted from atlas-only to deep-reviewed when they explain data structures, invariants, locking, lifecycle, and C implementation snippets.
- Driver-family pages are intentionally pattern-oriented unless they are part of the selected PCIe/NVMe representative device path.