Lines 129-190
cifs_bp_rename_retry:
Link Here
|
129 |
return full_path; |
129 |
return full_path; |
130 |
} |
130 |
} |
131 |
|
131 |
|
132 |
static void |
|
|
133 |
cifs_fill_fileinfo(struct inode *newinode, __u16 fileHandle, |
134 |
struct cifsTconInfo *tcon, bool write_only) |
135 |
{ |
136 |
int oplock = 0; |
137 |
struct cifsFileInfo *pCifsFile; |
138 |
struct cifsInodeInfo *pCifsInode; |
139 |
|
140 |
pCifsFile = kzalloc(sizeof(struct cifsFileInfo), GFP_KERNEL); |
141 |
|
142 |
if (pCifsFile == NULL) |
143 |
return; |
144 |
|
145 |
if (oplockEnabled) |
146 |
oplock = REQ_OPLOCK; |
147 |
|
148 |
pCifsFile->netfid = fileHandle; |
149 |
pCifsFile->pid = current->tgid; |
150 |
pCifsFile->pInode = newinode; |
151 |
pCifsFile->invalidHandle = false; |
152 |
pCifsFile->closePend = false; |
153 |
mutex_init(&pCifsFile->fh_mutex); |
154 |
mutex_init(&pCifsFile->lock_mutex); |
155 |
INIT_LIST_HEAD(&pCifsFile->llist); |
156 |
atomic_set(&pCifsFile->wrtPending, 0); |
157 |
|
158 |
/* set the following in open now |
159 |
pCifsFile->pfile = file; */ |
160 |
write_lock(&GlobalSMBSeslock); |
161 |
list_add(&pCifsFile->tlist, &tcon->openFileList); |
162 |
pCifsInode = CIFS_I(newinode); |
163 |
if (pCifsInode) { |
164 |
/* if readable file instance put first in list*/ |
165 |
if (write_only) |
166 |
list_add_tail(&pCifsFile->flist, |
167 |
&pCifsInode->openFileList); |
168 |
else |
169 |
list_add(&pCifsFile->flist, &pCifsInode->openFileList); |
170 |
|
171 |
if ((oplock & 0xF) == OPLOCK_EXCLUSIVE) { |
172 |
pCifsInode->clientCanCacheAll = true; |
173 |
pCifsInode->clientCanCacheRead = true; |
174 |
cFYI(1, ("Exclusive Oplock inode %p", newinode)); |
175 |
} else if ((oplock & 0xF) == OPLOCK_READ) |
176 |
pCifsInode->clientCanCacheRead = true; |
177 |
} |
178 |
write_unlock(&GlobalSMBSeslock); |
179 |
} |
180 |
|
181 |
int cifs_posix_open(char *full_path, struct inode **pinode, |
132 |
int cifs_posix_open(char *full_path, struct inode **pinode, |
182 |
struct super_block *sb, int mode, int oflags, |
133 |
struct super_block *sb, int mode, int oflags, |
183 |
int *poplock, __u16 *pnetfid, int xid) |
134 |
int *poplock, __u16 *pnetfid, int xid) |
184 |
{ |
135 |
{ |
185 |
int rc; |
136 |
int rc; |
186 |
__u32 oplock; |
137 |
__u32 oplock; |
187 |
bool write_only = false; |
|
|
188 |
FILE_UNIX_BASIC_INFO *presp_data; |
138 |
FILE_UNIX_BASIC_INFO *presp_data; |
189 |
__u32 posix_flags = 0; |
139 |
__u32 posix_flags = 0; |
190 |
struct cifs_sb_info *cifs_sb = CIFS_SB(sb); |
140 |
struct cifs_sb_info *cifs_sb = CIFS_SB(sb); |
Lines 222-229
int cifs_posix_open(char *full_path, struct inode **pinode,
Link Here
|
222 |
if (oflags & O_DIRECT) |
172 |
if (oflags & O_DIRECT) |
223 |
posix_flags |= SMB_O_DIRECT; |
173 |
posix_flags |= SMB_O_DIRECT; |
224 |
|
174 |
|
225 |
if (!(oflags & FMODE_READ)) |
|
|
226 |
write_only = true; |
227 |
|
175 |
|
228 |
rc = CIFSPOSIXCreate(xid, cifs_sb->tcon, posix_flags, mode, |
176 |
rc = CIFSPOSIXCreate(xid, cifs_sb->tcon, posix_flags, mode, |
229 |
pnetfid, presp_data, &oplock, full_path, |
177 |
pnetfid, presp_data, &oplock, full_path, |
Lines 252-259
int cifs_posix_open(char *full_path, struct inode **pinode,
Link Here
|
252 |
|
200 |
|
253 |
posix_fill_in_inode(*pinode, presp_data, 1); |
201 |
posix_fill_in_inode(*pinode, presp_data, 1); |
254 |
|
202 |
|
255 |
cifs_fill_fileinfo(*pinode, *pnetfid, cifs_sb->tcon, write_only); |
|
|
256 |
|
257 |
posix_open_ret: |
203 |
posix_open_ret: |
258 |
kfree(presp_data); |
204 |
kfree(presp_data); |
259 |
return rc; |
205 |
return rc; |
Lines 281-287
cifs_create(struct inode *inode, struct dentry *direntry, int mode,
Link Here
|
281 |
int create_options = CREATE_NOT_DIR; |
227 |
int create_options = CREATE_NOT_DIR; |
282 |
int oplock = 0; |
228 |
int oplock = 0; |
283 |
int oflags; |
229 |
int oflags; |
284 |
bool posix_create = false; |
|
|
285 |
/* |
230 |
/* |
286 |
* BB below access is probably too much for mknod to request |
231 |
* BB below access is probably too much for mknod to request |
287 |
* but we have to do query and setpathinfo so requesting |
232 |
* but we have to do query and setpathinfo so requesting |
Lines 296-301
cifs_create(struct inode *inode, struct dentry *direntry, int mode,
Link Here
|
296 |
char *full_path = NULL; |
241 |
char *full_path = NULL; |
297 |
FILE_ALL_INFO *buf = NULL; |
242 |
FILE_ALL_INFO *buf = NULL; |
298 |
struct inode *newinode = NULL; |
243 |
struct inode *newinode = NULL; |
|
|
244 |
struct cifsInodeInfo *pCifsInode; |
299 |
int disposition = FILE_OVERWRITE_IF; |
245 |
int disposition = FILE_OVERWRITE_IF; |
300 |
bool write_only = false; |
246 |
bool write_only = false; |
301 |
|
247 |
|
Lines 329-341
cifs_create(struct inode *inode, struct dentry *direntry, int mode,
Link Here
|
329 |
negotation. EREMOTE indicates DFS junction, which is not |
275 |
negotation. EREMOTE indicates DFS junction, which is not |
330 |
handled in posix open */ |
276 |
handled in posix open */ |
331 |
|
277 |
|
332 |
if (rc == 0) { |
278 |
if ((rc == 0) && (newinode == NULL)) |
333 |
posix_create = true; |
279 |
goto cifs_create_get_file_info; /* query inode info */ |
334 |
if (newinode == NULL) /* query inode info */ |
280 |
else if (rc == 0) /* success, no need to query */ |
335 |
goto cifs_create_get_file_info; |
281 |
goto cifs_create_set_dentry; |
336 |
else /* success, no need to query */ |
282 |
else if ((rc != -EIO) && (rc != -EREMOTE) && |
337 |
goto cifs_create_set_dentry; |
|
|
338 |
} else if ((rc != -EIO) && (rc != -EREMOTE) && |
339 |
(rc != -EOPNOTSUPP)) /* path not found or net err */ |
283 |
(rc != -EOPNOTSUPP)) /* path not found or net err */ |
340 |
goto cifs_create_out; |
284 |
goto cifs_create_out; |
341 |
/* else fallthrough to retry, using older open call, this is |
285 |
/* else fallthrough to retry, using older open call, this is |
Lines 467-475
cifs_create_set_dentry:
Link Here
|
467 |
if ((nd == NULL) || (!(nd->flags & LOOKUP_OPEN))) { |
411 |
if ((nd == NULL) || (!(nd->flags & LOOKUP_OPEN))) { |
468 |
/* mknod case - do not leave file open */ |
412 |
/* mknod case - do not leave file open */ |
469 |
CIFSSMBClose(xid, tcon, fileHandle); |
413 |
CIFSSMBClose(xid, tcon, fileHandle); |
470 |
} else if (!(posix_create) && (newinode)) { |
414 |
} else if (newinode) { |
471 |
cifs_fill_fileinfo(newinode, fileHandle, |
415 |
struct cifsFileInfo *pCifsFile = |
472 |
cifs_sb->tcon, write_only); |
416 |
kzalloc(sizeof(struct cifsFileInfo), GFP_KERNEL); |
|
|
417 |
|
418 |
if (pCifsFile == NULL) |
419 |
goto cifs_create_out; |
420 |
pCifsFile->netfid = fileHandle; |
421 |
pCifsFile->pid = current->tgid; |
422 |
pCifsFile->pInode = newinode; |
423 |
pCifsFile->invalidHandle = false; |
424 |
pCifsFile->closePend = false; |
425 |
init_MUTEX(&pCifsFile->fh_sem); |
426 |
mutex_init(&pCifsFile->lock_mutex); |
427 |
INIT_LIST_HEAD(&pCifsFile->llist); |
428 |
atomic_set(&pCifsFile->wrtPending, 0); |
429 |
|
430 |
/* set the following in open now |
431 |
pCifsFile->pfile = file; */ |
432 |
write_lock(&GlobalSMBSeslock); |
433 |
list_add(&pCifsFile->tlist, &tcon->openFileList); |
434 |
pCifsInode = CIFS_I(newinode); |
435 |
if (pCifsInode) { |
436 |
/* if readable file instance put first in list*/ |
437 |
if (write_only) { |
438 |
list_add_tail(&pCifsFile->flist, |
439 |
&pCifsInode->openFileList); |
440 |
} else { |
441 |
list_add(&pCifsFile->flist, |
442 |
&pCifsInode->openFileList); |
443 |
} |
444 |
if ((oplock & 0xF) == OPLOCK_EXCLUSIVE) { |
445 |
pCifsInode->clientCanCacheAll = true; |
446 |
pCifsInode->clientCanCacheRead = true; |
447 |
cFYI(1, ("Exclusive Oplock inode %p", |
448 |
newinode)); |
449 |
} else if ((oplock & 0xF) == OPLOCK_READ) |
450 |
pCifsInode->clientCanCacheRead = true; |
451 |
} |
452 |
write_unlock(&GlobalSMBSeslock); |
473 |
} |
453 |
} |
474 |
cifs_create_out: |
454 |
cifs_create_out: |
475 |
kfree(buf); |
455 |
kfree(buf); |
Lines 602-622
int cifs_mknod(struct inode *inode, struct dentry *direntry, int mode,
Link Here
|
602 |
return rc; |
582 |
return rc; |
603 |
} |
583 |
} |
604 |
|
584 |
|
|
|
585 |
|
605 |
struct dentry * |
586 |
struct dentry * |
606 |
cifs_lookup(struct inode *parent_dir_inode, struct dentry *direntry, |
587 |
cifs_lookup(struct inode *parent_dir_inode, struct dentry *direntry, |
607 |
struct nameidata *nd) |
588 |
struct nameidata *nd) |
608 |
{ |
589 |
{ |
609 |
int xid; |
590 |
int xid; |
610 |
int rc = 0; /* to get around spurious gcc warning, set to zero here */ |
591 |
int rc = 0; /* to get around spurious gcc warning, set to zero here */ |
611 |
int oplock = 0; |
|
|
612 |
int mode; |
613 |
__u16 fileHandle = 0; |
614 |
bool posix_open = false; |
615 |
struct cifs_sb_info *cifs_sb; |
592 |
struct cifs_sb_info *cifs_sb; |
616 |
struct cifsTconInfo *pTcon; |
593 |
struct cifsTconInfo *pTcon; |
617 |
struct inode *newInode = NULL; |
594 |
struct inode *newInode = NULL; |
618 |
char *full_path = NULL; |
595 |
char *full_path = NULL; |
619 |
struct file *filp; |
|
|
620 |
|
596 |
|
621 |
xid = GetXid(); |
597 |
xid = GetXid(); |
622 |
|
598 |
|
Lines 658-694
cifs_lookup(struct inode *parent_dir_inode, struct dentry *direntry,
Link Here
|
658 |
} |
634 |
} |
659 |
cFYI(1, ("Full path: %s inode = 0x%p", full_path, direntry->d_inode)); |
635 |
cFYI(1, ("Full path: %s inode = 0x%p", full_path, direntry->d_inode)); |
660 |
|
636 |
|
661 |
if (pTcon->unix_ext) { |
637 |
if (pTcon->unix_ext) |
662 |
if (!(nd->flags & (LOOKUP_PARENT | LOOKUP_DIRECTORY)) && |
638 |
rc = cifs_get_inode_info_unix(&newInode, full_path, |
663 |
(nd->flags & LOOKUP_OPEN)) { |
639 |
parent_dir_inode->i_sb, xid); |
664 |
if (!((nd->intent.open.flags & O_CREAT) && |
640 |
else |
665 |
(nd->intent.open.flags & O_EXCL))) { |
|
|
666 |
mode = nd->intent.open.create_mode & |
667 |
~current_umask(); |
668 |
rc = cifs_posix_open(full_path, &newInode, |
669 |
parent_dir_inode->i_sb, mode, |
670 |
nd->intent.open.flags, &oplock, |
671 |
&fileHandle, xid); |
672 |
/* |
673 |
* This code works around a bug in |
674 |
* samba posix open in samba versions 3.3.1 |
675 |
* and earlier where create works |
676 |
* but open fails with invalid parameter. |
677 |
* If either of these error codes are |
678 |
* returned, follow the normal lookup. |
679 |
* Otherwise, the error during posix open |
680 |
* is handled. |
681 |
*/ |
682 |
if ((rc != -EINVAL) && (rc != -EOPNOTSUPP)) |
683 |
posix_open = true; |
684 |
} |
685 |
} |
686 |
if (!posix_open) |
687 |
rc = cifs_get_inode_info_unix(&newInode, full_path, |
688 |
parent_dir_inode->i_sb, xid); |
689 |
} else |
690 |
rc = cifs_get_inode_info(&newInode, full_path, NULL, |
641 |
rc = cifs_get_inode_info(&newInode, full_path, NULL, |
691 |
parent_dir_inode->i_sb, xid, NULL); |
642 |
parent_dir_inode->i_sb, xid, NULL); |
692 |
|
643 |
|
693 |
if ((rc == 0) && (newInode != NULL)) { |
644 |
if ((rc == 0) && (newInode != NULL)) { |
694 |
if (pTcon->nocase) |
645 |
if (pTcon->nocase) |
Lines 696-703
cifs_lookup(struct inode *parent_dir_inode, struct dentry *direntry,
Link Here
|
696 |
else |
647 |
else |
697 |
direntry->d_op = &cifs_dentry_ops; |
648 |
direntry->d_op = &cifs_dentry_ops; |
698 |
d_add(direntry, newInode); |
649 |
d_add(direntry, newInode); |
699 |
if (posix_open) |
650 |
|
700 |
filp = lookup_instantiate_filp(nd, direntry, NULL); |
|
|
701 |
/* since paths are not looked up by component - the parent |
651 |
/* since paths are not looked up by component - the parent |
702 |
directories are presumed to be good here */ |
652 |
directories are presumed to be good here */ |
703 |
renew_parental_timestamps(direntry); |
653 |
renew_parental_timestamps(direntry); |