~ [ source navigation ] ~ [ diff markup ] ~ [ identifier search ] ~

TOMOYO Linux Cross Reference
Linux/fs/smb/client/dir.c

Version: ~ [ linux-6.12-rc7 ] ~ [ linux-6.11.7 ] ~ [ linux-6.10.14 ] ~ [ linux-6.9.12 ] ~ [ linux-6.8.12 ] ~ [ linux-6.7.12 ] ~ [ linux-6.6.60 ] ~ [ linux-6.5.13 ] ~ [ linux-6.4.16 ] ~ [ linux-6.3.13 ] ~ [ linux-6.2.16 ] ~ [ linux-6.1.116 ] ~ [ linux-6.0.19 ] ~ [ linux-5.19.17 ] ~ [ linux-5.18.19 ] ~ [ linux-5.17.15 ] ~ [ linux-5.16.20 ] ~ [ linux-5.15.171 ] ~ [ linux-5.14.21 ] ~ [ linux-5.13.19 ] ~ [ linux-5.12.19 ] ~ [ linux-5.11.22 ] ~ [ linux-5.10.229 ] ~ [ linux-5.9.16 ] ~ [ linux-5.8.18 ] ~ [ linux-5.7.19 ] ~ [ linux-5.6.19 ] ~ [ linux-5.5.19 ] ~ [ linux-5.4.285 ] ~ [ linux-5.3.18 ] ~ [ linux-5.2.21 ] ~ [ linux-5.1.21 ] ~ [ linux-5.0.21 ] ~ [ linux-4.20.17 ] ~ [ linux-4.19.323 ] ~ [ linux-4.18.20 ] ~ [ linux-4.17.19 ] ~ [ linux-4.16.18 ] ~ [ linux-4.15.18 ] ~ [ linux-4.14.336 ] ~ [ linux-4.13.16 ] ~ [ linux-4.12.14 ] ~ [ linux-4.11.12 ] ~ [ linux-4.10.17 ] ~ [ linux-4.9.337 ] ~ [ linux-4.4.302 ] ~ [ linux-3.10.108 ] ~ [ linux-2.6.32.71 ] ~ [ linux-2.6.0 ] ~ [ linux-2.4.37.11 ] ~ [ unix-v6-master ] ~ [ ccs-tools-1.8.12 ] ~ [ policy-sample ] ~
Architecture: ~ [ i386 ] ~ [ alpha ] ~ [ m68k ] ~ [ mips ] ~ [ ppc ] ~ [ sparc ] ~ [ sparc64 ] ~

Diff markup

Differences between /fs/smb/client/dir.c (Version linux-6.12-rc7) and /fs/smb/client/dir.c (Version linux-5.17.15)


  1 // SPDX-License-Identifier: LGPL-2.1                1 
  2 /*                                                
  3  *                                                
  4  *   vfs operations that deal with dentries       
  5  *                                                
  6  *   Copyright (C) International Business Mach    
  7  *   Author(s): Steve French (sfrench@us.ibm.c    
  8  *                                                
  9  */                                               
 10 #include <linux/fs.h>                             
 11 #include <linux/stat.h>                           
 12 #include <linux/slab.h>                           
 13 #include <linux/namei.h>                          
 14 #include <linux/mount.h>                          
 15 #include <linux/file.h>                           
 16 #include "cifsfs.h"                               
 17 #include "cifspdu.h"                              
 18 #include "cifsglob.h"                             
 19 #include "cifsproto.h"                            
 20 #include "cifs_debug.h"                           
 21 #include "cifs_fs_sb.h"                           
 22 #include "cifs_unicode.h"                         
 23 #include "fs_context.h"                           
 24 #include "cifs_ioctl.h"                           
 25 #include "fscache.h"                              
 26                                                   
 27 static void                                       
 28 renew_parental_timestamps(struct dentry *diren    
 29 {                                                 
 30         /* BB check if there is a way to get t    
 31            really need this */                    
 32         do {                                      
 33                 cifs_set_time(direntry, jiffie    
 34                 direntry = direntry->d_parent;    
 35         } while (!IS_ROOT(direntry));             
 36 }                                                 
 37                                                   
 38 char *                                            
 39 cifs_build_path_to_root(struct smb3_fs_context    
 40                         struct cifs_tcon *tcon    
 41 {                                                 
 42         int pplen = ctx->prepath ? strlen(ctx-    
 43         int dfsplen;                              
 44         char *full_path = NULL;                   
 45                                                   
 46         /* if no prefix path, simply set path     
 47         if (pplen == 0) {                         
 48                 full_path = kzalloc(1, GFP_KER    
 49                 return full_path;                 
 50         }                                         
 51                                                   
 52         if (add_treename)                         
 53                 dfsplen = strnlen(tcon->tree_n    
 54         else                                      
 55                 dfsplen = 0;                      
 56                                                   
 57         full_path = kmalloc(dfsplen + pplen +     
 58         if (full_path == NULL)                    
 59                 return full_path;                 
 60                                                   
 61         if (dfsplen)                              
 62                 memcpy(full_path, tcon->tree_n    
 63         full_path[dfsplen] = CIFS_DIR_SEP(cifs    
 64         memcpy(full_path + dfsplen + 1, ctx->p    
 65         convert_delimiter(full_path, CIFS_DIR_    
 66         return full_path;                         
 67 }                                                 
 68                                                   
 69 /* Note: caller must free return buffer */        
 70 const char *                                      
 71 build_path_from_dentry(struct dentry *direntry    
 72 {                                                 
 73         struct cifs_sb_info *cifs_sb = CIFS_SB    
 74         struct cifs_tcon *tcon = cifs_sb_maste    
 75         bool prefix = tcon->Flags & SMB_SHARE_    
 76                                                   
 77         return build_path_from_dentry_optional    
 78                                                   
 79 }                                                 
 80                                                   
 81 char *__build_path_from_dentry_optional_prefix    
 82                                                   
 83                                                   
 84 {                                                 
 85         int dfsplen;                              
 86         int pplen = 0;                            
 87         struct cifs_sb_info *cifs_sb = CIFS_SB    
 88         char dirsep = CIFS_DIR_SEP(cifs_sb);      
 89         char *s;                                  
 90                                                   
 91         if (unlikely(!page))                      
 92                 return ERR_PTR(-ENOMEM);          
 93                                                   
 94         if (prefix)                               
 95                 dfsplen = strnlen(tree, tree_l    
 96         else                                      
 97                 dfsplen = 0;                      
 98                                                   
 99         if (cifs_sb->mnt_cifs_flags & CIFS_MOU    
100                 pplen = cifs_sb->prepath ? str    
101                                                   
102         s = dentry_path_raw(direntry, page, PA    
103         if (IS_ERR(s))                            
104                 return s;                         
105         if (!s[1])      // for root we want ""    
106                 s++;                              
107         if (s < (char *)page + pplen + dfsplen    
108                 return ERR_PTR(-ENAMETOOLONG);    
109         if (pplen) {                              
110                 cifs_dbg(FYI, "using cifs_sb p    
111                 s -= pplen;                       
112                 memcpy(s + 1, cifs_sb->prepath    
113                 *s = '/';                         
114         }                                         
115         if (dirsep != '/') {                      
116                 /* BB test paths to Windows wi    
117                 char *p;                          
118                                                   
119                 for (p = s; *p; p++)              
120                         if (*p == '/')            
121                                 *p = dirsep;      
122         }                                         
123         if (dfsplen) {                            
124                 s -= dfsplen;                     
125                 memcpy(s, tree, dfsplen);         
126                 if (cifs_sb->mnt_cifs_flags &     
127                         int i;                    
128                         for (i = 0; i < dfsple    
129                                 if (s[i] == '\    
130                                         s[i] =    
131                         }                         
132                 }                                 
133         }                                         
134         return s;                                 
135 }                                                 
136                                                   
137 char *build_path_from_dentry_optional_prefix(s    
138                                              b    
139 {                                                 
140         struct cifs_sb_info *cifs_sb = CIFS_SB    
141         struct cifs_tcon *tcon = cifs_sb_maste    
142                                                   
143         return __build_path_from_dentry_option    
144                                                   
145 }                                                 
146                                                   
147 /*                                                
148  * Don't allow path components longer than the    
149  * Don't allow the separator character in a pa    
150  * The VFS will not allow "/", but "\" is allo    
151  */                                               
152 static int                                        
153 check_name(struct dentry *direntry, struct cif    
154 {                                                 
155         struct cifs_sb_info *cifs_sb = CIFS_SB    
156         int i;                                    
157                                                   
158         if (unlikely(tcon->fsAttrInfo.MaxPathN    
159                      direntry->d_name.len >       
160                      le32_to_cpu(tcon->fsAttrI    
161                 return -ENAMETOOLONG;             
162                                                   
163         if (!(cifs_sb->mnt_cifs_flags & CIFS_M    
164                 for (i = 0; i < direntry->d_na    
165                         if (direntry->d_name.n    
166                                 cifs_dbg(FYI,     
167                                 return -EINVAL    
168                         }                         
169                 }                                 
170         }                                         
171         return 0;                                 
172 }                                                 
173                                                   
174                                                   
175 /* Inode operations in similar order to how th    
176                                                   
177 static int cifs_do_create(struct inode *inode,    
178                           struct tcon_link *tl    
179                           struct cifs_fid *fid    
180 {                                                 
181         int rc = -ENOENT;                         
182         int create_options = CREATE_NOT_DIR;      
183         int desired_access;                       
184         struct cifs_sb_info *cifs_sb = CIFS_SB    
185         struct cifs_tcon *tcon = tlink_tcon(tl    
186         const char *full_path;                    
187         void *page = alloc_dentry_path();         
188         struct inode *newinode = NULL;            
189         int disposition;                          
190         struct TCP_Server_Info *server = tcon-    
191         struct cifs_open_parms oparms;            
192         int rdwr_for_fscache = 0;                 
193                                                   
194         *oplock = 0;                              
195         if (tcon->ses->server->oplocks)           
196                 *oplock = REQ_OPLOCK;             
197                                                   
198         full_path = build_path_from_dentry(dir    
199         if (IS_ERR(full_path)) {                  
200                 free_dentry_path(page);           
201                 return PTR_ERR(full_path);        
202         }                                         
203                                                   
204         /* If we're caching, we need to be abl    
205         if (cifs_fscache_enabled(inode) && (of    
206                 rdwr_for_fscache = 1;             
207                                                   
208 #ifdef CONFIG_CIFS_ALLOW_INSECURE_LEGACY          
209         if (tcon->unix_ext && cap_unix(tcon->s    
210             (CIFS_UNIX_POSIX_PATH_OPS_CAP &       
211                         le64_to_cpu(tcon->fsUn    
212                 rc = cifs_posix_open(full_path    
213                                      oflags, o    
214                 switch (rc) {                     
215                 case 0:                           
216                         if (newinode == NULL)     
217                                 /* query inode    
218                                 goto cifs_crea    
219                         }                         
220                                                   
221                         if (S_ISDIR(newinode->    
222                                 CIFSSMBClose(x    
223                                 iput(newinode)    
224                                 rc = -EISDIR;     
225                                 goto out;         
226                         }                         
227                                                   
228                         if (!S_ISREG(newinode-    
229                                 /*                
230                                  * The server     
231                                  * FIFOs, but     
232                                  * with that.     
233                                  * close it an    
234                                  * lookup.        
235                                  */               
236                                 CIFSSMBClose(x    
237                                 goto cifs_crea    
238                         }                         
239                         /* success, no need to    
240                         goto cifs_create_set_d    
241                                                   
242                 case -ENOENT:                     
243                         goto cifs_create_get_f    
244                                                   
245                 case -EIO:                        
246                 case -EINVAL:                     
247                         /*                        
248                          * EIO could indicate     
249                          * supported, despite     
250                          * negotiation.           
251                          *                        
252                          * POSIX open in samba    
253                          * incorrectly fail wi    
254                          */                       
255                         tcon->broken_posix_ope    
256                         break;                    
257                                                   
258                 case -EREMOTE:                    
259                 case -EOPNOTSUPP:                 
260                         /*                        
261                          * EREMOTE indicates D    
262                          * in posix open.  If     
263                          * returned, follow th    
264                          */                       
265                         break;                    
266                                                   
267                 default:                          
268                         goto out;                 
269                 }                                 
270                 /*                                
271                  * fallthrough to retry, using    
272                  * where server does not suppo    
273                  * claims capability (also get    
274                  * rare for path not covered o    
275                  */                               
276         }                                         
277 #endif /* CONFIG_CIFS_ALLOW_INSECURE_LEGACY */    
278                                                   
279         desired_access = 0;                       
280         if (OPEN_FMODE(oflags) & FMODE_READ)      
281                 desired_access |= GENERIC_READ    
282         if (OPEN_FMODE(oflags) & FMODE_WRITE)     
283                 desired_access |= GENERIC_WRIT    
284         if (rdwr_for_fscache == 1)                
285                 desired_access |= GENERIC_READ    
286                                                   
287         disposition = FILE_OVERWRITE_IF;          
288         if ((oflags & (O_CREAT | O_EXCL)) == (    
289                 disposition = FILE_CREATE;        
290         else if ((oflags & (O_CREAT | O_TRUNC)    
291                 disposition = FILE_OVERWRITE_I    
292         else if ((oflags & O_CREAT) == O_CREAT    
293                 disposition = FILE_OPEN_IF;       
294         else                                      
295                 cifs_dbg(FYI, "Create flag not    
296                                                   
297         /*                                        
298          * BB add processing to set equivalent    
299          * ACLs                                   
300          */                                       
301                                                   
302         if (!server->ops->open) {                 
303                 rc = -ENOSYS;                     
304                 goto out;                         
305         }                                         
306                                                   
307         /*                                        
308          * if we're not using unix extensions,    
309          * ATTR_READONLY on the create call       
310          */                                       
311         if (!tcon->unix_ext && (mode & S_IWUGO    
312                 create_options |= CREATE_OPTIO    
313                                                   
314 retry_open:                                       
315         oparms = (struct cifs_open_parms) {       
316                 .tcon = tcon,                     
317                 .cifs_sb = cifs_sb,               
318                 .desired_access = desired_acce    
319                 .create_options = cifs_create_    
320                 .disposition = disposition,       
321                 .path = full_path,                
322                 .fid = fid,                       
323                 .mode = mode,                     
324         };                                        
325         rc = server->ops->open(xid, &oparms, o    
326         if (rc) {                                 
327                 cifs_dbg(FYI, "cifs_create ret    
328                 if (rc == -EACCES && rdwr_for_    
329                         desired_access &= ~GEN    
330                         rdwr_for_fscache = 2;     
331                         goto retry_open;          
332                 }                                 
333                 goto out;                         
334         }                                         
335         if (rdwr_for_fscache == 2)                
336                 cifs_invalidate_cache(inode, F    
337                                                   
338 #ifdef CONFIG_CIFS_ALLOW_INSECURE_LEGACY          
339         /*                                        
340          * If Open reported that we actually c    
341          * set the mode if possible.              
342          */                                       
343         if ((tcon->unix_ext) && (*oplock & CIF    
344                 struct cifs_unix_set_info_args    
345                                 .mode   = mode    
346                                 .ctime  = NO_C    
347                                 .atime  = NO_C    
348                                 .mtime  = NO_C    
349                                 .device = 0,      
350                 };                                
351                                                   
352                 if (cifs_sb->mnt_cifs_flags &     
353                         args.uid = current_fsu    
354                         if (inode->i_mode & S_    
355                                 args.gid = ino    
356                         else                      
357                                 args.gid = cur    
358                 } else {                          
359                         args.uid = INVALID_UID    
360                         args.gid = INVALID_GID    
361                 }                                 
362                 CIFSSMBUnixSetFileInfo(xid, tc    
363                                        current    
364         } else {                                  
365                 /*                                
366                  * BB implement mode setting v    
367                  * descriptors e.g.               
368                  */                               
369                 /* CIFSSMBWinSetPerms(xid,tcon    
370                                                   
371                 /* Could set r/o dos attribute    
372         }                                         
373                                                   
374 cifs_create_get_file_info:                        
375         /* server might mask mode so we have t    
376         if (tcon->unix_ext)                       
377                 rc = cifs_get_inode_info_unix(    
378                                                   
379         else {                                    
380 #else                                             
381         {                                         
382 #endif /* CONFIG_CIFS_ALLOW_INSECURE_LEGACY */    
383                 /* TODO: Add support for calli    
384                 rc = cifs_get_inode_info(&newi    
385                 if (newinode) {                   
386                         if (server->ops->set_l    
387                                 server->ops->s    
388                         if ((*oplock & CIFS_CR    
389                                 if (cifs_sb->m    
390                                         newino    
391                                 if (cifs_sb->m    
392                                         newino    
393                                         if (in    
394                                                   
395                                         else      
396                                                   
397                                 }                 
398                         }                         
399                 }                                 
400         }                                         
401                                                   
402 #ifdef CONFIG_CIFS_ALLOW_INSECURE_LEGACY          
403 cifs_create_set_dentry:                           
404 #endif /* CONFIG_CIFS_ALLOW_INSECURE_LEGACY */    
405         if (rc != 0) {                            
406                 cifs_dbg(FYI, "Create worked,     
407                          rc);                     
408                 goto out_err;                     
409         }                                         
410                                                   
411         if (newinode)                             
412                 if (S_ISDIR(newinode->i_mode))    
413                         rc = -EISDIR;             
414                         goto out_err;             
415                 }                                 
416                                                   
417         d_drop(direntry);                         
418         d_add(direntry, newinode);                
419                                                   
420 out:                                              
421         free_dentry_path(page);                   
422         return rc;                                
423                                                   
424 out_err:                                          
425         if (server->ops->close)                   
426                 server->ops->close(xid, tcon,     
427         if (newinode)                             
428                 iput(newinode);                   
429         goto out;                                 
430 }                                                 
431                                                   
432 int                                               
433 cifs_atomic_open(struct inode *inode, struct d    
434                  struct file *file, unsigned o    
435 {                                                 
436         int rc;                                   
437         unsigned int xid;                         
438         struct tcon_link *tlink;                  
439         struct cifs_tcon *tcon;                   
440         struct TCP_Server_Info *server;           
441         struct cifs_fid fid = {};                 
442         struct cifs_pending_open open;            
443         __u32 oplock;                             
444         struct cifsFileInfo *file_info;           
445         struct cifs_open_info_data buf = {};      
446                                                   
447         if (unlikely(cifs_forced_shutdown(CIFS    
448                 return -EIO;                      
449                                                   
450         /*                                        
451          * Posix open is only called (at looku    
452          * opens (rather than creates), becaus    
453          * or directory yet, and current Samba    
454          * open on dirs, we could end up wasti    
455          * to be a dir. For file opens, we wai    
456          * cifs_open.  It could be added to at    
457          * performance tradeoff of the extra n    
458          * EACCES is returned would have to be    
459          * in network traffic in the other pat    
460          */                                       
461         if (!(oflags & O_CREAT)) {                
462                 struct dentry *res;               
463                                                   
464                 /*                                
465                  * Check for hashed negative d    
466                  * the dentry and it is fine.     
467                  */                               
468                 if (!d_in_lookup(direntry))       
469                         return -ENOENT;           
470                                                   
471                 res = cifs_lookup(inode, diren    
472                 if (IS_ERR(res))                  
473                         return PTR_ERR(res);      
474                                                   
475                 return finish_no_open(file, re    
476         }                                         
477                                                   
478         xid = get_xid();                          
479                                                   
480         cifs_dbg(FYI, "parent inode = 0x%p nam    
481                  inode, direntry, direntry);      
482                                                   
483         tlink = cifs_sb_tlink(CIFS_SB(inode->i    
484         if (IS_ERR(tlink)) {                      
485                 rc = PTR_ERR(tlink);              
486                 goto out_free_xid;                
487         }                                         
488                                                   
489         tcon = tlink_tcon(tlink);                 
490                                                   
491         rc = check_name(direntry, tcon);          
492         if (rc)                                   
493                 goto out;                         
494                                                   
495         server = tcon->ses->server;               
496                                                   
497         if (server->ops->new_lease_key)           
498                 server->ops->new_lease_key(&fi    
499                                                   
500         cifs_add_pending_open(&fid, tlink, &op    
501                                                   
502         rc = cifs_do_create(inode, direntry, x    
503                             &oplock, &fid, &bu    
504         if (rc) {                                 
505                 cifs_del_pending_open(&open);     
506                 goto out;                         
507         }                                         
508                                                   
509         if ((oflags & (O_CREAT | O_EXCL)) == (    
510                 file->f_mode |= FMODE_CREATED;    
511                                                   
512         rc = finish_open(file, direntry, gener    
513         if (rc) {                                 
514                 if (server->ops->close)           
515                         server->ops->close(xid    
516                 cifs_del_pending_open(&open);     
517                 goto out;                         
518         }                                         
519                                                   
520         if (file->f_flags & O_DIRECT &&           
521             CIFS_SB(inode->i_sb)->mnt_cifs_fla    
522                 if (CIFS_SB(inode->i_sb)->mnt_    
523                         file->f_op = &cifs_fil    
524                 else                              
525                         file->f_op = &cifs_fil    
526                 }                                 
527                                                   
528         file_info = cifs_new_fileinfo(&fid, fi    
529         if (file_info == NULL) {                  
530                 if (server->ops->close)           
531                         server->ops->close(xid    
532                 cifs_del_pending_open(&open);     
533                 rc = -ENOMEM;                     
534                 goto out;                         
535         }                                         
536                                                   
537         fscache_use_cookie(cifs_inode_cookie(f    
538                            file->f_mode & FMOD    
539                                                   
540 out:                                              
541         cifs_put_tlink(tlink);                    
542 out_free_xid:                                     
543         free_xid(xid);                            
544         cifs_free_open_info(&buf);                
545         return rc;                                
546 }                                                 
547                                                   
548 int cifs_create(struct mnt_idmap *idmap, struc    
549                 struct dentry *direntry, umode    
550 {                                                 
551         int rc;                                   
552         unsigned int xid = get_xid();             
553         /*                                        
554          * BB below access is probably too muc    
555          *    but we have to do query and setp    
556          *    less could fail (unless we want     
557          *    permissions (only).  At least fo    
558          *    request so much.                    
559          */                                       
560         unsigned oflags = O_EXCL | O_CREAT | O    
561         struct tcon_link *tlink;                  
562         struct cifs_tcon *tcon;                   
563         struct TCP_Server_Info *server;           
564         struct cifs_fid fid;                      
565         __u32 oplock;                             
566         struct cifs_open_info_data buf = {};      
567                                                   
568         cifs_dbg(FYI, "cifs_create parent inod    
569                  inode, direntry, direntry);      
570                                                   
571         if (unlikely(cifs_forced_shutdown(CIFS    
572                 rc = -EIO;                        
573                 goto out_free_xid;                
574         }                                         
575                                                   
576         tlink = cifs_sb_tlink(CIFS_SB(inode->i    
577         rc = PTR_ERR(tlink);                      
578         if (IS_ERR(tlink))                        
579                 goto out_free_xid;                
580                                                   
581         tcon = tlink_tcon(tlink);                 
582         server = tcon->ses->server;               
583                                                   
584         if (server->ops->new_lease_key)           
585                 server->ops->new_lease_key(&fi    
586                                                   
587         rc = cifs_do_create(inode, direntry, x    
588         if (!rc && server->ops->close)            
589                 server->ops->close(xid, tcon,     
590                                                   
591         cifs_free_open_info(&buf);                
592         cifs_put_tlink(tlink);                    
593 out_free_xid:                                     
594         free_xid(xid);                            
595         return rc;                                
596 }                                                 
597                                                   
598 int cifs_mknod(struct mnt_idmap *idmap, struct    
599                struct dentry *direntry, umode_    
600 {                                                 
601         int rc = -EPERM;                          
602         unsigned int xid;                         
603         struct cifs_sb_info *cifs_sb;             
604         struct tcon_link *tlink;                  
605         struct cifs_tcon *tcon;                   
606         const char *full_path;                    
607         void *page;                               
608                                                   
609         if (!old_valid_dev(device_number))        
610                 return -EINVAL;                   
611                                                   
612         cifs_sb = CIFS_SB(inode->i_sb);           
613         if (unlikely(cifs_forced_shutdown(cifs    
614                 return -EIO;                      
615                                                   
616         tlink = cifs_sb_tlink(cifs_sb);           
617         if (IS_ERR(tlink))                        
618                 return PTR_ERR(tlink);            
619                                                   
620         page = alloc_dentry_path();               
621         tcon = tlink_tcon(tlink);                 
622         xid = get_xid();                          
623                                                   
624         full_path = build_path_from_dentry(dir    
625         if (IS_ERR(full_path)) {                  
626                 rc = PTR_ERR(full_path);          
627                 goto mknod_out;                   
628         }                                         
629                                                   
630         trace_smb3_mknod_enter(xid, tcon->ses-    
631                                                   
632         rc = tcon->ses->server->ops->make_node    
633                                                   
634                                                   
635                                                   
636 mknod_out:                                        
637         if (rc)                                   
638                 trace_smb3_mknod_err(xid,  tco    
639         else                                      
640                 trace_smb3_mknod_done(xid, tco    
641                                                   
642         free_dentry_path(page);                   
643         free_xid(xid);                            
644         cifs_put_tlink(tlink);                    
645         return rc;                                
646 }                                                 
647                                                   
648 struct dentry *                                   
649 cifs_lookup(struct inode *parent_dir_inode, st    
650             unsigned int flags)                   
651 {                                                 
652         unsigned int xid;                         
653         int rc = 0; /* to get around spurious     
654         struct cifs_sb_info *cifs_sb;             
655         struct tcon_link *tlink;                  
656         struct cifs_tcon *pTcon;                  
657         struct inode *newInode = NULL;            
658         const char *full_path;                    
659         void *page;                               
660         int retry_count = 0;                      
661                                                   
662         xid = get_xid();                          
663                                                   
664         cifs_dbg(FYI, "parent inode = 0x%p nam    
665                  parent_dir_inode, direntry, d    
666                                                   
667         /* check whether path exists */           
668                                                   
669         cifs_sb = CIFS_SB(parent_dir_inode->i_    
670         tlink = cifs_sb_tlink(cifs_sb);           
671         if (IS_ERR(tlink)) {                      
672                 free_xid(xid);                    
673                 return ERR_CAST(tlink);           
674         }                                         
675         pTcon = tlink_tcon(tlink);                
676                                                   
677         rc = check_name(direntry, pTcon);         
678         if (unlikely(rc)) {                       
679                 cifs_put_tlink(tlink);            
680                 free_xid(xid);                    
681                 return ERR_PTR(rc);               
682         }                                         
683                                                   
684         /* can not grab the rename sem here si    
685         deadlock in the cases (beginning of sy    
686         in which we already have the sb rename    
687         page = alloc_dentry_path();               
688         full_path = build_path_from_dentry(dir    
689         if (IS_ERR(full_path)) {                  
690                 cifs_put_tlink(tlink);            
691                 free_xid(xid);                    
692                 free_dentry_path(page);           
693                 return ERR_CAST(full_path);       
694         }                                         
695                                                   
696         if (d_really_is_positive(direntry)) {     
697                 cifs_dbg(FYI, "non-NULL inode     
698         } else {                                  
699                 cifs_dbg(FYI, "NULL inode in l    
700         }                                         
701         cifs_dbg(FYI, "Full path: %s inode = 0    
702                  full_path, d_inode(direntry))    
703                                                   
704 again:                                            
705         if (pTcon->posix_extensions) {            
706                 rc = smb311_posix_get_inode_in    
707                                                   
708         } else if (pTcon->unix_ext) {             
709                 rc = cifs_get_inode_info_unix(    
710                                                   
711         } else {                                  
712                 rc = cifs_get_inode_info(&newI    
713                                 parent_dir_ino    
714         }                                         
715                                                   
716         if (rc == 0) {                            
717                 /* since paths are not looked     
718                    directories are presumed to    
719                 renew_parental_timestamps(dire    
720         } else if (rc == -EAGAIN && retry_coun    
721                 goto again;                       
722         } else if (rc == -ENOENT) {               
723                 cifs_set_time(direntry, jiffie    
724                 newInode = NULL;                  
725         } else {                                  
726                 if (rc != -EACCES) {              
727                         cifs_dbg(FYI, "Unexpec    
728                         /* We special case che    
729                         is a common return cod    
730                 }                                 
731                 newInode = ERR_PTR(rc);           
732         }                                         
733         free_dentry_path(page);                   
734         cifs_put_tlink(tlink);                    
735         free_xid(xid);                            
736         return d_splice_alias(newInode, dirent    
737 }                                                 
738                                                   
739 static int                                        
740 cifs_d_revalidate(struct dentry *direntry, uns    
741 {                                                 
742         struct inode *inode;                      
743         int rc;                                   
744                                                   
745         if (flags & LOOKUP_RCU)                   
746                 return -ECHILD;                   
747                                                   
748         if (d_really_is_positive(direntry)) {     
749                 inode = d_inode(direntry);        
750                 if ((flags & LOOKUP_REVAL) &&     
751                         CIFS_I(inode)->time =     
752                                                   
753                 rc = cifs_revalidate_dentry(di    
754                 if (rc) {                         
755                         cifs_dbg(FYI, "cifs_re    
756                         switch (rc) {             
757                         case -ENOENT:             
758                         case -ESTALE:             
759                                 /*                
760                                  * Those error    
761                                  * (file was d    
762                                  */               
763                                 return 0;         
764                         default:                  
765                                 /*                
766                                  * Otherwise s    
767                                  * report it a    
768                                  */               
769                                 return rc;        
770                         }                         
771                 }                                 
772                 else {                            
773                         /*                        
774                          * If the inode wasn't    
775                          * the dentry was inst    
776                          * via ->readdir(), it    
777                          * attributes will hav    
778                          * cifs_revalidate_den    
779                          */                       
780                         if (IS_AUTOMOUNT(inode    
781                            !(direntry->d_flags    
782                                 spin_lock(&dir    
783                                 direntry->d_fl    
784                                 spin_unlock(&d    
785                         }                         
786                                                   
787                         return 1;                 
788                 }                                 
789         }                                         
790                                                   
791         /*                                        
792          * This may be nfsd (or something), an    
793          * intent of this. So, since this can     
794          */                                       
795         if (!flags)                               
796                 return 0;                         
797                                                   
798         /*                                        
799          * Drop the negative dentry, in order     
800          * case sensitive name which is specif    
801          * for creation.                          
802          */                                       
803         if (flags & (LOOKUP_CREATE | LOOKUP_RE    
804                 return 0;                         
805                                                   
806         if (time_after(jiffies, cifs_get_time(    
807                 return 0;                         
808                                                   
809         return 1;                                 
810 }                                                 
811                                                   
812 /* static int cifs_d_delete(struct dentry *dir    
813 {                                                 
814         int rc = 0;                               
815                                                   
816         cifs_dbg(FYI, "In cifs d_delete, name     
817                                                   
818         return rc;                                
819 }     */                                          
820                                                   
821 const struct dentry_operations cifs_dentry_ops    
822         .d_revalidate = cifs_d_revalidate,        
823         .d_automount = cifs_d_automount,          
824 /* d_delete:       cifs_d_delete,      */ /* n    
825 };                                                
826                                                   
827 static int cifs_ci_hash(const struct dentry *d    
828 {                                                 
829         struct nls_table *codepage = CIFS_SB(d    
830         unsigned long hash;                       
831         wchar_t c;                                
832         int i, charlen;                           
833                                                   
834         hash = init_name_hash(dentry);            
835         for (i = 0; i < q->len; i += charlen)     
836                 charlen = codepage->char2uni(&    
837                 /* error out if we can't conve    
838                 if (unlikely(charlen < 0))        
839                         return charlen;           
840                 hash = partial_name_hash(cifs_    
841         }                                         
842         q->hash = end_name_hash(hash);            
843                                                   
844         return 0;                                 
845 }                                                 
846                                                   
847 static int cifs_ci_compare(const struct dentry    
848                 unsigned int len, const char *    
849 {                                                 
850         struct nls_table *codepage = CIFS_SB(d    
851         wchar_t c1, c2;                           
852         int i, l1, l2;                            
853                                                   
854         /*                                        
855          * We make the assumption here that up    
856          * codepage are always the same length    
857          *                                        
858          * If that's ever not the case, then t    
859          */                                       
860         if (name->len != len)                     
861                 return 1;                         
862                                                   
863         for (i = 0; i < len; i += l1) {           
864                 /* Convert characters in both     
865                 l1 = codepage->char2uni(&str[i    
866                 l2 = codepage->char2uni(&name-    
867                                                   
868                 /*                                
869                  * If we can't convert either     
870                  * be 1 byte long and compare     
871                  */                               
872                 if (unlikely(l1 < 0 && l2 < 0)    
873                         if (str[i] != name->na    
874                                 return 1;         
875                         l1 = 1;                   
876                         continue;                 
877                 }                                 
878                                                   
879                 /*                                
880                  * Here, we again ass|u|me tha    
881                  * a character are the same le    
882                  */                               
883                 if (l1 != l2)                     
884                         return 1;                 
885                                                   
886                 /* Now compare uppercase versi    
887                 if (cifs_toupper(c1) != cifs_t    
888                         return 1;                 
889         }                                         
890                                                   
891         return 0;                                 
892 }                                                 
893                                                   
894 const struct dentry_operations cifs_ci_dentry_    
895         .d_revalidate = cifs_d_revalidate,        
896         .d_hash = cifs_ci_hash,                   
897         .d_compare = cifs_ci_compare,             
898         .d_automount = cifs_d_automount,          
899 };                                                
900                                                   

~ [ source navigation ] ~ [ diff markup ] ~ [ identifier search ] ~

kernel.org | git.kernel.org | LWN.net | Project Home | SVN repository | Mail admin

Linux® is a registered trademark of Linus Torvalds in the United States and other countries.
TOMOYO® is a registered trademark of NTT DATA CORPORATION.

sflogo.php