Back to home page

OSCL-LXR

 
 

    


0001 // SPDX-License-Identifier: GPL-2.0
0002 /*
0003  *  linux/fs/nfs/unlink.c
0004  *
0005  * nfs sillydelete handling
0006  *
0007  */
0008 
0009 #include <linux/slab.h>
0010 #include <linux/string.h>
0011 #include <linux/dcache.h>
0012 #include <linux/sunrpc/sched.h>
0013 #include <linux/sunrpc/clnt.h>
0014 #include <linux/nfs_fs.h>
0015 #include <linux/sched.h>
0016 #include <linux/wait.h>
0017 #include <linux/namei.h>
0018 #include <linux/fsnotify.h>
0019 
0020 #include "internal.h"
0021 #include "nfs4_fs.h"
0022 #include "iostat.h"
0023 #include "delegation.h"
0024 
0025 #include "nfstrace.h"
0026 
0027 /**
0028  * nfs_free_unlinkdata - release data from a sillydelete operation.
0029  * @data: pointer to unlink structure.
0030  */
0031 static void
0032 nfs_free_unlinkdata(struct nfs_unlinkdata *data)
0033 {
0034     put_cred(data->cred);
0035     kfree(data->args.name.name);
0036     kfree(data);
0037 }
0038 
0039 /**
0040  * nfs_async_unlink_done - Sillydelete post-processing
0041  * @task: rpc_task of the sillydelete
0042  * @calldata: pointer to nfs_unlinkdata
0043  *
0044  * Do the directory attribute update.
0045  */
0046 static void nfs_async_unlink_done(struct rpc_task *task, void *calldata)
0047 {
0048     struct nfs_unlinkdata *data = calldata;
0049     struct inode *dir = d_inode(data->dentry->d_parent);
0050 
0051     trace_nfs_sillyrename_unlink(data, task->tk_status);
0052     if (!NFS_PROTO(dir)->unlink_done(task, dir))
0053         rpc_restart_call_prepare(task);
0054 }
0055 
0056 /**
0057  * nfs_async_unlink_release - Release the sillydelete data.
0058  * @calldata: struct nfs_unlinkdata to release
0059  *
0060  * We need to call nfs_put_unlinkdata as a 'tk_release' task since the
0061  * rpc_task would be freed too.
0062  */
0063 static void nfs_async_unlink_release(void *calldata)
0064 {
0065     struct nfs_unlinkdata   *data = calldata;
0066     struct dentry *dentry = data->dentry;
0067     struct super_block *sb = dentry->d_sb;
0068 
0069     up_read_non_owner(&NFS_I(d_inode(dentry->d_parent))->rmdir_sem);
0070     d_lookup_done(dentry);
0071     nfs_free_unlinkdata(data);
0072     dput(dentry);
0073     nfs_sb_deactive(sb);
0074 }
0075 
0076 static void nfs_unlink_prepare(struct rpc_task *task, void *calldata)
0077 {
0078     struct nfs_unlinkdata *data = calldata;
0079     struct inode *dir = d_inode(data->dentry->d_parent);
0080     NFS_PROTO(dir)->unlink_rpc_prepare(task, data);
0081 }
0082 
0083 static const struct rpc_call_ops nfs_unlink_ops = {
0084     .rpc_call_done = nfs_async_unlink_done,
0085     .rpc_release = nfs_async_unlink_release,
0086     .rpc_call_prepare = nfs_unlink_prepare,
0087 };
0088 
0089 static void nfs_do_call_unlink(struct inode *inode, struct nfs_unlinkdata *data)
0090 {
0091     struct rpc_message msg = {
0092         .rpc_argp = &data->args,
0093         .rpc_resp = &data->res,
0094         .rpc_cred = data->cred,
0095     };
0096     struct rpc_task_setup task_setup_data = {
0097         .rpc_message = &msg,
0098         .callback_ops = &nfs_unlink_ops,
0099         .callback_data = data,
0100         .workqueue = nfsiod_workqueue,
0101         .flags = RPC_TASK_ASYNC | RPC_TASK_CRED_NOREF,
0102     };
0103     struct rpc_task *task;
0104     struct inode *dir = d_inode(data->dentry->d_parent);
0105 
0106     if (nfs_server_capable(inode, NFS_CAP_MOVEABLE))
0107         task_setup_data.flags |= RPC_TASK_MOVEABLE;
0108 
0109     nfs_sb_active(dir->i_sb);
0110     data->args.fh = NFS_FH(dir);
0111     nfs_fattr_init(data->res.dir_attr);
0112 
0113     NFS_PROTO(dir)->unlink_setup(&msg, data->dentry, inode);
0114 
0115     task_setup_data.rpc_client = NFS_CLIENT(dir);
0116     task = rpc_run_task(&task_setup_data);
0117     if (!IS_ERR(task))
0118         rpc_put_task_async(task);
0119 }
0120 
0121 static int nfs_call_unlink(struct dentry *dentry, struct inode *inode, struct nfs_unlinkdata *data)
0122 {
0123     struct inode *dir = d_inode(dentry->d_parent);
0124     struct dentry *alias;
0125 
0126     down_read_non_owner(&NFS_I(dir)->rmdir_sem);
0127     alias = d_alloc_parallel(dentry->d_parent, &data->args.name, &data->wq);
0128     if (IS_ERR(alias)) {
0129         up_read_non_owner(&NFS_I(dir)->rmdir_sem);
0130         return 0;
0131     }
0132     if (!d_in_lookup(alias)) {
0133         int ret;
0134         void *devname_garbage = NULL;
0135 
0136         /*
0137          * Hey, we raced with lookup... See if we need to transfer
0138          * the sillyrename information to the aliased dentry.
0139          */
0140         spin_lock(&alias->d_lock);
0141         if (d_really_is_positive(alias) &&
0142             !(alias->d_flags & DCACHE_NFSFS_RENAMED)) {
0143             devname_garbage = alias->d_fsdata;
0144             alias->d_fsdata = data;
0145             alias->d_flags |= DCACHE_NFSFS_RENAMED;
0146             ret = 1;
0147         } else
0148             ret = 0;
0149         spin_unlock(&alias->d_lock);
0150         dput(alias);
0151         up_read_non_owner(&NFS_I(dir)->rmdir_sem);
0152         /*
0153          * If we'd displaced old cached devname, free it.  At that
0154          * point dentry is definitely not a root, so we won't need
0155          * that anymore.
0156          */
0157         kfree(devname_garbage);
0158         return ret;
0159     }
0160     data->dentry = alias;
0161     nfs_do_call_unlink(inode, data);
0162     return 1;
0163 }
0164 
0165 /**
0166  * nfs_async_unlink - asynchronous unlinking of a file
0167  * @dentry: parent directory of dentry
0168  * @name: name of dentry to unlink
0169  */
0170 static int
0171 nfs_async_unlink(struct dentry *dentry, const struct qstr *name)
0172 {
0173     struct nfs_unlinkdata *data;
0174     int status = -ENOMEM;
0175     void *devname_garbage = NULL;
0176 
0177     data = kzalloc(sizeof(*data), GFP_KERNEL);
0178     if (data == NULL)
0179         goto out;
0180     data->args.name.name = kstrdup(name->name, GFP_KERNEL);
0181     if (!data->args.name.name)
0182         goto out_free;
0183     data->args.name.len = name->len;
0184 
0185     data->cred = get_current_cred();
0186     data->res.dir_attr = &data->dir_attr;
0187     init_waitqueue_head(&data->wq);
0188 
0189     status = -EBUSY;
0190     spin_lock(&dentry->d_lock);
0191     if (dentry->d_flags & DCACHE_NFSFS_RENAMED)
0192         goto out_unlock;
0193     dentry->d_flags |= DCACHE_NFSFS_RENAMED;
0194     devname_garbage = dentry->d_fsdata;
0195     dentry->d_fsdata = data;
0196     spin_unlock(&dentry->d_lock);
0197     /*
0198      * If we'd displaced old cached devname, free it.  At that
0199      * point dentry is definitely not a root, so we won't need
0200      * that anymore.
0201      */
0202     kfree(devname_garbage);
0203     return 0;
0204 out_unlock:
0205     spin_unlock(&dentry->d_lock);
0206     put_cred(data->cred);
0207     kfree(data->args.name.name);
0208 out_free:
0209     kfree(data);
0210 out:
0211     return status;
0212 }
0213 
0214 /**
0215  * nfs_complete_unlink - Initialize completion of the sillydelete
0216  * @dentry: dentry to delete
0217  * @inode: inode
0218  *
0219  * Since we're most likely to be called by dentry_iput(), we
0220  * only use the dentry to find the sillydelete. We then copy the name
0221  * into the qstr.
0222  */
0223 void
0224 nfs_complete_unlink(struct dentry *dentry, struct inode *inode)
0225 {
0226     struct nfs_unlinkdata   *data;
0227 
0228     spin_lock(&dentry->d_lock);
0229     dentry->d_flags &= ~DCACHE_NFSFS_RENAMED;
0230     data = dentry->d_fsdata;
0231     dentry->d_fsdata = NULL;
0232     spin_unlock(&dentry->d_lock);
0233 
0234     if (NFS_STALE(inode) || !nfs_call_unlink(dentry, inode, data))
0235         nfs_free_unlinkdata(data);
0236 }
0237 
0238 /* Cancel a queued async unlink. Called when a sillyrename run fails. */
0239 static void
0240 nfs_cancel_async_unlink(struct dentry *dentry)
0241 {
0242     spin_lock(&dentry->d_lock);
0243     if (dentry->d_flags & DCACHE_NFSFS_RENAMED) {
0244         struct nfs_unlinkdata *data = dentry->d_fsdata;
0245 
0246         dentry->d_flags &= ~DCACHE_NFSFS_RENAMED;
0247         dentry->d_fsdata = NULL;
0248         spin_unlock(&dentry->d_lock);
0249         nfs_free_unlinkdata(data);
0250         return;
0251     }
0252     spin_unlock(&dentry->d_lock);
0253 }
0254 
0255 /**
0256  * nfs_async_rename_done - Sillyrename post-processing
0257  * @task: rpc_task of the sillyrename
0258  * @calldata: nfs_renamedata for the sillyrename
0259  *
0260  * Do the directory attribute updates and the d_move
0261  */
0262 static void nfs_async_rename_done(struct rpc_task *task, void *calldata)
0263 {
0264     struct nfs_renamedata *data = calldata;
0265     struct inode *old_dir = data->old_dir;
0266     struct inode *new_dir = data->new_dir;
0267     struct dentry *old_dentry = data->old_dentry;
0268 
0269     trace_nfs_sillyrename_rename(old_dir, old_dentry,
0270             new_dir, data->new_dentry, task->tk_status);
0271     if (!NFS_PROTO(old_dir)->rename_done(task, old_dir, new_dir)) {
0272         rpc_restart_call_prepare(task);
0273         return;
0274     }
0275 
0276     if (data->complete)
0277         data->complete(task, data);
0278 }
0279 
0280 /**
0281  * nfs_async_rename_release - Release the sillyrename data.
0282  * @calldata: the struct nfs_renamedata to be released
0283  */
0284 static void nfs_async_rename_release(void *calldata)
0285 {
0286     struct nfs_renamedata   *data = calldata;
0287     struct super_block *sb = data->old_dir->i_sb;
0288 
0289     if (d_really_is_positive(data->old_dentry))
0290         nfs_mark_for_revalidate(d_inode(data->old_dentry));
0291 
0292     /* The result of the rename is unknown. Play it safe by
0293      * forcing a new lookup */
0294     if (data->cancelled) {
0295         spin_lock(&data->old_dir->i_lock);
0296         nfs_force_lookup_revalidate(data->old_dir);
0297         spin_unlock(&data->old_dir->i_lock);
0298         if (data->new_dir != data->old_dir) {
0299             spin_lock(&data->new_dir->i_lock);
0300             nfs_force_lookup_revalidate(data->new_dir);
0301             spin_unlock(&data->new_dir->i_lock);
0302         }
0303     }
0304 
0305     dput(data->old_dentry);
0306     dput(data->new_dentry);
0307     iput(data->old_dir);
0308     iput(data->new_dir);
0309     nfs_sb_deactive(sb);
0310     put_cred(data->cred);
0311     kfree(data);
0312 }
0313 
0314 static void nfs_rename_prepare(struct rpc_task *task, void *calldata)
0315 {
0316     struct nfs_renamedata *data = calldata;
0317     NFS_PROTO(data->old_dir)->rename_rpc_prepare(task, data);
0318 }
0319 
0320 static const struct rpc_call_ops nfs_rename_ops = {
0321     .rpc_call_done = nfs_async_rename_done,
0322     .rpc_release = nfs_async_rename_release,
0323     .rpc_call_prepare = nfs_rename_prepare,
0324 };
0325 
0326 /**
0327  * nfs_async_rename - perform an asynchronous rename operation
0328  * @old_dir: directory that currently holds the dentry to be renamed
0329  * @new_dir: target directory for the rename
0330  * @old_dentry: original dentry to be renamed
0331  * @new_dentry: dentry to which the old_dentry should be renamed
0332  * @complete: Function to run on successful completion
0333  *
0334  * It's expected that valid references to the dentries and inodes are held
0335  */
0336 struct rpc_task *
0337 nfs_async_rename(struct inode *old_dir, struct inode *new_dir,
0338          struct dentry *old_dentry, struct dentry *new_dentry,
0339          void (*complete)(struct rpc_task *, struct nfs_renamedata *))
0340 {
0341     struct nfs_renamedata *data;
0342     struct rpc_message msg = { };
0343     struct rpc_task_setup task_setup_data = {
0344         .rpc_message = &msg,
0345         .callback_ops = &nfs_rename_ops,
0346         .workqueue = nfsiod_workqueue,
0347         .rpc_client = NFS_CLIENT(old_dir),
0348         .flags = RPC_TASK_ASYNC | RPC_TASK_CRED_NOREF,
0349     };
0350 
0351     if (nfs_server_capable(old_dir, NFS_CAP_MOVEABLE) &&
0352         nfs_server_capable(new_dir, NFS_CAP_MOVEABLE))
0353         task_setup_data.flags |= RPC_TASK_MOVEABLE;
0354 
0355     data = kzalloc(sizeof(*data), GFP_KERNEL);
0356     if (data == NULL)
0357         return ERR_PTR(-ENOMEM);
0358     task_setup_data.task = &data->task;
0359     task_setup_data.callback_data = data;
0360 
0361     data->cred = get_current_cred();
0362 
0363     msg.rpc_argp = &data->args;
0364     msg.rpc_resp = &data->res;
0365     msg.rpc_cred = data->cred;
0366 
0367     /* set up nfs_renamedata */
0368     data->old_dir = old_dir;
0369     ihold(old_dir);
0370     data->new_dir = new_dir;
0371     ihold(new_dir);
0372     data->old_dentry = dget(old_dentry);
0373     data->new_dentry = dget(new_dentry);
0374     nfs_fattr_init(&data->old_fattr);
0375     nfs_fattr_init(&data->new_fattr);
0376     data->complete = complete;
0377 
0378     /* set up nfs_renameargs */
0379     data->args.old_dir = NFS_FH(old_dir);
0380     data->args.old_name = &old_dentry->d_name;
0381     data->args.new_dir = NFS_FH(new_dir);
0382     data->args.new_name = &new_dentry->d_name;
0383 
0384     /* set up nfs_renameres */
0385     data->res.old_fattr = &data->old_fattr;
0386     data->res.new_fattr = &data->new_fattr;
0387 
0388     nfs_sb_active(old_dir->i_sb);
0389 
0390     NFS_PROTO(data->old_dir)->rename_setup(&msg, old_dentry, new_dentry);
0391 
0392     return rpc_run_task(&task_setup_data);
0393 }
0394 
0395 /*
0396  * Perform tasks needed when a sillyrename is done such as cancelling the
0397  * queued async unlink if it failed.
0398  */
0399 static void
0400 nfs_complete_sillyrename(struct rpc_task *task, struct nfs_renamedata *data)
0401 {
0402     struct dentry *dentry = data->old_dentry;
0403 
0404     if (task->tk_status != 0) {
0405         nfs_cancel_async_unlink(dentry);
0406         return;
0407     }
0408 }
0409 
0410 #define SILLYNAME_PREFIX ".nfs"
0411 #define SILLYNAME_PREFIX_LEN ((unsigned)sizeof(SILLYNAME_PREFIX) - 1)
0412 #define SILLYNAME_FILEID_LEN ((unsigned)sizeof(u64) << 1)
0413 #define SILLYNAME_COUNTER_LEN ((unsigned)sizeof(unsigned int) << 1)
0414 #define SILLYNAME_LEN (SILLYNAME_PREFIX_LEN + \
0415         SILLYNAME_FILEID_LEN + \
0416         SILLYNAME_COUNTER_LEN)
0417 
0418 /**
0419  * nfs_sillyrename - Perform a silly-rename of a dentry
0420  * @dir: inode of directory that contains dentry
0421  * @dentry: dentry to be sillyrenamed
0422  *
0423  * NFSv2/3 is stateless and the server doesn't know when the client is
0424  * holding a file open. To prevent application problems when a file is
0425  * unlinked while it's still open, the client performs a "silly-rename".
0426  * That is, it renames the file to a hidden file in the same directory,
0427  * and only performs the unlink once the last reference to it is put.
0428  *
0429  * The final cleanup is done during dentry_iput.
0430  *
0431  * (Note: NFSv4 is stateful, and has opens, so in theory an NFSv4 server
0432  * could take responsibility for keeping open files referenced.  The server
0433  * would also need to ensure that opened-but-deleted files were kept over
0434  * reboots.  However, we may not assume a server does so.  (RFC 5661
0435  * does provide an OPEN4_RESULT_PRESERVE_UNLINKED flag that a server can
0436  * use to advertise that it does this; some day we may take advantage of
0437  * it.))
0438  */
0439 int
0440 nfs_sillyrename(struct inode *dir, struct dentry *dentry)
0441 {
0442     static unsigned int sillycounter;
0443     unsigned char silly[SILLYNAME_LEN + 1];
0444     unsigned long long fileid;
0445     struct dentry *sdentry;
0446     struct inode *inode = d_inode(dentry);
0447     struct rpc_task *task;
0448     int            error = -EBUSY;
0449 
0450     dfprintk(VFS, "NFS: silly-rename(%pd2, ct=%d)\n",
0451         dentry, d_count(dentry));
0452     nfs_inc_stats(dir, NFSIOS_SILLYRENAME);
0453 
0454     /*
0455      * We don't allow a dentry to be silly-renamed twice.
0456      */
0457     if (dentry->d_flags & DCACHE_NFSFS_RENAMED)
0458         goto out;
0459 
0460     fileid = NFS_FILEID(d_inode(dentry));
0461 
0462     sdentry = NULL;
0463     do {
0464         int slen;
0465         dput(sdentry);
0466         sillycounter++;
0467         slen = scnprintf(silly, sizeof(silly),
0468                 SILLYNAME_PREFIX "%0*llx%0*x",
0469                 SILLYNAME_FILEID_LEN, fileid,
0470                 SILLYNAME_COUNTER_LEN, sillycounter);
0471 
0472         dfprintk(VFS, "NFS: trying to rename %pd to %s\n",
0473                 dentry, silly);
0474 
0475         sdentry = lookup_one_len(silly, dentry->d_parent, slen);
0476         /*
0477          * N.B. Better to return EBUSY here ... it could be
0478          * dangerous to delete the file while it's in use.
0479          */
0480         if (IS_ERR(sdentry))
0481             goto out;
0482     } while (d_inode(sdentry) != NULL); /* need negative lookup */
0483 
0484     ihold(inode);
0485 
0486     /* queue unlink first. Can't do this from rpc_release as it
0487      * has to allocate memory
0488      */
0489     error = nfs_async_unlink(dentry, &sdentry->d_name);
0490     if (error)
0491         goto out_dput;
0492 
0493     /* run the rename task, undo unlink if it fails */
0494     task = nfs_async_rename(dir, dir, dentry, sdentry,
0495                     nfs_complete_sillyrename);
0496     if (IS_ERR(task)) {
0497         error = -EBUSY;
0498         nfs_cancel_async_unlink(dentry);
0499         goto out_dput;
0500     }
0501 
0502     /* wait for the RPC task to complete, unless a SIGKILL intervenes */
0503     error = rpc_wait_for_completion_task(task);
0504     if (error == 0)
0505         error = task->tk_status;
0506     switch (error) {
0507     case 0:
0508         /* The rename succeeded */
0509         nfs_set_verifier(dentry, nfs_save_change_attribute(dir));
0510         spin_lock(&inode->i_lock);
0511         NFS_I(inode)->attr_gencount = nfs_inc_attr_generation_counter();
0512         nfs_set_cache_invalid(inode, NFS_INO_INVALID_CHANGE |
0513                              NFS_INO_INVALID_CTIME |
0514                              NFS_INO_REVAL_FORCED);
0515         spin_unlock(&inode->i_lock);
0516         d_move(dentry, sdentry);
0517         break;
0518     case -ERESTARTSYS:
0519         /* The result of the rename is unknown. Play it safe by
0520          * forcing a new lookup */
0521         d_drop(dentry);
0522         d_drop(sdentry);
0523     }
0524     rpc_put_task(task);
0525 out_dput:
0526     iput(inode);
0527     dput(sdentry);
0528 out:
0529     return error;
0530 }