inode_has_no_xattr(inode);
unlock_new_inode(inode);
}
+ } else if (is_bad_inode(inode)) {
+ iput(inode);
+ inode = ERR_PTR(-ESTALE);
} else if (!(inode->i_state & (I_FREEING | I_CLEAR))) {
rc = ll_update_inode(inode, md);
CDEBUG(D_VFSTRACE, "got inode: "DFID"(%p): rc = %d\n",
#else /* !HAVE_IOP_ATOMIC_OPEN */
static struct lookup_intent *
-ll_convert_intent(struct open_intent *oit, int lookup_flags)
+ll_convert_intent(struct open_intent *oit, int lookup_flags, bool is_readonly)
{
struct lookup_intent *it;
if (lookup_flags & LOOKUP_OPEN) {
it->it_op = IT_OPEN;
- if (lookup_flags & LOOKUP_CREATE)
+ /* Avoid file creation for ro bind mount point(is_readonly) */
+ if ((lookup_flags & LOOKUP_CREATE) && !is_readonly)
it->it_op |= IT_CREAT;
it->it_create_mode = (oit->create_mode & S_IALLUGO) | S_IFREG;
- it->it_flags = ll_namei_to_lookup_intent_flag(oit->flags);
+ it->it_flags = ll_namei_to_lookup_intent_flag(oit->flags &
+ ~(is_readonly ? O_CREAT : 0));
it->it_flags &= ~MDS_OPEN_FL_INTERNAL;
} else {
it->it_op = IT_GETATTR;
MAY_WRITE | MAY_EXEC) == 0))
RETURN(NULL);
- it = ll_convert_intent(&nd->intent.open, nd->flags);
+ it = ll_convert_intent(&nd->intent.open, nd->flags,
+ (nd->path.mnt->mnt_flags & MNT_READONLY) ||
+ (nd->path.mnt->mnt_sb->s_flags & MS_RDONLY));
if (IS_ERR(it))
RETURN((struct dentry *)it);
}
}
const struct inode_operations ll_dir_inode_operations = {
- .mknod = ll_mknod,
+ .mknod = ll_mknod,
#ifdef HAVE_IOP_ATOMIC_OPEN
- .atomic_open = ll_atomic_open,
+ .atomic_open = ll_atomic_open,
#endif
- .lookup = ll_lookup_nd,
- .create = ll_create_nd,
+ .lookup = ll_lookup_nd,
+ .create = ll_create_nd,
/* We need all these non-raw things for NFSD, to not patch it. */
- .unlink = ll_unlink,
- .mkdir = ll_mkdir,
- .rmdir = ll_rmdir,
- .symlink = ll_symlink,
- .link = ll_link,
- .rename = ll_rename,
- .setattr = ll_setattr,
- .getattr = ll_getattr,
- .permission = ll_inode_permission,
- .setxattr = ll_setxattr,
- .getxattr = ll_getxattr,
- .listxattr = ll_listxattr,
- .removexattr = ll_removexattr,
+ .unlink = ll_unlink,
+ .mkdir = ll_mkdir,
+ .rmdir = ll_rmdir,
+ .symlink = ll_symlink,
+ .link = ll_link,
+ .rename = ll_rename,
+ .setattr = ll_setattr,
+ .getattr = ll_getattr,
+ .permission = ll_inode_permission,
+#ifdef HAVE_IOP_XATTR
+ .setxattr = ll_setxattr,
+ .getxattr = ll_getxattr,
+ .removexattr = ll_removexattr,
+#endif
+ .listxattr = ll_listxattr,
#ifdef HAVE_IOP_GET_ACL
- .get_acl = ll_get_acl,
+ .get_acl = ll_get_acl,
+#endif
+#ifdef HAVE_IOP_SET_ACL
+ .set_acl = ll_set_acl,
#endif
};
.setattr = ll_setattr,
.getattr = ll_getattr,
.permission = ll_inode_permission,
- .setxattr = ll_setxattr,
- .getxattr = ll_getxattr,
- .listxattr = ll_listxattr,
+#ifdef HAVE_IOP_XATTR
+ .setxattr = ll_setxattr,
+ .getxattr = ll_getxattr,
.removexattr = ll_removexattr,
+#endif
+ .listxattr = ll_listxattr,
#ifdef HAVE_IOP_GET_ACL
- .get_acl = ll_get_acl,
+ .get_acl = ll_get_acl,
+#endif
+#ifdef HAVE_IOP_SET_ACL
+ .set_acl = ll_set_acl,
#endif
};