diff options
author | Pavel Shilovsky <pshilovsky@samba.org> | 2012-09-18 19:20:27 -0400 |
---|---|---|
committer | Steve French <smfrench@gmail.com> | 2012-09-24 22:46:27 -0400 |
commit | 253641388a49259f6bfefecfb14fa057ca58dc21 (patch) | |
tree | e38c2f0561e5fd547a1c5d0633c4b65dc6f371a0 /fs/cifs/dir.c | |
parent | b7546bc54c4acf1a79c83030fa0591cd24875125 (diff) |
CIFS: Move create code use ops struct
Signed-off-by: Pavel Shilovsky <pshilovsky@samba.org>
Signed-off-by: Steve French <smfrench@gmail.com>
Diffstat (limited to 'fs/cifs/dir.c')
-rw-r--r-- | fs/cifs/dir.c | 95 |
1 files changed, 52 insertions, 43 deletions
diff --git a/fs/cifs/dir.c b/fs/cifs/dir.c index 70823dc4f960..b99a1670dad4 100644 --- a/fs/cifs/dir.c +++ b/fs/cifs/dir.c | |||
@@ -160,17 +160,18 @@ check_name(struct dentry *direntry) | |||
160 | static int | 160 | static int |
161 | cifs_do_create(struct inode *inode, struct dentry *direntry, unsigned int xid, | 161 | cifs_do_create(struct inode *inode, struct dentry *direntry, unsigned int xid, |
162 | struct tcon_link *tlink, unsigned oflags, umode_t mode, | 162 | struct tcon_link *tlink, unsigned oflags, umode_t mode, |
163 | __u32 *oplock, __u16 *fileHandle, int *created) | 163 | __u32 *oplock, struct cifs_fid *fid, int *created) |
164 | { | 164 | { |
165 | int rc = -ENOENT; | 165 | int rc = -ENOENT; |
166 | int create_options = CREATE_NOT_DIR; | 166 | int create_options = CREATE_NOT_DIR; |
167 | int desiredAccess; | 167 | int desired_access; |
168 | struct cifs_sb_info *cifs_sb = CIFS_SB(inode->i_sb); | 168 | struct cifs_sb_info *cifs_sb = CIFS_SB(inode->i_sb); |
169 | struct cifs_tcon *tcon = tlink_tcon(tlink); | 169 | struct cifs_tcon *tcon = tlink_tcon(tlink); |
170 | char *full_path = NULL; | 170 | char *full_path = NULL; |
171 | FILE_ALL_INFO *buf = NULL; | 171 | FILE_ALL_INFO *buf = NULL; |
172 | struct inode *newinode = NULL; | 172 | struct inode *newinode = NULL; |
173 | int disposition; | 173 | int disposition; |
174 | struct TCP_Server_Info *server = tcon->ses->server; | ||
174 | 175 | ||
175 | *oplock = 0; | 176 | *oplock = 0; |
176 | if (tcon->ses->server->oplocks) | 177 | if (tcon->ses->server->oplocks) |
@@ -185,8 +186,8 @@ cifs_do_create(struct inode *inode, struct dentry *direntry, unsigned int xid, | |||
185 | if (tcon->unix_ext && cap_unix(tcon->ses) && !tcon->broken_posix_open && | 186 | if (tcon->unix_ext && cap_unix(tcon->ses) && !tcon->broken_posix_open && |
186 | (CIFS_UNIX_POSIX_PATH_OPS_CAP & | 187 | (CIFS_UNIX_POSIX_PATH_OPS_CAP & |
187 | le64_to_cpu(tcon->fsUnixInfo.Capability))) { | 188 | le64_to_cpu(tcon->fsUnixInfo.Capability))) { |
188 | rc = cifs_posix_open(full_path, &newinode, | 189 | rc = cifs_posix_open(full_path, &newinode, inode->i_sb, mode, |
189 | inode->i_sb, mode, oflags, oplock, fileHandle, xid); | 190 | oflags, oplock, &fid->netfid, xid); |
190 | switch (rc) { | 191 | switch (rc) { |
191 | case 0: | 192 | case 0: |
192 | if (newinode == NULL) { | 193 | if (newinode == NULL) { |
@@ -202,7 +203,7 @@ cifs_do_create(struct inode *inode, struct dentry *direntry, unsigned int xid, | |||
202 | * close it and proceed as if it were a normal | 203 | * close it and proceed as if it were a normal |
203 | * lookup. | 204 | * lookup. |
204 | */ | 205 | */ |
205 | CIFSSMBClose(xid, tcon, *fileHandle); | 206 | CIFSSMBClose(xid, tcon, fid->netfid); |
206 | goto cifs_create_get_file_info; | 207 | goto cifs_create_get_file_info; |
207 | } | 208 | } |
208 | /* success, no need to query */ | 209 | /* success, no need to query */ |
@@ -244,11 +245,11 @@ cifs_do_create(struct inode *inode, struct dentry *direntry, unsigned int xid, | |||
244 | */ | 245 | */ |
245 | } | 246 | } |
246 | 247 | ||
247 | desiredAccess = 0; | 248 | desired_access = 0; |
248 | if (OPEN_FMODE(oflags) & FMODE_READ) | 249 | if (OPEN_FMODE(oflags) & FMODE_READ) |
249 | desiredAccess |= GENERIC_READ; /* is this too little? */ | 250 | desired_access |= GENERIC_READ; /* is this too little? */ |
250 | if (OPEN_FMODE(oflags) & FMODE_WRITE) | 251 | if (OPEN_FMODE(oflags) & FMODE_WRITE) |
251 | desiredAccess |= GENERIC_WRITE; | 252 | desired_access |= GENERIC_WRITE; |
252 | 253 | ||
253 | disposition = FILE_OVERWRITE_IF; | 254 | disposition = FILE_OVERWRITE_IF; |
254 | if ((oflags & (O_CREAT | O_EXCL)) == (O_CREAT | O_EXCL)) | 255 | if ((oflags & (O_CREAT | O_EXCL)) == (O_CREAT | O_EXCL)) |
@@ -260,8 +261,15 @@ cifs_do_create(struct inode *inode, struct dentry *direntry, unsigned int xid, | |||
260 | else | 261 | else |
261 | cFYI(1, "Create flag not set in create function"); | 262 | cFYI(1, "Create flag not set in create function"); |
262 | 263 | ||
263 | /* BB add processing to set equivalent of mode - e.g. via CreateX with | 264 | /* |
264 | ACLs */ | 265 | * BB add processing to set equivalent of mode - e.g. via CreateX with |
266 | * ACLs | ||
267 | */ | ||
268 | |||
269 | if (!server->ops->open) { | ||
270 | rc = -ENOSYS; | ||
271 | goto out; | ||
272 | } | ||
265 | 273 | ||
266 | buf = kmalloc(sizeof(FILE_ALL_INFO), GFP_KERNEL); | 274 | buf = kmalloc(sizeof(FILE_ALL_INFO), GFP_KERNEL); |
267 | if (buf == NULL) { | 275 | if (buf == NULL) { |
@@ -279,28 +287,18 @@ cifs_do_create(struct inode *inode, struct dentry *direntry, unsigned int xid, | |||
279 | if (backup_cred(cifs_sb)) | 287 | if (backup_cred(cifs_sb)) |
280 | create_options |= CREATE_OPEN_BACKUP_INTENT; | 288 | create_options |= CREATE_OPEN_BACKUP_INTENT; |
281 | 289 | ||
282 | if (tcon->ses->capabilities & CAP_NT_SMBS) | 290 | rc = server->ops->open(xid, tcon, full_path, disposition, |
283 | rc = CIFSSMBOpen(xid, tcon, full_path, disposition, | 291 | desired_access, create_options, fid, oplock, |
284 | desiredAccess, create_options, | 292 | buf, cifs_sb); |
285 | fileHandle, oplock, buf, cifs_sb->local_nls, | ||
286 | cifs_sb->mnt_cifs_flags & CIFS_MOUNT_MAP_SPECIAL_CHR); | ||
287 | else | ||
288 | rc = -EIO; /* no NT SMB support fall into legacy open below */ | ||
289 | |||
290 | if (rc == -EIO) { | ||
291 | /* old server, retry the open legacy style */ | ||
292 | rc = SMBLegacyOpen(xid, tcon, full_path, disposition, | ||
293 | desiredAccess, create_options, | ||
294 | fileHandle, oplock, buf, cifs_sb->local_nls, | ||
295 | cifs_sb->mnt_cifs_flags & CIFS_MOUNT_MAP_SPECIAL_CHR); | ||
296 | } | ||
297 | if (rc) { | 293 | if (rc) { |
298 | cFYI(1, "cifs_create returned 0x%x", rc); | 294 | cFYI(1, "cifs_create returned 0x%x", rc); |
299 | goto out; | 295 | goto out; |
300 | } | 296 | } |
301 | 297 | ||
302 | /* If Open reported that we actually created a file | 298 | /* |
303 | then we now have to set the mode if possible */ | 299 | * If Open reported that we actually created a file then we now have to |
300 | * set the mode if possible. | ||
301 | */ | ||
304 | if ((tcon->unix_ext) && (*oplock & CIFS_CREATE_ACTION)) { | 302 | if ((tcon->unix_ext) && (*oplock & CIFS_CREATE_ACTION)) { |
305 | struct cifs_unix_set_info_args args = { | 303 | struct cifs_unix_set_info_args args = { |
306 | .mode = mode, | 304 | .mode = mode, |
@@ -321,11 +319,13 @@ cifs_do_create(struct inode *inode, struct dentry *direntry, unsigned int xid, | |||
321 | args.uid = NO_CHANGE_64; | 319 | args.uid = NO_CHANGE_64; |
322 | args.gid = NO_CHANGE_64; | 320 | args.gid = NO_CHANGE_64; |
323 | } | 321 | } |
324 | CIFSSMBUnixSetFileInfo(xid, tcon, &args, *fileHandle, | 322 | CIFSSMBUnixSetFileInfo(xid, tcon, &args, fid->netfid, |
325 | current->tgid); | 323 | current->tgid); |
326 | } else { | 324 | } else { |
327 | /* BB implement mode setting via Windows security | 325 | /* |
328 | descriptors e.g. */ | 326 | * BB implement mode setting via Windows security |
327 | * descriptors e.g. | ||
328 | */ | ||
329 | /* CIFSSMBWinSetPerms(xid,tcon,path,mode,-1,-1,nls);*/ | 329 | /* CIFSSMBWinSetPerms(xid,tcon,path,mode,-1,-1,nls);*/ |
330 | 330 | ||
331 | /* Could set r/o dos attribute if mode & 0222 == 0 */ | 331 | /* Could set r/o dos attribute if mode & 0222 == 0 */ |
@@ -334,11 +334,11 @@ cifs_do_create(struct inode *inode, struct dentry *direntry, unsigned int xid, | |||
334 | cifs_create_get_file_info: | 334 | cifs_create_get_file_info: |
335 | /* server might mask mode so we have to query for it */ | 335 | /* server might mask mode so we have to query for it */ |
336 | if (tcon->unix_ext) | 336 | if (tcon->unix_ext) |
337 | rc = cifs_get_inode_info_unix(&newinode, full_path, | 337 | rc = cifs_get_inode_info_unix(&newinode, full_path, inode->i_sb, |
338 | inode->i_sb, xid); | 338 | xid); |
339 | else { | 339 | else { |
340 | rc = cifs_get_inode_info(&newinode, full_path, buf, | 340 | rc = cifs_get_inode_info(&newinode, full_path, buf, inode->i_sb, |
341 | inode->i_sb, xid, fileHandle); | 341 | xid, &fid->netfid); |
342 | if (newinode) { | 342 | if (newinode) { |
343 | if (cifs_sb->mnt_cifs_flags & CIFS_MOUNT_DYNPERM) | 343 | if (cifs_sb->mnt_cifs_flags & CIFS_MOUNT_DYNPERM) |
344 | newinode->i_mode = mode; | 344 | newinode->i_mode = mode; |
@@ -356,7 +356,8 @@ cifs_create_get_file_info: | |||
356 | cifs_create_set_dentry: | 356 | cifs_create_set_dentry: |
357 | if (rc != 0) { | 357 | if (rc != 0) { |
358 | cFYI(1, "Create worked, get_inode_info failed rc = %d", rc); | 358 | cFYI(1, "Create worked, get_inode_info failed rc = %d", rc); |
359 | CIFSSMBClose(xid, tcon, *fileHandle); | 359 | if (server->ops->close) |
360 | server->ops->close(xid, tcon, fid); | ||
360 | goto out; | 361 | goto out; |
361 | } | 362 | } |
362 | d_drop(direntry); | 363 | d_drop(direntry); |
@@ -377,6 +378,7 @@ cifs_atomic_open(struct inode *inode, struct dentry *direntry, | |||
377 | unsigned int xid; | 378 | unsigned int xid; |
378 | struct tcon_link *tlink; | 379 | struct tcon_link *tlink; |
379 | struct cifs_tcon *tcon; | 380 | struct cifs_tcon *tcon; |
381 | struct TCP_Server_Info *server; | ||
380 | struct cifs_fid fid; | 382 | struct cifs_fid fid; |
381 | __u32 oplock; | 383 | __u32 oplock; |
382 | struct cifsFileInfo *file_info; | 384 | struct cifsFileInfo *file_info; |
@@ -414,22 +416,25 @@ cifs_atomic_open(struct inode *inode, struct dentry *direntry, | |||
414 | goto out_free_xid; | 416 | goto out_free_xid; |
415 | 417 | ||
416 | tcon = tlink_tcon(tlink); | 418 | tcon = tlink_tcon(tlink); |
419 | server = tcon->ses->server; | ||
417 | 420 | ||
418 | rc = cifs_do_create(inode, direntry, xid, tlink, oflags, mode, | 421 | rc = cifs_do_create(inode, direntry, xid, tlink, oflags, mode, |
419 | &oplock, &fid.netfid, opened); | 422 | &oplock, &fid, opened); |
420 | 423 | ||
421 | if (rc) | 424 | if (rc) |
422 | goto out; | 425 | goto out; |
423 | 426 | ||
424 | rc = finish_open(file, direntry, generic_file_open, opened); | 427 | rc = finish_open(file, direntry, generic_file_open, opened); |
425 | if (rc) { | 428 | if (rc) { |
426 | CIFSSMBClose(xid, tcon, fid.netfid); | 429 | if (server->ops->close) |
430 | server->ops->close(xid, tcon, &fid); | ||
427 | goto out; | 431 | goto out; |
428 | } | 432 | } |
429 | 433 | ||
430 | file_info = cifs_new_fileinfo(&fid, file, tlink, oplock); | 434 | file_info = cifs_new_fileinfo(&fid, file, tlink, oplock); |
431 | if (file_info == NULL) { | 435 | if (file_info == NULL) { |
432 | CIFSSMBClose(xid, tcon, fid.netfid); | 436 | if (server->ops->close) |
437 | server->ops->close(xid, tcon, &fid); | ||
433 | rc = -ENOMEM; | 438 | rc = -ENOMEM; |
434 | } | 439 | } |
435 | 440 | ||
@@ -454,7 +459,9 @@ int cifs_create(struct inode *inode, struct dentry *direntry, umode_t mode, | |||
454 | */ | 459 | */ |
455 | unsigned oflags = O_EXCL | O_CREAT | O_RDWR; | 460 | unsigned oflags = O_EXCL | O_CREAT | O_RDWR; |
456 | struct tcon_link *tlink; | 461 | struct tcon_link *tlink; |
457 | __u16 fileHandle; | 462 | struct cifs_tcon *tcon; |
463 | struct TCP_Server_Info *server; | ||
464 | struct cifs_fid fid; | ||
458 | __u32 oplock; | 465 | __u32 oplock; |
459 | int created = FILE_CREATED; | 466 | int created = FILE_CREATED; |
460 | 467 | ||
@@ -467,9 +474,11 @@ int cifs_create(struct inode *inode, struct dentry *direntry, umode_t mode, | |||
467 | goto out_free_xid; | 474 | goto out_free_xid; |
468 | 475 | ||
469 | rc = cifs_do_create(inode, direntry, xid, tlink, oflags, mode, | 476 | rc = cifs_do_create(inode, direntry, xid, tlink, oflags, mode, |
470 | &oplock, &fileHandle, &created); | 477 | &oplock, &fid, &created); |
471 | if (!rc) | 478 | tcon = tlink_tcon(tlink); |
472 | CIFSSMBClose(xid, tlink_tcon(tlink), fileHandle); | 479 | server = tcon->ses->server; |
480 | if (!rc && server->ops->close) | ||
481 | server->ops->close(xid, tcon, &fid); | ||
473 | 482 | ||
474 | cifs_put_tlink(tlink); | 483 | cifs_put_tlink(tlink); |
475 | out_free_xid: | 484 | out_free_xid: |