#include "cifs_fs_sb.h"
#include "cifs_unicode.h"
#include "fscache.h"
+#include "fs_context.h"
static void cifs_set_ops(struct inode *inode)
break;
}
- fattr->cf_uid = cifs_sb->mnt_uid;
+ fattr->cf_uid = cifs_sb->ctx->linux_uid;
if (!(cifs_sb->mnt_cifs_flags & CIFS_MOUNT_OVERR_UID)) {
u64 id = le64_to_cpu(info->Uid);
if (id < ((uid_t)-1)) {
}
}
- fattr->cf_gid = cifs_sb->mnt_gid;
+ fattr->cf_gid = cifs_sb->ctx->linux_gid;
if (!(cifs_sb->mnt_cifs_flags & CIFS_MOUNT_OVERR_GID)) {
u64 id = le64_to_cpu(info->Gid);
if (id < ((gid_t)-1)) {
memset(fattr, 0, sizeof(*fattr));
fattr->cf_mode = S_IFDIR | S_IXUGO | S_IRWXU;
- fattr->cf_uid = cifs_sb->mnt_uid;
- fattr->cf_gid = cifs_sb->mnt_gid;
+ fattr->cf_uid = cifs_sb->ctx->linux_uid;
+ fattr->cf_gid = cifs_sb->ctx->linux_gid;
ktime_get_coarse_real_ts64(&fattr->cf_mtime);
fattr->cf_atime = fattr->cf_ctime = fattr->cf_mtime;
fattr->cf_nlink = 2;
}
/* else if reparse point ... TODO: add support for FIFO and blk dev; special file types */
- fattr->cf_uid = cifs_sb->mnt_uid; /* TODO: map uid and gid from SID */
- fattr->cf_gid = cifs_sb->mnt_gid;
+ fattr->cf_uid = cifs_sb->ctx->linux_uid; /* TODO: map uid and gid from SID */
+ fattr->cf_gid = cifs_sb->ctx->linux_gid;
cifs_dbg(FYI, "POSIX query info: mode 0x%x uniqueid 0x%llx nlink %d\n",
fattr->cf_mode, fattr->cf_uniqueid, fattr->cf_nlink);
fattr->cf_nlink = le32_to_cpu(info->NumberOfLinks);
if (reparse_tag == IO_REPARSE_TAG_LX_SYMLINK) {
- fattr->cf_mode |= S_IFLNK | cifs_sb->mnt_file_mode;
+ fattr->cf_mode |= S_IFLNK | cifs_sb->ctx->file_mode;
fattr->cf_dtype = DT_LNK;
} else if (reparse_tag == IO_REPARSE_TAG_LX_FIFO) {
- fattr->cf_mode |= S_IFIFO | cifs_sb->mnt_file_mode;
+ fattr->cf_mode |= S_IFIFO | cifs_sb->ctx->file_mode;
fattr->cf_dtype = DT_FIFO;
} else if (reparse_tag == IO_REPARSE_TAG_AF_UNIX) {
- fattr->cf_mode |= S_IFSOCK | cifs_sb->mnt_file_mode;
+ fattr->cf_mode |= S_IFSOCK | cifs_sb->ctx->file_mode;
fattr->cf_dtype = DT_SOCK;
} else if (reparse_tag == IO_REPARSE_TAG_LX_CHR) {
- fattr->cf_mode |= S_IFCHR | cifs_sb->mnt_file_mode;
+ fattr->cf_mode |= S_IFCHR | cifs_sb->ctx->file_mode;
fattr->cf_dtype = DT_CHR;
} else if (reparse_tag == IO_REPARSE_TAG_LX_BLK) {
- fattr->cf_mode |= S_IFBLK | cifs_sb->mnt_file_mode;
+ fattr->cf_mode |= S_IFBLK | cifs_sb->ctx->file_mode;
fattr->cf_dtype = DT_BLK;
} else if (symlink) { /* TODO add more reparse tag checks */
fattr->cf_mode = S_IFLNK;
fattr->cf_dtype = DT_LNK;
} else if (fattr->cf_cifsattrs & ATTR_DIRECTORY) {
- fattr->cf_mode = S_IFDIR | cifs_sb->mnt_dir_mode;
+ fattr->cf_mode = S_IFDIR | cifs_sb->ctx->dir_mode;
fattr->cf_dtype = DT_DIR;
/*
* Server can return wrong NumberOfLinks value for directories
if (!tcon->unix_ext)
fattr->cf_flags |= CIFS_FATTR_UNKNOWN_NLINK;
} else {
- fattr->cf_mode = S_IFREG | cifs_sb->mnt_file_mode;
+ fattr->cf_mode = S_IFREG | cifs_sb->ctx->file_mode;
fattr->cf_dtype = DT_REG;
/* clear write bits if ATTR_READONLY is set */
}
}
- fattr->cf_uid = cifs_sb->mnt_uid;
- fattr->cf_gid = cifs_sb->mnt_gid;
+ fattr->cf_uid = cifs_sb->ctx->linux_uid;
+ fattr->cf_gid = cifs_sb->ctx->linux_gid;
}
static int
*/
rc = 0;
CIFS_I(inode)->time = 0;
+ goto cgfi_exit;
default:
goto cgfi_exit;
}
* cifs_backup_query_path_info - SMB1 fallback code to get ino
*
* Fallback code to get file metadata when we don't have access to
- * @full_path (EACCES) and have backup creds.
+ * full_path (EACCES) and have backup creds.
*
- * @data will be set to search info result buffer
- * @resp_buf will be set to cifs resp buf and needs to be freed with
- * cifs_buf_release() when done with @data.
+ * @xid: transaction id used to identify original request in logs
+ * @tcon: information about the server share we have mounted
+ * @sb: the superblock stores info such as disk space available
+ * @full_path: name of the file we are getting the metadata for
+ * @resp_buf: will be set to cifs resp buf and needs to be freed with
+ * cifs_buf_release() when done with @data
+ * @data: will be set to search info result buffer
*/
static int
cifs_backup_query_path_info(int xid,
set_nlink(inode, 2);
inode->i_op = &cifs_ipc_inode_ops;
inode->i_fop = &simple_dir_operations;
- inode->i_uid = cifs_sb->mnt_uid;
- inode->i_gid = cifs_sb->mnt_gid;
+ inode->i_uid = cifs_sb->ctx->linux_uid;
+ inode->i_gid = cifs_sb->ctx->linux_gid;
spin_unlock(&inode->i_lock);
} else if (rc) {
iget_failed(inode);
goto posix_mkdir_out;
}
-int cifs_mkdir(struct inode *inode, struct dentry *direntry, umode_t mode)
+int cifs_mkdir(struct user_namespace *mnt_userns, struct inode *inode,
+ struct dentry *direntry, umode_t mode)
{
int rc = 0;
unsigned int xid;
}
int
-cifs_rename2(struct inode *source_dir, struct dentry *source_dentry,
- struct inode *target_dir, struct dentry *target_dentry,
- unsigned int flags)
+cifs_rename2(struct user_namespace *mnt_userns, struct inode *source_dir,
+ struct dentry *source_dentry, struct inode *target_dir,
+ struct dentry *target_dentry, unsigned int flags)
{
char *from_name = NULL;
char *to_name = NULL;
if (!lookupCacheEnabled)
return true;
- if (!cifs_sb->actimeo)
+ if (!cifs_sb->ctx->actimeo)
return true;
if (!time_in_range(jiffies, cifs_i->time,
- cifs_i->time + cifs_sb->actimeo))
+ cifs_i->time + cifs_sb->ctx->actimeo))
return true;
/* hardlinked files w/ noserverino get "special" treatment */
/**
* cifs_wait_bit_killable - helper for functions that are sleeping on bit locks
- * @word: long word containing the bit lock
+ *
+ * @key: currently unused
+ * @mode: the task state to sleep in
*/
static int
cifs_wait_bit_killable(struct wait_bit_key *key, int mode)
return cifs_revalidate_mapping(inode);
}
-int cifs_getattr(const struct path *path, struct kstat *stat,
- u32 request_mask, unsigned int flags)
+int cifs_getattr(struct user_namespace *mnt_userns, const struct path *path,
+ struct kstat *stat, u32 request_mask, unsigned int flags)
{
struct dentry *dentry = path->dentry;
struct cifs_sb_info *cifs_sb = CIFS_SB(dentry->d_sb);
return rc;
}
- generic_fillattr(inode, stat);
- stat->blksize = cifs_sb->bsize;
+ generic_fillattr(&init_user_ns, inode, stat);
+ stat->blksize = cifs_sb->ctx->bsize;
stat->ino = CIFS_I(inode)->uniqueid;
/* old CIFS Unix Extensions doesn't return create time */
if (cifs_sb->mnt_cifs_flags & CIFS_MOUNT_NO_PERM)
attrs->ia_valid |= ATTR_FORCE;
- rc = setattr_prepare(direntry, attrs);
+ rc = setattr_prepare(&init_user_ns, direntry, attrs);
if (rc < 0)
goto out;
attrs->ia_size != i_size_read(inode))
truncate_setsize(inode, attrs->ia_size);
- setattr_copy(inode, attrs);
+ setattr_copy(&init_user_ns, inode, attrs);
mark_inode_dirty(inode);
/* force revalidate when any of these times are set since some
if (cifs_sb->mnt_cifs_flags & CIFS_MOUNT_NO_PERM)
attrs->ia_valid |= ATTR_FORCE;
- rc = setattr_prepare(direntry, attrs);
+ rc = setattr_prepare(&init_user_ns, direntry, attrs);
if (rc < 0) {
free_xid(xid);
return rc;
if ((cifs_sb->mnt_cifs_flags & CIFS_MOUNT_CIFS_ACL) ||
(cifs_sb->mnt_cifs_flags & CIFS_MOUNT_MODE_FROM_SID)) {
if (uid_valid(uid) || gid_valid(gid)) {
- rc = id_mode_to_cifs_acl(inode, full_path, NO_CHANGE_64,
+ mode = NO_CHANGE_64;
+ rc = id_mode_to_cifs_acl(inode, full_path, &mode,
uid, gid);
if (rc) {
cifs_dbg(FYI, "%s: Setting id failed with error: %d\n",
rc = 0;
if ((cifs_sb->mnt_cifs_flags & CIFS_MOUNT_CIFS_ACL) ||
(cifs_sb->mnt_cifs_flags & CIFS_MOUNT_MODE_FROM_SID)) {
- rc = id_mode_to_cifs_acl(inode, full_path, mode,
+ rc = id_mode_to_cifs_acl(inode, full_path, &mode,
INVALID_UID, INVALID_GID);
if (rc) {
cifs_dbg(FYI, "%s: Setting ACL failed with error: %d\n",
__func__, rc);
goto cifs_setattr_exit;
}
+
+ /*
+ * In case of CIFS_MOUNT_CIFS_ACL, we cannot support all modes.
+ * Pick up the actual mode bits that were set.
+ */
+ if (mode != attrs->ia_mode)
+ attrs->ia_mode = mode;
} else
if (((mode & S_IWUGO) == 0) &&
(cifsInode->cifsAttrs & ATTR_READONLY) == 0) {
attrs->ia_mode &= ~(S_IALLUGO);
if (S_ISDIR(inode->i_mode))
attrs->ia_mode |=
- cifs_sb->mnt_dir_mode;
+ cifs_sb->ctx->dir_mode;
else
attrs->ia_mode |=
- cifs_sb->mnt_file_mode;
+ cifs_sb->ctx->file_mode;
}
} else if (!(cifs_sb->mnt_cifs_flags & CIFS_MOUNT_DYNPERM)) {
/* ignore mode change - ATTR_READONLY hasn't changed */
attrs->ia_size != i_size_read(inode))
truncate_setsize(inode, attrs->ia_size);
- setattr_copy(inode, attrs);
+ setattr_copy(&init_user_ns, inode, attrs);
mark_inode_dirty(inode);
cifs_setattr_exit:
}
int
-cifs_setattr(struct dentry *direntry, struct iattr *attrs)
+cifs_setattr(struct user_namespace *mnt_userns, struct dentry *direntry,
+ struct iattr *attrs)
{
struct cifs_sb_info *cifs_sb = CIFS_SB(direntry->d_sb);
struct cifs_tcon *pTcon = cifs_sb_master_tcon(cifs_sb);