This source file includes following definitions.
- str_upper
- str_lower
- smb_dir_read
- smb_readdir
- smb_init_dir_cache
- smb_invalid_dir_cache
- smb_free_dir_cache
- get_pname_static
- get_pname
- put_pname
- smb_iget
- smb_free_inode_info
- smb_init_root
- smb_stat_root
- smb_free_all_inodes
- smb_invalidate_all_inodes
- smb_find_inode
- smb_lookup
- smb_create
- smb_mkdir
- smb_rmdir
- smb_unlink
- smb_rename
1
2
3
4
5
6
7
8 #include <linux/sched.h>
9 #include <linux/errno.h>
10 #include <linux/stat.h>
11 #include <linux/kernel.h>
12 #include <linux/malloc.h>
13 #include <linux/mm.h>
14 #include <linux/smb_fs.h>
15 #include <asm/segment.h>
16 #include <linux/errno.h>
17
18 #define NAME_OFFSET(de) ((int) ((de)->d_name - (char *) (de)))
19 #define ROUND_UP(x) (((x)+3) & ~3)
20
21 static int
22 smb_dir_read(struct inode *inode, struct file *filp, char *buf, int count);
23
24 static int
25 smb_readdir(struct inode *inode, struct file *filp,
26 void *dirent, filldir_t filldir);
27
28 static int
29 get_pname(struct inode *dir, const char *name, int len,
30 char **res_path, int *res_len);
31
32 static int
33 get_pname_static(struct inode *dir, const char *name, int len,
34 char *path, int *res_len);
35
36 static struct inode *
37 smb_iget(struct inode *dir, char *path, struct smb_dirent *finfo);
38
39 static void
40 put_pname(char *path);
41
42 static struct smb_inode_info *
43 smb_find_inode(struct smb_server *server, const char *path);
44
45 static int
46 smb_lookup(struct inode *dir, const char *__name,
47 int len, struct inode **result);
48
49 static int
50 smb_create(struct inode *dir, const char *name, int len, int mode,
51 struct inode **result);
52
53 static int
54 smb_mkdir(struct inode *dir, const char *name, int len, int mode);
55
56 static int
57 smb_rmdir(struct inode *dir, const char *name, int len);
58
59 static int
60 smb_unlink(struct inode *dir, const char *name, int len);
61
62 static int
63 smb_rename(struct inode *old_dir, const char *old_name, int old_len,
64 struct inode *new_dir, const char *new_name, int new_len);
65
66 static inline void str_upper(char *name)
67 {
68 while (*name) {
69 if (*name >= 'a' && *name <= 'z')
70 *name -= ('a' - 'A');
71 name++;
72 }
73 }
74
75 static inline void str_lower(char *name)
76 {
77 while (*name) {
78 if (*name >= 'A' && *name <= 'Z')
79 *name += ('a' - 'A');
80 name ++;
81 }
82 }
83
84 static struct file_operations smb_dir_operations = {
85 NULL,
86 smb_dir_read,
87 NULL,
88 smb_readdir,
89 NULL,
90 smb_ioctl,
91 NULL,
92 NULL,
93 NULL,
94 NULL
95 };
96
97 struct inode_operations smb_dir_inode_operations =
98 {
99 &smb_dir_operations,
100 smb_create,
101 smb_lookup,
102 NULL,
103 smb_unlink,
104 NULL,
105 smb_mkdir,
106 smb_rmdir,
107 NULL,
108 smb_rename,
109 NULL,
110 NULL,
111 NULL,
112 NULL,
113 NULL,
114 NULL
115 };
116
117
118 static int
119 smb_dir_read(struct inode *inode, struct file *filp, char *buf, int count)
120 {
121 return -EISDIR;
122 }
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149 static unsigned long c_ino = 0;
150 static int c_size;
151 static int c_seen_eof;
152 static int c_last_returned_index;
153 static struct smb_dirent* c_entry = NULL;
154
155 static int
156 smb_readdir(struct inode *inode, struct file *filp,
157 void *dirent, filldir_t filldir)
158 {
159 int result, i = 0;
160 int index = 0;
161 struct smb_dirent *entry = NULL;
162 struct smb_server *server = SMB_SERVER(inode);
163
164 DDPRINTK("smb_readdir: filp->f_pos = %d\n", (int)filp->f_pos);
165 DDPRINTK("smb_readdir: inode->i_ino = %ld, c_ino = %ld\n",
166 inode->i_ino, c_ino);
167
168 if (!inode || !S_ISDIR(inode->i_mode)) {
169 printk("smb_readdir: inode is NULL or not a directory\n");
170 return -EBADF;
171 }
172
173 if (c_entry == NULL)
174 {
175 i = sizeof (struct smb_dirent) * SMB_READDIR_CACHE_SIZE;
176 c_entry = (struct smb_dirent *) smb_kmalloc(i, GFP_KERNEL);
177 if (c_entry == NULL) {
178 printk("smb_readdir: no MEMORY for cache\n");
179 return -ENOMEM;
180 }
181 for (i = 0; i < SMB_READDIR_CACHE_SIZE; i++) {
182 c_entry[i].path =
183 (char *) smb_kmalloc(SMB_MAXNAMELEN + 1,
184 GFP_KERNEL);
185 if (c_entry[i].path == NULL) {
186 DPRINTK("smb_readdir: could not alloc path\n");
187 while (--i>=0)
188 kfree(c_entry[i].path);
189 kfree(c_entry);
190 c_entry = NULL;
191 return -ENOMEM;
192 }
193 }
194 }
195
196 if (filp->f_pos == 0) {
197 smb_invalid_dir_cache(inode->i_ino);
198 }
199
200 if (inode->i_ino == c_ino) {
201 for (i = 0; i < c_size; i++) {
202 if (filp->f_pos == c_entry[i].f_pos) {
203 entry = &c_entry[i];
204 c_last_returned_index = i;
205 index = i;
206 break;
207 }
208 }
209 if ((entry == NULL) && c_seen_eof)
210 return 0;
211 }
212
213 if (entry == NULL) {
214 DPRINTK("smb_readdir: Not found in cache.\n");
215 result = smb_proc_readdir(server, inode,
216 filp->f_pos, SMB_READDIR_CACHE_SIZE,
217 c_entry);
218
219 if (result < 0) {
220 c_ino = 0;
221 return result;
222 }
223
224 if (result > 0) {
225 c_seen_eof = (result < SMB_READDIR_CACHE_SIZE);
226 c_ino = inode->i_ino;
227 c_size = result;
228 entry = c_entry;
229 c_last_returned_index = 0;
230 index = 0;
231 for (i = 0; i < c_size; i++) {
232
233 switch (server->case_handling)
234 {
235 case CASE_UPPER:
236 str_upper(c_entry[i].path); break;
237 case CASE_LOWER:
238 str_lower(c_entry[i].path); break;
239 case CASE_DEFAULT:
240 break;
241 }
242 }
243 }
244 }
245
246 if (entry == NULL) {
247
248 return 0;
249 }
250
251 while (index < c_size) {
252
253
254
255
256
257
258 int path_len;
259 int len;
260 struct smb_inode_info *ino_info;
261 char complete_path[SMB_MAXPATHLEN];
262
263 len = strlen(entry->path);
264 if ((result = get_pname_static(inode, entry->path, len,
265 complete_path,
266 &path_len)) < 0)
267 return result;
268
269 ino_info = smb_find_inode(server, complete_path);
270
271
272
273
274 if (ino_info == NULL) {
275 ino_info = (struct smb_inode_info *) 1;
276 }
277
278 DDPRINTK("smb_readdir: entry->path = %s\n", entry->path);
279 DDPRINTK("smb_readdir: entry->f_pos = %ld\n", entry->f_pos);
280
281 if (filldir(dirent, entry->path, len,
282 entry->f_pos, (ino_t)ino_info) < 0) {
283 break;
284 }
285
286 if ( (inode->i_ino != c_ino)
287 || (entry->f_pos != filp->f_pos)) {
288
289
290 break;
291 }
292 filp->f_pos += 1;
293 index += 1;
294 entry += 1;
295 }
296 return 0;
297 }
298
299 void
300 smb_init_dir_cache(void)
301 {
302 c_ino = 0;
303 c_entry = NULL;
304 }
305
306 void
307 smb_invalid_dir_cache(unsigned long ino)
308 {
309 if (ino == c_ino) {
310 c_ino = 0;
311 c_seen_eof = 0;
312 }
313 }
314
315 void
316 smb_free_dir_cache(void)
317 {
318 int i;
319
320 DPRINTK("smb_free_dir_cache: enter\n");
321
322 if (c_entry == NULL)
323 return;
324
325 for (i = 0; i < SMB_READDIR_CACHE_SIZE; i++) {
326 smb_kfree_s(c_entry[i].path, NAME_MAX + 1);
327 }
328
329 smb_kfree_s(c_entry,
330 sizeof(struct smb_dirent) * SMB_READDIR_CACHE_SIZE);
331 c_entry = NULL;
332
333 DPRINTK("smb_free_dir_cache: exit\n");
334 }
335
336
337
338
339
340 static int
341 get_pname_static(struct inode *dir, const char *name, int len,
342 char *path, int *res_len)
343 {
344 char *parentname = SMB_INOP(dir)->finfo.path;
345 int parentlen = SMB_INOP(dir)->finfo.len;
346
347 #if 1
348 if (parentlen != strlen(parentname)) {
349 printk("get_pname: parent->finfo.len = %d instead of %d\n",
350 parentlen, strlen(parentname));
351 parentlen = strlen(parentname);
352 }
353
354 #endif
355 DDPRINTK("get_pname_static: parentname = %s, len = %d\n",
356 parentname, parentlen);
357
358 if (len > SMB_MAXNAMELEN) {
359 return -ENAMETOOLONG;
360 }
361
362
363 if (len == 0 || (len == 1 && name[0] == '.')) {
364
365 memcpy(path, parentname, parentlen + 1);
366 *res_len = parentlen;
367 return 0;
368 }
369
370
371 if (len == 2 && name[0] == '.' && name[1] == '.') {
372
373 char *pos = strrchr(parentname, '\\');
374
375 if ( (pos == NULL)
376 && (parentlen == 0)) {
377
378
379
380 path[0] = '\\';
381 path[1] = '\0';
382 *res_len = 2;
383 return 0;
384 }
385
386
387 if (pos == NULL) {
388 printk("smb_make_name: Bad parent SMB-name: %s",
389 parentname);
390 return -ENODATA;
391 }
392
393 len = pos - parentname;
394
395 memcpy(path, parentname, len);
396 path[len] = '\0';
397 }
398 else
399 {
400 if (len + parentlen + 2 > SMB_MAXPATHLEN)
401 return -ENAMETOOLONG;
402
403 memcpy(path, parentname, parentlen);
404 path[parentlen] = '\\';
405 memcpy(path + parentlen + 1, name, len);
406 path[parentlen + 1 + len] = '\0';
407 len = parentlen + len + 1;
408 }
409
410 switch (SMB_SERVER(dir)->case_handling)
411 {
412 case CASE_UPPER:
413 str_upper(path);
414 break;
415 case CASE_LOWER:
416 str_lower(path);
417 break;
418 case CASE_DEFAULT:
419 break;
420 }
421
422 *res_len = len;
423
424 DDPRINTK("get_pname: path = %s, *pathlen = %d\n",
425 path, *res_len);
426 return 0;
427 }
428
429 static int
430 get_pname(struct inode *dir, const char *name, int len,
431 char **res_path, int *res_len)
432 {
433 char result[SMB_MAXPATHLEN];
434 int result_len;
435 int res;
436
437 if ((res = get_pname_static(dir,name,len,result,&result_len) != 0)) {
438 return res;
439 }
440
441 if ((*res_path = smb_kmalloc(result_len+1, GFP_KERNEL)) == NULL) {
442 printk("get_pname: Out of memory while allocating name.");
443 return -ENOMEM;
444 }
445
446 strcpy(*res_path, result);
447 *res_len = result_len;
448 return 0;
449 }
450
451 static void
452 put_pname(char *path)
453 {
454 smb_kfree_s(path, 0);
455 }
456
457
458
459
460
461 static struct inode *
462 smb_iget(struct inode *dir, char *path, struct smb_dirent *finfo)
463 {
464 struct smb_dirent newent = { 0 };
465 struct inode *inode;
466 int error, len;
467 struct smb_inode_info *new_inode_info;
468 struct smb_inode_info *root;
469
470 if (!dir) {
471 printk("smb_iget: dir is NULL\n");
472 return NULL;
473 }
474
475 if (!path) {
476 printk("smb_iget: path is NULL\n");
477 return NULL;
478 }
479
480 len = strlen(path);
481
482 if (!finfo) {
483 error = smb_proc_getattr(&(SMB_SBP(dir->i_sb)->s_server),
484 path, len, &newent);
485 if (error) {
486 printk("smb_iget: getattr error = %d\n", -error);
487 return NULL;
488 }
489 finfo = &newent;
490 DPRINTK("smb_iget: Read finfo:\n");
491 DPRINTK("smb_iget: finfo->attr = 0x%X\n", finfo->attr);
492 }
493
494 new_inode_info = smb_kmalloc(sizeof(struct smb_inode_info),
495 GFP_KERNEL);
496
497 if (new_inode_info == NULL) {
498 printk("smb_iget: could not alloc mem for %s\n", path);
499 return NULL;
500 }
501
502 new_inode_info->state = INODE_LOOKED_UP;
503 new_inode_info->nused = 0;
504 new_inode_info->dir = SMB_INOP(dir);
505
506 new_inode_info->finfo = *finfo;
507 new_inode_info->finfo.opened = 0;
508 new_inode_info->finfo.path = path;
509 new_inode_info->finfo.len = len;
510
511 SMB_INOP(dir)->nused += 1;
512
513
514
515
516
517 root = &(SMB_SERVER(dir)->root);
518
519 new_inode_info->prev = root;
520 new_inode_info->next = root->next;
521 root->next->prev = new_inode_info;
522 root->next = new_inode_info;
523
524 if (!(inode = iget(dir->i_sb, (int)new_inode_info))) {
525 printk("smb_iget: iget failed!");
526 return NULL;
527 }
528
529 return inode;
530 }
531
532 void
533 smb_free_inode_info(struct smb_inode_info *i)
534 {
535 if (i == NULL) {
536 printk("smb_free_inode: i == NULL\n");
537 return;
538 }
539
540 i->state = INODE_CACHED;
541 while ((i->nused == 0) && (i->state == INODE_CACHED)) {
542 struct smb_inode_info *dir = i->dir;
543
544 i->next->prev = i->prev;
545 i->prev->next = i->next;
546
547 smb_kfree_s(i->finfo.path, i->finfo.len+1);
548 smb_kfree_s(i, sizeof(struct smb_inode_info));
549
550 if (dir == NULL) return;
551
552 (dir->nused)--;
553 i = dir;
554 }
555 }
556
557 void
558 smb_init_root(struct smb_server *server)
559 {
560 struct smb_inode_info *root = &(server->root);
561
562 root->finfo.path = server->m.root_path;
563 root->finfo.len = strlen(root->finfo.path);
564 root->finfo.opened = 0;
565
566 root->state = INODE_LOOKED_UP;
567 root->nused = 1;
568 root->dir = NULL;
569 root->next = root->prev = root;
570 return;
571 }
572
573 int
574 smb_stat_root(struct smb_server *server)
575 {
576 struct smb_inode_info *root = &(server->root);
577 int result;
578
579 if (root->finfo.len == 0) {
580 result = smb_proc_getattr(server, "\\", 1, &(root->finfo));
581 }
582 else
583 {
584 result = smb_proc_getattr(server,
585 root->finfo.path, root->finfo.len,
586 &(root->finfo));
587 }
588 return result;
589 }
590
591 void
592 smb_free_all_inodes(struct smb_server *server)
593 {
594
595
596
597 #if 1
598 struct smb_inode_info *root = &(server->root);
599
600 if (root->next != root) {
601 printk("smb_free_all_inodes: INODES LEFT!!!\n");
602 }
603
604 while (root->next != root) {
605 printk("smb_free_all_inodes: freeing inode\n");
606 smb_free_inode_info(root->next);
607
608 schedule();
609 }
610 #endif
611
612 return;
613 }
614
615
616
617
618 void
619 smb_invalidate_all_inodes(struct smb_server *server)
620 {
621 struct smb_inode_info *ino = &(server->root);
622
623 do {
624 ino->finfo.opened = 0;
625 ino = ino->next;
626 } while (ino != &(server->root));
627
628 return;
629 }
630
631
632
633
634
635
636 static struct smb_inode_info *
637 smb_find_inode(struct smb_server *server, const char *path)
638 {
639 struct smb_inode_info *result = &(server->root);
640
641 if (path == NULL)
642 return NULL;
643
644 do {
645 if (strcmp(result->finfo.path, path) == 0)
646 return result;
647 result = result->next;
648
649 } while (result != &(server->root));
650
651 return NULL;
652 }
653
654
655 static int
656 smb_lookup(struct inode *dir, const char *__name, int len,
657 struct inode **result)
658 {
659 char *name = NULL;
660 struct smb_dirent finfo;
661 struct smb_inode_info *result_info;
662 int error;
663 int found_in_cache;
664
665 *result = NULL;
666
667 if (!dir || !S_ISDIR(dir->i_mode)) {
668 printk("smb_lookup: inode is NULL or not a directory.\n");
669 iput(dir);
670 return -ENOENT;
671 }
672
673 DDPRINTK("smb_lookup: %s\n", __name);
674
675
676 if (len == 0 || (len == 1 && __name[0] == '.')) {
677 *result = dir;
678 return 0;
679 }
680
681
682 if ((error = get_pname(dir, __name, len, &name, &len)) < 0) {
683 iput(dir);
684 return error;
685 }
686
687 result_info = smb_find_inode(SMB_SERVER(dir), name);
688
689 if (result_info != 0) {
690
691 if (result_info->state == INODE_CACHED)
692 result_info->state = INODE_LOOKED_UP;
693
694 put_pname(name);
695
696
697
698
699 *result = iget(dir->i_sb, (int)result_info);
700 iput(dir);
701
702 if (*result == NULL) {
703 return -EACCES;
704 } else {
705 return 0;
706 }
707 }
708
709
710
711
712
713
714
715
716 found_in_cache = 0;
717
718 if (dir->i_ino == c_ino) {
719 int first = c_last_returned_index;
720 int i;
721
722 i = first;
723 do {
724 DDPRINTK("smb_lookup: trying index: %d, name: %s\n",
725 i, c_entry[i].path);
726 if (strcmp(c_entry[i].path, __name) == 0) {
727 DPRINTK("smb_lookup: found in cache!\n");
728 finfo = c_entry[i];
729 finfo.path = NULL;
730 found_in_cache = 1;
731 break;
732 }
733 i = (i + 1) % c_size;
734 DDPRINTK("smb_lookup: index %d, name %s failed\n",
735 i, c_entry[i].path);
736 } while (i != first);
737 }
738
739 if (found_in_cache == 0) {
740 error = smb_proc_getattr(SMB_SERVER(dir), name, len, &finfo);
741 if (error < 0) {
742 put_pname(name);
743 iput(dir);
744 return error;
745 }
746 }
747
748 if (!(*result = smb_iget(dir, name, &finfo))) {
749 put_pname(name);
750 iput(dir);
751 return -EACCES;
752 }
753
754 DDPRINTK("smb_lookup: %s => %lu\n", name, (unsigned long)result_info);
755 iput(dir);
756 return 0;
757 }
758
759 static int
760 smb_create(struct inode *dir, const char *name, int len, int mode,
761 struct inode **result)
762 {
763 int error;
764 char *path = NULL;
765 struct smb_dirent entry;
766
767 *result = NULL;
768
769 if (!dir || !S_ISDIR(dir->i_mode)) {
770 printk("smb_create: inode is NULL or not a directory\n");
771 iput(dir);
772 return -ENOENT;
773 }
774
775
776 if ((error = get_pname(dir, name, len, &path, &len)) < 0) {
777 iput(dir);
778 return error;
779 }
780
781 entry.attr = 0;
782 entry.ctime = CURRENT_TIME;
783 entry.atime = CURRENT_TIME;
784 entry.mtime = CURRENT_TIME;
785 entry.size = 0;
786
787 error = smb_proc_create(SMB_SERVER(dir), path, len, &entry);
788 if (error < 0) {
789 put_pname(path);
790 iput(dir);
791 return error;
792 }
793
794 smb_invalid_dir_cache(dir->i_ino);
795
796 if (!(*result = smb_iget(dir, path, &entry)) < 0) {
797 put_pname(path);
798 iput(dir);
799 return error;
800 }
801 iput(dir);
802 return 0;
803 }
804
805 static int
806 smb_mkdir(struct inode *dir, const char *name, int len, int mode)
807 {
808 int error;
809 char path[SMB_MAXPATHLEN];
810
811 if (!dir || !S_ISDIR(dir->i_mode)) {
812 printk("smb_mkdir: inode is NULL or not a directory\n");
813 iput(dir);
814 return -ENOENT;
815 }
816
817
818 if ((error = get_pname_static(dir, name, len, path, &len)) < 0) {
819 iput(dir);
820 return error;
821 }
822
823 if ((error = smb_proc_mkdir(SMB_SERVER(dir), path, len)) == 0) {
824 smb_invalid_dir_cache(dir->i_ino);
825 }
826
827 iput(dir);
828 return error;
829 }
830
831 static int
832 smb_rmdir(struct inode *dir, const char *name, int len)
833 {
834 int error;
835 char path[SMB_MAXPATHLEN];
836
837 if (!dir || !S_ISDIR(dir->i_mode)) {
838 printk("smb_rmdir: inode is NULL or not a directory\n");
839 iput(dir);
840 return -ENOENT;
841 }
842 if ((error = get_pname_static(dir, name, len, path, &len)) < 0) {
843 iput(dir);
844 return error;
845 }
846 if (smb_find_inode(SMB_SERVER(dir), path) != NULL) {
847 error = -EBUSY;
848 } else {
849 if ((error = smb_proc_rmdir(SMB_SERVER(dir), path, len)) == 0)
850 smb_invalid_dir_cache(dir->i_ino);
851 }
852 iput(dir);
853 return error;
854 }
855
856 static int
857 smb_unlink(struct inode *dir, const char *name, int len)
858 {
859 int error;
860 char path[SMB_MAXPATHLEN];
861
862 if (!dir || !S_ISDIR(dir->i_mode)) {
863 printk("smb_unlink: inode is NULL or not a directory\n");
864 iput(dir);
865 return -ENOENT;
866 }
867 if ((error = get_pname_static(dir, name, len, path, &len)) < 0) {
868 iput(dir);
869 return error;
870 }
871 if (smb_find_inode(SMB_SERVER(dir), path) != NULL) {
872 error = -EBUSY;
873 } else {
874 if ((error = smb_proc_unlink(SMB_SERVER(dir), path, len)) == 0)
875 smb_invalid_dir_cache(dir->i_ino);
876 }
877
878 iput(dir);
879 return error;
880 }
881
882 static int
883 smb_rename(struct inode *old_dir, const char *old_name, int old_len,
884 struct inode *new_dir, const char *new_name, int new_len)
885 {
886 int res;
887 char old_path[SMB_MAXPATHLEN], new_path[SMB_MAXPATHLEN];
888
889 if (!old_dir || !S_ISDIR(old_dir->i_mode)) {
890 printk("smb_rename: old inode is NULL or not a directory\n");
891 res = -ENOENT;
892 goto finished;
893 }
894
895 if (!new_dir || !S_ISDIR(new_dir->i_mode)) {
896 printk("smb_rename: new inode is NULL or not a directory\n");
897 res = -ENOENT;
898 goto finished;
899 }
900
901 res = get_pname_static(old_dir, old_name, old_len, old_path, &old_len);
902 if (res < 0) {
903 goto finished;
904 }
905
906 res = get_pname_static(new_dir, new_name, new_len, new_path, &new_len);
907 if (res < 0) {
908 goto finished;
909 }
910
911 if ( (smb_find_inode(SMB_SERVER(old_dir), old_path) != NULL)
912 || (smb_find_inode(SMB_SERVER(new_dir), new_path) != NULL)) {
913 res = -EBUSY;
914 goto finished;
915 }
916
917 res = smb_proc_mv(SMB_SERVER(old_dir), old_path, old_len,
918 new_path, new_len);
919
920 if (res == -EEXIST) {
921 int res1;
922 res1 = smb_proc_unlink(SMB_SERVER(old_dir), new_path, new_len);
923 if (res1 == 0) {
924 res = smb_proc_mv(SMB_SERVER(old_dir), old_path,
925 old_len, new_path, new_len);
926 }
927 }
928
929 if (res == 0) {
930 smb_invalid_dir_cache(old_dir->i_ino);
931 smb_invalid_dir_cache(new_dir->i_ino);
932 }
933
934 finished:
935 iput(old_dir);
936 iput(new_dir);
937 return res;
938 }
939
940
941
942
943
944
945
946
947
948
949
950
951
952
953
954
955