spin_lock(&sbi->ll_gns_lock);
if (sbi->ll_gns_state == LL_GNS_MOUNTING ||
sbi->ll_gns_state == LL_GNS_FINISHED) {
+ /*
+ * check if another control thread is trying to mount some GNS
+ * dentry too. Letting it know that we busy and make
+ * ll_lookup_it() ti restart syscall and try again later.
+ */
spin_unlock(&sbi->ll_gns_lock);
CDEBUG(D_INODE, "GNS is in progress now, throwing "
"-ERESTARTSYS to restart syscall and let "
"it finish.\n");
- RETURN(-ERESTARTSYS);
+ RETURN(-EBUSY);
}
LASSERT(sbi->ll_gns_state == LL_GNS_IDLE);
* mount object name is taken from sbi, where it is set in mount time or
* via /proc/fs... tunable. It may be ".mntinfo" or so.
*/
- dchild = lookup_one_len(sbi->ll_gns_oname, dentry,
- strlen(sbi->ll_gns_oname));
+
+ /*
+ * recursive lookup with trying to mount SUID bit marked directories on
+ * the way is not possible here, as lookup_one_len() does not pass nd to
+ * ->lookup() and this is checked in ll_lookup_it(). So, do not handle
+ * possible -EBUSY here.
+ */
+ dchild = ll_lookup_one_len(sbi->ll_gns_oname, dentry,
+ strlen(sbi->ll_gns_oname));
up(&sbi->ll_gns_sem);
cleanup_phase = 2;
if (IS_ERR(dchild)) {
rc = PTR_ERR(dchild);
-
- if (rc == -ERESTARTSYS) {
- CDEBUG(D_INODE, "possible endless loop is detected "
- "due to mount object is directory marked by "
- "SUID bit.\n");
- GOTO(cleanup, rc = -ELOOP);
- }
-
CERROR("can't find mount object %*s/%*s err = %d.\n",
(int)dentry->d_name.len, dentry->d_name.name,
strlen(sbi->ll_gns_oname), sbi->ll_gns_oname,
((flags & LOOKUP_CONTINUE) || (orig_it & (IT_CHDIR | IT_OPEN))))
{
rc = ll_gns_mount_object(dentry, nd->mnt);
- if (rc == -ERESTARTSYS) {
+ if (rc == -EBUSY) {
/*
* making system to restart syscall as currently GNS is
* in mounting progress.
*/
- GOTO(out, retval = ERR_PTR(rc));
+ GOTO(out, retval = ERR_PTR(-ERESTARTSYS));
+ }
+
+ if (rc) {
+ /*
+ * just reporting about GNS failures, lookup() is
+ * successful, do not stop it.
+ *
+ * GNS failure may be that found object is found in SUID
+ * bit marked dir but it is not regular file and we
+ * should lookup further until we find correct mount
+ * object. This will allow to perform GNS mount is the
+ * following case for instance:
+ *
+ * /mnt/lustre/gns_mount/.mntinfo/.mntinfo/..../.mntinfo
+ * where all ".mntinfo" are dirs and only last one is
+ * reg file.
+ */
+ CDEBUG(D_INODE, "failed to mount %*s, err %d\n",
+ (int)dentry->d_name.len, dentry->d_name.name);
}
}