diff options
author | Sachin Prabhu <sprabhu@redhat.com> | 2013-11-25 12:09:52 -0500 |
---|---|---|
committer | Steve French <smfrench@gmail.com> | 2014-01-20 01:14:00 -0500 |
commit | cbb0aba6ff3ff5b64f094f81f4d99d2323c0afcc (patch) | |
tree | ea11e115ecfc85225e7abda30ccf75db5996f3cf | |
parent | 8205d1bb31af047c6893a4f9e86ed88cf5d6113d (diff) |
cifs: Add create MFSymlinks to protocol ops struct
Add a new protocol ops function create_mf_symlink and have
create_mf_symlink() use it.
This patchset moves the MFSymlink operations completely to the
ops structure so that we only use the right protocol versions when
querying or creating MFSymlinks.
Signed-off-by: Sachin Prabhu <sprabhu@redhat.com>
Reviewed-by: Jeff Layton <jlayton@redhat.com>
Signed-off-by: Steve French <smfrench@gmail.com>
-rw-r--r-- | fs/cifs/cifsglob.h | 3 | ||||
-rw-r--r-- | fs/cifs/cifsproto.h | 4 | ||||
-rw-r--r-- | fs/cifs/link.c | 88 | ||||
-rw-r--r-- | fs/cifs/smb1ops.c | 1 |
4 files changed, 54 insertions, 42 deletions
diff --git a/fs/cifs/cifsglob.h b/fs/cifs/cifsglob.h index fba4d1341f88..61228b7f6b67 100644 --- a/fs/cifs/cifsglob.h +++ b/fs/cifs/cifsglob.h | |||
@@ -373,6 +373,9 @@ struct smb_version_operations { | |||
373 | int (*query_mf_symlink)(unsigned int, struct cifs_tcon *, | 373 | int (*query_mf_symlink)(unsigned int, struct cifs_tcon *, |
374 | struct cifs_sb_info *, const unsigned char *, | 374 | struct cifs_sb_info *, const unsigned char *, |
375 | char *, unsigned int *); | 375 | char *, unsigned int *); |
376 | int (*create_mf_symlink)(unsigned int, struct cifs_tcon *, | ||
377 | struct cifs_sb_info *, const unsigned char *, | ||
378 | char *, unsigned int *); | ||
376 | /* if we can do cache read operations */ | 379 | /* if we can do cache read operations */ |
377 | bool (*is_read_op)(__u32); | 380 | bool (*is_read_op)(__u32); |
378 | /* set oplock level for the inode */ | 381 | /* set oplock level for the inode */ |
diff --git a/fs/cifs/cifsproto.h b/fs/cifs/cifsproto.h index 78bb6d6ad06a..e88c3b192ef5 100644 --- a/fs/cifs/cifsproto.h +++ b/fs/cifs/cifsproto.h | |||
@@ -500,4 +500,8 @@ int cifs_query_mf_symlink(unsigned int xid, struct cifs_tcon *tcon, | |||
500 | struct cifs_sb_info *cifs_sb, | 500 | struct cifs_sb_info *cifs_sb, |
501 | const unsigned char *path, char *pbuf, | 501 | const unsigned char *path, char *pbuf, |
502 | unsigned int *pbytes_read); | 502 | unsigned int *pbytes_read); |
503 | int cifs_create_mf_symlink(unsigned int xid, struct cifs_tcon *tcon, | ||
504 | struct cifs_sb_info *cifs_sb, | ||
505 | const unsigned char *path, char *pbuf, | ||
506 | unsigned int *pbytes_written); | ||
503 | #endif /* _CIFSPROTO_H */ | 507 | #endif /* _CIFSPROTO_H */ |
diff --git a/fs/cifs/link.c b/fs/cifs/link.c index 77dbd55795d8..3f259aad361d 100644 --- a/fs/cifs/link.c +++ b/fs/cifs/link.c | |||
@@ -180,59 +180,31 @@ format_mf_symlink(u8 *buf, unsigned int buf_len, const char *link_str) | |||
180 | 180 | ||
181 | static int | 181 | static int |
182 | create_mf_symlink(const unsigned int xid, struct cifs_tcon *tcon, | 182 | create_mf_symlink(const unsigned int xid, struct cifs_tcon *tcon, |
183 | const char *fromName, const char *toName, | 183 | struct cifs_sb_info *cifs_sb, const char *fromName, |
184 | struct cifs_sb_info *cifs_sb) | 184 | const char *toName) |
185 | { | 185 | { |
186 | int rc; | 186 | int rc; |
187 | int oplock = 0; | ||
188 | int remap; | ||
189 | int create_options = CREATE_NOT_DIR; | ||
190 | __u16 netfid = 0; | ||
191 | u8 *buf; | 187 | u8 *buf; |
192 | unsigned int bytes_written = 0; | 188 | unsigned int bytes_written = 0; |
193 | struct cifs_io_parms io_parms; | ||
194 | struct nls_table *nls_codepage; | ||
195 | |||
196 | nls_codepage = cifs_sb->local_nls; | ||
197 | remap = cifs_sb->mnt_cifs_flags & CIFS_MOUNT_MAP_SPECIAL_CHR; | ||
198 | 189 | ||
199 | buf = kmalloc(CIFS_MF_SYMLINK_FILE_SIZE, GFP_KERNEL); | 190 | buf = kmalloc(CIFS_MF_SYMLINK_FILE_SIZE, GFP_KERNEL); |
200 | if (!buf) | 191 | if (!buf) |
201 | return -ENOMEM; | 192 | return -ENOMEM; |
202 | 193 | ||
203 | rc = format_mf_symlink(buf, CIFS_MF_SYMLINK_FILE_SIZE, toName); | 194 | rc = format_mf_symlink(buf, CIFS_MF_SYMLINK_FILE_SIZE, toName); |
204 | if (rc != 0) { | 195 | if (rc) |
205 | kfree(buf); | 196 | goto out; |
206 | return rc; | ||
207 | } | ||
208 | |||
209 | if (backup_cred(cifs_sb)) | ||
210 | create_options |= CREATE_OPEN_BACKUP_INTENT; | ||
211 | |||
212 | rc = CIFSSMBOpen(xid, tcon, fromName, FILE_CREATE, GENERIC_WRITE, | ||
213 | create_options, &netfid, &oplock, NULL, | ||
214 | nls_codepage, remap); | ||
215 | if (rc != 0) { | ||
216 | kfree(buf); | ||
217 | return rc; | ||
218 | } | ||
219 | |||
220 | io_parms.netfid = netfid; | ||
221 | io_parms.pid = current->tgid; | ||
222 | io_parms.tcon = tcon; | ||
223 | io_parms.offset = 0; | ||
224 | io_parms.length = CIFS_MF_SYMLINK_FILE_SIZE; | ||
225 | 197 | ||
226 | rc = CIFSSMBWrite(xid, &io_parms, &bytes_written, buf, NULL, 0); | 198 | rc = tcon->ses->server->ops->create_mf_symlink(xid, tcon, cifs_sb, |
227 | CIFSSMBClose(xid, tcon, netfid); | 199 | fromName, buf, &bytes_written); |
228 | kfree(buf); | 200 | if (rc) |
229 | if (rc != 0) | 201 | goto out; |
230 | return rc; | ||
231 | 202 | ||
232 | if (bytes_written != CIFS_MF_SYMLINK_FILE_SIZE) | 203 | if (bytes_written != CIFS_MF_SYMLINK_FILE_SIZE) |
233 | return -EIO; | 204 | rc = -EIO; |
234 | 205 | out: | |
235 | return 0; | 206 | kfree(buf); |
207 | return rc; | ||
236 | } | 208 | } |
237 | 209 | ||
238 | static int | 210 | static int |
@@ -320,6 +292,39 @@ out: | |||
320 | } | 292 | } |
321 | 293 | ||
322 | int | 294 | int |
295 | cifs_create_mf_symlink(unsigned int xid, struct cifs_tcon *tcon, | ||
296 | struct cifs_sb_info *cifs_sb, const unsigned char *path, | ||
297 | char *pbuf, unsigned int *pbytes_written) | ||
298 | { | ||
299 | int rc; | ||
300 | int oplock = 0; | ||
301 | __u16 netfid = 0; | ||
302 | struct cifs_io_parms io_parms; | ||
303 | int create_options = CREATE_NOT_DIR; | ||
304 | |||
305 | if (backup_cred(cifs_sb)) | ||
306 | create_options |= CREATE_OPEN_BACKUP_INTENT; | ||
307 | |||
308 | rc = CIFSSMBOpen(xid, tcon, path, FILE_CREATE, GENERIC_WRITE, | ||
309 | create_options, &netfid, &oplock, NULL, | ||
310 | cifs_sb->local_nls, | ||
311 | cifs_sb->mnt_cifs_flags & | ||
312 | CIFS_MOUNT_MAP_SPECIAL_CHR); | ||
313 | if (rc) | ||
314 | return rc; | ||
315 | |||
316 | io_parms.netfid = netfid; | ||
317 | io_parms.pid = current->tgid; | ||
318 | io_parms.tcon = tcon; | ||
319 | io_parms.offset = 0; | ||
320 | io_parms.length = CIFS_MF_SYMLINK_FILE_SIZE; | ||
321 | |||
322 | rc = CIFSSMBWrite(xid, &io_parms, pbytes_written, pbuf, NULL, 0); | ||
323 | CIFSSMBClose(xid, tcon, netfid); | ||
324 | return rc; | ||
325 | } | ||
326 | |||
327 | int | ||
323 | check_mf_symlink(unsigned int xid, struct cifs_tcon *tcon, | 328 | check_mf_symlink(unsigned int xid, struct cifs_tcon *tcon, |
324 | struct cifs_sb_info *cifs_sb, struct cifs_fattr *fattr, | 329 | struct cifs_sb_info *cifs_sb, struct cifs_fattr *fattr, |
325 | const unsigned char *path) | 330 | const unsigned char *path) |
@@ -553,8 +558,7 @@ cifs_symlink(struct inode *inode, struct dentry *direntry, const char *symname) | |||
553 | 558 | ||
554 | /* BB what if DFS and this volume is on different share? BB */ | 559 | /* BB what if DFS and this volume is on different share? BB */ |
555 | if (cifs_sb->mnt_cifs_flags & CIFS_MOUNT_MF_SYMLINKS) | 560 | if (cifs_sb->mnt_cifs_flags & CIFS_MOUNT_MF_SYMLINKS) |
556 | rc = create_mf_symlink(xid, pTcon, full_path, symname, | 561 | rc = create_mf_symlink(xid, pTcon, cifs_sb, full_path, symname); |
557 | cifs_sb); | ||
558 | else if (pTcon->unix_ext) | 562 | else if (pTcon->unix_ext) |
559 | rc = CIFSUnixCreateSymLink(xid, pTcon, full_path, symname, | 563 | rc = CIFSUnixCreateSymLink(xid, pTcon, full_path, symname, |
560 | cifs_sb->local_nls); | 564 | cifs_sb->local_nls); |
diff --git a/fs/cifs/smb1ops.c b/fs/cifs/smb1ops.c index 099c27602257..1470ec4fc39d 100644 --- a/fs/cifs/smb1ops.c +++ b/fs/cifs/smb1ops.c | |||
@@ -1010,6 +1010,7 @@ struct smb_version_operations smb1_operations = { | |||
1010 | .mand_unlock_range = cifs_unlock_range, | 1010 | .mand_unlock_range = cifs_unlock_range, |
1011 | .push_mand_locks = cifs_push_mandatory_locks, | 1011 | .push_mand_locks = cifs_push_mandatory_locks, |
1012 | .query_mf_symlink = cifs_query_mf_symlink, | 1012 | .query_mf_symlink = cifs_query_mf_symlink, |
1013 | .create_mf_symlink = cifs_create_mf_symlink, | ||
1013 | .is_read_op = cifs_is_read_op, | 1014 | .is_read_op = cifs_is_read_op, |
1014 | }; | 1015 | }; |
1015 | 1016 | ||