patch-2.1.122 linux/fs/umsdos/inode.c
Next file: linux/fs/umsdos/ioctl.c
Previous file: linux/fs/umsdos/file.c
Back to the patch index
Back to the overall index
- Lines: 334
- Date:
Wed Sep 16 15:12:31 1998
- Orig file:
v2.1.121/linux/fs/umsdos/inode.c
- Orig date:
Wed Sep 9 14:51:09 1998
diff -u --recursive --new-file v2.1.121/linux/fs/umsdos/inode.c linux/fs/umsdos/inode.c
@@ -19,6 +19,7 @@
#include <linux/umsdos_fs.h>
#include <linux/list.h>
+extern struct dentry_operations umsdos_dentry_operations;
extern struct inode_operations umsdos_rdir_inode_operations;
@@ -59,7 +60,7 @@
void fill_new_filp (struct file *filp, struct dentry *dentry)
{
if (!dentry)
- printk("fill_new_filp: NULL dentry!\n");
+ printk(KERN_ERR "fill_new_filp: NULL dentry!\n");
memset (filp, 0, sizeof (struct file));
filp->f_reada = 1;
@@ -133,7 +134,7 @@
,inode->u.umsdos_i.i_emd_owner, inode->u.umsdos_i.pos
,inode->u.umsdos_i.i_emd_dir, inode->i_count));
- if (inode && pseudo_root && inode == pseudo_root) {
+ if (inode == pseudo_root) {
printk (KERN_ERR "Umsdos: Oops releasing pseudo_root."
" Notify jacques@solucorp.qc.ca\n");
}
@@ -151,23 +152,6 @@
/*
- * Call msdos_lookup, but set back the original msdos function table.
- * Return 0 if OK, or a negative error code if not.
- * Dentry will hold inode of the file, if successful
- */
-int umsdos_real_lookup (struct inode *dir, struct dentry *dentry)
-{
- int ret;
-
- PRINTK ((KERN_DEBUG "umsdos_real_lookup: looking for %s/%s /",
- dentry->d_parent->d_name.name, dentry->d_name.name));
- ret = msdos_lookup (dir, dentry);
- PRINTK (("/ returned %d\n", ret));
-
- return ret;
-}
-
-/*
* Complete the setup of an directory dentry.
* First, it completes the function pointers, then
* it locates the EMD file. If the EMD is there, then plug the
@@ -230,6 +214,32 @@
/*
* Add some info into an inode so it can find its owner quickly
*/
+void umsdos_set_dirinfo_new (struct dentry *dentry, off_t f_pos)
+{
+ struct inode *inode = dentry->d_inode;
+ struct dentry *demd;
+
+ inode->u.umsdos_i.i_emd_owner = 0;
+ inode->u.umsdos_i.pos = f_pos;
+
+ /* now check the EMD file */
+ demd = umsdos_get_emd_dentry(dentry->d_parent);
+ if (IS_ERR(demd)) {
+ goto out;
+ }
+ if (demd->d_inode) {
+ inode->u.umsdos_i.i_emd_owner = demd->d_inode->i_ino;
+ }
+ dput (demd);
+out:
+ return;
+}
+
+
+/*
+ * Add some info into an inode so it can find its owner quickly
+ * Note: Deprecated; use above function if possible.
+ */
void umsdos_set_dirinfo (struct inode *inode, struct inode *dir, off_t f_pos)
{
struct inode *emd_owner = umsdos_emd_dir_lookup (dir, 1);
@@ -238,7 +248,6 @@
goto out;
Printk (("umsdos_set_dirinfo: emd_owner is %lu for dir %lu\n",
emd_owner->i_ino, dir->i_ino));
- inode->u.umsdos_i.i_dir_owner = dir->i_ino;
inode->u.umsdos_i.i_emd_owner = emd_owner->i_ino;
inode->u.umsdos_i.pos = f_pos;
iput (emd_owner);
@@ -405,20 +414,23 @@
}
-/* #Specification: notify_change / i_nlink > 0
- * notify change is only done for inode with nlink > 0. An inode
- * with nlink == 0 is no longer associated with any entry in
- * the EMD file, so there is nothing to update.
- */
-static int internal_notify_change (struct inode *inode, struct iattr *attr)
+int UMSDOS_notify_change (struct dentry *dentry, struct iattr *attr)
{
- unsigned long i_emd_owner = inode->u.umsdos_i.i_emd_owner;
+ struct inode *inode = dentry->d_inode;
+ struct dentry *demd;
int ret;
+ struct file filp;
+ struct umsdos_dirent entry;
- Printk ((KERN_DEBUG "UMSDOS_notify_change: entering\n"));
+Printk(("UMSDOS_notify_change: entering for %s/%s\n",
+dentry->d_parent->d_name.name, dentry->d_name.name));
- if ((ret = inode_change_ok (inode, attr)) != 0)
+ ret = inode_change_ok (inode, attr);
+ if (ret) {
+printk("UMSDOS_notify_change: %s/%s change not OK, ret=%d\n",
+dentry->d_parent->d_name.name, dentry->d_name.name, ret);
goto out;
+ }
if (inode->i_nlink == 0)
goto out_nolink;
@@ -426,61 +438,77 @@
if (inode->i_ino == UMSDOS_ROOT_INO)
goto out_nolink;
- if (i_emd_owner != 0xffffffff && i_emd_owner != 0) {
- /* This inode is not a EMD file nor an inode used internally
- * by MSDOS, so we can update its status.
- * See emd.c
- */
- struct inode *emd_owner;
- struct file filp;
- struct umsdos_dirent entry;
- struct dentry *emd_dentry;
-
- Printk (("notify change %p ", inode));
- ret = -EPERM;
- emd_owner = iget (inode->i_sb, i_emd_owner);
- if (!emd_owner) {
- printk ("UMSDOS: emd_owner = NULL ???");
- goto out_nolink;
- }
- emd_dentry = geti_dentry (emd_owner); /* FIXME? */
- fill_new_filp (&filp, emd_dentry);
+ /* get the EMD file dentry */
+ demd = umsdos_get_emd_dentry(dentry->d_parent);
+ ret = PTR_ERR(demd);
+ if (IS_ERR(demd))
+ goto out_nolink;
+ ret = -EPERM;
+ if (!demd->d_inode) {
+ printk(KERN_WARNING
+ "UMSDOS_notify_change: no EMD file %s/%s\n",
+ demd->d_parent->d_name.name, demd->d_name.name);
+ goto out_dput;
+ }
+
+ ret = 0;
+ /* don't do anything if this is the EMD itself */
+ if (inode == demd->d_inode)
+ goto out_dput;
+
+ /* This inode is not a EMD file nor an inode used internally
+ * by MSDOS, so we can update its status.
+ * See emd.c
+ */
- filp.f_pos = inode->u.umsdos_i.pos;
- filp.f_reada = 0;
- Printk (("pos = %Lu ", filp.f_pos));
- /* Read only the start of the entry since we don't touch */
- /* the name */
- ret = umsdos_emd_dir_read (&filp, (char *) &entry,
- UMSDOS_REC_SIZE);
- if (!ret) {
- if (attr->ia_valid & ATTR_UID)
- entry.uid = attr->ia_uid;
- if (attr->ia_valid & ATTR_GID)
- entry.gid = attr->ia_gid;
- if (attr->ia_valid & ATTR_MODE)
- entry.mode = attr->ia_mode;
- if (attr->ia_valid & ATTR_ATIME)
- entry.atime = attr->ia_atime;
- if (attr->ia_valid & ATTR_MTIME)
- entry.mtime = attr->ia_mtime;
- if (attr->ia_valid & ATTR_CTIME)
- entry.ctime = attr->ia_ctime;
-
- entry.nlink = inode->i_nlink;
- filp.f_pos = inode->u.umsdos_i.pos;
- ret = umsdos_emd_dir_write (&filp, (char *) &entry,
- UMSDOS_REC_SIZE);
-
- Printk (("notify pos %lu ret %d nlink %d ",
- inode->u.umsdos_i.pos, ret, entry.nlink));
- /* #Specification: notify_change / msdos fs
- * notify_change operation are done only on the
- * EMD file. The msdos fs is not even called.
- */
- }
- iput(emd_owner);
- }
+ fill_new_filp (&filp, demd);
+ filp.f_pos = inode->u.umsdos_i.pos;
+Printk(("UMSDOS_notify_change: %s/%s reading at %u\n",
+dentry->d_parent->d_name.name, dentry->d_name.name, filp.f_pos));
+
+ /* Read only the start of the entry since we don't touch the name */
+ ret = umsdos_emd_dir_read (&filp, (char *) &entry, UMSDOS_REC_SIZE);
+ if (ret) {
+ printk(KERN_WARNING
+ "umsdos_notify_change: %s/%s EMD read error, ret=%d\n",
+ dentry->d_parent->d_name.name, dentry->d_name.name,ret);
+ goto out_dput;
+ }
+ if (attr->ia_valid & ATTR_UID)
+ entry.uid = attr->ia_uid;
+ if (attr->ia_valid & ATTR_GID)
+ entry.gid = attr->ia_gid;
+ if (attr->ia_valid & ATTR_MODE)
+ entry.mode = attr->ia_mode;
+ if (attr->ia_valid & ATTR_ATIME)
+ entry.atime = attr->ia_atime;
+ if (attr->ia_valid & ATTR_MTIME)
+ entry.mtime = attr->ia_mtime;
+ if (attr->ia_valid & ATTR_CTIME)
+ entry.ctime = attr->ia_ctime;
+
+ entry.nlink = inode->i_nlink;
+ filp.f_pos = inode->u.umsdos_i.pos;
+ ret = umsdos_emd_dir_write (&filp, (char *) &entry, UMSDOS_REC_SIZE);
+ if (ret)
+ printk(KERN_WARNING
+ "umsdos_notify_change: %s/%s EMD write error, ret=%d\n",
+ dentry->d_parent->d_name.name, dentry->d_name.name,ret);
+
+ Printk (("notify pos %lu ret %d nlink %d ",
+ inode->u.umsdos_i.pos, ret, entry.nlink));
+ /* #Specification: notify_change / msdos fs
+ * notify_change operation are done only on the
+ * EMD file. The msdos fs is not even called.
+ */
+#ifdef UMSDOS_DEBUG_VERBOSE
+if (entry.flags & UMSDOS_HIDDEN)
+printk("umsdos_notify_change: %s/%s hidden, nlink=%d, ret=%d\n",
+dentry->d_parent->d_name.name, dentry->d_name.name, entry.nlink, ret);
+#endif
+
+out_dput:
+ dput(demd);
out_nolink:
if (ret == 0)
inode_setattr (inode, attr);
@@ -489,11 +517,6 @@
}
-int UMSDOS_notify_change (struct dentry *dentry, struct iattr *attr)
-{
- return internal_notify_change (dentry->d_inode, attr);
-}
-
/*
* Update the disk with the inode content
*/
@@ -551,16 +574,15 @@
if (!res)
goto out_fail;
- printk (KERN_INFO "UMSDOS dentry-WIP-Beta 0.82-7 "
+ printk (KERN_INFO "UMSDOS dentry-Beta 0.83 "
"(compatibility level %d.%d, fast msdos)\n",
UMSDOS_VERSION, UMSDOS_RELEASE);
sb->s_op = &umsdos_sops;
MSDOS_SB(sb)->options.dotsOK = 0; /* disable hidden==dotfile */
- /* FIXME:?? clear d_op on root so it will not be inherited */
- sb->s_root->d_op = NULL;
-
+ /* install our dentry operations ... */
+ sb->s_root->d_op = &umsdos_dentry_operations;
pseudo = sb->s_root->d_inode;
umsdos_setup_dir(sb->s_root);
@@ -599,7 +621,7 @@
sbin = creat_dentry ("sbin", 4, NULL, root);
Printk ((KERN_DEBUG "Mounting root\n"));
- if (umsdos_real_lookup (pseudo, root) == 0
+ if (msdos_lookup (pseudo, root) == 0
&& (root->d_inode != NULL)
&& S_ISDIR (root->d_inode->i_mode)) {
@@ -609,7 +631,7 @@
etc = creat_dentry ("etc", 3, NULL, root);
- if (umsdos_real_lookup (pseudo, etc) == 0
+ if (msdos_lookup (pseudo, etc) == 0
&& S_ISDIR (etc->d_inode->i_mode)) {
Printk ((KERN_DEBUG "/%s/etc is there\n", UMSDOS_PSDROOT_NAME));
@@ -617,9 +639,9 @@
init = creat_dentry ("init", 4, NULL, etc);
etc_rc = creat_dentry ("rc", 2, NULL, etc);
- if ((umsdos_real_lookup (pseudo, init) == 0
+ if ((msdos_lookup (pseudo, init) == 0
&& S_ISREG (init->d_inode->i_mode))
- || (umsdos_real_lookup (pseudo, etc_rc) == 0
+ || (msdos_lookup (pseudo, etc_rc) == 0
&& S_ISREG (etc_rc->d_inode->i_mode))) {
pseudo_ok = 1;
}
@@ -629,12 +651,12 @@
/* iput(rc); */
}
if (!pseudo_ok
- /* && umsdos_real_lookup (pseudo, "sbin", 4, sbin)==0 */
- && umsdos_real_lookup (pseudo, sbin) == 0
+ /* && msdos_lookup (pseudo, "sbin", 4, sbin)==0 */
+ && msdos_lookup (pseudo, sbin) == 0
&& S_ISDIR (sbin->d_inode->i_mode)) {
Printk ((KERN_DEBUG "/%s/sbin is there\n", UMSDOS_PSDROOT_NAME));
- if (umsdos_real_lookup (pseudo, init) == 0
+ if (msdos_lookup (pseudo, init) == 0
&& S_ISREG (init->d_inode->i_mode)) {
pseudo_ok = 1;
}
FUNET's LINUX-ADM group, linux-adm@nic.funet.fi
TCL-scripts by Sam Shen, slshen@lbl.gov