aboutsummaryrefslogtreecommitdiffstats
path: root/fs/cifs/dir.c
diff options
context:
space:
mode:
authorPavel Shilovsky <pshilovsky@samba.org>2012-09-18 19:20:27 -0400
committerSteve French <smfrench@gmail.com>2012-09-24 22:46:27 -0400
commit253641388a49259f6bfefecfb14fa057ca58dc21 (patch)
treee38c2f0561e5fd547a1c5d0633c4b65dc6f371a0 /fs/cifs/dir.c
parentb7546bc54c4acf1a79c83030fa0591cd24875125 (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.c95
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)
160static int 160static int
161cifs_do_create(struct inode *inode, struct dentry *direntry, unsigned int xid, 161cifs_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,
334cifs_create_get_file_info: 334cifs_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:
356cifs_create_set_dentry: 356cifs_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);
475out_free_xid: 484out_free_xid: