Back to home page

OSCL-LXR

 
 

    


0001 // SPDX-License-Identifier: GPL-2.0-or-later
0002 /*
0003  * export.c
0004  *
0005  * Functions to facilitate NFS exporting
0006  *
0007  * Copyright (C) 2002, 2005 Oracle.  All rights reserved.
0008  */
0009 
0010 #include <linux/fs.h>
0011 #include <linux/types.h>
0012 
0013 #include <cluster/masklog.h>
0014 
0015 #include "ocfs2.h"
0016 
0017 #include "alloc.h"
0018 #include "dir.h"
0019 #include "dlmglue.h"
0020 #include "dcache.h"
0021 #include "export.h"
0022 #include "inode.h"
0023 
0024 #include "buffer_head_io.h"
0025 #include "suballoc.h"
0026 #include "ocfs2_trace.h"
0027 
0028 struct ocfs2_inode_handle
0029 {
0030     u64 ih_blkno;
0031     u32 ih_generation;
0032 };
0033 
0034 static struct dentry *ocfs2_get_dentry(struct super_block *sb,
0035         struct ocfs2_inode_handle *handle)
0036 {
0037     struct inode *inode;
0038     struct ocfs2_super *osb = OCFS2_SB(sb);
0039     u64 blkno = handle->ih_blkno;
0040     int status, set;
0041     struct dentry *result;
0042 
0043     trace_ocfs2_get_dentry_begin(sb, handle, (unsigned long long)blkno);
0044 
0045     if (blkno == 0) {
0046         result = ERR_PTR(-ESTALE);
0047         goto bail;
0048     }
0049 
0050     inode = ocfs2_ilookup(sb, blkno);
0051     /*
0052      * If the inode exists in memory, we only need to check it's
0053      * generation number
0054      */
0055     if (inode)
0056         goto check_gen;
0057 
0058     /*
0059      * This will synchronize us against ocfs2_delete_inode() on
0060      * all nodes
0061      */
0062     status = ocfs2_nfs_sync_lock(osb, 1);
0063     if (status < 0) {
0064         mlog(ML_ERROR, "getting nfs sync lock(EX) failed %d\n", status);
0065         goto check_err;
0066     }
0067 
0068     status = ocfs2_test_inode_bit(osb, blkno, &set);
0069     if (status < 0) {
0070         if (status == -EINVAL) {
0071             /*
0072              * The blkno NFS gave us doesn't even show up
0073              * as an inode, we return -ESTALE to be
0074              * nice
0075              */
0076             status = -ESTALE;
0077         } else
0078             mlog(ML_ERROR, "test inode bit failed %d\n", status);
0079         goto unlock_nfs_sync;
0080     }
0081 
0082     trace_ocfs2_get_dentry_test_bit(status, set);
0083     /* If the inode allocator bit is clear, this inode must be stale */
0084     if (!set) {
0085         status = -ESTALE;
0086         goto unlock_nfs_sync;
0087     }
0088 
0089     inode = ocfs2_iget(osb, blkno, 0, 0);
0090 
0091 unlock_nfs_sync:
0092     ocfs2_nfs_sync_unlock(osb, 1);
0093 
0094 check_err:
0095     if (status < 0) {
0096         if (status == -ESTALE) {
0097             trace_ocfs2_get_dentry_stale((unsigned long long)blkno,
0098                              handle->ih_generation);
0099         }
0100         result = ERR_PTR(status);
0101         goto bail;
0102     }
0103 
0104     if (IS_ERR(inode)) {
0105         mlog_errno(PTR_ERR(inode));
0106         result = ERR_CAST(inode);
0107         goto bail;
0108     }
0109 
0110 check_gen:
0111     if (handle->ih_generation != inode->i_generation) {
0112         trace_ocfs2_get_dentry_generation((unsigned long long)blkno,
0113                           handle->ih_generation,
0114                           inode->i_generation);
0115         iput(inode);
0116         result = ERR_PTR(-ESTALE);
0117         goto bail;
0118     }
0119 
0120     result = d_obtain_alias(inode);
0121     if (IS_ERR(result))
0122         mlog_errno(PTR_ERR(result));
0123 
0124 bail:
0125     trace_ocfs2_get_dentry_end(result);
0126     return result;
0127 }
0128 
0129 static struct dentry *ocfs2_get_parent(struct dentry *child)
0130 {
0131     int status;
0132     u64 blkno;
0133     struct dentry *parent;
0134     struct inode *dir = d_inode(child);
0135     int set;
0136 
0137     trace_ocfs2_get_parent(child, child->d_name.len, child->d_name.name,
0138                    (unsigned long long)OCFS2_I(dir)->ip_blkno);
0139 
0140     status = ocfs2_nfs_sync_lock(OCFS2_SB(dir->i_sb), 1);
0141     if (status < 0) {
0142         mlog(ML_ERROR, "getting nfs sync lock(EX) failed %d\n", status);
0143         parent = ERR_PTR(status);
0144         goto bail;
0145     }
0146 
0147     status = ocfs2_inode_lock(dir, NULL, 0);
0148     if (status < 0) {
0149         if (status != -ENOENT)
0150             mlog_errno(status);
0151         parent = ERR_PTR(status);
0152         goto unlock_nfs_sync;
0153     }
0154 
0155     status = ocfs2_lookup_ino_from_name(dir, "..", 2, &blkno);
0156     if (status < 0) {
0157         parent = ERR_PTR(-ENOENT);
0158         goto bail_unlock;
0159     }
0160 
0161     status = ocfs2_test_inode_bit(OCFS2_SB(dir->i_sb), blkno, &set);
0162     if (status < 0) {
0163         if (status == -EINVAL) {
0164             status = -ESTALE;
0165         } else
0166             mlog(ML_ERROR, "test inode bit failed %d\n", status);
0167         parent = ERR_PTR(status);
0168         goto bail_unlock;
0169     }
0170 
0171     trace_ocfs2_get_dentry_test_bit(status, set);
0172     if (!set) {
0173         status = -ESTALE;
0174         parent = ERR_PTR(status);
0175         goto bail_unlock;
0176     }
0177 
0178     parent = d_obtain_alias(ocfs2_iget(OCFS2_SB(dir->i_sb), blkno, 0, 0));
0179 
0180 bail_unlock:
0181     ocfs2_inode_unlock(dir, 0);
0182 
0183 unlock_nfs_sync:
0184     ocfs2_nfs_sync_unlock(OCFS2_SB(dir->i_sb), 1);
0185 
0186 bail:
0187     trace_ocfs2_get_parent_end(parent);
0188 
0189     return parent;
0190 }
0191 
0192 static int ocfs2_encode_fh(struct inode *inode, u32 *fh_in, int *max_len,
0193                struct inode *parent)
0194 {
0195     int len = *max_len;
0196     int type = 1;
0197     u64 blkno;
0198     u32 generation;
0199     __le32 *fh = (__force __le32 *) fh_in;
0200 
0201 #ifdef TRACE_HOOKS_ARE_NOT_BRAINDEAD_IN_YOUR_OPINION
0202 #error "You go ahead and fix that mess, then.  Somehow"
0203     trace_ocfs2_encode_fh_begin(dentry, dentry->d_name.len,
0204                     dentry->d_name.name,
0205                     fh, len, connectable);
0206 #endif
0207 
0208     if (parent && (len < 6)) {
0209         *max_len = 6;
0210         type = FILEID_INVALID;
0211         goto bail;
0212     } else if (len < 3) {
0213         *max_len = 3;
0214         type = FILEID_INVALID;
0215         goto bail;
0216     }
0217 
0218     blkno = OCFS2_I(inode)->ip_blkno;
0219     generation = inode->i_generation;
0220 
0221     trace_ocfs2_encode_fh_self((unsigned long long)blkno, generation);
0222 
0223     len = 3;
0224     fh[0] = cpu_to_le32((u32)(blkno >> 32));
0225     fh[1] = cpu_to_le32((u32)(blkno & 0xffffffff));
0226     fh[2] = cpu_to_le32(generation);
0227 
0228     if (parent) {
0229         blkno = OCFS2_I(parent)->ip_blkno;
0230         generation = parent->i_generation;
0231 
0232         fh[3] = cpu_to_le32((u32)(blkno >> 32));
0233         fh[4] = cpu_to_le32((u32)(blkno & 0xffffffff));
0234         fh[5] = cpu_to_le32(generation);
0235 
0236         len = 6;
0237         type = 2;
0238 
0239         trace_ocfs2_encode_fh_parent((unsigned long long)blkno,
0240                          generation);
0241     }
0242 
0243     *max_len = len;
0244 
0245 bail:
0246     trace_ocfs2_encode_fh_type(type);
0247     return type;
0248 }
0249 
0250 static struct dentry *ocfs2_fh_to_dentry(struct super_block *sb,
0251         struct fid *fid, int fh_len, int fh_type)
0252 {
0253     struct ocfs2_inode_handle handle;
0254 
0255     if (fh_len < 3 || fh_type > 2)
0256         return NULL;
0257 
0258     handle.ih_blkno = (u64)le32_to_cpu(fid->raw[0]) << 32;
0259     handle.ih_blkno |= (u64)le32_to_cpu(fid->raw[1]);
0260     handle.ih_generation = le32_to_cpu(fid->raw[2]);
0261     return ocfs2_get_dentry(sb, &handle);
0262 }
0263 
0264 static struct dentry *ocfs2_fh_to_parent(struct super_block *sb,
0265         struct fid *fid, int fh_len, int fh_type)
0266 {
0267     struct ocfs2_inode_handle parent;
0268 
0269     if (fh_type != 2 || fh_len < 6)
0270         return NULL;
0271 
0272     parent.ih_blkno = (u64)le32_to_cpu(fid->raw[3]) << 32;
0273     parent.ih_blkno |= (u64)le32_to_cpu(fid->raw[4]);
0274     parent.ih_generation = le32_to_cpu(fid->raw[5]);
0275     return ocfs2_get_dentry(sb, &parent);
0276 }
0277 
0278 const struct export_operations ocfs2_export_ops = {
0279     .encode_fh  = ocfs2_encode_fh,
0280     .fh_to_dentry   = ocfs2_fh_to_dentry,
0281     .fh_to_parent   = ocfs2_fh_to_parent,
0282     .get_parent = ocfs2_get_parent,
0283 };