lkml.org 
[lkml]   [1997]   [Jul]   [28]   [last100]   RSS Feed
Views: [wrap][no wrap]   [headers]  [forward] 
 
Messages in this thread
    Patch in this message
    /
    Date
    From
    SubjectPATCH: ext2-undelete!
    On Sun, 27 Jul 1997, Kurt Huwig wrote:
    > On Sun, 27 Jul 1997, Rogier Wolff wrote:
    > > Kurt Huwig wrote:
    > > > I looked through dejanews and found Rogier's patch. It did not patch in
    > > > directly, because the sources have changed a little bit, so I did it by
    > > > hand, together with minor changes:
    > >
    > > Kurt, there should be a followup that had a slightly different patch.
    > > There is an attribute bit that says "this file needs safe delete",
    > > which is currently unused. I didn't know that, so I wrote it without
    > > using that bit. Someon else volunteerd "but there is a bit, for which
    > > you just made the implementation".
    >
    > After some time, I found the patch.

    Darren made some mistakes in his patch:

    - he made the name of the directory adjustable via define, but overlooked
    that you need the length of it in 'ext2_lookup'. So it would only work
    if you use a name with 12 letters. I don't want to use 'strlen' here.
    - he did not move the 'ext2_unlink' code after 'do_ext2_rename', so it
    won't compile at all. A
    - he changed some of the 'printk' into 'ext2_debug' but still every move
    is reported via one printk...annoying
    - you/he said 'moveing' instead of 'moving'...ok my English is worse ;-)

    I included the reference to 'chattr' and 'lsattr' in the config help. I
    think this will prevent any FAQs about how to set the 'u'-bit... ;-)

    Kurt

    -------------------------------------------------------------
    Impossible doesn't exist! Unmöglich gibt's nicht!
    Difficult exists. Schwierig gibt's.

    --- linux/Documentation/Configure.help.orig Sun Jul 27 14:27:45 1997
    +++ linux/Documentation/Configure.help Mon Jul 28 13:34:17 1997
    @@ -2987,6 +2987,29 @@
    sunsite.unc.edu:/pub/Linux/docs/faqs. This option will enlarge your
    kernel by about 41 kB. Default is Y.

    +Undelete support for ext2 filesystems
    +CONFIG_EXT2_UNDELETE
    + This enables an undelete feature for ext2-partitions. Files marked
    + with the ext2 attribute 'u' for 'undo remove' will be moved to a
    + .wastebasket directory at the top of the fs, similar to lost+found
    + and the bit will be cleared. If no .wastebasket directory exists
    + then undeletion is not active on that partition. All files created
    + in a directory with the 'u'-bit set will have it set, too.
    + You can use 'chattr' and 'lsattr' to change and view this attribute.
    + They are in the package 'e2fsprogs' available at
    + ftp://sunsite.unc.edu/pub/Linux/system/filesystems/ext2/
    + At present if a file in the .wastebasket directory already exists
    + then _0 is appened to the next file of that name and so on.
    + CAVEATS:
    + - If a user has the right to delete a file, it will be moved
    + to the wastebasket regardless of the permissions of the
    + wastebasket. If you don't want security holes to others, you
    + should make the wastebasket mode 700.
    + - You have to make sure that the directory is emptied or your
    + harddisk will be full very soon!
    + - Remember to set the 'u' bit on undeleted files if you want them
    + to be undelete-able again.
    +
    xiafs filesystem support
    CONFIG_XIA_FS
    This is an old filesystem (= method to organize files on a harddisk
    --- linux/fs/Config.in.orig Thu Jul 17 01:02:37 1997
    +++ linux/fs/Config.in Mon Jul 28 13:42:52 1997
    @@ -11,6 +11,9 @@
    tristate 'Second extended fs support' CONFIG_EXT2_FS
    if [ "$CONFIG_EXT2_FS" = "y" ]; then
    bool ' NO_ATIME support for ext2 filesystems' CONFIG_EXT2_NOATIME
    + if [ "$CONFIG_EXPERIMENTAL" = "y" ]; then
    + bool ' Undelete support for ext2 filesystems (EXPERIMENTAL)' CONFIG_EXT2_UNDELETE
    + fi
    fi
    tristate 'xiafs filesystem support' CONFIG_XIA_FS

    --- linux/fs/ext2/namei.c.orig Sat Nov 30 11:21:20 1996
    +++ linux/fs/ext2/namei.c Mon Jul 28 00:58:24 1997
    @@ -695,73 +695,6 @@
    return retval;
    }

    -int ext2_unlink (struct inode * dir, const char * name, int len)
    -{
    - int retval;
    - struct inode * inode;
    - struct buffer_head * bh;
    - struct ext2_dir_entry * de;
    -
    -repeat:
    - if (!dir)
    - return -ENOENT;
    - retval = -ENOENT;
    - inode = NULL;
    - if (len > EXT2_NAME_LEN) {
    - iput (dir);
    - return -ENAMETOOLONG;
    - }
    - bh = ext2_find_entry (dir, name, len, &de);
    - if (!bh)
    - goto end_unlink;
    - if (!(inode = iget (dir->i_sb, de->inode)))
    - goto end_unlink;
    - if (inode->i_sb->dq_op)
    - inode->i_sb->dq_op->initialize (inode, -1);
    - retval = -EPERM;
    - if (S_ISDIR(inode->i_mode))
    - goto end_unlink;
    - if (IS_APPEND(inode) || IS_IMMUTABLE(inode))
    - goto end_unlink;
    - if (de->inode != inode->i_ino) {
    - iput(inode);
    - brelse(bh);
    - current->counter = 0;
    - schedule();
    - goto repeat;
    - }
    - if ((dir->i_mode & S_ISVTX) && !fsuser() &&
    - current->fsuid != inode->i_uid &&
    - current->fsuid != dir->i_uid)
    - goto end_unlink;
    - if (!inode->i_nlink) {
    - ext2_warning (inode->i_sb, "ext2_unlink",
    - "Deleting nonexistent file (%lu), %d",
    - inode->i_ino, inode->i_nlink);
    - inode->i_nlink = 1;
    - }
    - retval = ext2_delete_entry (de, bh);
    - if (retval)
    - goto end_unlink;
    - dir->i_version = ++event;
    - mark_buffer_dirty(bh, 1);
    - if (IS_SYNC(dir)) {
    - ll_rw_block (WRITE, 1, &bh);
    - wait_on_buffer (bh);
    - }
    - dir->i_ctime = dir->i_mtime = CURRENT_TIME;
    - dir->i_dirt = 1;
    - inode->i_nlink--;
    - inode->i_dirt = 1;
    - inode->i_ctime = dir->i_ctime;
    - retval = 0;
    -end_unlink:
    - brelse (bh);
    - iput (inode);
    - iput (dir);
    - return retval;
    -}
    -
    int ext2_symlink (struct inode * dir, const char * name, int len,
    const char * symname)
    {
    @@ -1101,6 +1034,120 @@
    iput (new_inode);
    iput (old_dir);
    iput (new_dir);
    + return retval;
    +}
    +
    +int ext2_unlink (struct inode * dir, const char * name, int len)
    +{
    + int retval;
    + struct inode * inode;
    + struct buffer_head * bh;
    + struct ext2_dir_entry * de;
    +
    +repeat:
    + if (!dir)
    + return -ENOENT;
    + retval = -ENOENT;
    + inode = NULL;
    + if (len > EXT2_NAME_LEN) {
    + iput (dir);
    + return -ENAMETOOLONG;
    + }
    + bh = ext2_find_entry (dir, name, len, &de);
    + if (!bh)
    + goto end_unlink;
    + if (!(inode = iget (dir->i_sb, de->inode)))
    + goto end_unlink;
    + if (inode->i_sb->dq_op)
    + inode->i_sb->dq_op->initialize (inode, -1);
    + retval = -EPERM;
    + if (S_ISDIR(inode->i_mode))
    + goto end_unlink;
    + if (IS_APPEND(inode) || IS_IMMUTABLE(inode))
    + goto end_unlink;
    + if (de->inode != inode->i_ino) {
    + iput(inode);
    + brelse(bh);
    + current->counter = 0;
    + schedule();
    + goto repeat;
    + }
    + if ((dir->i_mode & S_ISVTX) && !fsuser() &&
    + current->fsuid != inode->i_uid &&
    + current->fsuid != dir->i_uid)
    + goto end_unlink;
    + if (!inode->i_nlink) {
    + ext2_warning (inode->i_sb, "ext2_unlink",
    + "Deleting nonexistent file (%lu), %d",
    + inode->i_ino, inode->i_nlink);
    + inode->i_nlink = 1;
    + }
    +#ifdef CONFIG_EXT2_UNDELETE
    + /* Only move if 'UNDO REMOVE' bit set */
    + if (inode->u.ext2_i.i_flags & EXT2_UNRM_FL) {
    + if (inode->i_sb) {
    + struct inode *wb,*tmp;
    + const char *new_name;
    + char buf[EXT2_NAME_LEN];
    + int new_len;
    + int version;
    +
    + inode->i_sb->s_mounted->i_count++;
    + if (ext2_lookup (inode->i_sb->s_mounted,".wastebasket",12,&wb) == 0) {
    + ext2_debug ("inode_c=%d, dir_c=%d,wb_c=%d\n",inode->i_count,dir->i_count,wb->i_count);
    + new_name=name;
    + new_len = len;
    + version = 0;
    + wb->i_count++;
    + while (ext2_lookup (wb,new_name,new_len,&tmp) == 0) {
    + iput (tmp);
    + sprintf (buf,"%s_%d",name,version++);
    + new_name = buf;
    + new_len = strlen (buf);
    + wb->i_count++;
    + }
    + ext2_debug ("moving %s to wastebasket as %s.\n",name,new_name);
    + while (dir->i_sb->u.ext2_sb.s_rename_lock)
    + sleep_on (&dir->i_sb->u.ext2_sb.s_rename_wait);
    + dir->i_sb->u.ext2_sb.s_rename_lock = 1;
    +
    + retval = do_ext2_rename (dir, name, len, wb, new_name, new_len, 0);
    +
    + dir->i_sb->u.ext2_sb.s_rename_lock = 0;
    + wake_up (&dir->i_sb->u.ext2_sb.s_rename_wait);
    + ext2_debug ("inode_c=%d, dir_c=%d,wb_c=%d\n",inode->i_count,dir->i_count,wb->i_count);
    + brelse (bh);
    + inode->u.ext2_i.i_flags &= ~EXT2_UNRM_FL;
    + iput (inode);
    + return retval;
    + } else {
    + ext2_debug ("No wastebasket. Old unlink for %s....\n",name);
    + }
    + } else {
    + printk ("Warning: Undelete can't find a superblock for inode %ld\n"
    + "Deleting file normally.\n",inode->i_ino);
    + }
    + }
    +#endif
    + retval = ext2_delete_entry (de, bh);
    + if (retval)
    + goto end_unlink;
    + dir->i_version = ++event;
    + mark_buffer_dirty(bh, 1);
    + if (IS_SYNC(dir)) {
    + ll_rw_block (WRITE, 1, &bh);
    + wait_on_buffer (bh);
    + }
    + dir->i_ctime = dir->i_mtime = CURRENT_TIME;
    + dir->i_dirt = 1;
    + inode->i_nlink--;
    + inode->i_dirt = 1;
    + inode->i_ctime = dir->i_ctime;
    + retval = 0;
    +end_unlink:
    + brelse (bh);
    + iput (inode);
    + iput (dir);
    return retval;
    }

    --- /dev/null Sun Jun 29 17:10:20 1997
    +++ linux/init/patches/ext2-undelete-2.0.30 Mon Jul 28 13:42:32 1997
    @@ -0,0 +1 @@
    +ext2 undelete support (Rogier Wolff <R.E.Wolff@BitWizard.nl>/Darren J Moffat <darren@xarius.demon.co.uk>/Kurt Huwig <kurt@huwig.de>)
    \
     
     \ /
      Last update: 2005-03-22 13:40    [W:0.047 / U:0.552 seconds]
    ©2003-2016 Jasper Spaans. hosted at Digital OceanAdvertise on this site