diff options
author | Pavel Shilovsky <piastry@etersoft.ru> | 2012-03-17 04:41:12 -0400 |
---|---|---|
committer | Steve French <smfrench@gmail.com> | 2012-07-27 16:17:40 -0400 |
commit | f436720e94ac53413e20c48b02d16e2ef180e166 (patch) | |
tree | fa831b67f689a847fcdb0942ad624c6d060594de | |
parent | ff691e969433a54e26fb6502a6613e02c680e8ee (diff) |
CIFS: Separate protocol specific part from mkdir
Signed-off-by: Pavel Shilovsky <piastry@etersoft.ru>
Signed-off-by: Steve French <smfrench@gmail.com>
-rw-r--r-- | fs/cifs/cifsglob.h | 7 | ||||
-rw-r--r-- | fs/cifs/cifsproto.h | 4 | ||||
-rw-r--r-- | fs/cifs/cifssmb.c | 8 | ||||
-rw-r--r-- | fs/cifs/inode.c | 32 | ||||
-rw-r--r-- | fs/cifs/smb1ops.c | 23 |
5 files changed, 49 insertions, 25 deletions
diff --git a/fs/cifs/cifsglob.h b/fs/cifs/cifsglob.h index 497da5ce704c..939f91aac162 100644 --- a/fs/cifs/cifsglob.h +++ b/fs/cifs/cifsglob.h | |||
@@ -246,6 +246,13 @@ struct smb_version_operations { | |||
246 | bool (*can_echo)(struct TCP_Server_Info *); | 246 | bool (*can_echo)(struct TCP_Server_Info *); |
247 | /* send echo request */ | 247 | /* send echo request */ |
248 | int (*echo)(struct TCP_Server_Info *); | 248 | int (*echo)(struct TCP_Server_Info *); |
249 | /* create directory */ | ||
250 | int (*mkdir)(const unsigned int, struct cifs_tcon *, const char *, | ||
251 | struct cifs_sb_info *); | ||
252 | /* set info on created directory */ | ||
253 | void (*mkdir_setinfo)(struct inode *, const char *, | ||
254 | struct cifs_sb_info *, struct cifs_tcon *, | ||
255 | const unsigned int); | ||
249 | }; | 256 | }; |
250 | 257 | ||
251 | struct smb_version_values { | 258 | struct smb_version_values { |
diff --git a/fs/cifs/cifsproto.h b/fs/cifs/cifsproto.h index cc39cc331bb3..5e128fb2b618 100644 --- a/fs/cifs/cifsproto.h +++ b/fs/cifs/cifsproto.h | |||
@@ -295,9 +295,7 @@ extern int CIFSSMBUnixSetPathInfo(const unsigned int xid, | |||
295 | int remap); | 295 | int remap); |
296 | 296 | ||
297 | extern int CIFSSMBMkDir(const unsigned int xid, struct cifs_tcon *tcon, | 297 | extern int CIFSSMBMkDir(const unsigned int xid, struct cifs_tcon *tcon, |
298 | const char *newName, | 298 | const char *name, struct cifs_sb_info *cifs_sb); |
299 | const struct nls_table *nls_codepage, | ||
300 | int remap_special_chars); | ||
301 | extern int CIFSSMBRmDir(const unsigned int xid, struct cifs_tcon *tcon, | 299 | extern int CIFSSMBRmDir(const unsigned int xid, struct cifs_tcon *tcon, |
302 | const char *name, const struct nls_table *nls_codepage, | 300 | const char *name, const struct nls_table *nls_codepage, |
303 | int remap_special_chars); | 301 | int remap_special_chars); |
diff --git a/fs/cifs/cifssmb.c b/fs/cifs/cifssmb.c index 01808eb3af47..eb74cceef480 100644 --- a/fs/cifs/cifssmb.c +++ b/fs/cifs/cifssmb.c | |||
@@ -992,14 +992,15 @@ RmDirRetry: | |||
992 | } | 992 | } |
993 | 993 | ||
994 | int | 994 | int |
995 | CIFSSMBMkDir(const unsigned int xid, struct cifs_tcon *tcon, | 995 | CIFSSMBMkDir(const unsigned int xid, struct cifs_tcon *tcon, const char *name, |
996 | const char *name, const struct nls_table *nls_codepage, int remap) | 996 | struct cifs_sb_info *cifs_sb) |
997 | { | 997 | { |
998 | int rc = 0; | 998 | int rc = 0; |
999 | CREATE_DIRECTORY_REQ *pSMB = NULL; | 999 | CREATE_DIRECTORY_REQ *pSMB = NULL; |
1000 | CREATE_DIRECTORY_RSP *pSMBr = NULL; | 1000 | CREATE_DIRECTORY_RSP *pSMBr = NULL; |
1001 | int bytes_returned; | 1001 | int bytes_returned; |
1002 | int name_len; | 1002 | int name_len; |
1003 | int remap = cifs_sb->mnt_cifs_flags & CIFS_MOUNT_MAP_SPECIAL_CHR; | ||
1003 | 1004 | ||
1004 | cFYI(1, "In CIFSSMBMkDir"); | 1005 | cFYI(1, "In CIFSSMBMkDir"); |
1005 | MkDirRetry: | 1006 | MkDirRetry: |
@@ -1010,7 +1011,8 @@ MkDirRetry: | |||
1010 | 1011 | ||
1011 | if (pSMB->hdr.Flags2 & SMBFLG2_UNICODE) { | 1012 | if (pSMB->hdr.Flags2 & SMBFLG2_UNICODE) { |
1012 | name_len = cifsConvertToUTF16((__le16 *) pSMB->DirName, name, | 1013 | name_len = cifsConvertToUTF16((__le16 *) pSMB->DirName, name, |
1013 | PATH_MAX, nls_codepage, remap); | 1014 | PATH_MAX, cifs_sb->local_nls, |
1015 | remap); | ||
1014 | name_len++; /* trailing null */ | 1016 | name_len++; /* trailing null */ |
1015 | name_len *= 2; | 1017 | name_len *= 2; |
1016 | } else { /* BB improve check for buffer overruns BB */ | 1018 | } else { /* BB improve check for buffer overruns BB */ |
diff --git a/fs/cifs/inode.c b/fs/cifs/inode.c index e9ba1a150fe3..d7e74b1268cb 100644 --- a/fs/cifs/inode.c +++ b/fs/cifs/inode.c | |||
@@ -1272,24 +1272,11 @@ cifs_mkdir_qinfo(struct inode *inode, struct dentry *dentry, umode_t mode, | |||
1272 | cifs_sb->mnt_cifs_flags & | 1272 | cifs_sb->mnt_cifs_flags & |
1273 | CIFS_MOUNT_MAP_SPECIAL_CHR); | 1273 | CIFS_MOUNT_MAP_SPECIAL_CHR); |
1274 | } else { | 1274 | } else { |
1275 | struct TCP_Server_Info *server = tcon->ses->server; | ||
1275 | if (!(cifs_sb->mnt_cifs_flags & CIFS_MOUNT_CIFS_ACL) && | 1276 | if (!(cifs_sb->mnt_cifs_flags & CIFS_MOUNT_CIFS_ACL) && |
1276 | (mode & S_IWUGO) == 0) { | 1277 | (mode & S_IWUGO) == 0 && server->ops->mkdir_setinfo) |
1277 | FILE_BASIC_INFO info; | 1278 | server->ops->mkdir_setinfo(newinode, full_path, cifs_sb, |
1278 | struct cifsInodeInfo *cifsInode; | 1279 | tcon, xid); |
1279 | u32 dosattrs; | ||
1280 | int tmprc; | ||
1281 | |||
1282 | memset(&info, 0, sizeof(info)); | ||
1283 | cifsInode = CIFS_I(newinode); | ||
1284 | dosattrs = cifsInode->cifsAttrs|ATTR_READONLY; | ||
1285 | info.Attributes = cpu_to_le32(dosattrs); | ||
1286 | tmprc = CIFSSMBSetPathInfo(xid, tcon, full_path, &info, | ||
1287 | cifs_sb->local_nls, | ||
1288 | cifs_sb->mnt_cifs_flags & | ||
1289 | CIFS_MOUNT_MAP_SPECIAL_CHR); | ||
1290 | if (tmprc == 0) | ||
1291 | cifsInode->cifsAttrs = dosattrs; | ||
1292 | } | ||
1293 | if (dentry->d_inode) { | 1280 | if (dentry->d_inode) { |
1294 | if (cifs_sb->mnt_cifs_flags & CIFS_MOUNT_DYNPERM) | 1281 | if (cifs_sb->mnt_cifs_flags & CIFS_MOUNT_DYNPERM) |
1295 | dentry->d_inode->i_mode = (mode | S_IFDIR); | 1282 | dentry->d_inode->i_mode = (mode | S_IFDIR); |
@@ -1377,6 +1364,7 @@ int cifs_mkdir(struct inode *inode, struct dentry *direntry, umode_t mode) | |||
1377 | struct cifs_sb_info *cifs_sb; | 1364 | struct cifs_sb_info *cifs_sb; |
1378 | struct tcon_link *tlink; | 1365 | struct tcon_link *tlink; |
1379 | struct cifs_tcon *tcon; | 1366 | struct cifs_tcon *tcon; |
1367 | struct TCP_Server_Info *server; | ||
1380 | char *full_path; | 1368 | char *full_path; |
1381 | 1369 | ||
1382 | cFYI(1, "In cifs_mkdir, mode = 0x%hx inode = 0x%p", mode, inode); | 1370 | 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) | |||
1403 | goto mkdir_out; | 1391 | goto mkdir_out; |
1404 | } | 1392 | } |
1405 | 1393 | ||
1394 | server = tcon->ses->server; | ||
1395 | |||
1396 | if (!server->ops->mkdir) { | ||
1397 | rc = -ENOSYS; | ||
1398 | goto mkdir_out; | ||
1399 | } | ||
1400 | |||
1406 | /* BB add setting the equivalent of mode via CreateX w/ACLs */ | 1401 | /* BB add setting the equivalent of mode via CreateX w/ACLs */ |
1407 | rc = CIFSSMBMkDir(xid, tcon, full_path, cifs_sb->local_nls, | 1402 | rc = server->ops->mkdir(xid, tcon, full_path, cifs_sb); |
1408 | cifs_sb->mnt_cifs_flags & CIFS_MOUNT_MAP_SPECIAL_CHR); | ||
1409 | if (rc) { | 1403 | if (rc) { |
1410 | cFYI(1, "cifs_mkdir returned 0x%x", rc); | 1404 | cFYI(1, "cifs_mkdir returned 0x%x", rc); |
1411 | d_drop(direntry); | 1405 | d_drop(direntry); |
diff --git a/fs/cifs/smb1ops.c b/fs/cifs/smb1ops.c index c40356d24c5c..861e2df0c37d 100644 --- a/fs/cifs/smb1ops.c +++ b/fs/cifs/smb1ops.c | |||
@@ -586,6 +586,27 @@ cifs_print_stats(struct seq_file *m, struct cifs_tcon *tcon) | |||
586 | #endif | 586 | #endif |
587 | } | 587 | } |
588 | 588 | ||
589 | static void | ||
590 | cifs_mkdir_setinfo(struct inode *inode, const char *full_path, | ||
591 | struct cifs_sb_info *cifs_sb, struct cifs_tcon *tcon, | ||
592 | const unsigned int xid) | ||
593 | { | ||
594 | FILE_BASIC_INFO info; | ||
595 | struct cifsInodeInfo *cifsInode; | ||
596 | u32 dosattrs; | ||
597 | int rc; | ||
598 | |||
599 | memset(&info, 0, sizeof(info)); | ||
600 | cifsInode = CIFS_I(inode); | ||
601 | dosattrs = cifsInode->cifsAttrs|ATTR_READONLY; | ||
602 | info.Attributes = cpu_to_le32(dosattrs); | ||
603 | rc = CIFSSMBSetPathInfo(xid, tcon, full_path, &info, cifs_sb->local_nls, | ||
604 | cifs_sb->mnt_cifs_flags & | ||
605 | CIFS_MOUNT_MAP_SPECIAL_CHR); | ||
606 | if (rc == 0) | ||
607 | cifsInode->cifsAttrs = dosattrs; | ||
608 | } | ||
609 | |||
589 | struct smb_version_operations smb1_operations = { | 610 | struct smb_version_operations smb1_operations = { |
590 | .send_cancel = send_nt_cancel, | 611 | .send_cancel = send_nt_cancel, |
591 | .compare_fids = cifs_compare_fids, | 612 | .compare_fids = cifs_compare_fids, |
@@ -620,6 +641,8 @@ struct smb_version_operations smb1_operations = { | |||
620 | .get_srv_inum = cifs_get_srv_inum, | 641 | .get_srv_inum = cifs_get_srv_inum, |
621 | .build_path_to_root = cifs_build_path_to_root, | 642 | .build_path_to_root = cifs_build_path_to_root, |
622 | .echo = CIFSSMBEcho, | 643 | .echo = CIFSSMBEcho, |
644 | .mkdir = CIFSSMBMkDir, | ||
645 | .mkdir_setinfo = cifs_mkdir_setinfo, | ||
623 | }; | 646 | }; |
624 | 647 | ||
625 | struct smb_version_values smb1_values = { | 648 | struct smb_version_values smb1_values = { |