aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorPavel Shilovsky <pshilovsky@samba.org>2012-09-18 19:20:25 -0400
committerSteve French <smfrench@gmail.com>2012-09-24 22:46:26 -0400
commited6875e0d6c28e4a6b44da04d6d4363b3d92d630 (patch)
tree9a5aa48100f62ed65319950689e911cb702abbaa
parent56d27adcb536b7430d5f8a6240df8ad261eb00bd (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.h6
-rw-r--r--fs/cifs/cifsproto.h9
-rw-r--r--fs/cifs/cifssmb.c16
-rw-r--r--fs/cifs/inode.c33
-rw-r--r--fs/cifs/smb1ops.c2
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
261struct smb_version_values { 267struct 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);
144extern int cifs_get_inode_info_unix(struct inode **pinode, 144extern 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);
147extern int cifs_set_file_info(struct inode *inode, struct iattr *attrs,
148 unsigned int xid, char *full_path, __u32 dosattr);
149extern int cifs_rename_pending_delete(const char *full_path,
150 struct dentry *dentry,
151 const unsigned int xid);
147extern int cifs_acl_to_fattr(struct cifs_sb_info *cifs_sb, 152extern 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);
305extern int CIFSSMBDelFile(const unsigned int xid, struct cifs_tcon *tcon, 310extern 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);
309extern int CIFSSMBRename(const unsigned int xid, struct cifs_tcon *tcon, 312extern 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
904int 904int
905CIFSSMBDelFile(const unsigned int xid, struct cifs_tcon *tcon, 905CIFSSMBDelFile(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
915DelFileRetry: 915DelFileRetry:
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
879static int 879int
880cifs_set_file_info(struct inode *inode, struct iattr *attrs, unsigned int xid, 880cifs_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 */
1000static int 1000int
1001cifs_rename_pending_delete(char *full_path, struct dentry *dentry, 1001cifs_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
1169retry_std_delete: 1171retry_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
1173psx_del_no_retry: 1179psx_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
649struct smb_version_values smb1_values = { 651struct smb_version_values smb1_values = {