vfs.c
上传用户:jlfgdled
上传日期:2013-04-10
资源大小:33168k
文件大小:79k
源码类别:

Linux/Unix编程

开发平台:

Unix_Linux

  1. /* -*- mode: c; c-basic-offset: 8; indent-tabs-mode: nil; -*-
  2.  * vim:expandtab:shiftwidth=8:tabstop=8:
  3.  *
  4.  *  Copyright (C) 2001, 2002 Cluster File Systems, Inc.
  5.  *  Copyright (C) 2000 Stelias Computing, Inc.
  6.  *  Copyright (C) 2000 Red Hat, Inc.
  7.  *
  8.  *   This file is part of InterMezzo, http://www.inter-mezzo.org.
  9.  *
  10.  *   InterMezzo is free software; you can redistribute it and/or
  11.  *   modify it under the terms of version 2 of the GNU General Public
  12.  *   License as published by the Free Software Foundation.
  13.  *
  14.  *   InterMezzo is distributed in the hope that it will be useful,
  15.  *   but WITHOUT ANY WARRANTY; without even the implied warranty of
  16.  *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  17.  *   GNU General Public License for more details.
  18.  *
  19.  *   You should have received a copy of the GNU General Public License
  20.  *   along with InterMezzo; if not, write to the Free Software
  21.  *   Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
  22.  *
  23.  * vfs.c
  24.  *
  25.  * This file implements kernel downcalls from lento.
  26.  *
  27.  * Author: Rob Simmonds <simmonds@stelias.com>
  28.  *         Andreas Dilger <adilger@stelias.com>
  29.  * Copyright (C) 2000 Stelias Computing Inc
  30.  * Copyright (C) 2000 Red Hat Inc.
  31.  *
  32.  * Extended attribute support
  33.  * Copyright (C) 2001 Shirish H. Phatak, Tacit Networks, Inc.
  34.  *
  35.  * This code is based on code from namei.c in the linux file system;
  36.  * see copyright notice below.
  37.  */
  38. /** namei.c copyright **/
  39. /*
  40.  *  linux/fs/namei.c
  41.  *
  42.  *  Copyright (C) 1991, 1992  Linus Torvalds
  43.  */
  44. /*
  45.  * Some corrections by tytso.
  46.  */
  47. /* [Feb 1997 T. Schoebel-Theuer] Complete rewrite of the pathname
  48.  * lookup logic.
  49.  */
  50. /** end of namei.c copyright **/
  51. #include <linux/mm.h>
  52. #include <linux/proc_fs.h>
  53. #include <linux/smp_lock.h>
  54. #include <linux/quotaops.h>
  55. #include <asm/uaccess.h>
  56. #include <asm/unaligned.h>
  57. #include <asm/semaphore.h>
  58. #include <asm/pgtable.h>
  59. #include <linux/file.h>
  60. #include <linux/fs.h>
  61. #include <linux/blk.h>
  62. #include <linux/intermezzo_fs.h>
  63. #include <linux/intermezzo_psdev.h>
  64. #ifdef CONFIG_FS_EXT_ATTR
  65. # include <linux/ext_attr.h>
  66. # ifdef CONFIG_FS_POSIX_ACL
  67. #  include <linux/posix_acl.h>
  68. # endif
  69. #endif
  70. extern struct inode_operations presto_sym_iops;
  71. /* Write the last_rcvd values to the last_rcvd file.  We don't know what the
  72.  * UUID or last_ctime values are, so we have to read from the file first
  73.  * (sigh). 
  74.  * exported for branch_reinter in kml_reint.c*/
  75. int presto_write_last_rcvd(struct rec_info *recinfo,
  76.                            struct presto_file_set *fset,
  77.                            struct lento_vfs_context *info)
  78. {
  79.         int rc;
  80.         struct izo_rcvd_rec rcvd_rec;
  81.         ENTRY;
  82.         memset(&rcvd_rec, 0, sizeof(rcvd_rec));
  83.         memcpy(rcvd_rec.lr_uuid, info->uuid, sizeof(rcvd_rec.lr_uuid));
  84.         rcvd_rec.lr_remote_recno = HTON__u64(info->recno);
  85.         rcvd_rec.lr_remote_offset = HTON__u64(info->kml_offset);
  86.         rcvd_rec.lr_local_recno = HTON__u64(recinfo->recno);
  87.         rcvd_rec.lr_local_offset = HTON__u64(recinfo->offset + recinfo->size);
  88.         rc = izo_rcvd_write(fset, &rcvd_rec);
  89.         if (rc < 0) {
  90.                 /* izo_rcvd_write returns negative errors and non-negative
  91.                  * offsets */
  92.                 CERROR("InterMezzo: izo_rcvd_write failed: %dn", rc);
  93.                 EXIT;
  94.                 return rc;
  95.         }
  96.         EXIT;
  97.         return 0;
  98. }
  99. /*
  100.  * It's inline, so penalty for filesystems that don't use sticky bit is
  101.  * minimal.
  102.  */
  103. static inline int check_sticky(struct inode *dir, struct inode *inode)
  104. {
  105.         if (!(dir->i_mode & S_ISVTX))
  106.                 return 0;
  107.         if (inode->i_uid == current->fsuid)
  108.                 return 0;
  109.         if (dir->i_uid == current->fsuid)
  110.                 return 0;
  111.         return !capable(CAP_FOWNER);
  112. }
  113. /* from linux/fs/namei.c */
  114. static inline int may_delete(struct inode *dir,struct dentry *victim, int isdir)
  115. {
  116.         int error;
  117.         if (!victim->d_inode || victim->d_parent->d_inode != dir)
  118.                 return -ENOENT;
  119.         error = permission(dir,MAY_WRITE | MAY_EXEC);
  120.         if (error)
  121.                 return error;
  122.         if (IS_APPEND(dir))
  123.                 return -EPERM;
  124.         if (check_sticky(dir, victim->d_inode)||IS_APPEND(victim->d_inode)||
  125.             IS_IMMUTABLE(victim->d_inode))
  126.                 return -EPERM;
  127.         if (isdir) {
  128.                 if (!S_ISDIR(victim->d_inode->i_mode))
  129.                         return -ENOTDIR;
  130.                 if (IS_ROOT(victim))
  131.                         return -EBUSY;
  132.         } else if (S_ISDIR(victim->d_inode->i_mode))
  133.                 return -EISDIR;
  134.         return 0;
  135. }
  136. /* from linux/fs/namei.c */
  137. static inline int may_create(struct inode *dir, struct dentry *child) {
  138.         if (child->d_inode)
  139.                 return -EEXIST;
  140.         if (IS_DEADDIR(dir))
  141.                 return -ENOENT;
  142.         return permission(dir,MAY_WRITE | MAY_EXEC);
  143. }
  144. #ifdef PRESTO_DEBUG
  145. /* The loop_discard_io() function is available via a kernel patch to the
  146.  * loop block device.  It "works" by accepting writes, but throwing them
  147.  * away, rather than trying to write them to disk.  The old method worked
  148.  * by setting the underlying device read-only, but that has the problem
  149.  * that dirty buffers are kept in memory, and ext3 didn't like that at all.
  150.  */
  151. #ifdef CONFIG_LOOP_DISCARD
  152. #define BLKDEV_FAIL(dev,fail) loop_discard_io(dev,fail)
  153. #else
  154. #define BLKDEV_FAIL(dev,fail) set_device_ro(dev, 1)
  155. #endif
  156. /* If a breakpoint has been set via /proc/sys/intermezzo/intermezzoX/errorval,
  157.  * that is the same as "value", the underlying device will "fail" now.
  158.  */
  159. inline void presto_debug_fail_blkdev(struct presto_file_set *fset,
  160.                                      unsigned long value)
  161. {
  162.         int minor = presto_f2m(fset);
  163.         int errorval = izo_channels[minor].uc_errorval;
  164.         kdev_t dev = fset->fset_dentry->d_inode->i_dev;
  165.         if (errorval && errorval == (long)value && !is_read_only(dev)) {
  166.                 CDEBUG(D_SUPER, "setting device %s read onlyn", kdevname(dev));
  167.                 BLKDEV_FAIL(dev, 1);
  168.                 izo_channels[minor].uc_errorval = -dev;
  169.         }
  170. }
  171. #else
  172. #define presto_debug_fail_blkdev(dev,value) do {} while (0)
  173. #endif
  174. static inline int presto_do_kml(struct lento_vfs_context *info,
  175.                                 struct dentry *dentry)
  176. {
  177.         if ( ! (info->flags & LENTO_FL_KML) )
  178.                 return 0;
  179.         if ( presto_chk(dentry, PRESTO_DONT_JOURNAL) )
  180.                 return 0;
  181.         return 1;
  182. }
  183. static inline int presto_do_rcvd(struct lento_vfs_context *info,
  184.                                  struct dentry *dentry)
  185. {
  186.         if ( ! (info->flags & LENTO_FL_EXPECT) ) 
  187.                 return 0;
  188.         if ( presto_chk(dentry, PRESTO_DONT_JOURNAL) )
  189.                 return 0;
  190.         return 1;
  191. }
  192. /* XXX fixme: this should not fail, all these dentries are in memory
  193.    when _we_ call this */
  194. int presto_settime(struct presto_file_set *fset, 
  195.                    struct dentry *newobj,
  196.                    struct dentry *parent,
  197.                    struct dentry *target,
  198.                    struct lento_vfs_context *ctx, 
  199.                    int valid)
  200. {
  201.         int error = 0;
  202.         struct dentry *dentry;
  203.         struct inode *inode;
  204.         struct inode_operations *iops;
  205.         struct iattr iattr;
  206.         ENTRY;
  207.         if (ctx->flags &  LENTO_FL_IGNORE_TIME ) { 
  208.                 EXIT;
  209.                 return 0;
  210.         }
  211.         iattr.ia_ctime = ctx->updated_time;
  212.         iattr.ia_mtime = ctx->updated_time;
  213.         iattr.ia_valid = valid;
  214.         while (1) {
  215.                 if (parent && ctx->flags & LENTO_FL_TOUCH_PARENT) {
  216.                         dentry = parent;
  217.                         parent = NULL;
  218.                 } else if (newobj && ctx->flags & LENTO_FL_TOUCH_NEWOBJ) {
  219.                         dentry = newobj;
  220.                         newobj = NULL;
  221.                 } else if (target) {
  222.                         dentry = target;
  223.                         target = NULL;
  224.                 } else
  225.                         break;
  226.                 inode = dentry->d_inode;
  227.                 error = -EROFS;
  228.                 if (IS_RDONLY(inode)) {
  229.                         EXIT;
  230.                         return -EROFS;
  231.                 }
  232.                 if (IS_IMMUTABLE(inode) || IS_APPEND(inode)) {
  233.                         EXIT;
  234.                         return -EPERM;
  235.                 }
  236.                 error = -EPERM;
  237.                 iops = filter_c2cdiops(fset->fset_cache->cache_filter); 
  238.                 if (!iops) { 
  239.                         EXIT;
  240.                         return error;
  241.                 }
  242.                 if (iops->setattr != NULL)
  243.                         error = iops->setattr(dentry, &iattr);
  244.                 else {
  245.                         error = 0;
  246.                         inode_setattr(dentry->d_inode, &iattr);
  247.                 }
  248.         }
  249.         EXIT;
  250.         return error;
  251. }
  252. void izo_get_rollback_data(struct inode *inode, struct izo_rollback_data *rb)
  253. {
  254.         rb->rb_mode = (__u32)inode->i_mode;
  255.         rb->rb_rdev = (__u32)inode->i_rdev;
  256.         rb->rb_uid  = (__u64)inode->i_uid;
  257.         rb->rb_gid  = (__u64)inode->i_gid;
  258. }
  259. int presto_do_close(struct presto_file_set *fset, struct file *file)
  260. {
  261.         struct rec_info rec;
  262.         int rc = -ENOSPC; 
  263.         void *handle;
  264.         struct inode *inode = file->f_dentry->d_inode;
  265.         struct presto_file_data *fdata = 
  266.                 (struct presto_file_data *)file->private_data;
  267.         ENTRY;
  268.         presto_getversion(&fdata->fd_info.remote_version, inode);
  269.         rc = presto_reserve_space(fset->fset_cache, PRESTO_REQHIGH); 
  270.         if (rc) { 
  271.                 EXIT;
  272.                 return rc;
  273.         }
  274.         handle = presto_trans_start(fset, file->f_dentry->d_inode, 
  275.                                             KML_OPCODE_RELEASE);
  276.         if ( IS_ERR(handle) ) {
  277.                 CERROR("presto_release: no space for transactionn");
  278.                 return rc;
  279.         }
  280.         if (fdata->fd_info.flags & LENTO_FL_KML) 
  281.                 rc = presto_journal_close(&rec, fset, file, file->f_dentry,
  282.                                           &fdata->fd_version, 
  283.                                           &fdata->fd_info.remote_version);
  284.         if (rc) { 
  285.                 CERROR("presto_close: cannot journal closen");
  286.                 goto out;
  287.         }
  288.         if (fdata->fd_info.flags & LENTO_FL_EXPECT) 
  289.                 rc = presto_write_last_rcvd(&rec, fset, &fdata->fd_info);
  290.         if (rc) { 
  291.                 CERROR("presto_close: cannot journal last_rcvdn");
  292.                 goto out;
  293.         }
  294.         presto_trans_commit(fset, handle); 
  295.         
  296.         /* cancel the LML record */ 
  297.         handle = presto_trans_start(fset, inode, KML_OPCODE_WRITE);
  298.         if ( IS_ERR(handle) ) {
  299.                 CERROR("presto_release: no space for clearn");
  300.                 return -ENOSPC;
  301.         }
  302.         rc = presto_clear_lml_close(fset, fdata->fd_lml_offset); 
  303.         if (rc < 0 ) { 
  304.                 CERROR("presto_close: cannot journal closen");
  305.                 goto out;
  306.         }
  307.         presto_truncate_lml(fset);
  308.  out:
  309.         presto_release_space(fset->fset_cache, PRESTO_REQHIGH); 
  310.         presto_trans_commit(fset, handle); 
  311.         EXIT;
  312.         return rc;
  313. }
  314. int presto_do_setattr(struct presto_file_set *fset, struct dentry *dentry,
  315.                       struct iattr *iattr, struct lento_vfs_context *info)
  316. {
  317.         struct rec_info rec;
  318.         struct inode *inode = dentry->d_inode;
  319.         struct inode_operations *iops;
  320.         int error;
  321.         struct presto_version old_ver, new_ver;
  322.         struct izo_rollback_data rb;
  323.         void *handle;
  324.         loff_t old_size=inode->i_size;
  325.         ENTRY;
  326.         error = -EROFS;
  327.         if (IS_RDONLY(inode)) {
  328.                 EXIT;
  329.                 return -EROFS;
  330.         }
  331.         if (IS_IMMUTABLE(inode) || IS_APPEND(inode)) {
  332.                 EXIT;
  333.                 return -EPERM;
  334.         }
  335.         presto_getversion(&old_ver, dentry->d_inode);
  336.         izo_get_rollback_data(dentry->d_inode, &rb);
  337.         error = -EPERM;
  338.         iops = filter_c2cdiops(fset->fset_cache->cache_filter); 
  339.         error = presto_reserve_space(fset->fset_cache, 2*PRESTO_REQHIGH); 
  340.         if (error) {
  341.                 EXIT;
  342.                 return error;
  343.         }
  344.         if  (iattr->ia_valid & ATTR_SIZE) {
  345.                 if (izo_mark_dentry(dentry, ~PRESTO_DATA, 0, NULL) != 0)
  346.                         CERROR("izo_mark_dentry(inode %ld, ~PRESTO_DATA) "
  347.                                "failedn", dentry->d_inode->i_ino);
  348.                 handle = presto_trans_start(fset, dentry->d_inode,
  349.                                             KML_OPCODE_TRUNC);
  350.         } else {
  351.                 handle = presto_trans_start(fset, dentry->d_inode,
  352.                                             KML_OPCODE_SETATTR);
  353.         }
  354.         if ( IS_ERR(handle) ) {
  355.                 CERROR("presto_do_setattr: no space for transactionn");
  356.                 presto_release_space(fset->fset_cache, 2*PRESTO_REQHIGH); 
  357.                 return -ENOSPC;
  358.         }
  359.         if (dentry->d_inode && iops && iops->setattr) {
  360.                 error = iops->setattr(dentry, iattr);
  361.         } else {
  362.                 error = inode_change_ok(dentry->d_inode, iattr);
  363.                 if (!error) 
  364.                         inode_setattr(inode, iattr);
  365.         }
  366.         if (!error && (iattr->ia_valid & ATTR_SIZE))
  367.                 vmtruncate(inode, iattr->ia_size);
  368.         if (error) {
  369.                 EXIT;
  370.                 goto exit;
  371.         }
  372.         presto_debug_fail_blkdev(fset, KML_OPCODE_SETATTR | 0x10);
  373.         if ( presto_do_kml(info, dentry) ) {
  374.                 if ((iattr->ia_valid & ATTR_SIZE) && (old_size != inode->i_size)) {
  375.                         struct file file;
  376.                         /* Journal a close whenever we see a potential truncate
  377.                         * At the receiving end, lento should explicitly remove
  378.                         * ATTR_SIZE from the list of valid attributes */
  379.                         presto_getversion(&new_ver, inode);
  380.                         file.private_data = NULL;
  381.                         file.f_dentry = dentry;
  382.                         error = presto_journal_close(&rec, fset, &file, dentry,
  383.                                                      &old_ver, &new_ver);
  384.                 }
  385.                 if (!error)
  386.                         error = presto_journal_setattr(&rec, fset, dentry,
  387.                                                        &old_ver, &rb, iattr);
  388.         }
  389.         presto_debug_fail_blkdev(fset, KML_OPCODE_SETATTR | 0x20);
  390.         if ( presto_do_rcvd(info, dentry) )
  391.                 error = presto_write_last_rcvd(&rec, fset, info);
  392.         presto_debug_fail_blkdev(fset, KML_OPCODE_SETATTR | 0x30);
  393.         EXIT;
  394. exit:
  395.         presto_release_space(fset->fset_cache, 2*PRESTO_REQHIGH); 
  396.         presto_trans_commit(fset, handle);
  397.         return error;
  398. }
  399. int lento_setattr(const char *name, struct iattr *iattr,
  400.                   struct lento_vfs_context *info)
  401. {
  402.         struct nameidata nd;
  403.         struct dentry *dentry;
  404.         struct presto_file_set *fset;
  405.         int error;
  406. #ifdef  CONFIG_FS_POSIX_ACL
  407.         int (*set_posix_acl)(struct inode *, int type, posix_acl_t *)=NULL;
  408. #endif
  409.         ENTRY;
  410.         CDEBUG(D_PIOCTL,"name %s, valid %#x, mode %#o, uid %d, gid %d, size %Ldn",
  411.                name, iattr->ia_valid, iattr->ia_mode, iattr->ia_uid,
  412.                iattr->ia_gid, iattr->ia_size);
  413.         CDEBUG(D_PIOCTL, "atime %#lx, mtime %#lx, ctime %#lx, attr_flags %#xn",
  414.                iattr->ia_atime, iattr->ia_mtime, iattr->ia_ctime,
  415.                iattr->ia_attr_flags);
  416.         CDEBUG(D_PIOCTL, "offset %d, recno %d, flags %#xn",
  417.                info->slot_offset, info->recno, info->flags);
  418.         lock_kernel();
  419.         error = presto_walk(name, &nd);
  420.         if (error) {
  421.                 EXIT;
  422.                 goto exit;
  423.         }
  424.         dentry = nd.dentry;
  425.         
  426.         fset = presto_fset(dentry);
  427.         error = -EINVAL;
  428.         if ( !fset ) {
  429.                 CERROR("No fileset!n");
  430.                 EXIT;
  431.                 goto exit_lock;
  432.         }
  433.         /* NOTE: this prevents us from changing the filetype on setattr,
  434.          *       as we normally only want to change permission bits.
  435.          *       If this is not correct, then we need to fix the perl code
  436.          *       to always send the file type OR'ed with the permission.
  437.          */
  438.         if (iattr->ia_valid & ATTR_MODE) {
  439.                 int set_mode = iattr->ia_mode;
  440.                 iattr->ia_mode = (iattr->ia_mode & S_IALLUGO) |
  441.                                  (dentry->d_inode->i_mode & ~S_IALLUGO);
  442.                 CDEBUG(D_PIOCTL, "chmod: orig %#o, set %#o, result %#on",
  443.                        dentry->d_inode->i_mode, set_mode, iattr->ia_mode);
  444. #ifdef CONFIG_FS_POSIX_ACL
  445.                 /* ACl code interacts badly with setattr 
  446.                  * since it tries to modify the ACL using 
  447.                  * set_ext_attr which recurses back into presto.  
  448.                  * This only happens if ATTR_MODE is set.
  449.                  * Here we are doing a "forced" mode set 
  450.                  * (initiated by lento), so we disable the 
  451.                  * set_posix_acl operation which 
  452.                  * prevents such recursion.  -SHP
  453.                  *
  454.                  * This will probably still be required when native
  455.                  * acl journalling is in place.
  456.                  */
  457.                 set_posix_acl=dentry->d_inode->i_op->set_posix_acl;
  458.                 dentry->d_inode->i_op->set_posix_acl=NULL;
  459. #endif
  460.         }
  461.         error = presto_do_setattr(fset, dentry, iattr, info);
  462.         if (info->flags & LENTO_FL_SET_DDFILEID) {
  463.                 struct presto_dentry_data *dd = presto_d2d(dentry);
  464.                 if (dd) {
  465.                         dd->remote_ino = info->remote_ino;
  466.                         dd->remote_generation = info->remote_generation;
  467.                 }
  468.         }
  469. #ifdef CONFIG_FS_POSIX_ACL
  470.         /* restore the inode_operations if we changed them*/
  471.         if (iattr->ia_valid & ATTR_MODE) 
  472.                 dentry->d_inode->i_op->set_posix_acl=set_posix_acl;
  473. #endif
  474.         EXIT;
  475. exit_lock:
  476.         path_release(&nd);
  477. exit:
  478.         unlock_kernel();
  479.         return error;
  480. }
  481. int presto_do_create(struct presto_file_set *fset, struct dentry *dir,
  482.                      struct dentry *dentry, int mode,
  483.                      struct lento_vfs_context *info)
  484. {
  485.         struct rec_info rec;
  486.         int error;
  487.         struct presto_version tgt_dir_ver, new_file_ver;
  488.         struct inode_operations *iops;
  489.         void *handle;
  490.         ENTRY;
  491.         mode &= S_IALLUGO;
  492.         mode |= S_IFREG;
  493.         down(&dir->d_inode->i_zombie);
  494.         error = presto_reserve_space(fset->fset_cache, PRESTO_REQHIGH); 
  495.         if (error) {
  496.                 EXIT;
  497.                 up(&dir->d_inode->i_zombie);
  498.                 return error;
  499.         }
  500.         error = may_create(dir->d_inode, dentry);
  501.         if (error) {
  502.                 EXIT;
  503.                 goto exit_pre_lock;
  504.         }
  505.         error = -EPERM;
  506.         iops = filter_c2cdiops(fset->fset_cache->cache_filter);
  507.         if (!iops->create) {
  508.                 EXIT;
  509.                 goto exit_pre_lock;
  510.         }
  511.         presto_getversion(&tgt_dir_ver, dir->d_inode);
  512.         handle = presto_trans_start(fset, dir->d_inode, KML_OPCODE_CREATE);
  513.         if ( IS_ERR(handle) ) {
  514.                 EXIT;
  515.                 presto_release_space(fset->fset_cache, PRESTO_REQHIGH); 
  516.                 CERROR("presto_do_create: no space for transactionn");
  517.                 error=-ENOSPC;
  518.                 goto exit_pre_lock;
  519.         }
  520.         DQUOT_INIT(dir->d_inode);
  521.         lock_kernel();
  522.         error = iops->create(dir->d_inode, dentry, mode);
  523.         if (error) {
  524.                 EXIT;
  525.                 goto exit_lock;
  526.         }
  527.         if (dentry->d_inode) {
  528.                 struct presto_cache *cache = fset->fset_cache;
  529.                 /* was this already done? */
  530.                 presto_set_ops(dentry->d_inode, cache->cache_filter);
  531.                 filter_setup_dentry_ops(cache->cache_filter, 
  532.                                         dentry->d_op, 
  533.                                         &presto_dentry_ops);
  534.                 dentry->d_op = filter_c2udops(cache->cache_filter);
  535.                 /* if Lento creates this file, we won't have data */
  536.                 if ( ISLENTO(presto_c2m(cache)) ) {
  537.                         presto_set(dentry, PRESTO_ATTR);
  538.                 } else {
  539.                         presto_set(dentry, PRESTO_ATTR | PRESTO_DATA);
  540.                 }
  541.         }
  542.         info->flags |= LENTO_FL_TOUCH_PARENT;
  543.         error = presto_settime(fset, NULL, dir, dentry,
  544.                                info, ATTR_CTIME | ATTR_MTIME);
  545.         if (error) { 
  546.                 EXIT;
  547.                 goto exit_lock;
  548.         }
  549.         presto_debug_fail_blkdev(fset, KML_OPCODE_CREATE | 0x10);
  550.         if ( presto_do_kml(info, dentry) ) { 
  551.                 presto_getversion(&new_file_ver, dentry->d_inode);
  552.                 error = presto_journal_create(&rec, fset, dentry, &tgt_dir_ver,
  553.                                               &new_file_ver, 
  554.                                               dentry->d_inode->i_mode);
  555.         }
  556.         presto_debug_fail_blkdev(fset, KML_OPCODE_CREATE | 0x20);
  557.         if ( presto_do_rcvd(info, dentry) )
  558.                 error = presto_write_last_rcvd(&rec, fset, info);
  559.         presto_debug_fail_blkdev(fset, KML_OPCODE_CREATE | 0x30);
  560.         /* add inode dentry */
  561.         if (fset->fset_cache->cache_filter->o_trops->tr_add_ilookup ) { 
  562.                 struct dentry *d;
  563.                 d = fset->fset_cache->cache_filter->o_trops->tr_add_ilookup
  564.                         (dir->d_inode->i_sb->s_root, dentry);
  565.         }
  566.         EXIT;
  567.  exit_lock:
  568.         unlock_kernel();
  569.         presto_trans_commit(fset, handle);
  570.  exit_pre_lock:
  571.         presto_release_space(fset->fset_cache, PRESTO_REQHIGH); 
  572.         up(&dir->d_inode->i_zombie);
  573.         return error;
  574. }
  575. /* from namei.c */
  576. static struct dentry *lookup_create(struct nameidata *nd, int is_dir)
  577. {
  578.         struct dentry *dentry;
  579.         down(&nd->dentry->d_inode->i_sem);
  580.         dentry = ERR_PTR(-EEXIST);
  581.         if (nd->last_type != LAST_NORM)
  582.                 goto fail;
  583.         dentry = lookup_hash(&nd->last, nd->dentry);
  584.         if (IS_ERR(dentry))
  585.                 goto fail;
  586.         if (!is_dir && nd->last.name[nd->last.len] && !dentry->d_inode)
  587.                 goto enoent;
  588.         return dentry;
  589. enoent:
  590.         dput(dentry);
  591.         dentry = ERR_PTR(-ENOENT);
  592. fail:
  593.         return dentry;
  594. }
  595. int lento_create(const char *name, int mode, struct lento_vfs_context *info)
  596. {
  597.         int error;
  598.         struct nameidata nd;
  599.         char * pathname;
  600.         struct dentry *dentry;
  601.         struct presto_file_set *fset;
  602.         ENTRY;
  603.         pathname = getname(name);
  604.         error = PTR_ERR(pathname);
  605.         if (IS_ERR(pathname)) {
  606.                 EXIT;
  607.                 goto exit;
  608.         }
  609.         /* this looks up the parent */
  610. //        if (path_init(pathname, LOOKUP_FOLLOW | LOOKUP_POSITIVE, &nd))
  611.         if (path_init(pathname,  LOOKUP_PARENT, &nd))
  612.                 error = path_walk(pathname, &nd);
  613.         if (error) {
  614.                 EXIT;
  615.                 goto exit;
  616.         }
  617.         dentry = lookup_create(&nd, 0);
  618.         error = PTR_ERR(dentry);
  619.         if (IS_ERR(dentry)) {
  620.                 EXIT;
  621.                 goto exit_lock;
  622.         }
  623.         fset = presto_fset(dentry);
  624.         error = -EINVAL;
  625.         if ( !fset ) {
  626.                 CERROR("No fileset!n");
  627.                 EXIT;
  628.                 goto exit_lock;
  629.         }
  630.         error = presto_do_create(fset, dentry->d_parent, dentry, (mode&S_IALLUGO)|S_IFREG,
  631.                                  info);
  632.         EXIT;
  633.  exit_lock:
  634.         path_release (&nd);
  635.         dput(dentry); 
  636.         up(&dentry->d_parent->d_inode->i_sem);
  637.         putname(pathname);
  638. exit:
  639.         return error;
  640. }
  641. int presto_do_link(struct presto_file_set *fset, struct dentry *old_dentry,
  642.                    struct dentry *dir, struct dentry *new_dentry,
  643.                    struct lento_vfs_context *info)
  644. {
  645.         struct rec_info rec;
  646.         struct inode *inode;
  647.         int error;
  648.         struct inode_operations *iops;
  649.         struct presto_version tgt_dir_ver;
  650.         struct presto_version new_link_ver;
  651.         void *handle;
  652.         down(&dir->d_inode->i_zombie);
  653.         error = presto_reserve_space(fset->fset_cache, PRESTO_REQHIGH); 
  654.         if (error) {
  655.                 EXIT;
  656.                 up(&dir->d_inode->i_zombie);
  657.                 return error;
  658.         }
  659.         error = -ENOENT;
  660.         inode = old_dentry->d_inode;
  661.         if (!inode)
  662.                 goto exit_lock;
  663.         error = may_create(dir->d_inode, new_dentry);
  664.         if (error)
  665.                 goto exit_lock;
  666.         error = -EXDEV;
  667.         if (dir->d_inode->i_dev != inode->i_dev)
  668.                 goto exit_lock;
  669.         /*
  670.          * A link to an append-only or immutable file cannot be created.
  671.          */
  672.         error = -EPERM;
  673.         if (IS_APPEND(inode) || IS_IMMUTABLE(inode)) {
  674.                 EXIT;
  675.                 goto exit_lock;
  676.         }
  677.         iops = filter_c2cdiops(fset->fset_cache->cache_filter);
  678.         if (!iops->link) {
  679.                 EXIT;
  680.                 goto exit_lock;
  681.         }
  682.         presto_getversion(&tgt_dir_ver, dir->d_inode);
  683.         handle = presto_trans_start(fset, dir->d_inode, KML_OPCODE_LINK);
  684.         if ( IS_ERR(handle) ) {
  685.                 presto_release_space(fset->fset_cache, PRESTO_REQHIGH); 
  686.                 CERROR("presto_do_link: no space for transactionn");
  687.                 return -ENOSPC;
  688.         }
  689.         DQUOT_INIT(dir->d_inode);
  690.         lock_kernel();
  691.         error = iops->link(old_dentry, dir->d_inode, new_dentry);
  692.         unlock_kernel();
  693.         if (error) {
  694.                 EXIT;
  695.                 goto exit_lock;
  696.         }
  697.         /* link dd data to that of existing dentry */
  698.         old_dentry->d_op->d_release(new_dentry); 
  699.         if (!presto_d2d(old_dentry)) 
  700.                 BUG();
  701.         presto_d2d(old_dentry)->dd_count++;
  702.         new_dentry->d_fsdata = presto_d2d(old_dentry);
  703.         info->flags |= LENTO_FL_TOUCH_PARENT;
  704.         error = presto_settime(fset, NULL, dir, new_dentry,
  705.                                info, ATTR_CTIME);
  706.         if (error) { 
  707.                 EXIT;
  708.                 goto exit_lock;
  709.         }
  710.         presto_debug_fail_blkdev(fset, KML_OPCODE_LINK | 0x10);
  711.         presto_getversion(&new_link_ver, new_dentry->d_inode);
  712.         if ( presto_do_kml(info, old_dentry) )
  713.                 error = presto_journal_link(&rec, fset, old_dentry, new_dentry,
  714.                                             &tgt_dir_ver, &new_link_ver);
  715.         presto_debug_fail_blkdev(fset, KML_OPCODE_LINK | 0x20);
  716.         if ( presto_do_rcvd(info, old_dentry) )
  717.                 error = presto_write_last_rcvd(&rec, fset, info);
  718.         presto_debug_fail_blkdev(fset, KML_OPCODE_LINK | 0x30);
  719.         EXIT;
  720.         presto_trans_commit(fset, handle);
  721. exit_lock:
  722.         presto_release_space(fset->fset_cache, PRESTO_REQHIGH); 
  723.         up(&dir->d_inode->i_zombie);
  724.         return error;
  725. }
  726. int lento_link(const char * oldname, const char * newname, 
  727.                          struct lento_vfs_context *info)
  728. {
  729.         int error;
  730.         char * from;
  731.         char * to;
  732.         struct presto_file_set *fset;
  733.         from = getname(oldname);
  734.         if(IS_ERR(from))
  735.                 return PTR_ERR(from);
  736.         to = getname(newname);
  737.         error = PTR_ERR(to);
  738.         if (!IS_ERR(to)) {
  739.                 struct dentry *new_dentry;
  740.                 struct nameidata nd, old_nd;
  741.                 error = 0;
  742.                 if (path_init(from, LOOKUP_POSITIVE, &old_nd))
  743.                         error = path_walk(from, &old_nd);
  744.                 if (error)
  745.                         goto exit;
  746.                 if (path_init(to, LOOKUP_PARENT, &nd))
  747.                         error = path_walk(to, &nd);
  748.                 if (error)
  749.                         goto out;
  750.                 error = -EXDEV;
  751.                 if (old_nd.mnt != nd.mnt)
  752.                         goto out;
  753.                 new_dentry = lookup_create(&nd, 0);
  754.                 error = PTR_ERR(new_dentry);
  755.                 if (!IS_ERR(new_dentry)) {
  756.                         fset = presto_fset(new_dentry);
  757.                         error = -EINVAL;
  758.                         if ( !fset ) {
  759.                                 CERROR("No fileset!n");
  760.                                 EXIT;
  761.                                 goto out2;
  762.                         }
  763.                         error = presto_do_link(fset, old_nd.dentry, 
  764.                                                nd.dentry,
  765.                                                new_dentry, info);
  766.                         dput(new_dentry);
  767.                 }
  768.         out2:
  769.                 up(&nd.dentry->d_inode->i_sem);
  770.                 path_release(&nd);
  771.         out:
  772.                 path_release(&old_nd);
  773.         exit:
  774.                 putname(to);
  775.         }
  776.         putname(from);
  777.         return error;
  778. }
  779. int presto_do_unlink(struct presto_file_set *fset, struct dentry *dir,
  780.                      struct dentry *dentry, struct lento_vfs_context *info)
  781. {
  782.         struct rec_info rec;
  783.         struct inode_operations *iops;
  784.         struct presto_version tgt_dir_ver, old_file_ver;
  785.         struct izo_rollback_data rb;
  786.         void *handle;
  787.         int do_kml = 0, do_rcvd = 0, linkno = 0, error, old_targetlen = 0;
  788.         char *old_target = NULL;
  789.         ENTRY;
  790.         down(&dir->d_inode->i_zombie);
  791.         error = may_delete(dir->d_inode, dentry, 0);
  792.         if (error) {
  793.                 EXIT;
  794.                 up(&dir->d_inode->i_zombie);
  795.                 return error;
  796.         }
  797.         error = -EPERM;
  798.         iops = filter_c2cdiops(fset->fset_cache->cache_filter);
  799.         if (!iops->unlink) {
  800.                 EXIT;
  801.                 up(&dir->d_inode->i_zombie);
  802.                 return error;
  803.         }
  804.         error = presto_reserve_space(fset->fset_cache, PRESTO_REQLOW); 
  805.         if (error) {
  806.                 EXIT;
  807.                 up(&dir->d_inode->i_zombie);
  808.                 return error;
  809.         }
  810.         if (presto_d2d(dentry)) { 
  811.                 struct presto_dentry_data *dd = presto_d2d(dentry); 
  812.                 struct dentry *de = dd->dd_inodentry;
  813.                 if (de && dentry->d_inode->i_nlink == 1) { 
  814.                         dd->dd_count--;
  815.                         dd->dd_inodentry = NULL; 
  816.                         de->d_fsdata = NULL; 
  817.                         atomic_dec(&de->d_inode->i_count); 
  818.                         de->d_inode = NULL;
  819.                         dput(de); 
  820.                 }
  821.         }
  822.         presto_getversion(&tgt_dir_ver, dir->d_inode);
  823.         presto_getversion(&old_file_ver, dentry->d_inode);
  824.         izo_get_rollback_data(dentry->d_inode, &rb);
  825.         handle = presto_trans_start(fset, dir->d_inode, KML_OPCODE_UNLINK);
  826.         if ( IS_ERR(handle) ) {
  827.                 presto_release_space(fset->fset_cache, PRESTO_REQLOW); 
  828.                 CERROR("ERROR: presto_do_unlink: no space for transaction. Tell Peter.n");
  829.                 up(&dir->d_inode->i_zombie);
  830.                 return -ENOSPC;
  831.         }
  832.         DQUOT_INIT(dir->d_inode);
  833.         if (d_mountpoint(dentry))
  834.                 error = -EBUSY;
  835.         else {
  836.                 lock_kernel();
  837.                 linkno = dentry->d_inode->i_nlink;
  838.                 if (linkno > 1) {
  839.                         dget(dentry);
  840.                 }
  841.                 if (S_ISLNK(dentry->d_inode->i_mode)) {
  842.                         mm_segment_t old_fs;
  843.                         struct inode_operations *riops;
  844.                         riops = filter_c2csiops(fset->fset_cache->cache_filter);
  845.                         PRESTO_ALLOC(old_target, PATH_MAX);
  846.                         if (old_target == NULL) {
  847.                                 error = -ENOMEM;
  848.                                 EXIT;
  849.                                 goto exit;
  850.                         }
  851.                         old_fs = get_fs();
  852.                         set_fs(get_ds());
  853.                         if (riops->readlink == NULL)
  854.                                 CERROR("InterMezzo %s: no readlink iops.n",
  855.                                        __FUNCTION__);
  856.                         else
  857.                                 old_targetlen =
  858.                                         riops->readlink(dentry, old_target,
  859.                                                         PATH_MAX);
  860.                         if (old_targetlen < 0) {
  861.                                 CERROR("InterMezzo: readlink failed: %ldn",
  862.                                        PTR_ERR(old_target));
  863.                                 PRESTO_FREE(old_target, PATH_MAX);
  864.                                 old_target = NULL;
  865.                                 old_targetlen = 0;
  866.                         }
  867.                         set_fs(old_fs);
  868.                 }
  869.                 do_kml = presto_do_kml(info, dir);
  870.                 do_rcvd = presto_do_rcvd(info, dir);
  871.                 error = iops->unlink(dir->d_inode, dentry);
  872.                 unlock_kernel();
  873.                 if (!error)
  874.                         d_delete(dentry);
  875.         }
  876.         if (linkno > 1) { 
  877.                 /* FIXME: Combine this with the next call? */
  878.                 error = presto_settime(fset, NULL, NULL, dentry,
  879.                                        info, ATTR_CTIME);
  880.                 dput(dentry); 
  881.                 if (error) { 
  882.                         EXIT;
  883.                         goto exit;
  884.                 }
  885.         }
  886.         error = presto_settime(fset, NULL, NULL, dir,
  887.                                info, ATTR_CTIME | ATTR_MTIME);
  888.         if (error) { 
  889.                 EXIT;
  890.                 goto exit;
  891.         }
  892.         up(&dir->d_inode->i_zombie);
  893.         if (error) {
  894.                 EXIT;
  895.                 goto exit;
  896.         }
  897.         presto_debug_fail_blkdev(fset, KML_OPCODE_UNLINK | 0x10);
  898.         if ( do_kml )
  899.                 error = presto_journal_unlink(&rec, fset, dir, &tgt_dir_ver,
  900.                                               &old_file_ver, &rb, dentry,
  901.                                               old_target, old_targetlen);
  902.         presto_debug_fail_blkdev(fset, KML_OPCODE_UNLINK | 0x20);
  903.         if ( do_rcvd ) { 
  904.                 error = presto_write_last_rcvd(&rec, fset, info);
  905.         }
  906.         presto_debug_fail_blkdev(fset, KML_OPCODE_UNLINK | 0x30);
  907.         EXIT;
  908. exit:
  909.         presto_release_space(fset->fset_cache, PRESTO_REQLOW); 
  910.         presto_trans_commit(fset, handle);
  911.         if (old_target != NULL)
  912.                 PRESTO_FREE(old_target, PATH_MAX);
  913.         return error;
  914. }
  915. int lento_unlink(const char *pathname, struct lento_vfs_context *info)
  916. {
  917.         int error = 0;
  918.         char * name;
  919.         struct dentry *dentry;
  920.         struct nameidata nd;
  921.         struct presto_file_set *fset;
  922.         ENTRY;
  923.         name = getname(pathname);
  924.         if(IS_ERR(name))
  925.                 return PTR_ERR(name);
  926.         if (path_init(name, LOOKUP_PARENT, &nd))
  927.                 error = path_walk(name, &nd);
  928.         if (error)
  929.                 goto exit;
  930.         error = -EISDIR;
  931.         if (nd.last_type != LAST_NORM)
  932.                 goto exit1;
  933.         down(&nd.dentry->d_inode->i_sem);
  934.         dentry = lookup_hash(&nd.last, nd.dentry);
  935.         error = PTR_ERR(dentry);
  936.         if (!IS_ERR(dentry)) {
  937.                 fset = presto_fset(dentry);
  938.                 error = -EINVAL;
  939.                 if ( !fset ) {
  940.                         CERROR("No fileset!n");
  941.                         EXIT;
  942.                         goto exit2;
  943.                 }
  944.                 /* Why not before? Because we want correct error value */
  945.                 if (nd.last.name[nd.last.len])
  946.                         goto slashes;
  947.                 error = presto_do_unlink(fset, nd.dentry, dentry, info);
  948.         exit2:
  949.                 EXIT;
  950.                 dput(dentry);
  951.         }
  952.         up(&nd.dentry->d_inode->i_sem);
  953. exit1:
  954.         path_release(&nd);
  955. exit:
  956.         putname(name);
  957.         return error;
  958. slashes:
  959.         error = !dentry->d_inode ? -ENOENT :
  960.                 S_ISDIR(dentry->d_inode->i_mode) ? -EISDIR : -ENOTDIR;
  961.         goto exit2;
  962. }
  963. int presto_do_symlink(struct presto_file_set *fset, struct dentry *dir,
  964.                       struct dentry *dentry, const char *oldname,
  965.                       struct lento_vfs_context *info)
  966. {
  967.         struct rec_info rec;
  968.         int error;
  969.         struct presto_version tgt_dir_ver, new_link_ver;
  970.         struct inode_operations *iops;
  971.         void *handle;
  972.         ENTRY;
  973.         down(&dir->d_inode->i_zombie);
  974.         /* record + max path len + space to free */ 
  975.         error = presto_reserve_space(fset->fset_cache, PRESTO_REQHIGH + 4096); 
  976.         if (error) {
  977.                 EXIT;
  978.                 up(&dir->d_inode->i_zombie);
  979.                 return error;
  980.         }
  981.         error = may_create(dir->d_inode, dentry);
  982.         if (error) {
  983.                 EXIT;
  984.                 goto exit_lock;
  985.         }
  986.         error = -EPERM;
  987.         iops = filter_c2cdiops(fset->fset_cache->cache_filter);
  988.         if (!iops->symlink) {
  989.                 EXIT;
  990.                 goto exit_lock;
  991.         }
  992.         presto_getversion(&tgt_dir_ver, dir->d_inode);
  993.         handle = presto_trans_start(fset, dir->d_inode, KML_OPCODE_SYMLINK);
  994.         if ( IS_ERR(handle) ) {
  995.                 presto_release_space(fset->fset_cache, PRESTO_REQHIGH + 4096); 
  996.                 CERROR("ERROR: presto_do_symlink: no space for transaction. Tell Peter.n"); 
  997.                 EXIT;
  998.                 up(&dir->d_inode->i_zombie);
  999.                 return -ENOSPC;
  1000.         }
  1001.         DQUOT_INIT(dir->d_inode);
  1002.         lock_kernel();
  1003.         error = iops->symlink(dir->d_inode, dentry, oldname);
  1004.         if (error) {
  1005.                 EXIT;
  1006.                 goto exit;
  1007.         }
  1008.         if (dentry->d_inode) {
  1009.                 struct presto_cache *cache = fset->fset_cache;
  1010.                 
  1011.                 presto_set_ops(dentry->d_inode, cache->cache_filter);
  1012.                 filter_setup_dentry_ops(cache->cache_filter, dentry->d_op, 
  1013.                                         &presto_dentry_ops);
  1014.                 dentry->d_op = filter_c2udops(cache->cache_filter);
  1015.                 /* XXX ? Cache state ? if Lento creates a symlink */
  1016.                 if ( ISLENTO(presto_c2m(cache)) ) {
  1017.                         presto_set(dentry, PRESTO_ATTR);
  1018.                 } else {
  1019.                         presto_set(dentry, PRESTO_ATTR | PRESTO_DATA);
  1020.                 }
  1021.         }
  1022.         info->flags |= LENTO_FL_TOUCH_PARENT;
  1023.         error = presto_settime(fset, NULL, dir, dentry,
  1024.                                info, ATTR_CTIME | ATTR_MTIME);
  1025.         if (error) { 
  1026.                 EXIT;
  1027.                 goto exit;
  1028.         }
  1029.         presto_debug_fail_blkdev(fset, KML_OPCODE_SYMLINK | 0x10);
  1030.         presto_getversion(&new_link_ver, dentry->d_inode);
  1031.         if ( presto_do_kml(info, dentry) )
  1032.                 error = presto_journal_symlink(&rec, fset, dentry, oldname,
  1033.                                                &tgt_dir_ver, &new_link_ver);
  1034.         presto_debug_fail_blkdev(fset, KML_OPCODE_SYMLINK | 0x20);
  1035.         if ( presto_do_rcvd(info, dentry) )
  1036.                 error = presto_write_last_rcvd(&rec, fset, info);
  1037.         presto_debug_fail_blkdev(fset, KML_OPCODE_SYMLINK | 0x30);
  1038.         EXIT;
  1039. exit:
  1040.         unlock_kernel();
  1041.         presto_trans_commit(fset, handle);
  1042.  exit_lock:
  1043.         presto_release_space(fset->fset_cache, PRESTO_REQHIGH + 4096); 
  1044.         up(&dir->d_inode->i_zombie);
  1045.         return error;
  1046. }
  1047. int lento_symlink(const char *oldname, const char *newname,
  1048.                   struct lento_vfs_context *info)
  1049. {
  1050.         int error;
  1051.         char *from;
  1052.         char *to;
  1053.         struct dentry *dentry;
  1054.         struct presto_file_set *fset;
  1055.         struct nameidata nd;
  1056.         ENTRY;
  1057.         lock_kernel();
  1058.         from = getname(oldname);
  1059.         error = PTR_ERR(from);
  1060.         if (IS_ERR(from)) {
  1061.                 EXIT;
  1062.                 goto exit;
  1063.         }
  1064.         to = getname(newname);
  1065.         error = PTR_ERR(to);
  1066.         if (IS_ERR(to)) {
  1067.                 EXIT;
  1068.                 goto exit_from;
  1069.         }
  1070.         if (path_init(to, LOOKUP_PARENT, &nd)) 
  1071.                 error = path_walk(to, &nd);
  1072.         if (error) {
  1073.                 EXIT;
  1074.                 goto exit_to;
  1075.         }
  1076.         dentry = lookup_create(&nd, 0);
  1077.         error = PTR_ERR(dentry);
  1078.         if (IS_ERR(dentry)) {
  1079.                 path_release(&nd);
  1080.                 EXIT;
  1081.                 goto exit_to;
  1082.         }
  1083.         fset = presto_fset(dentry);
  1084.         error = -EINVAL;
  1085.         if ( !fset ) {
  1086.                 CERROR("No fileset!n");
  1087.                 path_release(&nd);
  1088.                 EXIT;
  1089.                 goto exit_lock;
  1090.         }
  1091.         error = presto_do_symlink(fset, nd.dentry,
  1092.                                   dentry, oldname, info);
  1093.         path_release(&nd);
  1094.         EXIT;
  1095.  exit_lock:
  1096.         up(&nd.dentry->d_inode->i_sem);
  1097.         dput(dentry);
  1098.  exit_to:
  1099.         putname(to);
  1100.  exit_from:
  1101.         putname(from);
  1102.  exit:
  1103.         unlock_kernel();
  1104.         return error;
  1105. }
  1106. int presto_do_mkdir(struct presto_file_set *fset, struct dentry *dir,
  1107.                     struct dentry *dentry, int mode,
  1108.                     struct lento_vfs_context *info)
  1109. {
  1110.         struct rec_info rec;
  1111.         int error;
  1112.         struct presto_version tgt_dir_ver, new_dir_ver;
  1113.         void *handle;
  1114.         ENTRY;
  1115.         down(&dir->d_inode->i_zombie);
  1116.         /* one journal record + directory block + room for removals*/ 
  1117.         error = presto_reserve_space(fset->fset_cache, PRESTO_REQHIGH + 4096); 
  1118.         if (error) { 
  1119.                 EXIT;
  1120.                 up(&dir->d_inode->i_zombie);
  1121.                 return error;
  1122.         }
  1123.         error = may_create(dir->d_inode, dentry);
  1124.         if (error) {
  1125.                 EXIT;
  1126.                 goto exit_lock;
  1127.         }
  1128.         error = -EPERM;
  1129.         if (!filter_c2cdiops(fset->fset_cache->cache_filter)->mkdir) {
  1130.                 EXIT;
  1131.                 goto exit_lock;
  1132.         }
  1133.         error = -ENOSPC;
  1134.         presto_getversion(&tgt_dir_ver, dir->d_inode);
  1135.         handle = presto_trans_start(fset, dir->d_inode, KML_OPCODE_MKDIR);
  1136.         if ( IS_ERR(handle) ) {
  1137.                 presto_release_space(fset->fset_cache, PRESTO_REQHIGH + 4096); 
  1138.                 CERROR("presto_do_mkdir: no space for transactionn");
  1139.                 goto exit_lock;
  1140.         }
  1141.         DQUOT_INIT(dir->d_inode);
  1142.         mode &= (S_IRWXUGO|S_ISVTX);
  1143.         lock_kernel();
  1144.         error = filter_c2cdiops(fset->fset_cache->cache_filter)->mkdir(dir->d_inode, dentry, mode);
  1145.         if (error) {
  1146.                 EXIT;
  1147.                 goto exit;
  1148.         }
  1149.         if ( dentry->d_inode && !error) {
  1150.                 struct presto_cache *cache = fset->fset_cache;
  1151.                 presto_set_ops(dentry->d_inode, cache->cache_filter);
  1152.                 filter_setup_dentry_ops(cache->cache_filter, 
  1153.                                         dentry->d_op, 
  1154.                                         &presto_dentry_ops);
  1155.                 dentry->d_op = filter_c2udops(cache->cache_filter);
  1156.                 /* if Lento does this, we won't have data */
  1157.                 if ( ISLENTO(presto_c2m(cache)) ) {
  1158.                         presto_set(dentry, PRESTO_ATTR);
  1159.                 } else {
  1160.                         presto_set(dentry, PRESTO_ATTR | PRESTO_DATA);
  1161.                 }
  1162.         }
  1163.         info->flags |= LENTO_FL_TOUCH_PARENT;
  1164.         error = presto_settime(fset, NULL, dir, dentry,
  1165.                              info, ATTR_CTIME | ATTR_MTIME);
  1166.         if (error) { 
  1167.                 EXIT;
  1168.                 goto exit;
  1169.         }
  1170.         presto_debug_fail_blkdev(fset, KML_OPCODE_MKDIR | 0x10);
  1171.         presto_getversion(&new_dir_ver, dentry->d_inode);
  1172.         if ( presto_do_kml(info, dir) )
  1173.                 error = presto_journal_mkdir(&rec, fset, dentry, &tgt_dir_ver,
  1174.                                              &new_dir_ver, 
  1175.                                              dentry->d_inode->i_mode);
  1176.         presto_debug_fail_blkdev(fset, KML_OPCODE_MKDIR | 0x20);
  1177.         if ( presto_do_rcvd(info, dentry) )
  1178.                 error = presto_write_last_rcvd(&rec, fset, info);
  1179.         presto_debug_fail_blkdev(fset, KML_OPCODE_MKDIR | 0x30);
  1180.         EXIT;
  1181. exit:
  1182.         unlock_kernel();
  1183.         presto_trans_commit(fset, handle);
  1184.  exit_lock:
  1185.         presto_release_space(fset->fset_cache, PRESTO_REQHIGH + 4096); 
  1186.         up(&dir->d_inode->i_zombie);
  1187.         return error;
  1188. }
  1189. /*
  1190.  * Look out: this function may change a normal dentry
  1191.  * into a directory dentry (different size)..
  1192.  */
  1193. int lento_mkdir(const char *name, int mode, struct lento_vfs_context *info)
  1194. {
  1195.         int error;
  1196.         char *pathname;
  1197.         struct dentry *dentry;
  1198.         struct presto_file_set *fset;
  1199.         struct nameidata nd;
  1200.         ENTRY;
  1201.         CDEBUG(D_PIOCTL, "name: %s, mode %o, offset %d, recno %d, flags %xn",
  1202.                name, mode, info->slot_offset, info->recno, info->flags);
  1203.         pathname = getname(name);
  1204.         error = PTR_ERR(pathname);
  1205.         if (IS_ERR(pathname)) {
  1206.                 EXIT;
  1207.                 return error;
  1208.         }
  1209.         if (path_init(pathname, LOOKUP_PARENT, &nd))
  1210.                 error = path_walk(pathname, &nd);
  1211.         if (error)
  1212.                 goto out_name;
  1213.         dentry = lookup_create(&nd, 1);
  1214.         error = PTR_ERR(dentry);
  1215.         if (!IS_ERR(dentry)) {
  1216.                 fset = presto_fset(dentry);
  1217.                 error = -EINVAL;
  1218.                 if (!fset) {
  1219.                         CERROR("No fileset!n");
  1220.                         EXIT;
  1221.                         goto out_dput;
  1222.                 }
  1223.                 error = presto_do_mkdir(fset, nd.dentry, dentry, 
  1224.                                         mode & S_IALLUGO, info);
  1225. out_dput:
  1226.                 dput(dentry);
  1227.         }
  1228.         up(&nd.dentry->d_inode->i_sem);
  1229.         path_release(&nd);
  1230. out_name:
  1231.         EXIT;
  1232.         putname(pathname);
  1233.         CDEBUG(D_PIOCTL, "error: %dn", error);
  1234.         return error;
  1235. }
  1236. static void d_unhash(struct dentry *dentry)
  1237. {
  1238.         dget(dentry);
  1239.         switch (atomic_read(&dentry->d_count)) {
  1240.         default:
  1241.                 shrink_dcache_parent(dentry);
  1242.                 if (atomic_read(&dentry->d_count) != 2)
  1243.                         break;
  1244.         case 2:
  1245.                 d_drop(dentry);
  1246.         }
  1247. }
  1248. int presto_do_rmdir(struct presto_file_set *fset, struct dentry *dir,
  1249.                     struct dentry *dentry, struct lento_vfs_context *info)
  1250. {
  1251.         struct rec_info rec;
  1252.         int error;
  1253.         struct presto_version tgt_dir_ver, old_dir_ver;
  1254.         struct izo_rollback_data rb;
  1255.         struct inode_operations *iops;
  1256.         void *handle;
  1257.         int do_kml, do_rcvd;
  1258.         int size;
  1259.         ENTRY;
  1260.         error = may_delete(dir->d_inode, dentry, 1);
  1261.         if (error)
  1262.                 return error;
  1263.         error = -EPERM;
  1264.         iops = filter_c2cdiops(fset->fset_cache->cache_filter);
  1265.         if (!iops->rmdir) {
  1266.                 EXIT;
  1267.                 return error;
  1268.         }
  1269.         size = PRESTO_REQHIGH - dentry->d_inode->i_size; 
  1270.         error = presto_reserve_space(fset->fset_cache, size); 
  1271.         if (error) { 
  1272.                 EXIT;
  1273.                 return error;
  1274.         }
  1275.         presto_getversion(&tgt_dir_ver, dir->d_inode);
  1276.         presto_getversion(&old_dir_ver, dentry->d_inode);
  1277.         izo_get_rollback_data(dentry->d_inode, &rb);
  1278.         handle = presto_trans_start(fset, dir->d_inode, KML_OPCODE_RMDIR);
  1279.         if ( IS_ERR(handle) ) {
  1280.                 presto_release_space(fset->fset_cache, size); 
  1281.                 CERROR("ERROR: presto_do_rmdir: no space for transaction. Tell Peter.n");
  1282.                 return -ENOSPC;
  1283.         }
  1284.         DQUOT_INIT(dir->d_inode);
  1285.         do_kml = presto_do_kml(info, dir);
  1286.         do_rcvd = presto_do_rcvd(info, dir);
  1287.         double_down(&dir->d_inode->i_zombie, &dentry->d_inode->i_zombie);
  1288.         d_unhash(dentry);
  1289.         if (IS_DEADDIR(dir->d_inode))
  1290.                 error = -ENOENT;
  1291.         else if (d_mountpoint(dentry)) {
  1292.                 CERROR("foo: d_mountpoint(dentry): ino %ldn",
  1293.                        dentry->d_inode->i_ino);
  1294.                 error = -EBUSY;
  1295.         } else {
  1296.                 lock_kernel();
  1297.                 error = iops->rmdir(dir->d_inode, dentry);
  1298.                 unlock_kernel();
  1299.                 if (!error) {
  1300.                         dentry->d_inode->i_flags |= S_DEAD;
  1301.                         error = presto_settime(fset, NULL, NULL, dir, info,
  1302.                                                ATTR_CTIME | ATTR_MTIME);
  1303.                 }
  1304.         }
  1305.         double_up(&dir->d_inode->i_zombie, &dentry->d_inode->i_zombie);
  1306.         if (!error)
  1307.                 d_delete(dentry);
  1308.         dput(dentry);
  1309.         presto_debug_fail_blkdev(fset, KML_OPCODE_RMDIR | 0x10);
  1310.         if ( !error && do_kml )
  1311.                 error = presto_journal_rmdir(&rec, fset, dir, &tgt_dir_ver,
  1312.                                              &old_dir_ver, &rb,
  1313.                                              dentry->d_name.len,
  1314.                                              dentry->d_name.name);
  1315.         presto_debug_fail_blkdev(fset, KML_OPCODE_RMDIR | 0x20);
  1316.         if ( !error && do_rcvd ) 
  1317.                 error = presto_write_last_rcvd(&rec, fset, info);
  1318.         presto_debug_fail_blkdev(fset, KML_OPCODE_RMDIR | 0x30);
  1319.         EXIT;
  1320.         presto_trans_commit(fset, handle);
  1321.         presto_release_space(fset->fset_cache, size); 
  1322.         return error;
  1323. }
  1324. int lento_rmdir(const char *pathname, struct lento_vfs_context *info)
  1325. {
  1326.         int error = 0;
  1327.         char * name;
  1328.         struct dentry *dentry;
  1329.         struct presto_file_set *fset;
  1330.         struct nameidata nd;
  1331.         ENTRY;
  1332.         name = getname(pathname);
  1333.         if(IS_ERR(name)) {
  1334.                 EXIT;
  1335.                 return PTR_ERR(name);
  1336.         }
  1337.         if (path_init(name, LOOKUP_PARENT, &nd))
  1338.                 error = path_walk(name, &nd);
  1339.         if (error) {
  1340.                 EXIT;
  1341.                 goto exit;
  1342.         }
  1343.         switch(nd.last_type) {
  1344.         case LAST_DOTDOT:
  1345.                 error = -ENOTEMPTY;
  1346.                 EXIT;
  1347.                 goto exit1;
  1348.         case LAST_ROOT:
  1349.         case LAST_DOT:
  1350.                 error = -EBUSY;
  1351.                 EXIT;
  1352.                 goto exit1;
  1353.         }
  1354.         down(&nd.dentry->d_inode->i_sem);
  1355.         dentry = lookup_hash(&nd.last, nd.dentry);
  1356.         error = PTR_ERR(dentry);
  1357.         if (!IS_ERR(dentry)) {
  1358.                 fset = presto_fset(dentry);
  1359.                 error = -EINVAL;
  1360.                 if ( !fset ) {
  1361.                         CERROR("No fileset!n");
  1362.                         EXIT;
  1363.                         goto exit_put;
  1364.                 }
  1365.                 error = presto_do_rmdir(fset, nd.dentry, dentry, info);
  1366.         exit_put:
  1367.                 dput(dentry);
  1368.         }
  1369.         up(&nd.dentry->d_inode->i_sem);
  1370. exit1:
  1371.         path_release(&nd);
  1372. exit:
  1373.         putname(name);
  1374.         EXIT;
  1375.         return error;
  1376. }
  1377. int presto_do_mknod(struct presto_file_set *fset, struct dentry *dir,
  1378.                     struct dentry *dentry, int mode, dev_t dev,
  1379.                     struct lento_vfs_context *info)
  1380. {
  1381.         struct rec_info rec;
  1382.         int error = -EPERM;
  1383.         struct presto_version tgt_dir_ver, new_node_ver;
  1384.         struct inode_operations *iops;
  1385.         void *handle;
  1386.         ENTRY;
  1387.         down(&dir->d_inode->i_zombie);
  1388.         /* one KML entry */ 
  1389.         error = presto_reserve_space(fset->fset_cache, PRESTO_REQHIGH); 
  1390.         if (error) {
  1391.                 EXIT;
  1392.                 up(&dir->d_inode->i_zombie);
  1393.                 return error;
  1394.         }
  1395.         if ((S_ISCHR(mode) || S_ISBLK(mode)) && !capable(CAP_MKNOD)) {
  1396.                 EXIT;
  1397.                 goto exit_lock;
  1398.         }
  1399.         error = may_create(dir->d_inode, dentry);
  1400.         if (error) {
  1401.                 EXIT;
  1402.                 goto exit_lock;
  1403.         }
  1404.         error = -EPERM;
  1405.         iops = filter_c2cdiops(fset->fset_cache->cache_filter);
  1406.         if (!iops->mknod) {
  1407.                 EXIT;
  1408.                 goto exit_lock;
  1409.         }
  1410.         DQUOT_INIT(dir->d_inode);
  1411.         lock_kernel();
  1412.         
  1413.         error = -ENOSPC;
  1414.         presto_getversion(&tgt_dir_ver, dir->d_inode);
  1415.         handle = presto_trans_start(fset, dir->d_inode, KML_OPCODE_MKNOD);
  1416.         if ( IS_ERR(handle) ) {
  1417.                 presto_release_space(fset->fset_cache, PRESTO_REQHIGH); 
  1418.                 CERROR("presto_do_mknod: no space for transactionn");
  1419.                 goto exit_lock2;
  1420.         }
  1421.         error = iops->mknod(dir->d_inode, dentry, mode, dev);
  1422.         if (error) {
  1423.                 EXIT;
  1424.                 goto exit_commit;
  1425.         }
  1426.         if ( dentry->d_inode) {
  1427.                 struct presto_cache *cache = fset->fset_cache;
  1428.                 presto_set_ops(dentry->d_inode, cache->cache_filter);
  1429.                 filter_setup_dentry_ops(cache->cache_filter, dentry->d_op, 
  1430.                                         &presto_dentry_ops);
  1431.                 dentry->d_op = filter_c2udops(cache->cache_filter);
  1432.                 /* if Lento does this, we won't have data */
  1433.                 if ( ISLENTO(presto_c2m(cache)) ) {
  1434.                         presto_set(dentry, PRESTO_ATTR);
  1435.                 } else {
  1436.                         presto_set(dentry, PRESTO_ATTR | PRESTO_DATA);
  1437.                 }
  1438.         }
  1439.         error = presto_settime(fset, NULL, NULL, dir,
  1440.                                info, ATTR_MTIME);
  1441.         if (error) { 
  1442.                 EXIT;
  1443.         }
  1444.         error = presto_settime(fset, NULL, NULL, dentry,
  1445.                                info, ATTR_CTIME | ATTR_MTIME);
  1446.         if (error) { 
  1447.                 EXIT;
  1448.         }
  1449.         presto_debug_fail_blkdev(fset, KML_OPCODE_MKNOD | 0x10);
  1450.         presto_getversion(&new_node_ver, dentry->d_inode);
  1451.         if ( presto_do_kml(info, dentry) )
  1452.                 error = presto_journal_mknod(&rec, fset, dentry, &tgt_dir_ver,
  1453.                                              &new_node_ver, 
  1454.                                              dentry->d_inode->i_mode,
  1455.                                              MAJOR(dev), MINOR(dev) );
  1456.         presto_debug_fail_blkdev(fset, KML_OPCODE_MKNOD | 0x20);
  1457.         if ( presto_do_rcvd(info, dentry) )
  1458.                 error = presto_write_last_rcvd(&rec, fset, info);
  1459.         presto_debug_fail_blkdev(fset, KML_OPCODE_MKNOD | 0x30);
  1460.         EXIT;
  1461.  exit_commit:
  1462.         presto_trans_commit(fset, handle);
  1463.  exit_lock2:
  1464.         unlock_kernel();
  1465.  exit_lock:
  1466.         presto_release_space(fset->fset_cache, PRESTO_REQHIGH); 
  1467.         up(&dir->d_inode->i_zombie);
  1468.         return error;
  1469. }
  1470. int lento_mknod(const char *filename, int mode, dev_t dev,
  1471.                 struct lento_vfs_context *info)
  1472. {
  1473.         int error = 0;
  1474.         char * tmp;
  1475.         struct dentry * dentry;
  1476.         struct nameidata nd;
  1477.         struct presto_file_set *fset;
  1478.         ENTRY;
  1479.         if (S_ISDIR(mode))
  1480.                 return -EPERM;
  1481.         tmp = getname(filename);
  1482.         if (IS_ERR(tmp))
  1483.                 return PTR_ERR(tmp);
  1484.         if (path_init(tmp, LOOKUP_PARENT, &nd))
  1485.                 error = path_walk(tmp, &nd);
  1486.         if (error)
  1487.                 goto out;
  1488.         dentry = lookup_create(&nd, 0);
  1489.         error = PTR_ERR(dentry);
  1490.         if (!IS_ERR(dentry)) {
  1491.                 fset = presto_fset(dentry);
  1492.                 error = -EINVAL;
  1493.                 if ( !fset ) {
  1494.                         CERROR("No fileset!n");
  1495.                         EXIT;
  1496.                         goto exit_put;
  1497.                 }
  1498.                 switch (mode & S_IFMT) {
  1499.                 case 0: case S_IFREG:
  1500.                         error = -EOPNOTSUPP;
  1501.                         break;
  1502.                 case S_IFCHR: case S_IFBLK: case S_IFIFO: case S_IFSOCK:
  1503.                         error = presto_do_mknod(fset, nd.dentry, dentry, 
  1504.                                                 mode, dev, info);
  1505.                         break;
  1506.                 case S_IFDIR:
  1507.                         error = -EPERM;
  1508.                         break;
  1509.                 default:
  1510.                         error = -EINVAL;
  1511.                 }
  1512.         exit_put:
  1513.                 dput(dentry);
  1514.         }
  1515.         up(&nd.dentry->d_inode->i_sem);
  1516.         path_release(&nd);
  1517. out:
  1518.         putname(tmp);
  1519.         return error;
  1520. }
  1521. int do_rename(struct presto_file_set *fset,
  1522.                      struct dentry *old_parent, struct dentry *old_dentry,
  1523.                      struct dentry *new_parent, struct dentry *new_dentry,
  1524.                      struct lento_vfs_context *info)
  1525. {
  1526.         struct rec_info rec;
  1527.         int error;
  1528.         struct inode_operations *iops;
  1529.         struct presto_version src_dir_ver, tgt_dir_ver;
  1530.         void *handle;
  1531.         int new_inode_unlink = 0;
  1532.         struct inode *old_dir = old_parent->d_inode;
  1533.         struct inode *new_dir = new_parent->d_inode;
  1534.         ENTRY;
  1535.         presto_getversion(&src_dir_ver, old_dir);
  1536.         presto_getversion(&tgt_dir_ver, new_dir);
  1537.         error = -EPERM;
  1538.         iops = filter_c2cdiops(fset->fset_cache->cache_filter);
  1539.         if (!iops || !iops->rename) {
  1540.                 EXIT;
  1541.                 return error;
  1542.         }
  1543.         error = presto_reserve_space(fset->fset_cache, PRESTO_REQHIGH); 
  1544.         if (error) {
  1545.                 EXIT;
  1546.                 return error;
  1547.         }
  1548.         handle = presto_trans_start(fset, old_dir, KML_OPCODE_RENAME);
  1549.         if ( IS_ERR(handle) ) {
  1550.                 presto_release_space(fset->fset_cache, PRESTO_REQHIGH); 
  1551.                 CERROR("presto_do_rename: no space for transactionn");
  1552.                 return -ENOSPC;
  1553.         }
  1554.         if (new_dentry->d_inode && new_dentry->d_inode->i_nlink > 1) { 
  1555.                 dget(new_dentry); 
  1556.                 new_inode_unlink = 1;
  1557.         }
  1558.         error = iops->rename(old_dir, old_dentry, new_dir, new_dentry);
  1559.         if (error) {
  1560.                 EXIT;
  1561.                 goto exit;
  1562.         }
  1563.         if (new_inode_unlink) { 
  1564.                 error = presto_settime(fset, NULL, NULL, old_dentry,
  1565.                                        info, ATTR_CTIME);
  1566.                 dput(old_dentry); 
  1567.                 if (error) { 
  1568.                         EXIT;
  1569.                         goto exit;
  1570.                 }
  1571.         }
  1572.         info->flags |= LENTO_FL_TOUCH_PARENT;
  1573.         error = presto_settime(fset, NULL, new_parent, old_parent,
  1574.                                info, ATTR_CTIME | ATTR_MTIME);
  1575.         if (error) { 
  1576.                 EXIT;
  1577.                 goto exit;
  1578.         }
  1579.         /* XXX make a distinction between cross file set
  1580.          * and intra file set renames here
  1581.          */
  1582.         presto_debug_fail_blkdev(fset, KML_OPCODE_RENAME | 0x10);
  1583.         if ( presto_do_kml(info, old_dentry) )
  1584.                 error = presto_journal_rename(&rec, fset, old_dentry,
  1585.                                               new_dentry,
  1586.                                               &src_dir_ver, &tgt_dir_ver);
  1587.         presto_debug_fail_blkdev(fset, KML_OPCODE_RENAME | 0x20);
  1588.         if ( presto_do_rcvd(info, old_dentry) )
  1589.                 error = presto_write_last_rcvd(&rec, fset, info);
  1590.         presto_debug_fail_blkdev(fset, KML_OPCODE_RENAME | 0x30);
  1591.         EXIT;
  1592. exit:
  1593.         presto_trans_commit(fset, handle);
  1594.         presto_release_space(fset->fset_cache, PRESTO_REQHIGH); 
  1595.         return error;
  1596. }
  1597. static
  1598. int presto_rename_dir(struct presto_file_set *fset, struct dentry *old_parent,
  1599.                       struct dentry *old_dentry, struct dentry *new_parent,
  1600.                       struct dentry *new_dentry, struct lento_vfs_context *info)
  1601. {
  1602.         int error;
  1603.         struct inode *target;
  1604.         struct inode *old_dir = old_parent->d_inode;
  1605.         struct inode *new_dir = new_parent->d_inode;
  1606.         if (old_dentry->d_inode == new_dentry->d_inode)
  1607.                 return 0;
  1608.         error = may_delete(old_dir, old_dentry, 1);
  1609.         if (error)
  1610.                 return error;
  1611.         if (new_dir->i_dev != old_dir->i_dev)
  1612.                 return -EXDEV;
  1613.         if (!new_dentry->d_inode)
  1614.                 error = may_create(new_dir, new_dentry);
  1615.         else
  1616.                 error = may_delete(new_dir, new_dentry, 1);
  1617.         if (error)
  1618.                 return error;
  1619.         if (!old_dir->i_op || !old_dir->i_op->rename)
  1620.                 return -EPERM;
  1621.         /*
  1622.          * If we are going to change the parent - check write permissions,
  1623.          * we'll need to flip '..'.
  1624.          */
  1625.         if (new_dir != old_dir) {
  1626.                 error = permission(old_dentry->d_inode, MAY_WRITE);
  1627.         }
  1628.         if (error)
  1629.                 return error;
  1630.         DQUOT_INIT(old_dir);
  1631.         DQUOT_INIT(new_dir);
  1632.         down(&old_dir->i_sb->s_vfs_rename_sem);
  1633.         error = -EINVAL;
  1634.         if (is_subdir(new_dentry, old_dentry))
  1635.                 goto out_unlock;
  1636.         target = new_dentry->d_inode;
  1637.         if (target) { /* Hastur! Hastur! Hastur! */
  1638.                 triple_down(&old_dir->i_zombie,
  1639.                             &new_dir->i_zombie,
  1640.                             &target->i_zombie);
  1641.                 d_unhash(new_dentry);
  1642.         } else
  1643.                 double_down(&old_dir->i_zombie,
  1644.                             &new_dir->i_zombie);
  1645.         if (IS_DEADDIR(old_dir)||IS_DEADDIR(new_dir))
  1646.                 error = -ENOENT;
  1647.         else if (d_mountpoint(old_dentry)||d_mountpoint(new_dentry))
  1648.                 error = -EBUSY;
  1649.         else 
  1650.                 error = do_rename(fset, old_parent, old_dentry,
  1651.                                          new_parent, new_dentry, info);
  1652.         if (target) {
  1653.                 if (!error)
  1654.                         target->i_flags |= S_DEAD;
  1655.                 triple_up(&old_dir->i_zombie,
  1656.                           &new_dir->i_zombie,
  1657.                           &target->i_zombie);
  1658.                 if (d_unhashed(new_dentry))
  1659.                         d_rehash(new_dentry);
  1660.                 dput(new_dentry);
  1661.         } else
  1662.                 double_up(&old_dir->i_zombie,
  1663.                           &new_dir->i_zombie);
  1664.                 
  1665.         if (!error)
  1666.                 d_move(old_dentry,new_dentry);
  1667. out_unlock:
  1668.         up(&old_dir->i_sb->s_vfs_rename_sem);
  1669.         return error;
  1670. }
  1671. static
  1672. int presto_rename_other(struct presto_file_set *fset, struct dentry *old_parent,
  1673.                         struct dentry *old_dentry, struct dentry *new_parent,
  1674.                         struct dentry *new_dentry, struct lento_vfs_context *info)
  1675. {
  1676.         struct inode *old_dir = old_parent->d_inode;
  1677.         struct inode *new_dir = new_parent->d_inode;
  1678.         int error;
  1679.         if (old_dentry->d_inode == new_dentry->d_inode)
  1680.                 return 0;
  1681.         error = may_delete(old_dir, old_dentry, 0);
  1682.         if (error)
  1683.                 return error;
  1684.         if (new_dir->i_dev != old_dir->i_dev)
  1685.                 return -EXDEV;
  1686.         if (!new_dentry->d_inode)
  1687.                 error = may_create(new_dir, new_dentry);
  1688.         else
  1689.                 error = may_delete(new_dir, new_dentry, 0);
  1690.         if (error)
  1691.                 return error;
  1692.         if (!old_dir->i_op || !old_dir->i_op->rename)
  1693.                 return -EPERM;
  1694.         DQUOT_INIT(old_dir);
  1695.         DQUOT_INIT(new_dir);
  1696.         double_down(&old_dir->i_zombie, &new_dir->i_zombie);
  1697.         if (d_mountpoint(old_dentry)||d_mountpoint(new_dentry))
  1698.                 error = -EBUSY;
  1699.         else
  1700.                 error = do_rename(fset, old_parent, old_dentry,
  1701.                                   new_parent, new_dentry, info);
  1702.         double_up(&old_dir->i_zombie, &new_dir->i_zombie);
  1703.         if (error)
  1704.                 return error;
  1705.         /* The following d_move() should become unconditional */
  1706.         if (!(old_dir->i_sb->s_type->fs_flags & FS_ODD_RENAME)) {
  1707.                 d_move(old_dentry, new_dentry);
  1708.         }
  1709.         return 0;
  1710. }
  1711. int presto_do_rename(struct presto_file_set *fset, 
  1712.               struct dentry *old_parent, struct dentry *old_dentry,
  1713.               struct dentry *new_parent, struct dentry *new_dentry,
  1714.               struct lento_vfs_context *info)
  1715. {
  1716.         if (S_ISDIR(old_dentry->d_inode->i_mode))
  1717.                 return presto_rename_dir(fset, old_parent,old_dentry,new_parent,
  1718.                                       new_dentry, info);
  1719.         else
  1720.                 return presto_rename_other(fset, old_parent, old_dentry,
  1721.                                            new_parent,new_dentry, info);
  1722. }
  1723. int lento_do_rename(const char *oldname, const char *newname,
  1724.                  struct lento_vfs_context *info)
  1725. {
  1726.         int error = 0;
  1727.         struct dentry * old_dir, * new_dir;
  1728.         struct dentry * old_dentry, *new_dentry;
  1729.         struct nameidata oldnd, newnd;
  1730.         struct presto_file_set *fset;
  1731.         ENTRY;
  1732.         if (path_init(oldname, LOOKUP_PARENT, &oldnd))
  1733.                 error = path_walk(oldname, &oldnd);
  1734.         if (error)
  1735.                 goto exit;
  1736.         if (path_init(newname, LOOKUP_PARENT, &newnd))
  1737.                 error = path_walk(newname, &newnd);
  1738.         if (error)
  1739.                 goto exit1;
  1740.         error = -EXDEV;
  1741.         if (oldnd.mnt != newnd.mnt)
  1742.                 goto exit2;
  1743.         old_dir = oldnd.dentry;
  1744.         error = -EBUSY;
  1745.         if (oldnd.last_type != LAST_NORM)
  1746.                 goto exit2;
  1747.         new_dir = newnd.dentry;
  1748.         if (newnd.last_type != LAST_NORM)
  1749.                 goto exit2;
  1750.         double_lock(new_dir, old_dir);
  1751.         old_dentry = lookup_hash(&oldnd.last, old_dir);
  1752.         error = PTR_ERR(old_dentry);
  1753.         if (IS_ERR(old_dentry))
  1754.                 goto exit3;
  1755.         /* source must exist */
  1756.         error = -ENOENT;
  1757.         if (!old_dentry->d_inode)
  1758.                 goto exit4;
  1759.         fset = presto_fset(old_dentry);
  1760.         error = -EINVAL;
  1761.         if ( !fset ) {
  1762.                 CERROR("No fileset!n");
  1763.                 EXIT;
  1764.                 goto exit4;
  1765.         }
  1766.         /* unless the source is a directory trailing slashes give -ENOTDIR */
  1767.         if (!S_ISDIR(old_dentry->d_inode->i_mode)) {
  1768.                 error = -ENOTDIR;
  1769.                 if (oldnd.last.name[oldnd.last.len])
  1770.                         goto exit4;
  1771.                 if (newnd.last.name[newnd.last.len])
  1772.                         goto exit4;
  1773.         }
  1774.         new_dentry = lookup_hash(&newnd.last, new_dir);
  1775.         error = PTR_ERR(new_dentry);
  1776.         if (IS_ERR(new_dentry))
  1777.                 goto exit4;
  1778.         lock_kernel();
  1779.         error = presto_do_rename(fset, old_dir, old_dentry,
  1780.                                    new_dir, new_dentry, info);
  1781.         unlock_kernel();
  1782.         dput(new_dentry);
  1783. exit4:
  1784.         dput(old_dentry);
  1785. exit3:
  1786.         double_up(&new_dir->d_inode->i_sem, &old_dir->d_inode->i_sem);
  1787. exit2:
  1788.         path_release(&newnd);
  1789. exit1:
  1790.         path_release(&oldnd);
  1791. exit:
  1792.         return error;
  1793. }
  1794. int  lento_rename(const char * oldname, const char * newname,
  1795.                   struct lento_vfs_context *info)
  1796. {
  1797.         int error;
  1798.         char * from;
  1799.         char * to;
  1800.         from = getname(oldname);
  1801.         if(IS_ERR(from))
  1802.                 return PTR_ERR(from);
  1803.         to = getname(newname);
  1804.         error = PTR_ERR(to);
  1805.         if (!IS_ERR(to)) {
  1806.                 error = lento_do_rename(from,to, info);
  1807.                 putname(to);
  1808.         } 
  1809.         putname(from);
  1810.         return error;
  1811. }
  1812. struct dentry *presto_iopen(struct dentry *dentry,
  1813.                             ino_t ino, unsigned int generation)
  1814. {
  1815.         struct presto_file_set *fset;
  1816.         char name[48];
  1817.         int error;
  1818.         ENTRY;
  1819.         /* see if we already have the dentry we want */
  1820.         if (dentry->d_inode && dentry->d_inode->i_ino == ino &&
  1821.             dentry->d_inode->i_generation == generation) {
  1822.                 EXIT;
  1823.                 return dentry;
  1824.         }
  1825.         /* Make sure we have a cache beneath us.  We should always find at
  1826.          * least one dentry inside the cache (if it exists), otherwise not
  1827.          * even the cache root exists, or we passed in a bad name.
  1828.          */
  1829.         fset = presto_fset(dentry);
  1830.         error = -EINVAL;
  1831.         if (!fset) {
  1832.                 CERROR("No fileset for %*s!n",
  1833.                        dentry->d_name.len, dentry->d_name.name);
  1834.                 EXIT;
  1835.                 dput(dentry);
  1836.                 return ERR_PTR(error);
  1837.         }
  1838.         dput(dentry);
  1839.         sprintf(name, "%s%#lx%c%#x",
  1840.                 PRESTO_ILOOKUP_MAGIC, ino, PRESTO_ILOOKUP_SEP, generation);
  1841.         CDEBUG(D_PIOCTL, "opening %ld by number (as %s)n", ino, name);
  1842.         return lookup_one_len(name, fset->fset_dentry, strlen(name));
  1843. }
  1844. static struct file *presto_filp_dopen(struct dentry *dentry, int flags)
  1845. {
  1846.         struct file *f;
  1847.         struct inode *inode;
  1848.         int flag, error;
  1849.         ENTRY;
  1850.         error = -ENFILE;
  1851.         f = get_empty_filp();
  1852.         if (!f) {
  1853.                 CDEBUG(D_PIOCTL, "error getting file pointern");
  1854.                 EXIT;
  1855.                 goto out;
  1856.         }
  1857.         f->f_flags = flag = flags;
  1858.         f->f_mode = (flag+1) & O_ACCMODE;
  1859.         inode = dentry->d_inode;
  1860.         if (f->f_mode & FMODE_WRITE) {
  1861.                 error = get_write_access(inode);
  1862.                 if (error) {
  1863.                         CDEBUG(D_PIOCTL, "error getting write accessn");
  1864.                         EXIT;                        goto cleanup_file;
  1865.                 }
  1866.         }
  1867.         f->f_dentry = dentry;
  1868.         f->f_pos = 0;
  1869.         f->f_reada = 0;
  1870.         f->f_op = NULL;
  1871.         if (inode->i_op)
  1872.                 /* XXX should we set to presto ops, or leave at cache ops? */
  1873.                 f->f_op = inode->i_fop;
  1874.         if (f->f_op && f->f_op->open) {
  1875.                 error = f->f_op->open(inode, f);
  1876.                 if (error) {
  1877.                         CDEBUG(D_PIOCTL, "error calling cache 'open'n");
  1878.                         EXIT;
  1879.                         goto cleanup_all;
  1880.                 }
  1881.         }
  1882.         f->f_flags &= ~(O_CREAT | O_EXCL | O_NOCTTY | O_TRUNC);
  1883.         return f;
  1884. cleanup_all:
  1885.         if (f->f_mode & FMODE_WRITE)
  1886.                 put_write_access(inode);
  1887. cleanup_file:
  1888.         put_filp(f);
  1889. out:
  1890.         return ERR_PTR(error);
  1891. }
  1892. /* Open an inode by number.  We pass in the cache root name (or a subdirectory
  1893.  * from the cache that is guaranteed to exist) to be able to access the cache.
  1894.  */
  1895. int lento_iopen(const char *name, ino_t ino, unsigned int generation,
  1896.                 int flags)
  1897. {
  1898.         char * tmp;
  1899.         struct dentry *dentry;
  1900.         struct nameidata nd;
  1901.         int fd;
  1902.         int error;
  1903.         ENTRY;
  1904.         CDEBUG(D_PIOCTL,
  1905.                "open %s:inode %#lx (%ld), generation %x (%d), flags %d n",
  1906.                name, ino, ino, generation, generation, flags);
  1907.         /* We don't allow creation of files by number only, as it would
  1908.          * lead to a dangling files not in any directory.  We could also
  1909.          * just turn off the flag and ignore it.
  1910.          */
  1911.         if (flags & O_CREAT) {
  1912.                 CERROR("%s: create file by inode number (%ld) not allowedn",
  1913.                        __FUNCTION__, ino);
  1914.                 EXIT;
  1915.                 return -EACCES;
  1916.         }
  1917.         tmp = getname(name);
  1918.         if (IS_ERR(tmp)) {
  1919.                 EXIT;
  1920.                 return PTR_ERR(tmp);
  1921.         }
  1922.         lock_kernel();
  1923. again:  /* look the named file or a parent directory so we can get the cache */
  1924.         error = presto_walk(tmp, &nd);
  1925.         if ( error && error != -ENOENT ) {
  1926.                 EXIT;
  1927.                 unlock_kernel();
  1928.                 return error;
  1929.         } 
  1930.         if (error == -ENOENT)
  1931.                 dentry = NULL;
  1932.         else 
  1933.                 dentry = nd.dentry;
  1934.         /* we didn't find the named file, so see if a parent exists */
  1935.         if (!dentry) {
  1936.                 char *slash;
  1937.                 slash = strrchr(tmp, '/');
  1938.                 if (slash && slash != tmp) {
  1939.                         *slash = '';
  1940.                         path_release(&nd);
  1941.                         goto again;
  1942.                 }
  1943.                 /* we should never get here... */
  1944.                 CDEBUG(D_PIOCTL, "no more path components to try!n");
  1945.                 fd = -ENOENT;
  1946.                 goto exit;
  1947.         }
  1948.         CDEBUG(D_PIOCTL, "returned dentry %pn", dentry);
  1949.         dentry = presto_iopen(dentry, ino, generation);
  1950.         fd = PTR_ERR(dentry);
  1951.         if (IS_ERR(dentry)) {
  1952.                 EXIT;
  1953.                 goto exit;
  1954.         }
  1955.         /* XXX start of code that might be replaced by something like:
  1956.          * if (flags & (O_WRONLY | O_RDWR)) {
  1957.          *      error = get_write_access(dentry->d_inode);
  1958.          *      if (error) {
  1959.          *              EXIT;
  1960.          *              goto cleanup_dput;
  1961.          *      }
  1962.          * }
  1963.          * fd = open_dentry(dentry, flags);
  1964.          *
  1965.          * including the presto_filp_dopen() function (check dget counts!)
  1966.          */
  1967.         fd = get_unused_fd();
  1968.         if (fd < 0) {
  1969.                 EXIT;
  1970.                 goto cleanup_dput;
  1971.         }
  1972.         {
  1973.                 int error;
  1974.                 struct file * f = presto_filp_dopen(dentry, flags);
  1975.                 error = PTR_ERR(f);
  1976.                 if (IS_ERR(f)) {
  1977.                         put_unused_fd(fd);
  1978.                         fd = error;
  1979.                         EXIT;
  1980.                         goto cleanup_dput;
  1981.                 }
  1982.                 fd_install(fd, f);
  1983.         }
  1984.         /* end of code that might be replaced by open_dentry */
  1985.         EXIT;
  1986. exit:
  1987.         unlock_kernel();
  1988.         path_release(&nd);
  1989.         putname(tmp);
  1990.         return fd;
  1991. cleanup_dput:
  1992.         putname(&nd);
  1993.         goto exit;
  1994. }
  1995. #ifdef CONFIG_FS_EXT_ATTR
  1996. #ifdef CONFIG_FS_POSIX_ACL
  1997. /* Posix ACL code changes i_mode without using a notify_change (or
  1998.  * a mark_inode_dirty!). We need to duplicate this at the reintegrator
  1999.  * which is done by this function. This function also takes care of 
  2000.  * resetting the cached posix acls in this inode. If we don't reset these
  2001.  * VFS continues using the old acl information, which by now may be out of
  2002.  * date.
  2003.  */
  2004. int presto_setmode(struct presto_file_set *fset, struct dentry *dentry,
  2005.                    mode_t mode)
  2006. {
  2007.         struct inode *inode = dentry->d_inode;
  2008.         ENTRY;
  2009.         /* The extended attributes for this inode were modified. 
  2010.          * At this point we can not be sure if any of the ACL 
  2011.          * information for this inode was updated. So we will 
  2012.          * force VFS to reread the acls. Note that we do this 
  2013.          * only when called from the SETEXTATTR ioctl, which is why we
  2014.          * do this while setting the mode of the file. Also note
  2015.          * that mark_inode_dirty is not be needed for i_*acl only
  2016.          * to force i_mode info to disk, and should be removed once
  2017.          * we use notify_change to update the mode.
  2018.          * XXX: is mode setting really needed? Just setting acl's should
  2019.          * be enough! VFS should change the i_mode as needed? SHP
  2020.          */
  2021.         if (inode->i_acl && 
  2022.             inode->i_acl != POSIX_ACL_NOT_CACHED) 
  2023.             posix_acl_release(inode->i_acl);
  2024.         if (inode->i_default_acl && 
  2025.             inode->i_default_acl != POSIX_ACL_NOT_CACHED) 
  2026.             posix_acl_release(inode->i_default_acl);
  2027.         inode->i_acl = POSIX_ACL_NOT_CACHED;
  2028.         inode->i_default_acl = POSIX_ACL_NOT_CACHED;
  2029.         inode->i_mode = mode;
  2030.         /* inode should already be dirty...but just in case */
  2031.         mark_inode_dirty(inode);
  2032.         return 0;
  2033. #if 0
  2034.         /* XXX: The following code is the preferred way to set mode, 
  2035.          * however, I need to carefully go through possible recursion
  2036.          * paths back into presto. See comments in presto_do_setattr.
  2037.          */
  2038.         {    
  2039.         int error=0; 
  2040.         struct super_operations *sops;
  2041.         struct iattr iattr;
  2042.         iattr.ia_mode = mode;
  2043.         iattr.ia_valid = ATTR_MODE|ATTR_FORCE;
  2044.         error = -EPERM;
  2045.         sops = filter_c2csops(fset->fset_cache->cache_filter); 
  2046.         if (!sops &&
  2047.             !sops->notify_change) {
  2048.                 EXIT;
  2049.                 return error;
  2050.         }
  2051.         error = sops->notify_change(dentry, &iattr);
  2052.         EXIT;
  2053.         return error;
  2054.         }
  2055. #endif
  2056. }
  2057. #endif
  2058. /* setextattr Interface to cache filesystem */
  2059. int presto_do_set_ext_attr(struct presto_file_set *fset, 
  2060.                            struct dentry *dentry, 
  2061.                            const char *name, void *buffer,
  2062.                            size_t buffer_len, int flags, mode_t *mode,
  2063.                            struct lento_vfs_context *info) 
  2064. {
  2065.         struct rec_info rec;
  2066.         struct inode *inode = dentry->d_inode;
  2067.         struct inode_operations *iops;
  2068.         int error;
  2069.         struct presto_version ver;
  2070.         void *handle;
  2071.         char temp[PRESTO_EXT_ATTR_NAME_MAX+1];
  2072.         ENTRY;
  2073.         error = -EROFS;
  2074.         if (IS_RDONLY(inode)) {
  2075.                 EXIT;
  2076.                 return -EROFS;
  2077.         }
  2078.         if (IS_IMMUTABLE(inode) || IS_APPEND(inode)) {
  2079.                 EXIT;
  2080.                 return -EPERM;
  2081.         }
  2082.         presto_getversion(&ver, inode);
  2083.         error = -EPERM;
  2084.         /* We need to invoke different filters based on whether
  2085.          * this dentry is a regular file, directory or symlink.
  2086.          */
  2087.         switch (inode->i_mode & S_IFMT) {
  2088.                 case S_IFLNK: /* symlink */
  2089.                     iops = filter_c2csiops(fset->fset_cache->cache_filter); 
  2090.                     break;
  2091.                 case S_IFDIR: /* directory */
  2092.                     iops = filter_c2cdiops(fset->fset_cache->cache_filter); 
  2093.                     break;
  2094.                 case S_IFREG:
  2095.                 default: /* everything else including regular files */
  2096.                     iops = filter_c2cfiops(fset->fset_cache->cache_filter); 
  2097.         }
  2098.         if (!iops && !iops->set_ext_attr) {
  2099.                 EXIT;
  2100.                 return error;
  2101.         }
  2102.         error = presto_reserve_space(fset->fset_cache, PRESTO_REQHIGH); 
  2103.         if (error) {
  2104.                 EXIT;
  2105.                 return error;
  2106.         }
  2107.         
  2108.         handle = presto_trans_start(fset,dentry->d_inode,KML_OPCODE_SETEXTATTR);
  2109.         if ( IS_ERR(handle) ) {
  2110.                 CERROR("presto_do_set_ext_attr: no space for transactionn");
  2111.                 presto_release_space(fset->fset_cache, PRESTO_REQHIGH); 
  2112.                 return -ENOSPC;
  2113.         }
  2114.         /* We first "truncate" name to the maximum allowable in presto */
  2115.         /* This simulates the strncpy_from_use code in fs/ext_attr.c */
  2116.         strncpy(temp,name,sizeof(temp));
  2117.         /* Pass down to cache*/
  2118.         error = iops->set_ext_attr(inode,temp,buffer,buffer_len,flags);
  2119.         if (error) {
  2120.                 EXIT;
  2121.                 goto exit;
  2122.         }
  2123. #ifdef CONFIG_FS_POSIX_ACL
  2124.         /* Reset mode if specified*/
  2125.         /* XXX: when we do native acl support, move this code out! */
  2126.         if (mode != NULL) {
  2127.                 error = presto_setmode(fset, dentry, *mode);
  2128.                 if (error) { 
  2129.                     EXIT;
  2130.                     goto exit;
  2131.                 }
  2132.         }
  2133. #endif
  2134.         /* Reset ctime. Only inode change time (ctime) is affected */
  2135.         error = presto_settime(fset, NULL, NULL, dentry, info, ATTR_CTIME);
  2136.         if (error) { 
  2137.                 EXIT;
  2138.                 goto exit;
  2139.         }
  2140.         if (flags & EXT_ATTR_FLAG_USER) {
  2141.                 CERROR(" USER flag passed to presto_do_set_ext_attr!n");
  2142.                 BUG();
  2143.         }
  2144.         /* We are here, so set_ext_attr succeeded. We no longer need to keep
  2145.          * track of EXT_ATTR_FLAG_{EXISTS,CREATE}, instead, we will force
  2146.          * the attribute value during log replay. -SHP
  2147.          */
  2148.         flags &= ~(EXT_ATTR_FLAG_EXISTS | EXT_ATTR_FLAG_CREATE);
  2149.         presto_debug_fail_blkdev(fset, KML_OPCODE_SETEXTATTR | 0x10);
  2150.         if ( presto_do_kml(info, dentry) )
  2151.                 error = presto_journal_set_ext_attr
  2152.                         (&rec, fset, dentry, &ver, name, buffer, 
  2153.                          buffer_len, flags);
  2154.         presto_debug_fail_blkdev(fset, KML_OPCODE_SETEXTATTR | 0x20);
  2155.         if ( presto_do_rcvd(info, dentry) )
  2156.                 error = presto_write_last_rcvd(&rec, fset, info);
  2157.         presto_debug_fail_blkdev(fset, KML_OPCODE_SETEXTATTR | 0x30);
  2158.         EXIT;
  2159. exit:
  2160.         presto_release_space(fset->fset_cache, PRESTO_REQHIGH); 
  2161.         presto_trans_commit(fset, handle);
  2162.         return error;
  2163. }
  2164. #endif