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

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

Version: ~ [ linux-5.18-rc6 ] ~ [ linux-5.17.6 ] ~ [ linux-5.16.20 ] ~ [ linux-5.15.38 ] ~ [ linux-5.14.21 ] ~ [ linux-5.13.19 ] ~ [ linux-5.12.19 ] ~ [ linux-5.11.22 ] ~ [ linux-5.10.114 ] ~ [ linux-5.9.16 ] ~ [ linux-5.8.18 ] ~ [ linux-5.7.19 ] ~ [ linux-5.6.19 ] ~ [ linux-5.5.19 ] ~ [ linux-5.4.192 ] ~ [ linux-5.3.18 ] ~ [ linux-5.2.21 ] ~ [ linux-5.1.21 ] ~ [ linux-5.0.21 ] ~ [ linux-4.20.17 ] ~ [ linux-4.19.241 ] ~ [ linux-4.18.20 ] ~ [ linux-4.17.19 ] ~ [ linux-4.16.18 ] ~ [ linux-4.15.18 ] ~ [ linux-4.14.277 ] ~ [ linux-4.13.16 ] ~ [ linux-4.12.14 ] ~ [ linux-4.11.12 ] ~ [ linux-4.10.17 ] ~ [ linux-4.9.312 ] ~ [ linux-4.8.17 ] ~ [ linux-4.7.10 ] ~ [ linux-4.6.7 ] ~ [ linux-4.5.7 ] ~ [ linux-4.4.302 ] ~ [ linux-4.3.6 ] ~ [ linux-4.2.8 ] ~ [ linux-4.1.52 ] ~ [ linux-4.0.9 ] ~ [ 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 ] ~

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