how to safely not grab a semaphore when you already have it(rename sem)

From: Steve French
Date: Tue May 25 2004 - 14:38:18 EST


How do you safely test and not grab a semaphore (ie if the kernel above
you already has it ...) - without deadlock?

Al Viro correctly noted that walking a tree to build a full path can not
be safely done due to races with rename. Unfortunately for some
filesystems (including cifs), the only obvious way to protect against
this would be to grab the rename sem for the superblock everywhere a
full path is built e.g.

down(&i_sb->s_vfs_rename_sem);

but of course this would deadlock (vfs_rename calls at least 3 path
based operations in a filesystem, all while holding the rename sem - in
particular rename can make two lookup calls and a rename call into a vfs
while holding the sem). At least the lookup/revalidate path in the
filesystem would require a check such as:

if(!we_are_called_from_sys_rename)
down(&i_sb->s_vfs_rename_sem);

build_fullpath_from_dentry(dentry);

if(!we_are_called_from_sys_rename)
up(&_sb->s_vfs_rename_sem);

and there is no need to grab the semaphore in cifs_rename at all (it is
already held by the caller). Unfortuantely I don't know of any way to
tell that we are in lookup/revalidate called from sys_rename other than
trying to grab the rename sem and deadlocking.

Alternatively, is there were a way to do something like:

if(our task is not owner of rename sem) {
down(&i_sb->s_vfs_rename_sem);
build_fullpath_from_dentry(dentry);
up(&_sb->s_vfs_rename_sem);
} else /* our caller had already gotten rename sem */
build_fullpath_from_dentry(dentry);



-
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majordomo@xxxxxxxxxxxxxxx
More majordomo info at http://vger.kernel.org/majordomo-info.html
Please read the FAQ at http://www.tux.org/lkml/