diff options
author | Pavel Shilovsky <pshilovsky@samba.org> | 2012-09-18 19:20:25 -0400 |
---|---|---|
committer | Steve French <smfrench@gmail.com> | 2012-09-24 22:46:26 -0400 |
commit | ed6875e0d6c28e4a6b44da04d6d4363b3d92d630 (patch) | |
tree | 9a5aa48100f62ed65319950689e911cb702abbaa | |
parent | 56d27adcb536b7430d5f8a6240df8ad261eb00bd (diff) |
CIFS: Move unlink code to ops struct
Reviewed-by: Jeff Layton <jlayton@redhat.com>
Signed-off-by: Pavel Shilovsky <pshilovsky@samba.org>
Signed-off-by: Steve French <smfrench@gmail.com>
-rw-r--r-- | fs/cifs/cifsglob.h | 6 | ||||
-rw-r--r-- | fs/cifs/cifsproto.h | 9 | ||||
-rw-r--r-- | fs/cifs/cifssmb.c | 16 | ||||
-rw-r--r-- | fs/cifs/inode.c | 33 | ||||
-rw-r--r-- | fs/cifs/smb1ops.c | 2 |
5 files changed, 44 insertions, 22 deletions
diff --git a/fs/cifs/cifsglob.h b/fs/cifs/cifsglob.h index 977dc0e85ccb..843356fa262d 100644 --- a/fs/cifs/cifsglob.h +++ b/fs/cifs/cifsglob.h | |||
@@ -256,6 +256,12 @@ struct smb_version_operations { | |||
256 | /* remove directory */ | 256 | /* remove directory */ |
257 | int (*rmdir)(const unsigned int, struct cifs_tcon *, const char *, | 257 | int (*rmdir)(const unsigned int, struct cifs_tcon *, const char *, |
258 | struct cifs_sb_info *); | 258 | struct cifs_sb_info *); |
259 | /* unlink file */ | ||
260 | int (*unlink)(const unsigned int, struct cifs_tcon *, const char *, | ||
261 | struct cifs_sb_info *); | ||
262 | /* open, rename and delete file */ | ||
263 | int (*rename_pending_delete)(const char *, struct dentry *, | ||
264 | const unsigned int); | ||
259 | }; | 265 | }; |
260 | 266 | ||
261 | struct smb_version_values { | 267 | struct smb_version_values { |
diff --git a/fs/cifs/cifsproto.h b/fs/cifs/cifsproto.h index f1bbf8305d3a..79c088469757 100644 --- a/fs/cifs/cifsproto.h +++ b/fs/cifs/cifsproto.h | |||
@@ -144,6 +144,11 @@ extern int cifs_get_file_info_unix(struct file *filp); | |||
144 | extern int cifs_get_inode_info_unix(struct inode **pinode, | 144 | extern int cifs_get_inode_info_unix(struct inode **pinode, |
145 | const unsigned char *search_path, | 145 | const unsigned char *search_path, |
146 | struct super_block *sb, unsigned int xid); | 146 | struct super_block *sb, unsigned int xid); |
147 | extern int cifs_set_file_info(struct inode *inode, struct iattr *attrs, | ||
148 | unsigned int xid, char *full_path, __u32 dosattr); | ||
149 | extern int cifs_rename_pending_delete(const char *full_path, | ||
150 | struct dentry *dentry, | ||
151 | const unsigned int xid); | ||
147 | extern int cifs_acl_to_fattr(struct cifs_sb_info *cifs_sb, | 152 | extern int cifs_acl_to_fattr(struct cifs_sb_info *cifs_sb, |
148 | struct cifs_fattr *fattr, struct inode *inode, | 153 | struct cifs_fattr *fattr, struct inode *inode, |
149 | const char *path, const __u16 *pfid); | 154 | const char *path, const __u16 *pfid); |
@@ -303,9 +308,7 @@ extern int CIFSPOSIXDelFile(const unsigned int xid, struct cifs_tcon *tcon, | |||
303 | const struct nls_table *nls_codepage, | 308 | const struct nls_table *nls_codepage, |
304 | int remap_special_chars); | 309 | int remap_special_chars); |
305 | extern int CIFSSMBDelFile(const unsigned int xid, struct cifs_tcon *tcon, | 310 | extern int CIFSSMBDelFile(const unsigned int xid, struct cifs_tcon *tcon, |
306 | const char *name, | 311 | const char *name, struct cifs_sb_info *cifs_sb); |
307 | const struct nls_table *nls_codepage, | ||
308 | int remap_special_chars); | ||
309 | extern int CIFSSMBRename(const unsigned int xid, struct cifs_tcon *tcon, | 312 | extern int CIFSSMBRename(const unsigned int xid, struct cifs_tcon *tcon, |
310 | const char *fromName, const char *toName, | 313 | const char *fromName, const char *toName, |
311 | const struct nls_table *nls_codepage, | 314 | const struct nls_table *nls_codepage, |
diff --git a/fs/cifs/cifssmb.c b/fs/cifs/cifssmb.c index f0cf934ba877..2dddf01d2b66 100644 --- a/fs/cifs/cifssmb.c +++ b/fs/cifs/cifssmb.c | |||
@@ -902,15 +902,15 @@ PsxDelete: | |||
902 | } | 902 | } |
903 | 903 | ||
904 | int | 904 | int |
905 | CIFSSMBDelFile(const unsigned int xid, struct cifs_tcon *tcon, | 905 | CIFSSMBDelFile(const unsigned int xid, struct cifs_tcon *tcon, const char *name, |
906 | const char *fileName, const struct nls_table *nls_codepage, | 906 | struct cifs_sb_info *cifs_sb) |
907 | int remap) | ||
908 | { | 907 | { |
909 | DELETE_FILE_REQ *pSMB = NULL; | 908 | DELETE_FILE_REQ *pSMB = NULL; |
910 | DELETE_FILE_RSP *pSMBr = NULL; | 909 | DELETE_FILE_RSP *pSMBr = NULL; |
911 | int rc = 0; | 910 | int rc = 0; |
912 | int bytes_returned; | 911 | int bytes_returned; |
913 | int name_len; | 912 | int name_len; |
913 | int remap = cifs_sb->mnt_cifs_flags & CIFS_MOUNT_MAP_SPECIAL_CHR; | ||
914 | 914 | ||
915 | DelFileRetry: | 915 | DelFileRetry: |
916 | rc = smb_init(SMB_COM_DELETE, 1, tcon, (void **) &pSMB, | 916 | rc = smb_init(SMB_COM_DELETE, 1, tcon, (void **) &pSMB, |
@@ -919,15 +919,15 @@ DelFileRetry: | |||
919 | return rc; | 919 | return rc; |
920 | 920 | ||
921 | if (pSMB->hdr.Flags2 & SMBFLG2_UNICODE) { | 921 | if (pSMB->hdr.Flags2 & SMBFLG2_UNICODE) { |
922 | name_len = | 922 | name_len = cifsConvertToUTF16((__le16 *) pSMB->fileName, name, |
923 | cifsConvertToUTF16((__le16 *) pSMB->fileName, fileName, | 923 | PATH_MAX, cifs_sb->local_nls, |
924 | PATH_MAX, nls_codepage, remap); | 924 | remap); |
925 | name_len++; /* trailing null */ | 925 | name_len++; /* trailing null */ |
926 | name_len *= 2; | 926 | name_len *= 2; |
927 | } else { /* BB improve check for buffer overruns BB */ | 927 | } else { /* BB improve check for buffer overruns BB */ |
928 | name_len = strnlen(fileName, PATH_MAX); | 928 | name_len = strnlen(name, PATH_MAX); |
929 | name_len++; /* trailing null */ | 929 | name_len++; /* trailing null */ |
930 | strncpy(pSMB->fileName, fileName, name_len); | 930 | strncpy(pSMB->fileName, name, name_len); |
931 | } | 931 | } |
932 | pSMB->SearchAttributes = | 932 | pSMB->SearchAttributes = |
933 | cpu_to_le16(ATTR_READONLY | ATTR_HIDDEN | ATTR_SYSTEM); | 933 | cpu_to_le16(ATTR_READONLY | ATTR_HIDDEN | ATTR_SYSTEM); |
diff --git a/fs/cifs/inode.c b/fs/cifs/inode.c index cb79c7edecb0..bb39ea475a20 100644 --- a/fs/cifs/inode.c +++ b/fs/cifs/inode.c | |||
@@ -876,9 +876,9 @@ out: | |||
876 | return inode; | 876 | return inode; |
877 | } | 877 | } |
878 | 878 | ||
879 | static int | 879 | int |
880 | cifs_set_file_info(struct inode *inode, struct iattr *attrs, unsigned int xid, | 880 | cifs_set_file_info(struct inode *inode, struct iattr *attrs, unsigned int xid, |
881 | char *full_path, __u32 dosattr) | 881 | char *full_path, __u32 dosattr) |
882 | { | 882 | { |
883 | int rc; | 883 | int rc; |
884 | int oplock = 0; | 884 | int oplock = 0; |
@@ -993,13 +993,13 @@ out: | |||
993 | } | 993 | } |
994 | 994 | ||
995 | /* | 995 | /* |
996 | * open the given file (if it isn't already), set the DELETE_ON_CLOSE bit | 996 | * Open the given file (if it isn't already), set the DELETE_ON_CLOSE bit |
997 | * and rename it to a random name that hopefully won't conflict with | 997 | * and rename it to a random name that hopefully won't conflict with |
998 | * anything else. | 998 | * anything else. |
999 | */ | 999 | */ |
1000 | static int | 1000 | int |
1001 | cifs_rename_pending_delete(char *full_path, struct dentry *dentry, | 1001 | cifs_rename_pending_delete(const char *full_path, struct dentry *dentry, |
1002 | unsigned int xid) | 1002 | const unsigned int xid) |
1003 | { | 1003 | { |
1004 | int oplock = 0; | 1004 | int oplock = 0; |
1005 | int rc; | 1005 | int rc; |
@@ -1136,6 +1136,7 @@ int cifs_unlink(struct inode *dir, struct dentry *dentry) | |||
1136 | struct cifs_sb_info *cifs_sb = CIFS_SB(sb); | 1136 | struct cifs_sb_info *cifs_sb = CIFS_SB(sb); |
1137 | struct tcon_link *tlink; | 1137 | struct tcon_link *tlink; |
1138 | struct cifs_tcon *tcon; | 1138 | struct cifs_tcon *tcon; |
1139 | struct TCP_Server_Info *server; | ||
1139 | struct iattr *attrs = NULL; | 1140 | struct iattr *attrs = NULL; |
1140 | __u32 dosattr = 0, origattr = 0; | 1141 | __u32 dosattr = 0, origattr = 0; |
1141 | 1142 | ||
@@ -1145,6 +1146,7 @@ int cifs_unlink(struct inode *dir, struct dentry *dentry) | |||
1145 | if (IS_ERR(tlink)) | 1146 | if (IS_ERR(tlink)) |
1146 | return PTR_ERR(tlink); | 1147 | return PTR_ERR(tlink); |
1147 | tcon = tlink_tcon(tlink); | 1148 | tcon = tlink_tcon(tlink); |
1149 | server = tcon->ses->server; | ||
1148 | 1150 | ||
1149 | xid = get_xid(); | 1151 | xid = get_xid(); |
1150 | 1152 | ||
@@ -1167,8 +1169,12 @@ int cifs_unlink(struct inode *dir, struct dentry *dentry) | |||
1167 | } | 1169 | } |
1168 | 1170 | ||
1169 | retry_std_delete: | 1171 | retry_std_delete: |
1170 | rc = CIFSSMBDelFile(xid, tcon, full_path, cifs_sb->local_nls, | 1172 | if (!server->ops->unlink) { |
1171 | cifs_sb->mnt_cifs_flags & CIFS_MOUNT_MAP_SPECIAL_CHR); | 1173 | rc = -ENOSYS; |
1174 | goto psx_del_no_retry; | ||
1175 | } | ||
1176 | |||
1177 | rc = server->ops->unlink(xid, tcon, full_path, cifs_sb); | ||
1172 | 1178 | ||
1173 | psx_del_no_retry: | 1179 | psx_del_no_retry: |
1174 | if (!rc) { | 1180 | if (!rc) { |
@@ -1177,9 +1183,14 @@ psx_del_no_retry: | |||
1177 | } else if (rc == -ENOENT) { | 1183 | } else if (rc == -ENOENT) { |
1178 | d_drop(dentry); | 1184 | d_drop(dentry); |
1179 | } else if (rc == -ETXTBSY) { | 1185 | } else if (rc == -ETXTBSY) { |
1180 | rc = cifs_rename_pending_delete(full_path, dentry, xid); | 1186 | if (server->ops->rename_pending_delete) { |
1181 | if (rc == 0) | 1187 | rc = server->ops->rename_pending_delete(full_path, |
1182 | cifs_drop_nlink(inode); | 1188 | dentry, xid); |
1189 | if (rc == 0) | ||
1190 | cifs_drop_nlink(inode); | ||
1191 | } | ||
1192 | if (rc == -ETXTBSY) | ||
1193 | rc = -EBUSY; | ||
1183 | } else if ((rc == -EACCES) && (dosattr == 0) && inode) { | 1194 | } else if ((rc == -EACCES) && (dosattr == 0) && inode) { |
1184 | attrs = kzalloc(sizeof(*attrs), GFP_KERNEL); | 1195 | attrs = kzalloc(sizeof(*attrs), GFP_KERNEL); |
1185 | if (attrs == NULL) { | 1196 | if (attrs == NULL) { |
diff --git a/fs/cifs/smb1ops.c b/fs/cifs/smb1ops.c index 3129ac74b819..725fa6195867 100644 --- a/fs/cifs/smb1ops.c +++ b/fs/cifs/smb1ops.c | |||
@@ -644,6 +644,8 @@ struct smb_version_operations smb1_operations = { | |||
644 | .mkdir = CIFSSMBMkDir, | 644 | .mkdir = CIFSSMBMkDir, |
645 | .mkdir_setinfo = cifs_mkdir_setinfo, | 645 | .mkdir_setinfo = cifs_mkdir_setinfo, |
646 | .rmdir = CIFSSMBRmDir, | 646 | .rmdir = CIFSSMBRmDir, |
647 | .unlink = CIFSSMBDelFile, | ||
648 | .rename_pending_delete = cifs_rename_pending_delete, | ||
647 | }; | 649 | }; |
648 | 650 | ||
649 | struct smb_version_values smb1_values = { | 651 | struct smb_version_values smb1_values = { |