vfs.c
上传用户:lgb322
上传日期:2013-02-24
资源大小:30529k
文件大小:72k
源码类别:

嵌入式Linux

开发平台:

Unix_Linux

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