X-Git-Url: http://git.onelab.eu/?a=blobdiff_plain;f=include%2Flinux%2Fvs_cowbl.h;fp=include%2Flinux%2Fvs_cowbl.h;h=b4fff2de38303a472c41fe440f14916f6782852a;hb=76828883507a47dae78837ab5dec5a5b4513c667;hp=0000000000000000000000000000000000000000;hpb=64ba3f394c830ec48a1c31b53dcae312c56f1604;p=linux-2.6.git diff --git a/include/linux/vs_cowbl.h b/include/linux/vs_cowbl.h new file mode 100644 index 000000000..b4fff2de3 --- /dev/null +++ b/include/linux/vs_cowbl.h @@ -0,0 +1,44 @@ +#ifndef _VS_COWBL_H +#define _VS_COWBL_H + +#include +#include +#include + +extern struct dentry *cow_break_link(const char *pathname); + +static inline int cow_check_and_break(struct nameidata *nd) +{ + struct inode *inode = nd->dentry->d_inode; + int error = 0; + if (IS_RDONLY(inode) || MNT_IS_RDONLY(nd->mnt)) + return -EROFS; + if (IS_COW(inode)) { + if (IS_COW_LINK(inode)) { + struct dentry *new_dentry, *old_dentry = nd->dentry; + char *path, *buf; + + buf = kmalloc(PATH_MAX, GFP_KERNEL); + if (!buf) { + return -ENOMEM; + } + path = d_path(nd->dentry, nd->mnt, buf, PATH_MAX); + new_dentry = cow_break_link(path); + kfree(buf); + if (!IS_ERR(new_dentry)) { + nd->dentry = new_dentry; + dput(old_dentry); + } else + error = PTR_ERR(new_dentry); + } else { + inode->i_flags &= ~(S_IUNLINK|S_IMMUTABLE); + inode->i_ctime = CURRENT_TIME; + mark_inode_dirty(inode); + } + } + return error; +} + +#else +#warning duplicate inclusion +#endif