]> git.karo-electronics.de Git - karo-tx-linux.git/blobdiff - fs/afs/dir.c
Merge commit 'v2.6.36-rc1' into HEAD
[karo-tx-linux.git] / fs / afs / dir.c
index b42d5cc1d6d21aace96eaae96fe3aa521822c7c9..0d38c09bd55e10f4eaf5f0e25ef11fa3d9d82919 100644 (file)
@@ -476,6 +476,40 @@ static int afs_do_lookup(struct inode *dir, struct dentry *dentry,
        return 0;
 }
 
+/*
+ * Try to auto mount the mountpoint with pseudo directory, if the autocell
+ * operation is setted.
+ */
+static struct inode *afs_try_auto_mntpt(
+       int ret, struct dentry *dentry, struct inode *dir, struct key *key,
+       struct afs_fid *fid)
+{
+       const char *devname = dentry->d_name.name;
+       struct afs_vnode *vnode = AFS_FS_I(dir);
+       struct inode *inode;
+
+       _enter("%d, %p{%s}, {%x:%u}, %p",
+              ret, dentry, devname, vnode->fid.vid, vnode->fid.vnode, key);
+
+       if (ret != -ENOENT ||
+           !test_bit(AFS_VNODE_AUTOCELL, &vnode->flags))
+               goto out;
+
+       inode = afs_iget_autocell(dir, devname, strlen(devname), key);
+       if (IS_ERR(inode)) {
+               ret = PTR_ERR(inode);
+               goto out;
+       }
+
+       *fid = AFS_FS_I(inode)->fid;
+       _leave("= %p", inode);
+       return inode;
+
+out:
+       _leave("= %d", ret);
+       return ERR_PTR(ret);
+}
+
 /*
  * look up an entry in a directory
  */
@@ -520,6 +554,13 @@ static struct dentry *afs_lookup(struct inode *dir, struct dentry *dentry,
 
        ret = afs_do_lookup(dir, dentry, &fid, key);
        if (ret < 0) {
+               inode = afs_try_auto_mntpt(ret, dentry, dir, key, &fid);
+               if (!IS_ERR(inode)) {
+                       key_put(key);
+                       goto success;
+               }
+
+               ret = PTR_ERR(inode);
                key_put(key);
                if (ret == -ENOENT) {
                        d_add(dentry, NULL);
@@ -539,6 +580,7 @@ static struct dentry *afs_lookup(struct inode *dir, struct dentry *dentry,
                return ERR_CAST(inode);
        }
 
+success:
        dentry->d_op = &afs_fs_dentry_operations;
 
        d_add(dentry, inode);
@@ -696,8 +738,9 @@ static int afs_d_delete(struct dentry *dentry)
                goto zap;
 
        if (dentry->d_inode &&
-           test_bit(AFS_VNODE_DELETED, &AFS_FS_I(dentry->d_inode)->flags))
-                       goto zap;
+           (test_bit(AFS_VNODE_DELETED,   &AFS_FS_I(dentry->d_inode)->flags) ||
+            test_bit(AFS_VNODE_PSEUDODIR, &AFS_FS_I(dentry->d_inode)->flags)))
+               goto zap;
 
        _leave(" = 0 [keep]");
        return 0;