Whamcloud - gitweb
Add in a delete_inode method for use when the inode is finally unlinked,
authoradilger <adilger>
Fri, 29 Mar 2002 06:58:54 +0000 (06:58 +0000)
committeradilger <adilger>
Fri, 29 Mar 2002 06:58:54 +0000 (06:58 +0000)
so that we can clear out the objid if necessary.  Since delete_inode
is handled by a callback from the VFS when n_link == 0 (and we don't
want to introduce race conditions by checking this at unlink time), we
replace the client delete_inode method with a filesystem-specific MDS
delete_inode call, and then call the client delete_inode method from
within our MDS delete_inode operation.

lustre/mds/mds_ext2.c
lustre/mds/mds_ext3.c

index 4649322..f2a24b2 100644 (file)
@@ -76,6 +76,17 @@ static ssize_t mds_ext2_readpage(struct file *file, char *buf, size_t count,
                 return generic_file_read(file, buf, count, offset);
 }
 
+struct mds_fs_operations mds_ext2_fs_ops;
+
+void mds_ext2_delete_inode(struct inode * inode)
+{
+        if (!S_ISDIR(inode->i_mode))
+                mds_ext2_set_objid(inode, NULL, 0);
+
+        if (mds_ext2_fs_ops.cl_delete_inode)
+                mds_ext2_fs_ops.cl_delete_inode(inode);
+}
+
 struct mds_fs_operations mds_ext2_fs_ops = {
         fs_start:       mds_ext2_start,
         fs_commit:      mds_ext2_stop,
@@ -83,4 +94,6 @@ struct mds_fs_operations mds_ext2_fs_ops = {
         fs_set_objid:   mds_ext2_set_objid,
         fs_get_objid:   mds_ext2_get_objid,
         fs_readpage:    mds_ext2_readpage,
+        fs_delete_inode:mds_ext2_delete_inode,
+        cl_delete_inode:NULL,
 };
index 7f14e30..de62b4f 100644 (file)
@@ -33,19 +33,124 @@ static void *mds_ext3_start(struct inode *inode, int op)
         int nblocks = 0;
 
         switch(op) {
-        case MDS_JOP_RMDIR:
-        case MDS_JOP_UNLINK:     nblocks = EXT3_DELETE_TRANS_BLOCKS; break;
+        case MDS_FSOP_RMDIR:
+        case MDS_FSOP_UNLINK:   nblocks = EXT3_DELETE_TRANS_BLOCKS; break;
         }
 
         return journal_start(EXT3_JOURNAL(inode), nblocks);
 }
 
-static int mds_ext3_stop(void *handle, struct inode *inode)
+static int mds_ext3_commit(struct inode *inode, void *handle)
 {
         return journal_stop((handle_t *)handle);
 }
 
-struct mds_journal_operations mds_ext3_journal_ops = {
-        tr_start:       mds_ext3_start,
-        tr_commit:      mds_ext3_stop,
+static int mds_ext3_setattr(struct inode *inode, void *handle,
+                            struct iattr *iattr)
+{
+        /* a _really_ horrible hack to avoid removing the data stored
+           in the block pointers; this data is the object id
+           this will go into an extended attribute at some point.
+        */
+        if ( iattr->ia_valid & ATTR_SIZE ) {
+                /* ATTR_SIZE would invoke truncate: clear it */
+                iattr->ia_valid &= ~ATTR_SIZE;
+                inode->i_size = iattr->ia_size;
+
+                /* an _even_more_ horrible hack to make this hack work with
+                 * ext3.  This is because ext3 keeps a separate inode size
+                 * until the inode is committed to ensure consistency.  This
+                 * will also go away with the move to EAs.
+                 */
+                EXT3_I(inode)->i_disksize = inode->i_size;
+
+                /* make sure _something_ gets set - so new inode
+                   goes to disk (probably won't work over XFS */
+                if (!iattr->ia_valid & ATTR_MODE) {
+                        iattr->ia_valid |= ATTR_MODE;
+                        iattr->ia_mode = inode->i_mode;
+                }
+        }
+
+        return 0;
+}
+
+/*
+ * FIXME: nasty hack - store the object id in the first two
+ *        direct block spots.  This should be done with EAs...
+ */
+static int mds_ext3_set_objid(struct inode *inode, void *handle, obd_id id)
+{
+        memcpy(&EXT3_I(inode)->i_data, &id, sizeof(id));
+
+        return 0;
+}
+
+static void mds_ext3_get_objid(struct inode *inode, obd_id *id)
+{
+        memcpy(id, &EXT3_I(inode)->i_data, sizeof(*id));
+}
+
+static ssize_t mds_ext3_readpage(struct file *file, char *buf, size_t count,
+                                 loff_t *offset)
+{
+        struct inode *inode = file->f_dentry->d_inode;
+        int rc = 0;
+
+        if (S_ISREG(inode->i_mode))
+                rc = file->f_op->read(file, buf, count, offset);
+        else {
+                struct buffer_head *bh;
+
+                /* FIXME: this assumes the blocksize == count, but the calling
+                 *        function will detect this as an error for now */
+                bh = ext3_bread(NULL, inode,
+                                *offset >> inode->i_sb->s_blocksize_bits,
+                                0, &rc);
+
+                if (bh) {
+                        memcpy(buf, bh->b_data, inode->i_blksize);
+                        brelse(bh);
+                        rc = inode->i_blksize;
+                }
+        }
+
+        return rc;
+}
+
+struct mds_fs_operations mds_ext3_fs_ops;
+
+void mds_ext3_delete_inode(struct inode * inode)
+{
+        void *handle;
+
+        if (!S_ISDIR(inode->i_mode)) {
+                handle = mds_ext3_start(inode, MDS_FSOP_UNLINK);
+
+                if (!IS_ERR(handle)) {
+                        CERROR("unable to start transaction");
+                        EXIT;
+                        return;
+                }
+                if (mds_ext3_set_objid(inode, handle, 0))
+                        CERROR("error clearing objid on %ld\n", inode->i_ino);
+
+                if (mds_ext3_fs_ops.cl_delete_inode)
+                        mds_ext3_fs_ops.cl_delete_inode(inode);
+
+                if (mds_ext3_commit(inode, handle))
+                        CERROR("error closing handle on %ld\n", inode->i_ino);
+        } else if (mds_ext3_fs_ops.cl_delete_inode)
+                mds_ext3_fs_ops.cl_delete_inode(inode);
+}
+
+struct mds_fs_operations mds_ext3_fs_ops = {
+        fs_start:       mds_ext3_start,
+        fs_commit:      mds_ext3_commit,
+        fs_setattr:     mds_ext3_setattr,
+        fs_set_objid:   mds_ext3_set_objid,
+        fs_get_objid:   mds_ext3_get_objid,
+        fs_readpage:    mds_ext3_readpage,
+        fs_delete_inode:mds_ext3_delete_inode,
+        cl_delete_inode:NULL,
 };