locked = 1;
}
- if (locked && vcp->mvstat == 1) { /* mount point */
- if (vcp->mvid && (vcp->f.states & CMValid)) {
- int tryEvalOnly = 0;
- int code = 0;
- struct vrequest *treq = NULL;
-
- code = afs_CreateReq(&treq, credp);
- if (code) {
- dput(parent);
- goto bad_dentry;
- }
- if ((strcmp(dp->d_name.name, ".directory") == 0)) {
- tryEvalOnly = 1;
- }
- if (tryEvalOnly)
- code = afs_TryEvalFakeStat(&vcp, &fakestate, treq);
- else
- code = afs_EvalFakeStat(&vcp, &fakestate, treq);
- afs_DestroyReq(treq);
- if ((tryEvalOnly && vcp->mvstat == 1) || code) {
- /* a mount point, not yet replaced by its directory */
- dput(parent);
- goto bad_dentry;
+ if (locked) {
+ if (vcp->mvstat == 1) { /* mount point */
+ if (vcp->mvid && (vcp->f.states & CMValid)) {
+ int tryEvalOnly = 0;
+ int code = 0;
+ struct vrequest *treq = NULL;
+
+ code = afs_CreateReq(&treq, credp);
+ if (code) {
+ dput(parent);
+ goto bad_dentry;
+ }
+ if ((strcmp(dp->d_name.name, ".directory") == 0)) {
+ tryEvalOnly = 1;
+ }
+ if (tryEvalOnly)
+ code = afs_TryEvalFakeStat(&vcp, &fakestate, treq);
+ else
+ code = afs_EvalFakeStat(&vcp, &fakestate, treq);
+ afs_DestroyReq(treq);
+ if ((tryEvalOnly && vcp->mvstat == 1) || code) {
+ /* a mount point, not yet replaced by its directory */
+ dput(parent);
+ goto bad_dentry;
+ }
}
+ } else if (vcp->mvstat == 2 && *dp->d_name.name != '/') {
+ osi_Assert(vcp->mvid != NULL);
}
}
ip->i_flags |= S_AUTOMOUNT;
#endif
}
+ /*
+ * Take an extra reference so the inode doesn't go away if
+ * d_splice_alias drops our reference on error.
+ */
+ if (ip)
+#ifdef HAVE_LINUX_IHOLD
+ ihold(ip);
+#else
+ igrab(ip);
+#endif
+
newdp = d_splice_alias(ip, dp);
done:
* d_splice_alias can return an error (EIO) if there is an existing
* connected directory alias for this dentry.
*/
- if (!IS_ERR(newdp))
+ if (!IS_ERR(newdp)) {
+ iput(ip);
return newdp;
- else {
+ } else {
d_add(dp, ip);
+ /*
+ * Depending on the kernel version, d_splice_alias may or may
+ * not drop the inode reference on error. If it didn't, do it
+ * here.
+ */
+#if defined(D_SPLICE_ALIAS_LEAK_ON_ERROR)
+ iput(ip);
+#endif
return NULL;
}
- } else
+ } else {
+ if (ip)
+ iput(ip);
return ERR_PTR(afs_convert_code(code));
+ }
}
static int
struct uio tuio;
struct iovec iov;
+ memset(&tuio, 0, sizeof(tuio));
+ memset(&iov, 0, sizeof(iov));
+
setup_uio(&tuio, &iov, target, (afs_offs_t) 0, maxlen, UIO_READ, seg);
code = afs_readlink(VTOAFS(ip), &tuio, credp);
crfree(credp);
struct iovec iovec;
int f_flags = 0;
+ memset(&tuio, 0, sizeof(tuio));
+ memset(&iovec, 0, sizeof(iovec));
+
buffer = kmap(pp) + offset;
base = page_offset(pp) + offset;
if (vattr)
vattr2inode(ip, vattr);
+#ifdef STRUCT_ADDRESS_SPACE_HAS_BACKING_DEV_INFO
ip->i_mapping->backing_dev_info = afs_backing_dev_info;
+#endif
/* Reset ops if symlink or directory. */
if (S_ISREG(ip->i_mode)) {
ip->i_op = &afs_file_iops;