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

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

Version: ~ [ linux-6.11-rc3 ] ~ [ linux-6.10.4 ] ~ [ linux-6.9.12 ] ~ [ linux-6.8.12 ] ~ [ linux-6.7.12 ] ~ [ linux-6.6.45 ] ~ [ linux-6.5.13 ] ~ [ linux-6.4.16 ] ~ [ linux-6.3.13 ] ~ [ linux-6.2.16 ] ~ [ linux-6.1.104 ] ~ [ linux-6.0.19 ] ~ [ linux-5.19.17 ] ~ [ linux-5.18.19 ] ~ [ linux-5.17.15 ] ~ [ linux-5.16.20 ] ~ [ linux-5.15.164 ] ~ [ linux-5.14.21 ] ~ [ linux-5.13.19 ] ~ [ linux-5.12.19 ] ~ [ linux-5.11.22 ] ~ [ linux-5.10.223 ] ~ [ linux-5.9.16 ] ~ [ linux-5.8.18 ] ~ [ linux-5.7.19 ] ~ [ linux-5.6.19 ] ~ [ linux-5.5.19 ] ~ [ linux-5.4.281 ] ~ [ linux-5.3.18 ] ~ [ linux-5.2.21 ] ~ [ linux-5.1.21 ] ~ [ linux-5.0.21 ] ~ [ linux-4.20.17 ] ~ [ linux-4.19.319 ] ~ [ 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 ] ~

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

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