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

TOMOYO Linux Cross Reference
Linux/fs/udf/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/udf/namei.c (Version linux-6.11.5) and /fs/udf/namei.c (Version linux-6.10.4)


** Warning: Cannot open xref database.

  1 // SPDX-License-Identifier: GPL-2.0-only            1 
  2 /*                                                
  3  * namei.c                                        
  4  *                                                
  5  * PURPOSE                                        
  6  *      Inode name handling routines for the O    
  7  *                                                
  8  * COPYRIGHT                                      
  9  *  (C) 1998-2004 Ben Fennema                     
 10  *  (C) 1999-2000 Stelias Computing Inc           
 11  *                                                
 12  * HISTORY                                        
 13  *                                                
 14  *  12/12/98 blf  Created. Split out the looku    
 15  *  04/19/99 blf  link, mknod, symlink support    
 16  */                                               
 17                                                   
 18 #include "udfdecl.h"                              
 19                                                   
 20 #include "udf_i.h"                                
 21 #include "udf_sb.h"                               
 22 #include <linux/string.h>                         
 23 #include <linux/errno.h>                          
 24 #include <linux/mm.h>                             
 25 #include <linux/slab.h>                           
 26 #include <linux/sched.h>                          
 27 #include <linux/crc-itu-t.h>                      
 28 #include <linux/exportfs.h>                       
 29 #include <linux/iversion.h>                       
 30                                                   
 31 static inline int udf_match(int len1, const un    
 32                             const unsigned cha    
 33 {                                                 
 34         if (len1 != len2)                         
 35                 return 0;                         
 36                                                   
 37         return !memcmp(name1, name2, len1);       
 38 }                                                 
 39                                                   
 40 /**                                               
 41  * udf_fiiter_find_entry - find entry in given    
 42  *                                                
 43  * @dir:        directory inode to search in      
 44  * @child:      qstr of the name                  
 45  * @iter:       iter to use for searching         
 46  *                                                
 47  * This function searches in the directory @di    
 48  * found, @iter points to the position in the     
 49  *                                                
 50  * Returns 0 on success, < 0 on error (includi    
 51  */                                               
 52 static int udf_fiiter_find_entry(struct inode     
 53                                  struct udf_fi    
 54 {                                                 
 55         int flen;                                 
 56         unsigned char *fname = NULL;              
 57         struct super_block *sb = dir->i_sb;       
 58         int isdotdot = child->len == 2 &&         
 59                 child->name[0] == '.' && child    
 60         int ret;                                  
 61                                                   
 62         fname = kmalloc(UDF_NAME_LEN, GFP_KERN    
 63         if (!fname)                               
 64                 return -ENOMEM;                   
 65                                                   
 66         for (ret = udf_fiiter_init(iter, dir,     
 67              !ret && iter->pos < dir->i_size;     
 68              ret = udf_fiiter_advance(iter)) {    
 69                 if (iter->fi.fileCharacteristi    
 70                         if (!UDF_QUERY_FLAG(sb    
 71                                 continue;         
 72                 }                                 
 73                                                   
 74                 if (iter->fi.fileCharacteristi    
 75                         if (!UDF_QUERY_FLAG(sb    
 76                                 continue;         
 77                 }                                 
 78                                                   
 79                 if ((iter->fi.fileCharacterist    
 80                     isdotdot)                     
 81                         goto out_ok;              
 82                                                   
 83                 if (!iter->fi.lengthFileIdent)    
 84                         continue;                 
 85                                                   
 86                 flen = udf_get_filename(sb, it    
 87                                 iter->fi.lengt    
 88                 if (flen < 0) {                   
 89                         ret = flen;               
 90                         goto out_err;             
 91                 }                                 
 92                                                   
 93                 if (udf_match(flen, fname, chi    
 94                         goto out_ok;              
 95         }                                         
 96         if (!ret)                                 
 97                 ret = -ENOENT;                    
 98                                                   
 99 out_err:                                          
100         udf_fiiter_release(iter);                 
101 out_ok:                                           
102         kfree(fname);                             
103                                                   
104         return ret;                               
105 }                                                 
106                                                   
107 static struct dentry *udf_lookup(struct inode     
108                                  unsigned int     
109 {                                                 
110         struct inode *inode = NULL;               
111         struct udf_fileident_iter iter;           
112         int err;                                  
113                                                   
114         if (dentry->d_name.len > UDF_NAME_LEN)    
115                 return ERR_PTR(-ENAMETOOLONG);    
116                                                   
117         err = udf_fiiter_find_entry(dir, &dent    
118         if (err < 0 && err != -ENOENT)            
119                 return ERR_PTR(err);              
120                                                   
121         if (err == 0) {                           
122                 struct kernel_lb_addr loc;        
123                                                   
124                 loc = lelb_to_cpu(iter.fi.icb.    
125                 udf_fiiter_release(&iter);        
126                                                   
127                 inode = udf_iget(dir->i_sb, &l    
128         }                                         
129                                                   
130         return d_splice_alias(inode, dentry);     
131 }                                                 
132                                                   
133 static int udf_expand_dir_adinicb(struct inode    
134 {                                                 
135         udf_pblk_t newblock;                      
136         struct buffer_head *dbh = NULL;           
137         struct kernel_lb_addr eloc;               
138         struct extent_position epos;              
139         uint8_t alloctype;                        
140         struct udf_inode_info *iinfo = UDF_I(i    
141         struct udf_fileident_iter iter;           
142         uint8_t *impuse;                          
143         int ret;                                  
144                                                   
145         if (UDF_QUERY_FLAG(inode->i_sb, UDF_FL    
146                 alloctype = ICBTAG_FLAG_AD_SHO    
147         else                                      
148                 alloctype = ICBTAG_FLAG_AD_LON    
149                                                   
150         if (!inode->i_size) {                     
151                 iinfo->i_alloc_type = alloctyp    
152                 mark_inode_dirty(inode);          
153                 return 0;                         
154         }                                         
155                                                   
156         /* alloc block, and copy data to it */    
157         *block = udf_new_block(inode->i_sb, in    
158                                iinfo->i_locati    
159                                iinfo->i_locati    
160         if (!(*block))                            
161                 return ret;                       
162         newblock = udf_get_pblock(inode->i_sb,    
163                                   iinfo->i_loc    
164                                 0);               
165         if (newblock == 0xffffffff)               
166                 return -EFSCORRUPTED;             
167         dbh = sb_getblk(inode->i_sb, newblock)    
168         if (!dbh)                                 
169                 return -ENOMEM;                   
170         lock_buffer(dbh);                         
171         memcpy(dbh->b_data, iinfo->i_data, ino    
172         memset(dbh->b_data + inode->i_size, 0,    
173                inode->i_sb->s_blocksize - inod    
174         set_buffer_uptodate(dbh);                 
175         unlock_buffer(dbh);                       
176                                                   
177         /* Drop inline data, add block instead    
178         iinfo->i_alloc_type = alloctype;          
179         memset(iinfo->i_data + iinfo->i_lenEAt    
180         iinfo->i_lenAlloc = 0;                    
181         eloc.logicalBlockNum = *block;            
182         eloc.partitionReferenceNum =              
183                                 iinfo->i_locat    
184         iinfo->i_lenExtents = inode->i_size;      
185         epos.bh = NULL;                           
186         epos.block = iinfo->i_location;           
187         epos.offset = udf_file_entry_alloc_off    
188         ret = udf_add_aext(inode, &epos, &eloc    
189         brelse(epos.bh);                          
190         if (ret < 0) {                            
191                 brelse(dbh);                      
192                 udf_free_blocks(inode->i_sb, i    
193                 return ret;                       
194         }                                         
195         mark_inode_dirty(inode);                  
196                                                   
197         /* Now fixup tags in moved directory e    
198         for (ret = udf_fiiter_init(&iter, inod    
199              !ret && iter.pos < inode->i_size;    
200              ret = udf_fiiter_advance(&iter))     
201                 iter.fi.descTag.tagLocation =     
202                 if (iter.fi.lengthOfImpUse !=     
203                         impuse = dbh->b_data +    
204                                                   
205                 else                              
206                         impuse = NULL;            
207                 udf_fiiter_write_fi(&iter, imp    
208         }                                         
209         brelse(dbh);                              
210         /*                                        
211          * We don't expect the iteration to fa    
212          * already verified to be correct         
213          */                                       
214         WARN_ON_ONCE(ret);                        
215         udf_fiiter_release(&iter);                
216                                                   
217         return 0;                                 
218 }                                                 
219                                                   
220 static int udf_fiiter_add_entry(struct inode *    
221                                 struct udf_fil    
222 {                                                 
223         struct udf_inode_info *dinfo = UDF_I(d    
224         int nfidlen, namelen = 0;                 
225         int ret;                                  
226         int off, blksize = 1 << dir->i_blkbits    
227         udf_pblk_t block;                         
228         char name[UDF_NAME_LEN_CS0];              
229                                                   
230         if (dentry) {                             
231                 namelen = udf_put_filename(dir    
232                                            den    
233                                            nam    
234                 if (!namelen)                     
235                         return -ENAMETOOLONG;     
236         }                                         
237         nfidlen = ALIGN(sizeof(struct fileIden    
238                                                   
239         for (ret = udf_fiiter_init(iter, dir,     
240              !ret && iter->pos < dir->i_size;     
241              ret = udf_fiiter_advance(iter)) {    
242                 if (iter->fi.fileCharacteristi    
243                         if (udf_dir_entry_len(    
244                                 iter->fi.descT    
245                                 iter->fi.fileV    
246                                 iter->fi.fileC    
247                                 iter->fi.lengt    
248                                 iter->fi.lengt    
249                                 memcpy(iter->n    
250                                 iter->name = i    
251                                 return 0;         
252                         }                         
253                 }                                 
254         }                                         
255         if (ret) {                                
256                 udf_fiiter_release(iter);         
257                 return ret;                       
258         }                                         
259         if (dinfo->i_alloc_type == ICBTAG_FLAG    
260             blksize - udf_ext0_offset(dir) - i    
261                 udf_fiiter_release(iter);         
262                 ret = udf_expand_dir_adinicb(d    
263                 if (ret)                          
264                         return ret;               
265                 ret = udf_fiiter_init(iter, di    
266                 if (ret < 0)                      
267                         return ret;               
268         }                                         
269                                                   
270         /* Get blocknumber to use for entry ta    
271         if (dinfo->i_alloc_type == ICBTAG_FLAG    
272                 block = dinfo->i_location.logi    
273         } else {                                  
274                 block = iter->eloc.logicalBloc    
275                                 ((iter->elen -    
276         }                                         
277         off = iter->pos & (blksize - 1);          
278         if (!off)                                 
279                 off = blksize;                    
280         /* Entry fits into current block? */      
281         if (blksize - udf_ext0_offset(dir) - o    
282                 goto store_fi;                    
283                                                   
284         ret = udf_fiiter_append_blk(iter);        
285         if (ret) {                                
286                 udf_fiiter_release(iter);         
287                 return ret;                       
288         }                                         
289                                                   
290         /* Entry will be completely in the new    
291         if (!(iter->pos & (blksize - 1)))         
292                 block = iter->eloc.logicalBloc    
293                                 ((iter->elen -    
294 store_fi:                                         
295         memset(&iter->fi, 0, sizeof(struct fil    
296         if (UDF_SB(dir->i_sb)->s_udfrev >= 0x0    
297                 udf_new_tag((char *)(&iter->fi    
298                             sizeof(struct tag)    
299         else                                      
300                 udf_new_tag((char *)(&iter->fi    
301                             sizeof(struct tag)    
302         iter->fi.fileVersionNum = cpu_to_le16(    
303         iter->fi.lengthFileIdent = namelen;       
304         iter->fi.lengthOfImpUse = cpu_to_le16(    
305         memcpy(iter->namebuf, name, namelen);     
306         iter->name = iter->namebuf;               
307                                                   
308         dir->i_size += nfidlen;                   
309         if (dinfo->i_alloc_type == ICBTAG_FLAG    
310                 dinfo->i_lenAlloc += nfidlen;     
311         } else {                                  
312                 /* Truncate last extent to pro    
313                 udf_fiiter_update_elen(iter, i    
314                                         (dinfo    
315         }                                         
316         mark_inode_dirty(dir);                    
317                                                   
318         return 0;                                 
319 }                                                 
320                                                   
321 static void udf_fiiter_delete_entry(struct udf    
322 {                                                 
323         iter->fi.fileCharacteristics |= FID_FI    
324                                                   
325         if (UDF_QUERY_FLAG(iter->dir->i_sb, UD    
326                 memset(&iter->fi.icb, 0x00, si    
327                                                   
328         udf_fiiter_write_fi(iter, NULL);          
329 }                                                 
330                                                   
331 static void udf_add_fid_counter(struct super_b    
332 {                                                 
333         struct logicalVolIntegrityDescImpUse *    
334                                                   
335         if (!lvidiu)                              
336                 return;                           
337         mutex_lock(&UDF_SB(sb)->s_alloc_mutex)    
338         if (dir)                                  
339                 le32_add_cpu(&lvidiu->numDirs,    
340         else                                      
341                 le32_add_cpu(&lvidiu->numFiles    
342         udf_updated_lvid(sb);                     
343         mutex_unlock(&UDF_SB(sb)->s_alloc_mute    
344 }                                                 
345                                                   
346 static int udf_add_nondir(struct dentry *dentr    
347 {                                                 
348         struct udf_inode_info *iinfo = UDF_I(i    
349         struct inode *dir = d_inode(dentry->d_    
350         struct udf_fileident_iter iter;           
351         int err;                                  
352                                                   
353         err = udf_fiiter_add_entry(dir, dentry    
354         if (err) {                                
355                 inode_dec_link_count(inode);      
356                 discard_new_inode(inode);         
357                 return err;                       
358         }                                         
359         iter.fi.icb.extLength = cpu_to_le32(in    
360         iter.fi.icb.extLocation = cpu_to_lelb(    
361         *(__le32 *)((struct allocDescImpUse *)    
362                 cpu_to_le32(iinfo->i_unique &     
363         udf_fiiter_write_fi(&iter, NULL);         
364         inode_set_mtime_to_ts(dir, inode_set_c    
365         mark_inode_dirty(dir);                    
366         udf_fiiter_release(&iter);                
367         udf_add_fid_counter(dir->i_sb, false,     
368         d_instantiate_new(dentry, inode);         
369                                                   
370         return 0;                                 
371 }                                                 
372                                                   
373 static int udf_create(struct mnt_idmap *idmap,    
374                       struct dentry *dentry, u    
375 {                                                 
376         struct inode *inode = udf_new_inode(di    
377                                                   
378         if (IS_ERR(inode))                        
379                 return PTR_ERR(inode);            
380                                                   
381         inode->i_data.a_ops = &udf_aops;          
382         inode->i_op = &udf_file_inode_operatio    
383         inode->i_fop = &udf_file_operations;      
384         mark_inode_dirty(inode);                  
385                                                   
386         return udf_add_nondir(dentry, inode);     
387 }                                                 
388                                                   
389 static int udf_tmpfile(struct mnt_idmap *idmap    
390                        struct file *file, umod    
391 {                                                 
392         struct inode *inode = udf_new_inode(di    
393                                                   
394         if (IS_ERR(inode))                        
395                 return PTR_ERR(inode);            
396                                                   
397         inode->i_data.a_ops = &udf_aops;          
398         inode->i_op = &udf_file_inode_operatio    
399         inode->i_fop = &udf_file_operations;      
400         mark_inode_dirty(inode);                  
401         d_tmpfile(file, inode);                   
402         unlock_new_inode(inode);                  
403         return finish_open_simple(file, 0);       
404 }                                                 
405                                                   
406 static int udf_mknod(struct mnt_idmap *idmap,     
407                      struct dentry *dentry, um    
408 {                                                 
409         struct inode *inode;                      
410                                                   
411         if (!old_valid_dev(rdev))                 
412                 return -EINVAL;                   
413                                                   
414         inode = udf_new_inode(dir, mode);         
415         if (IS_ERR(inode))                        
416                 return PTR_ERR(inode);            
417                                                   
418         init_special_inode(inode, mode, rdev);    
419         return udf_add_nondir(dentry, inode);     
420 }                                                 
421                                                   
422 static int udf_mkdir(struct mnt_idmap *idmap,     
423                      struct dentry *dentry, um    
424 {                                                 
425         struct inode *inode;                      
426         struct udf_fileident_iter iter;           
427         int err;                                  
428         struct udf_inode_info *dinfo = UDF_I(d    
429         struct udf_inode_info *iinfo;             
430                                                   
431         inode = udf_new_inode(dir, S_IFDIR | m    
432         if (IS_ERR(inode))                        
433                 return PTR_ERR(inode);            
434                                                   
435         iinfo = UDF_I(inode);                     
436         inode->i_op = &udf_dir_inode_operation    
437         inode->i_fop = &udf_dir_operations;       
438         err = udf_fiiter_add_entry(inode, NULL    
439         if (err) {                                
440                 clear_nlink(inode);               
441                 discard_new_inode(inode);         
442                 return err;                       
443         }                                         
444         set_nlink(inode, 2);                      
445         iter.fi.icb.extLength = cpu_to_le32(in    
446         iter.fi.icb.extLocation = cpu_to_lelb(    
447         *(__le32 *)((struct allocDescImpUse *)    
448                 cpu_to_le32(dinfo->i_unique &     
449         iter.fi.fileCharacteristics =             
450                         FID_FILE_CHAR_DIRECTOR    
451         udf_fiiter_write_fi(&iter, NULL);         
452         udf_fiiter_release(&iter);                
453         mark_inode_dirty(inode);                  
454                                                   
455         err = udf_fiiter_add_entry(dir, dentry    
456         if (err) {                                
457                 clear_nlink(inode);               
458                 discard_new_inode(inode);         
459                 return err;                       
460         }                                         
461         iter.fi.icb.extLength = cpu_to_le32(in    
462         iter.fi.icb.extLocation = cpu_to_lelb(    
463         *(__le32 *)((struct allocDescImpUse *)    
464                 cpu_to_le32(iinfo->i_unique &     
465         iter.fi.fileCharacteristics |= FID_FIL    
466         udf_fiiter_write_fi(&iter, NULL);         
467         udf_fiiter_release(&iter);                
468         udf_add_fid_counter(dir->i_sb, true, 1    
469         inc_nlink(dir);                           
470         inode_set_mtime_to_ts(dir, inode_set_c    
471         mark_inode_dirty(dir);                    
472         d_instantiate_new(dentry, inode);         
473                                                   
474         return 0;                                 
475 }                                                 
476                                                   
477 static int empty_dir(struct inode *dir)           
478 {                                                 
479         struct udf_fileident_iter iter;           
480         int ret;                                  
481                                                   
482         for (ret = udf_fiiter_init(&iter, dir,    
483              !ret && iter.pos < dir->i_size;      
484              ret = udf_fiiter_advance(&iter))     
485                 if (iter.fi.lengthFileIdent &&    
486                     !(iter.fi.fileCharacterist    
487                         udf_fiiter_release(&it    
488                         return 0;                 
489                 }                                 
490         }                                         
491         udf_fiiter_release(&iter);                
492                                                   
493         return 1;                                 
494 }                                                 
495                                                   
496 static int udf_rmdir(struct inode *dir, struct    
497 {                                                 
498         int ret;                                  
499         struct inode *inode = d_inode(dentry);    
500         struct udf_fileident_iter iter;           
501         struct kernel_lb_addr tloc;               
502                                                   
503         ret = udf_fiiter_find_entry(dir, &dent    
504         if (ret)                                  
505                 goto out;                         
506                                                   
507         ret = -EFSCORRUPTED;                      
508         tloc = lelb_to_cpu(iter.fi.icb.extLoca    
509         if (udf_get_lb_pblock(dir->i_sb, &tloc    
510                 goto end_rmdir;                   
511         ret = -ENOTEMPTY;                         
512         if (!empty_dir(inode))                    
513                 goto end_rmdir;                   
514         udf_fiiter_delete_entry(&iter);           
515         if (inode->i_nlink != 2)                  
516                 udf_warn(inode->i_sb, "empty d    
517                          inode->i_nlink);         
518         clear_nlink(inode);                       
519         inode->i_size = 0;                        
520         inode_dec_link_count(dir);                
521         udf_add_fid_counter(dir->i_sb, true, -    
522         inode_set_mtime_to_ts(dir,                
523                               inode_set_ctime_    
524         mark_inode_dirty(dir);                    
525         ret = 0;                                  
526 end_rmdir:                                        
527         udf_fiiter_release(&iter);                
528 out:                                              
529         return ret;                               
530 }                                                 
531                                                   
532 static int udf_unlink(struct inode *dir, struc    
533 {                                                 
534         int ret;                                  
535         struct inode *inode = d_inode(dentry);    
536         struct udf_fileident_iter iter;           
537         struct kernel_lb_addr tloc;               
538                                                   
539         ret = udf_fiiter_find_entry(dir, &dent    
540         if (ret)                                  
541                 goto out;                         
542                                                   
543         ret = -EFSCORRUPTED;                      
544         tloc = lelb_to_cpu(iter.fi.icb.extLoca    
545         if (udf_get_lb_pblock(dir->i_sb, &tloc    
546                 goto end_unlink;                  
547                                                   
548         if (!inode->i_nlink) {                    
549                 udf_debug("Deleting nonexisten    
550                           inode->i_ino, inode-    
551                 set_nlink(inode, 1);              
552         }                                         
553         udf_fiiter_delete_entry(&iter);           
554         inode_set_mtime_to_ts(dir, inode_set_c    
555         mark_inode_dirty(dir);                    
556         inode_dec_link_count(inode);              
557         udf_add_fid_counter(dir->i_sb, false,     
558         inode_set_ctime_to_ts(inode, inode_get    
559         ret = 0;                                  
560 end_unlink:                                       
561         udf_fiiter_release(&iter);                
562 out:                                              
563         return ret;                               
564 }                                                 
565                                                   
566 static int udf_symlink(struct mnt_idmap *idmap    
567                        struct dentry *dentry,     
568 {                                                 
569         struct inode *inode;                      
570         struct pathComponent *pc;                 
571         const char *compstart;                    
572         struct extent_position epos = {};         
573         int eoffset, elen = 0;                    
574         uint8_t *ea;                              
575         int err;                                  
576         udf_pblk_t block;                         
577         unsigned char *name = NULL;               
578         int namelen;                              
579         struct udf_inode_info *iinfo;             
580         struct super_block *sb = dir->i_sb;       
581                                                   
582         name = kmalloc(UDF_NAME_LEN_CS0, GFP_K    
583         if (!name) {                              
584                 err = -ENOMEM;                    
585                 goto out;                         
586         }                                         
587                                                   
588         inode = udf_new_inode(dir, S_IFLNK | 0    
589         if (IS_ERR(inode)) {                      
590                 err = PTR_ERR(inode);             
591                 goto out;                         
592         }                                         
593                                                   
594         iinfo = UDF_I(inode);                     
595         down_write(&iinfo->i_data_sem);           
596         inode->i_data.a_ops = &udf_symlink_aop    
597         inode->i_op = &udf_symlink_inode_opera    
598         inode_nohighmem(inode);                   
599                                                   
600         if (iinfo->i_alloc_type != ICBTAG_FLAG    
601                 struct kernel_lb_addr eloc;       
602                 uint32_t bsize;                   
603                                                   
604                 block = udf_new_block(sb, inod    
605                                 iinfo->i_locat    
606                                 iinfo->i_locat    
607                 if (!block)                       
608                         goto out_no_entry;        
609                 epos.block = iinfo->i_location    
610                 epos.offset = udf_file_entry_a    
611                 epos.bh = NULL;                   
612                 eloc.logicalBlockNum = block;     
613                 eloc.partitionReferenceNum =      
614                                 iinfo->i_locat    
615                 bsize = sb->s_blocksize;          
616                 iinfo->i_lenExtents = bsize;      
617                 err = udf_add_aext(inode, &epo    
618                 brelse(epos.bh);                  
619                 if (err < 0) {                    
620                         udf_free_blocks(sb, in    
621                         goto out_no_entry;        
622                 }                                 
623                                                   
624                 block = udf_get_pblock(sb, blo    
625                                 iinfo->i_locat    
626                                 0);               
627                 epos.bh = sb_getblk(sb, block)    
628                 if (unlikely(!epos.bh)) {         
629                         err = -ENOMEM;            
630                         udf_free_blocks(sb, in    
631                         goto out_no_entry;        
632                 }                                 
633                 lock_buffer(epos.bh);             
634                 memset(epos.bh->b_data, 0x00,     
635                 set_buffer_uptodate(epos.bh);     
636                 unlock_buffer(epos.bh);           
637                 mark_buffer_dirty_inode(epos.b    
638                 ea = epos.bh->b_data + udf_ext    
639         } else                                    
640                 ea = iinfo->i_data + iinfo->i_    
641                                                   
642         eoffset = sb->s_blocksize - udf_ext0_o    
643         pc = (struct pathComponent *)ea;          
644                                                   
645         if (*symname == '/') {                    
646                 do {                              
647                         symname++;                
648                 } while (*symname == '/');        
649                                                   
650                 pc->componentType = 1;            
651                 pc->lengthComponentIdent = 0;     
652                 pc->componentFileVersionNum =     
653                 elen += sizeof(struct pathComp    
654         }                                         
655                                                   
656         err = -ENAMETOOLONG;                      
657                                                   
658         while (*symname) {                        
659                 if (elen + sizeof(struct pathC    
660                         goto out_no_entry;        
661                                                   
662                 pc = (struct pathComponent *)(    
663                                                   
664                 compstart = symname;              
665                                                   
666                 do {                              
667                         symname++;                
668                 } while (*symname && *symname     
669                                                   
670                 pc->componentType = 5;            
671                 pc->lengthComponentIdent = 0;     
672                 pc->componentFileVersionNum =     
673                 if (compstart[0] == '.') {        
674                         if ((symname - compsta    
675                                 pc->componentT    
676                         else if ((symname - co    
677                                         compst    
678                                 pc->componentT    
679                 }                                 
680                                                   
681                 if (pc->componentType == 5) {     
682                         namelen = udf_put_file    
683                                                   
684                                                   
685                         if (!namelen)             
686                                 goto out_no_en    
687                                                   
688                         if (elen + sizeof(stru    
689                                         eoffse    
690                                 goto out_no_en    
691                         else                      
692                                 pc->lengthComp    
693                                                   
694                         memcpy(pc->componentId    
695                 }                                 
696                                                   
697                 elen += sizeof(struct pathComp    
698                                                   
699                 if (*symname) {                   
700                         do {                      
701                                 symname++;        
702                         } while (*symname == '    
703                 }                                 
704         }                                         
705                                                   
706         brelse(epos.bh);                          
707         inode->i_size = elen;                     
708         if (iinfo->i_alloc_type == ICBTAG_FLAG    
709                 iinfo->i_lenAlloc = inode->i_s    
710         else                                      
711                 udf_truncate_tail_extent(inode    
712         mark_inode_dirty(inode);                  
713         up_write(&iinfo->i_data_sem);             
714                                                   
715         err = udf_add_nondir(dentry, inode);      
716 out:                                              
717         kfree(name);                              
718         return err;                               
719                                                   
720 out_no_entry:                                     
721         up_write(&iinfo->i_data_sem);             
722         inode_dec_link_count(inode);              
723         discard_new_inode(inode);                 
724         goto out;                                 
725 }                                                 
726                                                   
727 static int udf_link(struct dentry *old_dentry,    
728                     struct dentry *dentry)        
729 {                                                 
730         struct inode *inode = d_inode(old_dent    
731         struct udf_fileident_iter iter;           
732         int err;                                  
733                                                   
734         err = udf_fiiter_add_entry(dir, dentry    
735         if (err)                                  
736                 return err;                       
737         iter.fi.icb.extLength = cpu_to_le32(in    
738         iter.fi.icb.extLocation = cpu_to_lelb(    
739         if (UDF_SB(inode->i_sb)->s_lvid_bh) {     
740                 *(__le32 *)((struct allocDescI    
741                         cpu_to_le32(lvid_get_u    
742         }                                         
743         udf_fiiter_write_fi(&iter, NULL);         
744         udf_fiiter_release(&iter);                
745                                                   
746         inc_nlink(inode);                         
747         udf_add_fid_counter(dir->i_sb, false,     
748         inode_set_ctime_current(inode);           
749         mark_inode_dirty(inode);                  
750         inode_set_mtime_to_ts(dir, inode_set_c    
751         mark_inode_dirty(dir);                    
752         ihold(inode);                             
753         d_instantiate(dentry, inode);             
754                                                   
755         return 0;                                 
756 }                                                 
757                                                   
758 /* Anybody can rename anything with this: the     
759  * higher-level routines.                         
760  */                                               
761 static int udf_rename(struct mnt_idmap *idmap,    
762                       struct dentry *old_dentr    
763                       struct dentry *new_dentr    
764 {                                                 
765         struct inode *old_inode = d_inode(old_    
766         struct inode *new_inode = d_inode(new_    
767         struct udf_fileident_iter oiter, niter    
768         bool has_diriter = false, is_dir = fal    
769         int retval;                               
770         struct kernel_lb_addr tloc;               
771                                                   
772         if (flags & ~RENAME_NOREPLACE)            
773                 return -EINVAL;                   
774                                                   
775         retval = udf_fiiter_find_entry(old_dir    
776         if (retval)                               
777                 return retval;                    
778                                                   
779         tloc = lelb_to_cpu(oiter.fi.icb.extLoc    
780         if (udf_get_lb_pblock(old_dir->i_sb, &    
781                 retval = -ENOENT;                 
782                 goto out_oiter;                   
783         }                                         
784                                                   
785         if (S_ISDIR(old_inode->i_mode)) {         
786                 if (new_inode) {                  
787                         retval = -ENOTEMPTY;      
788                         if (!empty_dir(new_ino    
789                                 goto out_oiter    
790                 }                                 
791                 is_dir = true;                    
792         }                                         
793         if (is_dir && old_dir != new_dir) {       
794                 retval = udf_fiiter_find_entry    
795                                                   
796                 if (retval == -ENOENT) {          
797                         udf_err(old_inode->i_s    
798                                 "directory (in    
799                                 old_inode->i_i    
800                         retval = -EFSCORRUPTED    
801                 }                                 
802                 if (retval)                       
803                         goto out_oiter;           
804                 has_diriter = true;               
805                 tloc = lelb_to_cpu(diriter.fi.    
806                 if (udf_get_lb_pblock(old_inod    
807                                 old_dir->i_ino    
808                         retval = -EFSCORRUPTED    
809                         udf_err(old_inode->i_s    
810                                 "directory (in    
811                                 old_inode->i_i    
812                                 udf_get_lb_pbl    
813                         goto out_oiter;           
814                 }                                 
815         }                                         
816                                                   
817         retval = udf_fiiter_find_entry(new_dir    
818         if (retval && retval != -ENOENT)          
819                 goto out_oiter;                   
820         /* Entry found but not passed by VFS?     
821         if (!retval && !new_inode) {              
822                 retval = -EFSCORRUPTED;           
823                 udf_fiiter_release(&niter);       
824                 goto out_oiter;                   
825         }                                         
826         /* Entry not found? Need to add one...    
827         if (retval) {                             
828                 udf_fiiter_release(&niter);       
829                 retval = udf_fiiter_add_entry(    
830                 if (retval)                       
831                         goto out_oiter;           
832         }                                         
833                                                   
834         /*                                        
835          * Like most other Unix systems, set t    
836          * rename.                                
837          */                                       
838         inode_set_ctime_current(old_inode);       
839         mark_inode_dirty(old_inode);              
840                                                   
841         /*                                        
842          * ok, that's it                          
843          */                                       
844         niter.fi.fileVersionNum = oiter.fi.fil    
845         niter.fi.fileCharacteristics = oiter.f    
846         memcpy(&(niter.fi.icb), &(oiter.fi.icb    
847         udf_fiiter_write_fi(&niter, NULL);        
848         udf_fiiter_release(&niter);               
849                                                   
850         /*                                        
851          * The old entry may have moved due to    
852          * again.                                 
853          */                                       
854         udf_fiiter_release(&oiter);               
855         retval = udf_fiiter_find_entry(old_dir    
856         if (retval) {                             
857                 udf_err(old_dir->i_sb,            
858                         "failed to find rename    
859                         old_dir->i_ino);          
860         } else {                                  
861                 udf_fiiter_delete_entry(&oiter    
862                 udf_fiiter_release(&oiter);       
863         }                                         
864                                                   
865         if (new_inode) {                          
866                 inode_set_ctime_current(new_in    
867                 inode_dec_link_count(new_inode    
868                 udf_add_fid_counter(old_dir->i    
869                                     -1);          
870         }                                         
871         inode_set_mtime_to_ts(old_dir, inode_s    
872         inode_set_mtime_to_ts(new_dir, inode_s    
873         mark_inode_dirty(old_dir);                
874         mark_inode_dirty(new_dir);                
875                                                   
876         if (has_diriter) {                        
877                 diriter.fi.icb.extLocation =      
878                                         cpu_to    
879                 udf_fiiter_write_fi(&diriter,     
880                 udf_fiiter_release(&diriter);     
881         }                                         
882                                                   
883         if (is_dir) {                             
884                 inode_dec_link_count(old_dir);    
885                 if (new_inode)                    
886                         inode_dec_link_count(n    
887                 else {                            
888                         inc_nlink(new_dir);       
889                         mark_inode_dirty(new_d    
890                 }                                 
891         }                                         
892         return 0;                                 
893 out_oiter:                                        
894         if (has_diriter)                          
895                 udf_fiiter_release(&diriter);     
896         udf_fiiter_release(&oiter);               
897                                                   
898         return retval;                            
899 }                                                 
900                                                   
901 static struct dentry *udf_get_parent(struct de    
902 {                                                 
903         struct kernel_lb_addr tloc;               
904         struct udf_fileident_iter iter;           
905         int err;                                  
906                                                   
907         err = udf_fiiter_find_entry(d_inode(ch    
908         if (err)                                  
909                 return ERR_PTR(err);              
910                                                   
911         tloc = lelb_to_cpu(iter.fi.icb.extLoca    
912         udf_fiiter_release(&iter);                
913         return d_obtain_alias(udf_iget(child->    
914 }                                                 
915                                                   
916                                                   
917 static struct dentry *udf_nfs_get_inode(struct    
918                                         u16 pa    
919 {                                                 
920         struct inode *inode;                      
921         struct kernel_lb_addr loc;                
922                                                   
923         if (block == 0)                           
924                 return ERR_PTR(-ESTALE);          
925                                                   
926         loc.logicalBlockNum = block;              
927         loc.partitionReferenceNum = partref;      
928         inode = udf_iget(sb, &loc);               
929                                                   
930         if (IS_ERR(inode))                        
931                 return ERR_CAST(inode);           
932                                                   
933         if (generation && inode->i_generation     
934                 iput(inode);                      
935                 return ERR_PTR(-ESTALE);          
936         }                                         
937         return d_obtain_alias(inode);             
938 }                                                 
939                                                   
940 static struct dentry *udf_fh_to_dentry(struct     
941                                        struct     
942 {                                                 
943         if (fh_len < 3 ||                         
944             (fh_type != FILEID_UDF_WITH_PARENT    
945              fh_type != FILEID_UDF_WITHOUT_PAR    
946                 return NULL;                      
947                                                   
948         return udf_nfs_get_inode(sb, fid->udf.    
949                         fid->udf.generation);     
950 }                                                 
951                                                   
952 static struct dentry *udf_fh_to_parent(struct     
953                                        struct     
954 {                                                 
955         if (fh_len < 5 || fh_type != FILEID_UD    
956                 return NULL;                      
957                                                   
958         return udf_nfs_get_inode(sb, fid->udf.    
959                                  fid->udf.pare    
960                                  fid->udf.pare    
961 }                                                 
962 static int udf_encode_fh(struct inode *inode,     
963                          struct inode *parent)    
964 {                                                 
965         int len = *lenp;                          
966         struct kernel_lb_addr location = UDF_I    
967         struct fid *fid = (struct fid *)fh;       
968         int type = FILEID_UDF_WITHOUT_PARENT;     
969                                                   
970         if (parent && (len < 5)) {                
971                 *lenp = 5;                        
972                 return FILEID_INVALID;            
973         } else if (len < 3) {                     
974                 *lenp = 3;                        
975                 return FILEID_INVALID;            
976         }                                         
977                                                   
978         *lenp = 3;                                
979         fid->udf.block = location.logicalBlock    
980         fid->udf.partref = location.partitionR    
981         fid->udf.parent_partref = 0;              
982         fid->udf.generation = inode->i_generat    
983                                                   
984         if (parent) {                             
985                 location = UDF_I(parent)->i_lo    
986                 fid->udf.parent_block = locati    
987                 fid->udf.parent_partref = loca    
988                 fid->udf.parent_generation = i    
989                 *lenp = 5;                        
990                 type = FILEID_UDF_WITH_PARENT;    
991         }                                         
992                                                   
993         return type;                              
994 }                                                 
995                                                   
996 const struct export_operations udf_export_ops     
997         .encode_fh      = udf_encode_fh,          
998         .fh_to_dentry   = udf_fh_to_dentry,       
999         .fh_to_parent   = udf_fh_to_parent,       
1000         .get_parent     = udf_get_parent,        
1001 };                                               
1002                                                  
1003 const struct inode_operations udf_dir_inode_o    
1004         .lookup                         = udf    
1005         .create                         = udf    
1006         .link                           = udf    
1007         .unlink                         = udf    
1008         .symlink                        = udf    
1009         .mkdir                          = udf    
1010         .rmdir                          = udf    
1011         .mknod                          = udf    
1012         .rename                         = udf    
1013         .tmpfile                        = udf    
1014 };                                               
1015                                                  

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