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

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

Version: ~ [ linux-5.5-rc7 ] ~ [ linux-5.4.13 ] ~ [ linux-5.3.18 ] ~ [ linux-5.2.21 ] ~ [ linux-5.1.21 ] ~ [ linux-5.0.21 ] ~ [ linux-4.20.17 ] ~ [ linux-4.19.97 ] ~ [ linux-4.18.20 ] ~ [ linux-4.17.19 ] ~ [ linux-4.16.18 ] ~ [ linux-4.15.18 ] ~ [ linux-4.14.166 ] ~ [ linux-4.13.16 ] ~ [ linux-4.12.14 ] ~ [ linux-4.11.12 ] ~ [ linux-4.10.17 ] ~ [ linux-4.9.210 ] ~ [ linux-4.8.17 ] ~ [ linux-4.7.10 ] ~ [ linux-4.6.7 ] ~ [ linux-4.5.7 ] ~ [ linux-4.4.210 ] ~ [ linux-4.3.6 ] ~ [ linux-4.2.8 ] ~ [ linux-4.1.52 ] ~ [ linux-4.0.9 ] ~ [ linux-3.19.8 ] ~ [ linux-3.18.140 ] ~ [ linux-3.17.8 ] ~ [ linux-3.16.81 ] ~ [ linux-3.15.10 ] ~ [ linux-3.14.79 ] ~ [ linux-3.13.11 ] ~ [ linux-3.12.74 ] ~ [ linux-3.11.10 ] ~ [ linux-3.10.108 ] ~ [ linux-3.9.11 ] ~ [ linux-3.8.13 ] ~ [ linux-3.7.10 ] ~ [ linux-3.6.11 ] ~ [ linux-3.5.7 ] ~ [ linux-3.4.113 ] ~ [ linux-3.3.8 ] ~ [ linux-3.2.102 ] ~ [ linux-3.1.10 ] ~ [ linux-3.0.101 ] ~ [ linux-2.6.32.71 ] ~ [ linux-2.6.0 ] ~ [ linux-2.4.37.11 ] ~ [ unix-v6-master ] ~ [ ccs-tools-1.8.5 ] ~ [ policy-sample ] ~
Architecture: ~ [ i386 ] ~ [ alpha ] ~ [ m68k ] ~ [ mips ] ~ [ ppc ] ~ [ sparc ] ~ [ sparc64 ] ~

  1 /*
  2  *  linux/fs/hpfs/namei.c
  3  *
  4  *  Mikulas Patocka (mikulas@artax.karlin.mff.cuni.cz), 1998-1999
  5  *
  6  *  adding & removing files & directories
  7  */
  8 #include <linux/sched.h>
  9 #include "hpfs_fn.h"
 10 
 11 static int hpfs_mkdir(struct inode *dir, struct dentry *dentry, int mode)
 12 {
 13         const unsigned char *name = dentry->d_name.name;
 14         unsigned len = dentry->d_name.len;
 15         struct quad_buffer_head qbh0;
 16         struct buffer_head *bh;
 17         struct hpfs_dirent *de;
 18         struct fnode *fnode;
 19         struct dnode *dnode;
 20         struct inode *result;
 21         fnode_secno fno;
 22         dnode_secno dno;
 23         int r;
 24         struct hpfs_dirent dee;
 25         int err;
 26         if ((err = hpfs_chk_name(name, &len))) return err==-ENOENT ? -EINVAL : err;
 27         hpfs_lock(dir->i_sb);
 28         err = -ENOSPC;
 29         fnode = hpfs_alloc_fnode(dir->i_sb, hpfs_i(dir)->i_dno, &fno, &bh);
 30         if (!fnode)
 31                 goto bail;
 32         dnode = hpfs_alloc_dnode(dir->i_sb, fno, &dno, &qbh0);
 33         if (!dnode)
 34                 goto bail1;
 35         memset(&dee, 0, sizeof dee);
 36         dee.directory = 1;
 37         if (!(mode & 0222)) dee.read_only = 1;
 38         /*dee.archive = 0;*/
 39         dee.hidden = name[0] == '.';
 40         dee.fnode = cpu_to_le32(fno);
 41         dee.creation_date = dee.write_date = dee.read_date = cpu_to_le32(gmt_to_local(dir->i_sb, get_seconds()));
 42         result = new_inode(dir->i_sb);
 43         if (!result)
 44                 goto bail2;
 45         hpfs_init_inode(result);
 46         result->i_ino = fno;
 47         hpfs_i(result)->i_parent_dir = dir->i_ino;
 48         hpfs_i(result)->i_dno = dno;
 49         result->i_ctime.tv_sec = result->i_mtime.tv_sec = result->i_atime.tv_sec = local_to_gmt(dir->i_sb, le32_to_cpu(dee.creation_date));
 50         result->i_ctime.tv_nsec = 0; 
 51         result->i_mtime.tv_nsec = 0; 
 52         result->i_atime.tv_nsec = 0; 
 53         hpfs_i(result)->i_ea_size = 0;
 54         result->i_mode |= S_IFDIR;
 55         result->i_op = &hpfs_dir_iops;
 56         result->i_fop = &hpfs_dir_ops;
 57         result->i_blocks = 4;
 58         result->i_size = 2048;
 59         result->i_nlink = 2;
 60         if (dee.read_only)
 61                 result->i_mode &= ~0222;
 62 
 63         r = hpfs_add_dirent(dir, name, len, &dee);
 64         if (r == 1)
 65                 goto bail3;
 66         if (r == -1) {
 67                 err = -EEXIST;
 68                 goto bail3;
 69         }
 70         fnode->len = len;
 71         memcpy(fnode->name, name, len > 15 ? 15 : len);
 72         fnode->up = cpu_to_le32(dir->i_ino);
 73         fnode->dirflag = 1;
 74         fnode->btree.n_free_nodes = 7;
 75         fnode->btree.n_used_nodes = 1;
 76         fnode->btree.first_free = cpu_to_le16(0x14);
 77         fnode->u.external[0].disk_secno = cpu_to_le32(dno);
 78         fnode->u.external[0].file_secno = cpu_to_le32(-1);
 79         dnode->root_dnode = 1;
 80         dnode->up = cpu_to_le32(fno);
 81         de = hpfs_add_de(dir->i_sb, dnode, "\001\001", 2, 0);
 82         de->creation_date = de->write_date = de->read_date = cpu_to_le32(gmt_to_local(dir->i_sb, get_seconds()));
 83         if (!(mode & 0222)) de->read_only = 1;
 84         de->first = de->directory = 1;
 85         /*de->hidden = de->system = 0;*/
 86         de->fnode = cpu_to_le32(fno);
 87         mark_buffer_dirty(bh);
 88         brelse(bh);
 89         hpfs_mark_4buffers_dirty(&qbh0);
 90         hpfs_brelse4(&qbh0);
 91         inc_nlink(dir);
 92         insert_inode_hash(result);
 93 
 94         if (result->i_uid != current_fsuid() ||
 95             result->i_gid != current_fsgid() ||
 96             result->i_mode != (mode | S_IFDIR)) {
 97                 result->i_uid = current_fsuid();
 98                 result->i_gid = current_fsgid();
 99                 result->i_mode = mode | S_IFDIR;
100                 hpfs_write_inode_nolock(result);
101         }
102         d_instantiate(dentry, result);
103         hpfs_unlock(dir->i_sb);
104         return 0;
105 bail3:
106         iput(result);
107 bail2:
108         hpfs_brelse4(&qbh0);
109         hpfs_free_dnode(dir->i_sb, dno);
110 bail1:
111         brelse(bh);
112         hpfs_free_sectors(dir->i_sb, fno, 1);
113 bail:
114         hpfs_unlock(dir->i_sb);
115         return err;
116 }
117 
118 static int hpfs_create(struct inode *dir, struct dentry *dentry, int mode, struct nameidata *nd)
119 {
120         const unsigned char *name = dentry->d_name.name;
121         unsigned len = dentry->d_name.len;
122         struct inode *result = NULL;
123         struct buffer_head *bh;
124         struct fnode *fnode;
125         fnode_secno fno;
126         int r;
127         struct hpfs_dirent dee;
128         int err;
129         if ((err = hpfs_chk_name(name, &len)))
130                 return err==-ENOENT ? -EINVAL : err;
131         hpfs_lock(dir->i_sb);
132         err = -ENOSPC;
133         fnode = hpfs_alloc_fnode(dir->i_sb, hpfs_i(dir)->i_dno, &fno, &bh);
134         if (!fnode)
135                 goto bail;
136         memset(&dee, 0, sizeof dee);
137         if (!(mode & 0222)) dee.read_only = 1;
138         dee.archive = 1;
139         dee.hidden = name[0] == '.';
140         dee.fnode = cpu_to_le32(fno);
141         dee.creation_date = dee.write_date = dee.read_date = cpu_to_le32(gmt_to_local(dir->i_sb, get_seconds()));
142 
143         result = new_inode(dir->i_sb);
144         if (!result)
145                 goto bail1;
146         
147         hpfs_init_inode(result);
148         result->i_ino = fno;
149         result->i_mode |= S_IFREG;
150         result->i_mode &= ~0111;
151         result->i_op = &hpfs_file_iops;
152         result->i_fop = &hpfs_file_ops;
153         result->i_nlink = 1;
154         hpfs_i(result)->i_parent_dir = dir->i_ino;
155         result->i_ctime.tv_sec = result->i_mtime.tv_sec = result->i_atime.tv_sec = local_to_gmt(dir->i_sb, le32_to_cpu(dee.creation_date));
156         result->i_ctime.tv_nsec = 0;
157         result->i_mtime.tv_nsec = 0;
158         result->i_atime.tv_nsec = 0;
159         hpfs_i(result)->i_ea_size = 0;
160         if (dee.read_only)
161                 result->i_mode &= ~0222;
162         result->i_blocks = 1;
163         result->i_size = 0;
164         result->i_data.a_ops = &hpfs_aops;
165         hpfs_i(result)->mmu_private = 0;
166 
167         r = hpfs_add_dirent(dir, name, len, &dee);
168         if (r == 1)
169                 goto bail2;
170         if (r == -1) {
171                 err = -EEXIST;
172                 goto bail2;
173         }
174         fnode->len = len;
175         memcpy(fnode->name, name, len > 15 ? 15 : len);
176         fnode->up = cpu_to_le32(dir->i_ino);
177         mark_buffer_dirty(bh);
178         brelse(bh);
179 
180         insert_inode_hash(result);
181 
182         if (result->i_uid != current_fsuid() ||
183             result->i_gid != current_fsgid() ||
184             result->i_mode != (mode | S_IFREG)) {
185                 result->i_uid = current_fsuid();
186                 result->i_gid = current_fsgid();
187                 result->i_mode = mode | S_IFREG;
188                 hpfs_write_inode_nolock(result);
189         }
190         d_instantiate(dentry, result);
191         hpfs_unlock(dir->i_sb);
192         return 0;
193 
194 bail2:
195         iput(result);
196 bail1:
197         brelse(bh);
198         hpfs_free_sectors(dir->i_sb, fno, 1);
199 bail:
200         hpfs_unlock(dir->i_sb);
201         return err;
202 }
203 
204 static int hpfs_mknod(struct inode *dir, struct dentry *dentry, int mode, dev_t rdev)
205 {
206         const unsigned char *name = dentry->d_name.name;
207         unsigned len = dentry->d_name.len;
208         struct buffer_head *bh;
209         struct fnode *fnode;
210         fnode_secno fno;
211         int r;
212         struct hpfs_dirent dee;
213         struct inode *result = NULL;
214         int err;
215         if ((err = hpfs_chk_name(name, &len))) return err==-ENOENT ? -EINVAL : err;
216         if (hpfs_sb(dir->i_sb)->sb_eas < 2) return -EPERM;
217         if (!new_valid_dev(rdev))
218                 return -EINVAL;
219         hpfs_lock(dir->i_sb);
220         err = -ENOSPC;
221         fnode = hpfs_alloc_fnode(dir->i_sb, hpfs_i(dir)->i_dno, &fno, &bh);
222         if (!fnode)
223                 goto bail;
224         memset(&dee, 0, sizeof dee);
225         if (!(mode & 0222)) dee.read_only = 1;
226         dee.archive = 1;
227         dee.hidden = name[0] == '.';
228         dee.fnode = cpu_to_le32(fno);
229         dee.creation_date = dee.write_date = dee.read_date = cpu_to_le32(gmt_to_local(dir->i_sb, get_seconds()));
230 
231         result = new_inode(dir->i_sb);
232         if (!result)
233                 goto bail1;
234 
235         hpfs_init_inode(result);
236         result->i_ino = fno;
237         hpfs_i(result)->i_parent_dir = dir->i_ino;
238         result->i_ctime.tv_sec = result->i_mtime.tv_sec = result->i_atime.tv_sec = local_to_gmt(dir->i_sb, le32_to_cpu(dee.creation_date));
239         result->i_ctime.tv_nsec = 0;
240         result->i_mtime.tv_nsec = 0;
241         result->i_atime.tv_nsec = 0;
242         hpfs_i(result)->i_ea_size = 0;
243         result->i_uid = current_fsuid();
244         result->i_gid = current_fsgid();
245         result->i_nlink = 1;
246         result->i_size = 0;
247         result->i_blocks = 1;
248         init_special_inode(result, mode, rdev);
249 
250         r = hpfs_add_dirent(dir, name, len, &dee);
251         if (r == 1)
252                 goto bail2;
253         if (r == -1) {
254                 err = -EEXIST;
255                 goto bail2;
256         }
257         fnode->len = len;
258         memcpy(fnode->name, name, len > 15 ? 15 : len);
259         fnode->up = cpu_to_le32(dir->i_ino);
260         mark_buffer_dirty(bh);
261 
262         insert_inode_hash(result);
263 
264         hpfs_write_inode_nolock(result);
265         d_instantiate(dentry, result);
266         brelse(bh);
267         hpfs_unlock(dir->i_sb);
268         return 0;
269 bail2:
270         iput(result);
271 bail1:
272         brelse(bh);
273         hpfs_free_sectors(dir->i_sb, fno, 1);
274 bail:
275         hpfs_unlock(dir->i_sb);
276         return err;
277 }
278 
279 static int hpfs_symlink(struct inode *dir, struct dentry *dentry, const char *symlink)
280 {
281         const unsigned char *name = dentry->d_name.name;
282         unsigned len = dentry->d_name.len;
283         struct buffer_head *bh;
284         struct fnode *fnode;
285         fnode_secno fno;
286         int r;
287         struct hpfs_dirent dee;
288         struct inode *result;
289         int err;
290         if ((err = hpfs_chk_name(name, &len))) return err==-ENOENT ? -EINVAL : err;
291         hpfs_lock(dir->i_sb);
292         if (hpfs_sb(dir->i_sb)->sb_eas < 2) {
293                 hpfs_unlock(dir->i_sb);
294                 return -EPERM;
295         }
296         err = -ENOSPC;
297         fnode = hpfs_alloc_fnode(dir->i_sb, hpfs_i(dir)->i_dno, &fno, &bh);
298         if (!fnode)
299                 goto bail;
300         memset(&dee, 0, sizeof dee);
301         dee.archive = 1;
302         dee.hidden = name[0] == '.';
303         dee.fnode = cpu_to_le32(fno);
304         dee.creation_date = dee.write_date = dee.read_date = cpu_to_le32(gmt_to_local(dir->i_sb, get_seconds()));
305 
306         result = new_inode(dir->i_sb);
307         if (!result)
308                 goto bail1;
309         result->i_ino = fno;
310         hpfs_init_inode(result);
311         hpfs_i(result)->i_parent_dir = dir->i_ino;
312         result->i_ctime.tv_sec = result->i_mtime.tv_sec = result->i_atime.tv_sec = local_to_gmt(dir->i_sb, le32_to_cpu(dee.creation_date));
313         result->i_ctime.tv_nsec = 0;
314         result->i_mtime.tv_nsec = 0;
315         result->i_atime.tv_nsec = 0;
316         hpfs_i(result)->i_ea_size = 0;
317         result->i_mode = S_IFLNK | 0777;
318         result->i_uid = current_fsuid();
319         result->i_gid = current_fsgid();
320         result->i_blocks = 1;
321         result->i_nlink = 1;
322         result->i_size = strlen(symlink);
323         result->i_op = &page_symlink_inode_operations;
324         result->i_data.a_ops = &hpfs_symlink_aops;
325 
326         r = hpfs_add_dirent(dir, name, len, &dee);
327         if (r == 1)
328                 goto bail2;
329         if (r == -1) {
330                 err = -EEXIST;
331                 goto bail2;
332         }
333         fnode->len = len;
334         memcpy(fnode->name, name, len > 15 ? 15 : len);
335         fnode->up = cpu_to_le32(dir->i_ino);
336         hpfs_set_ea(result, fnode, "SYMLINK", symlink, strlen(symlink));
337         mark_buffer_dirty(bh);
338         brelse(bh);
339 
340         insert_inode_hash(result);
341 
342         hpfs_write_inode_nolock(result);
343         d_instantiate(dentry, result);
344         hpfs_unlock(dir->i_sb);
345         return 0;
346 bail2:
347         iput(result);
348 bail1:
349         brelse(bh);
350         hpfs_free_sectors(dir->i_sb, fno, 1);
351 bail:
352         hpfs_unlock(dir->i_sb);
353         return err;
354 }
355 
356 static int hpfs_unlink(struct inode *dir, struct dentry *dentry)
357 {
358         const unsigned char *name = dentry->d_name.name;
359         unsigned len = dentry->d_name.len;
360         struct quad_buffer_head qbh;
361         struct hpfs_dirent *de;
362         struct inode *inode = dentry->d_inode;
363         dnode_secno dno;
364         int r;
365         int rep = 0;
366         int err;
367 
368         hpfs_lock(dir->i_sb);
369         hpfs_adjust_length(name, &len);
370 again:
371         err = -ENOENT;
372         de = map_dirent(dir, hpfs_i(dir)->i_dno, name, len, &dno, &qbh);
373         if (!de)
374                 goto out;
375 
376         err = -EPERM;
377         if (de->first)
378                 goto out1;
379 
380         err = -EISDIR;
381         if (de->directory)
382                 goto out1;
383 
384         r = hpfs_remove_dirent(dir, dno, de, &qbh, 1);
385         switch (r) {
386         case 1:
387                 hpfs_error(dir->i_sb, "there was error when removing dirent");
388                 err = -EFSERROR;
389                 break;
390         case 2:         /* no space for deleting, try to truncate file */
391 
392                 err = -ENOSPC;
393                 if (rep++)
394                         break;
395 
396                 dentry_unhash(dentry);
397                 if (!d_unhashed(dentry)) {
398                         hpfs_unlock(dir->i_sb);
399                         return -ENOSPC;
400                 }
401                 if (generic_permission(inode, MAY_WRITE) ||
402                     !S_ISREG(inode->i_mode) ||
403                     get_write_access(inode)) {
404                         d_rehash(dentry);
405                 } else {
406                         struct iattr newattrs;
407                         /*printk("HPFS: truncating file before delete.\n");*/
408                         newattrs.ia_size = 0;
409                         newattrs.ia_valid = ATTR_SIZE | ATTR_CTIME;
410                         err = notify_change(dentry, &newattrs);
411                         put_write_access(inode);
412                         if (!err)
413                                 goto again;
414                 }
415                 hpfs_unlock(dir->i_sb);
416                 return -ENOSPC;
417         default:
418                 drop_nlink(inode);
419                 err = 0;
420         }
421         goto out;
422 
423 out1:
424         hpfs_brelse4(&qbh);
425 out:
426         hpfs_unlock(dir->i_sb);
427         return err;
428 }
429 
430 static int hpfs_rmdir(struct inode *dir, struct dentry *dentry)
431 {
432         const unsigned char *name = dentry->d_name.name;
433         unsigned len = dentry->d_name.len;
434         struct quad_buffer_head qbh;
435         struct hpfs_dirent *de;
436         struct inode *inode = dentry->d_inode;
437         dnode_secno dno;
438         int n_items = 0;
439         int err;
440         int r;
441 
442         hpfs_adjust_length(name, &len);
443         hpfs_lock(dir->i_sb);
444         err = -ENOENT;
445         de = map_dirent(dir, hpfs_i(dir)->i_dno, name, len, &dno, &qbh);
446         if (!de)
447                 goto out;
448 
449         err = -EPERM;
450         if (de->first)
451                 goto out1;
452 
453         err = -ENOTDIR;
454         if (!de->directory)
455                 goto out1;
456 
457         hpfs_count_dnodes(dir->i_sb, hpfs_i(inode)->i_dno, NULL, NULL, &n_items);
458         err = -ENOTEMPTY;
459         if (n_items)
460                 goto out1;
461 
462         r = hpfs_remove_dirent(dir, dno, de, &qbh, 1);
463         switch (r) {
464         case 1:
465                 hpfs_error(dir->i_sb, "there was error when removing dirent");
466                 err = -EFSERROR;
467                 break;
468         case 2:
469                 err = -ENOSPC;
470                 break;
471         default:
472                 drop_nlink(dir);
473                 clear_nlink(inode);
474                 err = 0;
475         }
476         goto out;
477 out1:
478         hpfs_brelse4(&qbh);
479 out:
480         hpfs_unlock(dir->i_sb);
481         return err;
482 }
483 
484 static int hpfs_symlink_readpage(struct file *file, struct page *page)
485 {
486         char *link = kmap(page);
487         struct inode *i = page->mapping->host;
488         struct fnode *fnode;
489         struct buffer_head *bh;
490         int err;
491 
492         err = -EIO;
493         hpfs_lock(i->i_sb);
494         if (!(fnode = hpfs_map_fnode(i->i_sb, i->i_ino, &bh)))
495                 goto fail;
496         err = hpfs_read_ea(i->i_sb, fnode, "SYMLINK", link, PAGE_SIZE);
497         brelse(bh);
498         if (err)
499                 goto fail;
500         hpfs_unlock(i->i_sb);
501         SetPageUptodate(page);
502         kunmap(page);
503         unlock_page(page);
504         return 0;
505 
506 fail:
507         hpfs_unlock(i->i_sb);
508         SetPageError(page);
509         kunmap(page);
510         unlock_page(page);
511         return err;
512 }
513 
514 const struct address_space_operations hpfs_symlink_aops = {
515         .readpage       = hpfs_symlink_readpage
516 };
517         
518 static int hpfs_rename(struct inode *old_dir, struct dentry *old_dentry,
519                 struct inode *new_dir, struct dentry *new_dentry)
520 {
521         const unsigned char *old_name = old_dentry->d_name.name;
522         unsigned old_len = old_dentry->d_name.len;
523         const unsigned char *new_name = new_dentry->d_name.name;
524         unsigned new_len = new_dentry->d_name.len;
525         struct inode *i = old_dentry->d_inode;
526         struct inode *new_inode = new_dentry->d_inode;
527         struct quad_buffer_head qbh, qbh1;
528         struct hpfs_dirent *dep, *nde;
529         struct hpfs_dirent de;
530         dnode_secno dno;
531         int r;
532         struct buffer_head *bh;
533         struct fnode *fnode;
534         int err;
535 
536         if ((err = hpfs_chk_name(new_name, &new_len))) return err;
537         err = 0;
538         hpfs_adjust_length(old_name, &old_len);
539 
540         hpfs_lock(i->i_sb);
541         /* order doesn't matter, due to VFS exclusion */
542         
543         /* Erm? Moving over the empty non-busy directory is perfectly legal */
544         if (new_inode && S_ISDIR(new_inode->i_mode)) {
545                 err = -EINVAL;
546                 goto end1;
547         }
548 
549         if (!(dep = map_dirent(old_dir, hpfs_i(old_dir)->i_dno, old_name, old_len, &dno, &qbh))) {
550                 hpfs_error(i->i_sb, "lookup succeeded but map dirent failed");
551                 err = -ENOENT;
552                 goto end1;
553         }
554         copy_de(&de, dep);
555         de.hidden = new_name[0] == '.';
556 
557         if (new_inode) {
558                 int r;
559                 if ((r = hpfs_remove_dirent(old_dir, dno, dep, &qbh, 1)) != 2) {
560                         if ((nde = map_dirent(new_dir, hpfs_i(new_dir)->i_dno, new_name, new_len, NULL, &qbh1))) {
561                                 clear_nlink(new_inode);
562                                 copy_de(nde, &de);
563                                 memcpy(nde->name, new_name, new_len);
564                                 hpfs_mark_4buffers_dirty(&qbh1);
565                                 hpfs_brelse4(&qbh1);
566                                 goto end;
567                         }
568                         hpfs_error(new_dir->i_sb, "hpfs_rename: could not find dirent");
569                         err = -EFSERROR;
570                         goto end1;
571                 }
572                 err = r == 2 ? -ENOSPC : r == 1 ? -EFSERROR : 0;
573                 goto end1;
574         }
575 
576         if (new_dir == old_dir) hpfs_brelse4(&qbh);
577 
578         if ((r = hpfs_add_dirent(new_dir, new_name, new_len, &de))) {
579                 if (r == -1) hpfs_error(new_dir->i_sb, "hpfs_rename: dirent already exists!");
580                 err = r == 1 ? -ENOSPC : -EFSERROR;
581                 if (new_dir != old_dir) hpfs_brelse4(&qbh);
582                 goto end1;
583         }
584         
585         if (new_dir == old_dir)
586                 if (!(dep = map_dirent(old_dir, hpfs_i(old_dir)->i_dno, old_name, old_len, &dno, &qbh))) {
587                         hpfs_error(i->i_sb, "lookup succeeded but map dirent failed at #2");
588                         err = -ENOENT;
589                         goto end1;
590                 }
591 
592         if ((r = hpfs_remove_dirent(old_dir, dno, dep, &qbh, 0))) {
593                 hpfs_error(i->i_sb, "hpfs_rename: could not remove dirent");
594                 err = r == 2 ? -ENOSPC : -EFSERROR;
595                 goto end1;
596         }
597 
598         end:
599         hpfs_i(i)->i_parent_dir = new_dir->i_ino;
600         if (S_ISDIR(i->i_mode)) {
601                 inc_nlink(new_dir);
602                 drop_nlink(old_dir);
603         }
604         if ((fnode = hpfs_map_fnode(i->i_sb, i->i_ino, &bh))) {
605                 fnode->up = cpu_to_le32(new_dir->i_ino);
606                 fnode->len = new_len;
607                 memcpy(fnode->name, new_name, new_len>15?15:new_len);
608                 if (new_len < 15) memset(&fnode->name[new_len], 0, 15 - new_len);
609                 mark_buffer_dirty(bh);
610                 brelse(bh);
611         }
612 end1:
613         hpfs_unlock(i->i_sb);
614         return err;
615 }
616 
617 const struct inode_operations hpfs_dir_iops =
618 {
619         .create         = hpfs_create,
620         .lookup         = hpfs_lookup,
621         .unlink         = hpfs_unlink,
622         .symlink        = hpfs_symlink,
623         .mkdir          = hpfs_mkdir,
624         .rmdir          = hpfs_rmdir,
625         .mknod          = hpfs_mknod,
626         .rename         = hpfs_rename,
627         .setattr        = hpfs_setattr,
628 };
629 

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

kernel.org | git.kernel.org | LWN.net | Project Home | Wiki (Japanese) | Wiki (English) | 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.

osdn.jp