* - ioctl's
*/
+
/*
* OST requests: OBDO & OBD request records
*/
#define MDS_TYPE_ERR 3
#define MDS_GETATTR 1
-#define MDS_SETATTR 2
+#define MDS_REINT 2
#define MDS_READPAGE 3
-#define MDS_CREATE 4
-#define MDS_LINK 5
-#define MDS_SYMLINK 6
-#define MDS_MKNOD 7
-#define MDS_MKDIR 8
-#define MDS_UNLINK 9
-#define MDS_RMDIR 10
-#define MDS_RENAME 11
+
+#define REINT_SETATTR 1
struct mds_req_hdr {
__u32 opc;
__u32 type;
};
-struct lustre_fid {
+struct ll_fid {
__u64 id;
__u32 generation;
__u32 f_type;
};
struct mds_req_packed {
- struct lustre_fid fid1;
- struct lustre_fid fid2;
+ struct ll_fid fid1;
+ struct ll_fid fid2;
int namelen;
int tgtlen;
+ __u32 opcode;
__u32 valid;
__u32 mode;
__u32 uid;
__u32 ino;
__u32 nlink;
__u32 generation;
- __u32 name_offset;
- __u32 tgt_offset;
};
struct mds_rep_packed {
- struct lustre_fid fid1;
- struct lustre_fid fid2;
+ struct ll_fid fid1;
+ struct ll_fid fid2;
int namelen;
int tgtlen;
__u32 valid;
__u32 ino;
__u32 nlink;
__u32 generation;
- __u32 name_offset;
- __u32 tgt_offset;
};
+
+struct mds_rec_setattr {
+ __u32 sa_len;
+ __u32 sa_opcode;
+ struct ll_fid sa_fid;
+ __u32 sa_valid;
+ __u32 sa_mode;
+ __u32 sa_uid;
+ __u32 sa_gid;
+ __u64 sa_size;
+ __u64 sa_atime;
+ __u64 sa_mtime;
+ __u64 sa_ctime;
+ __u32 sa_attr_flags;
+};
+
+#ifdef __KERNEL__
+
+static inline void ll_ino2fid(struct ll_fid *fid, ino_t ino, __u32 generation, int type)
+{
+ fid->id = HTON__u64((__u64)ino);
+ fid->generation = HTON__u32(generation);
+ fid->f_type = HTON__u32(type);
+}
+
+static inline void ll_inode2fid(struct ll_fid *fid, struct inode *inode)
+{
+ fid->id = HTON__u64((__u64)inode->i_ino);
+ fid->generation = HTON__u32(inode->i_generation);
+ fid->f_type = HTON__u32(inode->i_mode & S_IFMT);
+}
+
+#endif
+
/*
* OBD IOCTLS
*/
/* more or less identical to the packed structure, except for the pointers */
struct mds_req {
- struct lustre_fid fid1;
- struct lustre_fid fid2;
+ struct ll_fid fid1;
+ struct ll_fid fid2;
int namelen;
int tgtlen;
+ __u32 opcode;
__u32 valid;
__u32 mode;
__u32 uid;
__u32 ino;
__u32 nlink;
__u32 generation;
- char *name;
- char *tgt;
};
/* more or less identical to the packed structure, except for the pointers */
struct mds_rep {
- struct lustre_fid fid1;
- struct lustre_fid fid2;
+ struct ll_fid fid1;
+ struct ll_fid fid2;
int namelen;
int tgtlen;
__u32 valid;
__u32 ino;
__u32 nlink;
__u32 generation;
- char *name;
- char *tgt;
};
/* mds/mds_pack.c */
+void *mds_req_tgt(struct mds_req *req);
int mds_pack_req(char *name, int namelen, char *tgt, int tgtlen, struct mds_req_hdr **hdr, struct mds_req **req, int *len, char **buf);
int mds_unpack_req(char *buf, int len, struct mds_req_hdr **hdr, struct mds_req **req);
int mds_pack_rep(char *name, int namelen, char *tgt, int tgtlen, struct mds_rep_hdr **hdr, struct mds_rep **rep, int *len, char **buf);
int mds_unpack_rep(char *buf, int len, struct mds_rep_hdr **hdr, struct mds_rep **rep);
+/* mds/mds_reint.c */
+int mds_reint_setattr(struct mds_request *req);
+
+/* lib/mds_updates.c */
+void mds_setattr_unpack(struct mds_rec_setattr *rec, struct iattr *attr);
+void mds_setattr_pack(struct mds_rec_setattr *rec, struct inode *inode, struct iattr *iattr);
+
+/* mds/handler.c */
+struct dentry *mds_fid2dentry(struct mds_obd *mds, struct ll_fid *fid, struct vfsmount **mnt);
+
/* llight/request.c */
int mdc_getattr(ino_t ino, int type, int valid,
struct mds_rep **mds_reply, struct mds_rep_hdr **hdr);
+int mdc_setattr(struct inode *inode, struct iattr *iattr,
+ struct mds_rep **mds_reply, struct mds_rep_hdr **hdr);
int mdc_readpage(ino_t ino, int type, __u64 offset, char *addr,
struct mds_rep **rep, struct mds_rep_hdr **hdr);
#define IOC_REQUEST_GETATTR _IOWR('f', 30, long)
#define IOC_REQUEST_READPAGE _IOWR('f', 31, long)
-#define IOC_REQUEST_MAX_NR 31
+#define IOC_REQUEST_SETATTR _IOWR('f', 32, long)
+#define IOC_REQUEST_MAX_NR 32
#endif
(*req)->namelen = NTOH__u32(namelen);
if (name) {
- preq->name_offset = (__u32)(ptr - (char *)preq);
LOGL(name, namelen, ptr);
}
(*req)->tgtlen = NTOH__u32(tgtlen);
if (tgt) {
- preq->tgt_offset = (__u32)(ptr - (char *)preq);
LOGL(tgt, tgtlen, ptr);
}
return 0;
struct mds_req_hdr **hdr, struct mds_req **req)
{
struct mds_req_packed *preq;
- __u32 off1, off2;
char *name, *tgt;
if (len < sizeof(**hdr) + sizeof(**req)) {
*hdr = (struct mds_req_hdr *) (buf);
preq = (struct mds_req_packed *) (buf + sizeof(**hdr));
- off1 = preq->name_offset;
- off2 = preq->tgt_offset;
*req = (struct mds_req *) (buf + sizeof(**hdr));
(*req)->namelen = NTOH__u32((*req)->namelen);
}
if ((*req)->namelen) {
- name = buf + sizeof(**hdr) + off1;
+ name = buf + sizeof(**hdr) + sizeof(*preq);
} else {
name = NULL;
}
if ((*req)->tgtlen) {
- tgt = buf + sizeof(**hdr) + off2;
+ tgt = buf + sizeof(**hdr) + sizeof(*preq) +
+ size_round((*req)->namelen);
} else {
tgt = NULL;
}
- (*req)->name = name;
- (*req)->tgt = tgt;
EXIT;
return 0;
}
+void *mds_req_tgt(struct mds_req *req)
+{
+ if (!req->tgtlen)
+ return NULL;
+ return (void *)((char *)req + sizeof(*req) + size_round(req->namelen));
+}
+
int mds_pack_rep(char *name, int namelen, char *tgt, int tgtlen,
struct mds_rep_hdr **hdr, struct mds_rep **rep,
int *len, char **buf)
(*rep)->namelen = NTOH__u32(namelen);
if (name) {
- prep->name_offset = (__u32)(ptr - (char *)prep);
LOGL(name, namelen, ptr);
}
- (*rep)->tgtlen = NTOH__u32(tgtlen);
+ (*rep)->tgtlen = NTOH__u32(tgtlen);
if (tgt) {
- prep->tgt_offset = (__u32)(ptr - (char *)prep);
LOGL(tgt, tgtlen, ptr);
}
return 0;
struct mds_rep_hdr **hdr, struct mds_rep **rep)
{
struct mds_rep_packed *prep;
- __u32 off1, off2;
+
+ if (len < sizeof(**hdr)) {
+ EXIT;
+ return -EINVAL;
+ }
+ *hdr = (struct mds_rep_hdr *) (buf);
if (len < sizeof(**hdr) + sizeof(**rep)) {
EXIT;
return -EINVAL;
}
- *hdr = (struct mds_rep_hdr *) (buf);
prep = (struct mds_rep_packed *) (buf + sizeof(**hdr));
- off1 = prep->name_offset;
- off2 = prep->tgt_offset;
*rep = (struct mds_rep *) (buf + sizeof(**hdr));
(*rep)->namelen = NTOH__u32((*rep)->namelen);
return -EINVAL;
}
- if ((*rep)->namelen) {
- (*rep)->name = buf + sizeof(**hdr) + off1;
- } else {
- (*rep)->name = NULL;
- }
-
- if ((*rep)->tgtlen) {
- (*rep)->tgt = buf + sizeof(**hdr) + off2;
- } else {
- (*rep)->tgt = NULL;
- }
-
-
EXIT;
return 0;
}
+void *mds_rep_tgt(struct mds_rep *rep)
+{
+ if (!rep->tgtlen)
+ return NULL;
+ return (void *)((char *)rep + sizeof(*rep) + size_round(rep->namelen));
+}
+
#if 0
int mds_pack_rep(char *name, int namelen, char *tgt, int tgtlen,
struct mds_rep_hdr **hdr, struct mds_rep **rep,
err = ext2_commit_chunk(page, from, to);
// change_inode happens with the commit_chunk
- // ll_change_inode(dir);
- /* OFFSET_CACHE */
+ /* XXX OFFSET_CACHE */
+
out_unlock:
UnlockPage(page);
out_page:
#include <linux/lustre_light.h>
extern int ll_setattr(struct dentry *de, struct iattr *attr);
-void ll_change_inode(struct inode *inode);
static inline void ll_remove_suid(struct inode *inode)
{
if (mode && !capable(CAP_FSETID)) {
inode->i_mode &= ~mode;
// XXX careful here - we cannot change the size
- //ll_change_inode(inode);
}
}
static inline void ext2_inc_count(struct inode *inode)
{
inode->i_nlink++;
- ll_change_inode(inode);
}
/* postpone the disk update until the inode really goes away */
static inline void ext2_dec_count(struct inode *inode)
{
inode->i_nlink--;
- if (inode->i_nlink > 0)
- ll_change_inode(inode);
}
static inline int ext2_add_nondir(struct dentry *dentry, struct inode *inode)
int err = PTR_ERR(inode);
if (!IS_ERR(inode)) {
init_special_inode(inode, mode, rdev);
- ll_change_inode(inode);
err = ext2_add_nondir(dentry, inode);
}
return err;
memcpy(oinfo->lli_inline, symname, l);
inode->i_size = l-1;
}
- ll_change_inode(inode);
err = ext2_add_nondir(dentry, inode);
out:
/*
- * OBDFS Super operations
+ * Lustre Light I/O Page Cache
*
- * This code is issued under the GNU General Public License.
- * See the file COPYING in this distribution
- *
- * Copyright (C) 1996, 1997, Olaf Kirch <okir@monad.swb.de>
- * Copryright (C) 1999 Stelias Computing Inc,
- * (author Peter J. Braam <braam@stelias.com>)
- * Copryright (C) 1999 Seagate Technology Inc.
+ * Copyright (C) 2002, Cluster File Systems, Inc.
*/
#include <linux/lustre_mds.h>
#include <linux/lustre_light.h>
-void ll_change_inode(struct inode *inode);
-
-static int cache_writes = 0;
-
-
-/* page cache support stuff */
-
-
/*
* Add a page to the dirty page list.
*/
}
-
-
-
-
-static kmem_cache_t *ll_pgrq_cachep = NULL;
-
-int ll_init_pgrqcache(void)
-{
- ENTRY;
- if (ll_pgrq_cachep == NULL) {
- CDEBUG(D_CACHE, "allocating ll_pgrq_cache\n");
- ll_pgrq_cachep = kmem_cache_create("ll_pgrq",
- sizeof(struct ll_pgrq),
- 0, SLAB_HWCACHE_ALIGN,
- NULL, NULL);
- if (ll_pgrq_cachep == NULL) {
- EXIT;
- return -ENOMEM;
- } else {
- CDEBUG(D_CACHE, "allocated cache at %p\n",
- ll_pgrq_cachep);
- }
- } else {
- CDEBUG(D_CACHE, "using existing cache at %p\n",
- ll_pgrq_cachep);
- }
- EXIT;
- return 0;
-} /* ll_init_wreqcache */
-
-inline void ll_pgrq_del(struct ll_pgrq *pgrq)
-{
- --ll_cache_count;
- CDEBUG(D_INFO, "deleting page %p from list [count %ld]\n",
- pgrq->rq_page, ll_cache_count);
- list_del(&pgrq->rq_plist);
- OBDClearCachePage(pgrq->rq_page);
- kmem_cache_free(ll_pgrq_cachep, pgrq);
-}
-
-void ll_cleanup_pgrqcache(void)
-{
- ENTRY;
- if (ll_pgrq_cachep != NULL) {
- CDEBUG(D_CACHE, "destroying ll_pgrqcache at %p, count %ld\n",
- ll_pgrq_cachep, ll_cache_count);
- if (kmem_cache_destroy(ll_pgrq_cachep))
- printk(KERN_INFO __FUNCTION__
- ": unable to free all of cache\n");
- ll_pgrq_cachep = NULL;
- } else
- printk(KERN_INFO __FUNCTION__ ": called with NULL pointer\n");
-
- EXIT;
-} /* ll_cleanup_wreqcache */
-
-
-/* called with the list lock held */
-static struct page *ll_find_page_index(struct inode *inode,
- unsigned long index)
-{
- struct list_head *page_list = ll_iplist(inode);
- struct list_head *tmp;
- struct page *page;
-
- ENTRY;
-
- CDEBUG(D_INFO, "looking for inode %ld pageindex %ld\n",
- inode->i_ino, index);
- OIDEBUG(inode);
-
- if (list_empty(page_list)) {
- EXIT;
- return NULL;
- }
- tmp = page_list;
- while ( (tmp = tmp->next) != page_list ) {
- struct ll_pgrq *pgrq;
-
- pgrq = list_entry(tmp, struct ll_pgrq, rq_plist);
- page = pgrq->rq_page;
- if (index == page->index) {
- CDEBUG(D_INFO,
- "INDEX SEARCH found page %p, index %ld\n",
- page, index);
- EXIT;
- return page;
- }
- }
-
- EXIT;
- return NULL;
-} /* ll_find_page_index */
-
-
-/* call and free pages from Linux page cache: called with io lock on inodes */
-int ll_do_vec_wr(struct inode **inodes, obd_count num_io,
- obd_count num_obdos, struct obdo **obdos,
- obd_count *oa_bufs, struct page **pages, char **bufs,
- obd_size *counts, obd_off *offsets, obd_flag *flags)
-{
- int err;
-
- ENTRY;
-
- CDEBUG(D_INFO, "writing %d page(s), %d obdo(s) in vector\n",
- num_io, num_obdos);
- if (obd_debug_level & D_INFO) { /* DEBUGGING */
- int i;
- printk("OBDOS: ");
- for (i = 0; i < num_obdos; i++)
- printk("%ld:0x%p ", (long)obdos[i]->o_id, obdos[i]);
-
- printk("\nPAGES: ");
- for (i = 0; i < num_io; i++)
- printk("0x%p ", pages[i]);
- printk("\n");
- }
-
- err = obd_brw(WRITE, IID(inodes[0]), num_obdos, obdos,
- oa_bufs, pages, counts, offsets, flags);
-
- CDEBUG(D_INFO, "BRW done\n");
- /* release the pages from the page cache */
- while ( num_io > 0 ) {
- --num_io;
- CDEBUG(D_INFO, "calling put_page for %p, index %ld\n",
- pages[num_io], pages[num_io]->index);
- /* PDEBUG(pages[num_io], "do_vec_wr"); */
- put_page(pages[num_io]);
- /* PDEBUG(pages[num_io], "do_vec_wr"); */
- }
- CDEBUG(D_INFO, "put_page done\n");
-
- while ( num_obdos > 0) {
- --num_obdos;
- CDEBUG(D_INFO, "free obdo %ld\n",(long)obdos[num_obdos]->o_id);
- /* copy o_blocks to i_blocks */
- ll_set_size (inodes[num_obdos], obdos[num_obdos]->o_size);
- //ll_to_inode(inodes[num_obdos], obdos[num_obdos]);
- obdo_free(obdos[num_obdos]);
- }
- CDEBUG(D_INFO, "obdo_free done\n");
- EXIT;
- return err;
-}
-
-
-/*
- * Add a page to the write request cache list for later writing.
- * ASYNCHRONOUS write method.
- */
-static int ll_add_page_to_cache(struct inode *inode, struct page *page)
-{
- int err = 0;
- ENTRY;
-
- /* The PG_obdcache bit is cleared by ll_pgrq_del() BEFORE the page
- * is written, so at worst we will write the page out twice.
- *
- * If the page has the PG_obdcache bit set, then the inode MUST be
- * on the superblock dirty list so we don't need to check this.
- * Dirty inodes are removed from the superblock list ONLY when they
- * don't have any more cached pages. It is possible to have an inode
- * with no dirty pages on the superblock list, but not possible to
- * have an inode with dirty pages NOT on the superblock dirty list.
- */
- if (!OBDAddCachePage(page)) {
- struct ll_pgrq *pgrq;
- pgrq = kmem_cache_alloc(ll_pgrq_cachep, SLAB_KERNEL);
- if (!pgrq) {
- OBDClearCachePage(page);
- EXIT;
- return -ENOMEM;
- }
- /* not really necessary since we set all pgrq fields here
- memset(pgrq, 0, sizeof(*pgrq));
- */
-
- pgrq->rq_page = page;
- pgrq->rq_jiffies = jiffies;
- get_page(pgrq->rq_page);
-
- obd_down(&ll_i2sbi(inode)->ll_list_mutex);
- list_add(&pgrq->rq_plist, ll_iplist(inode));
- ll_cache_count++;
- //printk("-- count %d\n", ll_cache_count);
-
- /* If inode isn't already on superblock inodes list, add it.
- *
- * We increment the reference count on the inode to keep it
- * from being freed from memory. This _should_ be an iget()
- * with an iput() in both flush_reqs() and put_inode(), but
- * since put_inode() is called from iput() we can't call iput()
- * again there. Instead we just increment/decrement i_count,
- * which is mostly what iget/iput do for an inode in memory.
- */
- if ( list_empty(ll_islist(inode)) ) {
- atomic_inc(&inode->i_count);
- CDEBUG(D_INFO,
- "adding inode %ld to superblock list %p\n",
- inode->i_ino, ll_slist(inode));
- list_add(ll_islist(inode), ll_slist(inode));
- }
- obd_up(&ll_i2sbi(inode)->ll_list_mutex);
-
- }
-
- /* XXX For testing purposes, we can write out the page here.
- err = ll_flush_reqs(ll_slist(inode), ~0UL);
- */
-
- EXIT;
- return err;
-} /* ll_add_page_to_cache */
-
-void rebalance(void)
-{
- if (ll_cache_count > 60000) {
- printk("-- count %ld\n", ll_cache_count);
- //ll_flush_dirty_pages(~0UL);
- printk("-- count %ld\n", ll_cache_count);
- }
-}
-
/* select between SYNC and ASYNC I/O methods */
int ll_do_writepage(struct page *page, int sync)
{
ENTRY;
/* PDEBUG(page, "WRITEPAGE"); */
- if ( sync )
- err = ll_brw(WRITE, inode, page, 1);
- else {
- err = ll_add_page_to_cache(inode, page);
- CDEBUG(D_INFO, "DO_WR ino: %ld, page %p, err %d, uptodate %d\n",
- inode->i_ino, page, err, Page_Uptodate(page));
- }
-
+ /* XXX everything is synchronous now */
+ err = ll_brw(WRITE, inode, page, 1);
+
if ( !err ) {
SetPageUptodate(page);
set_page_clean(page);
CDEBUG(D_INODE, "commit write ino %ld (end at %Ld) from %d to %d ,ind %ld\n",
inode->i_ino, len, from, to, page->index);
-
- if (cache_writes == 0) {
- rc = ll_commit_page(page, 1, from, to);
- }
+ rc = ll_commit_page(page, 1, from, to);
if (len > inode->i_size) {
ll_set_size(inode, len);
return page;
}
-
-#ifdef EXT2_OBD_DEBUG
- if ((obd_debug_level & D_INFO) && ll_find_page_index(inode, index)) {
- CDEBUG(D_INFO, "OVERWRITE: found dirty page %p, index %ld\n",
- page, page->index);
- }
-#endif
-
err = ll_brw(READ, inode, page, create);
if ( err ) {
{
struct inode *root = 0;
struct ll_sb_info *sbi = (struct ll_sb_info *)(&sb->u.generic_sbp);
- struct obd_device *obddev;
char *device = NULL;
char *version = NULL;
- int root_ino = 2;
int connected = 0;
int devno;
int err;
struct mds_rep *rep;
struct mds_rep_hdr *hdr = NULL;
-
ENTRY;
MOD_INC_USE_COUNT;
+
memset(sbi, 0, sizeof(*sbi));
-
- CDEBUG(D_INFO, "\n");
+
ll_options(data, &device, &version);
if ( !device ) {
printk(__FUNCTION__ ": no device\n");
- EXIT;
+ sb = NULL;
goto ERR;
}
devno = simple_strtoul(device, NULL, 0);
- CDEBUG(D_INFO, "\n");
if ( devno >= MAX_OBD_DEVICES ) {
- printk(__FUNCTION__ ": device of %s too high (%d)\n", device, devno);
- EXIT;
+ printk(__FUNCTION__ ": device of %s too high\n", device);
+ sb = NULL;
goto ERR;
}
- CDEBUG(D_INFO, "\n");
-
- obddev = &obd_dev[devno];
- sbi->ll_conn.oc_dev = obddev;
- CDEBUG(D_INFO, "\n");
-
+ sbi->ll_conn.oc_dev = &obd_dev[devno];
err = obd_connect(&sbi->ll_conn);
- CDEBUG(D_INFO, "\n");
if ( err ) {
- printk("OBDFS: cannot connect to %s\n", device);
- EXIT;
+ printk(__FUNCTION__ "cannot connect to %s\n", device);
+ sb = NULL;
goto ERR;
}
connected = 1;
- /* list of dirty inodes, and a mutex to hold while modifying it */
- INIT_LIST_HEAD(&sbi->ll_inodes);
- init_MUTEX (&sbi->ll_list_mutex);
-
sbi->ll_super = sb;
sbi->ll_rootino = 2;
sb->s_maxbytes = 1LL << 36;
- printk("Max bytes: %Lx\n", sb->s_maxbytes);
sb->s_blocksize = PAGE_SIZE;
sb->s_blocksize_bits = (unsigned char)PAGE_SHIFT;
sb->s_magic = LL_SUPER_MAGIC;
sb->s_op = &ll_super_operations;
/* make root inode */
- err = mdc_getattr(root_ino, S_IFDIR, OBD_MD_FLNOTOBD|OBD_MD_FLBLOCKS,
- &rep, &hdr);
+ err = mdc_getattr(sbi->ll_rootino, S_IFDIR,
+ OBD_MD_FLNOTOBD|OBD_MD_FLBLOCKS,
+ &rep, &hdr);
if (err) {
- printk(__FUNCTION__ ": mds_getattr failed %d\n", err);
- if (rep)
- kfree(rep);
- EXIT;
+ printk(__FUNCTION__ ": mds_getattr failed for root %d\n", err);
+ sb = NULL;
goto ERR;
}
- root = iget4(sb, root_ino, NULL, rep);
- kfree(hdr);
- if (!root) {
+ root = iget4(sb, sbi->ll_rootino, NULL, rep);
+ if (root) {
+ sb->s_root = d_alloc_root(root);
+ } else {
printk("lustre_light: bad iget4 for root\n");
- sb->s_dev = 0;
- err = -ENOENT;
- EXIT;
+ sb = NULL;
goto ERR;
}
- sb->s_root = d_alloc_root(root);
- OBD_FREE(device, strlen(device) + 1);
- if (version)
- OBD_FREE(version, strlen(version) + 1);
- EXIT;
- return sb;
-
ERR:
- MOD_DEC_USE_COUNT;
+ if (hdr)
+ kfree(hdr);
if (device)
OBD_FREE(device, strlen(device) + 1);
if (version)
OBD_FREE(version, strlen(version) + 1);
- if (connected)
+ if (!sb && connected)
obd_disconnect(&sbi->ll_conn);
- if (sbi) {
- sbi->ll_super = NULL;
- }
- if (root) {
+ if (!sb && root) {
iput(root);
}
- sb->s_dev = 0;
- return NULL;
-} /* ll_read_super */
+ if (!sb)
+ MOD_DEC_USE_COUNT;
+ EXIT;
+ return sb;
+} /* ll_read_super */
static void ll_put_super(struct super_block *sb)
{
- struct ll_sb_info *sbi;
-
ENTRY;
- sb->s_dev = 0;
-
- sbi = (struct ll_sb_info *) &sb->u.generic_sbp;
+
obd_disconnect(ID(sb));
-
- printk(KERN_INFO "OBDFS: Bye bye.\n");
MOD_DEC_USE_COUNT;
EXIT;
} /* ll_put_super */
-void ll_do_change_inode(struct inode *inode, int valid)
-{
- struct obdo *oa;
- int err;
-
- ENTRY;
-
- oa = obdo_alloc();
- if ( !oa ) {
- printk(__FUNCTION__ ": obdo_alloc failed\n");
- EXIT;
- return;
- }
-
- oa->o_valid = OBD_MD_FLNOTOBD & (valid | OBD_MD_FLID);
- ll_from_inode(oa, inode);
- oa->o_mode = inode->i_mode;
- err = obd_setattr(IID(inode), oa);
-
- if ( err )
- printk(__FUNCTION__ ": obd_setattr fails (%d)\n", err);
-
- EXIT;
- obdo_free(oa);
-} /* ll_write_inode */
-
-void ll_change_inode(struct inode *inode, int mask)
-{
- return ll_do_change_inode(inode, OBD_MD_FLNLINK);
-}
-
extern void write_inode_pages(struct inode *);
/* This routine is called from iput() (for each unlink on the inode).
EXIT;
} /* ll_put_inode */
-
-static void ll_delete_inode(struct inode *inode)
-{
- ll_do_change_inode(inode, ~0);
- clear_inode(inode);
-}
-#if 0
-{
- struct obdo *oa;
- int err;
-
- ENTRY;
- if (IOPS(inode, destroy) == NULL) {
- printk(KERN_ERR __FUNCTION__ ": no destroy method!\n");
- EXIT;
- return;
- }
-
- oa = obdo_alloc();
- if ( !oa ) {
- printk(__FUNCTION__ ": obdo_alloc failed\n");
- EXIT;
- return;
- }
- oa->o_valid = OBD_MD_FLNOTOBD;
- ll_from_inode(oa, inode);
-
- /* XXX how do we know that this inode is now clean? */
- printk("delete_inode ------> link %d\n", inode->i_nlink);
- ODEBUG(oa);
- err = IOPS(inode, destroy)(IID(inode), oa);
- obdo_free(oa);
- clear_inode(inode);
- if (err) {
- printk(__FUNCTION__ ": obd_destroy fails (%d)\n", err);
- EXIT;
- return;
- }
-
- EXIT;
-} /* ll_delete_inode */
-#endif
-
-
+/* like inode_setattr, but doesn't mark the inode dirty */
static int ll_attr2inode(struct inode * inode, struct iattr * attr)
{
unsigned int ia_valid = attr->ia_valid;
if (error)
goto out;
}
-
if (ia_valid & ATTR_UID)
inode->i_uid = attr->ia_uid;
if (ia_valid & ATTR_GID)
int ll_setattr(struct dentry *de, struct iattr *attr)
{
struct inode *inode = de->d_inode;
- struct obdo *oa;
- int err;
+ struct mds_rep_hdr *hdr = NULL;
+ int err;
ENTRY;
- oa = obdo_alloc();
- if ( !oa ) {
- printk(__FUNCTION__ ": obdo_alloc failed\n");
- return -ENOMEM;
- }
-
+ /* change incore inode */
ll_attr2inode(inode, attr);
- oa->o_id = inode->i_ino;
- oa->o_mode = inode->i_mode;
- obdo_from_iattr(oa, attr);
- err = obd_setattr(IID(inode), oa);
+ err = mdc_setattr(inode, attr, NULL, &hdr);
if ( err )
- printk(__FUNCTION__ ": obd_setattr fails (%d)\n", err);
+ printk(__FUNCTION__ ": ll_setattr fails (%d)\n", err);
EXIT;
- obdo_free(oa);
return err;
} /* ll_setattr */
EXTRA_PROGRAMS = mdc
-mdc_SOURCES = mds_pack.c mdc_request.c
+mdc_SOURCES = mds_pack.c mdc_request.c mdc_reint.c mds_updates.c
mds_pack.c:
ln -s ../lib/mds_pack.c .
+mds_updates.c:
+ ln -s ../lib/mds_updates.c .
include $(top_srcdir)/Rules
extern int mds_queue_req(struct mds_request *);
-struct mds_request *mds_prep_req(int size, int opcode, int namelen, char *name, int tgtlen, char *tgt)
+struct mds_request *mds_prep_req(int opcode, int namelen, char *name, int tgtlen, char *tgt)
{
struct mds_request *request;
int rc;
printk("llight request: cannot pack request %d\n", rc);
return NULL;
}
+ printk("--> mds_prep_req: len %d, req %p, tgtlen %d\n",
+ request->rq_reqlen, request->rq_req,
+ request->rq_req->tgtlen);
request->rq_reqhdr->opc = opcode;
EXIT;
mds_unpack_rep(req->rq_repbuf, req->rq_replen, &req->rq_rephdr,
&req->rq_rep);
- printk("-->mdc_queue_wait: buf %p len %d status %d\n",
- req->rq_repbuf, req->rq_replen, req->rq_rephdr->status);
+ if ( req->rq_rephdr->status == 0 )
+ printk("-->mdc_queue_wait: buf %p len %d status %d\n",
+ req->rq_repbuf, req->rq_replen,
+ req->rq_rephdr->status);
EXIT;
return req->rq_rephdr->status;
struct mds_request *request;
int rc;
- request = mds_prep_req(sizeof(*request), MDS_GETATTR,
- 0, NULL, 0, NULL);
+ request = mds_prep_req(MDS_GETATTR, 0, NULL, 0, NULL);
if (!request) {
printk("llight request: cannot pack\n");
return -ENOMEM;
}
- request->rq_req->fid1.id = ino;
- request->rq_req->fid1.f_type = type;
+ ll_ino2fid(&request->rq_req->fid1, ino, 0, type);
+
request->rq_req->valid = valid;
rc = mds_queue_wait(request);
printk("mdc_readpage: inode: %ld\n", ino);
- request = mds_prep_req(sizeof(*request), MDS_READPAGE,
- 0, NULL,
+ request = mds_prep_req(MDS_READPAGE, 0, NULL,
sizeof(struct niobuf), (char *)&niobuf);
if (!request) {
printk("mdc request: cannot pack\n");
return rc;
}
+int mdc_reint(struct mds_request *request)
+{
+ int rc;
+
+ rc = mds_queue_wait(request);
+ if (rc) {
+ printk("mdc request: error in handling %d\n", rc);
+ }
+
+ return rc;
+}
+
static int request_ioctl(struct inode *inode, struct file *file,
unsigned int cmd, unsigned long arg)
switch (cmd) {
case IOC_REQUEST_GETATTR: {
- struct mds_rep_hdr *hdr;
+ struct mds_rep_hdr *hdr = NULL;
printk("-- getting attr for ino 2\n");
err = mdc_getattr(2, S_IFDIR, ~0, NULL, &hdr);
- kfree(hdr);
+ if (hdr)
+ kfree(hdr);
printk("-- done err %d\n", err);
break;
}
case IOC_REQUEST_READPAGE: {
- struct mds_rep_hdr *hdr;
+ struct mds_rep_hdr *hdr = NULL;
char *buf;
buf = kmalloc(PAGE_SIZE, GFP_KERNEL);
if (!buf) {
if (!err) {
printk("-- status: %d\n", hdr->status);
err = hdr->status;
- kfree(hdr);
+ if (hdr)
+ kfree(hdr);
}
kfree(buf);
break;
}
+
+ case IOC_REQUEST_SETATTR: {
+ struct inode inode;
+ struct mds_rep_hdr *hdr;
+ struct iattr iattr;
+
+ inode.i_ino = 2;
+ iattr.ia_mode = 040777;
+ iattr.ia_atime = 0;
+ iattr.ia_valid = ATTR_MODE | ATTR_ATIME;
+
+ err = mdc_setattr(&inode, &iattr, NULL, &hdr);
+ printk("-- done err %d\n", err);
+ if (!err) {
+ printk("-- status: %d\n", hdr->status);
+ err = hdr->status;
+ }
+ kfree(hdr);
+ break;
+ }
+
default:
err = -EINVAL;
EXIT;
EXPORT_SYMBOL(mdc_getattr);
EXPORT_SYMBOL(mdc_readpage);
+EXPORT_SYMBOL(mdc_setattr);
module_init(mds_request_init);
module_exit(mds_request_exit);
mds_pack.c:
ln -s ../lib/mds_pack.c .
+mds_updates.c:
+ ln -s ../lib/mds_updates.c .
-mds_SOURCES = mds_pack.c handler.c
+mds_SOURCES = mds_pack.c handler.c mds_reint.c mds_updates.c
include $(top_srcdir)/Rules
return mds_reply(req);
}
-static struct dentry *mds_fid2dentry(struct mds_obd *mds, struct lustre_fid *fid, struct vfsmount **mnt)
+struct dentry *mds_fid2dentry(struct mds_obd *mds, struct ll_fid *fid, struct vfsmount **mnt)
{
/* iget isn't really right if the inode is currently unallocated!!
*/
struct super_block *sb = mds->mds_sb;
unsigned long ino = fid->id;
- __u32 generation = fid->generation;
+ //__u32 generation = fid->generation;
+ __u32 generation = 0;
struct inode *inode;
struct list_head *lp;
struct dentry *result;
return 0;
}
- niobuf = (struct niobuf *)req->rq_req->tgt;
+ niobuf = mds_req_tgt(req->rq_req);
/* to make this asynchronous make sure that the handling function
doesn't send a reply when this function completes. Instead a
return 0;
}
+int mds_reint(struct mds_request *req)
+{
+ int opc = NTOH__u32(req->rq_req->opcode);
+
+ switch (opc) {
+ case REINT_SETATTR:
+ return mds_reint_setattr(req);
+ default:
+ printk(__FUNCTION__ "opcode %d not handled.\n", opc);
+ return -EINVAL;
+ }
+ return 0;
+}
//int mds_handle(struct mds_conn *conn, int len, char *buf)
int mds_handle(struct mds_request *req)
rc = mds_readpage(req);
break;
- case MDS_SETATTR:
- return mds_getattr(req);
-
- case MDS_CREATE:
- return mds_getattr(req);
-
- case MDS_MKDIR:
- return mds_getattr(req);
-
- case MDS_RMDIR:
- return mds_getattr(req);
-
- case MDS_SYMLINK:
- return mds_getattr(req);
-
- case MDS_LINK:
- return mds_getattr(req);
-
- case MDS_MKNOD:
- return mds_getattr(req);
-
- case MDS_UNLINK:
- return mds_getattr(req);
-
- case MDS_RENAME:
- return mds_getattr(req);
+ case MDS_REINT:
+ CDEBUG(D_INODE, "reint\n");
+ rc = mds_reint(req);
+ break;
default:
return mds_error(req);
#include <fcntl.h>
#include <errno.h>
#include <string.h>
+
#define IOC_REQUEST_GETATTR _IOWR('f', 30, long)
#define IOC_REQUEST_READPAGE _IOWR('f', 31, long)
+#define IOC_REQUEST_SETATTR _IOWR('f', 32, long)
int main(int argc, char **argv)
{
printf("readpage test... ");
rc = ioctl(fd, IOC_REQUEST_READPAGE, NULL);
printf("result: %d\n", rc);
+
+ printf("setattr test... ");
+ rc = ioctl(fd, IOC_REQUEST_SETATTR, NULL);
+ printf("result: %d\n", rc);
return 0;
}