Loading fs/cifs/cifsglob.h +7 −0 Original line number Diff line number Diff line Loading @@ -246,6 +246,13 @@ struct smb_version_operations { bool (*can_echo)(struct TCP_Server_Info *); /* send echo request */ int (*echo)(struct TCP_Server_Info *); /* create directory */ int (*mkdir)(const unsigned int, struct cifs_tcon *, const char *, struct cifs_sb_info *); /* set info on created directory */ void (*mkdir_setinfo)(struct inode *, const char *, struct cifs_sb_info *, struct cifs_tcon *, const unsigned int); }; struct smb_version_values { Loading fs/cifs/cifsproto.h +1 −3 Original line number Diff line number Diff line Loading @@ -295,9 +295,7 @@ extern int CIFSSMBUnixSetPathInfo(const unsigned int xid, int remap); extern int CIFSSMBMkDir(const unsigned int xid, struct cifs_tcon *tcon, const char *newName, const struct nls_table *nls_codepage, int remap_special_chars); const char *name, struct cifs_sb_info *cifs_sb); extern int CIFSSMBRmDir(const unsigned int xid, struct cifs_tcon *tcon, const char *name, const struct nls_table *nls_codepage, int remap_special_chars); Loading fs/cifs/cifssmb.c +5 −3 Original line number Diff line number Diff line Loading @@ -992,14 +992,15 @@ CIFSSMBRmDir(const unsigned int xid, struct cifs_tcon *tcon, } int CIFSSMBMkDir(const unsigned int xid, struct cifs_tcon *tcon, const char *name, const struct nls_table *nls_codepage, int remap) CIFSSMBMkDir(const unsigned int xid, struct cifs_tcon *tcon, const char *name, struct cifs_sb_info *cifs_sb) { int rc = 0; CREATE_DIRECTORY_REQ *pSMB = NULL; CREATE_DIRECTORY_RSP *pSMBr = NULL; int bytes_returned; int name_len; int remap = cifs_sb->mnt_cifs_flags & CIFS_MOUNT_MAP_SPECIAL_CHR; cFYI(1, "In CIFSSMBMkDir"); MkDirRetry: Loading @@ -1010,7 +1011,8 @@ CIFSSMBMkDir(const unsigned int xid, struct cifs_tcon *tcon, if (pSMB->hdr.Flags2 & SMBFLG2_UNICODE) { name_len = cifsConvertToUTF16((__le16 *) pSMB->DirName, name, PATH_MAX, nls_codepage, remap); PATH_MAX, cifs_sb->local_nls, remap); name_len++; /* trailing null */ name_len *= 2; } else { /* BB improve check for buffer overruns BB */ Loading fs/cifs/inode.c +13 −19 Original line number Diff line number Diff line Loading @@ -1272,24 +1272,11 @@ cifs_mkdir_qinfo(struct inode *inode, struct dentry *dentry, umode_t mode, cifs_sb->mnt_cifs_flags & CIFS_MOUNT_MAP_SPECIAL_CHR); } else { struct TCP_Server_Info *server = tcon->ses->server; if (!(cifs_sb->mnt_cifs_flags & CIFS_MOUNT_CIFS_ACL) && (mode & S_IWUGO) == 0) { FILE_BASIC_INFO info; struct cifsInodeInfo *cifsInode; u32 dosattrs; int tmprc; memset(&info, 0, sizeof(info)); cifsInode = CIFS_I(newinode); dosattrs = cifsInode->cifsAttrs|ATTR_READONLY; info.Attributes = cpu_to_le32(dosattrs); tmprc = CIFSSMBSetPathInfo(xid, tcon, full_path, &info, cifs_sb->local_nls, cifs_sb->mnt_cifs_flags & CIFS_MOUNT_MAP_SPECIAL_CHR); if (tmprc == 0) cifsInode->cifsAttrs = dosattrs; } (mode & S_IWUGO) == 0 && server->ops->mkdir_setinfo) server->ops->mkdir_setinfo(newinode, full_path, cifs_sb, tcon, xid); if (dentry->d_inode) { if (cifs_sb->mnt_cifs_flags & CIFS_MOUNT_DYNPERM) dentry->d_inode->i_mode = (mode | S_IFDIR); Loading Loading @@ -1377,6 +1364,7 @@ int cifs_mkdir(struct inode *inode, struct dentry *direntry, umode_t mode) struct cifs_sb_info *cifs_sb; struct tcon_link *tlink; struct cifs_tcon *tcon; struct TCP_Server_Info *server; char *full_path; cFYI(1, "In cifs_mkdir, mode = 0x%hx inode = 0x%p", mode, inode); Loading @@ -1403,9 +1391,15 @@ int cifs_mkdir(struct inode *inode, struct dentry *direntry, umode_t mode) goto mkdir_out; } server = tcon->ses->server; if (!server->ops->mkdir) { rc = -ENOSYS; goto mkdir_out; } /* BB add setting the equivalent of mode via CreateX w/ACLs */ rc = CIFSSMBMkDir(xid, tcon, full_path, cifs_sb->local_nls, cifs_sb->mnt_cifs_flags & CIFS_MOUNT_MAP_SPECIAL_CHR); rc = server->ops->mkdir(xid, tcon, full_path, cifs_sb); if (rc) { cFYI(1, "cifs_mkdir returned 0x%x", rc); d_drop(direntry); Loading fs/cifs/smb1ops.c +23 −0 Original line number Diff line number Diff line Loading @@ -586,6 +586,27 @@ cifs_print_stats(struct seq_file *m, struct cifs_tcon *tcon) #endif } static void cifs_mkdir_setinfo(struct inode *inode, const char *full_path, struct cifs_sb_info *cifs_sb, struct cifs_tcon *tcon, const unsigned int xid) { FILE_BASIC_INFO info; struct cifsInodeInfo *cifsInode; u32 dosattrs; int rc; memset(&info, 0, sizeof(info)); cifsInode = CIFS_I(inode); dosattrs = cifsInode->cifsAttrs|ATTR_READONLY; info.Attributes = cpu_to_le32(dosattrs); rc = CIFSSMBSetPathInfo(xid, tcon, full_path, &info, cifs_sb->local_nls, cifs_sb->mnt_cifs_flags & CIFS_MOUNT_MAP_SPECIAL_CHR); if (rc == 0) cifsInode->cifsAttrs = dosattrs; } struct smb_version_operations smb1_operations = { .send_cancel = send_nt_cancel, .compare_fids = cifs_compare_fids, Loading Loading @@ -620,6 +641,8 @@ struct smb_version_operations smb1_operations = { .get_srv_inum = cifs_get_srv_inum, .build_path_to_root = cifs_build_path_to_root, .echo = CIFSSMBEcho, .mkdir = CIFSSMBMkDir, .mkdir_setinfo = cifs_mkdir_setinfo, }; struct smb_version_values smb1_values = { Loading Loading
fs/cifs/cifsglob.h +7 −0 Original line number Diff line number Diff line Loading @@ -246,6 +246,13 @@ struct smb_version_operations { bool (*can_echo)(struct TCP_Server_Info *); /* send echo request */ int (*echo)(struct TCP_Server_Info *); /* create directory */ int (*mkdir)(const unsigned int, struct cifs_tcon *, const char *, struct cifs_sb_info *); /* set info on created directory */ void (*mkdir_setinfo)(struct inode *, const char *, struct cifs_sb_info *, struct cifs_tcon *, const unsigned int); }; struct smb_version_values { Loading
fs/cifs/cifsproto.h +1 −3 Original line number Diff line number Diff line Loading @@ -295,9 +295,7 @@ extern int CIFSSMBUnixSetPathInfo(const unsigned int xid, int remap); extern int CIFSSMBMkDir(const unsigned int xid, struct cifs_tcon *tcon, const char *newName, const struct nls_table *nls_codepage, int remap_special_chars); const char *name, struct cifs_sb_info *cifs_sb); extern int CIFSSMBRmDir(const unsigned int xid, struct cifs_tcon *tcon, const char *name, const struct nls_table *nls_codepage, int remap_special_chars); Loading
fs/cifs/cifssmb.c +5 −3 Original line number Diff line number Diff line Loading @@ -992,14 +992,15 @@ CIFSSMBRmDir(const unsigned int xid, struct cifs_tcon *tcon, } int CIFSSMBMkDir(const unsigned int xid, struct cifs_tcon *tcon, const char *name, const struct nls_table *nls_codepage, int remap) CIFSSMBMkDir(const unsigned int xid, struct cifs_tcon *tcon, const char *name, struct cifs_sb_info *cifs_sb) { int rc = 0; CREATE_DIRECTORY_REQ *pSMB = NULL; CREATE_DIRECTORY_RSP *pSMBr = NULL; int bytes_returned; int name_len; int remap = cifs_sb->mnt_cifs_flags & CIFS_MOUNT_MAP_SPECIAL_CHR; cFYI(1, "In CIFSSMBMkDir"); MkDirRetry: Loading @@ -1010,7 +1011,8 @@ CIFSSMBMkDir(const unsigned int xid, struct cifs_tcon *tcon, if (pSMB->hdr.Flags2 & SMBFLG2_UNICODE) { name_len = cifsConvertToUTF16((__le16 *) pSMB->DirName, name, PATH_MAX, nls_codepage, remap); PATH_MAX, cifs_sb->local_nls, remap); name_len++; /* trailing null */ name_len *= 2; } else { /* BB improve check for buffer overruns BB */ Loading
fs/cifs/inode.c +13 −19 Original line number Diff line number Diff line Loading @@ -1272,24 +1272,11 @@ cifs_mkdir_qinfo(struct inode *inode, struct dentry *dentry, umode_t mode, cifs_sb->mnt_cifs_flags & CIFS_MOUNT_MAP_SPECIAL_CHR); } else { struct TCP_Server_Info *server = tcon->ses->server; if (!(cifs_sb->mnt_cifs_flags & CIFS_MOUNT_CIFS_ACL) && (mode & S_IWUGO) == 0) { FILE_BASIC_INFO info; struct cifsInodeInfo *cifsInode; u32 dosattrs; int tmprc; memset(&info, 0, sizeof(info)); cifsInode = CIFS_I(newinode); dosattrs = cifsInode->cifsAttrs|ATTR_READONLY; info.Attributes = cpu_to_le32(dosattrs); tmprc = CIFSSMBSetPathInfo(xid, tcon, full_path, &info, cifs_sb->local_nls, cifs_sb->mnt_cifs_flags & CIFS_MOUNT_MAP_SPECIAL_CHR); if (tmprc == 0) cifsInode->cifsAttrs = dosattrs; } (mode & S_IWUGO) == 0 && server->ops->mkdir_setinfo) server->ops->mkdir_setinfo(newinode, full_path, cifs_sb, tcon, xid); if (dentry->d_inode) { if (cifs_sb->mnt_cifs_flags & CIFS_MOUNT_DYNPERM) dentry->d_inode->i_mode = (mode | S_IFDIR); Loading Loading @@ -1377,6 +1364,7 @@ int cifs_mkdir(struct inode *inode, struct dentry *direntry, umode_t mode) struct cifs_sb_info *cifs_sb; struct tcon_link *tlink; struct cifs_tcon *tcon; struct TCP_Server_Info *server; char *full_path; cFYI(1, "In cifs_mkdir, mode = 0x%hx inode = 0x%p", mode, inode); Loading @@ -1403,9 +1391,15 @@ int cifs_mkdir(struct inode *inode, struct dentry *direntry, umode_t mode) goto mkdir_out; } server = tcon->ses->server; if (!server->ops->mkdir) { rc = -ENOSYS; goto mkdir_out; } /* BB add setting the equivalent of mode via CreateX w/ACLs */ rc = CIFSSMBMkDir(xid, tcon, full_path, cifs_sb->local_nls, cifs_sb->mnt_cifs_flags & CIFS_MOUNT_MAP_SPECIAL_CHR); rc = server->ops->mkdir(xid, tcon, full_path, cifs_sb); if (rc) { cFYI(1, "cifs_mkdir returned 0x%x", rc); d_drop(direntry); Loading
fs/cifs/smb1ops.c +23 −0 Original line number Diff line number Diff line Loading @@ -586,6 +586,27 @@ cifs_print_stats(struct seq_file *m, struct cifs_tcon *tcon) #endif } static void cifs_mkdir_setinfo(struct inode *inode, const char *full_path, struct cifs_sb_info *cifs_sb, struct cifs_tcon *tcon, const unsigned int xid) { FILE_BASIC_INFO info; struct cifsInodeInfo *cifsInode; u32 dosattrs; int rc; memset(&info, 0, sizeof(info)); cifsInode = CIFS_I(inode); dosattrs = cifsInode->cifsAttrs|ATTR_READONLY; info.Attributes = cpu_to_le32(dosattrs); rc = CIFSSMBSetPathInfo(xid, tcon, full_path, &info, cifs_sb->local_nls, cifs_sb->mnt_cifs_flags & CIFS_MOUNT_MAP_SPECIAL_CHR); if (rc == 0) cifsInode->cifsAttrs = dosattrs; } struct smb_version_operations smb1_operations = { .send_cancel = send_nt_cancel, .compare_fids = cifs_compare_fids, Loading Loading @@ -620,6 +641,8 @@ struct smb_version_operations smb1_operations = { .get_srv_inum = cifs_get_srv_inum, .build_path_to_root = cifs_build_path_to_root, .echo = CIFSSMBEcho, .mkdir = CIFSSMBMkDir, .mkdir_setinfo = cifs_mkdir_setinfo, }; struct smb_version_values smb1_values = { Loading