@@ -129,12 +129,64 @@ build_path_from_dentry(struct dentry *direntry)
129
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 ,
170
+ & pCifsInode -> openFileList );
171
+ }
172
+ if ((oplock & 0xF ) == OPLOCK_EXCLUSIVE ) {
173
+ pCifsInode -> clientCanCacheAll = true;
174
+ pCifsInode -> clientCanCacheRead = true;
175
+ cFYI (1 , ("Exclusive Oplock inode %p" ,
176
+ newinode ));
177
+ } else if ((oplock & 0xF ) == OPLOCK_READ )
178
+ pCifsInode -> clientCanCacheRead = true;
179
+ }
180
+ write_unlock (& GlobalSMBSeslock );
181
+ }
182
+
132
183
int cifs_posix_open (char * full_path , struct inode * * pinode ,
133
184
struct super_block * sb , int mode , int oflags ,
134
185
int * poplock , __u16 * pnetfid , int xid )
135
186
{
136
187
int rc ;
137
188
__u32 oplock ;
189
+ bool write_only = false;
138
190
FILE_UNIX_BASIC_INFO * presp_data ;
139
191
__u32 posix_flags = 0 ;
140
192
struct cifs_sb_info * cifs_sb = CIFS_SB (sb );
@@ -172,6 +224,8 @@ int cifs_posix_open(char *full_path, struct inode **pinode,
172
224
if (oflags & O_DIRECT )
173
225
posix_flags |= SMB_O_DIRECT ;
174
226
227
+ if (!(oflags & FMODE_READ ))
228
+ write_only = true;
175
229
176
230
rc = CIFSPOSIXCreate (xid , cifs_sb -> tcon , posix_flags , mode ,
177
231
pnetfid , presp_data , & oplock , full_path ,
@@ -200,6 +254,8 @@ int cifs_posix_open(char *full_path, struct inode **pinode,
200
254
201
255
posix_fill_in_inode (* pinode , presp_data , 1 );
202
256
257
+ cifs_fill_fileinfo (* pinode , * pnetfid , cifs_sb -> tcon , write_only );
258
+
203
259
posix_open_ret :
204
260
kfree (presp_data );
205
261
return rc ;
@@ -241,7 +297,6 @@ cifs_create(struct inode *inode, struct dentry *direntry, int mode,
241
297
char * full_path = NULL ;
242
298
FILE_ALL_INFO * buf = NULL ;
243
299
struct inode * newinode = NULL ;
244
- struct cifsInodeInfo * pCifsInode ;
245
300
int disposition = FILE_OVERWRITE_IF ;
246
301
bool write_only = false;
247
302
@@ -412,44 +467,8 @@ cifs_create(struct inode *inode, struct dentry *direntry, int mode,
412
467
/* mknod case - do not leave file open */
413
468
CIFSSMBClose (xid , tcon , fileHandle );
414
469
} else if (newinode ) {
415
- struct cifsFileInfo * pCifsFile =
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 );
470
+ cifs_fill_fileinfo (newinode , fileHandle ,
471
+ cifs_sb -> tcon , write_only );
453
472
}
454
473
cifs_create_out :
455
474
kfree (buf );
@@ -582,17 +601,21 @@ int cifs_mknod(struct inode *inode, struct dentry *direntry, int mode,
582
601
return rc ;
583
602
}
584
603
585
-
586
604
struct dentry *
587
605
cifs_lookup (struct inode * parent_dir_inode , struct dentry * direntry ,
588
606
struct nameidata * nd )
589
607
{
590
608
int xid ;
591
609
int rc = 0 ; /* to get around spurious gcc warning, set to zero here */
610
+ int oplock = 0 ;
611
+ int mode ;
612
+ __u16 fileHandle = 0 ;
613
+ bool posix_open = false;
592
614
struct cifs_sb_info * cifs_sb ;
593
615
struct cifsTconInfo * pTcon ;
594
616
struct inode * newInode = NULL ;
595
617
char * full_path = NULL ;
618
+ struct file * filp ;
596
619
597
620
xid = GetXid ();
598
621
@@ -634,20 +657,36 @@ cifs_lookup(struct inode *parent_dir_inode, struct dentry *direntry,
634
657
}
635
658
cFYI (1 , ("Full path: %s inode = 0x%p" , full_path , direntry -> d_inode ));
636
659
637
- if (pTcon -> unix_ext )
638
- rc = cifs_get_inode_info_unix (& newInode , full_path ,
639
- parent_dir_inode -> i_sb , xid );
640
- else
660
+ if (pTcon -> unix_ext ) {
661
+ if (!(nd -> flags & (LOOKUP_PARENT | LOOKUP_DIRECTORY )) &&
662
+ (nd -> flags & LOOKUP_OPEN )) {
663
+ if (!((nd -> intent .open .flags & O_CREAT ) &&
664
+ (nd -> intent .open .flags & O_EXCL ))) {
665
+ mode = nd -> intent .open .create_mode &
666
+ ~current -> fs -> umask ;
667
+ rc = cifs_posix_open (full_path , & newInode ,
668
+ parent_dir_inode -> i_sb , mode ,
669
+ nd -> intent .open .flags , & oplock ,
670
+ & fileHandle , xid );
671
+ if ((rc != - EINVAL ) && (rc != - EOPNOTSUPP ))
672
+ posix_open = true;
673
+ }
674
+ }
675
+ if (!posix_open )
676
+ rc = cifs_get_inode_info_unix (& newInode , full_path ,
677
+ parent_dir_inode -> i_sb , xid );
678
+ } else
641
679
rc = cifs_get_inode_info (& newInode , full_path , NULL ,
642
- parent_dir_inode -> i_sb , xid , NULL );
680
+ parent_dir_inode -> i_sb , xid , NULL );
643
681
644
682
if ((rc == 0 ) && (newInode != NULL )) {
645
683
if (pTcon -> nocase )
646
684
direntry -> d_op = & cifs_ci_dentry_ops ;
647
685
else
648
686
direntry -> d_op = & cifs_dentry_ops ;
649
687
d_add (direntry , newInode );
650
-
688
+ if (posix_open )
689
+ filp = lookup_instantiate_filp (nd , direntry , NULL );
651
690
/* since paths are not looked up by component - the parent
652
691
directories are presumed to be good here */
653
692
renew_parental_timestamps (direntry );
0 commit comments