From 46ee1b3c000ef983d262a6d66d35c48751b3f736 Mon Sep 17 00:00:00 2001 From: adilger Date: Tue, 24 Sep 2002 19:23:31 +0000 Subject: [PATCH] Fix simple_mknod() to handle existing files properly. Specify the file type when creating a file in obdfilter() to allow checking. --- lustre/lib/simple.c | 6 +++--- lustre/obdfilter/filter.c | 47 ++++++++++++++++++++++++++++------------------- 2 files changed, 31 insertions(+), 22 deletions(-) diff --git a/lustre/lib/simple.c b/lustre/lib/simple.c index 9827eea..20f0829 100644 --- a/lustre/lib/simple.c +++ b/lustre/lib/simple.c @@ -92,13 +92,13 @@ struct dentry *simple_mknod(struct dentry *dir, char *name, int mode) GOTO(out, PTR_ERR(dchild)); if (dchild->d_inode) { - if (!S_ISDIR(dchild->d_inode->i_mode)) - GOTO(out, err = -ENOTDIR); + if (((dchild->d_inode->i_mode ^ mode) & S_IFMT) != 0) + GOTO(out, err = -EEXIST); GOTO(out, dchild); } - err = vfs_create(dir->d_inode, dchild, S_IFREG | mode); + err = vfs_create(dir->d_inode, dchild, (mode & S_IFMT) | S_IFREG); EXIT; out: up(&dir->d_inode->i_sem); diff --git a/lustre/obdfilter/filter.c b/lustre/obdfilter/filter.c index 7057a8e..a336649 100644 --- a/lustre/obdfilter/filter.c +++ b/lustre/obdfilter/filter.c @@ -26,6 +26,7 @@ long filter_memory; #define FILTER_ROOTINO 2 +#define FILTER_ROOTINO_STR __stringify(FILTER_ROOTINO) #define S_SHIFT 12 static char *obd_type_by_mode[S_IFMT >> S_SHIFT] = { @@ -64,10 +65,10 @@ static int filter_prep(struct obd_device *obddev) struct obd_run_ctxt saved; struct filter_obd *filter = &obddev->u.filter; struct dentry *dentry; + struct dentry *root; struct file *file; struct inode *inode; int rc = 0; - char rootid[128]; __u64 lastino = 2; int mode = 0; @@ -87,8 +88,6 @@ static int filter_prep(struct obd_device *obddev) CERROR("cannot open/create P: rc = %d\n", rc); GOTO(out_O, rc); } - CDEBUG(D_INODE, "putting P: %p, count = %d\n", dentry, - atomic_read(&dentry->d_count) - 1); f_dput(dentry); dentry = simple_mkdir(current->fs->pwd, "D", 0700); CDEBUG(D_INODE, "got/created D: %p\n", dentry); @@ -97,9 +96,16 @@ static int filter_prep(struct obd_device *obddev) CERROR("cannot open/create D: rc = %d\n", rc); GOTO(out_O, rc); } - CDEBUG(D_INODE, "putting D: %p, count = %d\n", dentry, - atomic_read(&dentry->d_count) - 1); + + root = simple_mknod(dentry, FILTER_ROOTINO_STR, S_IFREG | 0755); f_dput(dentry); + if (IS_ERR(root)) { + rc = PTR_ERR(root); + CERROR("OBD filter: cannot open/create root %d: rc = %d\n", + FILTER_ROOTINO, rc); + GOTO(out_O, rc); + } + f_dput(root); /* * Create directories and/or get dentries for each object type. @@ -122,16 +128,6 @@ static int filter_prep(struct obd_device *obddev) filter->fo_dentry_O_mode[mode] = dentry; } - filter_id(rootid, FILTER_ROOTINO, S_IFDIR); - file = filp_open(rootid, O_RDWR | O_CREAT, 0755); - if (IS_ERR(file)) { - rc = PTR_ERR(file); - CERROR("OBD filter: cannot open/create root %s: rc = %d\n", - rootid, rc); - GOTO(out_O_mode, rc); - } - filp_close(file, 0); - file = filp_open("D/status", O_RDWR | O_CREAT, 0700); if ( !file || IS_ERR(file) ) { rc = PTR_ERR(file); @@ -483,6 +479,7 @@ static int filter_getattr(struct lustre_handle *conn, struct obdo *oa, { struct obd_device *obddev = class_conn2obd(conn); struct dentry *dentry; + int rc = 0; ENTRY; if (!class_conn2export(conn)) { @@ -496,10 +493,16 @@ static int filter_getattr(struct lustre_handle *conn, struct obdo *oa, if (IS_ERR(dentry)) RETURN(PTR_ERR(dentry)); + if (!dentry->d_inode) { + CERROR("getattr on non-existent object: "LPU64"\n", oa->o_id); + GOTO(out_getattr, rc = -ENOENT); + } + filter_from_inode(oa, dentry->d_inode, oa->o_valid); +out_getattr: f_dput(dentry); - RETURN(0); + RETURN(rc); } static int filter_setattr(struct lustre_handle *conn, struct obdo *oa, @@ -548,7 +551,7 @@ out_setattr: } static int filter_open(struct lustre_handle *conn, struct obdo *oa, - struct lov_stripe_md *ea) + struct lov_stripe_md *ea) { struct obd_export *export; struct obd_device *obd; @@ -631,7 +634,8 @@ static int filter_create(struct lustre_handle* conn, struct obdo *oa, sprintf(name, LPU64, oa->o_id); mode = (oa->o_mode & ~S_IFMT) | S_IFREG; push_ctxt(&saved, &obd->u.filter.fo_ctxt); - new = simple_mknod(filter->fo_dentry_O_mode[S_IFREG >> S_SHIFT], name, oa->o_mode); + new = simple_mknod(filter->fo_dentry_O_mode[S_IFREG >> S_SHIFT], name, + mode); pop_ctxt(&saved); if (IS_ERR(new)) { CERROR("Error mknod obj %s, err %ld\n", name, PTR_ERR(new)); @@ -675,7 +679,7 @@ static int filter_destroy(struct lustre_handle *conn, struct obdo *oa, GOTO(out, rc = -ENOENT); inode = object_dentry->d_inode; - if (inode == NULL) { + if (!inode) { CERROR("trying to destroy negative inode "LPX64"!\n", oa->o_id); GOTO(out, rc = -ENOENT); } @@ -687,6 +691,11 @@ static int filter_destroy(struct lustre_handle *conn, struct obdo *oa, } inode->i_mode = S_IFREG; + if (atomic_read(&inode->i_count) > 1) { +#warning FIXME: need to handle open-unlinked case and move to hold dir + CERROR("inode has count %d\n", atomic_read(&inode->i_count)); + } + filter = &obd->u.filter; push_ctxt(&saved, &filter->fo_ctxt); -- 1.8.3.1