The Design and Implementation of the FreeBSD Operating System, Second Edition
Now available: The Design and Implementation of the FreeBSD Operating System (Second Edition)


[ source navigation ] [ diff markup ] [ identifier search ] [ freetext search ] [ file search ] [ list types ] [ track identifier ]

FreeBSD/Linux Kernel Cross Reference
sys/fs/hpfs/namei.c

Version: -  FREEBSD  -  FREEBSD-13-STABLE  -  FREEBSD-13-0  -  FREEBSD-12-STABLE  -  FREEBSD-12-0  -  FREEBSD-11-STABLE  -  FREEBSD-11-0  -  FREEBSD-10-STABLE  -  FREEBSD-10-0  -  FREEBSD-9-STABLE  -  FREEBSD-9-0  -  FREEBSD-8-STABLE  -  FREEBSD-8-0  -  FREEBSD-7-STABLE  -  FREEBSD-7-0  -  FREEBSD-6-STABLE  -  FREEBSD-6-0  -  FREEBSD-5-STABLE  -  FREEBSD-5-0  -  FREEBSD-4-STABLE  -  FREEBSD-3-STABLE  -  FREEBSD22  -  l41  -  OPENBSD  -  linux-2.6  -  MK84  -  PLAN9  -  xnu-8792 
SearchContext: -  none  -  3  -  10 

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

Cache object: b68d8ce4bb862476eafa49029382b037


[ source navigation ] [ diff markup ] [ identifier search ] [ freetext search ] [ file search ] [ list types ] [ track identifier ]


This page is part of the FreeBSD/Linux Linux Kernel Cross-Reference, and was automatically generated using a modified version of the LXR engine.