X-Git-Url: http://plrg.eecs.uci.edu/git/?a=blobdiff_plain;f=fs%2Fattr.c;h=6530ced19697d49a9189fa289c9112187448fee3;hb=5dc806cc889ffa876e7a6cea2787acb3bc02240f;hp=66fa6251c398d7584042c7169967f54bfed4278e;hpb=2075186d012c815911494f34fc16aef7c8f3492b;p=firefly-linux-kernel-4.4.55.git diff --git a/fs/attr.c b/fs/attr.c index 66fa6251c398..6530ced19697 100644 --- a/fs/attr.c +++ b/fs/attr.c @@ -167,7 +167,27 @@ void setattr_copy(struct inode *inode, const struct iattr *attr) } EXPORT_SYMBOL(setattr_copy); -int notify_change(struct dentry * dentry, struct iattr * attr) +/** + * notify_change - modify attributes of a filesytem object + * @dentry: object affected + * @iattr: new attributes + * @delegated_inode: returns inode, if the inode is delegated + * + * The caller must hold the i_mutex on the affected object. + * + * If notify_change discovers a delegation in need of breaking, + * it will return -EWOULDBLOCK and return a reference to the inode in + * delegated_inode. The caller should then break the delegation and + * retry. Because breaking a delegation may take a long time, the + * caller should drop the i_mutex before doing so. + * + * Alternatively, a caller may pass NULL for delegated_inode. This may + * be appropriate for callers that expect the underlying filesystem not + * to be NFS exported. Also, passing NULL is fine for callers holding + * the file open for write, as there can be no conflicting delegation in + * that case. + */ +int notify_change(struct dentry * dentry, struct iattr * attr, struct inode **delegated_inode) { struct inode *inode = dentry->d_inode; umode_t mode = inode->i_mode; @@ -236,6 +256,9 @@ int notify_change(struct dentry * dentry, struct iattr * attr) return 0; error = security_inode_setattr(dentry, attr); + if (error) + return error; + error = try_break_deleg(inode, delegated_inode); if (error) return error;