+/*lookup inode in dotsnap inode */
+static int smfs_dotsnap_lookup(struct inode *dir, struct dentry *dentry)
+{
+ if (dentry->d_name.len == 1 &&
+ !strcmp(dentry->d_name.name, ".")) {
+ d_add(dentry, iget(dir->i_sb, dir->i_ino));
+ } else if (dentry->d_name.len == 2 &&
+ !strcmp(dentry->d_name.name, "..")) {
+ struct inode *inode;
+ struct dentry *dparent = dentry->d_parent;
+ if (dparent->d_inode) {
+ inode = iget(dir->i_sb, dparent->d_inode->i_ino);
+ if (inode) {
+ if (!is_bad_inode(inode))
+ d_add(dentry, inode);
+ else
+ iput(inode);
+ }
+ }
+ } else {
+ /*find the name from the snaptable*/
+ struct fsfilt_operations *snapops = I2SNAPOPS(dir);
+ struct snap_table *table = S2SNAPI(dir->i_sb)->sntbl;
+ struct inode *inode;
+ int i = 0, index = -1;
+ for (i = 0; i < table->sntbl_count; i++) {
+ char *name = table->sntbl_items[i].sn_name;
+ if ((dentry->d_name.len == strlen(name)) &&
+ (memcmp(dentry->d_name.name, name,
+ dentry->d_name.len) == 0)) {
+ index = table->sntbl_items[i].sn_index;
+ break;
+ }
+ }
+ if (index != -1) {
+ CERROR("No such %s in this .snap dir \n",
+ dentry->d_name.name);
+ RETURN(-ENOENT);
+ }
+ inode = snapops->fs_get_indirect(dir, NULL, index);
+ d_add(dentry, inode);
+ }
+ RETURN(0);
+}