Merge branch 'work.inode-type-fixes' of git://git.kernel.org/pub/scm/linux/kernel/git/viro/vfs

Pull vfs inode type handling updates from Al Viro:
 "We should never change the type bits of ->i_mode or the method tables
  (->i_op and ->i_fop) of a live inode.

  Unfortunately, not all filesystems took care to prevent that"

* 'work.inode-type-fixes' of git://git.kernel.org/pub/scm/linux/kernel/git/viro/vfs:
  spufs: fix bogosity in S_ISGID handling
  9p: missing chunk of "fs/9p: Don't update file type when updating file attributes"
  openpromfs: don't do unlock_new_inode() until the new inode is set up
  hostfs_mknod(): don't bother with init_special_inode()
  cifs: have cifs_fattr_to_inode() refuse to change type on live inode
  cifs: have ->mkdir() handle race with another client sanely
  do_cifs_create(): don't set ->i_mode of something we had not created
  gfs2: be careful with inode refresh
  ocfs2_inode_lock_update(): make sure we don't change the type bits of i_mode
  orangefs_inode_is_stale(): i_mode type bits do *not* form a bitmap...
  vboxsf: don't allow to change the inode type
  afs: Fix updating of i_mode due to 3rd party change
  ceph: don't allow type or device number to change on non-I_NEW inodes
  ceph: fix up error handling with snapdirs
  new helper: inode_wrong_type()
This commit is contained in:
Linus Torvalds 2021-04-27 10:57:42 -07:00
Родитель 57fa2369ab c4ab036a2f
Коммит d1466bc583
29 изменённых файлов: 224 добавлений и 163 удалений

Просмотреть файл

@ -236,10 +236,7 @@ spufs_mkdir(struct inode *dir, struct dentry *dentry, unsigned int flags,
if (!inode) if (!inode)
return -ENOSPC; return -ENOSPC;
if (dir->i_mode & S_ISGID) { inode_init_owner(&init_user_ns, inode, dir, mode | S_IFDIR);
inode->i_gid = dir->i_gid;
inode->i_mode &= S_ISGID;
}
ctx = alloc_spu_context(SPUFS_I(dir)->i_gang); /* XXX gang */ ctx = alloc_spu_context(SPUFS_I(dir)->i_gang); /* XXX gang */
SPUFS_I(inode)->i_ctx = ctx; SPUFS_I(inode)->i_ctx = ctx;
if (!ctx) { if (!ctx) {
@ -470,10 +467,7 @@ spufs_mkgang(struct inode *dir, struct dentry *dentry, umode_t mode)
goto out; goto out;
ret = 0; ret = 0;
if (dir->i_mode & S_ISGID) { inode_init_owner(&init_user_ns, inode, dir, mode | S_IFDIR);
inode->i_gid = dir->i_gid;
inode->i_mode &= S_ISGID;
}
gang = alloc_spu_gang(); gang = alloc_spu_gang();
SPUFS_I(inode)->i_ctx = NULL; SPUFS_I(inode)->i_ctx = NULL;
SPUFS_I(inode)->i_gang = gang; SPUFS_I(inode)->i_gang = gang;

Просмотреть файл

@ -399,7 +399,7 @@ static int v9fs_test_inode(struct inode *inode, void *data)
umode = p9mode2unixmode(v9ses, st, &rdev); umode = p9mode2unixmode(v9ses, st, &rdev);
/* don't match inode of different type */ /* don't match inode of different type */
if ((inode->i_mode & S_IFMT) != (umode & S_IFMT)) if (inode_wrong_type(inode, umode))
return 0; return 0;
/* compare qid details */ /* compare qid details */
@ -1390,7 +1390,7 @@ int v9fs_refresh_inode(struct p9_fid *fid, struct inode *inode)
* Don't update inode if the file type is different * Don't update inode if the file type is different
*/ */
umode = p9mode2unixmode(v9ses, st, &rdev); umode = p9mode2unixmode(v9ses, st, &rdev);
if ((inode->i_mode & S_IFMT) != (umode & S_IFMT)) if (inode_wrong_type(inode, umode))
goto out; goto out;
/* /*

Просмотреть файл

@ -59,7 +59,7 @@ static int v9fs_test_inode_dotl(struct inode *inode, void *data)
struct p9_stat_dotl *st = (struct p9_stat_dotl *)data; struct p9_stat_dotl *st = (struct p9_stat_dotl *)data;
/* don't match inode of different type */ /* don't match inode of different type */
if ((inode->i_mode & S_IFMT) != (st->st_mode & S_IFMT)) if (inode_wrong_type(inode, st->st_mode))
return 0; return 0;
if (inode->i_generation != st->st_gen) if (inode->i_generation != st->st_gen)
@ -663,14 +663,10 @@ v9fs_stat2inode_dotl(struct p9_stat_dotl *stat, struct inode *inode,
if (stat->st_result_mask & P9_STATS_NLINK) if (stat->st_result_mask & P9_STATS_NLINK)
set_nlink(inode, stat->st_nlink); set_nlink(inode, stat->st_nlink);
if (stat->st_result_mask & P9_STATS_MODE) { if (stat->st_result_mask & P9_STATS_MODE) {
inode->i_mode = stat->st_mode; mode = stat->st_mode & S_IALLUGO;
if ((S_ISBLK(inode->i_mode)) || mode |= inode->i_mode & ~S_IALLUGO;
(S_ISCHR(inode->i_mode))) inode->i_mode = mode;
init_special_inode(inode, inode->i_mode,
inode->i_rdev);
} }
if (stat->st_result_mask & P9_STATS_RDEV)
inode->i_rdev = new_decode_dev(stat->st_rdev);
if (!(flags & V9FS_STAT2INODE_KEEP_ISIZE) && if (!(flags & V9FS_STAT2INODE_KEEP_ISIZE) &&
stat->st_result_mask & P9_STATS_SIZE) stat->st_result_mask & P9_STATS_SIZE)
v9fs_i_size_write(inode, stat->st_size); v9fs_i_size_write(inode, stat->st_size);
@ -959,7 +955,7 @@ int v9fs_refresh_inode_dotl(struct p9_fid *fid, struct inode *inode)
/* /*
* Don't update inode if the file type is different * Don't update inode if the file type is different
*/ */
if ((inode->i_mode & S_IFMT) != (st->st_mode & S_IFMT)) if (inode_wrong_type(inode, st->st_mode))
goto out; goto out;
/* /*

Просмотреть файл

@ -102,13 +102,13 @@ static int afs_inode_init_from_status(struct afs_operation *op,
switch (status->type) { switch (status->type) {
case AFS_FTYPE_FILE: case AFS_FTYPE_FILE:
inode->i_mode = S_IFREG | status->mode; inode->i_mode = S_IFREG | (status->mode & S_IALLUGO);
inode->i_op = &afs_file_inode_operations; inode->i_op = &afs_file_inode_operations;
inode->i_fop = &afs_file_operations; inode->i_fop = &afs_file_operations;
inode->i_mapping->a_ops = &afs_fs_aops; inode->i_mapping->a_ops = &afs_fs_aops;
break; break;
case AFS_FTYPE_DIR: case AFS_FTYPE_DIR:
inode->i_mode = S_IFDIR | status->mode; inode->i_mode = S_IFDIR | (status->mode & S_IALLUGO);
inode->i_op = &afs_dir_inode_operations; inode->i_op = &afs_dir_inode_operations;
inode->i_fop = &afs_dir_file_operations; inode->i_fop = &afs_dir_file_operations;
inode->i_mapping->a_ops = &afs_dir_aops; inode->i_mapping->a_ops = &afs_dir_aops;
@ -198,7 +198,7 @@ static void afs_apply_status(struct afs_operation *op,
if (status->mode != vnode->status.mode) { if (status->mode != vnode->status.mode) {
mode = inode->i_mode; mode = inode->i_mode;
mode &= ~S_IALLUGO; mode &= ~S_IALLUGO;
mode |= status->mode; mode |= status->mode & S_IALLUGO;
WRITE_ONCE(inode->i_mode, mode); WRITE_ONCE(inode->i_mode, mode);
} }

Просмотреть файл

@ -3358,7 +3358,13 @@ static void handle_cap_grant(struct inode *inode,
if ((newcaps & CEPH_CAP_AUTH_SHARED) && if ((newcaps & CEPH_CAP_AUTH_SHARED) &&
(extra_info->issued & CEPH_CAP_AUTH_EXCL) == 0) { (extra_info->issued & CEPH_CAP_AUTH_EXCL) == 0) {
inode->i_mode = le32_to_cpu(grant->mode); umode_t mode = le32_to_cpu(grant->mode);
if (inode_wrong_type(inode, mode))
pr_warn_once("inode type changed! (ino %llx.%llx is 0%o, mds says 0%o)\n",
ceph_vinop(inode), inode->i_mode, mode);
else
inode->i_mode = mode;
inode->i_uid = make_kuid(&init_user_ns, le32_to_cpu(grant->uid)); inode->i_uid = make_kuid(&init_user_ns, le32_to_cpu(grant->uid));
inode->i_gid = make_kgid(&init_user_ns, le32_to_cpu(grant->gid)); inode->i_gid = make_kgid(&init_user_ns, le32_to_cpu(grant->gid));
ci->i_btime = extra_info->btime; ci->i_btime = extra_info->btime;

Просмотреть файл

@ -677,6 +677,8 @@ int ceph_handle_snapdir(struct ceph_mds_request *req,
strcmp(dentry->d_name.name, strcmp(dentry->d_name.name,
fsc->mount_options->snapdir_name) == 0) { fsc->mount_options->snapdir_name) == 0) {
struct inode *inode = ceph_get_snapdir(parent); struct inode *inode = ceph_get_snapdir(parent);
if (IS_ERR(inode))
return PTR_ERR(inode);
dout("ENOENT on snapdir %p '%pd', linking to snapdir %p\n", dout("ENOENT on snapdir %p '%pd', linking to snapdir %p\n",
dentry, dentry, inode); dentry, dentry, inode);
BUG_ON(!d_unhashed(dentry)); BUG_ON(!d_unhashed(dentry));

Просмотреть файл

@ -248,9 +248,10 @@ static struct dentry *__snapfh_to_dentry(struct super_block *sb,
ihold(inode); ihold(inode);
} else { } else {
/* mds does not support lookup snapped inode */ /* mds does not support lookup snapped inode */
err = -EOPNOTSUPP; inode = ERR_PTR(-EOPNOTSUPP);
inode = NULL;
} }
} else {
inode = ERR_PTR(-ESTALE);
} }
ceph_mdsc_put_request(req); ceph_mdsc_put_request(req);
@ -261,8 +262,8 @@ static struct dentry *__snapfh_to_dentry(struct super_block *sb,
dout("snapfh_to_dentry %llx.%llx parent %llx hash %x err=%d", dout("snapfh_to_dentry %llx.%llx parent %llx hash %x err=%d",
vino.ino, vino.snap, sfh->parent_ino, sfh->hash, err); vino.ino, vino.snap, sfh->parent_ino, sfh->hash, err);
} }
if (!inode) if (IS_ERR(inode))
return ERR_PTR(-ESTALE); return ERR_CAST(inode);
/* see comments in ceph_get_parent() */ /* see comments in ceph_get_parent() */
return unlinked ? d_obtain_root(inode) : d_obtain_alias(inode); return unlinked ? d_obtain_root(inode) : d_obtain_alias(inode);
} }

Просмотреть файл

@ -78,9 +78,21 @@ struct inode *ceph_get_snapdir(struct inode *parent)
struct inode *inode = ceph_get_inode(parent->i_sb, vino); struct inode *inode = ceph_get_inode(parent->i_sb, vino);
struct ceph_inode_info *ci = ceph_inode(inode); struct ceph_inode_info *ci = ceph_inode(inode);
BUG_ON(!S_ISDIR(parent->i_mode));
if (IS_ERR(inode)) if (IS_ERR(inode))
return inode; return inode;
if (!S_ISDIR(parent->i_mode)) {
pr_warn_once("bad snapdir parent type (mode=0%o)\n",
parent->i_mode);
return ERR_PTR(-ENOTDIR);
}
if (!(inode->i_state & I_NEW) && !S_ISDIR(inode->i_mode)) {
pr_warn_once("bad snapdir inode type (mode=0%o)\n",
inode->i_mode);
return ERR_PTR(-ENOTDIR);
}
inode->i_mode = parent->i_mode; inode->i_mode = parent->i_mode;
inode->i_uid = parent->i_uid; inode->i_uid = parent->i_uid;
inode->i_gid = parent->i_gid; inode->i_gid = parent->i_gid;
@ -757,11 +769,32 @@ int ceph_fill_inode(struct inode *inode, struct page *locked_page,
bool queue_trunc = false; bool queue_trunc = false;
bool new_version = false; bool new_version = false;
bool fill_inline = false; bool fill_inline = false;
umode_t mode = le32_to_cpu(info->mode);
dev_t rdev = le32_to_cpu(info->rdev);
dout("%s %p ino %llx.%llx v %llu had %llu\n", __func__, dout("%s %p ino %llx.%llx v %llu had %llu\n", __func__,
inode, ceph_vinop(inode), le64_to_cpu(info->version), inode, ceph_vinop(inode), le64_to_cpu(info->version),
ci->i_version); ci->i_version);
/* Once I_NEW is cleared, we can't change type or dev numbers */
if (inode->i_state & I_NEW) {
inode->i_mode = mode;
} else {
if (inode_wrong_type(inode, mode)) {
pr_warn_once("inode type changed! (ino %llx.%llx is 0%o, mds says 0%o)\n",
ceph_vinop(inode), inode->i_mode, mode);
return -ESTALE;
}
if ((S_ISCHR(mode) || S_ISBLK(mode)) && inode->i_rdev != rdev) {
pr_warn_once("dev inode rdev changed! (ino %llx.%llx is %u:%u, mds says %u:%u)\n",
ceph_vinop(inode), MAJOR(inode->i_rdev),
MINOR(inode->i_rdev), MAJOR(rdev),
MINOR(rdev));
return -ESTALE;
}
}
info_caps = le32_to_cpu(info->cap.caps); info_caps = le32_to_cpu(info->cap.caps);
/* prealloc new cap struct */ /* prealloc new cap struct */
@ -815,8 +848,6 @@ int ceph_fill_inode(struct inode *inode, struct page *locked_page,
issued |= __ceph_caps_dirty(ci); issued |= __ceph_caps_dirty(ci);
new_issued = ~issued & info_caps; new_issued = ~issued & info_caps;
/* update inode */
inode->i_rdev = le32_to_cpu(info->rdev);
/* directories have fl_stripe_unit set to zero */ /* directories have fl_stripe_unit set to zero */
if (le32_to_cpu(info->layout.fl_stripe_unit)) if (le32_to_cpu(info->layout.fl_stripe_unit))
inode->i_blkbits = inode->i_blkbits =
@ -828,7 +859,7 @@ int ceph_fill_inode(struct inode *inode, struct page *locked_page,
if ((new_version || (new_issued & CEPH_CAP_AUTH_SHARED)) && if ((new_version || (new_issued & CEPH_CAP_AUTH_SHARED)) &&
(issued & CEPH_CAP_AUTH_EXCL) == 0) { (issued & CEPH_CAP_AUTH_EXCL) == 0) {
inode->i_mode = le32_to_cpu(info->mode); inode->i_mode = mode;
inode->i_uid = make_kuid(&init_user_ns, le32_to_cpu(info->uid)); inode->i_uid = make_kuid(&init_user_ns, le32_to_cpu(info->uid));
inode->i_gid = make_kgid(&init_user_ns, le32_to_cpu(info->gid)); inode->i_gid = make_kgid(&init_user_ns, le32_to_cpu(info->gid));
dout("%p mode 0%o uid.gid %d.%d\n", inode, inode->i_mode, dout("%p mode 0%o uid.gid %d.%d\n", inode, inode->i_mode,
@ -926,7 +957,7 @@ int ceph_fill_inode(struct inode *inode, struct page *locked_page,
case S_IFCHR: case S_IFCHR:
case S_IFSOCK: case S_IFSOCK:
inode->i_blkbits = PAGE_SHIFT; inode->i_blkbits = PAGE_SHIFT;
init_special_inode(inode, inode->i_mode, inode->i_rdev); init_special_inode(inode, inode->i_mode, rdev);
inode->i_op = &ceph_file_iops; inode->i_op = &ceph_file_iops;
break; break;
case S_IFREG: case S_IFREG:

Просмотреть файл

@ -205,7 +205,7 @@ extern void cifs_unix_basic_to_fattr(struct cifs_fattr *fattr,
struct cifs_sb_info *cifs_sb); struct cifs_sb_info *cifs_sb);
extern void cifs_dir_info_to_fattr(struct cifs_fattr *, FILE_DIRECTORY_INFO *, extern void cifs_dir_info_to_fattr(struct cifs_fattr *, FILE_DIRECTORY_INFO *,
struct cifs_sb_info *); struct cifs_sb_info *);
extern void cifs_fattr_to_inode(struct inode *inode, struct cifs_fattr *fattr); extern int cifs_fattr_to_inode(struct inode *inode, struct cifs_fattr *fattr);
extern struct inode *cifs_iget(struct super_block *sb, extern struct inode *cifs_iget(struct super_block *sb,
struct cifs_fattr *fattr); struct cifs_fattr *fattr);

Просмотреть файл

@ -374,15 +374,16 @@ cifs_create_get_file_info:
if (newinode) { if (newinode) {
if (server->ops->set_lease_key) if (server->ops->set_lease_key)
server->ops->set_lease_key(newinode, fid); server->ops->set_lease_key(newinode, fid);
if (cifs_sb->mnt_cifs_flags & CIFS_MOUNT_DYNPERM) if ((*oplock & CIFS_CREATE_ACTION) && S_ISREG(newinode->i_mode)) {
newinode->i_mode = mode; if (cifs_sb->mnt_cifs_flags & CIFS_MOUNT_DYNPERM)
if ((*oplock & CIFS_CREATE_ACTION) && newinode->i_mode = mode;
(cifs_sb->mnt_cifs_flags & CIFS_MOUNT_SET_UID)) { if (cifs_sb->mnt_cifs_flags & CIFS_MOUNT_SET_UID) {
newinode->i_uid = current_fsuid(); newinode->i_uid = current_fsuid();
if (inode->i_mode & S_ISGID) if (inode->i_mode & S_ISGID)
newinode->i_gid = inode->i_gid; newinode->i_gid = inode->i_gid;
else else
newinode->i_gid = current_fsgid(); newinode->i_gid = current_fsgid();
}
} }
} }
} }

Просмотреть файл

@ -166,7 +166,7 @@ int cifs_posix_open(const char *full_path, struct inode **pinode,
} }
} else { } else {
cifs_revalidate_mapping(*pinode); cifs_revalidate_mapping(*pinode);
cifs_fattr_to_inode(*pinode, &fattr); rc = cifs_fattr_to_inode(*pinode, &fattr);
} }
posix_open_ret: posix_open_ret:

Просмотреть файл

@ -157,12 +157,18 @@ cifs_nlink_fattr_to_inode(struct inode *inode, struct cifs_fattr *fattr)
} }
/* populate an inode with info from a cifs_fattr struct */ /* populate an inode with info from a cifs_fattr struct */
void int
cifs_fattr_to_inode(struct inode *inode, struct cifs_fattr *fattr) cifs_fattr_to_inode(struct inode *inode, struct cifs_fattr *fattr)
{ {
struct cifsInodeInfo *cifs_i = CIFS_I(inode); struct cifsInodeInfo *cifs_i = CIFS_I(inode);
struct cifs_sb_info *cifs_sb = CIFS_SB(inode->i_sb); struct cifs_sb_info *cifs_sb = CIFS_SB(inode->i_sb);
if (!(inode->i_state & I_NEW) &&
unlikely(inode_wrong_type(inode, fattr->cf_mode))) {
CIFS_I(inode)->time = 0; /* force reval */
return -ESTALE;
}
cifs_revalidate_cache(inode, fattr); cifs_revalidate_cache(inode, fattr);
spin_lock(&inode->i_lock); spin_lock(&inode->i_lock);
@ -219,6 +225,7 @@ cifs_fattr_to_inode(struct inode *inode, struct cifs_fattr *fattr)
inode->i_flags |= S_AUTOMOUNT; inode->i_flags |= S_AUTOMOUNT;
if (inode->i_state & I_NEW) if (inode->i_state & I_NEW)
cifs_set_ops(inode); cifs_set_ops(inode);
return 0;
} }
void void
@ -363,7 +370,7 @@ cifs_get_file_info_unix(struct file *filp)
rc = 0; rc = 0;
} }
cifs_fattr_to_inode(inode, &fattr); rc = cifs_fattr_to_inode(inode, &fattr);
free_xid(xid); free_xid(xid);
return rc; return rc;
} }
@ -426,14 +433,7 @@ int cifs_get_inode_info_unix(struct inode **pinode,
} }
/* if filetype is different, return error */ /* if filetype is different, return error */
if (unlikely(((*pinode)->i_mode & S_IFMT) != rc = cifs_fattr_to_inode(*pinode, &fattr);
(fattr.cf_mode & S_IFMT))) {
CIFS_I(*pinode)->time = 0; /* force reval */
rc = -ESTALE;
goto cgiiu_exit;
}
cifs_fattr_to_inode(*pinode, &fattr);
} }
cgiiu_exit: cgiiu_exit:
@ -783,7 +783,8 @@ cifs_get_file_info(struct file *filp)
*/ */
fattr.cf_uniqueid = CIFS_I(inode)->uniqueid; fattr.cf_uniqueid = CIFS_I(inode)->uniqueid;
fattr.cf_flags |= CIFS_FATTR_NEED_REVAL; fattr.cf_flags |= CIFS_FATTR_NEED_REVAL;
cifs_fattr_to_inode(inode, &fattr); /* if filetype is different, return error */
rc = cifs_fattr_to_inode(inode, &fattr);
cgfi_exit: cgfi_exit:
free_xid(xid); free_xid(xid);
return rc; return rc;
@ -1100,16 +1101,8 @@ handle_mnt_opt:
rc = -ESTALE; rc = -ESTALE;
goto out; goto out;
} }
/* if filetype is different, return error */ /* if filetype is different, return error */
if (unlikely(((*inode)->i_mode & S_IFMT) != rc = cifs_fattr_to_inode(*inode, &fattr);
(fattr.cf_mode & S_IFMT))) {
CIFS_I(*inode)->time = 0; /* force reval */
rc = -ESTALE;
goto out;
}
cifs_fattr_to_inode(*inode, &fattr);
} }
out: out:
cifs_buf_release(smb1_backup_rsp_buf); cifs_buf_release(smb1_backup_rsp_buf);
@ -1215,14 +1208,7 @@ smb311_posix_get_inode_info(struct inode **inode,
} }
/* if filetype is different, return error */ /* if filetype is different, return error */
if (unlikely(((*inode)->i_mode & S_IFMT) != rc = cifs_fattr_to_inode(*inode, &fattr);
(fattr.cf_mode & S_IFMT))) {
CIFS_I(*inode)->time = 0; /* force reval */
rc = -ESTALE;
goto out;
}
cifs_fattr_to_inode(*inode, &fattr);
} }
out: out:
cifs_put_tlink(tlink); cifs_put_tlink(tlink);
@ -1249,7 +1235,7 @@ cifs_find_inode(struct inode *inode, void *opaque)
return 0; return 0;
/* don't match inode of different type */ /* don't match inode of different type */
if ((inode->i_mode & S_IFMT) != (fattr->cf_mode & S_IFMT)) if (inode_wrong_type(inode, fattr->cf_mode))
return 0; return 0;
/* if it's not a directory or has no dentries, then flag it */ /* if it's not a directory or has no dentries, then flag it */
@ -1317,6 +1303,7 @@ retry_iget5_locked:
} }
} }
/* can't fail - see cifs_find_inode() */
cifs_fattr_to_inode(inode, fattr); cifs_fattr_to_inode(inode, fattr);
if (sb->s_flags & SB_NOATIME) if (sb->s_flags & SB_NOATIME)
inode->i_flags |= S_NOATIME | S_NOCMTIME; inode->i_flags |= S_NOATIME | S_NOCMTIME;
@ -1742,6 +1729,16 @@ cifs_mkdir_qinfo(struct inode *parent, struct dentry *dentry, umode_t mode,
if (rc) if (rc)
return rc; return rc;
if (!S_ISDIR(inode->i_mode)) {
/*
* mkdir succeeded, but another client has managed to remove the
* sucker and replace it with non-directory. Return success,
* but don't leave the child in dcache.
*/
iput(inode);
d_drop(dentry);
return 0;
}
/* /*
* setting nlink not necessary except in cases where we failed to get it * setting nlink not necessary except in cases where we failed to get it
* from the server or was set bogus. Also, since this is a brand new * from the server or was set bogus. Also, since this is a brand new
@ -1793,7 +1790,7 @@ cifs_mkdir_qinfo(struct inode *parent, struct dentry *dentry, umode_t mode,
} }
} }
d_instantiate(dentry, inode); d_instantiate(dentry, inode);
return rc; return 0;
} }
static int static int

Просмотреть файл

@ -119,9 +119,7 @@ retry:
/* update inode in place /* update inode in place
* if both i_ino and i_mode didn't change */ * if both i_ino and i_mode didn't change */
if (CIFS_I(inode)->uniqueid == fattr->cf_uniqueid && if (CIFS_I(inode)->uniqueid == fattr->cf_uniqueid &&
(inode->i_mode & S_IFMT) == cifs_fattr_to_inode(inode, fattr) == 0) {
(fattr->cf_mode & S_IFMT)) {
cifs_fattr_to_inode(inode, fattr);
dput(dentry); dput(dentry);
return; return;
} }

Просмотреть файл

@ -252,7 +252,7 @@ static int fuse_dentry_revalidate(struct dentry *entry, unsigned int flags)
if (ret == -ENOMEM) if (ret == -ENOMEM)
goto out; goto out;
if (ret || fuse_invalid_attr(&outarg.attr) || if (ret || fuse_invalid_attr(&outarg.attr) ||
(outarg.attr.mode ^ inode->i_mode) & S_IFMT) inode_wrong_type(inode, outarg.attr.mode))
goto invalid; goto invalid;
forget_all_cached_acls(inode); forget_all_cached_acls(inode);
@ -1054,7 +1054,7 @@ static int fuse_do_getattr(struct inode *inode, struct kstat *stat,
err = fuse_simple_request(fm, &args); err = fuse_simple_request(fm, &args);
if (!err) { if (!err) {
if (fuse_invalid_attr(&outarg.attr) || if (fuse_invalid_attr(&outarg.attr) ||
(inode->i_mode ^ outarg.attr.mode) & S_IFMT) { inode_wrong_type(inode, outarg.attr.mode)) {
fuse_make_bad(inode); fuse_make_bad(inode);
err = -EIO; err = -EIO;
} else { } else {
@ -1703,7 +1703,7 @@ int fuse_do_setattr(struct dentry *dentry, struct iattr *attr,
} }
if (fuse_invalid_attr(&outarg.attr) || if (fuse_invalid_attr(&outarg.attr) ||
(inode->i_mode ^ outarg.attr.mode) & S_IFMT) { inode_wrong_type(inode, outarg.attr.mode)) {
fuse_make_bad(inode); fuse_make_bad(inode);
err = -EIO; err = -EIO;
goto error; goto error;

Просмотреть файл

@ -350,7 +350,7 @@ retry:
inode->i_generation = generation; inode->i_generation = generation;
fuse_init_inode(inode, attr); fuse_init_inode(inode, attr);
unlock_new_inode(inode); unlock_new_inode(inode);
} else if ((inode->i_mode ^ attr->mode) & S_IFMT) { } else if (inode_wrong_type(inode, attr->mode)) {
/* Inode has changed type, any I/O on the old should fail */ /* Inode has changed type, any I/O on the old should fail */
fuse_make_bad(inode); fuse_make_bad(inode);
iput(inode); iput(inode);

Просмотреть файл

@ -202,7 +202,7 @@ retry:
inode = d_inode(dentry); inode = d_inode(dentry);
if (!inode || if (!inode ||
get_node_id(inode) != o->nodeid || get_node_id(inode) != o->nodeid ||
((o->attr.mode ^ inode->i_mode) & S_IFMT)) { inode_wrong_type(inode, o->attr.mode)) {
d_invalidate(dentry); d_invalidate(dentry);
dput(dentry); dput(dentry);
goto retry; goto retry;

Просмотреть файл

@ -394,18 +394,24 @@ static int gfs2_dinode_in(struct gfs2_inode *ip, const void *buf)
const struct gfs2_dinode *str = buf; const struct gfs2_dinode *str = buf;
struct timespec64 atime; struct timespec64 atime;
u16 height, depth; u16 height, depth;
umode_t mode = be32_to_cpu(str->di_mode);
bool is_new = ip->i_inode.i_flags & I_NEW;
if (unlikely(ip->i_no_addr != be64_to_cpu(str->di_num.no_addr))) if (unlikely(ip->i_no_addr != be64_to_cpu(str->di_num.no_addr)))
goto corrupt; goto corrupt;
if (unlikely(!is_new && inode_wrong_type(&ip->i_inode, mode)))
goto corrupt;
ip->i_no_formal_ino = be64_to_cpu(str->di_num.no_formal_ino); ip->i_no_formal_ino = be64_to_cpu(str->di_num.no_formal_ino);
ip->i_inode.i_mode = be32_to_cpu(str->di_mode); ip->i_inode.i_mode = mode;
ip->i_inode.i_rdev = 0; if (is_new) {
switch (ip->i_inode.i_mode & S_IFMT) { ip->i_inode.i_rdev = 0;
case S_IFBLK: switch (mode & S_IFMT) {
case S_IFCHR: case S_IFBLK:
ip->i_inode.i_rdev = MKDEV(be32_to_cpu(str->di_major), case S_IFCHR:
be32_to_cpu(str->di_minor)); ip->i_inode.i_rdev = MKDEV(be32_to_cpu(str->di_major),
break; be32_to_cpu(str->di_minor));
break;
}
} }
i_uid_write(&ip->i_inode, be32_to_cpu(str->di_uid)); i_uid_write(&ip->i_inode, be32_to_cpu(str->di_uid));

Просмотреть файл

@ -711,7 +711,6 @@ static int hostfs_mknod(struct user_namespace *mnt_userns, struct inode *dir,
if (name == NULL) if (name == NULL)
goto out_put; goto out_put;
init_special_inode(inode, mode, dev);
err = do_mknod(name, mode, MAJOR(dev), MINOR(dev)); err = do_mknod(name, mode, MAJOR(dev), MINOR(dev));
if (err) if (err)
goto out_free; goto out_free;

Просмотреть файл

@ -335,7 +335,7 @@ nfs_find_actor(struct inode *inode, void *opaque)
if (NFS_FILEID(inode) != fattr->fileid) if (NFS_FILEID(inode) != fattr->fileid)
return 0; return 0;
if ((S_IFMT & inode->i_mode) != (S_IFMT & fattr->mode)) if (inode_wrong_type(inode, fattr->mode))
return 0; return 0;
if (nfs_compare_fh(NFS_FH(inode), fh)) if (nfs_compare_fh(NFS_FH(inode), fh))
return 0; return 0;
@ -1461,7 +1461,7 @@ static int nfs_check_inode_attributes(struct inode *inode, struct nfs_fattr *fat
return 0; return 0;
return -ESTALE; return -ESTALE;
} }
if ((fattr->valid & NFS_ATTR_FATTR_TYPE) && (inode->i_mode & S_IFMT) != (fattr->mode & S_IFMT)) if ((fattr->valid & NFS_ATTR_FATTR_TYPE) && inode_wrong_type(inode, fattr->mode))
return -ESTALE; return -ESTALE;
@ -1876,7 +1876,7 @@ static int nfs_update_inode(struct inode *inode, struct nfs_fattr *fattr)
/* /*
* Make sure the inode's type hasn't changed. * Make sure the inode's type hasn't changed.
*/ */
if ((fattr->valid & NFS_ATTR_FATTR_TYPE) && (inode->i_mode & S_IFMT) != (fattr->mode & S_IFMT)) { if ((fattr->valid & NFS_ATTR_FATTR_TYPE) && inode_wrong_type(inode, fattr->mode)) {
/* /*
* Big trouble! The inode has become a different object. * Big trouble! The inode has become a different object.
*/ */

Просмотреть файл

@ -383,7 +383,7 @@ nfsd_proc_create(struct svc_rqst *rqstp)
/* Make sure the type and device matches */ /* Make sure the type and device matches */
resp->status = nfserr_exist; resp->status = nfserr_exist;
if (inode && type != (inode->i_mode & S_IFMT)) if (inode && inode_wrong_type(inode, type))
goto out_unlock; goto out_unlock;
} }

Просмотреть файл

@ -2204,7 +2204,7 @@ static void ocfs2_unpack_timespec(struct timespec64 *spec,
spec->tv_nsec = packed_time & OCFS2_NSEC_MASK; spec->tv_nsec = packed_time & OCFS2_NSEC_MASK;
} }
static void ocfs2_refresh_inode_from_lvb(struct inode *inode) static int ocfs2_refresh_inode_from_lvb(struct inode *inode)
{ {
struct ocfs2_inode_info *oi = OCFS2_I(inode); struct ocfs2_inode_info *oi = OCFS2_I(inode);
struct ocfs2_lock_res *lockres = &oi->ip_inode_lockres; struct ocfs2_lock_res *lockres = &oi->ip_inode_lockres;
@ -2213,6 +2213,8 @@ static void ocfs2_refresh_inode_from_lvb(struct inode *inode)
mlog_meta_lvb(0, lockres); mlog_meta_lvb(0, lockres);
lvb = ocfs2_dlm_lvb(&lockres->l_lksb); lvb = ocfs2_dlm_lvb(&lockres->l_lksb);
if (inode_wrong_type(inode, be16_to_cpu(lvb->lvb_imode)))
return -ESTALE;
/* We're safe here without the lockres lock... */ /* We're safe here without the lockres lock... */
spin_lock(&oi->ip_lock); spin_lock(&oi->ip_lock);
@ -2240,6 +2242,7 @@ static void ocfs2_refresh_inode_from_lvb(struct inode *inode)
ocfs2_unpack_timespec(&inode->i_ctime, ocfs2_unpack_timespec(&inode->i_ctime,
be64_to_cpu(lvb->lvb_ictime_packed)); be64_to_cpu(lvb->lvb_ictime_packed));
spin_unlock(&oi->ip_lock); spin_unlock(&oi->ip_lock);
return 0;
} }
static inline int ocfs2_meta_lvb_is_trustable(struct inode *inode, static inline int ocfs2_meta_lvb_is_trustable(struct inode *inode,
@ -2342,7 +2345,8 @@ static int ocfs2_inode_lock_update(struct inode *inode,
if (ocfs2_meta_lvb_is_trustable(inode, lockres)) { if (ocfs2_meta_lvb_is_trustable(inode, lockres)) {
mlog(0, "Trusting LVB on inode %llu\n", mlog(0, "Trusting LVB on inode %llu\n",
(unsigned long long)oi->ip_blkno); (unsigned long long)oi->ip_blkno);
ocfs2_refresh_inode_from_lvb(inode); status = ocfs2_refresh_inode_from_lvb(inode);
goto bail_refresh;
} else { } else {
/* Boo, we have to go to disk. */ /* Boo, we have to go to disk. */
/* read bh, cast, ocfs2_refresh_inode */ /* read bh, cast, ocfs2_refresh_inode */
@ -2352,6 +2356,10 @@ static int ocfs2_inode_lock_update(struct inode *inode,
goto bail_refresh; goto bail_refresh;
} }
fe = (struct ocfs2_dinode *) (*bh)->b_data; fe = (struct ocfs2_dinode *) (*bh)->b_data;
if (inode_wrong_type(inode, le16_to_cpu(fe->i_mode))) {
status = -ESTALE;
goto bail_refresh;
}
/* This is a good chance to make sure we're not /* This is a good chance to make sure we're not
* locking an invalid object. ocfs2_read_inode_block() * locking an invalid object. ocfs2_read_inode_block()

Просмотреть файл

@ -236,27 +236,31 @@ found:
mutex_unlock(&op_mutex); mutex_unlock(&op_mutex);
if (IS_ERR(inode)) if (IS_ERR(inode))
return ERR_CAST(inode); return ERR_CAST(inode);
ent_oi = OP_I(inode); if (inode->i_state & I_NEW) {
ent_oi->type = ent_type; inode->i_mtime = inode->i_atime = inode->i_ctime = current_time(inode);
ent_oi->u = ent_data; ent_oi = OP_I(inode);
ent_oi->type = ent_type;
ent_oi->u = ent_data;
switch (ent_type) { switch (ent_type) {
case op_inode_node: case op_inode_node:
inode->i_mode = S_IFDIR | S_IRUGO | S_IXUGO; inode->i_mode = S_IFDIR | S_IRUGO | S_IXUGO;
inode->i_op = &openprom_inode_operations; inode->i_op = &openprom_inode_operations;
inode->i_fop = &openprom_operations; inode->i_fop = &openprom_operations;
set_nlink(inode, 2); set_nlink(inode, 2);
break; break;
case op_inode_prop: case op_inode_prop:
if (of_node_name_eq(dp, "options") && (len == 17) && if (of_node_name_eq(dp, "options") && (len == 17) &&
!strncmp (name, "security-password", 17)) !strncmp (name, "security-password", 17))
inode->i_mode = S_IFREG | S_IRUSR | S_IWUSR; inode->i_mode = S_IFREG | S_IRUSR | S_IWUSR;
else else
inode->i_mode = S_IFREG | S_IRUGO; inode->i_mode = S_IFREG | S_IRUGO;
inode->i_fop = &openpromfs_prop_ops; inode->i_fop = &openpromfs_prop_ops;
set_nlink(inode, 1); set_nlink(inode, 1);
inode->i_size = ent_oi->u.prop->length; inode->i_size = ent_oi->u.prop->length;
break; break;
}
unlock_new_inode(inode);
} }
return d_splice_alias(inode, dentry); return d_splice_alias(inode, dentry);
@ -345,20 +349,9 @@ static void openprom_free_inode(struct inode *inode)
static struct inode *openprom_iget(struct super_block *sb, ino_t ino) static struct inode *openprom_iget(struct super_block *sb, ino_t ino)
{ {
struct inode *inode; struct inode *inode = iget_locked(sb, ino);
inode = iget_locked(sb, ino);
if (!inode) if (!inode)
return ERR_PTR(-ENOMEM); inode = ERR_PTR(-ENOMEM);
if (inode->i_state & I_NEW) {
inode->i_mtime = inode->i_atime = inode->i_ctime = current_time(inode);
if (inode->i_ino == OPENPROM_ROOT_INO) {
inode->i_op = &openprom_inode_operations;
inode->i_fop = &openprom_operations;
inode->i_mode = S_IFDIR | S_IRUGO | S_IXUGO;
}
unlock_new_inode(inode);
}
return inode; return inode;
} }
@ -394,9 +387,15 @@ static int openprom_fill_super(struct super_block *s, struct fs_context *fc)
goto out_no_root; goto out_no_root;
} }
root_inode->i_mtime = root_inode->i_atime =
root_inode->i_ctime = current_time(root_inode);
root_inode->i_op = &openprom_inode_operations;
root_inode->i_fop = &openprom_operations;
root_inode->i_mode = S_IFDIR | S_IRUGO | S_IXUGO;
oi = OP_I(root_inode); oi = OP_I(root_inode);
oi->type = op_inode_node; oi->type = op_inode_node;
oi->u.node = of_find_node_by_path("/"); oi->u.node = of_find_node_by_path("/");
unlock_new_inode(root_inode);
s->s_root = d_make_root(root_inode); s->s_root = d_make_root(root_inode);
if (!s->s_root) if (!s->s_root)

Просмотреть файл

@ -221,7 +221,7 @@ static int orangefs_inode_is_stale(struct inode *inode,
* If the inode type or symlink target have changed then this * If the inode type or symlink target have changed then this
* inode is stale. * inode is stale.
*/ */
if (type == -1 || !(inode->i_mode & type)) { if (type == -1 || inode_wrong_type(inode, type)) {
orangefs_make_bad_inode(inode); orangefs_make_bad_inode(inode);
return 1; return 1;
} }

Просмотреть файл

@ -371,7 +371,7 @@ int ovl_check_origin_fh(struct ovl_fs *ofs, struct ovl_fh *fh, bool connected,
return PTR_ERR(origin); return PTR_ERR(origin);
if (upperdentry && !ovl_is_whiteout(upperdentry) && if (upperdentry && !ovl_is_whiteout(upperdentry) &&
((d_inode(origin)->i_mode ^ d_inode(upperdentry)->i_mode) & S_IFMT)) inode_wrong_type(d_inode(upperdentry), d_inode(origin)->i_mode))
goto invalid; goto invalid;
if (!*stackp) if (!*stackp)
@ -730,7 +730,7 @@ struct dentry *ovl_lookup_index(struct ovl_fs *ofs, struct dentry *upper,
index = ERR_PTR(-ESTALE); index = ERR_PTR(-ESTALE);
goto out; goto out;
} else if (ovl_dentry_weird(index) || ovl_is_whiteout(index) || } else if (ovl_dentry_weird(index) || ovl_is_whiteout(index) ||
((inode->i_mode ^ d_inode(origin)->i_mode) & S_IFMT)) { inode_wrong_type(inode, d_inode(origin)->i_mode)) {
/* /*
* Index should always be of the same file type as origin * Index should always be of the same file type as origin
* except for the case of a whiteout index. A whiteout * except for the case of a whiteout index. A whiteout

Просмотреть файл

@ -225,7 +225,7 @@ static struct dentry *vboxsf_dir_lookup(struct inode *parent,
} else { } else {
inode = vboxsf_new_inode(parent->i_sb); inode = vboxsf_new_inode(parent->i_sb);
if (!IS_ERR(inode)) if (!IS_ERR(inode))
vboxsf_init_inode(sbi, inode, &fsinfo); vboxsf_init_inode(sbi, inode, &fsinfo, false);
} }
return d_splice_alias(inode, dentry); return d_splice_alias(inode, dentry);
@ -245,7 +245,7 @@ static int vboxsf_dir_instantiate(struct inode *parent, struct dentry *dentry,
sf_i = VBOXSF_I(inode); sf_i = VBOXSF_I(inode);
/* The host may have given us different attr then requested */ /* The host may have given us different attr then requested */
sf_i->force_restat = 1; sf_i->force_restat = 1;
vboxsf_init_inode(sbi, inode, info); vboxsf_init_inode(sbi, inode, info, false);
d_instantiate(dentry, inode); d_instantiate(dentry, inode);

Просмотреть файл

@ -207,7 +207,7 @@ static int vboxsf_fill_super(struct super_block *sb, struct fs_context *fc)
err = -ENOMEM; err = -ENOMEM;
goto fail_unmap; goto fail_unmap;
} }
vboxsf_init_inode(sbi, iroot, &sbi->root_info); vboxsf_init_inode(sbi, iroot, &sbi->root_info, false);
unlock_new_inode(iroot); unlock_new_inode(iroot);
droot = d_make_root(iroot); droot = d_make_root(iroot);
@ -418,7 +418,7 @@ static int vboxsf_reconfigure(struct fs_context *fc)
/* Apply changed options to the root inode */ /* Apply changed options to the root inode */
sbi->o = ctx->o; sbi->o = ctx->o;
vboxsf_init_inode(sbi, iroot, &sbi->root_info); vboxsf_init_inode(sbi, iroot, &sbi->root_info, true);
return 0; return 0;
} }

Просмотреть файл

@ -45,12 +45,12 @@ struct inode *vboxsf_new_inode(struct super_block *sb)
} }
/* set [inode] attributes based on [info], uid/gid based on [sbi] */ /* set [inode] attributes based on [info], uid/gid based on [sbi] */
void vboxsf_init_inode(struct vboxsf_sbi *sbi, struct inode *inode, int vboxsf_init_inode(struct vboxsf_sbi *sbi, struct inode *inode,
const struct shfl_fsobjinfo *info) const struct shfl_fsobjinfo *info, bool reinit)
{ {
const struct shfl_fsobjattr *attr; const struct shfl_fsobjattr *attr;
s64 allocated; s64 allocated;
int mode; umode_t mode;
attr = &info->attr; attr = &info->attr;
@ -75,29 +75,44 @@ void vboxsf_init_inode(struct vboxsf_sbi *sbi, struct inode *inode,
inode->i_mapping->a_ops = &vboxsf_reg_aops; inode->i_mapping->a_ops = &vboxsf_reg_aops;
if (SHFL_IS_DIRECTORY(attr->mode)) { if (SHFL_IS_DIRECTORY(attr->mode)) {
inode->i_mode = sbi->o.dmode_set ? sbi->o.dmode : mode; if (sbi->o.dmode_set)
inode->i_mode &= ~sbi->o.dmask; mode = sbi->o.dmode;
inode->i_mode |= S_IFDIR; mode &= ~sbi->o.dmask;
inode->i_op = &vboxsf_dir_iops; mode |= S_IFDIR;
inode->i_fop = &vboxsf_dir_fops; if (!reinit) {
/* inode->i_op = &vboxsf_dir_iops;
* XXX: this probably should be set to the number of entries inode->i_fop = &vboxsf_dir_fops;
* in the directory plus two (. ..) /*
*/ * XXX: this probably should be set to the number of entries
set_nlink(inode, 1); * in the directory plus two (. ..)
*/
set_nlink(inode, 1);
} else if (!S_ISDIR(inode->i_mode))
return -ESTALE;
inode->i_mode = mode;
} else if (SHFL_IS_SYMLINK(attr->mode)) { } else if (SHFL_IS_SYMLINK(attr->mode)) {
inode->i_mode = sbi->o.fmode_set ? sbi->o.fmode : mode; if (sbi->o.fmode_set)
inode->i_mode &= ~sbi->o.fmask; mode = sbi->o.fmode;
inode->i_mode |= S_IFLNK; mode &= ~sbi->o.fmask;
inode->i_op = &vboxsf_lnk_iops; mode |= S_IFLNK;
set_nlink(inode, 1); if (!reinit) {
inode->i_op = &vboxsf_lnk_iops;
set_nlink(inode, 1);
} else if (!S_ISLNK(inode->i_mode))
return -ESTALE;
inode->i_mode = mode;
} else { } else {
inode->i_mode = sbi->o.fmode_set ? sbi->o.fmode : mode; if (sbi->o.fmode_set)
inode->i_mode &= ~sbi->o.fmask; mode = sbi->o.fmode;
inode->i_mode |= S_IFREG; mode &= ~sbi->o.fmask;
inode->i_op = &vboxsf_reg_iops; mode |= S_IFREG;
inode->i_fop = &vboxsf_reg_fops; if (!reinit) {
set_nlink(inode, 1); inode->i_op = &vboxsf_reg_iops;
inode->i_fop = &vboxsf_reg_fops;
set_nlink(inode, 1);
} else if (!S_ISREG(inode->i_mode))
return -ESTALE;
inode->i_mode = mode;
} }
inode->i_uid = sbi->o.uid; inode->i_uid = sbi->o.uid;
@ -116,6 +131,7 @@ void vboxsf_init_inode(struct vboxsf_sbi *sbi, struct inode *inode,
info->change_time.ns_relative_to_unix_epoch); info->change_time.ns_relative_to_unix_epoch);
inode->i_mtime = ns_to_timespec64( inode->i_mtime = ns_to_timespec64(
info->modification_time.ns_relative_to_unix_epoch); info->modification_time.ns_relative_to_unix_epoch);
return 0;
} }
int vboxsf_create_at_dentry(struct dentry *dentry, int vboxsf_create_at_dentry(struct dentry *dentry,
@ -199,7 +215,9 @@ int vboxsf_inode_revalidate(struct dentry *dentry)
dentry->d_time = jiffies; dentry->d_time = jiffies;
sf_i->force_restat = 0; sf_i->force_restat = 0;
vboxsf_init_inode(sbi, inode, &info); err = vboxsf_init_inode(sbi, inode, &info, true);
if (err)
return err;
/* /*
* If the file was changed on the host side we need to invalidate the * If the file was changed on the host side we need to invalidate the

Просмотреть файл

@ -82,8 +82,8 @@ extern const struct dentry_operations vboxsf_dentry_ops;
/* from utils.c */ /* from utils.c */
struct inode *vboxsf_new_inode(struct super_block *sb); struct inode *vboxsf_new_inode(struct super_block *sb);
void vboxsf_init_inode(struct vboxsf_sbi *sbi, struct inode *inode, int vboxsf_init_inode(struct vboxsf_sbi *sbi, struct inode *inode,
const struct shfl_fsobjinfo *info); const struct shfl_fsobjinfo *info, bool reinit);
int vboxsf_create_at_dentry(struct dentry *dentry, int vboxsf_create_at_dentry(struct dentry *dentry,
struct shfl_createparms *params); struct shfl_createparms *params);
int vboxsf_stat(struct vboxsf_sbi *sbi, struct shfl_string *path, int vboxsf_stat(struct vboxsf_sbi *sbi, struct shfl_string *path,

Просмотреть файл

@ -2884,6 +2884,11 @@ static inline bool execute_ok(struct inode *inode)
return (inode->i_mode & S_IXUGO) || S_ISDIR(inode->i_mode); return (inode->i_mode & S_IXUGO) || S_ISDIR(inode->i_mode);
} }
static inline bool inode_wrong_type(const struct inode *inode, umode_t mode)
{
return (inode->i_mode ^ mode) & S_IFMT;
}
static inline void file_start_write(struct file *file) static inline void file_start_write(struct file *file)
{ {
if (!S_ISREG(file_inode(file)->i_mode)) if (!S_ISREG(file_inode(file)->i_mode))