本文整理汇总了C++中IS_IMMUTABLE函数的典型用法代码示例。如果您正苦于以下问题:C++ IS_IMMUTABLE函数的具体用法?C++ IS_IMMUTABLE怎么用?C++ IS_IMMUTABLE使用的例子?那么恭喜您, 这里精选的函数代码示例或许可以为您提供帮助。
在下文中一共展示了IS_IMMUTABLE函数的15个代码示例,这些例子默认根据受欢迎程度排序。您可以为喜欢或者感觉有用的代码点赞,您的评价将有助于系统推荐出更棒的C++代码示例。
示例1: jfs_permission
/*
* jfs_permission()
*
* modified vfs_permission to check posix acl
*/
int jfs_permission(struct inode * inode, int mask, struct nameidata *nd)
{
umode_t mode = inode->i_mode;
struct jfs_inode_info *ji = JFS_IP(inode);
if (mask & MAY_WRITE) {
/*
* Nobody gets write access to a read-only fs.
*/
if (IS_RDONLY(inode) &&
(S_ISREG(mode) || S_ISDIR(mode) || S_ISLNK(mode)))
return -EROFS;
/*
* Nobody gets write access to an immutable file.
*/
if (IS_IMMUTABLE(inode))
return -EACCES;
}
if (current->fsuid == inode->i_uid) {
mode >>= 6;
goto check_mode;
}
示例2: utimes_common
static int utimes_common(struct path *path, struct timespec *times)
{
int error;
struct iattr newattrs;
struct inode *inode = path->dentry->d_inode;
error = mnt_want_write(path->mnt);
if (error)
goto out;
if (times && times[0].tv_nsec == UTIME_NOW &&
times[1].tv_nsec == UTIME_NOW)
times = NULL;
newattrs.ia_valid = ATTR_CTIME | ATTR_MTIME | ATTR_ATIME;
if (times) {
if (times[0].tv_nsec == UTIME_OMIT)
newattrs.ia_valid &= ~ATTR_ATIME;
else if (times[0].tv_nsec != UTIME_NOW) {
newattrs.ia_atime.tv_sec = times[0].tv_sec;
newattrs.ia_atime.tv_nsec = times[0].tv_nsec;
newattrs.ia_valid |= ATTR_ATIME_SET;
}
if (times[1].tv_nsec == UTIME_OMIT)
newattrs.ia_valid &= ~ATTR_MTIME;
else if (times[1].tv_nsec != UTIME_NOW) {
newattrs.ia_mtime.tv_sec = times[1].tv_sec;
newattrs.ia_mtime.tv_nsec = times[1].tv_nsec;
newattrs.ia_valid |= ATTR_MTIME_SET;
}
/*
* Tell inode_change_ok(), that this is an explicit time
* update, even if neither ATTR_ATIME_SET nor ATTR_MTIME_SET
* were used.
*/
newattrs.ia_valid |= ATTR_TIMES_SET;
} else {
/*
* If times is NULL (or both times are UTIME_NOW),
* then we need to check permissions, because
* inode_change_ok() won't do it.
*/
error = -EACCES;
if (IS_IMMUTABLE(inode))
goto mnt_drop_write_and_out;
#ifdef CONFIG_FS_SYNO_ACL
if (IS_SYNOACL(inode)) {
if (inode->i_op->syno_permission(path->dentry, MAY_WRITE_ATTR | MAY_WRITE_EXT_ATTR)) {
goto mnt_drop_write_and_out;
}
} else
#endif
if (!inode_owner_or_capable(inode)) {
error = inode_permission(inode, MAY_WRITE);
if (error)
goto mnt_drop_write_and_out;
}
}
mutex_lock(&inode->i_mutex);
error = notify_change(path->dentry, &newattrs);
mutex_unlock(&inode->i_mutex);
mnt_drop_write_and_out:
mnt_drop_write(path->mnt);
out:
return error;
}
示例3: xfs_open_by_handle
int
xfs_open_by_handle(
struct file *parfilp,
xfs_fsop_handlereq_t *hreq)
{
const struct cred *cred = current_cred();
int error;
int fd;
int permflag;
struct file *filp;
struct inode *inode;
struct dentry *dentry;
fmode_t fmode;
struct path path;
if (!capable(CAP_SYS_ADMIN))
return -EPERM;
dentry = xfs_handlereq_to_dentry(parfilp, hreq);
if (IS_ERR(dentry))
return PTR_ERR(dentry);
inode = d_inode(dentry);
/* Restrict xfs_open_by_handle to directories & regular files. */
if (!(S_ISREG(inode->i_mode) || S_ISDIR(inode->i_mode))) {
error = -EPERM;
goto out_dput;
}
#if BITS_PER_LONG != 32
hreq->oflags |= O_LARGEFILE;
#endif
permflag = hreq->oflags;
fmode = OPEN_FMODE(permflag);
if ((!(permflag & O_APPEND) || (permflag & O_TRUNC)) &&
(fmode & FMODE_WRITE) && IS_APPEND(inode)) {
error = -EPERM;
goto out_dput;
}
if ((fmode & FMODE_WRITE) && IS_IMMUTABLE(inode)) {
error = -EACCES;
goto out_dput;
}
/* Can't write directories. */
if (S_ISDIR(inode->i_mode) && (fmode & FMODE_WRITE)) {
error = -EISDIR;
goto out_dput;
}
fd = get_unused_fd_flags(0);
if (fd < 0) {
error = fd;
goto out_dput;
}
path.mnt = parfilp->f_path.mnt;
path.dentry = dentry;
filp = dentry_open(&path, hreq->oflags, cred);
dput(dentry);
if (IS_ERR(filp)) {
put_unused_fd(fd);
return PTR_ERR(filp);
}
if (S_ISREG(inode->i_mode)) {
filp->f_flags |= O_NOATIME;
filp->f_mode |= FMODE_NOCMTIME;
}
fd_install(fd, filp);
return fd;
out_dput:
dput(dentry);
return error;
}
示例4: gfs2_link
static int gfs2_link(struct dentry *old_dentry, struct inode *dir,
struct dentry *dentry)
{
struct gfs2_inode *dip = GFS2_I(dir);
struct gfs2_sbd *sdp = GFS2_SB(dir);
struct inode *inode = old_dentry->d_inode;
struct gfs2_inode *ip = GFS2_I(inode);
struct gfs2_holder ghs[2];
int alloc_required;
int error;
if (S_ISDIR(inode->i_mode))
return -EPERM;
gfs2_holder_init(dip->i_gl, LM_ST_EXCLUSIVE, 0, ghs);
gfs2_holder_init(ip->i_gl, LM_ST_EXCLUSIVE, 0, ghs + 1);
error = gfs2_glock_nq(ghs); /* parent */
if (error)
goto out_parent;
error = gfs2_glock_nq(ghs + 1); /* child */
if (error)
goto out_child;
error = -ENOENT;
if (inode->i_nlink == 0)
goto out_gunlock;
error = gfs2_permission(dir, MAY_WRITE | MAY_EXEC);
if (error)
goto out_gunlock;
error = gfs2_dir_check(dir, &dentry->d_name, NULL);
switch (error) {
case -ENOENT:
break;
case 0:
error = -EEXIST;
default:
goto out_gunlock;
}
error = -EINVAL;
if (!dip->i_inode.i_nlink)
goto out_gunlock;
error = -EFBIG;
if (dip->i_entries == (u32)-1)
goto out_gunlock;
error = -EPERM;
if (IS_IMMUTABLE(inode) || IS_APPEND(inode))
goto out_gunlock;
error = -EINVAL;
if (!ip->i_inode.i_nlink)
goto out_gunlock;
error = -EMLINK;
if (ip->i_inode.i_nlink == (u32)-1)
goto out_gunlock;
alloc_required = error = gfs2_diradd_alloc_required(dir, &dentry->d_name);
if (error < 0)
goto out_gunlock;
error = 0;
if (alloc_required) {
struct gfs2_qadata *qa = gfs2_qadata_get(dip);
if (!qa) {
error = -ENOMEM;
goto out_gunlock;
}
error = gfs2_quota_lock_check(dip);
if (error)
goto out_alloc;
error = gfs2_inplace_reserve(dip, sdp->sd_max_dirres);
if (error)
goto out_gunlock_q;
error = gfs2_trans_begin(sdp, sdp->sd_max_dirres +
gfs2_rg_blocks(dip) +
2 * RES_DINODE + RES_STATFS +
RES_QUOTA, 0);
if (error)
goto out_ipres;
} else {
error = gfs2_trans_begin(sdp, 2 * RES_DINODE + RES_LEAF, 0);
if (error)
goto out_ipres;
}
error = gfs2_dir_add(dir, &dentry->d_name, ip, IF2DT(inode->i_mode));
if (error)
goto out_end_trans;
error = gfs2_change_nlink(ip, +1);
out_end_trans:
gfs2_trans_end(sdp);
//.........这里部分代码省略.........
示例5: xfs_open_by_handle
int
xfs_open_by_handle(
struct file *parfilp,
xfs_fsop_handlereq_t *hreq)
{
const struct cred *cred = current_cred();
int error;
int fd;
int permflag;
struct file *filp;
struct inode *inode;
struct dentry *dentry;
if (!capable(CAP_SYS_ADMIN))
return -XFS_ERROR(EPERM);
dentry = xfs_handlereq_to_dentry(parfilp, hreq);
if (IS_ERR(dentry))
return PTR_ERR(dentry);
inode = dentry->d_inode;
/* Restrict xfs_open_by_handle to directories & regular files. */
if (!(S_ISREG(inode->i_mode) || S_ISDIR(inode->i_mode))) {
error = -XFS_ERROR(EPERM);
goto out_dput;
}
#if BITS_PER_LONG != 32
hreq->oflags |= O_LARGEFILE;
#endif
/* Put open permission in namei format. */
permflag = hreq->oflags;
if ((permflag+1) & O_ACCMODE)
permflag++;
if (permflag & O_TRUNC)
permflag |= 2;
if ((!(permflag & O_APPEND) || (permflag & O_TRUNC)) &&
(permflag & FMODE_WRITE) && IS_APPEND(inode)) {
error = -XFS_ERROR(EPERM);
goto out_dput;
}
if ((permflag & FMODE_WRITE) && IS_IMMUTABLE(inode)) {
error = -XFS_ERROR(EACCES);
goto out_dput;
}
/* Can't write directories. */
if (S_ISDIR(inode->i_mode) && (permflag & FMODE_WRITE)) {
error = -XFS_ERROR(EISDIR);
goto out_dput;
}
fd = get_unused_fd();
if (fd < 0) {
error = fd;
goto out_dput;
}
filp = dentry_open(dentry, mntget(parfilp->f_path.mnt),
hreq->oflags, cred);
if (IS_ERR(filp)) {
put_unused_fd(fd);
return PTR_ERR(filp);
}
if (inode->i_mode & S_IFREG) {
filp->f_flags |= O_NOATIME;
filp->f_mode |= FMODE_NOCMTIME;
}
fd_install(fd, filp);
return fd;
out_dput:
dput(dentry);
return error;
}
示例6: link_dinode
//.........这里部分代码省略.........
error = gfs2_glock_nq(ghs); /* parent */
if (error)
goto out_parent;
error = gfs2_glock_nq(ghs + 1); /* child */
if (error)
goto out_child;
error = -ENOENT;
if (inode->i_nlink == 0)
goto out_gunlock;
error = gfs2_permission(dir, MAY_WRITE | MAY_EXEC);
if (error)
goto out_gunlock;
error = gfs2_dir_check(dir, &dentry->d_name, NULL);
switch (error) {
case -ENOENT:
break;
case 0:
error = -EEXIST;
default:
goto out_gunlock;
}
error = -EINVAL;
if (!dip->i_inode.i_nlink)
goto out_gunlock;
error = -EFBIG;
if (dip->i_entries == (u32)-1)
goto out_gunlock;
error = -EPERM;
if (IS_IMMUTABLE(inode) || IS_APPEND(inode))
goto out_gunlock;
error = -EINVAL;
if (!ip->i_inode.i_nlink)
goto out_gunlock;
error = -EMLINK;
if (ip->i_inode.i_nlink == (u32)-1)
goto out_gunlock;
error = gfs2_diradd_alloc_required(dir, &dentry->d_name, &da);
if (error < 0)
goto out_gunlock;
if (da.nr_blocks) {
struct gfs2_alloc_parms ap = { .target = da.nr_blocks, };
error = gfs2_quota_lock_check(dip);
if (error)
goto out_gunlock;
error = gfs2_inplace_reserve(dip, &ap);
if (error)
goto out_gunlock_q;
error = gfs2_trans_begin(sdp, gfs2_trans_da_blks(dip, &da, 2), 0);
if (error)
goto out_ipres;
} else {
error = gfs2_trans_begin(sdp, 2 * RES_DINODE + RES_LEAF, 0);
if (error)
goto out_ipres;
}
error = gfs2_meta_inode_buffer(ip, &dibh);
示例7: xfs_open_by_handle
STATIC int
xfs_open_by_handle(
xfs_mount_t *mp,
unsigned long arg,
struct file *parfilp,
struct inode *parinode)
{
int error;
int new_fd;
int permflag;
struct file *filp;
struct inode *inode;
struct dentry *dentry;
vnode_t *vp;
xfs_fsop_handlereq_t hreq;
error = xfs_vget_fsop_handlereq(mp, parinode, CAP_SYS_ADMIN, arg,
sizeof(xfs_fsop_handlereq_t),
&hreq, &vp, &inode);
if (error)
return -error;
/* Restrict xfs_open_by_handle to directories & regular files. */
if (!(S_ISREG(inode->i_mode) || S_ISDIR(inode->i_mode))) {
iput(inode);
return -XFS_ERROR(EINVAL);
}
#if BITS_PER_LONG != 32
hreq.oflags |= O_LARGEFILE;
#endif
/* Put open permission in namei format. */
permflag = hreq.oflags;
if ((permflag+1) & O_ACCMODE)
permflag++;
if (permflag & O_TRUNC)
permflag |= 2;
if ((!(permflag & O_APPEND) || (permflag & O_TRUNC)) &&
(permflag & FMODE_WRITE) && IS_APPEND(inode)) {
iput(inode);
return -XFS_ERROR(EPERM);
}
if ((permflag & FMODE_WRITE) && IS_IMMUTABLE(inode)) {
iput(inode);
return -XFS_ERROR(EACCES);
}
/* Can't write directories. */
if ( S_ISDIR(inode->i_mode) && (permflag & FMODE_WRITE)) {
iput(inode);
return -XFS_ERROR(EISDIR);
}
if ((new_fd = get_unused_fd()) < 0) {
iput(inode);
return new_fd;
}
dentry = d_alloc_anon(inode);
if (dentry == NULL) {
iput(inode);
put_unused_fd(new_fd);
return -XFS_ERROR(ENOMEM);
}
/* Ensure umount returns EBUSY on umounts while this file is open. */
mntget(parfilp->f_vfsmnt);
/* Create file pointer. */
filp = dentry_open(dentry, parfilp->f_vfsmnt, hreq.oflags);
if (IS_ERR(filp)) {
put_unused_fd(new_fd);
return -XFS_ERROR(-PTR_ERR(filp));
}
if (inode->i_mode & S_IFREG)
filp->f_op = &linvfs_invis_file_operations;
fd_install(new_fd, filp);
return new_fd;
}
示例8: notify_change
int notify_change(struct dentry * dentry, struct iattr * attr)
{
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(!mutex_is_locked(&inode->i_mutex));
if (ia_valid & (ATTR_MODE | ATTR_UID | ATTR_GID | ATTR_TIMES_SET)) {
if (IS_IMMUTABLE(inode) || IS_APPEND(inode))
return -EPERM;
}
if ((ia_valid & ATTR_SIZE) && IS_I_VERSION(inode)) {
if (attr->ia_size != inode->i_size)
inode_inc_iversion(inode);
}
if ((ia_valid & ATTR_MODE)) {
umode_t amode = attr->ia_mode;
/* Flag setting protected by i_mutex */
if (is_sxid(amode))
inode->i_flags &= ~S_NOSEC;
}
now = current_fs_time(inode->i_sb);
attr->ia_ctime = now;
if (!(ia_valid & ATTR_ATIME_SET))
attr->ia_atime = now;
if (!(ia_valid & ATTR_MTIME_SET))
attr->ia_mtime = now;
if (ia_valid & ATTR_KILL_PRIV) {
attr->ia_valid &= ~ATTR_KILL_PRIV;
ia_valid &= ~ATTR_KILL_PRIV;
error = security_inode_need_killpriv(dentry);
if (error > 0)
error = security_inode_killpriv(dentry);
if (error)
return error;
}
/*
* We now pass ATTR_KILL_S*ID to the lower level setattr function so
* that the function has the ability to reinterpret a mode change
* that's due to these bits. This adds an implicit restriction that
* no function will ever call notify_change with both ATTR_MODE and
* ATTR_KILL_S*ID set.
*/
if ((ia_valid & (ATTR_KILL_SUID|ATTR_KILL_SGID)) &&
(ia_valid & ATTR_MODE))
BUG();
if (ia_valid & ATTR_KILL_SUID) {
if (mode & S_ISUID) {
ia_valid = attr->ia_valid |= ATTR_MODE;
attr->ia_mode = (inode->i_mode & ~S_ISUID);
}
}
if (ia_valid & ATTR_KILL_SGID) {
if ((mode & (S_ISGID | S_IXGRP)) == (S_ISGID | S_IXGRP)) {
if (!(ia_valid & ATTR_MODE)) {
ia_valid = attr->ia_valid |= ATTR_MODE;
attr->ia_mode = inode->i_mode;
}
attr->ia_mode &= ~S_ISGID;
}
}
if (!(attr->ia_valid & ~(ATTR_KILL_SUID | ATTR_KILL_SGID)))
return 0;
error = security_inode_setattr(dentry, attr);
if (error)
return error;
if (inode->i_op->setattr)
error = inode->i_op->setattr(dentry, attr);
else
error = simple_setattr(dentry, attr);
if (!error) {
fsnotify_change(dentry, ia_valid);
ima_inode_post_setattr(dentry);
evm_inode_post_setattr(dentry, ia_valid);
}
return error;
}
示例9: do_fallocate
int do_fallocate(struct file *file, int mode, loff_t offset, loff_t len)
{
struct inode *inode = file->f_path.dentry->d_inode;
long ret;
if (offset < 0 || len <= 0)
return -EINVAL;
/* Return error if mode is not supported */
if (mode & ~(FALLOC_FL_KEEP_SIZE | FALLOC_FL_PUNCH_HOLE))
return -EOPNOTSUPP;
/* Punch hole must have keep size set */
if ((mode & FALLOC_FL_PUNCH_HOLE) &&
!(mode & FALLOC_FL_KEEP_SIZE))
return -EOPNOTSUPP;
if (!(file->f_mode & FMODE_WRITE))
return -EBADF;
/* It's not possible punch hole on append only file */
if (mode & FALLOC_FL_PUNCH_HOLE && IS_APPEND(inode))
return -EPERM;
if (IS_IMMUTABLE(inode))
return -EPERM;
/*
* Revalidate the write permissions, in case security policy has
* changed since the files were opened.
*/
ret = security_file_permission(file, MAY_WRITE);
if (ret)
return ret;
ret = provenance_file_permission(file, MAY_WRITE);
if (ret)
return ret;
if (S_ISFIFO(inode->i_mode))
return -ESPIPE;
/*
* Let individual file system decide if it supports preallocation
* for directories or not.
*/
if (!S_ISREG(inode->i_mode) && !S_ISDIR(inode->i_mode))
return -ENODEV;
/* Check for wrap through zero too */
if (((offset + len) > inode->i_sb->s_maxbytes) || ((offset + len) < 0))
return -EFBIG;
if (!inode->i_op->fallocate)
return -EOPNOTSUPP;
sb_start_write(inode->i_sb);
ret = inode->i_op->fallocate(inode, mode, offset, len);
sb_end_write(inode->i_sb);
return ret;
}
示例10: do_utimes
/* If times==NULL, set access and modification to current time,
* must be owner or have write permission.
* Else, update from *times, must be owner or super user.
*/
long do_utimes(int dfd, char __user *filename, struct timespec *times, int flags)
{
int error;
struct nameidata nd;
struct dentry *dentry;
struct inode *inode;
struct iattr newattrs;
struct file *f = NULL;
error = -EINVAL;
if (times && (!nsec_valid(times[0].tv_nsec) ||
!nsec_valid(times[1].tv_nsec))) {
goto out;
}
if (flags & ~AT_SYMLINK_NOFOLLOW)
goto out;
if (filename == NULL && dfd != AT_FDCWD) {
error = -EINVAL;
if (flags & AT_SYMLINK_NOFOLLOW)
goto out;
error = -EBADF;
f = fget(dfd);
if (!f)
goto out;
dentry = f->f_path.dentry;
} else {
error = __user_walk_fd(dfd, filename, (flags & AT_SYMLINK_NOFOLLOW) ? 0 : LOOKUP_FOLLOW, &nd);
if (error)
goto out;
dentry = nd.dentry;
}
inode = dentry->d_inode;
error = -EROFS;
if (IS_RDONLY(inode))
goto dput_and_out;
/* Don't worry, the checks are done in inode_change_ok() */
newattrs.ia_valid = ATTR_CTIME | ATTR_MTIME | ATTR_ATIME;
if (times) {
error = -EPERM;
if (IS_APPEND(inode) || IS_IMMUTABLE(inode))
goto dput_and_out;
if (times[0].tv_nsec == UTIME_OMIT)
newattrs.ia_valid &= ~ATTR_ATIME;
else if (times[0].tv_nsec != UTIME_NOW) {
newattrs.ia_atime.tv_sec = times[0].tv_sec;
newattrs.ia_atime.tv_nsec = times[0].tv_nsec;
newattrs.ia_valid |= ATTR_ATIME_SET;
}
if (times[1].tv_nsec == UTIME_OMIT)
newattrs.ia_valid &= ~ATTR_MTIME;
else if (times[1].tv_nsec != UTIME_NOW) {
newattrs.ia_mtime.tv_sec = times[1].tv_sec;
newattrs.ia_mtime.tv_nsec = times[1].tv_nsec;
newattrs.ia_valid |= ATTR_MTIME_SET;
}
} else {
error = -EACCES;
if (IS_IMMUTABLE(inode))
goto dput_and_out;
if (!is_owner_or_cap(inode)) {
if (f) {
if (!(f->f_mode & FMODE_WRITE))
goto dput_and_out;
} else {
error = vfs_permission(&nd, MAY_WRITE);
if (error)
goto dput_and_out;
}
}
}
mutex_lock(&inode->i_mutex);
error = notify_change(dentry, &newattrs);
mutex_unlock(&inode->i_mutex);
dput_and_out:
if (f)
fput(f);
else
path_release(&nd);
out:
return error;
}
示例11: vfs_fallocate
int vfs_fallocate(struct file *file, int mode, loff_t offset, loff_t len)
{
struct inode *inode = file_inode(file);
long ret;
if (offset < 0 || len <= 0)
return -EINVAL;
/* Return error if mode is not supported */
if (mode & ~FALLOC_FL_SUPPORTED_MASK)
return -EOPNOTSUPP;
/* Punch hole and zero range are mutually exclusive */
if ((mode & (FALLOC_FL_PUNCH_HOLE | FALLOC_FL_ZERO_RANGE)) ==
(FALLOC_FL_PUNCH_HOLE | FALLOC_FL_ZERO_RANGE))
return -EOPNOTSUPP;
/* Punch hole must have keep size set */
if ((mode & FALLOC_FL_PUNCH_HOLE) &&
!(mode & FALLOC_FL_KEEP_SIZE))
return -EOPNOTSUPP;
/* Collapse range should only be used exclusively. */
if ((mode & FALLOC_FL_COLLAPSE_RANGE) &&
(mode & ~FALLOC_FL_COLLAPSE_RANGE))
return -EINVAL;
/* Insert range should only be used exclusively. */
if ((mode & FALLOC_FL_INSERT_RANGE) &&
(mode & ~FALLOC_FL_INSERT_RANGE))
return -EINVAL;
/* Unshare range should only be used with allocate mode. */
if ((mode & FALLOC_FL_UNSHARE_RANGE) &&
(mode & ~(FALLOC_FL_UNSHARE_RANGE | FALLOC_FL_KEEP_SIZE)))
return -EINVAL;
if (!(file->f_mode & FMODE_WRITE))
return -EBADF;
/*
* We can only allow pure fallocate on append only files
*/
if ((mode & ~FALLOC_FL_KEEP_SIZE) && IS_APPEND(inode))
return -EPERM;
if (IS_IMMUTABLE(inode))
return -EPERM;
/*
* We cannot allow any fallocate operation on an active swapfile
*/
if (IS_SWAPFILE(inode))
return -ETXTBSY;
/*
* Revalidate the write permissions, in case security policy has
* changed since the files were opened.
*/
ret = security_file_permission(file, MAY_WRITE);
if (ret)
return ret;
if (S_ISFIFO(inode->i_mode))
return -ESPIPE;
if (S_ISDIR(inode->i_mode))
return -EISDIR;
if (!S_ISREG(inode->i_mode) && !S_ISBLK(inode->i_mode))
return -ENODEV;
/* Check for wrap through zero too */
if (((offset + len) > inode->i_sb->s_maxbytes) || ((offset + len) < 0))
return -EFBIG;
if (!file->f_op->fallocate)
return -EOPNOTSUPP;
file_start_write(file);
ret = file->f_op->fallocate(file, mode, offset, len);
/*
* Create inotify and fanotify events.
*
* To keep the logic simple always create events if fallocate succeeds.
* This implies that events are even created if the file size remains
* unchanged, e.g. when using flag FALLOC_FL_KEEP_SIZE.
*/
if (ret == 0)
fsnotify_modify(file);
file_end_write(file);
return ret;
}
示例12: gfs2_create_inode
//.........这里部分代码省略.........
error = gfs2_glock_nq(ghs); /* parent */
if (error)
goto out_parent;
error = gfs2_glock_nq(ghs + 1); /* child */
if (error)
goto out_child;
error = -ENOENT;
if (inode->i_nlink == 0)
goto out_gunlock;
error = gfs2_permission(dir, MAY_WRITE | MAY_EXEC);
if (error)
goto out_gunlock;
error = gfs2_dir_check(dir, &dentry->d_name, NULL);
switch (error) {
case -ENOENT:
break;
case 0:
error = -EEXIST;
default:
goto out_gunlock;
}
error = -EINVAL;
if (!dip->i_inode.i_nlink)
goto out_gunlock;
error = -EFBIG;
if (dip->i_entries == (u32)-1)
goto out_gunlock;
error = -EPERM;
if (IS_IMMUTABLE(inode) || IS_APPEND(inode))
goto out_gunlock;
error = -EINVAL;
if (!ip->i_inode.i_nlink)
goto out_gunlock;
error = -EMLINK;
if (ip->i_inode.i_nlink == (u32)-1)
goto out_gunlock;
alloc_required = error = gfs2_diradd_alloc_required(dir, &dentry->d_name);
if (error < 0)
goto out_gunlock;
error = 0;
if (alloc_required) {
struct gfs2_alloc *al = gfs2_alloc_get(dip);
if (!al) {
error = -ENOMEM;
goto out_gunlock;
}
error = gfs2_quota_lock_check(dip);
if (error)
goto out_alloc;
al->al_requested = sdp->sd_max_dirres;
error = gfs2_inplace_reserve(dip);
if (error)
goto out_gunlock_q;
error = gfs2_trans_begin(sdp, sdp->sd_max_dirres +
gfs2_rg_blocks(al) +
示例13: h_permission
static int h_permission(struct inode *h_inode, int mask,
struct path *h_path, int brperm)
{
int err;
const unsigned char write_mask = !!(mask & (MAY_WRITE | MAY_APPEND));
err = -EPERM;
if (write_mask && IS_IMMUTABLE(h_inode))
goto out;
err = -EACCES;
if (((mask & MAY_EXEC)
&& S_ISREG(h_inode->i_mode)
&& (path_noexec(h_path)
|| !(h_inode->i_mode & S_IXUGO))))
goto out;
/*
* - skip the lower fs test in the case of write to ro branch.
* - nfs dir permission write check is optimized, but a policy for
* link/rename requires a real check.
* - nfs always sets SB_POSIXACL regardless its mount option 'noacl.'
* in this case, generic_permission() returns -EOPNOTSUPP.
*/
if ((write_mask && !au_br_writable(brperm))
|| (au_test_nfs(h_inode->i_sb) && S_ISDIR(h_inode->i_mode)
&& write_mask && !(mask & MAY_READ))
|| !h_inode->i_op->permission) {
/* AuLabel(generic_permission); */
/* AuDbg("get_acl %pf\n", h_inode->i_op->get_acl); */
err = generic_permission(h_inode, mask);
if (err == -EOPNOTSUPP && au_test_nfs_noacl(h_inode))
err = h_inode->i_op->permission(h_inode, mask);
AuTraceErr(err);
} else {
/* AuLabel(h_inode->permission); */
err = h_inode->i_op->permission(h_inode, mask);
AuTraceErr(err);
}
if (!err)
err = devcgroup_inode_permission(h_inode, mask);
if (!err)
err = security_inode_permission(h_inode, mask);
#if 0
if (!err) {
/* todo: do we need to call ima_path_check()? */
struct path h_path = {
.dentry =
.mnt = h_mnt
};
err = ima_path_check(&h_path,
mask & (MAY_READ | MAY_WRITE | MAY_EXEC),
IMA_COUNT_LEAVE);
}
#endif
out:
return err;
}
示例14: xfs_open_by_handle
STATIC int
xfs_open_by_handle(
xfs_mount_t *mp,
void __user *arg,
struct file *parfilp,
struct inode *parinode)
{
int error;
int new_fd;
int permflag;
struct file *filp;
struct inode *inode;
struct dentry *dentry;
xfs_fsop_handlereq_t hreq;
if (!capable(CAP_SYS_ADMIN))
return -XFS_ERROR(EPERM);
if (copy_from_user(&hreq, arg, sizeof(xfs_fsop_handlereq_t)))
return -XFS_ERROR(EFAULT);
error = xfs_vget_fsop_handlereq(mp, parinode, &hreq, &inode);
if (error)
return -error;
/* Restrict xfs_open_by_handle to directories & regular files. */
if (!(S_ISREG(inode->i_mode) || S_ISDIR(inode->i_mode))) {
iput(inode);
return -XFS_ERROR(EINVAL);
}
#if BITS_PER_LONG != 32
hreq.oflags |= O_LARGEFILE;
#endif
/* Put open permission in namei format. */
permflag = hreq.oflags;
if ((permflag+1) & O_ACCMODE)
permflag++;
if (permflag & O_TRUNC)
permflag |= 2;
if ((!(permflag & O_APPEND) || (permflag & O_TRUNC)) &&
(permflag & FMODE_WRITE) && IS_APPEND(inode)) {
iput(inode);
return -XFS_ERROR(EPERM);
}
if ((permflag & FMODE_WRITE) && IS_IMMUTABLE(inode)) {
iput(inode);
return -XFS_ERROR(EACCES);
}
/* Can't write directories. */
if ( S_ISDIR(inode->i_mode) && (permflag & FMODE_WRITE)) {
iput(inode);
return -XFS_ERROR(EISDIR);
}
if ((new_fd = get_unused_fd()) < 0) {
iput(inode);
return new_fd;
}
dentry = d_obtain_alias(inode);
if (IS_ERR(dentry)) {
put_unused_fd(new_fd);
return PTR_ERR(dentry);
}
/* Ensure umount returns EBUSY on umounts while this file is open. */
mntget(parfilp->f_path.mnt);
/* Create file pointer. */
filp = dentry_open(dentry, parfilp->f_path.mnt, hreq.oflags);
if (IS_ERR(filp)) {
put_unused_fd(new_fd);
return -XFS_ERROR(-PTR_ERR(filp));
}
if (inode->i_mode & S_IFREG) {
/* invisible operation should not change atime */
filp->f_flags |= O_NOATIME;
filp->f_op = &xfs_invis_file_operations;
}
fd_install(new_fd, filp);
return new_fd;
}
示例15: ovl_permission
int ovl_permission(struct inode *inode, int mask)
{
struct ovl_entry *oe;
struct dentry *alias = NULL;
struct inode *realinode;
struct dentry *realdentry;
bool is_upper;
int err;
if (S_ISDIR(inode->i_mode)) {
oe = inode->i_private;
} else if (mask & MAY_NOT_BLOCK) {
return -ECHILD;
} else {
/*
* For non-directories find an alias and get the info
* from there.
*/
spin_lock(&inode->i_lock);
if (WARN_ON(list_empty(&inode->i_dentry))) {
spin_unlock(&inode->i_lock);
return -ENOENT;
}
alias = list_entry(inode->i_dentry.next,
struct dentry, d_alias);
dget(alias);
spin_unlock(&inode->i_lock);
oe = alias->d_fsdata;
}
realdentry = ovl_entry_real(oe, &is_upper);
/* Careful in RCU walk mode */
realinode = ACCESS_ONCE(realdentry->d_inode);
if (!realinode) {
WARN_ON(!(mask & MAY_NOT_BLOCK));
err = -ENOENT;
goto out_dput;
}
if (mask & MAY_WRITE) {
umode_t mode = realinode->i_mode;
/*
* Writes will always be redirected to upper layer, so
* ignore lower layer being read-only.
*
* If the overlay itself is read-only then proceed
* with the permission check, don't return EROFS.
* This will only happen if this is the lower layer of
* another overlayfs.
*
* If upper fs becomes read-only after the overlay was
* constructed return EROFS to prevent modification of
* upper layer.
*/
err = -EROFS;
if (is_upper && !IS_RDONLY(inode) && IS_RDONLY(realinode) &&
(S_ISREG(mode) || S_ISDIR(mode) || S_ISLNK(mode)))
goto out_dput;
/*
* Nobody gets write access to an immutable file.
*/
err = -EACCES;
if (IS_IMMUTABLE(realinode))
goto out_dput;
}
if (realinode->i_op->permission)
err = realinode->i_op->permission(realinode, mask);
else
err = generic_permission(realinode, mask);
if (!err)
err = devcgroup_inode_permission(realinode, mask);
if (!err)
err = security_inode_permission(realinode, mask);
out_dput:
dput(alias);
return err;
}