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

TOMOYO Linux Cross Reference
Linux/fs/jfs/namei.c

Version: ~ [ linux-6.11.5 ] ~ [ linux-6.10.14 ] ~ [ linux-6.9.12 ] ~ [ linux-6.8.12 ] ~ [ linux-6.7.12 ] ~ [ linux-6.6.58 ] ~ [ linux-6.5.13 ] ~ [ linux-6.4.16 ] ~ [ linux-6.3.13 ] ~ [ linux-6.2.16 ] ~ [ linux-6.1.114 ] ~ [ linux-6.0.19 ] ~ [ linux-5.19.17 ] ~ [ linux-5.18.19 ] ~ [ linux-5.17.15 ] ~ [ linux-5.16.20 ] ~ [ linux-5.15.169 ] ~ [ linux-5.14.21 ] ~ [ linux-5.13.19 ] ~ [ linux-5.12.19 ] ~ [ linux-5.11.22 ] ~ [ linux-5.10.228 ] ~ [ linux-5.9.16 ] ~ [ linux-5.8.18 ] ~ [ linux-5.7.19 ] ~ [ linux-5.6.19 ] ~ [ linux-5.5.19 ] ~ [ linux-5.4.284 ] ~ [ linux-5.3.18 ] ~ [ linux-5.2.21 ] ~ [ linux-5.1.21 ] ~ [ linux-5.0.21 ] ~ [ linux-4.20.17 ] ~ [ linux-4.19.322 ] ~ [ 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.9 ] ~ [ policy-sample ] ~
Architecture: ~ [ i386 ] ~ [ alpha ] ~ [ m68k ] ~ [ mips ] ~ [ ppc ] ~ [ sparc ] ~ [ sparc64 ] ~

Diff markup

Differences between /fs/jfs/namei.c (Version linux-6.11.5) and /fs/jfs/namei.c (Version linux-4.19.319)


** Warning: Cannot open xref database.

  1 // SPDX-License-Identifier: GPL-2.0-or-later        1 
  2 /*                                                
  3  *   Copyright (C) International Business Mach    
  4  *   Portions Copyright (C) Christoph Hellwig,    
  5  */                                               
  6                                                   
  7 #include <linux/fs.h>                             
  8 #include <linux/namei.h>                          
  9 #include <linux/ctype.h>                          
 10 #include <linux/quotaops.h>                       
 11 #include <linux/exportfs.h>                       
 12 #include "jfs_incore.h"                           
 13 #include "jfs_superblock.h"                       
 14 #include "jfs_inode.h"                            
 15 #include "jfs_dinode.h"                           
 16 #include "jfs_dmap.h"                             
 17 #include "jfs_unicode.h"                          
 18 #include "jfs_metapage.h"                         
 19 #include "jfs_xattr.h"                            
 20 #include "jfs_acl.h"                              
 21 #include "jfs_debug.h"                            
 22                                                   
 23 /*                                                
 24  * forward references                             
 25  */                                               
 26 const struct dentry_operations jfs_ci_dentry_o    
 27                                                   
 28 static s64 commitZeroLink(tid_t, struct inode     
 29                                                   
 30 /*                                                
 31  * NAME:        free_ea_wmap(inode)               
 32  *                                                
 33  * FUNCTION:    free uncommitted extended attr    
 34  *                                                
 35  */                                               
 36 static inline void free_ea_wmap(struct inode *    
 37 {                                                 
 38         dxd_t *ea = &JFS_IP(inode)->ea;           
 39                                                   
 40         if (ea->flag & DXD_EXTENT) {              
 41                 /* free EA pages from cache */    
 42                 invalidate_dxd_metapages(inode    
 43                 dbFree(inode, addressDXD(ea),     
 44         }                                         
 45         ea->flag = 0;                             
 46 }                                                 
 47                                                   
 48 /*                                                
 49  * NAME:        jfs_create(dip, dentry, mode)     
 50  *                                                
 51  * FUNCTION:    create a regular file in the p    
 52  *              with name = <from dentry> and     
 53  *                                                
 54  * PARAMETER:   dip     - parent directory vno    
 55  *              dentry  - dentry of new file      
 56  *              mode    - create mode (rwxrwxr    
 57  *              nd- nd struct                     
 58  *                                                
 59  * RETURN:      Errors from subroutines           
 60  *                                                
 61  */                                               
 62 static int jfs_create(struct mnt_idmap *idmap,    
 63                       struct dentry *dentry, u    
 64 {                                                 
 65         int rc = 0;                               
 66         tid_t tid;              /* transaction    
 67         struct inode *ip = NULL;        /* chi    
 68         ino_t ino;                                
 69         struct component_name dname;    /* chi    
 70         struct btstack btstack;                   
 71         struct inode *iplist[2];                  
 72         struct tblock *tblk;                      
 73                                                   
 74         jfs_info("jfs_create: dip:0x%p name:%p    
 75                                                   
 76         rc = dquot_initialize(dip);               
 77         if (rc)                                   
 78                 goto out1;                        
 79                                                   
 80         /*                                        
 81          * search parent directory for entry/f    
 82          * (dtSearch() returns parent director    
 83          */                                       
 84         if ((rc = get_UCSname(&dname, dentry))    
 85                 goto out1;                        
 86                                                   
 87         /*                                        
 88          * Either iAlloc() or txBegin() may bl    
 89          * block there while holding dtree pag    
 90          * begin the transaction before we sea    
 91          */                                       
 92         ip = ialloc(dip, mode);                   
 93         if (IS_ERR(ip)) {                         
 94                 rc = PTR_ERR(ip);                 
 95                 goto out2;                        
 96         }                                         
 97                                                   
 98         tid = txBegin(dip->i_sb, 0);              
 99                                                   
100         mutex_lock_nested(&JFS_IP(dip)->commit    
101         mutex_lock_nested(&JFS_IP(ip)->commit_    
102                                                   
103         rc = jfs_init_acl(tid, ip, dip);          
104         if (rc)                                   
105                 goto out3;                        
106                                                   
107         rc = jfs_init_security(tid, ip, dip, &    
108         if (rc) {                                 
109                 txAbort(tid, 0);                  
110                 goto out3;                        
111         }                                         
112                                                   
113         if ((rc = dtSearch(dip, &dname, &ino,     
114                 jfs_err("jfs_create: dtSearch     
115                 txAbort(tid, 0);                  
116                 goto out3;                        
117         }                                         
118                                                   
119         tblk = tid_to_tblock(tid);                
120         tblk->xflag |= COMMIT_CREATE;             
121         tblk->ino = ip->i_ino;                    
122         tblk->u.ixpxd = JFS_IP(ip)->ixpxd;        
123                                                   
124         iplist[0] = dip;                          
125         iplist[1] = ip;                           
126                                                   
127         /*                                        
128          * initialize the child XAD tree root     
129          */                                       
130         xtInitRoot(tid, ip);                      
131                                                   
132         /*                                        
133          * create entry in parent directory fo    
134          * (dtInsert() releases parent directo    
135          */                                       
136         ino = ip->i_ino;                          
137         if ((rc = dtInsert(tid, dip, &dname, &    
138                 if (rc == -EIO) {                 
139                         jfs_err("jfs_create: d    
140                         txAbort(tid, 1);          
141                 } else                            
142                         txAbort(tid, 0);          
143                 goto out3;                        
144         }                                         
145                                                   
146         ip->i_op = &jfs_file_inode_operations;    
147         ip->i_fop = &jfs_file_operations;         
148         ip->i_mapping->a_ops = &jfs_aops;         
149                                                   
150         mark_inode_dirty(ip);                     
151                                                   
152         inode_set_mtime_to_ts(dip, inode_set_c    
153                                                   
154         mark_inode_dirty(dip);                    
155                                                   
156         rc = txCommit(tid, 2, &iplist[0], 0);     
157                                                   
158       out3:                                       
159         txEnd(tid);                               
160         mutex_unlock(&JFS_IP(ip)->commit_mutex    
161         mutex_unlock(&JFS_IP(dip)->commit_mute    
162         if (rc) {                                 
163                 free_ea_wmap(ip);                 
164                 clear_nlink(ip);                  
165                 discard_new_inode(ip);            
166         } else {                                  
167                 d_instantiate_new(dentry, ip);    
168         }                                         
169                                                   
170       out2:                                       
171         free_UCSname(&dname);                     
172                                                   
173       out1:                                       
174                                                   
175         jfs_info("jfs_create: rc:%d", rc);        
176         return rc;                                
177 }                                                 
178                                                   
179                                                   
180 /*                                                
181  * NAME:        jfs_mkdir(dip, dentry, mode)      
182  *                                                
183  * FUNCTION:    create a child directory in th    
184  *              with name = <from dentry> and     
185  *                                                
186  * PARAMETER:   dip     - parent directory vno    
187  *              dentry  - dentry of child dire    
188  *              mode    - create mode (rwxrwxr    
189  *                                                
190  * RETURN:      Errors from subroutines           
191  *                                                
192  * note:                                          
193  * EACCES: user needs search+write permission     
194  */                                               
195 static int jfs_mkdir(struct mnt_idmap *idmap,     
196                      struct dentry *dentry, um    
197 {                                                 
198         int rc = 0;                               
199         tid_t tid;              /* transaction    
200         struct inode *ip = NULL;        /* chi    
201         ino_t ino;                                
202         struct component_name dname;    /* chi    
203         struct btstack btstack;                   
204         struct inode *iplist[2];                  
205         struct tblock *tblk;                      
206                                                   
207         jfs_info("jfs_mkdir: dip:0x%p name:%pd    
208                                                   
209         rc = dquot_initialize(dip);               
210         if (rc)                                   
211                 goto out1;                        
212                                                   
213         /*                                        
214          * search parent directory for entry/f    
215          * (dtSearch() returns parent director    
216          */                                       
217         if ((rc = get_UCSname(&dname, dentry))    
218                 goto out1;                        
219                                                   
220         /*                                        
221          * Either iAlloc() or txBegin() may bl    
222          * block there while holding dtree pag    
223          * begin the transaction before we sea    
224          */                                       
225         ip = ialloc(dip, S_IFDIR | mode);         
226         if (IS_ERR(ip)) {                         
227                 rc = PTR_ERR(ip);                 
228                 goto out2;                        
229         }                                         
230                                                   
231         tid = txBegin(dip->i_sb, 0);              
232                                                   
233         mutex_lock_nested(&JFS_IP(dip)->commit    
234         mutex_lock_nested(&JFS_IP(ip)->commit_    
235                                                   
236         rc = jfs_init_acl(tid, ip, dip);          
237         if (rc)                                   
238                 goto out3;                        
239                                                   
240         rc = jfs_init_security(tid, ip, dip, &    
241         if (rc) {                                 
242                 txAbort(tid, 0);                  
243                 goto out3;                        
244         }                                         
245                                                   
246         if ((rc = dtSearch(dip, &dname, &ino,     
247                 jfs_err("jfs_mkdir: dtSearch r    
248                 txAbort(tid, 0);                  
249                 goto out3;                        
250         }                                         
251                                                   
252         tblk = tid_to_tblock(tid);                
253         tblk->xflag |= COMMIT_CREATE;             
254         tblk->ino = ip->i_ino;                    
255         tblk->u.ixpxd = JFS_IP(ip)->ixpxd;        
256                                                   
257         iplist[0] = dip;                          
258         iplist[1] = ip;                           
259                                                   
260         /*                                        
261          * initialize the child directory in-l    
262          */                                       
263         dtInitRoot(tid, ip, dip->i_ino);          
264                                                   
265         /*                                        
266          * create entry in parent directory fo    
267          * (dtInsert() releases parent directo    
268          */                                       
269         ino = ip->i_ino;                          
270         if ((rc = dtInsert(tid, dip, &dname, &    
271                 if (rc == -EIO) {                 
272                         jfs_err("jfs_mkdir: dt    
273                         txAbort(tid, 1);          
274                 } else                            
275                         txAbort(tid, 0);          
276                 goto out3;                        
277         }                                         
278                                                   
279         set_nlink(ip, 2);       /* for '.' */     
280         ip->i_op = &jfs_dir_inode_operations;     
281         ip->i_fop = &jfs_dir_operations;          
282                                                   
283         mark_inode_dirty(ip);                     
284                                                   
285         /* update parent directory inode */       
286         inc_nlink(dip);         /* for '..' fr    
287         inode_set_mtime_to_ts(dip, inode_set_c    
288         mark_inode_dirty(dip);                    
289                                                   
290         rc = txCommit(tid, 2, &iplist[0], 0);     
291                                                   
292       out3:                                       
293         txEnd(tid);                               
294         mutex_unlock(&JFS_IP(ip)->commit_mutex    
295         mutex_unlock(&JFS_IP(dip)->commit_mute    
296         if (rc) {                                 
297                 free_ea_wmap(ip);                 
298                 clear_nlink(ip);                  
299                 discard_new_inode(ip);            
300         } else {                                  
301                 d_instantiate_new(dentry, ip);    
302         }                                         
303                                                   
304       out2:                                       
305         free_UCSname(&dname);                     
306                                                   
307                                                   
308       out1:                                       
309                                                   
310         jfs_info("jfs_mkdir: rc:%d", rc);         
311         return rc;                                
312 }                                                 
313                                                   
314 /*                                                
315  * NAME:        jfs_rmdir(dip, dentry)            
316  *                                                
317  * FUNCTION:    remove a link to child directo    
318  *                                                
319  * PARAMETER:   dip     - parent inode            
320  *              dentry  - child directory dent    
321  *                                                
322  * RETURN:      -EINVAL - if name is . or ..      
323  *              -EINVAL - if . or .. exist but    
324  *              errors from subroutines           
325  *                                                
326  * note:                                          
327  * if other threads have the directory open wh    
328  * is removed, the "." and ".." entries, if pr    
329  * rmdir() returns and no new entries may be c    
330  * but the directory is not removed until the     
331  * the directory is released (cf.unlink() of r    
332  */                                               
333 static int jfs_rmdir(struct inode *dip, struct    
334 {                                                 
335         int rc;                                   
336         tid_t tid;              /* transaction    
337         struct inode *ip = d_inode(dentry);       
338         ino_t ino;                                
339         struct component_name dname;              
340         struct inode *iplist[2];                  
341         struct tblock *tblk;                      
342                                                   
343         jfs_info("jfs_rmdir: dip:0x%p name:%pd    
344                                                   
345         /* Init inode for quota operations. */    
346         rc = dquot_initialize(dip);               
347         if (rc)                                   
348                 goto out;                         
349         rc = dquot_initialize(ip);                
350         if (rc)                                   
351                 goto out;                         
352                                                   
353         /* directory must be empty to be remov    
354         if (!dtEmpty(ip)) {                       
355                 rc = -ENOTEMPTY;                  
356                 goto out;                         
357         }                                         
358                                                   
359         if ((rc = get_UCSname(&dname, dentry))    
360                 goto out;                         
361         }                                         
362                                                   
363         tid = txBegin(dip->i_sb, 0);              
364                                                   
365         mutex_lock_nested(&JFS_IP(dip)->commit    
366         mutex_lock_nested(&JFS_IP(ip)->commit_    
367                                                   
368         iplist[0] = dip;                          
369         iplist[1] = ip;                           
370                                                   
371         tblk = tid_to_tblock(tid);                
372         tblk->xflag |= COMMIT_DELETE;             
373         tblk->u.ip = ip;                          
374                                                   
375         /*                                        
376          * delete the entry of target director    
377          */                                       
378         ino = ip->i_ino;                          
379         if ((rc = dtDelete(tid, dip, &dname, &    
380                 jfs_err("jfs_rmdir: dtDelete r    
381                 if (rc == -EIO)                   
382                         txAbort(tid, 1);          
383                 txEnd(tid);                       
384                 mutex_unlock(&JFS_IP(ip)->comm    
385                 mutex_unlock(&JFS_IP(dip)->com    
386                                                   
387                 goto out2;                        
388         }                                         
389                                                   
390         /* update parent directory's link coun    
391          * to ".." entry of the target directo    
392          */                                       
393         inode_set_mtime_to_ts(dip, inode_set_c    
394         inode_dec_link_count(dip);                
395                                                   
396         /*                                        
397          * OS/2 could have created EA and/or A    
398          */                                       
399         /* free EA from both persistent and wo    
400         if (JFS_IP(ip)->ea.flag & DXD_EXTENT)     
401                 /* free EA pages */               
402                 txEA(tid, ip, &JFS_IP(ip)->ea,    
403         }                                         
404         JFS_IP(ip)->ea.flag = 0;                  
405                                                   
406         /* free ACL from both persistent and w    
407         if (JFS_IP(ip)->acl.flag & DXD_EXTENT)    
408                 /* free ACL pages */              
409                 txEA(tid, ip, &JFS_IP(ip)->acl    
410         }                                         
411         JFS_IP(ip)->acl.flag = 0;                 
412                                                   
413         /* mark the target directory as delete    
414         clear_nlink(ip);                          
415         mark_inode_dirty(ip);                     
416                                                   
417         rc = txCommit(tid, 2, &iplist[0], 0);     
418                                                   
419         txEnd(tid);                               
420                                                   
421         mutex_unlock(&JFS_IP(ip)->commit_mutex    
422         mutex_unlock(&JFS_IP(dip)->commit_mute    
423                                                   
424         /*                                        
425          * Truncating the directory index tabl    
426          * may need to be done iteratively        
427          */                                       
428         if (test_cflag(COMMIT_Stale, dip)) {      
429                 if (dip->i_size > 1)              
430                         jfs_truncate_nolock(di    
431                                                   
432                 clear_cflag(COMMIT_Stale, dip)    
433         }                                         
434                                                   
435       out2:                                       
436         free_UCSname(&dname);                     
437                                                   
438       out:                                        
439         jfs_info("jfs_rmdir: rc:%d", rc);         
440         return rc;                                
441 }                                                 
442                                                   
443 /*                                                
444  * NAME:        jfs_unlink(dip, dentry)           
445  *                                                
446  * FUNCTION:    remove a link to object <vp> n    
447  *              from parent directory <dvp>       
448  *                                                
449  * PARAMETER:   dip     - inode of parent dire    
450  *              dentry  - dentry of object to     
451  *                                                
452  * RETURN:      errors from subroutines           
453  *                                                
454  * note:                                          
455  * temporary file: if one or more processes ha    
456  * when the last link is removed, the link wil    
457  * unlink() returns, but the removal of the fi    
458  * postponed until all references to the files    
459  *                                                
460  * JFS does NOT support unlink() on directorie    
461  *                                                
462  */                                               
463 static int jfs_unlink(struct inode *dip, struc    
464 {                                                 
465         int rc;                                   
466         tid_t tid;              /* transaction    
467         struct inode *ip = d_inode(dentry);       
468         ino_t ino;                                
469         struct component_name dname;    /* obj    
470         struct inode *iplist[2];                  
471         struct tblock *tblk;                      
472         s64 new_size = 0;                         
473         int commit_flag;                          
474                                                   
475         jfs_info("jfs_unlink: dip:0x%p name:%p    
476                                                   
477         /* Init inode for quota operations. */    
478         rc = dquot_initialize(dip);               
479         if (rc)                                   
480                 goto out;                         
481         rc = dquot_initialize(ip);                
482         if (rc)                                   
483                 goto out;                         
484                                                   
485         if ((rc = get_UCSname(&dname, dentry))    
486                 goto out;                         
487                                                   
488         IWRITE_LOCK(ip, RDWRLOCK_NORMAL);         
489                                                   
490         tid = txBegin(dip->i_sb, 0);              
491                                                   
492         mutex_lock_nested(&JFS_IP(dip)->commit    
493         mutex_lock_nested(&JFS_IP(ip)->commit_    
494                                                   
495         iplist[0] = dip;                          
496         iplist[1] = ip;                           
497                                                   
498         /*                                        
499          * delete the entry of target file fro    
500          */                                       
501         ino = ip->i_ino;                          
502         if ((rc = dtDelete(tid, dip, &dname, &    
503                 jfs_err("jfs_unlink: dtDelete     
504                 if (rc == -EIO)                   
505                         txAbort(tid, 1);          
506                 txEnd(tid);                       
507                 mutex_unlock(&JFS_IP(ip)->comm    
508                 mutex_unlock(&JFS_IP(dip)->com    
509                 IWRITE_UNLOCK(ip);                
510                 goto out1;                        
511         }                                         
512                                                   
513         ASSERT(ip->i_nlink);                      
514                                                   
515         inode_set_mtime_to_ts(dip,                
516                               inode_set_ctime_    
517         mark_inode_dirty(dip);                    
518                                                   
519         /* update target's inode */               
520         inode_dec_link_count(ip);                 
521                                                   
522         /*                                        
523          *      commit zero link count object     
524          */                                       
525         if (ip->i_nlink == 0) {                   
526                 assert(!test_cflag(COMMIT_Noli    
527                 /* free block resources */        
528                 if ((new_size = commitZeroLink    
529                         txAbort(tid, 1);          
530                         txEnd(tid);               
531                         mutex_unlock(&JFS_IP(i    
532                         mutex_unlock(&JFS_IP(d    
533                         IWRITE_UNLOCK(ip);        
534                         rc = new_size;            
535                         goto out1;                
536                 }                                 
537                 tblk = tid_to_tblock(tid);        
538                 tblk->xflag |= COMMIT_DELETE;     
539                 tblk->u.ip = ip;                  
540         }                                         
541                                                   
542         /*                                        
543          * Incomplete truncate of file data ca    
544          * result in timing problems unless we    
545          * transaction.                           
546          */                                       
547         if (new_size)                             
548                 commit_flag = COMMIT_SYNC;        
549         else                                      
550                 commit_flag = 0;                  
551                                                   
552         /*                                        
553          * If xtTruncate was incomplete, commi    
554          * timing complications                   
555          */                                       
556         rc = txCommit(tid, 2, &iplist[0], comm    
557                                                   
558         txEnd(tid);                               
559                                                   
560         mutex_unlock(&JFS_IP(ip)->commit_mutex    
561         mutex_unlock(&JFS_IP(dip)->commit_mute    
562                                                   
563         while (new_size && (rc == 0)) {           
564                 tid = txBegin(dip->i_sb, 0);      
565                 mutex_lock(&JFS_IP(ip)->commit    
566                 new_size = xtTruncate_pmap(tid    
567                 if (new_size < 0) {               
568                         txAbort(tid, 1);          
569                         rc = new_size;            
570                 } else                            
571                         rc = txCommit(tid, 2,     
572                 txEnd(tid);                       
573                 mutex_unlock(&JFS_IP(ip)->comm    
574         }                                         
575                                                   
576         if (ip->i_nlink == 0)                     
577                 set_cflag(COMMIT_Nolink, ip);     
578                                                   
579         IWRITE_UNLOCK(ip);                        
580                                                   
581         /*                                        
582          * Truncating the directory index tabl    
583          * may need to be done iteratively        
584          */                                       
585         if (test_cflag(COMMIT_Stale, dip)) {      
586                 if (dip->i_size > 1)              
587                         jfs_truncate_nolock(di    
588                                                   
589                 clear_cflag(COMMIT_Stale, dip)    
590         }                                         
591                                                   
592       out1:                                       
593         free_UCSname(&dname);                     
594       out:                                        
595         jfs_info("jfs_unlink: rc:%d", rc);        
596         return rc;                                
597 }                                                 
598                                                   
599 /*                                                
600  * NAME:        commitZeroLink()                  
601  *                                                
602  * FUNCTION:    for non-directory, called by j    
603  *              truncate a regular file, direc    
604  *              link to zero length. return 0     
605  *              one of these.                     
606  *                                                
607  *              if the file is currently assoc    
608  *              only permanent disk and inode     
609  *              and neither the inode nor indi    
610  *              so that the resources can be l    
611  *              map by ctrunc1.                   
612  *              if there is no VM segment on e    
613  *              freed in both work and permane    
614  *              (? for temporary file - memory    
615  *              after no reference:               
616  *              reference count > 0 -   )         
617  *                                                
618  * PARAMETERS:  cd      - pointer to commit da    
619  *                        current inode is the    
620  *                                                
621  * RETURN:      Errors from subroutines           
622  */                                               
623 static s64 commitZeroLink(tid_t tid, struct in    
624 {                                                 
625         int filetype;                             
626         struct tblock *tblk;                      
627                                                   
628         jfs_info("commitZeroLink: tid = %d, ip    
629                                                   
630         filetype = ip->i_mode & S_IFMT;           
631         switch (filetype) {                       
632         case S_IFREG:                             
633                 break;                            
634         case S_IFLNK:                             
635                 /* fast symbolic link */          
636                 if (ip->i_size < IDATASIZE) {     
637                         ip->i_size = 0;           
638                         return 0;                 
639                 }                                 
640                 break;                            
641         default:                                  
642                 assert(filetype != S_IFDIR);      
643                 return 0;                         
644         }                                         
645                                                   
646         set_cflag(COMMIT_Freewmap, ip);           
647                                                   
648         /* mark transaction of block map updat    
649         tblk = tid_to_tblock(tid);                
650         tblk->xflag |= COMMIT_PMAP;               
651                                                   
652         /*                                        
653          * free EA                                
654          */                                       
655         if (JFS_IP(ip)->ea.flag & DXD_EXTENT)     
656                 /* acquire maplock on EA to be    
657                 txEA(tid, ip, &JFS_IP(ip)->ea,    
658                                                   
659         /*                                        
660          * free ACL                               
661          */                                       
662         if (JFS_IP(ip)->acl.flag & DXD_EXTENT)    
663                 /* acquire maplock on EA to be    
664                 txEA(tid, ip, &JFS_IP(ip)->acl    
665                                                   
666         /*                                        
667          * free xtree/data (truncate to zero l    
668          * free xtree/data pages from cache if    
669          * free xtree/data blocks from persist    
670          * free xtree/data blocks from working    
671          */                                       
672         if (ip->i_size)                           
673                 return xtTruncate_pmap(tid, ip    
674                                                   
675         return 0;                                 
676 }                                                 
677                                                   
678                                                   
679 /*                                                
680  * NAME:        jfs_free_zero_link()              
681  *                                                
682  * FUNCTION:    for non-directory, called by i    
683  *              free resources of a file from     
684  *              for a file previously committe    
685  *              while associated with a pager     
686  *                                                
687  * PARAMETER:   ip      - pointer to inode of     
688  */                                               
689 void jfs_free_zero_link(struct inode *ip)         
690 {                                                 
691         int type;                                 
692                                                   
693         jfs_info("jfs_free_zero_link: ip = 0x%    
694                                                   
695         /* return if not reg or symbolic link     
696          * already ok.                            
697          */                                       
698         type = ip->i_mode & S_IFMT;               
699                                                   
700         switch (type) {                           
701         case S_IFREG:                             
702                 break;                            
703         case S_IFLNK:                             
704                 /* if its contained in inode n    
705                 if (ip->i_size < IDATASIZE)       
706                         return;                   
707                 break;                            
708         default:                                  
709                 return;                           
710         }                                         
711                                                   
712         /*                                        
713          * free EA                                
714          */                                       
715         if (JFS_IP(ip)->ea.flag & DXD_EXTENT)     
716                 s64 xaddr = addressDXD(&JFS_IP    
717                 int xlen = lengthDXD(&JFS_IP(i    
718                 struct maplock maplock; /* map    
719                 struct pxd_lock *pxdlock;         
720                                                   
721                 /* free EA pages from cache */    
722                 invalidate_dxd_metapages(ip, J    
723                                                   
724                 /* free EA extent from working    
725                 maplock.index = 1;                
726                 pxdlock = (struct pxd_lock *)     
727                 pxdlock->flag = mlckFREEPXD;      
728                 PXDaddress(&pxdlock->pxd, xadd    
729                 PXDlength(&pxdlock->pxd, xlen)    
730                 txFreeMap(ip, pxdlock, NULL, C    
731         }                                         
732                                                   
733         /*                                        
734          * free ACL                               
735          */                                       
736         if (JFS_IP(ip)->acl.flag & DXD_EXTENT)    
737                 s64 xaddr = addressDXD(&JFS_IP    
738                 int xlen = lengthDXD(&JFS_IP(i    
739                 struct maplock maplock; /* map    
740                 struct pxd_lock *pxdlock;         
741                                                   
742                 invalidate_dxd_metapages(ip, J    
743                                                   
744                 /* free ACL extent from workin    
745                 maplock.index = 1;                
746                 pxdlock = (struct pxd_lock *)     
747                 pxdlock->flag = mlckFREEPXD;      
748                 PXDaddress(&pxdlock->pxd, xadd    
749                 PXDlength(&pxdlock->pxd, xlen)    
750                 txFreeMap(ip, pxdlock, NULL, C    
751         }                                         
752                                                   
753         /*                                        
754          * free xtree/data (truncate to zero l    
755          * free xtree/data pages from cache, a    
756          * free xtree/data blocks from working    
757          */                                       
758         if (ip->i_size)                           
759                 xtTruncate(0, ip, 0, COMMIT_WM    
760 }                                                 
761                                                   
762 /*                                                
763  * NAME:        jfs_link(vp, dvp, name, crp)      
764  *                                                
765  * FUNCTION:    create a link to <vp> by the n    
766  *              in the parent directory <dvp>     
767  *                                                
768  * PARAMETER:   vp      - target object           
769  *              dvp     - parent directory of     
770  *              name    - name of new link to     
771  *              crp     - credential              
772  *                                                
773  * RETURN:      Errors from subroutines           
774  *                                                
775  * note:                                          
776  * JFS does NOT support link() on directories     
777  * path in the directory hierarchy);              
778  * EPERM: the target object is a directory, an    
779  * does not have appropriate privileges or the    
780  * using link() on directories [XPG4.2].          
781  *                                                
782  * JFS does NOT support links between file sys    
783  * EXDEV: target object and new link are on di    
784  * implementation does not support links betwe    
785  */                                               
786 static int jfs_link(struct dentry *old_dentry,    
787              struct inode *dir, struct dentry     
788 {                                                 
789         int rc;                                   
790         tid_t tid;                                
791         struct inode *ip = d_inode(old_dentry)    
792         ino_t ino;                                
793         struct component_name dname;              
794         struct btstack btstack;                   
795         struct inode *iplist[2];                  
796                                                   
797         jfs_info("jfs_link: %pd %pd", old_dent    
798                                                   
799         rc = dquot_initialize(dir);               
800         if (rc)                                   
801                 goto out;                         
802                                                   
803         if (isReadOnly(ip)) {                     
804                 jfs_error(ip->i_sb, "read-only    
805                 return -EROFS;                    
806         }                                         
807                                                   
808         tid = txBegin(ip->i_sb, 0);               
809                                                   
810         mutex_lock_nested(&JFS_IP(dir)->commit    
811         mutex_lock_nested(&JFS_IP(ip)->commit_    
812                                                   
813         /*                                        
814          * scan parent directory for entry/fre    
815          */                                       
816         if ((rc = get_UCSname(&dname, dentry))    
817                 goto out_tx;                      
818                                                   
819         if ((rc = dtSearch(dir, &dname, &ino,     
820                 goto free_dname;                  
821                                                   
822         /*                                        
823          * create entry for new link in parent    
824          */                                       
825         ino = ip->i_ino;                          
826         if ((rc = dtInsert(tid, dir, &dname, &    
827                 goto free_dname;                  
828                                                   
829         /* update object inode */                 
830         inc_nlink(ip);          /* for new lin    
831         inode_set_ctime_current(ip);              
832         inode_set_mtime_to_ts(dir, inode_set_c    
833         mark_inode_dirty(dir);                    
834         ihold(ip);                                
835                                                   
836         iplist[0] = ip;                           
837         iplist[1] = dir;                          
838         rc = txCommit(tid, 2, &iplist[0], 0);     
839                                                   
840         if (rc) {                                 
841                 drop_nlink(ip); /* never insta    
842                 iput(ip);                         
843         } else                                    
844                 d_instantiate(dentry, ip);        
845                                                   
846       free_dname:                                 
847         free_UCSname(&dname);                     
848                                                   
849       out_tx:                                     
850         txEnd(tid);                               
851                                                   
852         mutex_unlock(&JFS_IP(ip)->commit_mutex    
853         mutex_unlock(&JFS_IP(dir)->commit_mute    
854                                                   
855       out:                                        
856         jfs_info("jfs_link: rc:%d", rc);          
857         return rc;                                
858 }                                                 
859                                                   
860 /*                                                
861  * NAME:        jfs_symlink(dip, dentry, name)    
862  *                                                
863  * FUNCTION:    creates a symbolic link to <sy    
864  *                      in directory <dip>        
865  *                                                
866  * PARAMETER:   dip     - parent directory vno    
867  *              dentry  - dentry of symbolic l    
868  *              name    - the path name of the    
869  *                        that will be the sou    
870  *                                                
871  * RETURN:      errors from subroutines           
872  *                                                
873  * note:                                          
874  * ENAMETOOLONG: pathname resolution of a symb    
875  * an intermediate result whose length exceeds    
876 */                                                
877                                                   
878 static int jfs_symlink(struct mnt_idmap *idmap    
879                        struct dentry *dentry,     
880 {                                                 
881         int rc;                                   
882         tid_t tid;                                
883         ino_t ino = 0;                            
884         struct component_name dname;              
885         u32 ssize;              /* source path    
886         struct btstack btstack;                   
887         struct inode *ip;                         
888         s64 xlen = 0;                             
889         int bmask = 0, xsize;                     
890         s64 xaddr;                                
891         struct metapage *mp;                      
892         struct super_block *sb;                   
893         struct tblock *tblk;                      
894                                                   
895         struct inode *iplist[2];                  
896                                                   
897         jfs_info("jfs_symlink: dip:0x%p name:%    
898                                                   
899         rc = dquot_initialize(dip);               
900         if (rc)                                   
901                 goto out1;                        
902                                                   
903         ssize = strlen(name) + 1;                 
904                                                   
905         /*                                        
906          * search parent directory for entry/f    
907          * (dtSearch() returns parent director    
908          */                                       
909                                                   
910         if ((rc = get_UCSname(&dname, dentry))    
911                 goto out1;                        
912                                                   
913         /*                                        
914          * allocate on-disk/in-memory inode fo    
915          * (iAlloc() returns new, locked inode    
916          */                                       
917         ip = ialloc(dip, S_IFLNK | 0777);         
918         if (IS_ERR(ip)) {                         
919                 rc = PTR_ERR(ip);                 
920                 goto out2;                        
921         }                                         
922                                                   
923         tid = txBegin(dip->i_sb, 0);              
924                                                   
925         mutex_lock_nested(&JFS_IP(dip)->commit    
926         mutex_lock_nested(&JFS_IP(ip)->commit_    
927                                                   
928         rc = jfs_init_security(tid, ip, dip, &    
929         if (rc)                                   
930                 goto out3;                        
931                                                   
932         tblk = tid_to_tblock(tid);                
933         tblk->xflag |= COMMIT_CREATE;             
934         tblk->ino = ip->i_ino;                    
935         tblk->u.ixpxd = JFS_IP(ip)->ixpxd;        
936                                                   
937         /* fix symlink access permission          
938          * (dir_create() ANDs in the u.u_cmask    
939          * but symlinks really need to be 777     
940          */                                       
941         ip->i_mode |= 0777;                       
942                                                   
943         /*                                        
944          * write symbolic link target path nam    
945          */                                       
946         xtInitRoot(tid, ip);                      
947                                                   
948         /*                                        
949          * write source path name inline in on    
950          */                                       
951                                                   
952         if (ssize <= IDATASIZE) {                 
953                 ip->i_op = &jfs_fast_symlink_i    
954                                                   
955                 ip->i_link = JFS_IP(ip)->i_inl    
956                 memcpy(ip->i_link, name, ssize    
957                 ip->i_size = ssize - 1;           
958                                                   
959                 /*                                
960                  * if symlink is > 128 bytes,     
961                  * store inline extended attri    
962                  */                               
963                 if (ssize > sizeof (JFS_IP(ip)    
964                         JFS_IP(ip)->mode2 &= ~    
965                                                   
966                 jfs_info("jfs_symlink: fast sy    
967                          ssize, name);            
968         }                                         
969         /*                                        
970          * write source path name in a single     
971          */                                       
972         else {                                    
973                 jfs_info("jfs_symlink: allocat    
974                                                   
975                 ip->i_op = &jfs_symlink_inode_    
976                 inode_nohighmem(ip);              
977                 ip->i_mapping->a_ops = &jfs_ao    
978                                                   
979                 /*                                
980                  * even though the data of sym    
981                  * path name) is treated as no    
982                  * it is read/written thru buf    
983                  */                               
984                 sb = ip->i_sb;                    
985                 bmask = JFS_SBI(sb)->bsize - 1    
986                 xsize = (ssize + bmask) & ~bma    
987                 xaddr = 0;                        
988                 xlen = xsize >> JFS_SBI(sb)->l    
989                 if ((rc = xtInsert(tid, ip, 0,    
990                         txAbort(tid, 0);          
991                         goto out3;                
992                 }                                 
993                 ip->i_size = ssize - 1;           
994                 while (ssize) {                   
995                         /* This is kind of sil    
996                         u32 copy_size = min_t(    
997                                                   
998                         mp = get_metapage(ip,     
999                                                   
1000                         if (mp == NULL) {        
1001                                 xtTruncate(ti    
1002                                 rc = -EIO;       
1003                                 txAbort(tid,     
1004                                 goto out3;       
1005                         }                        
1006                         memcpy(mp->data, name    
1007                         flush_metapage(mp);      
1008                         ssize -= copy_size;      
1009                         name += copy_size;       
1010                         xaddr += JFS_SBI(sb)-    
1011                 }                                
1012         }                                        
1013                                                  
1014         /*                                       
1015          * create entry for symbolic link in     
1016          */                                      
1017         rc = dtSearch(dip, &dname, &ino, &bts    
1018         if (rc == 0) {                           
1019                 ino = ip->i_ino;                 
1020                 rc = dtInsert(tid, dip, &dnam    
1021         }                                        
1022         if (rc) {                                
1023                 if (xlen)                        
1024                         xtTruncate(tid, ip, 0    
1025                 txAbort(tid, 0);                 
1026                 /* discard new inode */          
1027                 goto out3;                       
1028         }                                        
1029                                                  
1030         mark_inode_dirty(ip);                    
1031                                                  
1032         inode_set_mtime_to_ts(dip, inode_set_    
1033         mark_inode_dirty(dip);                   
1034         /*                                       
1035          * commit update of parent directory     
1036          */                                      
1037                                                  
1038         iplist[0] = dip;                         
1039         iplist[1] = ip;                          
1040         rc = txCommit(tid, 2, &iplist[0], 0);    
1041                                                  
1042       out3:                                      
1043         txEnd(tid);                              
1044         mutex_unlock(&JFS_IP(ip)->commit_mute    
1045         mutex_unlock(&JFS_IP(dip)->commit_mut    
1046         if (rc) {                                
1047                 free_ea_wmap(ip);                
1048                 clear_nlink(ip);                 
1049                 discard_new_inode(ip);           
1050         } else {                                 
1051                 d_instantiate_new(dentry, ip)    
1052         }                                        
1053                                                  
1054       out2:                                      
1055         free_UCSname(&dname);                    
1056                                                  
1057       out1:                                      
1058         jfs_info("jfs_symlink: rc:%d", rc);      
1059         return rc;                               
1060 }                                                
1061                                                  
1062                                                  
1063 /*                                               
1064  * NAME:        jfs_rename                       
1065  *                                               
1066  * FUNCTION:    rename a file or directory       
1067  */                                              
1068 static int jfs_rename(struct mnt_idmap *idmap    
1069                       struct dentry *old_dent    
1070                       struct dentry *new_dent    
1071 {                                                
1072         struct btstack btstack;                  
1073         ino_t ino;                               
1074         struct component_name new_dname;         
1075         struct inode *new_ip;                    
1076         struct component_name old_dname;         
1077         struct inode *old_ip;                    
1078         int rc;                                  
1079         tid_t tid;                               
1080         struct tlock *tlck;                      
1081         struct dt_lock *dtlck;                   
1082         struct lv *lv;                           
1083         int ipcount;                             
1084         struct inode *iplist[4];                 
1085         struct tblock *tblk;                     
1086         s64 new_size = 0;                        
1087         int commit_flag;                         
1088                                                  
1089         if (flags & ~RENAME_NOREPLACE)           
1090                 return -EINVAL;                  
1091                                                  
1092         jfs_info("jfs_rename: %pd %pd", old_d    
1093                                                  
1094         rc = dquot_initialize(old_dir);          
1095         if (rc)                                  
1096                 goto out1;                       
1097         rc = dquot_initialize(new_dir);          
1098         if (rc)                                  
1099                 goto out1;                       
1100                                                  
1101         old_ip = d_inode(old_dentry);            
1102         new_ip = d_inode(new_dentry);            
1103                                                  
1104         if ((rc = get_UCSname(&old_dname, old    
1105                 goto out1;                       
1106                                                  
1107         if ((rc = get_UCSname(&new_dname, new    
1108                 goto out2;                       
1109                                                  
1110         /*                                       
1111          * Make sure source inode number is w    
1112          */                                      
1113         rc = dtSearch(old_dir, &old_dname, &i    
1114         if (rc || (ino != old_ip->i_ino)) {      
1115                 rc = -ENOENT;                    
1116                 goto out3;                       
1117         }                                        
1118                                                  
1119         /*                                       
1120          * Make sure dest inode number (if an    
1121          */                                      
1122         rc = dtSearch(new_dir, &new_dname, &i    
1123         if (!rc) {                               
1124                 if ((!new_ip) || (ino != new_    
1125                         rc = -ESTALE;            
1126                         goto out3;               
1127                 }                                
1128         } else if (rc != -ENOENT)                
1129                 goto out3;                       
1130         else if (new_ip) {                       
1131                 /* no entry exists, but one w    
1132                 rc = -ESTALE;                    
1133                 goto out3;                       
1134         }                                        
1135                                                  
1136         if (S_ISDIR(old_ip->i_mode)) {           
1137                 if (new_ip) {                    
1138                         if (!dtEmpty(new_ip))    
1139                                 rc = -ENOTEMP    
1140                                 goto out3;       
1141                         }                        
1142                 }                                
1143         } else if (new_ip) {                     
1144                 IWRITE_LOCK(new_ip, RDWRLOCK_    
1145                 /* Init inode for quota opera    
1146                 rc = dquot_initialize(new_ip)    
1147                 if (rc)                          
1148                         goto out_unlock;         
1149         }                                        
1150                                                  
1151         /*                                       
1152          * The real work starts here             
1153          */                                      
1154         tid = txBegin(new_dir->i_sb, 0);         
1155                                                  
1156         /*                                       
1157          * How do we know the locking is safe    
1158          * The vfs does the hard part for us.    
1159          * commit_mutexes, the vfs already ha    
1160          * Here, the vfs has already taken i_    
1161          */                                      
1162         mutex_lock_nested(&JFS_IP(new_dir)->c    
1163         mutex_lock_nested(&JFS_IP(old_ip)->co    
1164         if (old_dir != new_dir)                  
1165                 mutex_lock_nested(&JFS_IP(old    
1166                                   COMMIT_MUTE    
1167                                                  
1168         if (new_ip) {                            
1169                 mutex_lock_nested(&JFS_IP(new    
1170                                   COMMIT_MUTE    
1171                 /*                               
1172                  * Change existing directory     
1173                  */                              
1174                 ino = new_ip->i_ino;             
1175                 rc = dtModify(tid, new_dir, &    
1176                               old_ip->i_ino,     
1177                 if (rc)                          
1178                         goto out_tx;             
1179                 drop_nlink(new_ip);              
1180                 if (S_ISDIR(new_ip->i_mode))     
1181                         drop_nlink(new_ip);      
1182                         if (new_ip->i_nlink)     
1183                                 mutex_unlock(    
1184                                 if (old_dir !    
1185                                         mutex    
1186                                 mutex_unlock(    
1187                                 mutex_unlock(    
1188                                 if (!S_ISDIR(    
1189                                         IWRIT    
1190                                 jfs_error(new    
1191                                           "ne    
1192                                 return -EIO;     
1193                         }                        
1194                         tblk = tid_to_tblock(    
1195                         tblk->xflag |= COMMIT    
1196                         tblk->u.ip = new_ip;     
1197                 } else if (new_ip->i_nlink ==    
1198                         assert(!test_cflag(CO    
1199                         /* free block resourc    
1200                         if ((new_size = commi    
1201                                 txAbort(tid,     
1202                                 rc = new_size    
1203                                 goto out_tx;     
1204                         }                        
1205                         tblk = tid_to_tblock(    
1206                         tblk->xflag |= COMMIT    
1207                         tblk->u.ip = new_ip;     
1208                 } else {                         
1209                         inode_set_ctime_curre    
1210                         mark_inode_dirty(new_    
1211                 }                                
1212         } else {                                 
1213                 /*                               
1214                  * Add new directory entry       
1215                  */                              
1216                 rc = dtSearch(new_dir, &new_d    
1217                               JFS_CREATE);       
1218                 if (rc) {                        
1219                         jfs_err("jfs_rename d    
1220                                 rc);             
1221                         goto out_tx;             
1222                 }                                
1223                                                  
1224                 ino = old_ip->i_ino;             
1225                 rc = dtInsert(tid, new_dir, &    
1226                 if (rc) {                        
1227                         if (rc == -EIO)          
1228                                 jfs_err("jfs_    
1229                         goto out_tx;             
1230                 }                                
1231                 if (S_ISDIR(old_ip->i_mode))     
1232                         inc_nlink(new_dir);      
1233         }                                        
1234         /*                                       
1235          * Remove old directory entry            
1236          */                                      
1237                                                  
1238         ino = old_ip->i_ino;                     
1239         rc = dtDelete(tid, old_dir, &old_dnam    
1240         if (rc) {                                
1241                 jfs_err("jfs_rename did not e    
1242                         rc);                     
1243                 txAbort(tid, 1);        /* Ma    
1244                 goto out_tx;                     
1245         }                                        
1246         if (S_ISDIR(old_ip->i_mode)) {           
1247                 drop_nlink(old_dir);             
1248                 if (old_dir != new_dir) {        
1249                         /*                       
1250                          * Change inode numbe    
1251                          */                      
1252                                                  
1253                         JFS_IP(old_ip)->i_dtr    
1254                                 cpu_to_le32(n    
1255                                                  
1256                         /* Linelock header of    
1257                         tlck = txLock(tid, ol    
1258                                     (struct m    
1259                                       tlckDTR    
1260                         dtlck = (struct dt_lo    
1261                         ASSERT(dtlck->index =    
1262                         lv = & dtlck->lv[0];     
1263                         lv->offset = 0;          
1264                         lv->length = 1;          
1265                         dtlck->index++;          
1266                 }                                
1267         }                                        
1268                                                  
1269         /*                                       
1270          * Update ctime on changed/moved inod    
1271          */                                      
1272         inode_set_ctime_current(old_ip);         
1273         mark_inode_dirty(old_ip);                
1274                                                  
1275         inode_set_mtime_to_ts(new_dir, inode_    
1276         mark_inode_dirty(new_dir);               
1277                                                  
1278         /* Build list of inodes modified by t    
1279         ipcount = 0;                             
1280         iplist[ipcount++] = old_ip;              
1281         if (new_ip)                              
1282                 iplist[ipcount++] = new_ip;      
1283         iplist[ipcount++] = old_dir;             
1284                                                  
1285         if (old_dir != new_dir) {                
1286                 iplist[ipcount++] = new_dir;     
1287                 inode_set_mtime_to_ts(old_dir    
1288                                       inode_s    
1289                 mark_inode_dirty(old_dir);       
1290         }                                        
1291                                                  
1292         /*                                       
1293          * Incomplete truncate of file data c    
1294          * result in timing problems unless w    
1295          * transaction.                          
1296          */                                      
1297         if (new_size)                            
1298                 commit_flag = COMMIT_SYNC;       
1299         else                                     
1300                 commit_flag = 0;                 
1301                                                  
1302         rc = txCommit(tid, ipcount, iplist, c    
1303                                                  
1304       out_tx:                                    
1305         txEnd(tid);                              
1306         if (new_ip)                              
1307                 mutex_unlock(&JFS_IP(new_ip)-    
1308         if (old_dir != new_dir)                  
1309                 mutex_unlock(&JFS_IP(old_dir)    
1310         mutex_unlock(&JFS_IP(old_ip)->commit_    
1311         mutex_unlock(&JFS_IP(new_dir)->commit    
1312                                                  
1313         while (new_size && (rc == 0)) {          
1314                 tid = txBegin(new_ip->i_sb, 0    
1315                 mutex_lock(&JFS_IP(new_ip)->c    
1316                 new_size = xtTruncate_pmap(ti    
1317                 if (new_size < 0) {              
1318                         txAbort(tid, 1);         
1319                         rc = new_size;           
1320                 } else                           
1321                         rc = txCommit(tid, 1,    
1322                 txEnd(tid);                      
1323                 mutex_unlock(&JFS_IP(new_ip)-    
1324         }                                        
1325         if (new_ip && (new_ip->i_nlink == 0))    
1326                 set_cflag(COMMIT_Nolink, new_    
1327         /*                                       
1328          * Truncating the directory index tab    
1329          * may need to be done iteratively       
1330          */                                      
1331         if (test_cflag(COMMIT_Stale, old_dir)    
1332                 if (old_dir->i_size > 1)         
1333                         jfs_truncate_nolock(o    
1334                                                  
1335                 clear_cflag(COMMIT_Stale, old    
1336         }                                        
1337       out_unlock:                                
1338         if (new_ip && !S_ISDIR(new_ip->i_mode    
1339                 IWRITE_UNLOCK(new_ip);           
1340       out3:                                      
1341         free_UCSname(&new_dname);                
1342       out2:                                      
1343         free_UCSname(&old_dname);                
1344       out1:                                      
1345         jfs_info("jfs_rename: returning %d",     
1346         return rc;                               
1347 }                                                
1348                                                  
1349                                                  
1350 /*                                               
1351  * NAME:        jfs_mknod                        
1352  *                                               
1353  * FUNCTION:    Create a special file (device    
1354  */                                              
1355 static int jfs_mknod(struct mnt_idmap *idmap,    
1356                      struct dentry *dentry, u    
1357 {                                                
1358         struct jfs_inode_info *jfs_ip;           
1359         struct btstack btstack;                  
1360         struct component_name dname;             
1361         ino_t ino;                               
1362         struct inode *ip;                        
1363         struct inode *iplist[2];                 
1364         int rc;                                  
1365         tid_t tid;                               
1366         struct tblock *tblk;                     
1367                                                  
1368         jfs_info("jfs_mknod: %pd", dentry);      
1369                                                  
1370         rc = dquot_initialize(dir);              
1371         if (rc)                                  
1372                 goto out;                        
1373                                                  
1374         if ((rc = get_UCSname(&dname, dentry)    
1375                 goto out;                        
1376                                                  
1377         ip = ialloc(dir, mode);                  
1378         if (IS_ERR(ip)) {                        
1379                 rc = PTR_ERR(ip);                
1380                 goto out1;                       
1381         }                                        
1382         jfs_ip = JFS_IP(ip);                     
1383                                                  
1384         tid = txBegin(dir->i_sb, 0);             
1385                                                  
1386         mutex_lock_nested(&JFS_IP(dir)->commi    
1387         mutex_lock_nested(&JFS_IP(ip)->commit    
1388                                                  
1389         rc = jfs_init_acl(tid, ip, dir);         
1390         if (rc)                                  
1391                 goto out3;                       
1392                                                  
1393         rc = jfs_init_security(tid, ip, dir,     
1394         if (rc) {                                
1395                 txAbort(tid, 0);                 
1396                 goto out3;                       
1397         }                                        
1398                                                  
1399         if ((rc = dtSearch(dir, &dname, &ino,    
1400                 txAbort(tid, 0);                 
1401                 goto out3;                       
1402         }                                        
1403                                                  
1404         tblk = tid_to_tblock(tid);               
1405         tblk->xflag |= COMMIT_CREATE;            
1406         tblk->ino = ip->i_ino;                   
1407         tblk->u.ixpxd = JFS_IP(ip)->ixpxd;       
1408                                                  
1409         ino = ip->i_ino;                         
1410         if ((rc = dtInsert(tid, dir, &dname,     
1411                 txAbort(tid, 0);                 
1412                 goto out3;                       
1413         }                                        
1414                                                  
1415         ip->i_op = &jfs_file_inode_operations    
1416         jfs_ip->dev = new_encode_dev(rdev);      
1417         init_special_inode(ip, ip->i_mode, rd    
1418                                                  
1419         mark_inode_dirty(ip);                    
1420                                                  
1421         inode_set_mtime_to_ts(dir, inode_set_    
1422                                                  
1423         mark_inode_dirty(dir);                   
1424                                                  
1425         iplist[0] = dir;                         
1426         iplist[1] = ip;                          
1427         rc = txCommit(tid, 2, iplist, 0);        
1428                                                  
1429       out3:                                      
1430         txEnd(tid);                              
1431         mutex_unlock(&JFS_IP(ip)->commit_mute    
1432         mutex_unlock(&JFS_IP(dir)->commit_mut    
1433         if (rc) {                                
1434                 free_ea_wmap(ip);                
1435                 clear_nlink(ip);                 
1436                 discard_new_inode(ip);           
1437         } else {                                 
1438                 d_instantiate_new(dentry, ip)    
1439         }                                        
1440                                                  
1441       out1:                                      
1442         free_UCSname(&dname);                    
1443                                                  
1444       out:                                       
1445         jfs_info("jfs_mknod: returning %d", r    
1446         return rc;                               
1447 }                                                
1448                                                  
1449 static struct dentry *jfs_lookup(struct inode    
1450 {                                                
1451         struct btstack btstack;                  
1452         ino_t inum;                              
1453         struct inode *ip;                        
1454         struct component_name key;               
1455         int rc;                                  
1456                                                  
1457         jfs_info("jfs_lookup: name = %pd", de    
1458                                                  
1459         if ((rc = get_UCSname(&key, dentry)))    
1460                 return ERR_PTR(rc);              
1461         rc = dtSearch(dip, &key, &inum, &btst    
1462         free_UCSname(&key);                      
1463         if (rc == -ENOENT) {                     
1464                 ip = NULL;                       
1465         } else if (rc) {                         
1466                 jfs_err("jfs_lookup: dtSearch    
1467                 ip = ERR_PTR(rc);                
1468         } else {                                 
1469                 ip = jfs_iget(dip->i_sb, inum    
1470                 if (IS_ERR(ip))                  
1471                         jfs_err("jfs_lookup:     
1472         }                                        
1473                                                  
1474         return d_splice_alias(ip, dentry);       
1475 }                                                
1476                                                  
1477 static struct inode *jfs_nfs_get_inode(struct    
1478                 u64 ino, u32 generation)         
1479 {                                                
1480         struct inode *inode;                     
1481                                                  
1482         if (ino == 0)                            
1483                 return ERR_PTR(-ESTALE);         
1484         inode = jfs_iget(sb, ino);               
1485         if (IS_ERR(inode))                       
1486                 return ERR_CAST(inode);          
1487                                                  
1488         if (generation && inode->i_generation    
1489                 iput(inode);                     
1490                 return ERR_PTR(-ESTALE);         
1491         }                                        
1492                                                  
1493         return inode;                            
1494 }                                                
1495                                                  
1496 struct dentry *jfs_fh_to_dentry(struct super_    
1497                 int fh_len, int fh_type)         
1498 {                                                
1499         return generic_fh_to_dentry(sb, fid,     
1500                                     jfs_nfs_g    
1501 }                                                
1502                                                  
1503 struct dentry *jfs_fh_to_parent(struct super_    
1504                 int fh_len, int fh_type)         
1505 {                                                
1506         return generic_fh_to_parent(sb, fid,     
1507                                     jfs_nfs_g    
1508 }                                                
1509                                                  
1510 struct dentry *jfs_get_parent(struct dentry *    
1511 {                                                
1512         unsigned long parent_ino;                
1513                                                  
1514         parent_ino =                             
1515                 le32_to_cpu(JFS_IP(d_inode(de    
1516                                                  
1517         return d_obtain_alias(jfs_iget(dentry    
1518 }                                                
1519                                                  
1520 const struct inode_operations jfs_dir_inode_o    
1521         .create         = jfs_create,            
1522         .lookup         = jfs_lookup,            
1523         .link           = jfs_link,              
1524         .unlink         = jfs_unlink,            
1525         .symlink        = jfs_symlink,           
1526         .mkdir          = jfs_mkdir,             
1527         .rmdir          = jfs_rmdir,             
1528         .mknod          = jfs_mknod,             
1529         .rename         = jfs_rename,            
1530         .listxattr      = jfs_listxattr,         
1531         .setattr        = jfs_setattr,           
1532         .fileattr_get   = jfs_fileattr_get,      
1533         .fileattr_set   = jfs_fileattr_set,      
1534 #ifdef CONFIG_JFS_POSIX_ACL                      
1535         .get_inode_acl  = jfs_get_acl,           
1536         .set_acl        = jfs_set_acl,           
1537 #endif                                           
1538 };                                               
1539                                                  
1540 WRAP_DIR_ITER(jfs_readdir) // FIXME!             
1541 const struct file_operations jfs_dir_operatio    
1542         .read           = generic_read_dir,      
1543         .iterate_shared = shared_jfs_readdir,    
1544         .fsync          = jfs_fsync,             
1545         .unlocked_ioctl = jfs_ioctl,             
1546         .compat_ioctl   = compat_ptr_ioctl,      
1547         .llseek         = generic_file_llseek    
1548 };                                               
1549                                                  
1550 static int jfs_ci_hash(const struct dentry *d    
1551 {                                                
1552         unsigned long hash;                      
1553         int i;                                   
1554                                                  
1555         hash = init_name_hash(dir);              
1556         for (i=0; i < this->len; i++)            
1557                 hash = partial_name_hash(tolo    
1558         this->hash = end_name_hash(hash);        
1559                                                  
1560         return 0;                                
1561 }                                                
1562                                                  
1563 static int jfs_ci_compare(const struct dentry    
1564                 unsigned int len, const char     
1565 {                                                
1566         int i, result = 1;                       
1567                                                  
1568         if (len != name->len)                    
1569                 goto out;                        
1570         for (i=0; i < len; i++) {                
1571                 if (tolower(str[i]) != tolowe    
1572                         goto out;                
1573         }                                        
1574         result = 0;                              
1575 out:                                             
1576         return result;                           
1577 }                                                
1578                                                  
1579 static int jfs_ci_revalidate(struct dentry *d    
1580 {                                                
1581         /*                                       
1582          * This is not negative dentry. Alway    
1583          *                                       
1584          * Note, rename() to existing directo    
1585          * and will use existing name which i    
1586          *                                       
1587          * We may be able to drop this positi    
1588          * positive dentry isn't good idea. S    
1589          * rename("filename", "FILENAME") for    
1590          */                                      
1591         if (d_really_is_positive(dentry))        
1592                 return 1;                        
1593                                                  
1594         /*                                       
1595          * This may be nfsd (or something), a    
1596          * intent of this. So, since this can    
1597          */                                      
1598         if (!flags)                              
1599                 return 0;                        
1600                                                  
1601         /*                                       
1602          * Drop the negative dentry, in order    
1603          * case sensitive name which is speci    
1604          * for creation.                         
1605          */                                      
1606         if (flags & (LOOKUP_CREATE | LOOKUP_R    
1607                 return 0;                        
1608         return 1;                                
1609 }                                                
1610                                                  
1611 const struct dentry_operations jfs_ci_dentry_    
1612 {                                                
1613         .d_hash = jfs_ci_hash,                   
1614         .d_compare = jfs_ci_compare,             
1615         .d_revalidate = jfs_ci_revalidate,       
1616 };                                               
1617                                                  

~ [ 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