]> rtime.felk.cvut.cz Git - can-eth-gw-linux.git/commitdiff
CIFS: Separate protocol specific part from mkdir
authorPavel Shilovsky <piastry@etersoft.ru>
Sat, 17 Mar 2012 08:41:12 +0000 (11:41 +0300)
committerSteve French <smfrench@gmail.com>
Fri, 27 Jul 2012 20:17:40 +0000 (15:17 -0500)
Signed-off-by: Pavel Shilovsky <piastry@etersoft.ru>
Signed-off-by: Steve French <smfrench@gmail.com>
fs/cifs/cifsglob.h
fs/cifs/cifsproto.h
fs/cifs/cifssmb.c
fs/cifs/inode.c
fs/cifs/smb1ops.c

index 497da5ce704c1022b136742cdf603d31fd92b1df..939f91aac1626e25bd002e027f4df92d74c28be9 100644 (file)
@@ -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 {
index cc39cc331bb36abc7f454ac6020222e49bc82ab7..5e128fb2b618fdda318b0703754a48380d82a179 100644 (file)
@@ -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);
index 01808eb3af47854d2b6cb95af2ac1af36628ffb5..eb74cceef480831cabd5249943c7f3487a633663 100644 (file)
@@ -992,14 +992,15 @@ RmDirRetry:
 }
 
 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:
@@ -1010,7 +1011,8 @@ MkDirRetry:
 
        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 */
index e9ba1a150fe3ed29890c9d89ecf20fc100ed3d4b..d7e74b1268cb66cf78f71300cacd8660baa1b6ba 100644 (file)
@@ -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);
@@ -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);
@@ -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);
index c40356d24c5ce8dd235bd3e8e7e632d06ac29613..861e2df0c37dba9ddadf62765d8b344272cbaf30 100644 (file)
@@ -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,
@@ -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 = {