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

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

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

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